-
Notifications
You must be signed in to change notification settings - Fork 55
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
IWF-70: allow headers to be set in Interpreter Config #424
Conversation
@@ -67,6 +67,7 @@ type IwfServiceTestConfig struct { | |||
MemoEncryption bool | |||
DisableFailAtMemoIncompatibility bool // default to false so that we will fail at test | |||
OptimizedVersioning *bool | |||
DefaultHeaders map[string]string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I saw that the previous implementation had integration tests that would check for the presence of the headers in every call, am I seeing that right? https://github.com/indeedeng/iwf/pull/356/files#diff-c3752f9aebfa9a670e62a5c0cc34c36bbfbfcbe849288ece0973806a34eac156R30-R33
I wanted to do something more flexible, where we would have a specific integration test for checking the headers passed in the configuration are being used, rather than having the route check it every time a call was made.
I do need some of your guidance here, I can't figure out how to do the integration tests with this approach.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The headers will be used when making calls for stateAPI. So for a specific integ tests, you will still need to build out a router. But it will be cleaner to have that specific router, is that what you meant?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's what I'm thinking yes. Do you think that would be overkill for testing such a small feature?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it’s a good idea. I have been lazy to do the right thing and the tests have become messy here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have created the tests now, I struggled a bit navigating through the existing ones trying to use one as a template. I'm sure the tests I created can be better. We can have a chat tomorrow about them and you can point me where I've gone wrong! Thanks in advance! 🙌
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good. I went through it and left you some comments already. and we can go through them later
@longquanzheng If you have some time tomorrow, let's chat tomorrow about this PR. I do need some guidance on the integration tests in the comment above. |
c58672e
to
d325a39
Compare
integ/workflow/headers/routers.go
Outdated
const ( | ||
WorkflowType = "basic" | ||
State1 = "S1" | ||
State2 = "S2" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: We can only have one state for this test
integ/workflow/headers/routers.go
Outdated
) | ||
|
||
const ( | ||
WorkflowType = "basic" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: maybe "header"?
integ/workflow/headers/routers.go
Outdated
if context.GetAttempt() <= 0 || context.GetFirstAttemptTimestamp() <= 0 { | ||
panic("attempt and firstAttemptTimestamp should be greater than zero") | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you don't have to check this
integ/headers_test.go
Outdated
// start a workflow | ||
sharedConfig := env.GetSharedConfig() | ||
apiClient := iwfidl.NewAPIClient(&iwfidl.Configuration{ | ||
DefaultHeader: sharedConfig.Interpreter.InterpreterActivityConfig.DefaultHeader, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we need this?
integ/headers_test.go
Outdated
req := apiClient.DefaultApi.ApiV1WorkflowStartPost(context.Background()) | ||
startReq := iwfidl.WorkflowStartRequest{ | ||
WorkflowId: wfId, | ||
IwfWorkflowType: basic.WorkflowType, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should start the header workflow here
integ/headers_test.go
Outdated
IwfWorkflowType: basic.WorkflowType, | ||
WorkflowTimeoutSeconds: 100, | ||
IwfWorkerUrl: "http://localhost:" + testWorkflowServerPort, | ||
StartStateId: ptr.Any(basic.State1), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the starting state should be the header.State1
integ/headers_test.go
Outdated
WorkflowIDReusePolicy: ptr.Any(iwfidl.REJECT_DUPLICATE), | ||
// TODO: need more work to write integ test for cron | ||
// manual testing for now by uncomment the following line | ||
// CronSchedule: iwfidl.PtrString("* * * * *"), | ||
RetryPolicy: &iwfidl.WorkflowRetryPolicy{ | ||
InitialIntervalSeconds: iwfidl.PtrInt32(11), | ||
BackoffCoefficient: iwfidl.PtrFloat32(11), | ||
MaximumAttempts: iwfidl.PtrInt32(11), | ||
MaximumIntervalSeconds: iwfidl.PtrInt32(11), | ||
}, | ||
}, | ||
StateOptions: &iwfidl.WorkflowStateOptions{ | ||
StartApiTimeoutSeconds: iwfidl.PtrInt32(12), | ||
DecideApiTimeoutSeconds: iwfidl.PtrInt32(13), | ||
StartApiRetryPolicy: &iwfidl.RetryPolicy{ | ||
InitialIntervalSeconds: iwfidl.PtrInt32(12), | ||
BackoffCoefficient: iwfidl.PtrFloat32(12), | ||
MaximumAttempts: iwfidl.PtrInt32(12), | ||
MaximumIntervalSeconds: iwfidl.PtrInt32(12), | ||
}, | ||
DecideApiRetryPolicy: &iwfidl.RetryPolicy{ | ||
InitialIntervalSeconds: iwfidl.PtrInt32(13), | ||
BackoffCoefficient: iwfidl.PtrFloat32(13), | ||
MaximumAttempts: iwfidl.PtrInt32(13), | ||
MaximumIntervalSeconds: iwfidl.PtrInt32(13), | ||
}, | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we can skip all these
integ/headers_test.go
Outdated
resp2, httpResp, err := req2.WorkflowGetRequest(iwfidl.WorkflowGetRequest{ | ||
WorkflowId: wfId, | ||
}).Execute() | ||
panicAtHttpError(err, httpResp) | ||
|
||
// use a wrong workflowId to test the error case | ||
_, _, err = req2.WorkflowGetRequest(iwfidl.WorkflowGetRequest{ | ||
WorkflowId: "a wrong workflowId", | ||
}).Execute() | ||
apiErr, ok = err.(*iwfidl.GenericOpenAPIError) | ||
if !ok { | ||
log.Fatalf("Should fail to invoke get api %v", err) | ||
} | ||
errResp, ok = apiErr.Model().(iwfidl.ErrorResponse) | ||
if !ok { | ||
log.Fatalf("should be error response") | ||
} | ||
assertions.Equal(errResp.GetSubStatus(), iwfidl.WORKFLOW_NOT_EXISTS_SUB_STATUS) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we can skip these. So that the test is focusing on the header stuff only
Thanks for all the test feedback @longquanzheng! This should be good to review now, let me know if there's something that you think I could simplify further! Thanks in advance! 🙌 |
config/config.go
Outdated
@@ -68,6 +68,7 @@ type ( | |||
// default is http://localhost:ApiConfig.Port | |||
ApiServiceAddress string `json:"serviceAddress"` | |||
DumpWorkflowInternalActivityConfig *DumpWorkflowInternalActivityConfig `json:"dumpWorkflowInternalActivityConfig"` | |||
DefaultHeader map[string]string `json:"defaultHeader"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not: headers (plural)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good eye! Thanks, fixed now 🙌
func (h *handler) ApiV1WorkflowStateStart(c *gin.Context) { | ||
headerValue := c.GetHeader(TestHeaderKey) | ||
if headerValue != TestHeaderValue { | ||
c.JSON(http.StatusBadRequest, gin.H{"error": "test header not found"}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we need to return here after c.JSON
. Otherwise the remaining code will override it.
func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { | ||
headerValue := c.GetHeader(TestHeaderKey) | ||
if headerValue != TestHeaderValue { | ||
c.JSON(http.StatusBadRequest, gin.H{"error": "test header not found"}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same here
integ/workflow/headers/routers.go
Outdated
if req.GetWorkflowType() == WorkflowType { | ||
h.invokeHistory[req.GetWorkflowStateId()+"_decide"]++ | ||
if req.GetWorkflowStateId() == State1 { | ||
// go to S2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: wrong comment
config/config.go
Outdated
@@ -68,6 +68,7 @@ type ( | |||
// default is http://localhost:ApiConfig.Port | |||
ApiServiceAddress string `json:"serviceAddress"` | |||
DumpWorkflowInternalActivityConfig *DumpWorkflowInternalActivityConfig `json:"dumpWorkflowInternalActivityConfig"` | |||
DefaultHeaders map[string]string `json:"defaultHeader"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
json:"defaultHeaders"
integ/workflow/headers/config.go
Outdated
const TestHeaderKey = "integration-test-header" | ||
const TestHeaderValue = "integration-test-value" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: maybe constant.go? or just put it into routers.go
Thanks for the comments! Should be all good now 👍 |
Did you forget to push the changes m? |
I did push them here: af66ce5 Unless I forgot something ... 🤔 edit: i forgot to push the reset of the changes as you pointed out 😂 pushing now |
Ok, now it should be good 😂 |
integ/workflow/headers/constants.go
Outdated
@@ -0,0 +1 @@ | |||
package headers |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nite: we can remove it if it's empty
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #424 +/- ##
==========================================
- Coverage 72.15% 64.10% -8.06%
==========================================
Files 56 57 +1
Lines 5043 5937 +894
==========================================
+ Hits 3639 3806 +167
- Misses 1138 1866 +728
+ Partials 266 265 -1 ☔ View full report in Codecov by Sentry. |
Closes #436