@@ -760,6 +760,67 @@ func (s *standaloneActivityTestSuite) TestCompletedActivity_CannotTerminate() {
760760 require .Error (t , err )
761761}
762762
763+ func (s * standaloneActivityTestSuite ) TestScheduleToCloseTimeout_WithRetry () {
764+ t := s .T ()
765+ ctx , cancel := context .WithTimeout (t .Context (), 30 * time .Second )
766+ defer cancel ()
767+ activityID := testcore .RandomizeStr (t .Name ())
768+ taskQueue := testcore .RandomizeStr (t .Name ())
769+
770+ // Start an activity
771+ startResp , err := s .FrontendClient ().StartActivityExecution (ctx , & workflowservice.StartActivityExecutionRequest {
772+ Namespace : s .Namespace ().String (),
773+ ActivityId : activityID ,
774+ ActivityType : & commonpb.ActivityType {
775+ Name : "test-activity-type" ,
776+ },
777+ Options : & activitypb.ActivityOptions {
778+ TaskQueue : & taskqueuepb.TaskQueue {
779+ Name : taskQueue ,
780+ },
781+ // It's not possible to guarantee (e.g. via NextRetryDelay or RetryPolicy) that a retry
782+ // will start with a delay <1s because of the use of TimerProcessorMaxTimeShift in the
783+ // timer queue. Therefore we allow 1s for the ActivityDispatchTask to be executed, and
784+ // time out the activity 1s into Attempt 2.
785+ ScheduleToCloseTimeout : durationpb .New (2 * time .Second ),
786+ },
787+ })
788+ require .NoError (t , err )
789+
790+ // Fail attempt 1, causing the attempt counter to increment.
791+ pollTaskResp , err := s .pollActivityTaskQueue (ctx , taskQueue )
792+ require .NoError (t , err )
793+ _ , err = s .FrontendClient ().RespondActivityTaskFailed (ctx , & workflowservice.RespondActivityTaskFailedRequest {
794+ Namespace : s .Namespace ().String (),
795+ TaskToken : pollTaskResp .TaskToken ,
796+ Failure : & failurepb.Failure {
797+ Message : "Retryable failure" ,
798+ FailureInfo : & failurepb.Failure_ApplicationFailureInfo {ApplicationFailureInfo : & failurepb.ApplicationFailureInfo {
799+ NonRetryable : false ,
800+ NextRetryDelay : durationpb .New (1 * time .Second ),
801+ }},
802+ },
803+ })
804+ require .NoError (t , err )
805+ pollTaskResp , err = s .pollActivityTaskQueue (ctx , taskQueue )
806+ require .NoError (t , err )
807+
808+ // Wait for schedule-to-close timeout.
809+ pollResp , err := s .FrontendClient ().PollActivityExecution (ctx , & workflowservice.PollActivityExecutionRequest {
810+ Namespace : s .Namespace ().String (),
811+ ActivityId : activityID ,
812+ RunId : startResp .RunId ,
813+ IncludeInfo : true ,
814+ IncludeOutcome : true ,
815+ WaitPolicy : & workflowservice.PollActivityExecutionRequest_WaitCompletion {
816+ WaitCompletion : & workflowservice.PollActivityExecutionRequest_CompletionWaitOptions {},
817+ },
818+ })
819+ require .NoError (t , err )
820+ require .Equal (t , enumspb .ACTIVITY_EXECUTION_STATUS_TIMED_OUT , pollResp .GetInfo ().GetStatus ())
821+ require .Equal (t , enumspb .TIMEOUT_TYPE_SCHEDULE_TO_CLOSE , pollResp .GetFailure ().GetTimeoutFailureInfo ().GetTimeoutType ())
822+ }
823+
763824// TestStartToCloseTimeout tests that a start-to-close timeout is recorded after the activity is
764825// started. It also verifies that PollActivityExecution can be used to poll for a TimedOut state
765826// change caused by execution of a timer task.
@@ -865,11 +926,6 @@ func (s *standaloneActivityTestSuite) TestStartToCloseTimeout() {
865926 "expected StartToCloseTimeout but is %s" , pollResp .GetFailure ().GetTimeoutFailureInfo ().GetTimeoutType ())
866927}
867928
868- func (s * standaloneActivityTestSuite ) TestScheduleToCloseTimeout () {
869- // TODO implement when we have PollActivityExecution. Make sure we check the attempt vs. outcome failure population.
870- s .T ().Skip ("Temporarily disabled" )
871- }
872-
873929func (s * standaloneActivityTestSuite ) TestPollActivityExecution_NoWait () {
874930 t := s .T ()
875931 ctx , cancel := context .WithTimeout (t .Context (), 10 * time .Second )
0 commit comments