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  }