From 058efe5bc5e570fc459194976be48e142f7f0bba Mon Sep 17 00:00:00 2001 From: Nedyalko Andreev Date: Fri, 3 Feb 2023 10:44:01 +0200 Subject: [PATCH] Fix the exit code and run_status when the cloud output aborts a test --- errext/abort_reason.go | 1 + output/cloud/output.go | 13 +++++++++---- output/cloud/output_test.go | 12 ++++++------ output/types.go | 8 ++++---- 4 files changed, 20 insertions(+), 14 deletions(-) diff --git a/errext/abort_reason.go b/errext/abort_reason.go index a9452f92be78..a4c6f0348c38 100644 --- a/errext/abort_reason.go +++ b/errext/abort_reason.go @@ -14,6 +14,7 @@ const ( AbortedByScriptError AbortedByScriptAbort AbortedByTimeout + AbortedByOutput ) // HasAbortReason is a wrapper around an error with an attached abort reason. diff --git a/output/cloud/output.go b/output/cloud/output.go index f05ad1d530d4..4b99954be814 100644 --- a/output/cloud/output.go +++ b/output/cloud/output.go @@ -15,6 +15,7 @@ import ( "go.k6.io/k6/cloudapi" "go.k6.io/k6/errext" + "go.k6.io/k6/errext/exitcodes" "go.k6.io/k6/output" "go.k6.io/k6/lib" @@ -59,7 +60,7 @@ type Output struct { aggregationDone *sync.WaitGroup stopOutput chan struct{} outputDone *sync.WaitGroup - engineStopFunc func(error) + testStopFunc func(error) } // Verify that Output implements the wanted interfaces @@ -309,7 +310,7 @@ func (out *Output) getRunStatus(testErr error) cloudapi.RunStatus { return cloudapi.RunStatusAbortedScriptError case errext.AbortedByScriptAbort: return cloudapi.RunStatusAbortedUser // TODO: have a better value than this? - case errext.AbortedByTimeout: + case errext.AbortedByTimeout, errext.AbortedByOutput: return cloudapi.RunStatusAbortedLimit case errext.AbortedByThresholdsAfterTestEnd: // The test run finished normally, it wasn't prematurely aborted by @@ -349,7 +350,7 @@ func (out *Output) SetThresholds(scriptThresholds map[string]metrics.Thresholds) // SetTestRunStopCallback receives the function that stops the engine on error func (out *Output) SetTestRunStopCallback(stopFunc func(error)) { - out.engineStopFunc = stopFunc + out.testStopFunc = stopFunc } // AddMetricSamples receives a set of metric samples. This method is never @@ -652,8 +653,12 @@ func (out *Output) pushMetrics() { if err != nil { if out.shouldStopSendingMetrics(err) { out.logger.WithError(err).Warn("Stopped sending metrics to cloud due to an error") + serr := errext.WithAbortReasonIfNone( + errext.WithExitCodeIfNone(err, exitcodes.ExternalAbort), + errext.AbortedByOutput, + ) if out.config.StopOnError.Bool { - out.engineStopFunc(err) + out.testStopFunc(serr) } close(out.stopSendingMetrics) break diff --git a/output/cloud/output_test.go b/output/cloud/output_test.go index 7b16e03a1f78..0b19fb7d1a17 100644 --- a/output/cloud/output_test.go +++ b/output/cloud/output_test.go @@ -436,13 +436,13 @@ func testCloudOutputStopSendingMetric(t *testing.T, stopOnError bool) { }, ScriptPath: &url.URL{Path: "/script.js"}, }) - var expectedEngineStopFuncCalled int64 + var expectedTestStopFuncCalled int64 if stopOnError { - expectedEngineStopFuncCalled = 1 + expectedTestStopFuncCalled = 1 } - var engineStopFuncCalled int64 - out.engineStopFunc = func(error) { - atomic.AddInt64(&engineStopFuncCalled, 1) + var TestStopFuncCalled int64 + out.testStopFunc = func(error) { + atomic.AddInt64(&TestStopFuncCalled, 1) } require.NoError(t, err) now := time.Now() @@ -513,7 +513,7 @@ func testCloudOutputStopSendingMetric(t *testing.T, stopOnError bool) { t.Fatal("sending metrics wasn't stopped") } require.Equal(t, max, count) - require.Equal(t, expectedEngineStopFuncCalled, engineStopFuncCalled) + require.Equal(t, expectedTestStopFuncCalled, TestStopFuncCalled) nBufferSamples := len(out.bufferSamples) nBufferHTTPTrails := len(out.bufferHTTPTrails) diff --git a/output/types.go b/output/types.go index 5aa1b203eb49..0d3ca08ec4eb 100644 --- a/output/types.go +++ b/output/types.go @@ -66,10 +66,10 @@ type WithThresholds interface { SetThresholds(map[string]metrics.Thresholds) } -// WithTestRunStop is an output that can stop the Engine mid-test, interrupting -// the whole test run execution if some internal condition occurs, completely -// independently from the thresholds. It requires a callback function which -// expects an error and triggers the Engine to stop. +// WithTestRunStop is an output that can stop the test run mid-way through, +// interrupting the whole test run execution if some internal condition occurs, +// completely independently from the thresholds. It requires a callback function +// which expects an error and triggers the Engine to stop. type WithTestRunStop interface { Output SetTestRunStopCallback(func(error))