mirror of
https://github.com/optim-enterprises-bv/vault.git
synced 2025-11-02 11:38:02 +00:00
Use a separate package for API integration tests
This removes the cyclic dependency
This commit is contained in:
117
api/api_integration_test.go
Normal file
117
api/api_integration_test.go
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
package api_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/hashicorp/vault/api"
|
||||||
|
"github.com/hashicorp/vault/builtin/logical/pki"
|
||||||
|
"github.com/hashicorp/vault/builtin/logical/transit"
|
||||||
|
"github.com/hashicorp/vault/logical"
|
||||||
|
"github.com/hashicorp/vault/vault"
|
||||||
|
|
||||||
|
cleanhttp "github.com/hashicorp/go-cleanhttp"
|
||||||
|
vaulthttp "github.com/hashicorp/vault/http"
|
||||||
|
logxi "github.com/mgutz/logxi/v1"
|
||||||
|
dockertest "gopkg.in/ory-am/dockertest.v3"
|
||||||
|
)
|
||||||
|
|
||||||
|
var testVaultServerDefaultBackends = map[string]logical.Factory{
|
||||||
|
"transit": transit.Factory,
|
||||||
|
"pki": pki.Factory,
|
||||||
|
}
|
||||||
|
|
||||||
|
func testVaultServer(t testing.TB) (*api.Client, func()) {
|
||||||
|
return testVaultServerBackends(t, testVaultServerDefaultBackends)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testVaultServerBackends(t testing.TB, backends map[string]logical.Factory) (*api.Client, func()) {
|
||||||
|
handlers := []http.Handler{
|
||||||
|
http.NewServeMux(),
|
||||||
|
http.NewServeMux(),
|
||||||
|
http.NewServeMux(),
|
||||||
|
}
|
||||||
|
|
||||||
|
coreConfig := &vault.CoreConfig{
|
||||||
|
DisableMlock: true,
|
||||||
|
DisableCache: true,
|
||||||
|
Logger: logxi.NullLog,
|
||||||
|
LogicalBackends: backends,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Chicken-and-egg: Handler needs a core. So we create handlers first, then
|
||||||
|
// add routes chained to a Handler-created handler.
|
||||||
|
cores := vault.TestCluster(t, handlers, coreConfig, true)
|
||||||
|
for i, core := range cores {
|
||||||
|
handlers[i].(*http.ServeMux).Handle("/", vaulthttp.Handler(core.Core))
|
||||||
|
}
|
||||||
|
|
||||||
|
// make it easy to get access to the active
|
||||||
|
core := cores[0].Core
|
||||||
|
vault.TestWaitActive(t, core)
|
||||||
|
|
||||||
|
rootToken := cores[0].Root
|
||||||
|
address := fmt.Sprintf("https://127.0.0.1:%d", cores[1].Listeners[0].Address.Port)
|
||||||
|
|
||||||
|
config := api.DefaultConfig()
|
||||||
|
config.Address = address
|
||||||
|
config.HttpClient = cleanhttp.DefaultClient()
|
||||||
|
config.HttpClient.Transport.(*http.Transport).TLSClientConfig = cores[0].TLSConfig
|
||||||
|
client, err := api.NewClient(config)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("error creating vault cluster: %s", err)
|
||||||
|
}
|
||||||
|
client.SetToken(rootToken)
|
||||||
|
|
||||||
|
// Sanity check
|
||||||
|
secret, err := client.Auth().Token().LookupSelf()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if secret == nil || secret.Data["id"].(string) != rootToken {
|
||||||
|
t.Fatal("token mismatch: %q vs %q", secret, rootToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
return client, func() {
|
||||||
|
for _, core := range cores {
|
||||||
|
defer core.CloseListeners()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// testPostgresDB creates a testing postgres database in a Docker container,
|
||||||
|
// returning the connection URL and the associated closer function.
|
||||||
|
func testPostgresDB(t testing.TB) (string, func()) {
|
||||||
|
pool, err := dockertest.NewPool("")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("postgresdb: failed to connect to docker: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
resource, err := pool.Run("postgres", "latest", []string{
|
||||||
|
"POSTGRES_PASSWORD=secret",
|
||||||
|
"POSTGRES_DB=database",
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("postgresdb: could not start container: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
addr := fmt.Sprintf("postgres://postgres:secret@localhost:%s/database?sslmode=disable", resource.GetPort("5432/tcp"))
|
||||||
|
|
||||||
|
if err := pool.Retry(func() error {
|
||||||
|
db, err := sql.Open("postgres", addr)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return db.Ping()
|
||||||
|
}); err != nil {
|
||||||
|
t.Fatalf("postgresdb: could not connect: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return addr, func() {
|
||||||
|
if err := pool.Purge(resource); err != nil {
|
||||||
|
t.Fatalf("postgresdb: failed to cleanup container: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,18 +1,10 @@
|
|||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
|
||||||
"os/exec"
|
|
||||||
"sync/atomic"
|
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
|
||||||
|
|
||||||
_ "github.com/lib/pq"
|
|
||||||
dockertest "gopkg.in/ory-am/dockertest.v3"
|
|
||||||
|
|
||||||
"golang.org/x/net/http2"
|
"golang.org/x/net/http2"
|
||||||
)
|
)
|
||||||
@@ -37,94 +29,3 @@ func testHTTPServer(
|
|||||||
|
|
||||||
return config, ln
|
return config, ln
|
||||||
}
|
}
|
||||||
|
|
||||||
// nextPort is the next port to use for the API server.
|
|
||||||
var nextPort int32 = 28200
|
|
||||||
|
|
||||||
// restVaultServer runs an instance of the Vault server in development mode.
|
|
||||||
// This requires that the vault binary is installed and in the $PATH.
|
|
||||||
func testVaultServer(t *testing.T) (*Client, func()) {
|
|
||||||
bin, err := exec.LookPath("vault")
|
|
||||||
if err != nil || bin == "" {
|
|
||||||
t.Fatal("vault binary not found")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the port number
|
|
||||||
port := atomic.AddInt32(&nextPort, 1)
|
|
||||||
|
|
||||||
// Construct the address
|
|
||||||
addr := fmt.Sprintf("127.0.0.1:%d", port)
|
|
||||||
|
|
||||||
// Start the server
|
|
||||||
cmd := exec.Command(
|
|
||||||
bin, "server", "-dev",
|
|
||||||
"-dev-listen-address", addr,
|
|
||||||
"-dev-root-token-id", "root",
|
|
||||||
)
|
|
||||||
if err := cmd.Start(); err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < 10; i++ {
|
|
||||||
conn, err := net.DialTimeout("tcp", addr, time.Second)
|
|
||||||
if err != nil {
|
|
||||||
time.Sleep(100 * time.Millisecond)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
conn.Close()
|
|
||||||
|
|
||||||
config := DefaultConfig()
|
|
||||||
config.Address = fmt.Sprintf("http://%s", addr)
|
|
||||||
client, err := NewClient(config)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
client.SetToken("root")
|
|
||||||
|
|
||||||
return client, func() {
|
|
||||||
cmd.Process.Signal(os.Interrupt)
|
|
||||||
cmd.Process.Wait()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
t.Fatalf("timeout waiting for vault server")
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func testPostgresDatabase(t *testing.T) (string, func()) {
|
|
||||||
if os.Getenv("PG_URL") != "" {
|
|
||||||
return os.Getenv("PG_URL"), func() {}
|
|
||||||
}
|
|
||||||
|
|
||||||
pool, err := dockertest.NewPool("")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Failed to connect to docker: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
resource, err := pool.Run("postgres", "latest", []string{"POSTGRES_PASSWORD=secret", "POSTGRES_DB=database"})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Could not start local PostgreSQL docker container: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
cleanup := func() {
|
|
||||||
err := pool.Purge(resource)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Failed to cleanup local container: %s", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pgURL := fmt.Sprintf("postgres://postgres:secret@localhost:%s/database?sslmode=disable", resource.GetPort("5432/tcp"))
|
|
||||||
|
|
||||||
// exponential backoff-retry
|
|
||||||
if err := pool.Retry(func() error {
|
|
||||||
db, err := sql.Open("postgres", pgURL)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return db.Ping()
|
|
||||||
}); err != nil {
|
|
||||||
t.Fatalf("Could not connect to PostgreSQL docker container: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return pgURL, cleanup
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user