go.temporal.io/server@v1.23.0/common/persistence/sql/sqlplugin/tests/history_replication_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 "math/rand" 29 "testing" 30 31 "github.com/stretchr/testify/require" 32 "github.com/stretchr/testify/suite" 33 34 "go.temporal.io/server/common/persistence/sql/sqlplugin" 35 "go.temporal.io/server/common/shuffle" 36 ) 37 38 type ( 39 historyHistoryReplicationTaskSuite struct { 40 suite.Suite 41 *require.Assertions 42 43 store sqlplugin.HistoryReplicationTask 44 } 45 ) 46 47 const ( 48 testHistoryReplicationTaskEncoding = "random encoding" 49 ) 50 51 var ( 52 testHistoryReplicationTaskData = []byte("random history replication task data") 53 ) 54 55 func NewHistoryReplicationTaskSuite( 56 t *testing.T, 57 store sqlplugin.HistoryReplicationTask, 58 ) *historyHistoryReplicationTaskSuite { 59 return &historyHistoryReplicationTaskSuite{ 60 Assertions: require.New(t), 61 store: store, 62 } 63 } 64 65 func (s *historyHistoryReplicationTaskSuite) SetupSuite() { 66 67 } 68 69 func (s *historyHistoryReplicationTaskSuite) TearDownSuite() { 70 71 } 72 73 func (s *historyHistoryReplicationTaskSuite) SetupTest() { 74 s.Assertions = require.New(s.T()) 75 } 76 77 func (s *historyHistoryReplicationTaskSuite) TearDownTest() { 78 79 } 80 81 func (s *historyHistoryReplicationTaskSuite) TestInsert_Single_Success() { 82 shardID := rand.Int31() 83 taskID := int64(1) 84 85 task := s.newRandomReplicationTaskRow(shardID, taskID) 86 result, err := s.store.InsertIntoReplicationTasks(newExecutionContext(), []sqlplugin.ReplicationTasksRow{task}) 87 s.NoError(err) 88 rowsAffected, err := result.RowsAffected() 89 s.NoError(err) 90 s.Equal(1, int(rowsAffected)) 91 } 92 93 func (s *historyHistoryReplicationTaskSuite) TestInsert_Multiple_Success() { 94 shardID := rand.Int31() 95 taskID := int64(1) 96 97 task1 := s.newRandomReplicationTaskRow(shardID, taskID) 98 taskID++ 99 task2 := s.newRandomReplicationTaskRow(shardID, taskID) 100 result, err := s.store.InsertIntoReplicationTasks(newExecutionContext(), []sqlplugin.ReplicationTasksRow{task1, task2}) 101 s.NoError(err) 102 rowsAffected, err := result.RowsAffected() 103 s.NoError(err) 104 s.Equal(2, int(rowsAffected)) 105 } 106 107 func (s *historyHistoryReplicationTaskSuite) TestInsert_Single_Fail_Duplicate() { 108 shardID := rand.Int31() 109 taskID := int64(1) 110 111 task := s.newRandomReplicationTaskRow(shardID, taskID) 112 result, err := s.store.InsertIntoReplicationTasks(newExecutionContext(), []sqlplugin.ReplicationTasksRow{task}) 113 s.NoError(err) 114 rowsAffected, err := result.RowsAffected() 115 s.NoError(err) 116 s.Equal(1, int(rowsAffected)) 117 118 task = s.newRandomReplicationTaskRow(shardID, taskID) 119 _, err = s.store.InsertIntoReplicationTasks(newExecutionContext(), []sqlplugin.ReplicationTasksRow{task}) 120 s.Error(err) // TODO persistence layer should do proper error translation 121 } 122 123 func (s *historyHistoryReplicationTaskSuite) TestInsert_Multiple_Fail_Duplicate() { 124 shardID := rand.Int31() 125 taskID := int64(1) 126 127 task1 := s.newRandomReplicationTaskRow(shardID, taskID) 128 taskID++ 129 task2 := s.newRandomReplicationTaskRow(shardID, taskID) 130 result, err := s.store.InsertIntoReplicationTasks(newExecutionContext(), []sqlplugin.ReplicationTasksRow{task1, task2}) 131 s.NoError(err) 132 rowsAffected, err := result.RowsAffected() 133 s.NoError(err) 134 s.Equal(2, int(rowsAffected)) 135 136 task2 = s.newRandomReplicationTaskRow(shardID, taskID) 137 taskID++ 138 task3 := s.newRandomReplicationTaskRow(shardID, taskID) 139 _, err = s.store.InsertIntoReplicationTasks(newExecutionContext(), []sqlplugin.ReplicationTasksRow{task2, task3}) 140 s.Error(err) // TODO persistence layer should do proper error translation 141 } 142 143 func (s *historyHistoryReplicationTaskSuite) TestInsertSelect_Single() { 144 shardID := rand.Int31() 145 taskID := int64(1) 146 147 task := s.newRandomReplicationTaskRow(shardID, taskID) 148 result, err := s.store.InsertIntoReplicationTasks(newExecutionContext(), []sqlplugin.ReplicationTasksRow{task}) 149 s.NoError(err) 150 rowsAffected, err := result.RowsAffected() 151 s.NoError(err) 152 s.Equal(1, int(rowsAffected)) 153 154 rangeFilter := sqlplugin.ReplicationTasksRangeFilter{ 155 ShardID: shardID, 156 InclusiveMinTaskID: taskID, 157 ExclusiveMaxTaskID: taskID + 1, 158 PageSize: 1, 159 } 160 rows, err := s.store.RangeSelectFromReplicationTasks(newExecutionContext(), rangeFilter) 161 s.NoError(err) 162 for index := range rows { 163 rows[index].ShardID = shardID 164 } 165 s.Equal([]sqlplugin.ReplicationTasksRow{task}, rows) 166 } 167 168 func (s *historyHistoryReplicationTaskSuite) TestInsertSelect_Multiple() { 169 numTasks := 20 170 pageSize := numTasks * 2 171 172 shardID := rand.Int31() 173 minTaskID := int64(1) 174 taskID := minTaskID 175 maxTaskID := taskID + int64(numTasks) 176 177 var tasks []sqlplugin.ReplicationTasksRow 178 for i := 0; i < numTasks; i++ { 179 task := s.newRandomReplicationTaskRow(shardID, taskID) 180 taskID++ 181 tasks = append(tasks, task) 182 } 183 result, err := s.store.InsertIntoReplicationTasks(newExecutionContext(), tasks) 184 s.NoError(err) 185 rowsAffected, err := result.RowsAffected() 186 s.NoError(err) 187 s.Equal(numTasks, int(rowsAffected)) 188 189 filter := sqlplugin.ReplicationTasksRangeFilter{ 190 ShardID: shardID, 191 InclusiveMinTaskID: minTaskID, 192 ExclusiveMaxTaskID: maxTaskID, 193 PageSize: pageSize, 194 } 195 rows, err := s.store.RangeSelectFromReplicationTasks(newExecutionContext(), filter) 196 s.NoError(err) 197 for index := range rows { 198 rows[index].ShardID = shardID 199 } 200 s.Equal(tasks, rows) 201 } 202 203 func (s *historyHistoryReplicationTaskSuite) TestDeleteSelect_Single() { 204 shardID := rand.Int31() 205 taskID := int64(1) 206 207 filter := sqlplugin.ReplicationTasksFilter{ 208 ShardID: shardID, 209 TaskID: taskID, 210 } 211 result, err := s.store.DeleteFromReplicationTasks(newExecutionContext(), filter) 212 s.NoError(err) 213 rowsAffected, err := result.RowsAffected() 214 s.NoError(err) 215 s.Equal(0, int(rowsAffected)) 216 217 rangeFilter := sqlplugin.ReplicationTasksRangeFilter{ 218 ShardID: shardID, 219 InclusiveMinTaskID: taskID, 220 ExclusiveMaxTaskID: taskID + 1, 221 PageSize: 1, 222 } 223 rows, err := s.store.RangeSelectFromReplicationTasks(newExecutionContext(), rangeFilter) 224 s.NoError(err) 225 for index := range rows { 226 rows[index].ShardID = shardID 227 } 228 s.Equal([]sqlplugin.ReplicationTasksRow(nil), rows) 229 } 230 231 func (s *historyHistoryReplicationTaskSuite) TestDeleteSelect_Multiple() { 232 shardID := rand.Int31() 233 minTaskID := int64(1) 234 maxTaskID := int64(101) 235 236 filter := sqlplugin.ReplicationTasksRangeFilter{ 237 ShardID: shardID, 238 InclusiveMinTaskID: minTaskID, 239 ExclusiveMaxTaskID: maxTaskID, 240 PageSize: 0, 241 } 242 result, err := s.store.RangeDeleteFromReplicationTasks(newExecutionContext(), filter) 243 s.NoError(err) 244 rowsAffected, err := result.RowsAffected() 245 s.NoError(err) 246 s.Equal(0, int(rowsAffected)) 247 248 rows, err := s.store.RangeSelectFromReplicationTasks(newExecutionContext(), filter) 249 s.NoError(err) 250 for index := range rows { 251 rows[index].ShardID = shardID 252 } 253 s.Equal([]sqlplugin.ReplicationTasksRow(nil), rows) 254 } 255 256 func (s *historyHistoryReplicationTaskSuite) TestInsertDeleteSelect_Single() { 257 shardID := rand.Int31() 258 taskID := int64(1) 259 260 task := s.newRandomReplicationTaskRow(shardID, taskID) 261 result, err := s.store.InsertIntoReplicationTasks(newExecutionContext(), []sqlplugin.ReplicationTasksRow{task}) 262 s.NoError(err) 263 rowsAffected, err := result.RowsAffected() 264 s.NoError(err) 265 s.Equal(1, int(rowsAffected)) 266 267 filter := sqlplugin.ReplicationTasksFilter{ 268 ShardID: shardID, 269 TaskID: taskID, 270 } 271 result, err = s.store.DeleteFromReplicationTasks(newExecutionContext(), filter) 272 s.NoError(err) 273 rowsAffected, err = result.RowsAffected() 274 s.NoError(err) 275 s.Equal(1, int(rowsAffected)) 276 277 rangeFilter := sqlplugin.ReplicationTasksRangeFilter{ 278 ShardID: shardID, 279 InclusiveMinTaskID: taskID, 280 ExclusiveMaxTaskID: taskID + 1, 281 PageSize: 1, 282 } 283 rows, err := s.store.RangeSelectFromReplicationTasks(newExecutionContext(), rangeFilter) 284 s.NoError(err) 285 for index := range rows { 286 rows[index].ShardID = shardID 287 } 288 s.Equal([]sqlplugin.ReplicationTasksRow(nil), rows) 289 } 290 291 func (s *historyHistoryReplicationTaskSuite) TestInsertDeleteSelect_Multiple() { 292 numTasks := 20 293 pageSize := numTasks * 2 294 295 shardID := rand.Int31() 296 minTaskID := int64(1) 297 taskID := minTaskID 298 maxTaskID := taskID + int64(numTasks) 299 300 var tasks []sqlplugin.ReplicationTasksRow 301 for i := 0; i < numTasks; i++ { 302 task := s.newRandomReplicationTaskRow(shardID, taskID) 303 taskID++ 304 tasks = append(tasks, task) 305 } 306 result, err := s.store.InsertIntoReplicationTasks(newExecutionContext(), tasks) 307 s.NoError(err) 308 rowsAffected, err := result.RowsAffected() 309 s.NoError(err) 310 s.Equal(numTasks, int(rowsAffected)) 311 312 filter := sqlplugin.ReplicationTasksRangeFilter{ 313 ShardID: shardID, 314 InclusiveMinTaskID: minTaskID, 315 ExclusiveMaxTaskID: maxTaskID, 316 PageSize: pageSize, 317 } 318 result, err = s.store.RangeDeleteFromReplicationTasks(newExecutionContext(), filter) 319 s.NoError(err) 320 rowsAffected, err = result.RowsAffected() 321 s.NoError(err) 322 s.Equal(numTasks, int(rowsAffected)) 323 324 rows, err := s.store.RangeSelectFromReplicationTasks(newExecutionContext(), filter) 325 s.NoError(err) 326 for index := range rows { 327 rows[index].ShardID = shardID 328 } 329 s.Equal([]sqlplugin.ReplicationTasksRow(nil), rows) 330 } 331 332 func (s *historyHistoryReplicationTaskSuite) newRandomReplicationTaskRow( 333 shardID int32, 334 taskID int64, 335 ) sqlplugin.ReplicationTasksRow { 336 return sqlplugin.ReplicationTasksRow{ 337 ShardID: shardID, 338 TaskID: taskID, 339 Data: shuffle.Bytes(testHistoryReplicationTaskData), 340 DataEncoding: testHistoryReplicationTaskEncoding, 341 } 342 }