mirror of
https://github.com/gotenberg/gotenberg.git
synced 2026-10-16 17:23:17 +01:00
test(integration): drop the per-scenario Docker network
This commit is contained in:
@@ -11,7 +11,6 @@ import (
|
|||||||
"github.com/moby/moby/client"
|
"github.com/moby/moby/client"
|
||||||
"github.com/testcontainers/testcontainers-go"
|
"github.com/testcontainers/testcontainers-go"
|
||||||
"github.com/testcontainers/testcontainers-go/exec"
|
"github.com/testcontainers/testcontainers-go/exec"
|
||||||
"github.com/testcontainers/testcontainers-go/network"
|
|
||||||
"github.com/testcontainers/testcontainers-go/wait"
|
"github.com/testcontainers/testcontainers-go/wait"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -21,11 +20,13 @@ import (
|
|||||||
const testcontainersLabel = "org.testcontainers"
|
const testcontainersLabel = "org.testcontainers"
|
||||||
|
|
||||||
// PruneOrphanedNetworks removes dangling networks created by the test suite.
|
// PruneOrphanedNetworks removes dangling networks created by the test suite.
|
||||||
// Each scenario spins a dedicated network, and a failed container start can
|
// Scenarios no longer create one: the Gotenberg container is reached over its
|
||||||
// leak one before teardown records it. Leaked networks consume Docker's
|
// mapped port and the host-side helper over host.docker.internal, so the
|
||||||
// predefined address pools until none remain and every later scenario fails
|
// default bridge suffices. This stays as cheap insurance against networks
|
||||||
// with "all predefined address pools have been fully subnetted". Call this
|
// leaked by an older suite version or an interrupted run, which consume
|
||||||
// before a run and between retries to reclaim the subnets.
|
// Docker's predefined address pools until none remain and every later
|
||||||
|
// scenario fails with "all predefined address pools have been fully
|
||||||
|
// subnetted".
|
||||||
//
|
//
|
||||||
// Only unused networks bearing the testcontainers label are removed, so
|
// Only unused networks bearing the testcontainers label are removed, so
|
||||||
// running containers and operator networks are never affected.
|
// running containers and operator networks are never affected.
|
||||||
@@ -99,17 +100,18 @@ func applyDefaultEnv(env map[string]string) map[string]string {
|
|||||||
return env
|
return env
|
||||||
}
|
}
|
||||||
|
|
||||||
func startGotenbergContainer(ctx context.Context, env map[string]string) (*testcontainers.DockerNetwork, testcontainers.Container, error) {
|
// startGotenbergContainer starts a Gotenberg container on Docker's default
|
||||||
|
// bridge. No dedicated network is created: the suite addresses the container
|
||||||
|
// through container.Host plus its mapped port, and the container reaches the
|
||||||
|
// host-side webhook and static file server through the host.docker.internal
|
||||||
|
// alias below, so a per-scenario network would carry no traffic while still
|
||||||
|
// consuming one of Docker's predefined subnets.
|
||||||
|
func startGotenbergContainer(ctx context.Context, env map[string]string) (testcontainers.Container, error) {
|
||||||
ctx, cancel := context.WithTimeout(ctx, 2*time.Minute)
|
ctx, cancel := context.WithTimeout(ctx, 2*time.Minute)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
env = applyDefaultEnv(env)
|
env = applyDefaultEnv(env)
|
||||||
|
|
||||||
n, err := network.New(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, fmt.Errorf("create Gotenberg container network: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
healthPath := "/health"
|
healthPath := "/health"
|
||||||
if env["API_ROOT_PATH"] != "" {
|
if env["API_ROOT_PATH"] != "" {
|
||||||
healthPath = fmt.Sprintf("%shealth", env["API_ROOT_PATH"])
|
healthPath = fmt.Sprintf("%shealth", env["API_ROOT_PATH"])
|
||||||
@@ -122,7 +124,6 @@ func startGotenbergContainer(ctx context.Context, env map[string]string) (*testc
|
|||||||
HostConfigModifier: func(hostConfig *container.HostConfig) {
|
HostConfigModifier: func(hostConfig *container.HostConfig) {
|
||||||
hostConfig.ExtraHosts = []string{"host.docker.internal:host-gateway"}
|
hostConfig.ExtraHosts = []string{"host.docker.internal:host-gateway"}
|
||||||
},
|
},
|
||||||
Networks: []string{n.Name},
|
|
||||||
WaitingFor: wait.ForHTTP(healthPath),
|
WaitingFor: wait.ForHTTP(healthPath),
|
||||||
Env: env,
|
Env: env,
|
||||||
}
|
}
|
||||||
@@ -148,19 +149,10 @@ func startGotenbergContainer(ctx context.Context, env map[string]string) (*testc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The network is already created. The scenario teardown only
|
return nil, err
|
||||||
// removes networks it knows about, and the caller discards n on
|
|
||||||
// error, so remove it here to avoid leaking a subnet on every
|
|
||||||
// failed start. Leaked networks accumulate until Docker's address
|
|
||||||
// pools are fully subnetted and all later scenarios fail.
|
|
||||||
if errRemove := n.Remove(ctx); errRemove != nil {
|
|
||||||
err = fmt.Errorf("%w (also failed to remove network: %v)", err, errRemove)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return n, c, nil
|
return c, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func execCommandInIntegrationToolsContainer(ctx context.Context, cmd []string, path string) (string, error) {
|
func execCommandInIntegrationToolsContainer(ctx context.Context, cmd []string, path string) (string, error) {
|
||||||
|
|||||||
@@ -86,16 +86,15 @@ func findScenarioLine(filePath, name string) int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type scenario struct {
|
type scenario struct {
|
||||||
resp *httptest.ResponseRecorder
|
resp *httptest.ResponseRecorder
|
||||||
concurrentResps []*httptest.ResponseRecorder
|
concurrentResps []*httptest.ResponseRecorder
|
||||||
probeResps []*httptest.ResponseRecorder
|
probeResps []*httptest.ResponseRecorder
|
||||||
sequentialResps []*httptest.ResponseRecorder
|
sequentialResps []*httptest.ResponseRecorder
|
||||||
workdir string
|
workdir string
|
||||||
teststoreDir string
|
teststoreDir string
|
||||||
gotenbergContainer testcontainers.Container
|
gotenbergContainer testcontainers.Container
|
||||||
gotenbergContainerNetwork *testcontainers.DockerNetwork
|
server *server
|
||||||
server *server
|
hostPort int
|
||||||
hostPort int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *scenario) reset(ctx context.Context) error {
|
func (s *scenario) reset(ctx context.Context) error {
|
||||||
@@ -123,11 +122,10 @@ func (s *scenario) reset(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *scenario) iHaveADefaultGotenbergContainer(ctx context.Context) error {
|
func (s *scenario) iHaveADefaultGotenbergContainer(ctx context.Context) error {
|
||||||
n, c, err := startGotenbergContainer(ctx, nil)
|
c, err := startGotenbergContainer(ctx, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("create Gotenberg container: %s", err)
|
return fmt.Errorf("create Gotenberg container: %s", err)
|
||||||
}
|
}
|
||||||
s.gotenbergContainerNetwork = n
|
|
||||||
s.gotenbergContainer = c
|
s.gotenbergContainer = c
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -137,11 +135,10 @@ func (s *scenario) iHaveAGotenbergContainerWithTheFollowingEnvironmentVariables(
|
|||||||
for _, row := range envTable.Rows {
|
for _, row := range envTable.Rows {
|
||||||
env[row.Cells[0].Value] = row.Cells[1].Value
|
env[row.Cells[0].Value] = row.Cells[1].Value
|
||||||
}
|
}
|
||||||
n, c, err := startGotenbergContainer(ctx, env)
|
c, err := startGotenbergContainer(ctx, env)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("create Gotenberg container: %s", err)
|
return fmt.Errorf("create Gotenberg container: %s", err)
|
||||||
}
|
}
|
||||||
s.gotenbergContainerNetwork = n
|
|
||||||
s.gotenbergContainer = c
|
s.gotenbergContainer = c
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -1812,12 +1809,6 @@ func InitializeScenario(ctx *godog.ScenarioContext) {
|
|||||||
return ctx, fmt.Errorf("terminate Gotenberg container: %w", errTerminate)
|
return ctx, fmt.Errorf("terminate Gotenberg container: %w", errTerminate)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if s.gotenbergContainerNetwork != nil {
|
|
||||||
errRemove := s.gotenbergContainerNetwork.Remove(ctx)
|
|
||||||
if errRemove != nil {
|
|
||||||
return ctx, fmt.Errorf("remove Gotenberg container network: %w", errRemove)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ctx, nil
|
return ctx, nil
|
||||||
})
|
})
|
||||||
ctx.After(func(ctx context.Context, sc *godog.Scenario, err error) (context.Context, error) {
|
ctx.After(func(ctx context.Context, sc *godog.Scenario, err error) (context.Context, error) {
|
||||||
|
|||||||
Reference in New Issue
Block a user