When a cucumber worker sends the testCaseFinished event back to the coordinator, do not mark the worker as "not in progress" until after all retries have finished being processed by the worker.
⚡️ What's your motivation?
Howdy, I started getting feedback from other people that Cucumber wasn't respecting parallel rules when retrying long-running tests in certain situations. I was skeptical at first, but I was able to replicate it and find the source of the problem.
The following test minimally reproduces the issue:
// example.feature
@parallelTesting
Feature: Testing retries not in parallel
Scenario: I wait awhile SHOULD FAIL
When I print "Start waiting 3"
And I wait 3
And I fail
Example: I wait awhile again
When I print "Start waiting <number>"
When I wait <number>
And I print "Waited <number>"
Examples:
| number |
| 5 |
@notInParallel
Example: NO PARALLEL I wait awhile
When I print "Start waiting <number>"
When I wait <number>
And I print "Waited <number>"
Examples:
| number |
| 1 |
| 1 |
| 1 |
| 1 |
| 1 |
For this example, I had retries set to 4 to really hammer the point home. I started realizing that the NO PARALLEL tests actually started running, even when the SHOULD FAIL test was still doing a retry. This only occurs if the subsequent parallel scenarios finish and non-parallel tests need to run. Because the this.inProgressWorkers map is empty, it forces the notInParallel test to run while the retries are being attempted. This is causing flakiness in some of our tests.
You can remove the changes from src/runtime/parallel/coordinator.ts and the test case provided in the PR will fail, demonstrating the issue and ensuring the issue is not encountered again.
🏷️ What kind of change is this?
:bug: Bug fix (non-breaking change which fixes a defect)
♻️ Anything particular you want feedback on?
The scenario and step definition look kinda ugly, so I'm very much open to ideas to make the code look a bit simpler. Filtering through the envelopes is always a bit difficult to do cleanly, especially without chaining higher order functions.
coverage: 98.234% (+0.001%) from 98.233%
when pulling 1e08b0ecadf3c6c4449ac4a2632212a648e993bf on tristanzander:main
into b02a90a36e7ee73488bbe1f78245e3045620abd7 on cucumber:main.
🤔 What's changed?
When a cucumber worker sends the
testCaseFinished
event back to the coordinator, do not mark the worker as "not in progress" until after all retries have finished being processed by the worker.⚡️ What's your motivation?
Howdy, I started getting feedback from other people that Cucumber wasn't respecting parallel rules when retrying long-running tests in certain situations. I was skeptical at first, but I was able to replicate it and find the source of the problem.
The following test minimally reproduces the issue:
For this example, I had retries set to 4 to really hammer the point home. I started realizing that the
NO PARALLEL
tests actually started running, even when theSHOULD FAIL
test was still doing a retry. This only occurs if the subsequent parallel scenarios finish and non-parallel tests need to run. Because thethis.inProgressWorkers
map is empty, it forces thenotInParallel
test to run while the retries are being attempted. This is causing flakiness in some of our tests.You can remove the changes from
src/runtime/parallel/coordinator.ts
and the test case provided in the PR will fail, demonstrating the issue and ensuring the issue is not encountered again.🏷️ What kind of change is this?
♻️ Anything particular you want feedback on?
The scenario and step definition look kinda ugly, so I'm very much open to ideas to make the code look a bit simpler. Filtering through the envelopes is always a bit difficult to do cleanly, especially without chaining higher order functions.
📋 Checklist:
This text was originally generated from a template, then edited by hand. You can modify the template here.