78 lines
1.8 KiB
Go
78 lines
1.8 KiB
Go
package testutils
|
|
|
|
import (
|
|
"context"
|
|
"sync"
|
|
|
|
"github.com/redis/go-redis/v9"
|
|
"github.com/testcontainers/testcontainers-go"
|
|
"github.com/testcontainers/testcontainers-go/wait"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
var (
|
|
redisContainer testcontainers.Container
|
|
redisClient *redis.Client
|
|
redisOnce sync.Once
|
|
redisErr error
|
|
)
|
|
|
|
// GetTestRedisClient ensures the Redis container is running and returns a client.
|
|
// It uses a singleton pattern to start the container only once per test run.
|
|
func GetTestRedisClient(ctx context.Context) (*redis.Client, error) {
|
|
redisOnce.Do(func() {
|
|
redisErr = setupRedisContainer(ctx)
|
|
})
|
|
return redisClient, redisErr
|
|
}
|
|
|
|
func setupRedisContainer(ctx context.Context) error {
|
|
logger := zap.NewNop()
|
|
if zap.L() != nil {
|
|
logger = zap.L()
|
|
}
|
|
|
|
logger.Info("Starting Redis testcontainer")
|
|
|
|
req := testcontainers.ContainerRequest{
|
|
Image: "redis:7-alpine",
|
|
ExposedPorts: []string{"6379/tcp"},
|
|
WaitingFor: wait.ForLog("Ready to accept connections"),
|
|
}
|
|
|
|
var containerErr error
|
|
redisContainer, containerErr = testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{
|
|
ContainerRequest: req,
|
|
Started: true,
|
|
})
|
|
|
|
if containerErr != nil {
|
|
logger.Error("Failed to start Redis testcontainer", zap.Error(containerErr))
|
|
return containerErr
|
|
}
|
|
|
|
endpoint, err := redisContainer.Endpoint(ctx, "")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
redisClient = redis.NewClient(&redis.Options{
|
|
Addr: endpoint,
|
|
})
|
|
|
|
// Wait for Redis to be ready
|
|
if err := redisClient.Ping(ctx).Err(); err != nil {
|
|
return err
|
|
}
|
|
|
|
logger.Info("Redis testcontainer started successfully")
|
|
return nil
|
|
}
|
|
|
|
// TerminateRedisContainer allows manual termination if needed (mostly for cleanup)
|
|
func TerminateRedisContainer(ctx context.Context) error {
|
|
if redisContainer != nil {
|
|
return redisContainer.Terminate(ctx)
|
|
}
|
|
return nil
|
|
}
|