go.temporal.io/server@v1.23.0/common/persistence/sql/sqlplugin/tests/matching_task.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 testMatchingTaskRangeHash = 42 40 testMatchingTaskEncoding = "random encoding" 41 ) 42 43 var ( 44 testMatchingTaskTaskData = []byte("random matching task data") 45 ) 46 47 type ( 48 matchingTaskSuite struct { 49 suite.Suite 50 *require.Assertions 51 52 store sqlplugin.MatchingTask 53 } 54 ) 55 56 func NewMatchingTaskSuite( 57 t *testing.T, 58 store sqlplugin.MatchingTask, 59 ) *matchingTaskSuite { 60 return &matchingTaskSuite{ 61 Assertions: require.New(t), 62 store: store, 63 } 64 } 65 66 func (s *matchingTaskSuite) SetupSuite() { 67 68 } 69 70 func (s *matchingTaskSuite) TearDownSuite() { 71 72 } 73 74 func (s *matchingTaskSuite) SetupTest() { 75 s.Assertions = require.New(s.T()) 76 } 77 78 func (s *matchingTaskSuite) TearDownTest() { 79 80 } 81 82 func (s *matchingTaskSuite) TestInsert_Single_Success() { 83 queueID := shuffle.Bytes(testMatchingTaskTaskQueueID) 84 taskID := int64(1) 85 86 task := s.newRandomTasksRow(queueID, taskID) 87 result, err := s.store.InsertIntoTasks(newExecutionContext(), []sqlplugin.TasksRow{task}) 88 s.NoError(err) 89 rowsAffected, err := result.RowsAffected() 90 s.NoError(err) 91 s.Equal(1, int(rowsAffected)) 92 } 93 94 func (s *matchingTaskSuite) TestInsert_Multiple_Success() { 95 queueID := shuffle.Bytes(testMatchingTaskTaskQueueID) 96 taskID := int64(1) 97 98 task1 := s.newRandomTasksRow(queueID, taskID) 99 taskID++ 100 task2 := s.newRandomTasksRow(queueID, taskID) 101 taskID++ 102 result, err := s.store.InsertIntoTasks(newExecutionContext(), []sqlplugin.TasksRow{task1, task2}) 103 s.NoError(err) 104 rowsAffected, err := result.RowsAffected() 105 s.NoError(err) 106 s.Equal(2, int(rowsAffected)) 107 } 108 109 func (s *matchingTaskSuite) TestInsert_Single_Fail_Duplicate() { 110 queueID := shuffle.Bytes(testMatchingTaskTaskQueueID) 111 taskID := int64(1) 112 113 task := s.newRandomTasksRow(queueID, taskID) 114 result, err := s.store.InsertIntoTasks(newExecutionContext(), []sqlplugin.TasksRow{task}) 115 s.NoError(err) 116 rowsAffected, err := result.RowsAffected() 117 s.NoError(err) 118 s.Equal(1, int(rowsAffected)) 119 120 task = s.newRandomTasksRow(queueID, taskID) 121 _, err = s.store.InsertIntoTasks(newExecutionContext(), []sqlplugin.TasksRow{task}) 122 s.Error(err) // TODO persistence layer should do proper error translation 123 } 124 125 func (s *matchingTaskSuite) TestInsert_Multiple_Fail_Duplicate() { 126 queueID := shuffle.Bytes(testMatchingTaskTaskQueueID) 127 taskID := int64(1) 128 129 task1 := s.newRandomTasksRow(queueID, taskID) 130 taskID++ 131 task2 := s.newRandomTasksRow(queueID, taskID) 132 result, err := s.store.InsertIntoTasks(newExecutionContext(), []sqlplugin.TasksRow{task1, task2}) 133 s.NoError(err) 134 rowsAffected, err := result.RowsAffected() 135 s.NoError(err) 136 s.Equal(2, int(rowsAffected)) 137 138 task2 = s.newRandomTasksRow(queueID, taskID) 139 taskID++ 140 task3 := s.newRandomTasksRow(queueID, taskID) 141 _, err = s.store.InsertIntoTasks(newExecutionContext(), []sqlplugin.TasksRow{task2, task3}) 142 s.Error(err) // TODO persistence layer should do proper error translation 143 } 144 145 func (s *matchingTaskSuite) TestInsertSelect_Single() { 146 queueID := shuffle.Bytes(testMatchingTaskTaskQueueID) 147 taskID := int64(100) 148 149 task := s.newRandomTasksRow(queueID, taskID) 150 result, err := s.store.InsertIntoTasks(newExecutionContext(), []sqlplugin.TasksRow{task}) 151 s.NoError(err) 152 rowsAffected, err := result.RowsAffected() 153 s.NoError(err) 154 s.Equal(1, int(rowsAffected)) 155 156 inclusiveMinTaskID := convert.Int64Ptr(taskID) 157 exclusiveMaxTaskID := convert.Int64Ptr(taskID + 1) 158 pageSize := convert.IntPtr(1) 159 filter := sqlplugin.TasksFilter{ 160 RangeHash: testMatchingTaskRangeHash, 161 TaskQueueID: queueID, 162 InclusiveMinTaskID: inclusiveMinTaskID, 163 ExclusiveMaxTaskID: exclusiveMaxTaskID, 164 PageSize: pageSize, 165 } 166 rows, err := s.store.SelectFromTasks(newExecutionContext(), filter) 167 s.NoError(err) 168 // fill in some omitted info 169 for index := range rows { 170 rows[index].RangeHash = testMatchingTaskRangeHash 171 rows[index].TaskQueueID = queueID 172 } 173 s.Equal([]sqlplugin.TasksRow{task}, rows) 174 } 175 176 func (s *matchingTaskSuite) TestInsertSelect_Multiple() { 177 queueID := shuffle.Bytes(testMatchingTaskTaskQueueID) 178 taskID := int64(100) 179 180 task1 := s.newRandomTasksRow(queueID, taskID) 181 taskID++ 182 task2 := s.newRandomTasksRow(queueID, taskID) 183 result, err := s.store.InsertIntoTasks(newExecutionContext(), []sqlplugin.TasksRow{task1, task2}) 184 s.NoError(err) 185 rowsAffected, err := result.RowsAffected() 186 s.NoError(err) 187 s.Equal(2, int(rowsAffected)) 188 189 inclusiveMinTaskID := convert.Int64Ptr(taskID - 1) 190 exclusiveMaxTaskID := convert.Int64Ptr(taskID + 1) 191 pageSize := convert.IntPtr(2) 192 filter := sqlplugin.TasksFilter{ 193 RangeHash: testMatchingTaskRangeHash, 194 TaskQueueID: queueID, 195 InclusiveMinTaskID: inclusiveMinTaskID, 196 ExclusiveMaxTaskID: exclusiveMaxTaskID, 197 PageSize: pageSize, 198 } 199 rows, err := s.store.SelectFromTasks(newExecutionContext(), filter) 200 s.NoError(err) 201 // fill in some omitted info 202 for index := range rows { 203 rows[index].RangeHash = testMatchingTaskRangeHash 204 rows[index].TaskQueueID = queueID 205 } 206 s.Equal([]sqlplugin.TasksRow{task1, task2}, rows) 207 } 208 209 func (s *matchingTaskSuite) TestDeleteSelect() { 210 queueID := shuffle.Bytes(testMatchingTaskTaskQueueID) 211 taskID := int64(100) 212 213 filter := sqlplugin.TasksFilter{ 214 RangeHash: testMatchingTaskRangeHash, 215 TaskQueueID: queueID, 216 TaskID: convert.Int64Ptr(taskID), 217 } 218 result, err := s.store.DeleteFromTasks(newExecutionContext(), filter) 219 s.NoError(err) 220 rowsAffected, err := result.RowsAffected() 221 s.NoError(err) 222 s.Equal(0, int(rowsAffected)) 223 } 224 225 func (s *matchingTaskSuite) TestInsertDeleteSelect_Single() { 226 queueID := shuffle.Bytes(testMatchingTaskTaskQueueID) 227 taskID := int64(100) 228 229 task := s.newRandomTasksRow(queueID, taskID) 230 result, err := s.store.InsertIntoTasks(newExecutionContext(), []sqlplugin.TasksRow{task}) 231 s.NoError(err) 232 rowsAffected, err := result.RowsAffected() 233 s.NoError(err) 234 s.Equal(1, int(rowsAffected)) 235 236 filter := sqlplugin.TasksFilter{ 237 RangeHash: testMatchingTaskRangeHash, 238 TaskQueueID: queueID, 239 TaskID: convert.Int64Ptr(taskID), 240 } 241 result, err = s.store.DeleteFromTasks(newExecutionContext(), filter) 242 s.NoError(err) 243 rowsAffected, err = result.RowsAffected() 244 s.NoError(err) 245 s.Equal(1, int(rowsAffected)) 246 247 inclusiveMinTaskID := convert.Int64Ptr(taskID) 248 exclusiveMaxTaskID := convert.Int64Ptr(taskID + 1) 249 pageSize := convert.IntPtr(1) 250 filter = sqlplugin.TasksFilter{ 251 RangeHash: testMatchingTaskRangeHash, 252 TaskQueueID: queueID, 253 InclusiveMinTaskID: inclusiveMinTaskID, 254 ExclusiveMaxTaskID: exclusiveMaxTaskID, 255 PageSize: pageSize, 256 } 257 rows, err := s.store.SelectFromTasks(newExecutionContext(), filter) 258 s.NoError(err) 259 s.Equal([]sqlplugin.TasksRow(nil), rows) 260 } 261 262 func (s *matchingTaskSuite) TestInsertDeleteSelect_Multiple() { 263 queueID := shuffle.Bytes(testMatchingTaskTaskQueueID) 264 taskID := int64(100) 265 266 task1 := s.newRandomTasksRow(queueID, taskID) 267 taskID++ 268 task2 := s.newRandomTasksRow(queueID, taskID) 269 result, err := s.store.InsertIntoTasks(newExecutionContext(), []sqlplugin.TasksRow{task1, task2}) 270 s.NoError(err) 271 rowsAffected, err := result.RowsAffected() 272 s.NoError(err) 273 s.Equal(2, int(rowsAffected)) 274 275 filter := sqlplugin.TasksFilter{ 276 RangeHash: testMatchingTaskRangeHash, 277 TaskQueueID: queueID, 278 ExclusiveMaxTaskID: convert.Int64Ptr(taskID + 1), 279 Limit: convert.IntPtr(2), 280 } 281 result, err = s.store.DeleteFromTasks(newExecutionContext(), filter) 282 s.NoError(err) 283 rowsAffected, err = result.RowsAffected() 284 s.NoError(err) 285 s.Equal(2, int(rowsAffected)) 286 287 inclusiveMinTaskID := convert.Int64Ptr(taskID - 1) 288 exclusiveMaxTaskID := convert.Int64Ptr(taskID + 1) 289 pageSize := convert.IntPtr(2) 290 filter = sqlplugin.TasksFilter{ 291 RangeHash: testMatchingTaskRangeHash, 292 TaskQueueID: queueID, 293 InclusiveMinTaskID: inclusiveMinTaskID, 294 ExclusiveMaxTaskID: exclusiveMaxTaskID, 295 PageSize: pageSize, 296 } 297 rows, err := s.store.SelectFromTasks(newExecutionContext(), filter) 298 s.NoError(err) 299 s.Equal([]sqlplugin.TasksRow(nil), rows) 300 } 301 302 func (s *matchingTaskSuite) newRandomTasksRow( 303 queueID []byte, 304 taskID int64, 305 ) sqlplugin.TasksRow { 306 return sqlplugin.TasksRow{ 307 RangeHash: testMatchingTaskRangeHash, 308 TaskQueueID: queueID, 309 TaskID: taskID, 310 Data: shuffle.Bytes(testMatchingTaskTaskData), 311 DataEncoding: testMatchingTaskEncoding, 312 } 313 }