2022-08-08 22:14:42 +03:00
|
|
|
//go:build mage
|
2020-08-06 20:58:47 +03:00
|
|
|
|
|
|
|
// This magefile contains targets for starting and stopping
|
|
|
|
// the Sakila test containers locally.
|
|
|
|
|
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"fmt"
|
|
|
|
"sync"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/testcontainers/testcontainers-go/wait"
|
2022-12-17 01:54:09 +03:00
|
|
|
|
|
|
|
"github.com/magefile/mage/mg"
|
2020-08-06 20:58:47 +03:00
|
|
|
"golang.org/x/sync/errgroup"
|
|
|
|
|
|
|
|
"github.com/testcontainers/testcontainers-go"
|
|
|
|
)
|
|
|
|
|
|
|
|
// Sakila is the mage namespace for sakila targets.
|
|
|
|
type Sakila mg.Namespace
|
|
|
|
|
|
|
|
const startupTimeout = time.Minute * 5
|
|
|
|
|
2022-12-18 02:11:33 +03:00
|
|
|
// requests is the set of database server containers required for
|
2020-08-06 20:58:47 +03:00
|
|
|
// integration testing.
|
2022-08-08 22:14:42 +03:00
|
|
|
//
|
2022-12-18 02:11:33 +03:00
|
|
|
// See: https://golang.testcontainers.org/features/creating_container/
|
2022-08-08 22:14:42 +03:00
|
|
|
//
|
2022-12-18 02:11:33 +03:00
|
|
|
// FIXME: huzzah
|
|
|
|
// TODO: The wait.ForLog mechanism is probably not fully correct for any of the
|
|
|
|
// containers (e.g. the string may appear multiple times in the log output),
|
|
|
|
// thus the containers may not have started fully when WaitingFor completes.
|
|
|
|
var requests = []testcontainers.ContainerRequest{
|
|
|
|
//{
|
|
|
|
// Image: "sakiladb/sqlserver:2017",
|
|
|
|
// Name: "sakiladb-sqlserver-2017",
|
|
|
|
// ExposedPorts: []string{"14337:1433"},
|
|
|
|
// WaitingFor: wait.ForLog("Changed database context to 'sakila'.").WithStartupTimeout(startupTimeout),
|
|
|
|
//},
|
2022-11-20 21:59:35 +03:00
|
|
|
// {
|
|
|
|
// Image: "sakiladb/postgres:9",
|
|
|
|
// Name: "sakiladb-postgres-9",
|
|
|
|
// ExposedPorts: []string{"54329:5432"},
|
|
|
|
// WaitingFor: wait.ForLog("PostgreSQL init process complete; ready for start up.").WithStartupTimeout(startupTimeout),
|
|
|
|
// },
|
|
|
|
// {
|
|
|
|
// Image: "sakiladb/postgres:10",
|
|
|
|
// Name: "sakiladb-postgres-10",
|
|
|
|
// ExposedPorts: []string{"54330:5432"},
|
|
|
|
// WaitingFor: wait.ForLog("PostgreSQL init process complete; ready for start up.").WithStartupTimeout(startupTimeout),
|
|
|
|
// },
|
|
|
|
// {
|
|
|
|
// Image: "sakiladb/postgres:11",
|
|
|
|
// Name: "sakiladb-postgres-11",
|
|
|
|
// ExposedPorts: []string{"54331:5432"},
|
|
|
|
// WaitingFor: wait.ForLog("PostgreSQL init process complete; ready for start up.").WithStartupTimeout(startupTimeout),
|
|
|
|
// },
|
2022-12-17 01:54:09 +03:00
|
|
|
{
|
|
|
|
Image: "sakiladb/postgres:12",
|
|
|
|
Name: "sakiladb-postgres-12",
|
|
|
|
ExposedPorts: []string{"54332:5432"},
|
|
|
|
WaitingFor: wait.ForLog("PostgreSQL init process complete; ready for start up.").WithStartupTimeout(startupTimeout),
|
|
|
|
},
|
2022-11-20 21:59:35 +03:00
|
|
|
// {
|
|
|
|
// Image: "sakiladb/mysql:5.6",
|
|
|
|
// Name: "sakiladb-mysql-5.6",
|
|
|
|
// ExposedPorts: []string{"33066:3306"},
|
|
|
|
// WaitingFor: wait.ForLog("[Note] mysqld: ready for connections.").WithStartupTimeout(startupTimeout),
|
|
|
|
// },
|
|
|
|
// {
|
|
|
|
// Image: "sakiladb/mysql:5.7",
|
|
|
|
// Name: "sakiladb-mysql-5.7",
|
|
|
|
// ExposedPorts: []string{"33067:3306"},
|
|
|
|
// WaitingFor: wait.ForLog("[Note] mysqld: ready for connections.").WithStartupTimeout(startupTimeout),
|
|
|
|
// },
|
|
|
|
// {
|
|
|
|
// Image: "sakiladb/mysql:8",
|
|
|
|
// Name: "sakiladb-mysql-8",
|
|
|
|
// ExposedPorts: []string{"33068:3306"},
|
|
|
|
// WaitingFor: wait.ForLog("[Server] /usr/sbin/mysqld: ready for connections.").WithStartupTimeout(startupTimeout),
|
|
|
|
// },
|
|
|
|
}
|
|
|
|
|
|
|
|
var startedContainers []testcontainers.Container
|
|
|
|
var startedContainersMu sync.Mutex
|
|
|
|
|
|
|
|
func containerStarted(cont testcontainers.Container) {
|
|
|
|
startedContainersMu.Lock()
|
|
|
|
defer startedContainersMu.Unlock()
|
|
|
|
|
|
|
|
startedContainers = append(startedContainers, cont)
|
2020-08-06 20:58:47 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// StartAll starts all the sakila database server containers locally.
|
|
|
|
// Use RemoveAll to stop & remove the containers.
|
2022-11-20 21:59:35 +03:00
|
|
|
func (Sakila) StartAll(ctx context.Context) error {
|
2020-08-06 20:58:47 +03:00
|
|
|
const envarInfo = `export SQ_TEST_SRC__SAKILA_MY56=localhost:33066
|
|
|
|
export SQ_TEST_SRC__SAKILA_MY57=localhost:33067
|
|
|
|
export SQ_TEST_SRC__SAKILA_MY8=localhost:33068
|
|
|
|
export SQ_TEST_SRC__SAKILA_PG9=localhost:54329
|
|
|
|
export SQ_TEST_SRC__SAKILA_PG10=localhost:54330
|
|
|
|
export SQ_TEST_SRC__SAKILA_PG11=localhost:54331
|
|
|
|
export SQ_TEST_SRC__SAKILA_PG12=localhost:54332
|
|
|
|
export SQ_TEST_SRC__SAKILA_MS17=localhost:14337`
|
|
|
|
|
|
|
|
fmt.Println("Starting all containers...")
|
|
|
|
fmt.Printf("'src' the following:\n===\n%s\n===\n\n", envarInfo)
|
|
|
|
|
2022-11-20 21:59:35 +03:00
|
|
|
errGroup, ctx := errgroup.WithContext(ctx)
|
2020-08-06 20:58:47 +03:00
|
|
|
|
2022-12-18 02:11:33 +03:00
|
|
|
for _, containerReq := range requests {
|
2022-11-20 21:59:35 +03:00
|
|
|
containerReq := containerReq
|
2020-08-06 20:58:47 +03:00
|
|
|
// The user invokes mage sakila:RemoveAll to remove all the containers.
|
2022-11-20 21:59:35 +03:00
|
|
|
containerReq.SkipReaper = true
|
2020-08-06 20:58:47 +03:00
|
|
|
|
|
|
|
errGroup.Go(func() error {
|
2022-11-20 21:59:35 +03:00
|
|
|
fmt.Printf("Starting container %s for %s\n", containerReq.Name, containerReq.Image)
|
2020-08-06 20:58:47 +03:00
|
|
|
|
2022-11-20 21:59:35 +03:00
|
|
|
gotContainer, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{
|
|
|
|
ContainerRequest: containerReq,
|
2020-08-06 20:58:47 +03:00
|
|
|
Started: true,
|
|
|
|
})
|
|
|
|
|
|
|
|
if err != nil {
|
2022-11-20 21:59:35 +03:00
|
|
|
return fmt.Errorf("image %s: %w", containerReq.Image, err)
|
2020-08-06 20:58:47 +03:00
|
|
|
}
|
|
|
|
|
2022-11-20 21:59:35 +03:00
|
|
|
containerStarted(gotContainer)
|
|
|
|
|
|
|
|
fmt.Printf("SUCCESS: started container %s for %s\n", containerReq.Name, containerReq.Image)
|
2020-08-06 20:58:47 +03:00
|
|
|
return nil
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
err := errGroup.Wait()
|
|
|
|
if err != nil {
|
|
|
|
fmt.Println("ERROR: problem reported trying to start all containers (some or all containers may actually have started)")
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
fmt.Println("SUCCESS: All database containers started")
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// RemoveAll removes all the Sakila docker containers.
|
2022-11-20 21:59:35 +03:00
|
|
|
func (Sakila) RemoveAll(ctx context.Context) {
|
2020-08-06 20:58:47 +03:00
|
|
|
wg := &sync.WaitGroup{}
|
2022-12-18 02:11:33 +03:00
|
|
|
wg.Add(len(requests))
|
|
|
|
for _, containerReq := range requests {
|
2022-11-20 21:59:35 +03:00
|
|
|
containerReq := containerReq
|
2020-08-06 20:58:47 +03:00
|
|
|
|
|
|
|
go func() {
|
|
|
|
defer wg.Done()
|
|
|
|
// We don't care if there's an error
|
2022-11-20 21:59:35 +03:00
|
|
|
_ = execDocker("rm", "-f", containerReq.Name)
|
2020-08-06 20:58:47 +03:00
|
|
|
}()
|
|
|
|
}
|
|
|
|
|
|
|
|
wg.Wait()
|
|
|
|
}
|