From fdf3318f72a35391d66904938fd6285970ceafbf Mon Sep 17 00:00:00 2001 From: Michael Li Date: Thu, 22 Dec 2022 11:11:03 -0500 Subject: [PATCH] test(e2e): Add tests for bytes_up/bytes_down (#2740) * refact(e2e): Create env files for consistency * refact(e2e): Addmethod for waiting for session * test(e2e): Add bytes up/down test * fix(e2e): Fix require.Equal statements to have the correct order * fix(e2e): Fix loop variable --- testing/internal/e2e/boundary/authenticate.go | 94 ++++++++++++++++ testing/internal/e2e/boundary/boundary.go | 106 ------------------ testing/internal/e2e/boundary/env.go | 20 ++++ testing/internal/e2e/boundary/session.go | 50 ++++++++- .../dynamichostcatalog_host_set_empty_test.go | 15 +-- .../tests/static/bytes_up_down_empty_test.go | 92 +++++++++++++++ .../e2e/tests/static/bytes_up_down_test.go | 92 +++++++++++++++ .../tests/static/connect_localhost_test.go | 39 +------ .../tests/static/session_cancel_admin_test.go | 2 +- .../tests/static/session_cancel_group_test.go | 5 +- .../tests/static/session_cancel_user_test.go | 5 +- .../session_end_delete_host_set_test.go | 2 +- .../static/session_end_delete_host_test.go | 2 +- .../static/session_end_delete_target_test.go | 2 +- .../static/session_end_delete_user_test.go | 2 +- testing/internal/e2e/vault/env.go | 18 +++ testing/internal/e2e/vault/vault.go | 16 --- 17 files changed, 384 insertions(+), 178 deletions(-) create mode 100644 testing/internal/e2e/boundary/authenticate.go create mode 100644 testing/internal/e2e/boundary/env.go create mode 100644 testing/internal/e2e/tests/static/bytes_up_down_empty_test.go create mode 100644 testing/internal/e2e/tests/static/bytes_up_down_test.go create mode 100644 testing/internal/e2e/vault/env.go diff --git a/testing/internal/e2e/boundary/authenticate.go b/testing/internal/e2e/boundary/authenticate.go new file mode 100644 index 0000000000..532aa474a5 --- /dev/null +++ b/testing/internal/e2e/boundary/authenticate.go @@ -0,0 +1,94 @@ +package boundary + +import ( + "context" + "encoding/json" + "fmt" + "testing" + + "github.com/hashicorp/boundary/api" + "github.com/hashicorp/boundary/api/authmethods" + "github.com/hashicorp/boundary/testing/internal/e2e" + "github.com/stretchr/testify/require" +) + +// NewApiClient creates a new Api client for the specified Boundary instance and +// attempts to authenticate it. Returns the client. +func NewApiClient() (*api.Client, error) { + c, err := loadConfig() + if err != nil { + return nil, err + } + + client, err := api.NewClient(&api.Config{Addr: c.Address}) + if err != nil { + return nil, err + } + + ctx := context.Background() + authmethodsClient := authmethods.NewClient(client) + authenticationResult, err := authmethodsClient.Authenticate(ctx, c.AuthMethodId, "login", + map[string]any{ + "login_name": c.AdminLoginName, + "password": c.AdminLoginPassword, + }, + ) + if err != nil { + return nil, err + } + + client.SetToken(fmt.Sprint(authenticationResult.Attributes["token"])) + return client, err +} + +// AuthenticateAdminCli uses the cli to authenticate the specified Boundary instance as an admin +func AuthenticateAdminCli(t testing.TB, ctx context.Context) { + c, err := loadConfig() + require.NoError(t, err) + + AuthenticateCli(t, ctx, c.AdminLoginName, c.AdminLoginPassword) +} + +// AuthenticateCli uses the cli to authenticate the specified Boundary instance +func AuthenticateCli(t testing.TB, ctx context.Context, loginName string, password string) { + c, err := loadConfig() + require.NoError(t, err) + + output := e2e.RunCommand(ctx, "boundary", + e2e.WithArgs( + "authenticate", "password", + "-addr", c.Address, + "-auth-method-id", c.AuthMethodId, + "-login-name", loginName, + "-password", "env://E2E_TEST_BOUNDARY_PASSWORD", + ), + e2e.WithEnv("E2E_TEST_BOUNDARY_PASSWORD", password), + ) + require.NoError(t, output.Err, string(output.Stderr)) +} + +// GetAuthenticationTokenCli uses the cli to get an auth token that can be used in subsequent +// commands +func GetAuthenticationTokenCli(t testing.TB, ctx context.Context, loginName string, password string) string { + c, err := loadConfig() + require.NoError(t, err) + + output := e2e.RunCommand(ctx, "boundary", + e2e.WithArgs( + "authenticate", "password", + "-addr", c.Address, + "-auth-method-id", c.AuthMethodId, + "-login-name", loginName, + "-password", "env://E2E_TEST_BOUNDARY_PASSWORD", + "-format", "json", + ), + e2e.WithEnv("E2E_TEST_BOUNDARY_PASSWORD", password), + ) + require.NoError(t, output.Err, string(output.Stderr)) + + var authenticationResult AuthenticateCliOutput + err = json.Unmarshal(output.Stdout, &authenticationResult) + require.NoError(t, err) + + return fmt.Sprint(authenticationResult.Item.Attributes["token"]) +} diff --git a/testing/internal/e2e/boundary/boundary.go b/testing/internal/e2e/boundary/boundary.go index b697669be3..fd6f47adb8 100644 --- a/testing/internal/e2e/boundary/boundary.go +++ b/testing/internal/e2e/boundary/boundary.go @@ -2,25 +2,10 @@ package boundary import ( - "context" - "encoding/json" - "fmt" - "testing" - "github.com/hashicorp/boundary/api" "github.com/hashicorp/boundary/api/authmethods" - "github.com/hashicorp/boundary/testing/internal/e2e" - "github.com/kelseyhightower/envconfig" - "github.com/stretchr/testify/require" ) -type config struct { - Address string `envconfig:"BOUNDARY_ADDR" required:"true"` // e.g. http://127.0.0.1:9200 - AuthMethodId string `envconfig:"E2E_PASSWORD_AUTH_METHOD_ID" required:"true"` // e.g. ampw_1234567890 - AdminLoginName string `envconfig:"E2E_PASSWORD_ADMIN_LOGIN_NAME" default:"admin"` - AdminLoginPassword string `envconfig:"E2E_PASSWORD_ADMIN_PASSWORD" required:"true"` -} - // AuthenticateCliOutput parses the json response from running `boundary authenticate` type AuthenticateCliOutput struct { Item *authmethods.AuthenticateResult @@ -43,94 +28,3 @@ type DbInitInfo struct { type CliError struct { Status int `json:"status"` } - -func loadConfig() (*config, error) { - var c config - err := envconfig.Process("", &c) - if err != nil { - return nil, err - } - - return &c, nil -} - -// NewApiClient creates a new Api client for the specified Boundary instance and -// attempts to authenticate it. Returns the client. -func NewApiClient() (*api.Client, error) { - c, err := loadConfig() - if err != nil { - return nil, err - } - - client, err := api.NewClient(&api.Config{Addr: c.Address}) - if err != nil { - return nil, err - } - - ctx := context.Background() - authmethodsClient := authmethods.NewClient(client) - authenticationResult, err := authmethodsClient.Authenticate(ctx, c.AuthMethodId, "login", - map[string]any{ - "login_name": c.AdminLoginName, - "password": c.AdminLoginPassword, - }, - ) - if err != nil { - return nil, err - } - - client.SetToken(fmt.Sprint(authenticationResult.Attributes["token"])) - return client, err -} - -// AuthenticateAdminCli uses the cli to authenticate the specified Boundary instance as an admin -func AuthenticateAdminCli(t testing.TB, ctx context.Context) { - c, err := loadConfig() - require.NoError(t, err) - - AuthenticateCli(t, ctx, c.AdminLoginName, c.AdminLoginPassword) -} - -// AuthenticateCli uses the cli to authenticate the specified Boundary instance -func AuthenticateCli(t testing.TB, ctx context.Context, loginName string, password string) { - c, err := loadConfig() - require.NoError(t, err) - - output := e2e.RunCommand(ctx, "boundary", - e2e.WithArgs( - "authenticate", "password", - "-addr", c.Address, - "-auth-method-id", c.AuthMethodId, - "-login-name", loginName, - "-password", "env://E2E_TEST_BOUNDARY_PASSWORD", - ), - e2e.WithEnv("E2E_TEST_BOUNDARY_PASSWORD", password), - ) - require.NoError(t, output.Err, string(output.Stderr)) -} - -// GetAuthenticationTokenCli uses the cli to get an auth token that can be used in subsequent -// commands -func GetAuthenticationTokenCli(t testing.TB, ctx context.Context, loginName string, password string) string { - c, err := loadConfig() - require.NoError(t, err) - - output := e2e.RunCommand(ctx, "boundary", - e2e.WithArgs( - "authenticate", "password", - "-addr", c.Address, - "-auth-method-id", c.AuthMethodId, - "-login-name", loginName, - "-password", "env://E2E_TEST_BOUNDARY_PASSWORD", - "-format", "json", - ), - e2e.WithEnv("E2E_TEST_BOUNDARY_PASSWORD", password), - ) - require.NoError(t, output.Err, string(output.Stderr)) - - var authenticationResult AuthenticateCliOutput - err = json.Unmarshal(output.Stdout, &authenticationResult) - require.NoError(t, err) - - return fmt.Sprint(authenticationResult.Item.Attributes["token"]) -} diff --git a/testing/internal/e2e/boundary/env.go b/testing/internal/e2e/boundary/env.go new file mode 100644 index 0000000000..bfac1734f6 --- /dev/null +++ b/testing/internal/e2e/boundary/env.go @@ -0,0 +1,20 @@ +package boundary + +import "github.com/kelseyhightower/envconfig" + +type config struct { + Address string `envconfig:"BOUNDARY_ADDR" required:"true"` // e.g. http://127.0.0.1:9200 + AuthMethodId string `envconfig:"E2E_PASSWORD_AUTH_METHOD_ID" required:"true"` // e.g. ampw_1234567890 + AdminLoginName string `envconfig:"E2E_PASSWORD_ADMIN_LOGIN_NAME" default:"admin"` + AdminLoginPassword string `envconfig:"E2E_PASSWORD_ADMIN_PASSWORD" required:"true"` +} + +func loadConfig() (*config, error) { + var c config + err := envconfig.Process("", &c) + if err != nil { + return nil, err + } + + return &c, nil +} diff --git a/testing/internal/e2e/boundary/session.go b/testing/internal/e2e/boundary/session.go index e5720b8476..3d2754d421 100644 --- a/testing/internal/e2e/boundary/session.go +++ b/testing/internal/e2e/boundary/session.go @@ -14,14 +14,60 @@ import ( "github.com/stretchr/testify/require" ) -func WaitForSessionToBeActiveCli(t testing.TB, ctx context.Context, scopeId string) *sessions.Session { +// WaitForSessionCli waits for a session to appear in the session list and returns the session +// information +func WaitForSessionCli(t testing.TB, ctx context.Context, projectId string) *sessions.Session { + t.Log("Waiting for session to appear...") + var session *sessions.Session + err := backoff.RetryNotify( + func() error { + // List sessions + output := e2e.RunCommand(ctx, "boundary", + e2e.WithArgs("sessions", "list", "-scope-id", projectId, "-include-terminated", "-format", "json"), + ) + if output.Err != nil { + return backoff.Permanent(errors.New(string(output.Stderr))) + } + var sessionListResult sessions.SessionListResult + err := json.Unmarshal(output.Stdout, &sessionListResult) + if err != nil { + return backoff.Permanent(err) + } + + // Check if there is one session + sessionCount := len(sessionListResult.Items) + if sessionCount == 0 { + return errors.New("No items are appearing in the session list") + } + + t.Logf("Found %d session(s)", sessionCount) + if sessionCount != 1 { + return backoff.Permanent(errors.New("Only one session was expected to be found")) + } + + session = sessionListResult.Items[0] + return nil + }, + backoff.WithMaxRetries(backoff.NewConstantBackOff(3*time.Second), 5), + func(err error, td time.Duration) { + t.Logf("%s. Retrying...", err.Error()) + }, + ) + require.NoError(t, err) + + return session +} + +// WaitForSessionToBeActiveCli waits for a session to appear in the session list and returns the +// session information once the session has an active status +func WaitForSessionToBeActiveCli(t testing.TB, ctx context.Context, projectId string) *sessions.Session { t.Log("Waiting for session to be active...") var session *sessions.Session err := backoff.RetryNotify( func() error { // List sessions output := e2e.RunCommand(ctx, "boundary", - e2e.WithArgs("sessions", "list", "-scope-id", scopeId, "-format", "json"), + e2e.WithArgs("sessions", "list", "-scope-id", projectId, "-format", "json"), ) if output.Err != nil { return backoff.Permanent(errors.New(string(output.Stderr))) diff --git a/testing/internal/e2e/tests/aws/dynamichostcatalog_host_set_empty_test.go b/testing/internal/e2e/tests/aws/dynamichostcatalog_host_set_empty_test.go index 0709fc1ece..98eae37416 100644 --- a/testing/internal/e2e/tests/aws/dynamichostcatalog_host_set_empty_test.go +++ b/testing/internal/e2e/tests/aws/dynamichostcatalog_host_set_empty_test.go @@ -4,6 +4,7 @@ import ( "context" "encoding/json" "fmt" + "net/http" "testing" "time" @@ -40,8 +41,8 @@ func TestCliCreateAwsDynamicHostCatalogWithEmptyHostSet(t *testing.T) { // Check that there are no hosts in the host set t.Logf("Looking for items in the host set...") var actualHostSetCount int - for i := 1; i <= 3; i++ { - if i != 1 { + for i := 0; i < 3; i++ { + if i != 0 { time.Sleep(3 * time.Second) } @@ -58,7 +59,7 @@ func TestCliCreateAwsDynamicHostCatalogWithEmptyHostSet(t *testing.T) { require.NoError(t, err) actualHostSetCount = len(hostSetsReadResult.Item.HostIds) - require.Equal(t, actualHostSetCount, 0, + require.Equal(t, 0, actualHostSetCount, fmt.Sprintf("Detected incorrect number of hosts. Expected: 0, Actual: %d", actualHostSetCount), ) } @@ -67,8 +68,8 @@ func TestCliCreateAwsDynamicHostCatalogWithEmptyHostSet(t *testing.T) { // Check that there are no hosts in the host catalog t.Logf("Looking for items in the host catalog...") var actualHostCatalogCount int - for i := 1; i <= 3; i++ { - if i != 1 { + for i := 0; i < 3; i++ { + if i != 0 { time.Sleep(3 * time.Second) } @@ -81,7 +82,7 @@ func TestCliCreateAwsDynamicHostCatalogWithEmptyHostSet(t *testing.T) { require.NoError(t, err) actualHostCatalogCount = len(hostCatalogListResult.Items) - require.Equal(t, actualHostCatalogCount, 0, + require.Equal(t, 0, actualHostCatalogCount, fmt.Sprintf("Detected incorrect number of hosts. Expected: 0, Actual: %d", actualHostCatalogCount), ) } @@ -111,6 +112,6 @@ func TestCliCreateAwsDynamicHostCatalogWithEmptyHostSet(t *testing.T) { var response boundary.CliError err = json.Unmarshal(output.Stderr, &response) require.NoError(t, err) - require.Equal(t, response.Status, 404, "Expected to error when connecting to a target with zero hosts") + require.Equal(t, http.StatusNotFound, response.Status, "Expected to error when connecting to a target with zero hosts") t.Log("Successfully failed to connect to target") } diff --git a/testing/internal/e2e/tests/static/bytes_up_down_empty_test.go b/testing/internal/e2e/tests/static/bytes_up_down_empty_test.go new file mode 100644 index 0000000000..664035041f --- /dev/null +++ b/testing/internal/e2e/tests/static/bytes_up_down_empty_test.go @@ -0,0 +1,92 @@ +package static_test + +import ( + "context" + "encoding/json" + "testing" + "time" + + "github.com/hashicorp/boundary/api/sessions" + "github.com/hashicorp/boundary/testing/internal/e2e" + "github.com/hashicorp/boundary/testing/internal/e2e/boundary" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +// TestCliBytesUpDownEmpty uses the cli to verify that the bytes_up/bytes_down fields of a +// session correctly increase when data is transmitting during a session. +func TestCliBytesUpDownEmpty(t *testing.T) { + e2e.MaybeSkipTest(t) + c, err := loadConfig() + require.NoError(t, err) + + ctx := context.Background() + boundary.AuthenticateAdminCli(t, ctx) + newOrgId := boundary.CreateNewOrgCli(t, ctx) + t.Cleanup(func() { + ctx := context.Background() + boundary.AuthenticateAdminCli(t, ctx) + output := e2e.RunCommand(ctx, "boundary", e2e.WithArgs("scopes", "delete", "-id", newOrgId)) + require.NoError(t, output.Err, string(output.Stderr)) + }) + newProjectId := boundary.CreateNewProjectCli(t, ctx, newOrgId) + newHostCatalogId := boundary.CreateNewHostCatalogCli(t, ctx, newProjectId) + newHostSetId := boundary.CreateNewHostSetCli(t, ctx, newHostCatalogId) + newHostId := boundary.CreateNewHostCli(t, ctx, newHostCatalogId, c.TargetIp) + boundary.AddHostToHostSetCli(t, ctx, newHostSetId, newHostId) + newTargetId := boundary.CreateNewTargetCli(t, ctx, newProjectId, c.TargetPort) + boundary.AddHostSourceToTargetCli(t, ctx, newTargetId, newHostSetId) + + // Create a session where no additional commands are run + ctxCancel, cancel := context.WithCancel(context.Background()) + errChan := make(chan *e2e.CommandResult) + go func() { + t.Log("Starting session...") + errChan <- e2e.RunCommand(ctxCancel, "boundary", + e2e.WithArgs( + "connect", + "-target-id", newTargetId, + "-exec", "/usr/bin/ssh", "--", + "-l", c.TargetSshUser, + "-i", c.TargetSshKeyPath, + "-o", "UserKnownHostsFile=/dev/null", + "-o", "StrictHostKeyChecking=no", + "-o", "IdentitiesOnly=yes", // forces the use of the provided key + "-p", "{{boundary.port}}", // this is provided by boundary + "{{boundary.ip}}", + ), + ) + }() + t.Cleanup(cancel) + + session := boundary.WaitForSessionCli(t, ctx, newProjectId) + assert.Equal(t, newTargetId, session.TargetId) + assert.Equal(t, newHostId, session.HostId) + + // Confirm that bytesUp and bytesDown do not change + bytesUp := 0 + bytesDown := 0 + t.Log("Reading bytes_up/bytes_down values...") + for i := 0; i < 3; i++ { + if i != 0 { + time.Sleep(2 * time.Second) + } + + output := e2e.RunCommand(ctx, "boundary", + e2e.WithArgs("sessions", "read", "-id", session.Id, "-format", "json"), + ) + require.NoError(t, output.Err, string(output.Stderr)) + var newSessionReadResult sessions.SessionReadResult + err = json.Unmarshal(output.Stdout, &newSessionReadResult) + require.NoError(t, err) + bytesUp = int(newSessionReadResult.Item.Connections[0].BytesUp) + bytesDown = int(newSessionReadResult.Item.Connections[0].BytesDown) + + if i != 1 { + require.Equal(t, bytesUp, int(newSessionReadResult.Item.Connections[0].BytesUp)) + require.Equal(t, bytesDown, int(newSessionReadResult.Item.Connections[0].BytesDown)) + } + + t.Logf("bytes_up: %d, bytes_down: %d", bytesUp, bytesDown) + } +} diff --git a/testing/internal/e2e/tests/static/bytes_up_down_test.go b/testing/internal/e2e/tests/static/bytes_up_down_test.go new file mode 100644 index 0000000000..3ffe932223 --- /dev/null +++ b/testing/internal/e2e/tests/static/bytes_up_down_test.go @@ -0,0 +1,92 @@ +package static_test + +import ( + "context" + "encoding/json" + "testing" + "time" + + "github.com/hashicorp/boundary/api/sessions" + "github.com/hashicorp/boundary/testing/internal/e2e" + "github.com/hashicorp/boundary/testing/internal/e2e/boundary" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +// TestCliBytesUpDownTransferData uses the cli to verify that the bytes_up/bytes_down fields of a +// session correctly increase when data is transmitting during a session. +func TestCliBytesUpDownTransferData(t *testing.T) { + e2e.MaybeSkipTest(t) + c, err := loadConfig() + require.NoError(t, err) + + ctx := context.Background() + boundary.AuthenticateAdminCli(t, ctx) + newOrgId := boundary.CreateNewOrgCli(t, ctx) + t.Cleanup(func() { + ctx := context.Background() + boundary.AuthenticateAdminCli(t, ctx) + output := e2e.RunCommand(ctx, "boundary", e2e.WithArgs("scopes", "delete", "-id", newOrgId)) + require.NoError(t, output.Err, string(output.Stderr)) + }) + newProjectId := boundary.CreateNewProjectCli(t, ctx, newOrgId) + newHostCatalogId := boundary.CreateNewHostCatalogCli(t, ctx, newProjectId) + newHostSetId := boundary.CreateNewHostSetCli(t, ctx, newHostCatalogId) + newHostId := boundary.CreateNewHostCli(t, ctx, newHostCatalogId, c.TargetIp) + boundary.AddHostToHostSetCli(t, ctx, newHostSetId, newHostId) + newTargetId := boundary.CreateNewTargetCli(t, ctx, newProjectId, c.TargetPort) + boundary.AddHostSourceToTargetCli(t, ctx, newTargetId, newHostSetId) + + // Create a session where no additional commands are run + ctxCancel, cancel := context.WithCancel(context.Background()) + errChan := make(chan *e2e.CommandResult) + + // Run commands on the target to send data through connection + go func() { + t.Log("Starting session...") + errChan <- e2e.RunCommand(ctxCancel, "boundary", + e2e.WithArgs( + "connect", + "-target-id", newTargetId, + "-exec", "/usr/bin/ssh", "--", + "-l", c.TargetSshUser, + "-i", c.TargetSshKeyPath, + "-o", "UserKnownHostsFile=/dev/null", + "-o", "StrictHostKeyChecking=no", + "-o", "IdentitiesOnly=yes", // forces the use of the provided key + "-p", "{{boundary.port}}", // this is provided by boundary + "{{boundary.ip}}", + "for i in {1..10}; do pwd; sleep 1s; done", + ), + ) + }() + t.Cleanup(cancel) + + session := boundary.WaitForSessionToBeActiveCli(t, ctx, newProjectId) + assert.Equal(t, newTargetId, session.TargetId) + assert.Equal(t, newHostId, session.HostId) + + // Confirm that bytesDown is increasing + bytesUp := 0 + bytesDown := 0 + t.Log("Reading bytes_up/bytes_down values...") + for i := 0; i < 3; i++ { + if i != 0 { + time.Sleep(2 * time.Second) + } + + output := e2e.RunCommand(ctx, "boundary", + e2e.WithArgs("sessions", "read", "-id", session.Id, "-format", "json"), + ) + require.NoError(t, output.Err, string(output.Stderr)) + var newSessionReadResult sessions.SessionReadResult + err = json.Unmarshal(output.Stdout, &newSessionReadResult) + require.NoError(t, err) + require.GreaterOrEqual(t, int(newSessionReadResult.Item.Connections[0].BytesUp), bytesUp) + bytesUp = int(newSessionReadResult.Item.Connections[0].BytesUp) + require.Greater(t, int(newSessionReadResult.Item.Connections[0].BytesDown), bytesDown) + bytesDown = int(newSessionReadResult.Item.Connections[0].BytesDown) + + t.Logf("bytes_up: %d, bytes_down: %d", bytesUp, bytesDown) + } +} diff --git a/testing/internal/e2e/tests/static/connect_localhost_test.go b/testing/internal/e2e/tests/static/connect_localhost_test.go index 9812040be9..419f8cc900 100644 --- a/testing/internal/e2e/tests/static/connect_localhost_test.go +++ b/testing/internal/e2e/tests/static/connect_localhost_test.go @@ -3,14 +3,11 @@ package static_test import ( "context" "encoding/json" - "errors" "fmt" "strings" "testing" "time" - "github.com/cenkalti/backoff/v4" - "github.com/hashicorp/boundary/api/sessions" "github.com/hashicorp/boundary/testing/internal/e2e" "github.com/hashicorp/boundary/testing/internal/e2e/boundary" "github.com/stretchr/testify/require" @@ -55,41 +52,7 @@ func TestCliConnectTargetWithLocalhost(t *testing.T) { }() t.Cleanup(cancel) - // Wait for session to appear - t.Log("Waiting for session to appear...") - err = backoff.RetryNotify( - func() error { - output := e2e.RunCommand(ctx, "boundary", - e2e.WithArgs("sessions", "list", "-scope-id", newProjectId, "-format", "json"), - ) - if output.Err != nil { - return backoff.Permanent(errors.New(string(output.Stderr))) - } - - var sessionListResult sessions.SessionListResult - err := json.Unmarshal(output.Stdout, &sessionListResult) - if err != nil { - return backoff.Permanent(err) - } - - sessionCount := len(sessionListResult.Items) - if sessionCount == 0 { - return errors.New("No items are appearing in the session list") - } - - t.Logf("Found %d session(s)", sessionCount) - if sessionCount != 1 { - return backoff.Permanent(errors.New("Only one session was expected to be found")) - } - - return nil - }, - backoff.WithMaxRetries(backoff.NewConstantBackOff(3*time.Second), 5), - func(err error, td time.Duration) { - t.Logf("%s. Retrying...", err.Error()) - }, - ) - require.NoError(t, err) + boundary.WaitForSessionCli(t, ctx, newProjectId) // Connect to target and print host's IP address output := e2e.RunCommand(ctx, "ssh", diff --git a/testing/internal/e2e/tests/static/session_cancel_admin_test.go b/testing/internal/e2e/tests/static/session_cancel_admin_test.go index 2126a25d78..273e6e7614 100644 --- a/testing/internal/e2e/tests/static/session_cancel_admin_test.go +++ b/testing/internal/e2e/tests/static/session_cancel_admin_test.go @@ -84,7 +84,7 @@ func TestCliSessionCancelAdmin(t *testing.T) { select { case output := <-errChan: // `boundary connect` returns a 255 when cancelled - require.Equal(t, output.ExitCode, 255, string(output.Stdout), string(output.Stderr)) + require.Equal(t, 255, output.ExitCode, string(output.Stdout), string(output.Stderr)) case <-time.After(time.Second * 5): t.Fatal("Timed out waiting for session command to exit") } diff --git a/testing/internal/e2e/tests/static/session_cancel_group_test.go b/testing/internal/e2e/tests/static/session_cancel_group_test.go index 40fd350bdb..986bb34c03 100644 --- a/testing/internal/e2e/tests/static/session_cancel_group_test.go +++ b/testing/internal/e2e/tests/static/session_cancel_group_test.go @@ -3,6 +3,7 @@ package static_test import ( "context" "encoding/json" + "net/http" "testing" "time" @@ -83,7 +84,7 @@ func TestCliSessionCancelGroup(t *testing.T) { var response boundary.CliError err = json.Unmarshal(output.Stderr, &response) require.NoError(t, err) - require.Equal(t, 403, int(response.Status)) + require.Equal(t, http.StatusForbidden, int(response.Status)) t.Log("Successfully received an error when connecting to target as a user without permissions") // Create a group @@ -168,7 +169,7 @@ func TestCliSessionCancelGroup(t *testing.T) { select { case output := <-errChan: // `boundary connect` returns a 255 when cancelled - require.Equal(t, output.ExitCode, 255, string(output.Stdout), string(output.Stderr)) + require.Equal(t, 255, output.ExitCode, string(output.Stdout), string(output.Stderr)) case <-time.After(time.Second * 5): t.Fatal("Timed out waiting for session command to exit") } diff --git a/testing/internal/e2e/tests/static/session_cancel_user_test.go b/testing/internal/e2e/tests/static/session_cancel_user_test.go index 48f3b5e164..5a6d8f90b1 100644 --- a/testing/internal/e2e/tests/static/session_cancel_user_test.go +++ b/testing/internal/e2e/tests/static/session_cancel_user_test.go @@ -3,6 +3,7 @@ package static_test import ( "context" "encoding/json" + "net/http" "testing" "time" @@ -82,7 +83,7 @@ func TestCliSessionCancelUser(t *testing.T) { var response boundary.CliError err = json.Unmarshal(output.Stderr, &response) require.NoError(t, err) - require.Equal(t, 403, int(response.Status)) + require.Equal(t, http.StatusForbidden, int(response.Status)) t.Log("Successfully received an error when connecting to target as a user without permissions") // Create a role for user @@ -142,7 +143,7 @@ func TestCliSessionCancelUser(t *testing.T) { select { case output := <-errChan: // `boundary connect` returns a 255 when cancelled - require.Equal(t, output.ExitCode, 255, string(output.Stdout), string(output.Stderr)) + require.Equal(t, 255, output.ExitCode, string(output.Stdout), string(output.Stderr)) case <-time.After(time.Second * 5): t.Fatal("Timed out waiting for session command to exit") } diff --git a/testing/internal/e2e/tests/static/session_end_delete_host_set_test.go b/testing/internal/e2e/tests/static/session_end_delete_host_set_test.go index e09623f9f0..0bf08e5799 100644 --- a/testing/internal/e2e/tests/static/session_end_delete_host_set_test.go +++ b/testing/internal/e2e/tests/static/session_end_delete_host_set_test.go @@ -100,7 +100,7 @@ func TestCliSessionEndWhenHostSetIsDeleted(t *testing.T) { select { case output := <-errChan: // `boundary connect` returns a 255 when cancelled - require.Equal(t, output.ExitCode, 255, string(output.Stdout), string(output.Stderr)) + require.Equal(t, 255, output.ExitCode, string(output.Stdout), string(output.Stderr)) case <-time.After(time.Second * 5): t.Fatal("Timed out waiting for session command to exit") } diff --git a/testing/internal/e2e/tests/static/session_end_delete_host_test.go b/testing/internal/e2e/tests/static/session_end_delete_host_test.go index 887b7228ec..c407118514 100644 --- a/testing/internal/e2e/tests/static/session_end_delete_host_test.go +++ b/testing/internal/e2e/tests/static/session_end_delete_host_test.go @@ -100,7 +100,7 @@ func TestCliSessionEndWhenHostIsDeleted(t *testing.T) { select { case output := <-errChan: // `boundary connect` returns a 255 when cancelled - require.Equal(t, output.ExitCode, 255, string(output.Stdout), string(output.Stderr)) + require.Equal(t, 255, output.ExitCode, string(output.Stdout), string(output.Stderr)) case <-time.After(time.Second * 5): t.Fatal("Timed out waiting for session command to exit") } diff --git a/testing/internal/e2e/tests/static/session_end_delete_target_test.go b/testing/internal/e2e/tests/static/session_end_delete_target_test.go index 32743caeff..84566ad4ee 100644 --- a/testing/internal/e2e/tests/static/session_end_delete_target_test.go +++ b/testing/internal/e2e/tests/static/session_end_delete_target_test.go @@ -100,7 +100,7 @@ func TestCliSessionEndWhenTargetIsDeleted(t *testing.T) { select { case output := <-errChan: // `boundary connect` returns a 255 when cancelled - require.Equal(t, output.ExitCode, 255, string(output.Stdout), string(output.Stderr)) + require.Equal(t, 255, output.ExitCode, string(output.Stdout), string(output.Stderr)) case <-time.After(time.Second * 5): t.Fatal("Timed out waiting for session command to exit") } diff --git a/testing/internal/e2e/tests/static/session_end_delete_user_test.go b/testing/internal/e2e/tests/static/session_end_delete_user_test.go index 007c7ec00b..6f4246821f 100644 --- a/testing/internal/e2e/tests/static/session_end_delete_user_test.go +++ b/testing/internal/e2e/tests/static/session_end_delete_user_test.go @@ -93,7 +93,7 @@ func TestCliSessionEndWhenUserIsDeleted(t *testing.T) { select { case output := <-errChan: // `boundary connect` returns a 255 when cancelled - require.Equal(t, output.ExitCode, 255, string(output.Stdout), string(output.Stderr)) + require.Equal(t, 255, output.ExitCode, string(output.Stdout), string(output.Stderr)) case <-time.After(time.Second * 5): t.Fatal("Timed out waiting for session command to exit") } diff --git a/testing/internal/e2e/vault/env.go b/testing/internal/e2e/vault/env.go new file mode 100644 index 0000000000..31cb09cdfb --- /dev/null +++ b/testing/internal/e2e/vault/env.go @@ -0,0 +1,18 @@ +package vault + +import "github.com/kelseyhightower/envconfig" + +type config struct { + VaultAddr string `envconfig:"VAULT_ADDR" required:"true"` // e.g. "http://127.0.0.1:8200" + VaultToken string `envconfig:"VAULT_TOKEN" required:"true"` +} + +func loadConfig() (*config, error) { + var c config + err := envconfig.Process("", &c) + if err != nil { + return nil, err + } + + return &c, nil +} diff --git a/testing/internal/e2e/vault/vault.go b/testing/internal/e2e/vault/vault.go index b9c8db15c7..2e4eaaa8e9 100644 --- a/testing/internal/e2e/vault/vault.go +++ b/testing/internal/e2e/vault/vault.go @@ -10,15 +10,9 @@ import ( "github.com/hashicorp/boundary/testing/internal/e2e" "github.com/hashicorp/go-secure-stdlib/base62" - "github.com/kelseyhightower/envconfig" "github.com/stretchr/testify/require" ) -type config struct { - VaultAddr string `envconfig:"VAULT_ADDR" required:"true"` // e.g. "http://127.0.0.1:8200" - VaultToken string `envconfig:"VAULT_TOKEN" required:"true"` -} - // CreateTokenResponse parses the json response from running `vault token create` type CreateTokenResponse struct { Auth struct { @@ -26,16 +20,6 @@ type CreateTokenResponse struct { } } -func loadConfig() (*config, error) { - var c config - err := envconfig.Process("", &c) - if err != nil { - return nil, err - } - - return &c, nil -} - // Setup verifies if appropriate credentials are set and adds the boundary controller // policy to vault. Returns the vault address. func Setup(t testing.TB) (vaultAddr string, boundaryPolicyName string, kvPolicyFilePath string) {