From fcf70b011d35bda51e1d69718e3743165dafa0cb Mon Sep 17 00:00:00 2001 From: "vpatil16@ext.uber.com" Date: Wed, 5 Feb 2025 17:39:05 -0800 Subject: [PATCH 1/2] Recalibrating expense workflow timeout to 12 mins --- cmd/samples/expense/main.go | 4 +- cmd/samples/expense/workflow.go | 6 +- cmd/samples/expense/workflow_test.go | 105 +++++++++++++++++++++++++++ 3 files changed, 110 insertions(+), 5 deletions(-) diff --git a/cmd/samples/expense/main.go b/cmd/samples/expense/main.go index 934e4a16..b7864deb 100644 --- a/cmd/samples/expense/main.go +++ b/cmd/samples/expense/main.go @@ -26,8 +26,8 @@ func startWorkflow(h *common.SampleHelper, expenseID string) { workflowOptions := client.StartWorkflowOptions{ ID: "expense_" + uuid.New(), TaskList: ApplicationName, - ExecutionStartToCloseTimeout: time.Minute, - DecisionTaskStartToCloseTimeout: time.Minute, + ExecutionStartToCloseTimeout: time.Minute * 12, + DecisionTaskStartToCloseTimeout: time.Minute * 12, } h.StartWorkflow(workflowOptions, sampleExpenseWorkflow, expenseID) } diff --git a/cmd/samples/expense/workflow.go b/cmd/samples/expense/workflow.go index a34825ed..22e41a47 100644 --- a/cmd/samples/expense/workflow.go +++ b/cmd/samples/expense/workflow.go @@ -33,11 +33,11 @@ func sampleExpenseWorkflow(ctx workflow.Context, expenseID string) (result strin // step 2, wait for the expense report to be approved (or rejected) ao = workflow.ActivityOptions{ - ScheduleToStartTimeout: 10 * time.Minute, - StartToCloseTimeout: 10 * time.Minute, + ScheduleToStartTimeout: time.Minute, + StartToCloseTimeout: 4 * time.Minute, } ctx2 := workflow.WithActivityOptions(ctx, ao) - // Notice that we set the timeout to be 10 minutes for this sample demo. If the expected time for the activity to + // Notice that we set the timeout to be 4 minutes for this sample demo. If the expected time for the activity to // complete (waiting for human to approve the request) is longer, you should set the timeout accordingly so the // cadence system will wait accordingly. Otherwise, cadence system could mark the activity as failure by timeout. var status string diff --git a/cmd/samples/expense/workflow_test.go b/cmd/samples/expense/workflow_test.go index 28c7c3d7..b9f40056 100644 --- a/cmd/samples/expense/workflow_test.go +++ b/cmd/samples/expense/workflow_test.go @@ -1,6 +1,7 @@ package main import ( + "errors" "io" "net/http" "net/http/httptest" @@ -50,6 +51,110 @@ func (s *UnitTestSuite) Test_WorkflowWithMockActivities() { s.Equal("COMPLETED", workflowResult) } +func (s *UnitTestSuite) Test_TimeoutWithMockActivities() { + s.env.OnActivity(createExpenseActivity, mock.Anything, mock.Anything).Return(nil).Once() + // s.env.OnActivity(waitForDecisionActivity, mock.Anything, mock.Anything).Return("APPROVED", nil).Once() + // s.env.OnActivity(paymentActivity, mock.Anything, mock.Anything).Return(nil).Once() + s.env.SetWorkflowTimeout(time.Microsecond * 500) + s.env.SetTestTimeout(time.Minute * 10) + + s.env.ExecuteWorkflow(sampleExpenseWorkflow, "test-expense-id") + + var workflowResult string + err := s.env.GetWorkflowResult(&workflowResult) + s.Equal("TimeoutType: SCHEDULE_TO_CLOSE", err.Error()) + s.Empty(workflowResult) +} + +func (s *UnitTestSuite) Test_WorkflowStatusRejected() { + s.env.OnActivity(createExpenseActivity, mock.Anything, mock.Anything).Return(nil).Once() + s.env.OnActivity(waitForDecisionActivity, mock.Anything, mock.Anything).Return("REJECTED", nil).Once() + // s.env.OnActivity(paymentActivity, mock.Anything, mock.Anything).Return(nil).Once() + + s.env.ExecuteWorkflow(sampleExpenseWorkflow, "test-expense-id") + + s.True(s.env.IsWorkflowCompleted()) + s.NoError(s.env.GetWorkflowError()) + var workflowResult string + err := s.env.GetWorkflowResult(&workflowResult) + s.NoError(err) + s.Empty(workflowResult) +} + +func (s *UnitTestSuite) Test_WorkflowStatusCancelled() { + s.env.OnActivity(createExpenseActivity, mock.Anything, mock.Anything).Return(nil).Once() + s.env.OnActivity(waitForDecisionActivity, mock.Anything, mock.Anything).Return("CANCELLED", nil).Once() + + s.env.ExecuteWorkflow(sampleExpenseWorkflow, "test-expense-id") + + s.True(s.env.IsWorkflowCompleted()) + s.NoError(s.env.GetWorkflowError()) + var workflowResult string + err := s.env.GetWorkflowResult(&workflowResult) + s.NoError(err) + s.Empty(workflowResult) +} + +func (s *UnitTestSuite) Test_WorkflowStatusApprovedWithPaymentError() { + s.env.OnActivity(createExpenseActivity, mock.Anything, mock.Anything).Return(nil).Once() + s.env.OnActivity(waitForDecisionActivity, mock.Anything, mock.Anything).Return("APPROVED", nil).Once() + s.env.OnActivity(paymentActivity, mock.Anything, mock.Anything).Return(errors.New("payment error")).Once() + + s.env.ExecuteWorkflow(sampleExpenseWorkflow, "test-expense-id") + + s.True(s.env.IsWorkflowCompleted()) + s.Error(s.env.GetWorkflowError()) + var workflowResult string + err := s.env.GetWorkflowResult(&workflowResult) + s.Equal("payment error", err.Error()) + s.Empty(workflowResult) +} + +func (s *UnitTestSuite) Test_CreateActivityFailed() { + s.env.OnActivity(createExpenseActivity, mock.Anything, mock.Anything).Return(errors.New("expense id is empty")).Once() + + s.env.ExecuteWorkflow(sampleExpenseWorkflow, "") + + s.True(s.env.IsWorkflowCompleted()) + s.Error(s.env.GetWorkflowError()) + var workflowResult string + + err := s.env.GetWorkflowResult(&workflowResult) + s.Equal("expense id is empty", err.Error()) + s.Empty(workflowResult) +} + +func (s *UnitTestSuite) Test_WaitForDecisionActivityFailed() { + s.env.OnActivity(createExpenseActivity, mock.Anything, mock.Anything).Return(nil).Once() + s.env.OnActivity(waitForDecisionActivity, mock.Anything, mock.Anything).Return("", errors.New("failed to get decision")).Once() + + s.env.ExecuteWorkflow(sampleExpenseWorkflow, "test-expense-id") + + s.True(s.env.IsWorkflowCompleted()) + s.Error(s.env.GetWorkflowError()) + var workflowResult string + + err := s.env.GetWorkflowResult(&workflowResult) + s.Equal("failed to get decision", err.Error()) + s.Empty(workflowResult) +} + +func (s *UnitTestSuite) Test_PaymentActivityFailed() { + s.env.OnActivity(createExpenseActivity, mock.Anything, mock.Anything).Return(nil).Once() + s.env.OnActivity(waitForDecisionActivity, mock.Anything, mock.Anything).Return("APPROVED", nil).Once() + s.env.OnActivity(paymentActivity, mock.Anything, mock.Anything).Return(errors.New("payment failed")).Once() + + s.env.ExecuteWorkflow(sampleExpenseWorkflow, "test-expense-id") + + s.True(s.env.IsWorkflowCompleted()) + s.Error(s.env.GetWorkflowError()) + var workflowResult string + + err := s.env.GetWorkflowResult(&workflowResult) + s.Equal("payment failed", err.Error()) + s.Empty(workflowResult) +} + func (s *UnitTestSuite) Test_WorkflowWithMockServer() { // setup mock expense server handler := func(w http.ResponseWriter, r *http.Request) { From 55035e1f712cf59c8108bc9f9febab2c405b5c70 Mon Sep 17 00:00:00 2001 From: "vpatil16@ext.uber.com" Date: Wed, 5 Feb 2025 22:46:03 -0800 Subject: [PATCH 2/2] adressing review comments --- cmd/samples/expense/workflow_test.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/cmd/samples/expense/workflow_test.go b/cmd/samples/expense/workflow_test.go index b9f40056..bffc247a 100644 --- a/cmd/samples/expense/workflow_test.go +++ b/cmd/samples/expense/workflow_test.go @@ -53,8 +53,6 @@ func (s *UnitTestSuite) Test_WorkflowWithMockActivities() { func (s *UnitTestSuite) Test_TimeoutWithMockActivities() { s.env.OnActivity(createExpenseActivity, mock.Anything, mock.Anything).Return(nil).Once() - // s.env.OnActivity(waitForDecisionActivity, mock.Anything, mock.Anything).Return("APPROVED", nil).Once() - // s.env.OnActivity(paymentActivity, mock.Anything, mock.Anything).Return(nil).Once() s.env.SetWorkflowTimeout(time.Microsecond * 500) s.env.SetTestTimeout(time.Minute * 10) @@ -69,7 +67,6 @@ func (s *UnitTestSuite) Test_TimeoutWithMockActivities() { func (s *UnitTestSuite) Test_WorkflowStatusRejected() { s.env.OnActivity(createExpenseActivity, mock.Anything, mock.Anything).Return(nil).Once() s.env.OnActivity(waitForDecisionActivity, mock.Anything, mock.Anything).Return("REJECTED", nil).Once() - // s.env.OnActivity(paymentActivity, mock.Anything, mock.Anything).Return(nil).Once() s.env.ExecuteWorkflow(sampleExpenseWorkflow, "test-expense-id")