go.uber.org/cadence@v1.2.9/internal/query_builder_test.go (about)

     1  // Copyright (c) 2017-2021 Uber Technologies Inc.
     2  //
     3  // Permission is hereby granted, free of charge, to any person obtaining a copy
     4  // of this software and associated documentation files (the "Software"), to deal
     5  // in the Software without restriction, including without limitation the rights
     6  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     7  // copies of the Software, and to permit persons to whom the Software is
     8  // furnished to do so, subject to the following conditions:
     9  //
    10  // The above copyright notice and this permission notice shall be included in
    11  // all copies or substantial portions of the Software.
    12  //
    13  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    14  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    15  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    16  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    17  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    18  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    19  // THE SOFTWARE.
    20  
    21  package internal
    22  
    23  import (
    24  	"fmt"
    25  	"testing"
    26  	"time"
    27  
    28  	"github.com/stretchr/testify/require"
    29  	"github.com/stretchr/testify/suite"
    30  )
    31  
    32  type queryBuilderSuite struct {
    33  	*require.Assertions
    34  	suite.Suite
    35  }
    36  
    37  func TestQueryBuilderSuite(t *testing.T) {
    38  	s := new(queryBuilderSuite)
    39  	suite.Run(t, s)
    40  }
    41  
    42  func (s *queryBuilderSuite) SetupTest() {
    43  	s.Assertions = require.New(s.T())
    44  }
    45  
    46  func (s *queryBuilderSuite) TestWorkflowTypeQuery() {
    47  	testCases := []struct {
    48  		msg           string
    49  		workflowTypes []string
    50  		expectedQuery string
    51  	}{
    52  		{
    53  			msg:           "empty workflowTypes",
    54  			workflowTypes: nil,
    55  			expectedQuery: "",
    56  		},
    57  		{
    58  			msg:           "single workflowType",
    59  			workflowTypes: []string{"testWorkflowType"},
    60  			expectedQuery: `(WorkflowType = "testWorkflowType")`,
    61  		},
    62  		{
    63  			msg:           "multiple workflowTypes",
    64  			workflowTypes: []string{"testWorkflowType1", "testWorkflowType2"},
    65  			expectedQuery: `(WorkflowType = "testWorkflowType1" or WorkflowType = "testWorkflowType2")`,
    66  		},
    67  	}
    68  
    69  	for _, test := range testCases {
    70  		s.T().Run(test.msg, func(t *testing.T) {
    71  			builder := NewQueryBuilder()
    72  			builder.WorkflowTypes(test.workflowTypes)
    73  			s.Equal(test.expectedQuery, builder.Build())
    74  		})
    75  	}
    76  }
    77  
    78  func (s *queryBuilderSuite) TestWorkflowStatusQuery() {
    79  	testCases := []struct {
    80  		msg              string
    81  		workflowStatuses []WorkflowStatus
    82  		expectedQuery    string
    83  	}{
    84  		{
    85  			msg:              "empty workflow status",
    86  			workflowStatuses: []WorkflowStatus{},
    87  			expectedQuery:    "",
    88  		},
    89  		{
    90  			msg:              "open workflow",
    91  			workflowStatuses: []WorkflowStatus{WorkflowStatusOpen},
    92  			expectedQuery:    "(CloseTime = missing)",
    93  		},
    94  		{
    95  			msg:              "closed workflow",
    96  			workflowStatuses: []WorkflowStatus{WorkflowStatusClosed},
    97  			expectedQuery:    "(CloseTime != missing)",
    98  		},
    99  		{
   100  			msg:              "multiple workflow statuses",
   101  			workflowStatuses: []WorkflowStatus{WorkflowStatusFailed, WorkflowStatusTimedOut},
   102  			expectedQuery:    `(CloseStatus = "FAILED" or CloseStatus = "TIMED_OUT")`,
   103  		},
   104  		{
   105  			msg:              "all workflows",
   106  			workflowStatuses: []WorkflowStatus{WorkflowStatusTerminated, WorkflowStatusALL},
   107  			expectedQuery:    "",
   108  		},
   109  	}
   110  
   111  	for _, test := range testCases {
   112  		s.T().Run(test.msg, func(t *testing.T) {
   113  			builder := NewQueryBuilder()
   114  			builder.WorkflowStatus(test.workflowStatuses)
   115  			s.Equal(test.expectedQuery, builder.Build())
   116  		})
   117  	}
   118  }
   119  
   120  func (s *queryBuilderSuite) TestStartTimeQuery() {
   121  	testTimestamp := time.Now()
   122  	testCases := []struct {
   123  		msg           string
   124  		minStartTime  time.Time
   125  		maxStartTime  time.Time
   126  		expectedQuery string
   127  	}{
   128  		{
   129  			msg:           "empty minTimestamp",
   130  			maxStartTime:  testTimestamp,
   131  			expectedQuery: fmt.Sprintf("(StartTime <= %v)", testTimestamp.UnixNano()),
   132  		},
   133  		{
   134  			msg:           "max maxTimestamp",
   135  			minStartTime:  testTimestamp,
   136  			maxStartTime:  maxTimestamp,
   137  			expectedQuery: fmt.Sprintf("(StartTime >= %v)", testTimestamp.UnixNano()),
   138  		},
   139  		{
   140  			msg:           "both timestamps are used",
   141  			minStartTime:  testTimestamp.Add(-time.Hour),
   142  			maxStartTime:  testTimestamp,
   143  			expectedQuery: fmt.Sprintf("(StartTime >= %v and StartTime <= %v)", testTimestamp.Add(-time.Hour).UnixNano(), testTimestamp.UnixNano()),
   144  		},
   145  	}
   146  
   147  	for _, test := range testCases {
   148  		s.T().Run(test.msg, func(t *testing.T) {
   149  			builder := NewQueryBuilder()
   150  			builder.StartTime(test.minStartTime, test.maxStartTime)
   151  			s.Equal(test.expectedQuery, builder.Build())
   152  		})
   153  	}
   154  }
   155  
   156  func (s *queryBuilderSuite) TestMultipleFilters() {
   157  	maxStartTime := time.Now()
   158  	minStartTime := maxStartTime.Add(-time.Hour)
   159  
   160  	builder := NewQueryBuilder().
   161  		WorkflowTypes([]string{"testWorkflowType1", "testWorkflowType2"}).
   162  		WorkflowStatus([]WorkflowStatus{WorkflowStatusOpen}).
   163  		StartTime(minStartTime, maxStartTime)
   164  
   165  	expectedQuery := fmt.Sprintf(`(WorkflowType = "testWorkflowType1" or WorkflowType = "testWorkflowType2") and (CloseTime = missing) and (StartTime >= %v and StartTime <= %v)`,
   166  		minStartTime.UnixNano(),
   167  		maxStartTime.UnixNano(),
   168  	)
   169  	s.Equal(expectedQuery, builder.Build())
   170  }
   171  
   172  func (s *queryBuilderSuite) TestToWorkflowStatus() {
   173  	testCases := []struct {
   174  		msg            string
   175  		statusString   string
   176  		expectErr      bool
   177  		expectedStatus WorkflowStatus
   178  	}{
   179  		{
   180  			msg:          "unknown status",
   181  			statusString: "unknown",
   182  			expectErr:    true,
   183  		},
   184  		{
   185  			msg:            "lower case status string",
   186  			statusString:   "open",
   187  			expectErr:      false,
   188  			expectedStatus: WorkflowStatusOpen,
   189  		},
   190  		{
   191  			msg:            "mixed case status string",
   192  			statusString:   "Timed_Out",
   193  			expectErr:      false,
   194  			expectedStatus: WorkflowStatusTimedOut,
   195  		},
   196  		{
   197  			msg:            "upper case status string",
   198  			statusString:   "TERMINATED",
   199  			expectErr:      false,
   200  			expectedStatus: WorkflowStatusTerminated,
   201  		},
   202  		{
   203  			msg:            "all",
   204  			statusString:   "ALL",
   205  			expectErr:      false,
   206  			expectedStatus: WorkflowStatusALL,
   207  		},
   208  		{
   209  			msg:            "closed",
   210  			statusString:   "CLOSED",
   211  			expectErr:      false,
   212  			expectedStatus: WorkflowStatusClosed,
   213  		},
   214  		{
   215  			msg:            "failed",
   216  			statusString:   "FAILED",
   217  			expectErr:      false,
   218  			expectedStatus: WorkflowStatusFailed,
   219  		},
   220  		{
   221  			msg:            "completed",
   222  			statusString:   "COMPLETED",
   223  			expectErr:      false,
   224  			expectedStatus: WorkflowStatusCompleted,
   225  		},
   226  		{
   227  			msg:            "canceled",
   228  			statusString:   "CANCELED",
   229  			expectErr:      false,
   230  			expectedStatus: WorkflowStatusCanceled,
   231  		},
   232  		{
   233  			msg:            "continued as new",
   234  			statusString:   "CONTINUED_AS_NEW",
   235  			expectErr:      false,
   236  			expectedStatus: WorkflowStatusContinuedAsNew,
   237  		},
   238  	}
   239  
   240  	for _, test := range testCases {
   241  		s.T().Run(test.msg, func(t *testing.T) {
   242  			actualStatus, err := ToWorkflowStatus(test.statusString)
   243  			if test.expectErr {
   244  				s.Error(err)
   245  				return
   246  			}
   247  
   248  			s.Equal(test.expectedStatus, actualStatus)
   249  		})
   250  	}
   251  }