github.com/rudderlabs/rudder-go-kit@v0.30.0/testhelper/docker/resource/redis/redis.go (about) 1 package redis 2 3 import ( 4 "context" 5 _ "encoding/json" 6 "fmt" 7 8 "github.com/go-redis/redis/v8" 9 _ "github.com/lib/pq" 10 "github.com/ory/dockertest/v3" 11 12 "github.com/rudderlabs/rudder-go-kit/testhelper/docker/resource" 13 ) 14 15 // WithTag is used to specify a custom tag that is used when pulling the Redis image from the container registry 16 func WithTag(tag string) Option { 17 return func(c *redisConfig) { 18 c.tag = tag 19 } 20 } 21 22 // WithCmdArg is used to specify the save argument when running the container. 23 func WithCmdArg(key, value string) Option { 24 return func(c *redisConfig) { 25 c.cmdArgs = append(c.cmdArgs, key, value) 26 } 27 } 28 29 // WithEnv is used to pass environment variables to the container. 30 func WithEnv(envs ...string) Option { 31 return func(c *redisConfig) { 32 c.envs = envs 33 } 34 } 35 36 type Resource struct { 37 Addr string 38 } 39 40 type Option func(*redisConfig) 41 42 type redisConfig struct { 43 tag string 44 envs []string 45 cmdArgs []string 46 } 47 48 func Setup(ctx context.Context, pool *dockertest.Pool, d resource.Cleaner, opts ...Option) (*Resource, error) { 49 conf := redisConfig{ 50 tag: "6", 51 } 52 for _, opt := range opts { 53 opt(&conf) 54 } 55 runOptions := &dockertest.RunOptions{ 56 Repository: "redis", 57 Tag: conf.tag, 58 Env: conf.envs, 59 Cmd: []string{"redis-server"}, 60 } 61 if len(conf.cmdArgs) > 0 { 62 runOptions.Cmd = append(runOptions.Cmd, conf.cmdArgs...) 63 } 64 65 // pulls a redis image, creates a container based on it and runs it 66 container, err := pool.RunWithOptions(runOptions) 67 if err != nil { 68 return nil, err 69 } 70 d.Cleanup(func() { 71 if err := pool.Purge(container); err != nil { 72 d.Log("Could not purge resource:", err) 73 } 74 }) 75 76 // exponential backoff-retry, because the application in the container might not be ready to accept connections yet 77 addr := fmt.Sprintf("localhost:%s", container.GetPort("6379/tcp")) 78 err = pool.Retry(func() error { 79 redisClient := redis.NewClient(&redis.Options{ 80 Addr: addr, 81 }) 82 defer func() { _ = redisClient.Close() }() 83 _, err := redisClient.Ping(ctx).Result() 84 return err 85 }) 86 if err != nil { 87 return nil, err 88 } 89 90 return &Resource{Addr: addr}, nil 91 }