feat: backend service
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
package testenv
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"testing"
|
||||
|
||||
"github.com/testcontainers/testcontainers-go"
|
||||
)
|
||||
|
||||
// Platform aggregates a fully booted Galaxy stack: shared Docker
|
||||
// network, Postgres, Redis, mailpit, backend and gateway. Tests use
|
||||
// this struct to access HTTP/gRPC endpoints, mailpit and backend
|
||||
// admin without touching testcontainers directly.
|
||||
type Platform struct {
|
||||
Network string
|
||||
Postgres *Postgres
|
||||
Redis *Redis
|
||||
Mailpit *Mailpit
|
||||
Backend *BackendContainer
|
||||
Gateway *GatewayContainer
|
||||
}
|
||||
|
||||
// BootstrapOptions tunes platform-level knobs that flow into backend
|
||||
// or gateway configuration. The zero value is valid and produces a
|
||||
// stack with sensible defaults for happy-path scenarios.
|
||||
type BootstrapOptions struct {
|
||||
BackendExtra map[string]string
|
||||
GatewayExtra map[string]string
|
||||
}
|
||||
|
||||
// Bootstrap builds three Docker images (backend, gateway, optionally
|
||||
// the engine in the caller), spins up Postgres, Redis, mailpit, then
|
||||
// boots backend and gateway connected to those services. It registers
|
||||
// t.Cleanup hooks for every component, so callers do not own
|
||||
// teardown.
|
||||
//
|
||||
// The function calls RequireDocker and skips the test gracefully if
|
||||
// the daemon is unreachable, so every scenario can start with a
|
||||
// single Bootstrap call.
|
||||
func Bootstrap(t *testing.T, opts BootstrapOptions) *Platform {
|
||||
t.Helper()
|
||||
RequireDocker(t)
|
||||
|
||||
net := StartNetwork(t)
|
||||
pg := StartPostgres(t, net.Name)
|
||||
redis := StartRedis(t, net.Name)
|
||||
mp := StartMailpit(t, net.Name)
|
||||
geoip := SyntheticGeoIPDB(t)
|
||||
|
||||
backend := StartBackend(t, BackendOptions{
|
||||
NetworkAlias: "backend",
|
||||
NetworkName: net.Name,
|
||||
PostgresDSN: pg.NetworkDSN,
|
||||
MailpitHost: "mailpit",
|
||||
MailpitPort: 1025,
|
||||
GeoIPHostPath: geoip,
|
||||
Extra: opts.BackendExtra,
|
||||
})
|
||||
gateway := StartGateway(t, GatewayOptions{
|
||||
NetworkAlias: "gateway",
|
||||
NetworkName: net.Name,
|
||||
BackendHTTPURL: "http://backend:8080",
|
||||
BackendGRPCURL: "backend:8081",
|
||||
RedisAddr: "redis:6379",
|
||||
Extra: opts.GatewayExtra,
|
||||
})
|
||||
|
||||
plat := &Platform{
|
||||
Network: net.Name,
|
||||
Postgres: pg,
|
||||
Redis: redis,
|
||||
Mailpit: mp,
|
||||
Backend: backend,
|
||||
Gateway: gateway,
|
||||
}
|
||||
t.Cleanup(func() {
|
||||
if !t.Failed() {
|
||||
return
|
||||
}
|
||||
dumpLogs(t, "backend", backend.Container)
|
||||
dumpLogs(t, "gateway", gateway.Container)
|
||||
})
|
||||
return plat
|
||||
}
|
||||
|
||||
// dumpLogs writes the container's stdout/stderr to test output. Used
|
||||
// only on failure to surface backend / gateway diagnostics.
|
||||
func dumpLogs(t *testing.T, name string, c testcontainers.Container) {
|
||||
t.Helper()
|
||||
if c == nil {
|
||||
return
|
||||
}
|
||||
rc, err := c.Logs(context.Background())
|
||||
if err != nil {
|
||||
t.Logf("%s logs unavailable: %v", name, err)
|
||||
return
|
||||
}
|
||||
defer rc.Close()
|
||||
body, _ := io.ReadAll(rc)
|
||||
t.Logf("--- %s container logs ---\n%s", name, string(body))
|
||||
}
|
||||
Reference in New Issue
Block a user