77 "testing"
88 "time"
99
10+ "github.com/stretchr/testify/assert"
1011 "github.com/stretchr/testify/require"
1112 commandpb "go.temporal.io/api/command/v1"
1213 commonpb "go.temporal.io/api/common/v1"
@@ -17,12 +18,15 @@ import (
1718 "go.temporal.io/api/serviceerror"
1819 updatepb "go.temporal.io/api/update/v1"
1920 workerpb "go.temporal.io/api/worker/v1"
21+ clockspb "go.temporal.io/server/api/clock/v1"
2022 persistencespb "go.temporal.io/server/api/persistence/v1"
23+ "go.temporal.io/server/common"
2124 "go.temporal.io/server/common/backoff"
2225 "go.temporal.io/server/common/collection"
2326 "go.temporal.io/server/common/dynamicconfig"
2427 "go.temporal.io/server/common/effect"
2528 "go.temporal.io/server/common/log"
29+ "go.temporal.io/server/common/tasktoken"
2630 "go.temporal.io/server/common/metrics"
2731 "go.temporal.io/server/common/namespace"
2832 "go.temporal.io/server/common/namespace/nsregistry"
@@ -470,3 +474,120 @@ func TestFlushWorkerCommandsTasks(t *testing.T) {
470474 require .NoError (t , err )
471475 })
472476}
477+
478+ func TestHandleCommandRequestCancelActivity_WorkerCommands (t * testing.T ) {
479+ t .Parallel ()
480+
481+ cancelReqEvent := & historypb.HistoryEvent {EventId : 10 }
482+ scheduledEventID := int64 (5 )
483+ controlQueue := "/_sys/worker-commands/test-ns/key1"
484+
485+ t .Run ("started activity with clock collects worker command" , func (t * testing.T ) {
486+ ctrl := gomock .NewController (t )
487+ ms := historyi .NewMockMutableState (ctrl )
488+
489+ ai := & persistencespb.ActivityInfo {
490+ ScheduledEventId : scheduledEventID ,
491+ StartedEventId : 7 ,
492+ ActivityId : "act-1" ,
493+ WorkerControlTaskQueue : controlQueue ,
494+ StartedClock : & clockspb.VectorClock {ClusterId : 1 , ShardId : 1 , Clock : 100 },
495+ Version : 1 ,
496+ StartVersion : 1 ,
497+ Attempt : 1 ,
498+ ActivityType : & commonpb.ActivityType {Name : "test-activity" },
499+ }
500+
501+ ms .EXPECT ().AddActivityTaskCancelRequestedEvent (int64 (123 ), scheduledEventID , "test-identity" ).
502+ Return (cancelReqEvent , ai , nil )
503+ ms .EXPECT ().GetNamespaceEntry ().Return (tests .LocalNamespaceEntry ).AnyTimes ()
504+ ms .EXPECT ().GetWorkflowKey ().Return (tests .WorkflowKey ).AnyTimes ()
505+
506+ handler := & workflowTaskCompletedHandler {
507+ identity : "test-identity" ,
508+ workflowTaskCompletedID : 123 ,
509+ mutableState : ms ,
510+ tokenSerializer : tasktoken .NewSerializer (),
511+ logger : log .NewNoopLogger (),
512+ }
513+
514+ event , err := handler .handleCommandRequestCancelActivity (
515+ context .Background (),
516+ & commandpb.RequestCancelActivityTaskCommandAttributes {
517+ ScheduledEventId : scheduledEventID ,
518+ },
519+ )
520+ require .NoError (t , err )
521+ assert .Equal (t , cancelReqEvent , event )
522+ assert .Len (t , handler .pendingWorkerCommandsByControlQueue [controlQueue ], 1 )
523+ })
524+
525+ t .Run ("started activity without clock skips worker command" , func (t * testing.T ) {
526+ ctrl := gomock .NewController (t )
527+ ms := historyi .NewMockMutableState (ctrl )
528+
529+ ai := & persistencespb.ActivityInfo {
530+ ScheduledEventId : scheduledEventID ,
531+ StartedEventId : 7 ,
532+ ActivityId : "act-1" ,
533+ WorkerControlTaskQueue : controlQueue ,
534+ StartedClock : nil , // pre-deploy: no clock stored
535+ Version : 1 ,
536+ StartVersion : 1 ,
537+ Attempt : 1 ,
538+ }
539+
540+ ms .EXPECT ().AddActivityTaskCancelRequestedEvent (int64 (123 ), scheduledEventID , "test-identity" ).
541+ Return (cancelReqEvent , ai , nil )
542+
543+ handler := & workflowTaskCompletedHandler {
544+ identity : "test-identity" ,
545+ workflowTaskCompletedID : 123 ,
546+ mutableState : ms ,
547+ logger : log .NewNoopLogger (),
548+ }
549+
550+ event , err := handler .handleCommandRequestCancelActivity (
551+ context .Background (),
552+ & commandpb.RequestCancelActivityTaskCommandAttributes {
553+ ScheduledEventId : scheduledEventID ,
554+ },
555+ )
556+ require .NoError (t , err )
557+ assert .Equal (t , cancelReqEvent , event )
558+ assert .Empty (t , handler .pendingWorkerCommandsByControlQueue , "no worker command should be created when StartedClock is nil" )
559+ })
560+
561+ t .Run ("started activity without control queue does not collect worker command" , func (t * testing.T ) {
562+ ctrl := gomock .NewController (t )
563+ ms := historyi .NewMockMutableState (ctrl )
564+
565+ ai := & persistencespb.ActivityInfo {
566+ ScheduledEventId : scheduledEventID ,
567+ StartedEventId : 7 ,
568+ ActivityId : "act-1" ,
569+ WorkerControlTaskQueue : "" , // worker doesn't support control tasks
570+ StartedClock : & clockspb.VectorClock {ClusterId : 1 , ShardId : 1 , Clock : 100 },
571+ }
572+
573+ ms .EXPECT ().AddActivityTaskCancelRequestedEvent (int64 (123 ), scheduledEventID , "test-identity" ).
574+ Return (cancelReqEvent , ai , nil )
575+
576+ handler := & workflowTaskCompletedHandler {
577+ identity : "test-identity" ,
578+ workflowTaskCompletedID : 123 ,
579+ mutableState : ms ,
580+ logger : log .NewNoopLogger (),
581+ }
582+
583+ event , err := handler .handleCommandRequestCancelActivity (
584+ context .Background (),
585+ & commandpb.RequestCancelActivityTaskCommandAttributes {
586+ ScheduledEventId : scheduledEventID ,
587+ },
588+ )
589+ require .NoError (t , err )
590+ assert .Equal (t , cancelReqEvent , event )
591+ assert .Empty (t , handler .pendingWorkerCommandsByControlQueue )
592+ })
593+ }
0 commit comments