diff --git a/cmd/run.go b/cmd/run.go index ae60f900b843..6097f2025bdf 100644 --- a/cmd/run.go +++ b/cmd/run.go @@ -251,9 +251,6 @@ a commandline interface for interacting with it.`, initBar.Modify(pb.WithConstProgress(0, "Init VUs...")) engineRun, engineWait, err := engine.Init(globalCtx, runCtx) if err != nil { - if common.IsInterruptError(err) { - return errext.WithExitCodeIfNone(err, exitcodes.ScriptException) - } // Add a generic engine exit code if we don't have a more specific one return errext.WithExitCodeIfNone(err, exitcodes.GenericEngine) } @@ -281,6 +278,8 @@ a commandline interface for interacting with it.`, err = engineRun() if err != nil { if common.IsInterruptError(err) { + // Don't return here since we need to work with --linger, + // show the end-of-test summary and exit cleanly. interrupt = err } if !conf.Linger.Bool && interrupt == nil { @@ -335,7 +334,7 @@ a commandline interface for interacting with it.`, engineWait() logger.Debug("Everything has finished, exiting k6!") if interrupt != nil { - return errext.WithExitCodeIfNone(interrupt, exitcodes.ScriptException) + return interrupt } if engine.IsTainted() { return errext.WithExitCodeIfNone(errors.New("some thresholds have failed"), exitcodes.ThresholdsHaveFailed) diff --git a/cmd/run_test.go b/cmd/run_test.go index 95b02e1d044b..58198104d92d 100644 --- a/cmd/run_test.go +++ b/cmd/run_test.go @@ -136,7 +136,7 @@ func TestHandleSummaryResultError(t *testing.T) { func TestAbortTest(t *testing.T) { //nolint: tparallel t.Parallel() - t.Run("Check status code is 107", func(t *testing.T) { //nolint: paralleltest + t.Run("Check correct status code", func(t *testing.T) { //nolint: paralleltest ctx, cancel := context.WithCancel(context.Background()) defer cancel() logger := testutils.NewLogger(t) @@ -148,7 +148,8 @@ func TestAbortTest(t *testing.T) { //nolint: tparallel err = cmd.Execute() var e errext.HasExitCode require.ErrorAs(t, err, &e) - require.Equal(t, exitcodes.ScriptException, e.ExitCode(), "Status code must be 107") + assert.Equalf(t, exitcodes.ScriptAborted, e.ExitCode(), + "Status code must be %d", exitcodes.ScriptAborted) require.Contains(t, e.Error(), common.AbortTest) }) @@ -172,7 +173,8 @@ func TestAbortTest(t *testing.T) { //nolint: tparallel err = cmd.Execute() var e errext.HasExitCode require.ErrorAs(t, err, &e) - assert.Equal(t, exitcodes.ScriptException, e.ExitCode(), "Status code must be 107") + assert.Equalf(t, exitcodes.ScriptAborted, e.ExitCode(), + "Status code must be %d", exitcodes.ScriptAborted) assert.Contains(t, e.Error(), common.AbortTest) assert.Contains(t, buf.String(), msg) }) diff --git a/errext/exitcodes/codes.go b/errext/exitcodes/codes.go index d98aaf4ab721..c0e0b48c5ee5 100644 --- a/errext/exitcodes/codes.go +++ b/errext/exitcodes/codes.go @@ -36,4 +36,5 @@ const ( ExternalAbort errext.ExitCode = 105 CannotStartRESTAPI errext.ExitCode = 106 ScriptException errext.ExitCode = 107 + ScriptAborted errext.ExitCode = 108 ) diff --git a/js/common/interrupt_error.go b/js/common/interrupt_error.go index c568e131ada3..ffa0d3b6b349 100644 --- a/js/common/interrupt_error.go +++ b/js/common/interrupt_error.go @@ -20,17 +20,30 @@ package common -import "errors" +import ( + "errors" + + "go.k6.io/k6/errext" + "go.k6.io/k6/errext/exitcodes" +) // InterruptError is an error that halts engine execution type InterruptError struct { Reason string } +var _ errext.HasExitCode = &InterruptError{} + +// Error returns the reason of the interruption. func (i *InterruptError) Error() string { return i.Reason } +// ExitCode returns the status code used when the k6 process exits. +func (i *InterruptError) ExitCode() errext.ExitCode { + return exitcodes.ScriptAborted +} + // AbortTest is the reason emitted when a test script calls test.abort() const AbortTest = "test aborted"