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