Skip to content

Commit

Permalink
WIP: perform API contract testing using Testcontainers
Browse files Browse the repository at this point in the history
Signed-off-by: Paul Balogh <[email protected]>
  • Loading branch information
javaducky committed Jan 22, 2024
1 parent abdde5f commit ff6a4af
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 3 deletions.
1 change: 0 additions & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,5 @@
.git/
.gitignore
.idea/
Dockerfile
bin/
gorm.db
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ deps:
go mod tidy

## test: Runs unit tests for the application.
test: deps
go test -cover ./...
test:
go test -test.short -cover ./...

## imports: Organizes imports within the codebase.
imports:
Expand Down
86 changes: 86 additions & 0 deletions api/api_contract_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package api

import (
"context"
"net"
"net/http"
"testing"
"time"

"github.com/stretchr/testify/assert"
"github.com/testcontainers/testcontainers-go"
"github.com/testcontainers/testcontainers-go/wait"
)

type serviceContainer struct {
testcontainers.Container
URI string
}

func TestAPIContract(t *testing.T) {
if testing.Short() {
t.Skip("skipping integration tests")
}
t.Parallel()

// Build the image and start a container with our service.
svcContainer, err := buildServiceContainer(t)
if err != nil {
t.Fatal(err)
}

// TODO Start a k6 container to run our compliance script
//nolint:noctx
resp, err := http.Get(svcContainer.URI + "/api/places")
assert.NoError(t, err)

defer resp.Body.Close()
assert.Equal(t, http.StatusOK, resp.StatusCode)
}

// buildServiceContainer will build and start our service within a container based on current source.
func buildServiceContainer(t *testing.T) (*serviceContainer, error) {
ctx := context.Background()

container, err := testcontainers.GenericContainer(
ctx,
testcontainers.GenericContainerRequest{
ContainerRequest: testcontainers.ContainerRequest{
FromDockerfile: testcontainers.FromDockerfile{
Context: "..",
Dockerfile: "Dockerfile",
PrintBuildLog: false,
KeepImage: false,
},
ExposedPorts: []string{"9092/tcp"},
Cmd: []string{"/bin/sh", "-c", "/app/weesvc migrate; /app/weesvc serve"},
WaitingFor: wait.ForHTTP("/api/hello").WithStartupTimeout(10 * time.Second),
},
Started: true,
},
)
if err != nil {
return nil, err
}

t.Cleanup(func() {
if terr := container.Terminate(ctx); terr != nil {
t.Fatalf("failed to terminate ServiceContainer: %s", terr)
}
})

ip, err := container.Host(ctx)
if err != nil {
return nil, err
}

mappedPort, err := container.MappedPort(ctx, "9092")
if err != nil {
return nil, err
}

return &serviceContainer{
Container: container,
URI: "http://" + net.JoinHostPort(ip, mappedPort.Port()),
}, nil
}

0 comments on commit ff6a4af

Please sign in to comment.