Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Set up testcontainers + add readme example as test #65

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
88 changes: 88 additions & 0 deletions end_to_end_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package vault

import (
"context"
"fmt"
"testing"

"github.com/stretchr/testify/require"
"github.com/testcontainers/testcontainers-go"
)

type VaultContainer struct {
testcontainers.Container
address string
}

func setupVaultContainer(ctx context.Context, rootToken string) (*VaultContainer, error) {
req := testcontainers.ContainerRequest{
Image: "vault",
ExposedPorts: []string{"8200/tcp"},
Env: map[string]string{
"VAULT_DEV_ROOT_TOKEN_ID": rootToken,
},
CapAdd: []string{"IPC_LOCK"},
}

container, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{
ContainerRequest: req,
Started: true,
})
if err != nil {
return nil, fmt.Errorf("unable to start container: %w", err)
}

ip, err := container.Host(ctx)
if err != nil {
return nil, fmt.Errorf("could not get container ip: %w", err)
}

mappedPort, err := container.MappedPort(ctx, "8200")
if err != nil {
return nil, fmt.Errorf("could not get mapped port from container: %w", err)
}

vaultContainer := VaultContainer{
Container: container,
address: fmt.Sprintf("http://%s:%s", ip, mappedPort.Port()),
}

return &vaultContainer, nil
}

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

const rootToken = "read&write"
ctx := context.Background()

vault, err := setupVaultContainer(ctx, rootToken)
require.NoError(t, err)
defer vault.Terminate(ctx)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd be interested in seeing how long it takes to bring up / shut down the Vault container. If we have one container per test, it may make sense to just have a few long-running containers for the entire test suite.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

once it was pulled (most of the time was spent downloading/extracting image), only a second or two to run!
lifetime of the container would definitely depend on the test
if you notice, the port mapping isn't a 1-to-1 (8200 doesn't map to 8200 local) so you can run tests in parallel


client, err := NewClient(Configuration{
BaseAddress: vault.address,
})
require.NoError(t, err)

require.NoError(t, client.SetToken(rootToken))

const secretPath = "/secret/data/my-secret"
expected := map[string]interface{}{
"password1": "abc123",
"password2": "trustno1",
}

_, err = client.Write(ctx, secretPath, map[string]interface{}{
"data": expected, // TODO: is this key always `data`?
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, for KVv2, the "data" element is part of the protocol (unfortunately). To address the confusion, we have introduced KV wrappers in the original vault/api library. The plan is to add something similar here at some point :)

})
require.NoError(t, err)

resp, err := client.Read(ctx, secretPath)
require.NoError(t, err)

// TODO: can we assert other things about the response here?
require.Equal(t, expected, resp.Data["data"])
}
33 changes: 32 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,46 @@ require (
github.com/hashicorp/go-rootcerts v1.0.2
github.com/hashicorp/go-secure-stdlib/strutil v0.1.2
github.com/stretchr/testify v1.8.0
github.com/testcontainers/testcontainers-go v0.14.1-0.20221016081642-d9bb48832213
golang.org/x/exp v0.0.0-20220921164117-439092de6870
golang.org/x/time v0.0.0-20220922220347-f3bd1da661af
)

require (
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a bit concerned about the number of indirect dependencies we are pulling with testcontainers. This was one of the complaints we received about the original vault/api library.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah... was going to make a comment
looks like testcontainers-go has some stuff that's probably not needed https://github.com/testcontainers/testcontainers-go/blob/d9bb48832213a363800e10b88d41e57a59447ccb/go.mod

for our immediate use-case, we can put in something like internal/tests and have a separate go.mod

github.com/Microsoft/go-winio v0.5.2 // indirect
github.com/Microsoft/hcsshim v0.9.4 // indirect
github.com/cenkalti/backoff/v4 v4.1.3 // indirect
github.com/containerd/cgroups v1.0.4 // indirect
github.com/containerd/containerd v1.6.8 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/hashicorp/errwrap v1.0.0 // indirect
github.com/docker/distribution v2.8.1+incompatible // indirect
github.com/docker/docker v20.10.17+incompatible // indirect
github.com/docker/go-connections v0.4.0 // indirect
github.com/docker/go-units v0.5.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/magiconair/properties v1.8.6 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/moby/sys/mount v0.3.3 // indirect
github.com/moby/sys/mountinfo v0.6.2 // indirect
github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 // indirect
github.com/morikuni/aec v1.0.0 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799 // indirect
github.com/opencontainers/runc v1.1.3 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/ryanuber/go-glob v1.0.0 // indirect
github.com/sirupsen/logrus v1.8.1 // indirect
go.opencensus.io v0.23.0 // indirect
golang.org/x/net v0.0.0-20220617184016-355a448f1bc9 // indirect
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f // indirect
google.golang.org/genproto v0.0.0-20220617124728-180714bec0ad // indirect
google.golang.org/grpc v1.47.0 // indirect
google.golang.org/protobuf v1.28.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)