From 55d85f90b9ff7873ef279675c137b58808c71938 Mon Sep 17 00:00:00 2001 From: Michael Li Date: Mon, 14 Aug 2023 16:03:30 -0400 Subject: [PATCH] test(e2e): Refactor migration test docker repo definition (#3578) This commit refactors docker repo definitions in the migration test to make it simpler to modify which version of boundary is being used. Additionally, this also refactors where "pull image" is performed to reduce another spot where the docker repository needs to be passed in. --- testing/internal/e2e/infra/docker.go | 68 ++++++++++++++----- .../e2e/tests/database/migration_test.go | 60 ++++++++++------ 2 files changed, 88 insertions(+), 40 deletions(-) diff --git a/testing/internal/e2e/infra/docker.go b/testing/internal/e2e/infra/docker.go index cd681dc9f..19ec22e14 100644 --- a/testing/internal/e2e/infra/docker.go +++ b/testing/internal/e2e/infra/docker.go @@ -28,11 +28,17 @@ type Container struct { // StartBoundaryDatabase spins up a postgres database in a docker container. // Returns information about the container -func StartBoundaryDatabase(t testing.TB, pool *dockertest.Pool, network *dockertest.Network) *Container { +func StartBoundaryDatabase(t testing.TB, pool *dockertest.Pool, network *dockertest.Network, repository, tag string) *Container { t.Log("Starting postgres database...") c, err := LoadConfig() require.NoError(t, err) + err = pool.Client.PullImage(docker.PullImageOptions{ + Repository: repository, + Tag: tag, + }, docker.AuthConfiguration{}) + require.NoError(t, err) + networkAlias := "e2epostgres" postgresDb := "e2eboundarydb" postgresUser := "e2eboundary" @@ -41,8 +47,8 @@ func StartBoundaryDatabase(t testing.TB, pool *dockertest.Pool, network *dockert require.NoError(t, err) resource, err := pool.RunWithOptions(&dockertest.RunOptions{ - Repository: c.DockerMirror + "/library/postgres", - Tag: "latest", + Repository: fmt.Sprintf("%s/%s", c.DockerMirror, repository), + Tag: tag, Cmd: []string{"postgres", "-c", "config_file=/etc/postgresql/postgresql.conf"}, Env: []string{ "POSTGRES_DB=" + postgresDb, @@ -77,7 +83,7 @@ func StartBoundaryDatabase(t testing.TB, pool *dockertest.Pool, network *dockert // InitBoundaryDatabase starts a boundary container (of the latest released version) and initializes a // postgres database (using `boundary database init`) at the specified postgres URI. // Returns information about the container -func InitBoundaryDatabase(t testing.TB, pool *dockertest.Pool, network *dockertest.Network, postgresURI string) *Container { +func InitBoundaryDatabase(t testing.TB, pool *dockertest.Pool, network *dockertest.Network, repository, tag, postgresURI string) *Container { t.Log("Initializing postgres database...") c, err := LoadConfig() require.NoError(t, err) @@ -85,9 +91,15 @@ func InitBoundaryDatabase(t testing.TB, pool *dockertest.Pool, network *dockerte boundaryConfigFilePath, err := filepath.Abs("testdata/boundary-config.hcl") require.NoError(t, err) + err = pool.Client.PullImage(docker.PullImageOptions{ + Repository: repository, + Tag: tag, + }, docker.AuthConfiguration{}) + require.NoError(t, err) + resource, err := pool.RunWithOptions(&dockertest.RunOptions{ - Repository: c.DockerMirror + "/hashicorp/boundary", - Tag: "latest", + Repository: fmt.Sprintf("%s/%s", c.DockerMirror, repository), + Tag: tag, Cmd: []string{"boundary", "database", "init", "-config", "/boundary/boundary-config.hcl", "-format", "json"}, Env: []string{ "BOUNDARY_POSTGRES_URL=" + postgresURI, @@ -132,7 +144,7 @@ func GetDbInitInfoFromContainer(t testing.TB, pool *dockertest.Pool, container * // StartBoundary starts a boundary container and spins up an instance of boundary using the // specified database at postgresURI. // Returns information about the container. -func StartBoundary(t testing.TB, pool *dockertest.Pool, network *dockertest.Network, postgresURI string) *Container { +func StartBoundary(t testing.TB, pool *dockertest.Pool, network *dockertest.Network, repository, tag, postgresURI string) *Container { t.Log("Starting Boundary...") c, err := LoadConfig() require.NoError(t, err) @@ -140,12 +152,19 @@ func StartBoundary(t testing.TB, pool *dockertest.Pool, network *dockertest.Netw boundaryConfigFilePath, err := filepath.Abs("testdata/boundary-config.hcl") require.NoError(t, err) + err = pool.Client.PullImage(docker.PullImageOptions{ + Repository: fmt.Sprintf("%s/%s", c.DockerMirror, repository), + Tag: tag, + }, docker.AuthConfiguration{}) + require.NoError(t, err) + resource, err := pool.RunWithOptions(&dockertest.RunOptions{ - Repository: c.DockerMirror + "/hashicorp/boundary", - Tag: "latest", + Repository: fmt.Sprintf("%s/%s", c.DockerMirror, repository), + Tag: tag, Cmd: []string{"boundary", "server", "-config", "/boundary/boundary-config.hcl"}, Env: []string{ - "BOUNDARY_POSTGRES_URL=" + postgresURI, + fmt.Sprintf("BOUNDARY_LICENSE=%s", c.BoundaryLicense), + fmt.Sprintf("BOUNDARY_POSTGRES_URL=%s", postgresURI), "HOSTNAME=boundary", "SKIP_CHOWN=true", }, @@ -172,15 +191,21 @@ func StartBoundary(t testing.TB, pool *dockertest.Pool, network *dockertest.Netw // StartVault starts a vault container. // Returns information about the container. -func StartVault(t testing.TB, pool *dockertest.Pool, network *dockertest.Network) (*Container, string) { +func StartVault(t testing.TB, pool *dockertest.Pool, network *dockertest.Network, repository, tag string) (*Container, string) { t.Log("Starting Vault...") c, err := LoadConfig() require.NoError(t, err) + err = pool.Client.PullImage(docker.PullImageOptions{ + Repository: fmt.Sprintf("%s/%s", c.DockerMirror, repository), + Tag: tag, + }, docker.AuthConfiguration{}) + require.NoError(t, err) + vaultToken := "boundarytok" resource, err := pool.RunWithOptions(&dockertest.RunOptions{ - Repository: c.DockerMirror + "/hashicorp/vault", - Tag: "latest", + Repository: fmt.Sprintf("%s/%s", c.DockerMirror, repository), + Tag: tag, Env: []string{ "VAULT_DEV_ROOT_TOKEN_ID=" + vaultToken, }, @@ -207,14 +232,14 @@ func StartVault(t testing.TB, pool *dockertest.Pool, network *dockertest.Network // ConnectToTarget starts a boundary container and attempts to connect to the specified target. The // goal of this method is to create a session entry in the database. // Returns information about the container. -func ConnectToTarget(t testing.TB, pool *dockertest.Pool, network *dockertest.Network, boundaryAddr string, token string, targetId string) *Container { +func ConnectToTarget(t testing.TB, pool *dockertest.Pool, network *dockertest.Network, repository, tag, boundaryAddr, token, targetId string) *Container { t.Log("Connecting to target...") c, err := LoadConfig() require.NoError(t, err) resource, err := pool.RunWithOptions(&dockertest.RunOptions{ - Repository: c.DockerMirror + "/hashicorp/boundary", - Tag: "latest", + Repository: fmt.Sprintf("%s/%s", c.DockerMirror, repository), + Tag: tag, Cmd: []string{ "boundary", "connect", "-token", "env://E2E_AUTH_TOKEN", @@ -239,11 +264,17 @@ func ConnectToTarget(t testing.TB, pool *dockertest.Pool, network *dockertest.Ne // StartOpenSshServer starts an openssh container to serve as a target for Boundary. // Returns information about the container. -func StartOpenSshServer(t testing.TB, pool *dockertest.Pool, network *dockertest.Network, user string, privateKeyFilePath string) *Container { +func StartOpenSshServer(t testing.TB, pool *dockertest.Pool, network *dockertest.Network, repository, tag, user, privateKeyFilePath string) *Container { t.Log("Starting openssh-server to serve as target...") c, err := LoadConfig() require.NoError(t, err) + err = pool.Client.PullImage(docker.PullImageOptions{ + Repository: fmt.Sprintf("%s/%s", c.DockerMirror, repository), + Tag: tag, + }, docker.AuthConfiguration{}) + require.NoError(t, err) + privateKeyRaw, err := os.ReadFile(privateKeyFilePath) require.NoError(t, err) signer, err := ssh.ParsePrivateKey(privateKeyRaw) @@ -251,7 +282,8 @@ func StartOpenSshServer(t testing.TB, pool *dockertest.Pool, network *dockertest networkAlias := "target" resource, err := pool.RunWithOptions(&dockertest.RunOptions{ - Repository: c.DockerMirror + "/linuxserver/openssh-server", + Repository: fmt.Sprintf("%s/%s", c.DockerMirror, repository), + Tag: tag, Env: []string{ "PUID=1000", "PGID=1000", diff --git a/testing/internal/e2e/tests/database/migration_test.go b/testing/internal/e2e/tests/database/migration_test.go index 4664fffe7..a8fa071b5 100644 --- a/testing/internal/e2e/tests/database/migration_test.go +++ b/testing/internal/e2e/tests/database/migration_test.go @@ -45,8 +45,12 @@ func TestDatabaseMigration(t *testing.T) { require.NoError(t, err) ctx := context.Background() - te := setupEnvironment(t, ctx, c) - populateBoundaryDatabase(t, ctx, c, te) + + boundaryRepo := "hashicorp/boundary" + boundaryTag := "latest" + + te := setupEnvironment(t, ctx, c, boundaryRepo, boundaryTag) + populateBoundaryDatabase(t, ctx, c, te, boundaryRepo, boundaryTag) // Migrate database t.Log("Stopping boundary before migrating...") @@ -70,25 +74,13 @@ func TestDatabaseMigration(t *testing.T) { t.Logf("Migration Output: %s", output.Stderr) } -func setupEnvironment(t testing.TB, ctx context.Context, c *config) TestEnvironment { +func setupEnvironment(t testing.TB, ctx context.Context, c *config, boundaryRepo, boundaryTag string) TestEnvironment { pool, err := dockertest.NewPool("") require.NoError(t, err) err = pool.Client.Ping() require.NoError(t, err) pool.MaxWait = 10 * time.Second - // This ensures that the latest images are used - err = pool.Client.PullImage(docker.PullImageOptions{ - Repository: "hashicorp/boundary", - Tag: "latest", - }, docker.AuthConfiguration{}) - require.NoError(t, err) - err = pool.Client.PullImage(docker.PullImageOptions{ - Repository: "hashicorp/vault", - Tag: "latest", - }, docker.AuthConfiguration{}) - require.NoError(t, err) - // Set up docker network network, err := pool.CreateNetwork(t.Name()) require.NoError(t, err) @@ -97,7 +89,7 @@ func setupEnvironment(t testing.TB, ctx context.Context, c *config) TestEnvironm }) // Start Vault - v, vaultToken := infra.StartVault(t, pool, network) + v, vaultToken := infra.StartVault(t, pool, network, "hashicorp/vault", "latest") t.Cleanup(func() { pool.Purge(v.Resource) }) @@ -120,7 +112,7 @@ func setupEnvironment(t testing.TB, ctx context.Context, c *config) TestEnvironm require.NoError(t, err) // Start a Boundary database and wait until it's ready - db := infra.StartBoundaryDatabase(t, pool, network) + db := infra.StartBoundaryDatabase(t, pool, network, "library/postgres", "latest") t.Cleanup(func() { pool.Purge(db.Resource) }) @@ -135,20 +127,35 @@ func setupEnvironment(t testing.TB, ctx context.Context, c *config) TestEnvironm require.NoError(t, err) // Create a target - target := infra.StartOpenSshServer(t, pool, network, c.TargetSshUser, c.TargetSshKeyPath) + target := infra.StartOpenSshServer( + t, + pool, + network, + "linuxserver/openssh-server", + "latest", + c.TargetSshUser, + c.TargetSshKeyPath, + ) t.Cleanup(func() { pool.Purge(target.Resource) }) // Initialize the database and extract resulting information - dbInit := infra.InitBoundaryDatabase(t, pool, network, db.UriNetwork) + dbInit := infra.InitBoundaryDatabase( + t, + pool, + network, + boundaryRepo, + boundaryTag, + db.UriNetwork, + ) t.Cleanup(func() { pool.Purge(dbInit.Resource) }) dbInitInfo := infra.GetDbInitInfoFromContainer(t, pool, dbInit) // Start a Boundary server and wait until Boundary has finished loading - b := infra.StartBoundary(t, pool, network, db.UriNetwork) + b := infra.StartBoundary(t, pool, network, boundaryRepo, boundaryTag, db.UriNetwork) t.Cleanup(func() { pool.Purge(b.Resource) }) @@ -191,7 +198,7 @@ func setupEnvironment(t testing.TB, ctx context.Context, c *config) TestEnvironm } } -func populateBoundaryDatabase(t testing.TB, ctx context.Context, c *config, te TestEnvironment) { +func populateBoundaryDatabase(t testing.TB, ctx context.Context, c *config, te TestEnvironment, boundaryRepo, boundaryTag string) { // Create resources for target. Uses the local CLI so that these methods can be reused. // While the CLI version used won't necessarily match the controller version, it should be (and is // supposed to be) backwards ompatible @@ -323,7 +330,16 @@ func populateBoundaryDatabase(t testing.TB, ctx context.Context, c *config, te T auth_token, ok := authenticationResult.Item.Attributes["token"].(string) require.True(t, ok) - connectTarget := infra.ConnectToTarget(t, te.Pool, te.Network, te.Boundary.UriNetwork, auth_token, newTargetId) + connectTarget := infra.ConnectToTarget( + t, + te.Pool, + te.Network, + boundaryRepo, + boundaryTag, + te.Boundary.UriNetwork, + auth_token, + newTargetId, + ) t.Cleanup(func() { te.Pool.Purge(connectTarget.Resource) })