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  }