Hi! I’m writing workflow unit tests and wondering if the Temporal experts here have any pointers on testing timeouts?
The workflow will be part of a service that has an SLO, so before executing a child workflow, I set a timeout:
Test framework performs time skipping if a workflow is blocked so it allows unit tests to execute much much faster.
You could use RegisterDelayedCallback (sample here) to registers a callback to fire after a delay and perform your checks in this callback.
That said we should try to reproduce this so could make sure there isn’t and issue with WorkflowExecutionTimeout in SDK test suite. Could you share a reproduce and your Go SDK version used?
Thank you tihomir! I was interested to know whether the issue was incorrect setup or that the timeouts are ignored in the test environment. Glad to have an answer
I can probably do a manual testing to verify the timeout setup, but having a unit test would be much easier. Thanks maxim for filing the issue!
I’m using Go version 1.18.4
Repro:
Note that I made some changes to make the examples simpler but the results are the same.
Test:
type TimeoutTestSuite struct {
suite.Suite
testsuite.WorkflowTestSuite
env *testsuite.TestWorkflowEnvironment
}
func (s *TimeoutTestSuite) SetupTest() {
s.env = s.NewTestWorkflowEnvironment()
s.env.RegisterWorkflow(NoOp)
s.env.RegisterActivity(NoopActivity2)
s.env.RegisterWorkflow(NoOp2)
s.env.RegisterWorkflow(NoopChild)
}
func (s *TimeoutTestSuite) AfterTest(_, _ string) {
s.env.AssertExpectations(s.T())
}
func TestTimeoutTestSuite(t *testing.T) {
suite.Run(t, new(TimeoutTestSuite))
}
func (s *TimeoutTestSuite) Test_Timeouts_2() {
// Make activity run longer than timeouts
s.env.OnActivity(NoopActivity2, mock.Anything).Return(nil).After(30 * 24 * time.Hour).Once()
// example 1: timeout set in test
s.env.SetStartWorkflowOptions(client.StartWorkflowOptions{WorkflowExecutionTimeout: 1 * time.Hour})
s.env.ExecuteWorkflow(NoOp)
s.True(s.env.IsWorkflowCompleted())
s.Error(s.env.GetWorkflowError()) // expect timeout error here but not the case
}
func (s *TimeoutTestSuite) Test_Timeouts_3() {
// Make child workflows run longer than timeouts
s.env.OnWorkflow(NoopChild, mock.Anything).Return(nil).After(30 * 24 * time.Hour).Once()
s.env.ExecuteWorkflow(NoOp2)
s.True(s.env.IsWorkflowCompleted())
s.Error(s.env.GetWorkflowError()) // expect timeout error here but not the case
}