go.temporal.io/server@v1.23.0/common/persistence/persistence-tests/queue_persistence.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 persistencetests 26 27 import ( 28 "context" 29 "fmt" 30 "sync" 31 "time" 32 33 "github.com/stretchr/testify/require" 34 35 enumsspb "go.temporal.io/server/api/enums/v1" 36 replicationspb "go.temporal.io/server/api/replication/v1" 37 "go.temporal.io/server/common/debug" 38 "go.temporal.io/server/common/persistence" 39 ) 40 41 type ( 42 // QueuePersistenceSuite contains queue persistence tests 43 QueuePersistenceSuite struct { 44 *TestBase 45 // override suite.Suite.Assertions with require.Assertions; this means that s.NotNil(nil) will stop the test, 46 // not merely log an error 47 *require.Assertions 48 49 ctx context.Context 50 cancel context.CancelFunc 51 } 52 ) 53 54 // SetupSuite implementation 55 func (s *QueuePersistenceSuite) SetupSuite() { 56 } 57 58 // SetupTest implementation 59 func (s *QueuePersistenceSuite) SetupTest() { 60 // Have to define our overridden assertions in the test setup. If we did it earlier, s.T() will return nil 61 s.Assertions = require.New(s.T()) 62 s.ctx, s.cancel = context.WithTimeout(context.Background(), 30*time.Second*debug.TimeoutMultiplier) 63 } 64 65 func (s *QueuePersistenceSuite) TearDownTest() { 66 s.cancel() 67 } 68 69 // TearDownSuite implementation 70 func (s *QueuePersistenceSuite) TearDownSuite() { 71 s.TearDownWorkflowStore() 72 } 73 74 // TestNamespaceReplicationQueue tests namespace replication queue operations 75 func (s *QueuePersistenceSuite) TestNamespaceReplicationQueue() { 76 numMessages := 100 77 concurrentSenders := 10 78 79 messageChan := make(chan *replicationspb.ReplicationTask) 80 81 taskType := enumsspb.REPLICATION_TASK_TYPE_NAMESPACE_TASK 82 go func() { 83 for i := 0; i < numMessages; i++ { 84 messageChan <- &replicationspb.ReplicationTask{ 85 TaskType: taskType, 86 Attributes: &replicationspb.ReplicationTask_NamespaceTaskAttributes{ 87 NamespaceTaskAttributes: &replicationspb.NamespaceTaskAttributes{ 88 Id: fmt.Sprintf("message-%v", i), 89 }, 90 }, 91 } 92 } 93 close(messageChan) 94 }() 95 96 wg := sync.WaitGroup{} 97 wg.Add(concurrentSenders) 98 99 for i := 0; i < concurrentSenders; i++ { 100 go func(senderNum int) { 101 defer wg.Done() 102 for message := range messageChan { 103 err := s.Publish(s.ctx, message) 104 id := message.Attributes.(*replicationspb.ReplicationTask_NamespaceTaskAttributes).NamespaceTaskAttributes.Id 105 s.Nil(err, "Enqueue message failed when sender %d tried to send %s", senderNum, id) 106 } 107 }(i) 108 } 109 110 wg.Wait() 111 112 result, lastRetrievedMessageID, err := s.GetReplicationMessages(s.ctx, persistence.EmptyQueueMessageID, numMessages) 113 s.Nil(err, "GetReplicationMessages failed.") 114 s.Len(result, numMessages) 115 s.Equal(int64(numMessages-1), lastRetrievedMessageID) 116 } 117 118 // TestQueueMetadataOperations tests queue metadata operations 119 func (s *QueuePersistenceSuite) TestQueueMetadataOperations() { 120 clusterAckLevels, err := s.GetAckLevels(s.ctx) 121 s.Require().NoError(err) 122 s.Assert().Len(clusterAckLevels, 0) 123 124 err = s.UpdateAckLevel(s.ctx, 10, "test1") 125 s.Require().NoError(err) 126 127 clusterAckLevels, err = s.GetAckLevels(s.ctx) 128 s.Require().NoError(err) 129 s.Assert().Len(clusterAckLevels, 1) 130 s.Assert().Equal(int64(10), clusterAckLevels["test1"]) 131 132 err = s.UpdateAckLevel(s.ctx, 20, "test1") 133 s.Require().NoError(err) 134 135 clusterAckLevels, err = s.GetAckLevels(s.ctx) 136 s.Require().NoError(err) 137 s.Assert().Len(clusterAckLevels, 1) 138 s.Assert().Equal(int64(20), clusterAckLevels["test1"]) 139 140 err = s.UpdateAckLevel(s.ctx, 25, "test2") 141 s.Require().NoError(err) 142 143 clusterAckLevels, err = s.GetAckLevels(s.ctx) 144 s.Require().NoError(err) 145 s.Assert().Len(clusterAckLevels, 2) 146 s.Assert().Equal(int64(20), clusterAckLevels["test1"]) 147 s.Assert().Equal(int64(25), clusterAckLevels["test2"]) 148 } 149 150 // TestNamespaceReplicationDLQ tests namespace DLQ operations 151 func (s *QueuePersistenceSuite) TestNamespaceReplicationDLQ() { 152 maxMessageID := int64(100) 153 numMessages := 100 154 concurrentSenders := 10 155 156 messageChan := make(chan *replicationspb.ReplicationTask) 157 158 taskType := enumsspb.REPLICATION_TASK_TYPE_NAMESPACE_TASK 159 go func() { 160 for i := 0; i < numMessages; i++ { 161 messageChan <- &replicationspb.ReplicationTask{ 162 TaskType: taskType, 163 Attributes: &replicationspb.ReplicationTask_NamespaceTaskAttributes{ 164 NamespaceTaskAttributes: &replicationspb.NamespaceTaskAttributes{ 165 Id: fmt.Sprintf("message-%v", i), 166 }, 167 }, 168 } 169 } 170 close(messageChan) 171 }() 172 173 wg := sync.WaitGroup{} 174 wg.Add(concurrentSenders) 175 176 for i := 0; i < concurrentSenders; i++ { 177 go func(senderNum int) { 178 defer wg.Done() 179 for message := range messageChan { 180 err := s.PublishToNamespaceDLQ(s.ctx, message) 181 id := message.Attributes.(*replicationspb.ReplicationTask_NamespaceTaskAttributes).NamespaceTaskAttributes.Id 182 s.Nil(err, "Enqueue message failed when sender %d tried to send %s", senderNum, id) 183 } 184 }(i) 185 } 186 187 wg.Wait() 188 189 result1, token, err := s.GetMessagesFromNamespaceDLQ(s.ctx, persistence.EmptyQueueMessageID, maxMessageID, numMessages/2, nil) 190 s.Nil(err, "GetReplicationMessages failed.") 191 s.NotNil(token) 192 result2, token, err := s.GetMessagesFromNamespaceDLQ(s.ctx, persistence.EmptyQueueMessageID, maxMessageID, numMessages, token) 193 s.Nil(err, "GetReplicationMessages failed.") 194 s.Equal(len(token), 0) 195 s.Equal(len(result1)+len(result2), numMessages) 196 _, _, err = s.GetMessagesFromNamespaceDLQ(s.ctx, persistence.EmptyQueueMessageID, 1<<63-1, numMessages, nil) 197 s.NoError(err, "GetReplicationMessages failed.") 198 s.Equal(len(token), 0) 199 200 lastMessageID := result2[len(result2)-1].SourceTaskId 201 err = s.DeleteMessageFromNamespaceDLQ(s.ctx, lastMessageID) 202 s.NoError(err) 203 result3, token, err := s.GetMessagesFromNamespaceDLQ(s.ctx, persistence.EmptyQueueMessageID, maxMessageID, numMessages, token) 204 s.Nil(err, "GetReplicationMessages failed.") 205 s.Equal(len(token), 0) 206 s.Equal(len(result3), numMessages-1) 207 208 err = s.RangeDeleteMessagesFromNamespaceDLQ(s.ctx, persistence.EmptyQueueMessageID, lastMessageID) 209 s.NoError(err) 210 result4, token, err := s.GetMessagesFromNamespaceDLQ(s.ctx, persistence.EmptyQueueMessageID, maxMessageID, numMessages, token) 211 s.Nil(err, "GetReplicationMessages failed.") 212 s.Equal(len(token), 0) 213 s.Equal(len(result4), 0) 214 } 215 216 // TestNamespaceDLQMetadataOperations tests queue metadata operations 217 func (s *QueuePersistenceSuite) TestNamespaceDLQMetadataOperations() { 218 ackLevel, err := s.GetNamespaceDLQAckLevel(s.ctx) 219 s.Require().NoError(err) 220 s.Equal(persistence.EmptyQueueMessageID, ackLevel) 221 222 err = s.UpdateNamespaceDLQAckLevel(s.ctx, 10) 223 s.NoError(err) 224 225 ackLevel, err = s.GetNamespaceDLQAckLevel(s.ctx) 226 s.Require().NoError(err) 227 s.Equal(int64(10), ackLevel) 228 229 err = s.UpdateNamespaceDLQAckLevel(s.ctx, 1) 230 s.NoError(err) 231 232 ackLevel, err = s.GetNamespaceDLQAckLevel(s.ctx) 233 s.Require().NoError(err) 234 s.Equal(int64(10), ackLevel) 235 }