Files
wehub-resource-sync 75f3dd141c
CodeQL / Analyze (go) (push) Has been cancelled
CodeQL / Analyze (actions) (push) Has been cancelled
CodeQL / Analyze (javascript-typescript) (push) Has been cancelled
CI and Release / lint-frontend (push) Has been cancelled
CI and Release / dockerfile-scan (push) Has been cancelled
CI and Release / test-frontend (push) Has been cancelled
CI and Release / lint-verification-agent (push) Has been cancelled
CI and Release / test-verification-agent (push) Has been cancelled
CI and Release / e2e-verification-agent (push) Has been cancelled
CI and Release / test-backend (push) Has been cancelled
CI and Release / build-dev-image (push) Has been cancelled
CI and Release / push-dev-image (push) Has been cancelled
CI and Release / build-image (push) Has been cancelled
CI and Release / build-verification-image (push) Has been cancelled
CI and Release / determine-version (push) Has been cancelled
CI and Release / push-image (push) Has been cancelled
CI and Release / push-verification-image (12) (push) Has been cancelled
CI and Release / lint-backend (push) Has been cancelled
CI and Release / push-verification-image (17) (push) Has been cancelled
CI and Release / push-verification-image (18) (push) Has been cancelled
CI and Release / release (push) Has been cancelled
CI and Release / publish-helm-chart (push) Has been cancelled
CI and Release / push-verification-image (13) (push) Has been cancelled
CI and Release / push-verification-image (14) (push) Has been cancelled
CI and Release / push-verification-image (15) (push) Has been cancelled
CI and Release / push-verification-image (16) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:11:07 +08:00

102 lines
3.3 KiB
Go

package containers
import (
"testing"
"time"
"github.com/testcontainers/testcontainers-go"
"github.com/testcontainers/testcontainers-go/wait"
)
// Credentials baked into every test MySQL container.
const (
MysqlRootPassword = "rootpassword"
MysqlUsername = "testuser"
MysqlPassword = "testpassword"
MysqlDatabase = "testdb"
)
const mysqlPort = "3306/tcp"
// mysqlStartupTimeout is generous because go test -p=N boots many containers at once; the two-phase
// MySQL/MariaDB cold init (temp server for initdb, then a restart of the real one) runs under CPU
// contention and needs far more than its uncontended ~20s. A fast host returns as soon as the
// server is ready, so the ceiling is free there.
const mysqlStartupTimeout = 300 * time.Second
func mysqlEnv() map[string]string {
return map[string]string{
"MYSQL_ROOT_PASSWORD": MysqlRootPassword,
"MYSQL_DATABASE": MysqlDatabase,
"MYSQL_USER": MysqlUsername,
"MYSQL_PASSWORD": MysqlPassword,
}
}
// mysqlFamilyReady waits for the network-listening server on port. The entrypoint starts a
// temporary socket-only server for initdb and then restarts the real one, so "ready for
// connections" is logged twice; the second occurrence is the real server. MariaDB shares this
// behaviour, so it passes its own port.
func mysqlFamilyReady(port string) wait.Strategy {
return wait.ForAll(
wait.ForLog("ready for connections").WithOccurrence(2).WithStartupTimeout(mysqlStartupTimeout),
wait.ForListeningPort(port),
)
}
// mysqlFamilyCmd returns the server flags shared by MySQL and MariaDB: the utf8mb4 charset
// defaults, plus durability-off flags (no fsync, doublewrite or binary log) that are safe for
// throwaway tmpfs containers and make the cold init and the e2e restore RAM-fast.
func mysqlFamilyCmd() []string {
return []string{
"--character-set-server=utf8mb4",
"--collation-server=utf8mb4_unicode_ci",
"--innodb-flush-log-at-trx-commit=0",
"--innodb-doublewrite=0",
"--sync-binlog=0",
"--skip-log-bin",
}
}
// mysqlCmd appends the native password plugin for mysql:8.0 (removed in 8.4+) to the shared family
// flags; later versions use the family flags unchanged.
func mysqlCmd(image string) []string {
cmd := mysqlFamilyCmd()
if image == "mysql:8.0" {
cmd = append(cmd, "--default-authentication-plugin=mysql_native_password")
}
return cmd
}
// mysqlRequest builds the container request for image (e.g. "mysql:8.0").
func mysqlRequest(image string) testcontainers.ContainerRequest {
return testcontainers.ContainerRequest{
Image: image,
ExposedPorts: []string{mysqlPort},
Env: mysqlEnv(),
Cmd: mysqlCmd(image),
Tmpfs: map[string]string{"/var/lib/mysql": dataDirTmpfsOptions},
WaitingFor: mysqlFamilyReady(mysqlPort),
}
}
// StartMysql boots a MySQL server from image (e.g. "mysql:8.0").
func StartMysql(t *testing.T, image string) Endpoint {
t.Helper()
return start(t, mysqlRequest(image), mysqlPort)
}
// StartMysqlSSL boots a MySQL server that rejects unencrypted connections. The image auto-generates
// its server certificates, so the test connects with tlsInsecure and no client cert.
func StartMysqlSSL(t *testing.T, image string) Endpoint {
t.Helper()
req := mysqlRequest(image)
req.Cmd = append(req.Cmd, "--require_secure_transport=ON")
return start(t, req, mysqlPort)
}