Skip to content

Commit 243bb8a

Browse files
assert exit codes
1 parent 2ce11ae commit 243bb8a

File tree

12 files changed

+50
-0
lines changed

12 files changed

+50
-0
lines changed

test/integration/awsconfig_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,5 +153,6 @@ func TestStartNonInteractiveEmitsNoteWhenAWSProfileMissing(t *testing.T) {
153153
"start",
154154
)
155155
require.NoError(t, err)
156+
requireExitCode(t, 0, err)
156157
assert.Contains(t, stdout, "No complete LocalStack AWS profile found")
157158
}

test/integration/config_test.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ func TestConfigFileCreatedOnStartup(t *testing.T) {
2222
e := testEnvWithHome(tmpHome, xdgOverride)
2323
_, stderr, err := runLstk(t, testContext(t), workDir, e, "logout")
2424
require.NoError(t, err, stderr)
25+
requireExitCode(t, 0, err)
2526

2627
expectedConfigFile := filepath.Join(tmpHome, ".config", "lstk", "config.toml")
2728
assert.FileExists(t, expectedConfigFile)
@@ -36,6 +37,7 @@ func TestConfigFileCreatedOnStartup(t *testing.T) {
3637
e := testEnvWithHome(tmpHome, xdgOverride)
3738
_, stderr, err := runLstk(t, testContext(t), workDir, e, "logout")
3839
require.NoError(t, err, stderr)
40+
requireExitCode(t, 0, err)
3941

4042
expectedConfigFile := filepath.Join(expectedOSConfigDir(tmpHome, xdgOverride), "config.toml")
4143
assert.FileExists(t, expectedConfigFile)
@@ -69,6 +71,7 @@ IAM_SOFT_MODE = "1"
6971
ctx := testContext(t)
7072
_, stderr, err := runLstk(t, ctx, "", env.With(env.APIEndpoint, mockServer.URL), "--config", configFile, "start")
7173
require.NoError(t, err, "lstk start failed: %s", stderr)
74+
requireExitCode(t, 0, err)
7275

7376
inspect, err := dockerClient.ContainerInspect(ctx, containerName)
7477
require.NoError(t, err, "failed to inspect container")
@@ -81,6 +84,7 @@ func TestConfigFlagOverridesConfigPath(t *testing.T) {
8184

8285
stdout, stderr, err := runLstk(t, testContext(t), t.TempDir(), os.Environ(), "--config", customConfig, "config", "path")
8386
require.NoError(t, err, stderr)
87+
requireExitCode(t, 0, err)
8488

8589
assertSamePath(t, customConfig, stdout)
8690
}
@@ -98,6 +102,7 @@ func TestLocalConfigTakesPrecedence(t *testing.T) {
98102
e := testEnvWithHome(tmpHome, xdgOverride)
99103
stdout, stderr, err := runLstk(t, testContext(t), workDir, e, "config", "path")
100104
require.NoError(t, err, stderr)
105+
requireExitCode(t, 0, err)
101106

102107
expectedLocalPath, err := filepath.Abs(localConfigFile)
103108
require.NoError(t, err)
@@ -117,6 +122,7 @@ func TestXDGConfigTakesPrecedence(t *testing.T) {
117122
e := testEnvWithHome(tmpHome, xdgOverride)
118123
stdout, stderr, err := runLstk(t, testContext(t), workDir, e, "config", "path")
119124
require.NoError(t, err, stderr)
125+
requireExitCode(t, 0, err)
120126

121127
assertSamePath(t, xdgConfigFile, stdout)
122128
}
@@ -130,6 +136,7 @@ func TestConfigPathCommand(t *testing.T) {
130136
e := testEnvWithHome(tmpHome, filepath.Join(tmpHome, "xdg-config-home"))
131137
stdout, stderr, err := runLstk(t, testContext(t), workDir, e, "config", "path")
132138
require.NoError(t, err, stderr)
139+
requireExitCode(t, 0, err)
133140

134141
assertSamePath(t, xdgConfigFile, stdout)
135142
}
@@ -143,6 +150,7 @@ func TestConfigPathCommandDoesNotCreateConfig(t *testing.T) {
143150
e := testEnvWithHome(tmpHome, xdgOverride)
144151
stdout, stderr, err := runLstk(t, testContext(t), workDir, e, "config", "path")
145152
require.NoError(t, err, stderr)
153+
requireExitCode(t, 0, err)
146154

147155
assertSamePath(t, expectedConfigFile, stdout)
148156
assert.NoFileExists(t, expectedConfigFile)

test/integration/license_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ func TestLicenseValidationSuccess(t *testing.T) {
6565
}
6666

6767
require.NoError(t, err, "lstk start failed: %s", stderr)
68+
requireExitCode(t, 0, err)
6869

6970
inspect, err := dockerClient.ContainerInspect(ctx, containerName)
7071
require.NoError(t, err, "failed to inspect container")
@@ -82,6 +83,7 @@ func TestLicenseValidationFailure(t *testing.T) {
8283
ctx := testContext(t)
8384
_, stderr, err := runLstk(t, ctx, "", env.With(env.APIEndpoint, mockServer.URL).With(env.AuthToken, "test-token-for-license-validation"), "start")
8485
require.Error(t, err, "expected lstk start to fail with forbidden license")
86+
requireExitCode(t, 1, err)
8587
assert.Contains(t, stderr, "license validation failed")
8688
assert.Contains(t, stderr, "invalid, inactive, or expired")
8789

test/integration/login_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ func TestDeviceFlowSuccess(t *testing.T) {
120120

121121
out := output.String()
122122
require.NoError(t, err, "login should succeed: %s", out)
123+
requireExitCode(t, 0, err)
123124
assert.Contains(t, out, "Opening browser to login...")
124125
assert.Contains(t, out, "Browser didn't open? Visit")
125126
assert.Contains(t, out, "/auth/request/test-auth-req-id?code=TEST123")
@@ -176,6 +177,7 @@ func TestDeviceFlowFailure_RequestNotConfirmed(t *testing.T) {
176177

177178
out := output.String()
178179
require.Error(t, err, "expected login to fail when request not confirmed")
180+
requireExitCode(t, 1, err)
179181
assert.Contains(t, out, "Opening browser to login...")
180182
assert.Contains(t, out, "Browser didn't open? Visit")
181183
assert.Contains(t, out, "/auth/request/test-auth-req-id?code=TEST123")

test/integration/logout_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ func TestLogoutCommandRemovesToken(t *testing.T) {
1919

2020
stdout, stderr, err := runLstk(t, testContext(t), "", nil, "logout")
2121
require.NoError(t, err, "lstk logout failed: %s", stderr)
22+
requireExitCode(t, 0, err)
2223
assert.Contains(t, stdout, "Logged out successfully")
2324

2425
_, err = GetAuthTokenFromKeyring()
@@ -30,6 +31,7 @@ func TestLogoutCommandSucceedsWhenNoToken(t *testing.T) {
3031

3132
stdout, stderr, err := runLstk(t, testContext(t), "", env.Without(env.AuthToken), "logout")
3233
require.NoError(t, err, "lstk logout should succeed even with no token: %s", stderr)
34+
requireExitCode(t, 0, err)
3335
assert.Contains(t, stdout, "Not currently logged in")
3436
}
3537

@@ -38,6 +40,7 @@ func TestLogoutCommandWithEnvVarToken(t *testing.T) {
3840

3941
stdout, stderr, err := runLstk(t, testContext(t), "", env.Without(env.AuthToken).With(env.AuthToken, "test-env-token"), "logout")
4042
require.NoError(t, err, "lstk logout should succeed: %s", stderr)
43+
requireExitCode(t, 0, err)
4144
assert.Contains(t, stdout, "LOCALSTACK_AUTH_TOKEN")
4245
}
4346

@@ -57,5 +60,6 @@ func TestLogoutCommandNotesWhenEmulatorStillRunning(t *testing.T) {
5760

5861
stdout, stderr, err := runLstk(t, ctx, "", nil, "logout")
5962
require.NoError(t, err, "lstk logout failed: %s", stderr)
63+
requireExitCode(t, 0, err)
6064
assert.Contains(t, stdout, "LocalStack is still running in the background")
6165
}

test/integration/logs_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ func TestLogsExitsByDefault(t *testing.T) {
2222

2323
_, _, err := runLstk(t, ctx, "", nil, "logs")
2424
require.NoError(t, err, "lstk logs should exit cleanly when container is running")
25+
requireExitCode(t, 0, err)
2526
}
2627

2728
func TestLogsCommandFailsWhenNotRunning(t *testing.T) {
@@ -31,6 +32,7 @@ func TestLogsCommandFailsWhenNotRunning(t *testing.T) {
3132

3233
_, stderr, err := runLstk(t, testContext(t), "", nil, "logs", "--follow")
3334
require.Error(t, err, "expected lstk logs --follow to fail when container not running")
35+
requireExitCode(t, 1, err)
3436
assert.Contains(t, stderr, "emulator is not running")
3537
}
3638

test/integration/main_test.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,17 @@ func runLstkInPTY(t *testing.T, ctx context.Context, environ []string, args ...s
237237
return strings.TrimSpace(out.String()), err
238238
}
239239

240+
func requireExitCode(t *testing.T, expected int, err error) {
241+
t.Helper()
242+
if expected == 0 {
243+
require.NoError(t, err)
244+
return
245+
}
246+
var exitErr *exec.ExitError
247+
require.ErrorAs(t, err, &exitErr)
248+
require.Equal(t, expected, exitErr.ExitCode())
249+
}
250+
240251
func createMockLicenseServer(success bool) *httptest.Server {
241252
return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
242253
if r.Method == "POST" && r.URL.Path == "/v1/license/request" {

test/integration/non_interactive_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
func TestNonInteractiveFlagBlocksLogin(t *testing.T) {
1212
out, err := runLstkInPTY(t, testContext(t), nil, "login", "--non-interactive")
1313
require.Error(t, err, "expected login --non-interactive to fail")
14+
requireExitCode(t, 1, err)
1415
assert.Contains(t, out, "login requires an interactive terminal")
1516
}
1617

@@ -24,6 +25,7 @@ func TestNonInteractiveFlagFailsWithoutToken(t *testing.T) {
2425

2526
out, err := runLstkInPTY(t, testContext(t), env.Without(env.AuthToken).With(env.APIEndpoint, mockServer.URL), "start", "--non-interactive")
2627
require.Error(t, err, "expected start --non-interactive to fail with no auth token")
28+
requireExitCode(t, 1, err)
2729
assert.Contains(t, out, "authentication required: set LOCALSTACK_AUTH_TOKEN or run in interactive mode")
2830
}
2931

@@ -37,5 +39,6 @@ func TestRootNonInteractiveFlagFailsWithoutToken(t *testing.T) {
3739

3840
out, err := runLstkInPTY(t, testContext(t), env.Without(env.AuthToken).With(env.APIEndpoint, mockServer.URL), "--non-interactive")
3941
require.Error(t, err, "expected lstk --non-interactive to fail with no auth token")
42+
requireExitCode(t, 1, err)
4043
assert.Contains(t, out, "authentication required: set LOCALSTACK_AUTH_TOKEN or run in interactive mode")
4144
}

test/integration/start_test.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ func TestStartCommandSucceedsWithValidToken(t *testing.T) {
2424
ctx := testContext(t)
2525
_, stderr, err := runLstk(t, ctx, "", env.With(env.APIEndpoint, mockServer.URL), "start")
2626
require.NoError(t, err, "lstk start failed: %s", stderr)
27+
requireExitCode(t, 0, err)
2728

2829
inspect, err := dockerClient.ContainerInspect(ctx, containerName)
2930
require.NoError(t, err, "failed to inspect container")
@@ -47,6 +48,7 @@ func TestStartCommandSucceedsWithKeyringToken(t *testing.T) {
4748
// Run without LOCALSTACK_AUTH_TOKEN should use keyring
4849
_, stderr, err := runLstk(t, ctx, "", env.Without(env.AuthToken).With(env.APIEndpoint, mockServer.URL), "start")
4950
require.NoError(t, err, "lstk start failed: %s", stderr)
51+
requireExitCode(t, 0, err)
5052

5153
inspect, err := dockerClient.ContainerInspect(ctx, containerName)
5254
require.NoError(t, err, "failed to inspect container")
@@ -63,6 +65,7 @@ func TestStartCommandFailsWithInvalidToken(t *testing.T) {
6365

6466
_, stderr, err := runLstk(t, testContext(t), "", env.With(env.AuthToken, "invalid-token").With(env.APIEndpoint, mockServer.URL), "start")
6567
require.Error(t, err, "expected lstk start to fail with invalid token")
68+
requireExitCode(t, 1, err)
6669
assert.Contains(t, stderr, "license validation failed")
6770
}
6871

@@ -76,6 +79,7 @@ func TestStartCommandDoesNothingWhenAlreadyRunning(t *testing.T) {
7679

7780
stdout, stderr, err := runLstk(t, ctx, "", env.With(env.AuthToken, "fake-token"), "start")
7881
require.NoError(t, err, "lstk start should succeed when container is already running: %s", stderr)
82+
requireExitCode(t, 0, err)
7983
assert.Contains(t, stdout, "already running")
8084
}
8185

@@ -90,6 +94,7 @@ func TestStartCommandFailsWhenPortInUse(t *testing.T) {
9094

9195
stdout, _, err := runLstk(t, testContext(t), "", env.With(env.AuthToken, "fake-token"), "start")
9296
require.Error(t, err, "expected lstk start to fail when port is in use")
97+
requireExitCode(t, 1, err)
9398
assert.Contains(t, stdout, "Port 4566 already in use")
9499
assert.Contains(t, stdout, "LocalStack may already be running.")
95100
assert.Contains(t, stdout, "lstk stop")

test/integration/stop_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ func TestStopCommandSucceeds(t *testing.T) {
1717

1818
stdout, stderr, err := runLstk(t, ctx, "", nil, "stop")
1919
require.NoError(t, err, "lstk stop failed: %s", stderr)
20+
requireExitCode(t, 0, err)
2021
assert.Contains(t, stdout, "Stopping", "should show stopping message")
2122
assert.Contains(t, stdout, "stopped", "should show stopped message")
2223

@@ -31,6 +32,7 @@ func TestStopCommandFailsWhenNotRunning(t *testing.T) {
3132

3233
_, stderr, err := runLstk(t, testContext(t), "", nil, "stop")
3334
require.Error(t, err, "expected lstk stop to fail when container not running")
35+
requireExitCode(t, 1, err)
3436
assert.Contains(t, stderr, "is not running")
3537
}
3638

@@ -44,10 +46,12 @@ func TestStopCommandIsIdempotent(t *testing.T) {
4446

4547
_, stderr, err := runLstk(t, ctx, "", nil, "stop")
4648
require.NoError(t, err, "first lstk stop failed: %s", stderr)
49+
requireExitCode(t, 0, err)
4750

4851
_, err = dockerClient.ContainerInspect(ctx, containerName)
4952
require.Error(t, err, "container should not exist after first stop")
5053

5154
_, _, err = runLstk(t, ctx, "", nil, "stop")
5255
assert.Error(t, err, "second lstk stop should fail since container already removed")
56+
requireExitCode(t, 1, err)
5357
}

0 commit comments

Comments
 (0)