-
Notifications
You must be signed in to change notification settings - Fork 3.2k
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
feat: experimental retries #27930
feat: experimental retries #27930
Conversation
…st-burnin chore: merge develop into test burnin
* feat: add the burnIn Configuration to the config package. Option currently is a no-op * chore: make burn in experimental * chore: set experimentalBurnIn to false by default
* feat: implement the experimental retries configuration options to pair with test burn in * [run ci]
…chore/merge-develop-test-burn-in
…rn-in chore: merge develop test burn in
…chore/merge-develop
chore: merge develop into feature/test-burn-in
…chore/merge-develop-burnin
chore: merge develop burnin
* add burnInTestAction capability * feat: add burn in capability for cloud * chore: fix snapshot for record_spec
* chore: format the retries/runner snapshot files to make diff easier * feat: implement experimentalRetries strategies 'detect-flake-and-pass-on-threshold' and 'detect-flake-but-always-fail'. This should not be a breaking change, though it does modify mocha and the test object even when the experiment is not configured. This is to exercise the system and make sure things still work as expected even when we go GA. Test updates will follow in following commits. * chore: update snapshots from system tests and cy-in-cy tests that now have the cypress test metadata property _cypressTestStatusInfo. tests have been added in the fail-with-[before|after]each specs to visually see the suite being skipped when developing. * chore: add cy-in-cy tests to verify reporter behavior for pass/fail tests, as well as new mocha snapshots to verify attempts. New tests were needed for this as the 'retries' option in testConfigOverrides currently is and will be invalid for experiment and will function as an override. tests run in the cy-in-cy tests are using globally configured experimentalRetries for the given tested project, which showcases the different behavior between attempts/retries and pass/fail status. * chore: add unit test like driver test to verify the test object in mocha is decorated/handled properly in calculateTestStatus * chore: add sanity system tests to verify console reporter output for experimental retries logic. Currently there is a bug in the reporter where the logged status doesnt wait for the aftereach to complete, which impacts the total exitCode and printed status. * fix: aftereach console output. make sure to fail the test in the appropriate spot in runner.ts and not prematurely, which in turn updates the snapshots for cy-in-cy as the fail event comes later." * chore: address comments from code review * fix: make sure hook failures print outer status + attempts when the error is the hook itself. * chore: improve types within calculateTestStatus inside mocha.ts
This reverts commit ae3df1a.
…feature/experimental-retries
f010aef
to
33591c1
Compare
33591c1
to
f866c5c
Compare
@@ -14,6 +14,7 @@ exports['module api and after:run results'] = ` | |||
"arch": "x64", | |||
"baseUrl": null, | |||
"blockHosts": null, | |||
"experimentalBurnIn": 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.
nit: Is it posssible to alphabetize this? I feel like Chris might have said it's not automatic. 😅
Regardless, approval given for this change as the codeowner of this file.
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.
I don't think we can but I cant remember. Either way this should not be there, so I am going to revert the commit it was introduced which was bb5046c
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.
reverted in 83842a6
… in experimentalflag" This reverts commit bb5046c.
Co-authored-by: Chris Breiding <chrisbreiding@users.noreply.github.com>
@@ -52,6 +52,22 @@ function setConfig (testConfig: ResolvedTestConfigOverride, config, localConfigO | |||
|
|||
try { | |||
testConfig.applied = overrideLevel | |||
// this is unique validation, not applied to the general cy config. |
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.
Should this logic be pushed up the validateOverridableAtRunTime
method to ensure the stack & messaging is consistent with the existing override error messaging (found here). That is the place that ensure these levels are appropriate for the config passed in.
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.
We can't declare invalid override levels for these keys because these are subkeys, and not defined as a primary config key. I can move the subkey detection to validateOverridableAtRunTime
, but this logic will be removed in the next few weeks when we add support for setting experimental retry config at test & suite level overrides.
// If experimentalRetries are configured, a experimentalStrategy is present, and the retries configured is a boolean | ||
// then we need to set the mocha '_retries' to 'maxRetries' present in the 'experimentalOptions' configuration. | ||
if (testRetries['experimentalStrategy'] && _.isBoolean(retriesAsNumberOrBoolean) && retriesAsNumberOrBoolean) { | ||
return testRetries['experimentalOptions'].maxRetries |
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.
If maxRetries are not set, does/should this fallback to the retriesAsNumberOrBoolean
value? Or should this condition be verifying maxRetries is set?
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 logic was previously reviewed (see PR description)
let shouldAttemptsContinue: boolean = true | ||
let outerTestStatus: 'passed' | 'failed' | undefined = undefined | ||
|
||
const passedTests = _.filter(test.prevAttempts, (o) => o.state === 'passed') |
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.
Could probably do this and the next line in one loop and it'd be a shade more efficient. However, guessing that prevAttempts is likely not ever that large so ultimately doesn't matter. Up to you.
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.
Looks good! Couple of very minor things.
Co-authored-by: Ryan Manuel <ryanm@cypress.io>
Co-authored-by: Ryan Manuel <ryanm@cypress.io>
Co-authored-by: Ryan Manuel <ryanm@cypress.io>
… experiments in Experimenets.vue
…tions to experiments in Experimenets.vue" This reverts commit b459aba.
@@ -103,7 +103,9 @@ export const validateConfig = (state: State, config: Record<string, any>, skipCo | |||
validateOverridableAtRunTime(config, isSuiteOverride, (validationResult) => { | |||
let errKey = 'config.cypress_config_api.read_only' | |||
|
|||
if (validationResult.supportedOverrideLevel === 'suite') { | |||
if (validationResult.supportedOverrideLevel === 'global_only') { |
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.
Can def fix this later, but read_only & global_only should be the same thing. can't be updated at test-time so must be set in the configuration file.
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.
at least that is how I intended it to be if it's not working that way 🙃
Released in This comment thread has been locked. If you are still experiencing this issue after upgrading to |
Description
This feature branch his based of the
feature/test-burn-in
branch with the following commits reverted:experimentalBurnIn
is not ready for release yet and we have decided to omit the config options from the release ofexperimentalRetries
burnInAction
as it isn't needed for experimentalRetries release.experimentalBurnIn
snapshot which was updated with the v13 releaseALL COMMITS ON THIS BRANCH HAVE BEEN PREVIOUSLY REVIEWED (with the exception of f010aef)!
Goals / Risk
The goal of this feature branch is to release
experimentalRetries
ahead ofexperimentalBurnIn
, which will allow users to try the new configuration options for themselves and report any bugs if found.The secondary goal of releasing
experimentalRetries
ahead of burn in is to get users to experiment with the experimental feature and identify bugs that might occur withexperimentalRetries
. However, the primary goal is to detect any issues that might have occurred adapting the existing GAretries
to the new retries engine implemented under the hood of the Cypress App.It's important to understand that in order to support
experimentalRetries
, we needed to patchmocha
in order to rerun passed test attempts. To accomplish this, we needed to change how retries fundamentally work, which means signficant changes to the retries mechanism. In short, this means that the logic within the newcalculateTestStatus
function backports the retries functionality into the new engine. An easy way to think about this would be:retries: 2
would map to a strategy ofdetect-flake-and-pass-on-threshold
with amaxRetries
of2
and apassesRequired
of1
In addition, the new field, called
_cypressTestStatusInfo
, which is used by both the cypress reporter in console and in the browser, is still used in GA implementation to interpret the test outerStatus, and will fallback to the status of the last attempt.It's important to note that there isn't currently anything signaling that the implementation changes are an issue, but we want to ship this out to a wider audience to reduce the scope of changes and have the impact be deterministic. If issues occur with the release of this feature, we can determine those issues with as little noise as possible, and if needed, rollback easily and assess what went wrong.
For more information on this, please see the following PRs that go into the implementation details more specifically:
The Feature
Experimental retries will allow users to leverage what we are calling a retry strategy. These strategies include
detect-flake-and-pass-on-threshold
detect-flake-but-always-fail
detect-flake-and-pass-on-threshold
is similar to how retries work today. Users will be able to specify a retry limit and specify a required number of passes needed in order for that to be marked as passed. Today, that limit is1
, but users can set the limit to whatever they'd like. This can be useful if a test is retrying and is known to be flaky, but the test engineers wishes to make sure that the test can at least pass a certain threshold in order to be marked as passed, which might help in confidence that the test is just flaky and the failure is not legitimate. It's important to note that if thepassesRequired
can not be acheived by the remaining retries of the test, the test will stop retrying and the test will be marked as a failure.The other,
detect-flake-but-always-fail
, will always mark a test that enters retries as failed, regardless of how many retried attempts pass. There is an option here, calledstopIfAnyPassed
, that will stop the test retries if any attempt passes. Without this option, a user might want to see what the probability that their test might pass (similar todetect-flake-and-pass-on-threshold
, but mark the test as failed as the test engineer might not want to mark any detected flaky test as a passed test.with
experimentalStrategy
andexperimentalOptions
enabledwith only
experimentalStrategy
enabledwith neither enabled
For reference, here are some configuration examples as to hopw the experimental options compare to what exists today, and how their outputs differ.
current implementation (GA)
retries: 2
Experimental options
Detect Flake and Pass on Threshold
Detect Flake but Always Fail
Detect Flake but Always Fail (
stopIfAnyPassed=true
)Steps to test
For how this experiment is tested, please see the description of #27826, which uses several testing strategies and mechanisms to guarantee functionality
How has the user experience changed?
Users will now be able to provide
experimentalStrategy
andexperimentalOptions
in their global config and watch the new form of retries take hold in their testPR Tasks
cypress-documentation
?type definitions
?