go.temporal.io/server@v1.23.0/common/persistence/sql/sqlplugin/tests/matching_task_queue.go (about)

     1  // The MIT License
     2  //
     3  // Copyright (c) 2020 Temporal Technologies Inc.  All rights reserved.
     4  //
     5  // Copyright (c) 2020 Uber Technologies, Inc.
     6  //
     7  // Permission is hereby granted, free of charge, to any person obtaining a copy
     8  // of this software and associated documentation files (the "Software"), to deal
     9  // in the Software without restriction, including without limitation the rights
    10  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    11  // copies of the Software, and to permit persons to whom the Software is
    12  // furnished to do so, subject to the following conditions:
    13  //
    14  // The above copyright notice and this permission notice shall be included in
    15  // all copies or substantial portions of the Software.
    16  //
    17  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    18  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    19  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    20  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    21  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    22  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    23  // THE SOFTWARE.
    24  
    25  package tests
    26  
    27  import (
    28  	"testing"
    29  
    30  	"github.com/stretchr/testify/require"
    31  	"github.com/stretchr/testify/suite"
    32  
    33  	"go.temporal.io/server/common/convert"
    34  	"go.temporal.io/server/common/persistence/sql/sqlplugin"
    35  	"go.temporal.io/server/common/shuffle"
    36  )
    37  
    38  const (
    39  	testMatchingTaskQueueRangeHash = 42
    40  	testMatchingTaskQueueEncoding  = "random encoding"
    41  )
    42  
    43  var (
    44  	testMatchingTaskTaskQueueID   = []byte("random matching task queue")
    45  	testMatchingTaskTaskQueueData = []byte("random matching task data")
    46  )
    47  
    48  type (
    49  	matchingTaskQueueSuite struct {
    50  		suite.Suite
    51  		*require.Assertions
    52  
    53  		store sqlplugin.MatchingTaskQueue
    54  	}
    55  )
    56  
    57  // TODO SelectFromTaskQueues with RangeHashGreaterThanEqualTo / RangeHashLessThanEqualTo / TaskQueueIDGreaterThan looks weird
    58  //  need to go over the logic in matching engine
    59  
    60  func NewMatchingTaskQueueSuite(
    61  	t *testing.T,
    62  	store sqlplugin.MatchingTaskQueue,
    63  ) *matchingTaskQueueSuite {
    64  	return &matchingTaskQueueSuite{
    65  		Assertions: require.New(t),
    66  		store:      store,
    67  	}
    68  }
    69  
    70  func (s *matchingTaskQueueSuite) SetupSuite() {
    71  
    72  }
    73  
    74  func (s *matchingTaskQueueSuite) TearDownSuite() {
    75  
    76  }
    77  
    78  func (s *matchingTaskQueueSuite) SetupTest() {
    79  	s.Assertions = require.New(s.T())
    80  }
    81  
    82  func (s *matchingTaskQueueSuite) TearDownTest() {
    83  
    84  }
    85  
    86  func (s *matchingTaskQueueSuite) TestInsert_Success() {
    87  	queueID := shuffle.Bytes(testMatchingTaskTaskQueueID)
    88  	rangeID := int64(1)
    89  
    90  	taskQueue := s.newRandomTasksQueueRow(queueID, rangeID)
    91  	result, err := s.store.InsertIntoTaskQueues(newExecutionContext(), &taskQueue)
    92  	s.NoError(err)
    93  	rowsAffected, err := result.RowsAffected()
    94  	s.NoError(err)
    95  	s.Equal(1, int(rowsAffected))
    96  }
    97  
    98  func (s *matchingTaskQueueSuite) TestInsert_Fail_Duplicate() {
    99  	queueID := shuffle.Bytes(testMatchingTaskTaskQueueID)
   100  	rangeID := int64(1)
   101  
   102  	taskQueue := s.newRandomTasksQueueRow(queueID, rangeID)
   103  	result, err := s.store.InsertIntoTaskQueues(newExecutionContext(), &taskQueue)
   104  	s.NoError(err)
   105  	rowsAffected, err := result.RowsAffected()
   106  	s.NoError(err)
   107  	s.Equal(1, int(rowsAffected))
   108  
   109  	taskQueue = s.newRandomTasksQueueRow(queueID, rangeID)
   110  	_, err = s.store.InsertIntoTaskQueues(newExecutionContext(), &taskQueue)
   111  	s.Error(err) // TODO persistence layer should do proper error translation
   112  }
   113  
   114  func (s *matchingTaskQueueSuite) TestInsertSelect() {
   115  	queueID := shuffle.Bytes(testMatchingTaskTaskQueueID)
   116  	rangeID := int64(1)
   117  
   118  	taskQueue := s.newRandomTasksQueueRow(queueID, rangeID)
   119  	result, err := s.store.InsertIntoTaskQueues(newExecutionContext(), &taskQueue)
   120  	s.NoError(err)
   121  	rowsAffected, err := result.RowsAffected()
   122  	s.NoError(err)
   123  	s.Equal(1, int(rowsAffected))
   124  
   125  	filter := sqlplugin.TaskQueuesFilter{
   126  		RangeHash:   testMatchingTaskQueueRangeHash,
   127  		TaskQueueID: queueID,
   128  	}
   129  	rows, err := s.store.SelectFromTaskQueues(newExecutionContext(), filter)
   130  	s.NoError(err)
   131  	s.Equal([]sqlplugin.TaskQueuesRow{taskQueue}, rows)
   132  }
   133  
   134  func (s *matchingTaskQueueSuite) TestInsertUpdate_Success() {
   135  	queueID := shuffle.Bytes(testMatchingTaskTaskQueueID)
   136  	rangeID := int64(1)
   137  
   138  	taskQueue := s.newRandomTasksQueueRow(queueID, rangeID)
   139  	rangeID++
   140  	result, err := s.store.InsertIntoTaskQueues(newExecutionContext(), &taskQueue)
   141  	s.NoError(err)
   142  	rowsAffected, err := result.RowsAffected()
   143  	s.NoError(err)
   144  	s.Equal(1, int(rowsAffected))
   145  
   146  	taskQueue = s.newRandomTasksQueueRow(queueID, rangeID)
   147  	result, err = s.store.UpdateTaskQueues(newExecutionContext(), &taskQueue)
   148  	s.NoError(err)
   149  	rowsAffected, err = result.RowsAffected()
   150  	s.NoError(err)
   151  	s.Equal(1, int(rowsAffected))
   152  }
   153  
   154  func (s *matchingTaskQueueSuite) TestUpdate_Fail() {
   155  	queueID := shuffle.Bytes(testMatchingTaskTaskQueueID)
   156  	rangeID := int64(1)
   157  
   158  	taskQueue := s.newRandomTasksQueueRow(queueID, rangeID)
   159  	result, err := s.store.UpdateTaskQueues(newExecutionContext(), &taskQueue)
   160  	s.NoError(err)
   161  	rowsAffected, err := result.RowsAffected()
   162  	s.NoError(err)
   163  	s.Equal(0, int(rowsAffected))
   164  }
   165  
   166  func (s *matchingTaskQueueSuite) TestInsertUpdateSelect() {
   167  	queueID := shuffle.Bytes(testMatchingTaskTaskQueueID)
   168  	rangeID := int64(1)
   169  
   170  	taskQueue := s.newRandomTasksQueueRow(queueID, rangeID)
   171  	rangeID++
   172  	result, err := s.store.InsertIntoTaskQueues(newExecutionContext(), &taskQueue)
   173  	s.NoError(err)
   174  	rowsAffected, err := result.RowsAffected()
   175  	s.NoError(err)
   176  	s.Equal(1, int(rowsAffected))
   177  
   178  	taskQueue = s.newRandomTasksQueueRow(queueID, rangeID)
   179  	result, err = s.store.UpdateTaskQueues(newExecutionContext(), &taskQueue)
   180  	s.NoError(err)
   181  	rowsAffected, err = result.RowsAffected()
   182  	s.NoError(err)
   183  	s.Equal(1, int(rowsAffected))
   184  
   185  	filter := sqlplugin.TaskQueuesFilter{
   186  		RangeHash:   testMatchingTaskQueueRangeHash,
   187  		TaskQueueID: queueID,
   188  	}
   189  	rows, err := s.store.SelectFromTaskQueues(newExecutionContext(), filter)
   190  	s.NoError(err)
   191  	s.Equal([]sqlplugin.TaskQueuesRow{taskQueue}, rows)
   192  }
   193  
   194  func (s *matchingTaskQueueSuite) TestDeleteSelect() {
   195  	queueID := shuffle.Bytes(testMatchingTaskTaskQueueID)
   196  	rangeID := int64(1)
   197  
   198  	filter := sqlplugin.TaskQueuesFilter{
   199  		RangeHash:   testMatchingTaskQueueRangeHash,
   200  		TaskQueueID: queueID,
   201  		RangeID:     convert.Int64Ptr(rangeID),
   202  	}
   203  	result, err := s.store.DeleteFromTaskQueues(newExecutionContext(), filter)
   204  	s.NoError(err)
   205  	rowsAffected, err := result.RowsAffected()
   206  	s.NoError(err)
   207  	s.Equal(0, int(rowsAffected))
   208  
   209  	filter = sqlplugin.TaskQueuesFilter{
   210  		RangeHash:   testMatchingTaskQueueRangeHash,
   211  		TaskQueueID: queueID,
   212  	}
   213  	// TODO the behavior is weird
   214  	_, err = s.store.SelectFromTaskQueues(newExecutionContext(), filter)
   215  	s.Error(err) // TODO persistence layer should do proper error translation
   216  }
   217  
   218  func (s *matchingTaskQueueSuite) TestInsertDeleteSelect_Success() {
   219  	queueID := shuffle.Bytes(testMatchingTaskTaskQueueID)
   220  	rangeID := int64(1)
   221  
   222  	taskQueue := s.newRandomTasksQueueRow(queueID, rangeID)
   223  	result, err := s.store.InsertIntoTaskQueues(newExecutionContext(), &taskQueue)
   224  	s.NoError(err)
   225  	rowsAffected, err := result.RowsAffected()
   226  	s.NoError(err)
   227  	s.Equal(1, int(rowsAffected))
   228  
   229  	filter := sqlplugin.TaskQueuesFilter{
   230  		RangeHash:   testMatchingTaskQueueRangeHash,
   231  		TaskQueueID: queueID,
   232  		RangeID:     convert.Int64Ptr(rangeID),
   233  	}
   234  	result, err = s.store.DeleteFromTaskQueues(newExecutionContext(), filter)
   235  	s.NoError(err)
   236  	rowsAffected, err = result.RowsAffected()
   237  	s.NoError(err)
   238  	s.Equal(1, int(rowsAffected))
   239  
   240  	filter = sqlplugin.TaskQueuesFilter{
   241  		RangeHash:   testMatchingTaskQueueRangeHash,
   242  		TaskQueueID: queueID,
   243  	}
   244  	rows, err := s.store.SelectFromTaskQueues(newExecutionContext(), filter)
   245  	s.Error(err) // TODO persistence layer should do proper error translation
   246  	s.Nil(rows)
   247  }
   248  
   249  func (s *matchingTaskQueueSuite) TestInsertDeleteSelect_Fail() {
   250  	queueID := shuffle.Bytes(testMatchingTaskTaskQueueID)
   251  	rangeID := int64(1)
   252  
   253  	taskQueue := s.newRandomTasksQueueRow(queueID, rangeID)
   254  	result, err := s.store.InsertIntoTaskQueues(newExecutionContext(), &taskQueue)
   255  	s.NoError(err)
   256  	rowsAffected, err := result.RowsAffected()
   257  	s.NoError(err)
   258  	s.Equal(1, int(rowsAffected))
   259  
   260  	filter := sqlplugin.TaskQueuesFilter{
   261  		RangeHash:   testMatchingTaskQueueRangeHash,
   262  		TaskQueueID: queueID,
   263  		RangeID:     convert.Int64Ptr(rangeID + 1),
   264  	}
   265  	result, err = s.store.DeleteFromTaskQueues(newExecutionContext(), filter)
   266  	s.NoError(err)
   267  	rowsAffected, err = result.RowsAffected()
   268  	s.NoError(err)
   269  	s.Equal(0, int(rowsAffected))
   270  
   271  	filter = sqlplugin.TaskQueuesFilter{
   272  		RangeHash:   testMatchingTaskQueueRangeHash,
   273  		TaskQueueID: queueID,
   274  	}
   275  	rows, err := s.store.SelectFromTaskQueues(newExecutionContext(), filter)
   276  	s.NoError(err)
   277  	s.Equal([]sqlplugin.TaskQueuesRow{taskQueue}, rows)
   278  }
   279  
   280  func (s *matchingTaskQueueSuite) TestInsertLock() {
   281  	queueID := shuffle.Bytes(testMatchingTaskTaskQueueID)
   282  	rangeID := int64(2)
   283  
   284  	taskQueue := s.newRandomTasksQueueRow(queueID, rangeID)
   285  	result, err := s.store.InsertIntoTaskQueues(newExecutionContext(), &taskQueue)
   286  	s.NoError(err)
   287  	rowsAffected, err := result.RowsAffected()
   288  	s.NoError(err)
   289  	s.Equal(1, int(rowsAffected))
   290  
   291  	// NOTE: lock without transaction is equivalent to select
   292  	//  this test only test the select functionality
   293  	filter := sqlplugin.TaskQueuesFilter{
   294  		RangeHash:   testMatchingTaskQueueRangeHash,
   295  		TaskQueueID: queueID,
   296  	}
   297  	rangeIDInDB, err := s.store.LockTaskQueues(newExecutionContext(), filter)
   298  	s.NoError(err)
   299  	s.Equal(rangeID, rangeIDInDB)
   300  }
   301  
   302  func (s *matchingTaskQueueSuite) newRandomTasksQueueRow(
   303  	queueID []byte,
   304  	rangeID int64,
   305  ) sqlplugin.TaskQueuesRow {
   306  	return sqlplugin.TaskQueuesRow{
   307  		RangeHash:    testMatchingTaskQueueRangeHash,
   308  		TaskQueueID:  queueID,
   309  		RangeID:      rangeID,
   310  		Data:         shuffle.Bytes(testMatchingTaskTaskQueueData),
   311  		DataEncoding: testMatchingTaskQueueEncoding,
   312  	}
   313  }