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  }