diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ba1b16077..a92963a60 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -211,6 +211,8 @@ jobs: version: v1.58.2 - name: Run Go tests + env: + TESTCONTAINERS_RYUK_DISABLED: true run: go test ./... build-docker: diff --git a/go.mod b/go.mod index 60f9ed4d9..31ad19890 100644 --- a/go.mod +++ b/go.mod @@ -16,6 +16,8 @@ require github.com/BurntSushi/toml v1.4.0 require ( github.com/Khan/genqlient v0.7.0 github.com/deepmap/oapi-codegen/v2 v2.1.0 + github.com/docker/docker v27.0.3+incompatible + github.com/docker/go-connections v0.5.0 github.com/golang-migrate/migrate/v4 v4.17.1 github.com/jackc/pgx/v5 v5.6.0 github.com/lmittmann/tint v1.0.4 @@ -52,8 +54,6 @@ require ( github.com/deckarep/golang-set/v2 v2.6.0 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect github.com/distribution/reference v0.6.0 // indirect - github.com/docker/docker v27.0.3+incompatible // indirect - github.com/docker/go-connections v0.5.0 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/ethereum/c-kzg-4844 v1.0.2 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect diff --git a/internal/deps/deps.go b/internal/deps/deps.go index 7742fb830..b985d2a36 100644 --- a/internal/deps/deps.go +++ b/internal/deps/deps.go @@ -13,6 +13,8 @@ import ( "sync" "time" + "github.com/docker/docker/api/types/container" + "github.com/docker/go-connections/nat" "github.com/testcontainers/testcontainers-go" "github.com/testcontainers/testcontainers-go/wait" ) @@ -38,6 +40,11 @@ const ( devnetKey ) +const ( + postgresContainerPort = "5432/tcp" + devnetContainerPort = "8545/tcp" +) + // Struct to hold Node dependencies containers configurations type DepsConfig struct { Postgres *PostgresConfig @@ -159,6 +166,24 @@ func createHook(finishedWaitGroup *sync.WaitGroup) []testcontainers.ContainerLif } } +func buildPortMap(portSpec string) (nat.PortMap, error) { + portMappings, err := nat.ParsePortSpec(portSpec) + if err != nil { + return nil, err + } + + portMap := nat.PortMap{} + for _, portMapping := range portMappings { + portMap[portMapping.Port] = append( + portMap[portMapping.Port], + nat.PortBinding{ + HostIP: portMapping.Binding.HostIP, + HostPort: portMapping.Binding.HostPort, + }) + } + return portMap, nil +} + // Run starts the Node dependencies containers. // The returned DepContainers struct can be used to gracefully // terminate the containers using the Terminate method @@ -173,20 +198,30 @@ func Run(ctx context.Context, depsConfig DepsConfig) (*DepsContainers, error) { WithOccurrence(numPostgresCheckReadyAttempts). WithPollInterval(pollInterval) - postgresExposedPorts := "5432/tcp" + postgresPortSpec := postgresContainerPort if depsConfig.Postgres.Port != "" { - postgresExposedPorts = strings.Join([]string{ - depsConfig.Postgres.Port, ":", postgresExposedPorts}, "") + postgresPortSpec = strings.Join([]string{ + depsConfig.Postgres.Port, ":", postgresPortSpec}, "") + } + + portMap, err := buildPortMap(postgresPortSpec) + if err != nil { + return nil, err } + postgresReq := testcontainers.ContainerRequest{ Image: depsConfig.Postgres.DockerImage, - ExposedPorts: []string{postgresExposedPorts}, + ExposedPorts: []string{postgresContainerPort}, WaitingFor: postgresWaitStrategy, Env: map[string]string{ "POSTGRES_PASSWORD": depsConfig.Postgres.Password, }, LifecycleHooks: createHook(&finishedWaitGroup), + HostConfigModifier: func(hostConfig *container.HostConfig) { + hostConfig.PortBindings = portMap + }, } + postgres, err := testcontainers.GenericContainer( ctx, testcontainers.GenericContainerRequest{ @@ -204,11 +239,18 @@ func Run(ctx context.Context, depsConfig DepsConfig) (*DepsContainers, error) { if depsConfig.Devnet != nil { - devnetExposedPort := "8545/tcp" + devnetPortSpec := devnetContainerPort if depsConfig.Devnet.Port != "" { - devnetExposedPort = strings.Join([]string{ - depsConfig.Devnet.Port, ":", devnetExposedPort}, "") + devnetPortSpec = strings.Join([]string{ + depsConfig.Devnet.Port, ":", devnetPortSpec}, "") + } + + portMap, err := buildPortMap(devnetPortSpec) + + if err != nil { + return nil, err } + cmd := []string{ "anvil", "--load-state", @@ -225,11 +267,15 @@ func Run(ctx context.Context, depsConfig DepsConfig) (*DepsContainers, error) { } devNetReq := testcontainers.ContainerRequest{ Image: depsConfig.Devnet.DockerImage, - ExposedPorts: []string{devnetExposedPort}, + ExposedPorts: []string{devnetContainerPort}, WaitingFor: waitStrategy, Cmd: cmd, LifecycleHooks: createHook(&finishedWaitGroup), + HostConfigModifier: func(hostConfig *container.HostConfig) { + hostConfig.PortBindings = portMap + }, } + devnet, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{ ContainerRequest: devNetReq, Started: true,