// Copyright 2023 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT package queue import ( "context" "testing" "code.gitea.io/gitea/modules/queue/mock" "code.gitea.io/gitea/modules/setting" "github.com/redis/go-redis/v9" "github.com/stretchr/testify/suite" "go.uber.org/mock/gomock" ) type baseRedisUnitTestSuite struct { suite.Suite mockController *gomock.Controller } func TestBaseRedis(t *testing.T) { suite.Run(t, &baseRedisUnitTestSuite{}) } func (suite *baseRedisUnitTestSuite) SetupSuite() { suite.mockController = gomock.NewController(suite.T()) } func (suite *baseRedisUnitTestSuite) TestBasic() { queueName := "test-queue" testCases := []struct { Name string ConnectionString string QueueName string Unique bool }{ { Name: "unique", ConnectionString: "redis://127.0.0.1/0", QueueName: queueName, Unique: true, }, { Name: "non-unique", ConnectionString: "redis://127.0.0.1/0", QueueName: queueName, Unique: false, }, { Name: "unique with prefix", ConnectionString: "redis://127.0.0.1/0?prefix=forgejo:queue:", QueueName: "forgejo:queue:" + queueName, Unique: true, }, { Name: "non-unique with prefix", ConnectionString: "redis://127.0.0.1/0?prefix=forgejo:queue:", QueueName: "forgejo:queue:" + queueName, Unique: false, }, } for _, testCase := range testCases { suite.Run(testCase.Name, func() { queueSettings := setting.QueueSettings{ Length: 10, ConnStr: testCase.ConnectionString, } // Configure expectations. mockRedisStore := mock.NewInMemoryMockRedis() redisClient := mock.NewMockUniversalClient(suite.mockController) redisClient.EXPECT(). Ping(gomock.Any()). Times(1). Return(&redis.StatusCmd{}) redisClient.EXPECT(). LLen(gomock.Any(), testCase.QueueName). Times(1). DoAndReturn(mockRedisStore.LLen) redisClient.EXPECT(). LPop(gomock.Any(), testCase.QueueName). Times(1). DoAndReturn(mockRedisStore.LPop) redisClient.EXPECT(). RPush(gomock.Any(), testCase.QueueName, gomock.Any()). Times(1). DoAndReturn(mockRedisStore.RPush) if testCase.Unique { redisClient.EXPECT(). SAdd(gomock.Any(), testCase.QueueName+"_unique", gomock.Any()). Times(1). DoAndReturn(mockRedisStore.SAdd) redisClient.EXPECT(). SRem(gomock.Any(), testCase.QueueName+"_unique", gomock.Any()). Times(1). DoAndReturn(mockRedisStore.SRem) redisClient.EXPECT(). SIsMember(gomock.Any(), testCase.QueueName+"_unique", gomock.Any()). Times(2). DoAndReturn(mockRedisStore.SIsMember) } client, err := newBaseRedisGeneric( toBaseConfig(queueName, queueSettings), testCase.Unique, redisClient, ) suite.Require().NoError(err) ctx := context.Background() expectedContent := []byte("test") suite.Require().NoError(client.PushItem(ctx, expectedContent)) found, err := client.HasItem(ctx, expectedContent) suite.Require().NoError(err) if testCase.Unique { suite.True(found) } else { suite.False(found) } found, err = client.HasItem(ctx, []byte("not found content")) suite.Require().NoError(err) suite.False(found) content, err := client.PopItem(ctx) suite.Require().NoError(err) suite.Equal(expectedContent, content) }) } }