github.com/rudderlabs/rudder-go-kit@v0.30.0/testhelper/docker/resource/mysql/mysql.go (about)

     1  package mysql
     2  
     3  import (
     4  	"bytes"
     5  	_ "encoding/json"
     6  	"fmt"
     7  
     8  	"github.com/ory/dockertest/v3"
     9  	dc "github.com/ory/dockertest/v3/docker"
    10  
    11  	"github.com/rudderlabs/rudder-go-kit/testhelper/docker/resource"
    12  )
    13  
    14  const (
    15  	defaultDB       = "sources"
    16  	defaultUser     = "root"
    17  	defaultPassword = "password"
    18  )
    19  
    20  type Resource struct {
    21  	DBDsn    string
    22  	Database string
    23  	Password string
    24  	User     string
    25  	Host     string
    26  	Port     string
    27  }
    28  
    29  func Setup(pool *dockertest.Pool, d resource.Cleaner, opts ...func(*Config)) (*Resource, error) {
    30  	c := &Config{
    31  		Tag: "8.2",
    32  	}
    33  	for _, opt := range opts {
    34  		opt(c)
    35  	}
    36  
    37  	// pulls an image, creates a container based on it and runs it
    38  	mysqlContainer, err := pool.RunWithOptions(&dockertest.RunOptions{
    39  		Repository: "mysql",
    40  		Tag:        c.Tag,
    41  		Env: []string{
    42  			"MYSQL_ROOT_PASSWORD=" + defaultPassword,
    43  			"MYSQL_DATABASE=" + defaultDB,
    44  		},
    45  	}, func(hc *dc.HostConfig) {
    46  		hc.ShmSize = c.ShmSize
    47  	})
    48  	if err != nil {
    49  		return nil, fmt.Errorf("running container: %w", err)
    50  	}
    51  
    52  	d.Cleanup(func() {
    53  		if err := pool.Purge(mysqlContainer); err != nil {
    54  			d.Log("Could not purge resource:", err)
    55  		}
    56  	})
    57  
    58  	dbDSN := fmt.Sprintf("%s:%s@tcp(127.0.0.1:%s)/%s?tls=false",
    59  		defaultUser, defaultPassword, mysqlContainer.GetPort("3306/tcp"), defaultDB,
    60  	)
    61  	// exponential backoff-retry, because the application in the container might not be ready to accept connections yet
    62  	err = pool.Retry(func() (err error) {
    63  		var w bytes.Buffer
    64  		code, err := mysqlContainer.Exec([]string{
    65  			"bash",
    66  			"-c",
    67  			"mysqladmin ping -h 127.0.0.1 --silent",
    68  		}, dockertest.ExecOptions{StdOut: &w, StdErr: &w})
    69  		if err != nil {
    70  			return err
    71  		}
    72  		if code != 0 {
    73  			return fmt.Errorf("mysql not ready:\n%s" + w.String())
    74  		}
    75  		return nil
    76  	})
    77  	if err != nil {
    78  		return nil, fmt.Errorf("pinging container: %w", err)
    79  	}
    80  	return &Resource{
    81  		DBDsn:    dbDSN,
    82  		Database: defaultDB,
    83  		User:     defaultUser,
    84  		Password: defaultPassword,
    85  		Host:     "localhost",
    86  		Port:     mysqlContainer.GetPort("3306/tcp"),
    87  	}, nil
    88  }