Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions internal/internal_workflow_testsuite.go
Original file line number Diff line number Diff line change
Expand Up @@ -2281,9 +2281,16 @@ func (env *testWorkflowEnvironmentImpl) RequestCancelChildWorkflow(_, workflowID

func (env *testWorkflowEnvironmentImpl) RequestCancelExternalWorkflow(namespace, workflowID, runID string, callback ResultHandler) {
if env.workflowInfo.WorkflowExecution.ID == workflowID {
// cancel current workflow
env.workflowCancelHandler()
// check if current workflow is a child workflow
// The way testWorkflowEnvironment is setup today, we close the child workflow dispatcher before calling
// the workflowCancelHandler. A larger refactor would be needed to handle this similar to non-test code.
// Maybe worth doing when https://github.com/temporalio/go-sdk/issues/50 is tackled.
if sd, ok := env.workflowDef.(*syncWorkflowDefinition); ok && env.isChildWorkflow() {
sd.dispatcher.NewCoroutine(sd.rootCtx, "cancel-self", true, func(ctx Context) {
env.workflowCancelHandler()
})
} else {
env.workflowCancelHandler()
}
if env.isChildWorkflow() && env.onChildWorkflowCanceledListener != nil {
env.postCallback(func() {
env.onChildWorkflowCanceledListener(env.workflowInfo)
Expand Down
34 changes: 34 additions & 0 deletions internal/workflow_testsuite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1232,3 +1232,37 @@ func TestDynamicWorkflows(t *testing.T) {
require.NoError(t, err)
require.Equal(t, "dynamic-activity - grape - cherry", result)
}

func SleepHour(ctx Context) error {
return Sleep(ctx, time.Hour)
}

func SleepThenCancel(ctx Context) error {
cwf := ExecuteChildWorkflow(
ctx,
SleepHour,
)
var res WorkflowExecution
if err := cwf.GetChildWorkflowExecution().Get(ctx, &res); err != nil {
return err
}

// Canceling an external workflow that causes a timer to cancel used to fail due to
// "illegal access from outside of workflow context"
err := RequestCancelExternalWorkflow(ctx, res.ID, res.RunID).Get(ctx, nil)
if err != nil {
return err
}

// Give the workflow time to finish canceling the child workflow
return Sleep(ctx, 1*time.Second)
}

func TestRequestCancelExternalWorkflowInSelector(t *testing.T) {
testSuite := &WorkflowTestSuite{}
env := testSuite.NewTestWorkflowEnvironment()
env.RegisterWorkflow(SleepHour)
env.ExecuteWorkflow(SleepThenCancel)
require.NoError(t, env.GetWorkflowError())
env.IsWorkflowCompleted()
}
Loading