diff --git a/.github/workflows/coder.yaml b/.github/workflows/coder.yaml index 41f1dd04d4c7b..b63e0819419e2 100644 --- a/.github/workflows/coder.yaml +++ b/.github/workflows/coder.yaml @@ -164,7 +164,7 @@ jobs: run: DB=true gotestsum --jsonfile="gotests.json" --packages="./..." -- -covermode=atomic -coverprofile="gotests.coverage" -timeout=3m - -count=1 -race -parallel=1 + -count=1 -race -parallel=2 - uses: codecov/codecov-action@v2 if: github.actor != 'dependabot[bot]' diff --git a/database/postgres/postgres.go b/database/postgres/postgres.go index d022cd6669a8f..78d02de150ac8 100644 --- a/database/postgres/postgres.go +++ b/database/postgres/postgres.go @@ -4,6 +4,7 @@ import ( "database/sql" "fmt" "io/ioutil" + "net" "os" "time" @@ -22,6 +23,13 @@ func Open() (string, func(), error) { if err != nil { return "", nil, xerrors.Errorf("create tempdir: %w", err) } + // Pick an explicit port on the host to connect to 5432. + // This is necessary so we can configure the port to only use ipv4. + port, err := getFreePort() + if err != nil { + return "", nil, xerrors.Errorf("Unable to get free port: %w", err) + } + resource, err := pool.RunWithOptions(&dockertest.RunOptions{ Repository: "postgres", Tag: "11", @@ -33,6 +41,15 @@ func Open() (string, func(), error) { "PGDATA=/tmp", "listen_addresses = '*'", }, + PortBindings: map[docker.Port][]docker.PortBinding{ + "5432/tcp": {{ + // Manually specifying a host IP tells Docker just to use an IPV4 address. + // If we don't do this, we hit a fun bug: + // https://github.com/moby/moby/issues/42442 + // where the ipv4 and ipv6 ports might be _different_ and collide with other running docker containers. + HostIP: "0.0.0.0", + HostPort: fmt.Sprintf("%d", port)}}, + }, Mounts: []string{ // The postgres image has a VOLUME parameter in it's image. // If we don't mount at this point, Docker will allocate a @@ -76,3 +93,16 @@ func Open() (string, func(), error) { _ = os.RemoveAll(tempDir) }, nil } + +// getFreePort asks the kernel for a free open port that is ready to use. +func getFreePort() (port int, err error) { + // Binding to port 0 tells the OS to grab a port for us: + // https://stackoverflow.com/questions/1365265/on-localhost-how-do-i-pick-a-free-port-number + listener, err := net.Listen("tcp", "localhost:0") + if err != nil { + return 0, err + } + + defer listener.Close() + return listener.Addr().(*net.TCPAddr).Port, nil +}