go.temporal.io/server@v1.23.0/common/persistence/tests/queue_v2_test_suite.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  	"context"
    29  	"strconv"
    30  	"testing"
    31  
    32  	"github.com/stretchr/testify/assert"
    33  	"github.com/stretchr/testify/require"
    34  	"go.temporal.io/api/enums/v1"
    35  	"go.temporal.io/api/serviceerror"
    36  	"go.temporal.io/server/common/persistence/persistencetest"
    37  	"go.temporal.io/server/common/persistence/serialization"
    38  	"go.temporal.io/server/common/persistence/sql/sqlplugin/tests"
    39  
    40  	"go.temporal.io/server/common/persistence"
    41  	"go.temporal.io/server/common/persistence/sql"
    42  )
    43  
    44  // RunQueueV2TestSuite executes interface-level tests for a queue persistence-layer implementation. There should be more
    45  // implementation-specific tests that will not be covered by this suite elsewhere.
    46  func RunQueueV2TestSuite(t *testing.T, q persistence.QueueV2) {
    47  	ctx := context.Background()
    48  
    49  	queueType := persistence.QueueTypeHistoryNormal
    50  	queueName := "test-queue-" + t.Name()
    51  
    52  	_, err := q.CreateQueue(ctx, &persistence.InternalCreateQueueRequest{
    53  		QueueType: queueType,
    54  		QueueName: queueName,
    55  	})
    56  	require.NoError(t, err)
    57  	t.Run("TestListQueues", func(t *testing.T) {
    58  		testListQueues(ctx, t, q)
    59  	})
    60  	t.Run("TestHappyPath", func(t *testing.T) {
    61  		t.Parallel()
    62  
    63  		testHappyPath(ctx, t, q, queueType, queueName)
    64  	})
    65  	t.Run("TestInvalidPageToken", func(t *testing.T) {
    66  		t.Parallel()
    67  
    68  		_, err := q.ReadMessages(ctx, &persistence.InternalReadMessagesRequest{
    69  			QueueType:     queueType,
    70  			QueueName:     queueName,
    71  			PageSize:      1,
    72  			NextPageToken: []byte("some invalid token"),
    73  		})
    74  		assert.ErrorIs(t, err, persistence.ErrInvalidReadQueueMessagesNextPageToken)
    75  	})
    76  	t.Run("TestNonPositivePageSize", func(t *testing.T) {
    77  		t.Parallel()
    78  
    79  		_, err := q.ReadMessages(ctx, &persistence.InternalReadMessagesRequest{
    80  			QueueType:     queueType,
    81  			QueueName:     queueName,
    82  			PageSize:      0,
    83  			NextPageToken: nil,
    84  		})
    85  		assert.ErrorIs(t, err, persistence.ErrNonPositiveReadQueueMessagesPageSize)
    86  	})
    87  	t.Run("TestEnqueueMessageToNonExistentQueue", func(t *testing.T) {
    88  		t.Parallel()
    89  
    90  		_, err := q.EnqueueMessage(ctx, &persistence.InternalEnqueueMessageRequest{
    91  			QueueType: queueType,
    92  			QueueName: "non-existent-queue",
    93  		})
    94  		assert.ErrorAs(t, err, new(*serviceerror.NotFound))
    95  		assert.ErrorContains(t, err, "non-existent-queue")
    96  		assert.ErrorContains(t, err, strconv.Itoa(int(queueType)))
    97  	})
    98  	t.Run("TestCreateQueueTwice", func(t *testing.T) {
    99  		t.Parallel()
   100  
   101  		_, err := q.CreateQueue(ctx, &persistence.InternalCreateQueueRequest{
   102  			QueueType: queueType,
   103  			QueueName: queueName,
   104  		})
   105  		require.Error(t, err)
   106  		assert.ErrorIs(t, err, persistence.ErrQueueAlreadyExists)
   107  		assert.ErrorContains(t, err, strconv.Itoa(int(queueType)))
   108  		assert.ErrorContains(t, err, queueName)
   109  	})
   110  	t.Run("InvalidEncodingForQueueMessage", func(t *testing.T) {
   111  		queueType := persistence.QueueTypeHistoryNormal
   112  		queueName := "test-queue-" + t.Name()
   113  		_, err := q.CreateQueue(ctx, &persistence.InternalCreateQueueRequest{
   114  			QueueType: queueType,
   115  			QueueName: queueName,
   116  		})
   117  		require.NoError(t, err)
   118  		_, err = persistencetest.EnqueueMessage(context.Background(), q, queueType, queueName, func(p *persistencetest.EnqueueParams) {
   119  			p.EncodingType = -1
   120  		})
   121  		require.NoError(t, err)
   122  		_, err = q.ReadMessages(ctx, &persistence.InternalReadMessagesRequest{
   123  			QueueType: queueType,
   124  			QueueName: queueName,
   125  			PageSize:  10,
   126  		})
   127  		require.Error(t, err)
   128  		assert.ErrorAs(t, err, new(*serialization.UnknownEncodingTypeError))
   129  	})
   130  	t.Run("InvalidEncodingForQueueMetadata", func(t *testing.T) {
   131  		queueType := persistence.QueueTypeHistoryNormal
   132  		queueName := "test-queue-" + t.Name()
   133  		_, err := q.CreateQueue(ctx, &persistence.InternalCreateQueueRequest{
   134  			QueueType: queueType,
   135  			QueueName: queueName,
   136  		})
   137  		require.NoError(t, err)
   138  		_, err = persistencetest.EnqueueMessage(context.Background(), q, queueType, queueName, func(p *persistencetest.EnqueueParams) {
   139  			p.EncodingType = -1
   140  		})
   141  		require.NoError(t, err)
   142  		_, err = q.ReadMessages(ctx, &persistence.InternalReadMessagesRequest{
   143  			QueueType: queueType,
   144  			QueueName: queueName,
   145  			PageSize:  10,
   146  		})
   147  		require.Error(t, err)
   148  		assert.ErrorAs(t, err, new(*serialization.UnknownEncodingTypeError))
   149  	})
   150  	t.Run("TestRangeDeleteMessages", func(t *testing.T) {
   151  		t.Parallel()
   152  		testRangeDeleteMessages(ctx, t, q)
   153  	})
   154  	t.Run("HistoryTaskQueueManagerImpl", func(t *testing.T) {
   155  		t.Parallel()
   156  		RunHistoryTaskQueueManagerTestSuite(t, q)
   157  	})
   158  }
   159  
   160  func testHappyPath(
   161  	ctx context.Context,
   162  	t *testing.T,
   163  	queue persistence.QueueV2,
   164  	queueType persistence.QueueV2Type,
   165  	queueName string,
   166  ) {
   167  	response, err := queue.ReadMessages(ctx, &persistence.InternalReadMessagesRequest{
   168  		QueueType:     queueType,
   169  		QueueName:     queueName,
   170  		PageSize:      1,
   171  		NextPageToken: nil,
   172  	})
   173  	require.NoError(t, err)
   174  	assert.Equal(t, 0, len(response.Messages))
   175  
   176  	encodingType := enums.ENCODING_TYPE_JSON
   177  	_, err = persistencetest.EnqueueMessage(ctx, queue, queueType, queueName)
   178  	require.NoError(t, err)
   179  
   180  	_, err = persistencetest.EnqueueMessage(ctx, queue, queueType, queueName, func(p *persistencetest.EnqueueParams) {
   181  		p.Data = []byte("2")
   182  	})
   183  	require.NoError(t, err)
   184  
   185  	response, err = queue.ReadMessages(ctx, &persistence.InternalReadMessagesRequest{
   186  		QueueType:     queueType,
   187  		QueueName:     queueName,
   188  		PageSize:      1,
   189  		NextPageToken: nil,
   190  	})
   191  	require.NoError(t, err)
   192  	require.Len(t, response.Messages, 1)
   193  	assert.Equal(t, int64(persistence.FirstQueueMessageID), response.Messages[0].MetaData.ID)
   194  	assert.Equal(t, []byte("1"), response.Messages[0].Data.Data)
   195  	assert.Equal(t, encodingType, response.Messages[0].Data.EncodingType)
   196  	assert.NotNil(t, response.NextPageToken)
   197  
   198  	response, err = queue.ReadMessages(ctx, &persistence.InternalReadMessagesRequest{
   199  		QueueType:     queueType,
   200  		QueueName:     queueName,
   201  		PageSize:      1,
   202  		NextPageToken: response.NextPageToken,
   203  	})
   204  	require.NoError(t, err)
   205  	require.Len(t, response.Messages, 1)
   206  	assert.Equal(t, int64(persistence.FirstQueueMessageID+1), response.Messages[0].MetaData.ID)
   207  	assert.Equal(t, []byte("2"), response.Messages[0].Data.Data)
   208  	assert.Equal(t, encodingType, response.Messages[0].Data.EncodingType)
   209  
   210  	response, err = queue.ReadMessages(ctx, &persistence.InternalReadMessagesRequest{
   211  		QueueType:     queueType,
   212  		QueueName:     queueName,
   213  		PageSize:      1,
   214  		NextPageToken: response.NextPageToken,
   215  	})
   216  	require.NoError(t, err)
   217  	assert.Empty(t, response.Messages)
   218  	assert.Nil(t, response.NextPageToken)
   219  }
   220  
   221  func testRangeDeleteMessages(ctx context.Context, t *testing.T, queue persistence.QueueV2) {
   222  	t.Helper()
   223  
   224  	t.Run("DeleteBeforeCreate", func(t *testing.T) {
   225  		t.Parallel()
   226  
   227  		queueType := persistence.QueueTypeHistoryNormal
   228  		queueName := "test-queue-" + t.Name()
   229  		_, err := queue.RangeDeleteMessages(ctx, &persistence.InternalRangeDeleteMessagesRequest{
   230  			QueueType: queueType,
   231  			QueueName: queueName,
   232  		})
   233  		assert.ErrorAs(t, err, new(*serviceerror.NotFound))
   234  	})
   235  
   236  	t.Run("InvalidMaxMessageID", func(t *testing.T) {
   237  		t.Parallel()
   238  
   239  		queueType := persistence.QueueTypeHistoryNormal
   240  		queueName := "test-queue-" + t.Name()
   241  		_, err := queue.CreateQueue(ctx, &persistence.InternalCreateQueueRequest{
   242  			QueueType: queueType,
   243  			QueueName: queueName,
   244  		})
   245  		require.NoError(t, err)
   246  		_, err = queue.RangeDeleteMessages(ctx, &persistence.InternalRangeDeleteMessagesRequest{
   247  			QueueType: queueType,
   248  			QueueName: queueName,
   249  			InclusiveMaxMessageMetadata: persistence.MessageMetadata{
   250  				ID: persistence.FirstQueueMessageID - 1,
   251  			},
   252  		})
   253  		require.Error(t, err)
   254  		assert.ErrorIs(t, err, persistence.ErrInvalidQueueRangeDeleteMaxMessageID)
   255  		assert.ErrorContains(t, err, strconv.Itoa(persistence.FirstQueueMessageID-1))
   256  		assert.ErrorContains(t, err, strconv.Itoa(persistence.FirstQueueMessageID))
   257  	})
   258  
   259  	t.Run("HappyPath", func(t *testing.T) {
   260  		t.Parallel()
   261  
   262  		queueType := persistence.QueueTypeHistoryNormal
   263  		queueName := "test-queue-" + t.Name()
   264  		_, err := queue.CreateQueue(ctx, &persistence.InternalCreateQueueRequest{
   265  			QueueType: queueType,
   266  			QueueName: queueName,
   267  		})
   268  		require.NoError(t, err)
   269  		for i := 0; i < 3; i++ {
   270  			_, err := persistencetest.EnqueueMessage(ctx, queue, queueType, queueName)
   271  			require.NoError(t, err)
   272  		}
   273  		resp, err := queue.RangeDeleteMessages(ctx, &persistence.InternalRangeDeleteMessagesRequest{
   274  			QueueType: queueType,
   275  			QueueName: queueName,
   276  			InclusiveMaxMessageMetadata: persistence.MessageMetadata{
   277  				ID: persistence.FirstQueueMessageID + 1,
   278  			},
   279  		})
   280  		require.NoError(t, err)
   281  		assert.Equal(t, int64(2), resp.MessagesDeleted)
   282  		response, err := queue.ReadMessages(ctx, &persistence.InternalReadMessagesRequest{
   283  			QueueType: queueType,
   284  			QueueName: queueName,
   285  			PageSize:  10,
   286  		})
   287  		require.NoError(t, err)
   288  		require.Len(t, response.Messages, 1)
   289  		assert.Equal(t, int64(persistence.FirstQueueMessageID+2), response.Messages[0].MetaData.ID)
   290  	})
   291  
   292  	t.Run("DeleteAllAndReEnqueue", func(t *testing.T) {
   293  		t.Parallel()
   294  
   295  		queueType := persistence.QueueTypeHistoryNormal
   296  		queueName := "test-queue-" + t.Name()
   297  		_, err := queue.CreateQueue(ctx, &persistence.InternalCreateQueueRequest{
   298  			QueueType: queueType,
   299  			QueueName: queueName,
   300  		})
   301  		require.NoError(t, err)
   302  		msg, err := persistencetest.EnqueueMessage(ctx, queue, queueType, queueName)
   303  		require.NoError(t, err)
   304  		assert.Equal(t, int64(persistence.FirstQueueMessageID), msg.Metadata.ID)
   305  		resp, err := queue.RangeDeleteMessages(ctx, &persistence.InternalRangeDeleteMessagesRequest{
   306  			QueueType: queueType,
   307  			QueueName: queueName,
   308  			InclusiveMaxMessageMetadata: persistence.MessageMetadata{
   309  				ID: persistence.FirstQueueMessageID,
   310  			},
   311  		})
   312  		require.NoError(t, err)
   313  		assert.Equal(t, int64(1), resp.MessagesDeleted)
   314  		msg, err = persistencetest.EnqueueMessage(ctx, queue, queueType, queueName)
   315  		require.NoError(t, err)
   316  		assert.Equal(t, int64(persistence.FirstQueueMessageID+1), msg.Metadata.ID, "Even though all"+
   317  			" messages are deleted, the next message ID should still be incremented")
   318  	})
   319  
   320  	t.Run("DeleteAndValidateMinId", func(t *testing.T) {
   321  		t.Parallel()
   322  
   323  		queueType := persistence.QueueTypeHistoryNormal
   324  		queueName := "test-queue-" + t.Name()
   325  		_, err := queue.CreateQueue(ctx, &persistence.InternalCreateQueueRequest{
   326  			QueueType: queueType,
   327  			QueueName: queueName,
   328  		})
   329  		require.NoError(t, err)
   330  		for i := 0; i < 3; i++ {
   331  			msg, err := persistencetest.EnqueueMessage(ctx, queue, queueType, queueName)
   332  			require.NoError(t, err)
   333  			assert.Equal(t, int64(persistence.FirstQueueMessageID+i), msg.Metadata.ID)
   334  		}
   335  		resp, err := queue.RangeDeleteMessages(ctx, &persistence.InternalRangeDeleteMessagesRequest{
   336  			QueueType: queueType,
   337  			QueueName: queueName,
   338  			InclusiveMaxMessageMetadata: persistence.MessageMetadata{
   339  				ID: persistence.FirstQueueMessageID + 10,
   340  			},
   341  		})
   342  		require.NoError(t, err)
   343  		require.Equal(t, int64(3), resp.MessagesDeleted)
   344  		_, err = persistencetest.EnqueueMessage(ctx, queue, queueType, queueName)
   345  		require.NoError(t, err)
   346  		response, err := queue.ReadMessages(ctx, &persistence.InternalReadMessagesRequest{
   347  			QueueType: queueType,
   348  			QueueName: queueName,
   349  			PageSize:  10,
   350  		})
   351  		require.NoError(t, err)
   352  		require.Len(t, response.Messages, 1)
   353  		require.Equal(t, response.Messages[0].MetaData.ID, int64(3))
   354  	})
   355  
   356  	t.Run("DeleteSameRangeTwice", func(t *testing.T) {
   357  		t.Parallel()
   358  
   359  		queueType := persistence.QueueTypeHistoryNormal
   360  		queueName := "test-queue-" + t.Name()
   361  		_, err := queue.CreateQueue(ctx, &persistence.InternalCreateQueueRequest{
   362  			QueueType: queueType,
   363  			QueueName: queueName,
   364  		})
   365  		require.NoError(t, err)
   366  		for i := 0; i < 2; i++ {
   367  			_, err := persistencetest.EnqueueMessage(ctx, queue, queueType, queueName)
   368  			require.NoError(t, err)
   369  		}
   370  
   371  		resp, err := queue.RangeDeleteMessages(ctx, &persistence.InternalRangeDeleteMessagesRequest{
   372  			QueueType: queueType,
   373  			QueueName: queueName,
   374  			InclusiveMaxMessageMetadata: persistence.MessageMetadata{
   375  				ID: persistence.FirstQueueMessageID,
   376  			},
   377  		})
   378  		require.NoError(t, err)
   379  		require.Equal(t, int64(1), resp.MessagesDeleted)
   380  
   381  		resp, err = queue.RangeDeleteMessages(ctx, &persistence.InternalRangeDeleteMessagesRequest{
   382  			QueueType: queueType,
   383  			QueueName: queueName,
   384  			InclusiveMaxMessageMetadata: persistence.MessageMetadata{
   385  				ID: persistence.FirstQueueMessageID,
   386  			},
   387  		})
   388  		require.NoError(t, err)
   389  		require.Equal(t, int64(0), resp.MessagesDeleted)
   390  
   391  		response, err := queue.ReadMessages(ctx, &persistence.InternalReadMessagesRequest{
   392  			QueueType: queueType,
   393  			QueueName: queueName,
   394  			PageSize:  10,
   395  		})
   396  		require.NoError(t, err)
   397  		require.Len(t, response.Messages, 1)
   398  		assert.Equal(t, int64(persistence.FirstQueueMessageID+1), response.Messages[0].MetaData.ID)
   399  	})
   400  }
   401  
   402  func RunQueueV2TestSuiteForSQL(t *testing.T, factory *sql.Factory) {
   403  	t.Run("Generic", func(t *testing.T) {
   404  		t.Parallel()
   405  		queue, err := factory.NewQueueV2()
   406  		require.NoError(t, err)
   407  		RunQueueV2TestSuite(t, queue)
   408  	})
   409  	t.Run("SQL", func(t *testing.T) {
   410  		t.Parallel()
   411  		db, err := factory.GetDB()
   412  		require.NoError(t, err)
   413  		tests.RunSQLQueueV2TestSuite(t, db)
   414  	})
   415  }
   416  
   417  func testListQueues(ctx context.Context, t *testing.T, queue persistence.QueueV2) {
   418  	t.Run("HappyPath", func(t *testing.T) {
   419  		// ListQueues when empty
   420  		queueType := persistence.QueueTypeHistoryDLQ
   421  		response, err := queue.ListQueues(ctx, &persistence.InternalListQueuesRequest{
   422  			QueueType:     queueType,
   423  			PageSize:      10,
   424  			NextPageToken: nil,
   425  		})
   426  		require.NoError(t, err)
   427  		require.Equal(t, 0, len(response.Queues))
   428  
   429  		// List of all created queues
   430  		var queueNames []string
   431  
   432  		// List one queue.
   433  		queueName := "test-queue-" + t.Name() + "first"
   434  		queueNames = append(queueNames, queueName)
   435  		_, err = queue.CreateQueue(ctx, &persistence.InternalCreateQueueRequest{
   436  			QueueType: queueType,
   437  			QueueName: queueName,
   438  		})
   439  		require.NoError(t, err)
   440  		response, err = queue.ListQueues(ctx, &persistence.InternalListQueuesRequest{
   441  			QueueType:     queueType,
   442  			PageSize:      10,
   443  			NextPageToken: nil,
   444  		})
   445  		require.NoError(t, err)
   446  		require.Equal(t, 1, len(response.Queues))
   447  		require.Equal(t, queueName, response.Queues[0].QueueName)
   448  		require.Equal(t, int64(0), response.Queues[0].MessageCount)
   449  
   450  		// List multiple queues.
   451  		queueName = "test-queue-" + t.Name() + "second"
   452  		queueNames = append(queueNames, queueName)
   453  		_, err = queue.CreateQueue(ctx, &persistence.InternalCreateQueueRequest{
   454  			QueueType: queueType,
   455  			QueueName: queueName,
   456  		})
   457  		require.NoError(t, err)
   458  		response, err = queue.ListQueues(ctx, &persistence.InternalListQueuesRequest{
   459  			QueueType:     queueType,
   460  			PageSize:      10,
   461  			NextPageToken: nil,
   462  		})
   463  		require.NoError(t, err)
   464  		require.Equal(t, 2, len(response.Queues))
   465  		require.Contains(t, []string{response.Queues[0].QueueName, response.Queues[1].QueueName}, queueName)
   466  		require.Equal(t, int64(0), response.Queues[0].MessageCount)
   467  		require.Equal(t, int64(0), response.Queues[1].MessageCount)
   468  
   469  		// List multiple queues in pages.
   470  		for i := 0; i < 3; i++ {
   471  			queueNames = append(queueNames, "test-queue-"+t.Name()+strconv.Itoa(i))
   472  		}
   473  		for _, queueName := range queueNames[2:] {
   474  			_, err := queue.CreateQueue(ctx, &persistence.InternalCreateQueueRequest{
   475  				QueueType: queueType,
   476  				QueueName: queueName,
   477  			})
   478  			require.NoError(t, err)
   479  		}
   480  		var listedQueueNames []string
   481  		response, err = queue.ListQueues(ctx, &persistence.InternalListQueuesRequest{
   482  			QueueType:     queueType,
   483  			PageSize:      1,
   484  			NextPageToken: nil,
   485  		})
   486  		require.NoError(t, err)
   487  		require.Equal(t, 1, len(response.Queues))
   488  		listedQueueNames = append(listedQueueNames, response.Queues[0].QueueName)
   489  		require.Equal(t, int64(0), response.Queues[0].MessageCount)
   490  		response, err = queue.ListQueues(ctx, &persistence.InternalListQueuesRequest{
   491  			QueueType:     queueType,
   492  			PageSize:      1,
   493  			NextPageToken: response.NextPageToken,
   494  		})
   495  		require.NoError(t, err)
   496  		require.Equal(t, 1, len(response.Queues))
   497  		listedQueueNames = append(listedQueueNames, response.Queues[0].QueueName)
   498  		require.Equal(t, int64(0), response.Queues[0].MessageCount)
   499  		response, err = queue.ListQueues(ctx, &persistence.InternalListQueuesRequest{
   500  			QueueType:     queueType,
   501  			PageSize:      3,
   502  			NextPageToken: response.NextPageToken,
   503  		})
   504  		require.NoError(t, err)
   505  		require.Equal(t, 3, len(response.Queues))
   506  		for _, queue := range response.Queues {
   507  			listedQueueNames = append(listedQueueNames, queue.QueueName)
   508  			require.Equal(t, int64(0), queue.MessageCount)
   509  		}
   510  		response, err = queue.ListQueues(ctx, &persistence.InternalListQueuesRequest{
   511  			QueueType:     queueType,
   512  			PageSize:      1,
   513  			NextPageToken: response.NextPageToken,
   514  		})
   515  		require.NoError(t, err)
   516  		require.Equal(t, 0, len(response.Queues))
   517  		require.Empty(t, response.NextPageToken)
   518  		for _, queueName := range queueNames {
   519  			require.Contains(t, listedQueueNames, queueName)
   520  		}
   521  	})
   522  	t.Run("QueueSize", func(t *testing.T) {
   523  		queueType := persistence.QueueTypeHistoryDLQ
   524  		queueName := "test-queue-" + t.Name()
   525  		_, err := queue.CreateQueue(ctx, &persistence.InternalCreateQueueRequest{
   526  			QueueType: queueType,
   527  			QueueName: queueName,
   528  		})
   529  		require.NoError(t, err)
   530  		response, err := queue.ListQueues(ctx, &persistence.InternalListQueuesRequest{
   531  			QueueType:     queueType,
   532  			PageSize:      100,
   533  			NextPageToken: nil,
   534  		})
   535  		require.NoError(t, err)
   536  		var queueNames []string
   537  		for _, queue := range response.Queues {
   538  			queueNames = append(queueNames, queue.QueueName)
   539  			if queue.QueueName == queueName {
   540  				assert.Equal(t, int64(0), queue.MessageCount)
   541  			}
   542  		}
   543  		require.Contains(t, queueNames, queueName)
   544  
   545  		// Enqueue one message and verify QueueSize is 1
   546  		_, err = persistencetest.EnqueueMessage(ctx, queue, queueType, queueName)
   547  		require.NoError(t, err)
   548  		response, err = queue.ListQueues(ctx, &persistence.InternalListQueuesRequest{
   549  			QueueType:     queueType,
   550  			PageSize:      100,
   551  			NextPageToken: nil,
   552  		})
   553  		require.NoError(t, err)
   554  		for _, queue := range response.Queues {
   555  			queueNames = append(queueNames, queue.QueueName)
   556  			if queue.QueueName == queueName {
   557  				assert.Equal(t, int64(1), queue.MessageCount)
   558  			}
   559  		}
   560  		require.Contains(t, queueNames, queueName)
   561  
   562  		// Enqueue one more message and verify QueueSize is 2
   563  		_, err = persistencetest.EnqueueMessage(ctx, queue, queueType, queueName)
   564  		require.NoError(t, err)
   565  		response, err = queue.ListQueues(ctx, &persistence.InternalListQueuesRequest{
   566  			QueueType:     queueType,
   567  			PageSize:      100,
   568  			NextPageToken: nil,
   569  		})
   570  		require.NoError(t, err)
   571  		for _, queue := range response.Queues {
   572  			queueNames = append(queueNames, queue.QueueName)
   573  			if queue.QueueName == queueName {
   574  				assert.Equal(t, int64(2), queue.MessageCount)
   575  			}
   576  		}
   577  		require.Contains(t, queueNames, queueName)
   578  
   579  		// Delete one message and verify QueueSize is 1
   580  		_, err = queue.RangeDeleteMessages(ctx, &persistence.InternalRangeDeleteMessagesRequest{
   581  			QueueType: queueType,
   582  			QueueName: queueName,
   583  			InclusiveMaxMessageMetadata: persistence.MessageMetadata{
   584  				ID: persistence.FirstQueueMessageID,
   585  			},
   586  		})
   587  		require.NoError(t, err)
   588  		response, err = queue.ListQueues(ctx, &persistence.InternalListQueuesRequest{
   589  			QueueType:     queueType,
   590  			PageSize:      100,
   591  			NextPageToken: nil,
   592  		})
   593  		require.NoError(t, err)
   594  		for _, queue := range response.Queues {
   595  			queueNames = append(queueNames, queue.QueueName)
   596  			if queue.QueueName == queueName {
   597  				assert.Equal(t, int64(1), queue.MessageCount)
   598  			}
   599  		}
   600  		require.Contains(t, queueNames, queueName)
   601  
   602  		// Delete one more message and verify QueueSize is 0
   603  		_, err = queue.RangeDeleteMessages(ctx, &persistence.InternalRangeDeleteMessagesRequest{
   604  			QueueType: queueType,
   605  			QueueName: queueName,
   606  			InclusiveMaxMessageMetadata: persistence.MessageMetadata{
   607  				ID: persistence.FirstQueueMessageID + 1,
   608  			},
   609  		})
   610  		require.NoError(t, err)
   611  		response, err = queue.ListQueues(ctx, &persistence.InternalListQueuesRequest{
   612  			QueueType:     queueType,
   613  			PageSize:      100,
   614  			NextPageToken: nil,
   615  		})
   616  		require.NoError(t, err)
   617  		for _, queue := range response.Queues {
   618  			queueNames = append(queueNames, queue.QueueName)
   619  			if queue.QueueName == queueName {
   620  				assert.Equal(t, int64(0), queue.MessageCount)
   621  			}
   622  		}
   623  		require.Contains(t, queueNames, queueName)
   624  
   625  		// Enqueue one message once again and verify QueueSize is 1
   626  		_, err = persistencetest.EnqueueMessage(ctx, queue, queueType, queueName)
   627  		require.NoError(t, err)
   628  		response, err = queue.ListQueues(ctx, &persistence.InternalListQueuesRequest{
   629  			QueueType:     queueType,
   630  			PageSize:      100,
   631  			NextPageToken: nil,
   632  		})
   633  		require.NoError(t, err)
   634  		for _, queue := range response.Queues {
   635  			queueNames = append(queueNames, queue.QueueName)
   636  			if queue.QueueName == queueName {
   637  				assert.Equal(t, int64(1), queue.MessageCount)
   638  			}
   639  		}
   640  		require.Contains(t, queueNames, queueName)
   641  
   642  	})
   643  	t.Run("NegativePageSize", func(t *testing.T) {
   644  		t.Parallel()
   645  		queueType := persistence.QueueTypeHistoryDLQ
   646  		_, err := queue.ListQueues(ctx, &persistence.InternalListQueuesRequest{
   647  			QueueType:     queueType,
   648  			PageSize:      -1,
   649  			NextPageToken: nil,
   650  		})
   651  		require.Error(t, err)
   652  		require.ErrorIs(t, err, persistence.ErrNonPositiveListQueuesPageSize)
   653  	})
   654  	t.Run("InvalidPageToken", func(t *testing.T) {
   655  		t.Parallel()
   656  		queueType := persistence.QueueTypeHistoryDLQ
   657  		_, err := queue.ListQueues(ctx, &persistence.InternalListQueuesRequest{
   658  			QueueType:     queueType,
   659  			PageSize:      1,
   660  			NextPageToken: []byte("some invalid token"),
   661  		})
   662  		assert.Error(t, err)
   663  	})
   664  }