go.uber.org/cadence@v1.2.9/internal/internal_task_handlers_interfaces_test.go (about) 1 // Copyright (c) 2017-2020 Uber Technologies Inc. 2 // Portions of the Software are attributed to Copyright (c) 2020 Temporal Technologies Inc. 3 // 4 // Permission is hereby granted, free of charge, to any person obtaining a copy 5 // of this software and associated documentation files (the "Software"), to deal 6 // in the Software without restriction, including without limitation the rights 7 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 // copies of the Software, and to permit persons to whom the Software is 9 // furnished to do so, subject to the following conditions: 10 // 11 // The above copyright notice and this permission notice shall be included in 12 // all copies or substantial portions of the Software. 13 // 14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 // THE SOFTWARE. 21 22 package internal 23 24 import ( 25 "testing" 26 27 "github.com/golang/mock/gomock" 28 "github.com/stretchr/testify/suite" 29 "github.com/uber/tchannel-go/thrift" 30 "golang.org/x/net/context" 31 32 "go.uber.org/cadence/.gen/go/cadence/workflowservicetest" 33 m "go.uber.org/cadence/.gen/go/shared" 34 "go.uber.org/cadence/internal/common" 35 ) 36 37 type ( 38 PollLayerInterfacesTestSuite struct { 39 suite.Suite 40 mockCtrl *gomock.Controller 41 service *workflowservicetest.MockClient 42 } 43 ) 44 45 // Sample Workflow task handler 46 type sampleWorkflowTaskHandler struct { 47 } 48 49 func (wth sampleWorkflowTaskHandler) ProcessWorkflowTask( 50 workflowTask *workflowTask, 51 d decisionHeartbeatFunc, 52 ) (interface{}, error) { 53 return &m.RespondDecisionTaskCompletedRequest{ 54 TaskToken: workflowTask.task.TaskToken, 55 }, nil 56 } 57 58 func newSampleWorkflowTaskHandler() *sampleWorkflowTaskHandler { 59 return &sampleWorkflowTaskHandler{} 60 } 61 62 // Sample ActivityTaskHandler 63 type sampleActivityTaskHandler struct { 64 } 65 66 func newSampleActivityTaskHandler() *sampleActivityTaskHandler { 67 return &sampleActivityTaskHandler{} 68 } 69 70 func (ath sampleActivityTaskHandler) Execute(taskList string, task *m.PollForActivityTaskResponse) (interface{}, error) { 71 activityImplementation := &greeterActivity{} 72 result, err := activityImplementation.Execute(context.Background(), task.Input) 73 if err != nil { 74 reason := err.Error() 75 return &m.RespondActivityTaskFailedRequest{ 76 TaskToken: task.TaskToken, 77 Reason: &reason, 78 }, nil 79 } 80 return &m.RespondActivityTaskCompletedRequest{ 81 TaskToken: task.TaskToken, 82 Result: result, 83 }, nil 84 } 85 86 // Test suite. 87 func TestPollLayerInterfacesTestSuite(t *testing.T) { 88 suite.Run(t, new(PollLayerInterfacesTestSuite)) 89 } 90 91 func (s *PollLayerInterfacesTestSuite) SetupTest() { 92 s.mockCtrl = gomock.NewController(s.T()) 93 s.service = workflowservicetest.NewMockClient(s.mockCtrl) 94 } 95 96 func (s *PollLayerInterfacesTestSuite) TearDownTest() { 97 s.mockCtrl.Finish() // assert mock’s expectations 98 } 99 100 func (s *PollLayerInterfacesTestSuite) TestProcessWorkflowTaskInterface() { 101 ctx, cancel := thrift.NewContext(10) 102 defer cancel() 103 104 // mocks 105 s.service.EXPECT().PollForDecisionTask(gomock.Any(), gomock.Any()).Return(&m.PollForDecisionTaskResponse{}, nil) 106 s.service.EXPECT().RespondDecisionTaskCompleted(gomock.Any(), gomock.Any()).Return(nil, nil) 107 108 response, err := s.service.PollForDecisionTask(ctx, &m.PollForDecisionTaskRequest{}) 109 s.NoError(err) 110 111 // Process task and respond to the service. 112 taskHandler := newSampleWorkflowTaskHandler() 113 request, err := taskHandler.ProcessWorkflowTask(&workflowTask{task: response}, nil) 114 completionRequest := request.(*m.RespondDecisionTaskCompletedRequest) 115 s.NoError(err) 116 117 _, err = s.service.RespondDecisionTaskCompleted(ctx, completionRequest) 118 s.NoError(err) 119 } 120 121 func (s *PollLayerInterfacesTestSuite) TestProcessActivityTaskInterface() { 122 ctx, cancel := thrift.NewContext(10) 123 defer cancel() 124 125 // mocks 126 s.service.EXPECT().PollForActivityTask(gomock.Any(), gomock.Any()).Return(&m.PollForActivityTaskResponse{}, nil) 127 s.service.EXPECT().RespondActivityTaskCompleted(gomock.Any(), gomock.Any()).Return(nil) 128 129 response, err := s.service.PollForActivityTask(ctx, &m.PollForActivityTaskRequest{}) 130 s.NoError(err) 131 132 // Execute activity task and respond to the service. 133 taskHandler := newSampleActivityTaskHandler() 134 request, err := taskHandler.Execute(tasklist, response) 135 s.NoError(err) 136 switch request.(type) { 137 case *m.RespondActivityTaskCompletedRequest: 138 err = s.service.RespondActivityTaskCompleted(ctx, request.(*m.RespondActivityTaskCompletedRequest)) 139 s.NoError(err) 140 case *m.RespondActivityTaskFailedRequest: // shouldn't happen 141 err = s.service.RespondActivityTaskFailed(ctx, request.(*m.RespondActivityTaskFailedRequest)) 142 s.NoError(err) 143 } 144 } 145 146 func (s *PollLayerInterfacesTestSuite) TestGetNextDecisions() { 147 // Schedule an activity and see if we complete workflow. 148 taskList := "tl1" 149 testEvents := []*m.HistoryEvent{ 150 createTestEventWorkflowExecutionStarted(1, &m.WorkflowExecutionStartedEventAttributes{TaskList: &m.TaskList{Name: &taskList}}), 151 createTestEventDecisionTaskScheduled(2, &m.DecisionTaskScheduledEventAttributes{TaskList: &m.TaskList{Name: &taskList}}), 152 createTestEventDecisionTaskStarted(3), 153 { 154 EventId: common.Int64Ptr(4), 155 EventType: common.EventTypePtr(m.EventTypeDecisionTaskFailed), 156 }, 157 { 158 EventId: common.Int64Ptr(5), 159 EventType: common.EventTypePtr(m.EventTypeWorkflowExecutionSignaled), 160 }, 161 createTestEventDecisionTaskScheduled(6, &m.DecisionTaskScheduledEventAttributes{TaskList: &m.TaskList{Name: &taskList}}), 162 createTestEventDecisionTaskStarted(7), 163 } 164 task := createWorkflowTask(testEvents[0:3], 0, "HelloWorld_Workflow") 165 166 historyIterator := &historyIteratorImpl{ 167 iteratorFunc: func(nextToken []byte) (*m.History, []byte, error) { 168 return &m.History{ 169 Events: testEvents[3:], 170 }, nil, nil 171 }, 172 nextPageToken: []byte("test"), 173 } 174 175 workflowTask := &workflowTask{task: task, historyIterator: historyIterator} 176 177 eh := newHistory(workflowTask, nil) 178 179 events, _, _, err := eh.NextDecisionEvents() 180 181 s.NoError(err) 182 s.Equal(3, len(events)) 183 s.Equal(m.EventTypeWorkflowExecutionSignaled, events[1].GetEventType()) 184 s.Equal(m.EventTypeDecisionTaskStarted, events[2].GetEventType()) 185 s.Equal(int64(7), events[2].GetEventId()) 186 }