-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add abortTest() helper function #1920
Conversation
Closes grafana#1001 This adds abortTest() helper function to the k6 module. This function when called inside a script it will - stop the whole test run and k6 will exit with 107 status code - stops immediately the VU that called it and no more iterations are started - make sure the teardown() is called - the engine run status is 7 (RunStatusAbortedScriptError) `(*goja.Runtime).Interrupt` is used for halting script execution and capturing stack traces for better error message of what is happening with the script. We introduce InterruptError which is used with `(*goja.Runtime).Interrupt` to identify interrupts emitted by abortTest(). This way we use special handling of this type. Example script is ```js import { abortTest, sleep } from 'k6'; export default function () { // We abort the test on second iteration if (__ITER == 1) { abortTest(); } sleep(1); } export function teardown() { console.log('This function will be called even when we abort script'); } ``` abortTest() can be called in both default and setup functions, however you can't use it in the init context The following script will fail with the error ``` ERRO[0000] Using abortTest() in the init context is not supported at (...path to the script )init.js:13:43(34) ``` ```js import { abortTest } from 'k6'; abortTest(); export function setup() { } export default function () { // ... some test logic ... console.log('mayday, mayday'); } ``` You can customize the reason for abortTest() by passing values to the function ```js abortTest("Exceeded expectations"); ``` Will emit `"Exceeded expectations"` on the logs
Codecov Report
@@ Coverage Diff @@
## master #1920 +/- ##
==========================================
+ Coverage 71.26% 73.04% +1.78%
==========================================
Files 183 183
Lines 14336 14382 +46
==========================================
+ Hits 10216 10505 +289
+ Misses 3480 3206 -274
- Partials 640 671 +31
Flags with carried forward coverage won't be shown. Click here to find out more.
Continue to review full report at Codecov.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! I haven't done a full code review yet, I've only skimmed the changes and played around with the resulting binary a bit, but in general, your approach looks good! The only big issue I noticed is that these changes break the --linger
functionality.
k6 run --linger script.js
should still linger when abortTest()
is used, i.e. the k6 process shouldn't exit directly after the test run has stopped. This behavior should remain the same as it was with the old way of aborting the test run (thresholds with abortOnFail: true
).
This change makes abortTest() behave like thresholds with `abortOnFail: true` when called with --linger flag
@na-- thanks for the quick and good feedback. I had missed the When we run scripts that use Winding down of the engine will be observed like with thresholds and waiting for Relevant commit c07af18 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks very good to me, nice work! I just left some minor comments and nitpicks.
Also there's a check next to "Check teardown is called when a script aborts", but I don't see that test and I agree that it should be added.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems good in general 🎉
- definitely, need to move the IterruptedError definition out of
js/common
and probably ...lib/errors
, something else ? - not so certain that this isn't an abuse of contexts and that I wouldn't prefer a more direct approach, but looking at the code around this ... I think that will require some pretty big refactoring and probably will make things actually worse than better, so I am fine with it
lib/executor/helpers.go
Outdated
if handleInterupt(ctx, err) { | ||
executionState.AddInterruptedIterations(1) | ||
return false | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Co-authored-by: Ivan Mirić <[email protected]>
Co-authored-by: Ivan Mirić <[email protected]>
Co-authored-by: Ivan Mirić <[email protected]>
Co-authored-by: Ivan Mirić <[email protected]>
Co-authored-by: Ivan Mirić <[email protected]>
Co-authored-by: Ivan Mirić <[email protected]>
* master: Fix DOCKER_IMAGE_ID and add GHCR_IMAGE_ID after repo move Drop all the go mod replaces Bump golang version to 1.16 in Dockerfile Bump versions in CI from 1.14->1.15 and from 1.15->1.16 Disable let/const babel plugin and co update goja to latest master
to avoid panics and data races pass empty flag address
@na-- @imiric @mstoykov thanks a lot for the amazing feedback, I have addressed all review comments (I think) PTAL
Thanks for catching this one, I added the test in b5b8441 (that i improved a bit in later commits, like cancel context .. etc) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! The only minor nitpick I have is that instead of directly type casting errors, you should probably use the recent errors.Is()
and errors.As()
stdlib functions.
Other than that, everything looks great! The changes ended up more complex than I expected, but can't think of a way to simplify them without significant refactoring and everything is still understandable, so this is going to be it! 🎉
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, well done! Just left a tiny nitpick, feel free to disregard.
Also, please rebase on top of the latest master
and cleanup the commits a bit before this is merged. Not necessarily squashing to a single commit, but whatever makes sense for the changes to be atomic.
cmd.Flags().AddFlag(&pflag.Flag{ | ||
Name: "address", | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is this for?
...
Ah, I see, it's to avoid a nil pointer panic in run.go:217
. It doesn't seem to be required for this test, but the one below does fail without it. In any case, it would be good to mention this in a comment.
Also, both of these tests are quite noisy when ran with go test -v
. It would be good if that could be captured internally and not actually printed to stdout
. Though if it requires overriding the global stdout
var, then it's probably not worth it 😄
Hi all, Just been looking into this functionality would be great if this can get merged in soon! |
@rushby, we wanted to merge this for k6 v0.33.0, but we weren't able because it's blocked by some other changes we needed to make in k6 (e.g. #1863) and in our cloud, so it can work both in single instance and in distributed tests. We plan to merge it for k6 v0.34.0, slated to be released sometime in the end of August/early September. |
Closes #1001
This adds
abortTest()
helper function to the k6 module. This function whencalled inside a script it will
(*goja.Runtime).Interrupt
is used for halting script execution and capturingstack traces for better error message of what is happening with the script.
We introduce InterruptError which is used with
(*goja.Runtime).Interrupt
toidentify interrupts emitted by abortTest(). This way we use special handling of
this type.
Example script is
abortTest() can be called anywhere in the script.
The following script will fail with the error
You can customize the reason for abortTest() by passing values to the function
Will emit
"Exceeded expectations"
on the logsMissing
107
when theabortTest()
is called in a scriptCTRL+C
when--linger
flag is setabortTest()
without argumentsabortTest("maybday!")