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

143 lines
5.1 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package containers
import (
"strconv"
"strings"
"testing"
"time"
"github.com/testcontainers/testcontainers-go"
"github.com/testcontainers/testcontainers-go/wait"
)
// Credentials baked into every test PostgreSQL container.
const (
PostgresUsername = "testuser"
PostgresPassword = "testpassword"
PostgresDatabase = "testdb"
)
const postgresPort = "5432/tcp"
// postgresStartupTimeout is generous because go test -p=N boots many containers at once; under CPU
// contention a cold start runs far longer than its uncontended time, and a fast host returns as
// soon as the server is ready, so the high ceiling costs nothing there.
const postgresStartupTimeout = 240 * time.Second
func postgresEnv() map[string]string {
return map[string]string{
"POSTGRES_DB": PostgresDatabase,
"POSTGRES_USER": PostgresUsername,
"POSTGRES_PASSWORD": PostgresPassword,
}
}
// postgresReady waits for the network-listening server. The entrypoint starts a temporary
// socket-only server for initdb and then restarts the real one, so "ready to accept connections"
// is logged twice; waiting for the second occurrence avoids racing the socket-only server.
func postgresReady() wait.Strategy {
return wait.ForAll(
wait.ForLog("database system is ready to accept connections").
WithOccurrence(2).WithStartupTimeout(postgresStartupTimeout),
wait.ForListeningPort(postgresPort),
)
}
// postgresRequest builds the container request for image (e.g. "postgres:16"). The durability
// flags are safe for a throwaway server and a large speedup for the write-heavy e2e restore.
func postgresRequest(image string) testcontainers.ContainerRequest {
return testcontainers.ContainerRequest{
Image: image,
ExposedPorts: []string{postgresPort},
Env: postgresEnv(),
Cmd: []string{"-c", "fsync=off", "-c", "full_page_writes=off", "-c", "synchronous_commit=off"},
Tmpfs: map[string]string{postgresDataDir(image): dataDirTmpfsOptions},
WaitingFor: postgresReady(),
}
}
// postgresDataDir returns the data directory to mount on tmpfs for image. postgres 1417 keep
// PGDATA and the data VOLUME at /var/lib/postgresql/data. postgres:18 relocated PGDATA and moved
// the volume up to /var/lib/postgresql; mounting tmpfs at the old path there leaves a stray empty
// dir the entrypoint's layout detection rejects, so the server exits before becoming ready.
// Mounting at the parent volume avoids that. An unparseable tag falls back to the pre-18 path.
func postgresDataDir(image string) string {
if postgresMajorVersion(image) >= 18 {
return "/var/lib/postgresql"
}
return "/var/lib/postgresql/data"
}
// PostgresMajorVersion returns the major version from an image like "postgres:16" or
// "postgres:17.2", or 0 when the tag is missing or not a leading integer (treated as pre-18).
func PostgresMajorVersion(image string) int {
return postgresMajorVersion(image)
}
// postgresMajorVersion returns the major version from an image like "postgres:16" or
// "postgres:17.2", or 0 when the tag is missing or not a leading integer (treated as pre-18).
func postgresMajorVersion(image string) int {
_, tag, hasTag := strings.Cut(image, ":")
if !hasTag {
return 0
}
major, _, _ := strings.Cut(tag, ".")
version, err := strconv.Atoi(major)
if err != nil {
return 0
}
return version
}
// StartPostgres boots a PostgreSQL server from image (e.g. "postgres:16").
func StartPostgres(t *testing.T, image string) Endpoint {
t.Helper()
return start(t, postgresRequest(image), postgresPort)
}
// StartPostgresSSL boots an ssl=on PostgreSQL whose pg_hba.conf rejects non-TLS TCP. The image is
// built from contextDir (Dockerfile, server cert/key, pg_hba.conf) because PostgreSQL refuses a key
// file that is group/world-readable or not owned by postgres — the Dockerfile chowns+chmods it,
// which a copied-in file cannot. The test connects with sslmode=require.
func StartPostgresSSL(t *testing.T, contextDir string) Endpoint {
t.Helper()
return startPostgresBuild(t, contextDir, "databasus-test-postgres-ssl")
}
// StartPostgresMtls boots a PostgreSQL that also requires a client certificate signed by its ca.crt
// (pg_hba clientcert=verify-ca). Same build rationale as StartPostgresSSL; the test connects with
// sslmode=verify-ca and a client cert/key.
func StartPostgresMtls(t *testing.T, contextDir string) Endpoint {
t.Helper()
return startPostgresBuild(t, contextDir, "databasus-test-postgres-mtls")
}
// startPostgresBuild builds the image from contextDir/Dockerfile and boots it. The stable repo tag
// plus KeepImage lets Docker's layer cache skip the rebuild on repeat runs; the readiness flags
// live in the Dockerfile's CMD, so the request only sets the env and wait strategy.
func startPostgresBuild(t *testing.T, contextDir, repo string) Endpoint {
t.Helper()
req := testcontainers.ContainerRequest{
FromDockerfile: testcontainers.FromDockerfile{
Context: contextDir,
Dockerfile: "Dockerfile",
Repo: repo,
Tag: "latest",
KeepImage: true,
},
ExposedPorts: []string{postgresPort},
Env: postgresEnv(),
WaitingFor: postgresReady(),
}
return start(t, req, postgresPort)
}