mirror of
				https://github.com/gofiber/storage.git
				synced 2025-10-31 11:46:32 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			169 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			169 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package testredis
 | |
| 
 | |
| import (
 | |
| 	"context"
 | |
| 	"crypto/tls"
 | |
| 	"strings"
 | |
| 	"testing"
 | |
| 
 | |
| 	"github.com/stretchr/testify/require"
 | |
| 	"github.com/testcontainers/testcontainers-go"
 | |
| 	"github.com/testcontainers/testcontainers-go/modules/redis"
 | |
| )
 | |
| 
 | |
| const (
 | |
| 	Port = "6379/tcp"
 | |
| )
 | |
| 
 | |
| // Config represents the configuration for a Redis container
 | |
| type Config struct {
 | |
| 	// TLS settings
 | |
| 	UseTLS       bool
 | |
| 	SecureURL    bool
 | |
| 	MTLSDisabled bool
 | |
| 	UseAddress   bool
 | |
| 	UseHostPort  bool
 | |
| 	UseURL       bool
 | |
| 	name         string
 | |
| }
 | |
| 
 | |
| // Option is a function that configures a Config
 | |
| type Option func(*Config)
 | |
| 
 | |
| // WithTLS configures the container to use TLS
 | |
| func WithTLS(secureURL bool, mtlsDisabled bool) Option {
 | |
| 	return func(c *Config) {
 | |
| 		c.UseTLS = true
 | |
| 		c.SecureURL = secureURL
 | |
| 		c.MTLSDisabled = mtlsDisabled
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // WithAddress sets the container to use address-based connection
 | |
| func WithAddress() Option {
 | |
| 	return func(c *Config) {
 | |
| 		c.UseAddress = true
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // WithHostPort sets the container to use host and port based connection
 | |
| func WithHostPort() Option {
 | |
| 	return func(c *Config) {
 | |
| 		c.UseHostPort = true
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // WithURL sets the container to use a URL
 | |
| func WithURL(useContainerURI bool) Option {
 | |
| 	return func(c *Config) {
 | |
| 		c.UseURL = useContainerURI
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // WithReuse sets the container to be reused,
 | |
| // providing a name to identify the container.
 | |
| // This container is not cleaned up when the test completes.
 | |
| func WithReuse(name string) Option {
 | |
| 	return func(c *Config) {
 | |
| 		c.name = name
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // Container represents a running Redis container
 | |
| type Container struct {
 | |
| 	URL       string
 | |
| 	cmds      []string
 | |
| 	Addrs     []string
 | |
| 	Host      string
 | |
| 	Port      int
 | |
| 	TLSConfig *tls.Config
 | |
| }
 | |
| 
 | |
| // Start starts a Redis container for testing and returns its configuration
 | |
| func Start(t testing.TB, img string, opts ...Option) *Container {
 | |
| 	t.Helper()
 | |
| 
 | |
| 	config := &Config{
 | |
| 		UseURL: true, // by default, use the URL provided by the testcontainer
 | |
| 	}
 | |
| 	for _, o := range opts {
 | |
| 		o(config)
 | |
| 	}
 | |
| 
 | |
| 	if img == "" {
 | |
| 		panic("Redis image is not set: callers must provide a non-empty image parameter")
 | |
| 	}
 | |
| 
 | |
| 	ctx := context.Background()
 | |
| 	tcOpts := []testcontainers.ContainerCustomizer{}
 | |
| 
 | |
| 	var cmds []string
 | |
| 	if config.UseTLS {
 | |
| 		tcOpts = append(tcOpts, redis.WithTLS())
 | |
| 
 | |
| 		cmds = append(cmds,
 | |
| 			"--port", "0",
 | |
| 			"--tls-port", "6379",
 | |
| 			"--tls-cert-file", "/tls/server.crt",
 | |
| 			"--tls-key-file", "/tls/server.key",
 | |
| 			"--tls-ca-cert-file", "/tls/ca.crt",
 | |
| 		)
 | |
| 
 | |
| 		cmds = append(cmds, "--tls-auth-clients", func() string {
 | |
| 			if config.MTLSDisabled {
 | |
| 				return "no"
 | |
| 			}
 | |
| 			return "yes"
 | |
| 		}())
 | |
| 
 | |
| 		tcOpts = append(tcOpts, testcontainers.WithCmd(cmds...))
 | |
| 	}
 | |
| 
 | |
| 	if config.name != "" {
 | |
| 		tcOpts = append(tcOpts, testcontainers.WithReuseByName(config.name))
 | |
| 	}
 | |
| 
 | |
| 	c, err := redis.Run(ctx, img, tcOpts...)
 | |
| 	if config.name == "" {
 | |
| 		// only cleanup the container if it's not being reused
 | |
| 		testcontainers.CleanupContainer(t, c)
 | |
| 	}
 | |
| 	require.NoError(t, err)
 | |
| 
 | |
| 	ctr := &Container{
 | |
| 		TLSConfig: c.TLSConfig(),
 | |
| 		cmds:      cmds,
 | |
| 	}
 | |
| 
 | |
| 	uri, err := c.ConnectionString(ctx)
 | |
| 	require.NoError(t, err)
 | |
| 
 | |
| 	if config.UseHostPort {
 | |
| 		host, err := c.Host(ctx)
 | |
| 		require.NoError(t, err)
 | |
| 
 | |
| 		port, err := c.MappedPort(ctx, Port)
 | |
| 		require.NoError(t, err)
 | |
| 
 | |
| 		ctr.Host = host
 | |
| 		ctr.Port = port.Int()
 | |
| 	}
 | |
| 
 | |
| 	if config.UseAddress {
 | |
| 		// trim the schemes from the URI
 | |
| 		addr := strings.TrimPrefix(uri, "redis://")
 | |
| 		addr = strings.TrimPrefix(addr, "rediss://")
 | |
| 		ctr.Addrs = []string{addr}
 | |
| 	}
 | |
| 
 | |
| 	if config.UseURL {
 | |
| 		ctr.URL = uri
 | |
| 		if !config.SecureURL {
 | |
| 			// Replace the scheme with the insecure one
 | |
| 			ctr.URL = strings.Replace(ctr.URL, "rediss://", "redis://", 1)
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return ctr
 | |
| }
 | 
