Skip to content
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

introduce flaky lines, remove unnecessary functionality #1

Merged
merged 7 commits into from
Feb 17, 2024
Merged

Conversation

nikitaevg
Copy link
Collaborator

@nikitaevg nikitaevg commented Feb 4, 2024

We introduce flaky indicators that help distinguish flakes from real failures. We also remove all functionality that is not necessary for our project. And we also add test coverage for the action.

@nikitaevg nikitaevg changed the title test introduce flaky lines, remove unnecessary functionality Feb 4, 2024
Copy link
Member

@seanlip seanlip left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @nikitaevg, sorry for the review delay! This looks good on the whole IMO :)

I just had a few comments -- haven't had time to make changes directly yet, but will try to make a PR later in the week if possible, so I figured I'd just leave the comments here for reference at least.

README.md Outdated
### `exit_error`

The final error returned by the command
**Optional** Specify which lines in output indicate that the failure is flaky. Note - if not specified, all failures are considered as real failures.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do these have to be full lines or just substrings?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just substrings, updated the description

@@ -0,0 +1,128 @@
import 'jest';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add copyright notice.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

src/index.ts Outdated
// mimics native continue-on-error that is not supported in composite actions
process.exit(inputs.continue_on_error ? 0 : exitCode);
error(`Failed test with exception ${err.message}`);
process.exit(-1);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't the exit code be 1?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, thanks!

});

it('detects real errors after flakes', async () => {
// The second file is used to indicate the flake.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am getting a bit confused when reading these tests. In some cases the flaky string seems to be inside the temp files and in others it seems to be within the command / printed to the terminal. So I don't entirely understand what is going on here...

If the point of the second file is to print stuff to the terminal output then why not just echo it like we do with everything else?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In some cases the flaky string seems to be inside the temp files and in others it seems to be within the command / printed to the terminal.

It's always printed to the terminal, see this tests cats the file contents.

If the point of the second file is to print stuff to the terminal output then why not just echo it like we do with everything else?

We need different outputs in the first and second attempts - the first attempt is a flake, the second is not. Adjusted the comments a bit.

expect(data).toBe(content);
}

describe('retry', () => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be worth adding a test to distinguish matching by substring vs matching by line

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed this test so it shows that we look for substrings

src/action.ts Outdated

if (code === null) {
error('exit code cannot be null');
exitCode = -1;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be 1?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, you're right


function hasFlakyOutput(flaky_test_output_lines: string[], output: string[]): boolean {
const flakyIndicator = flaky_test_output_lines.find((flakyLine) =>
output.some((outputLine) => outputLine.includes(flakyLine))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does seem like this is checking for substrings, maybe we should be calling the argument flaky_test_indicators or flaky_test_indicator_substrings instead (or something that doesn't have "lines" in the name).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed to substrings_indicating_flaky_execution


if (!hasFlakyOutput(inputs.flakyTestOutputLines, output)) {
return exitCode;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe add log after this to say it failed flakily and that we're restarting.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't mind, but note that we already will have
"Output contains flaky line: ${flakyIndicator}" log + "Starting attempt #${attempt}". IMO it's enough, but I can add if you want

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah thanks, I missed that, sorry -- but I think the call to info() is in the wrong place. Can we move it to this function?

Based on its name, hasFlakyOutput() is something that would be expected to just return a boolean and shouldn't have any meaningful side effects, whereas we do want printing the log to be a deliberate action that we take in the execution.

I also suggest adding "Restarting test" or similar to that message since it connects the restart with the error.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on its name, hasFlakyOutput() is something that would be expected to just return a boolean and shouldn't have any meaningful side effects, whereas we do want printing the log to be a deliberate action that we take in the execution.

I agree with that, but I think it's very helpful to output which flake indicator was found, so we need to output something in the hasFlakyOutput method.

I moved logging to the calling side, and also left the log of what indicator was found.

@seanlip seanlip assigned nikitaevg and unassigned seanlip Feb 13, 2024
Copy link
Collaborator Author

@nikitaevg nikitaevg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@seanlip PTAL

README.md Outdated
### `exit_error`

The final error returned by the command
**Optional** Specify which lines in output indicate that the failure is flaky. Note - if not specified, all failures are considered as real failures.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just substrings, updated the description

expect(data).toBe(content);
}

describe('retry', () => {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed this test so it shows that we look for substrings

});

it('detects real errors after flakes', async () => {
// The second file is used to indicate the flake.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In some cases the flaky string seems to be inside the temp files and in others it seems to be within the command / printed to the terminal.

It's always printed to the terminal, see this tests cats the file contents.

If the point of the second file is to print stuff to the terminal output then why not just echo it like we do with everything else?

We need different outputs in the first and second attempts - the first attempt is a flake, the second is not. Adjusted the comments a bit.

src/action.ts Outdated

if (code === null) {
error('exit code cannot be null');
exitCode = -1;
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, you're right


function hasFlakyOutput(flaky_test_output_lines: string[], output: string[]): boolean {
const flakyIndicator = flaky_test_output_lines.find((flakyLine) =>
output.some((outputLine) => outputLine.includes(flakyLine))
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed to substrings_indicating_flaky_execution


if (!hasFlakyOutput(inputs.flakyTestOutputLines, output)) {
return exitCode;
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't mind, but note that we already will have
"Output contains flaky line: ${flakyIndicator}" log + "Starting attempt #${attempt}". IMO it's enough, but I can add if you want

src/index.ts Outdated
// mimics native continue-on-error that is not supported in composite actions
process.exit(inputs.continue_on_error ? 0 : exitCode);
error(`Failed test with exception ${err.message}`);
process.exit(-1);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, thanks!

@@ -0,0 +1,128 @@
import 'jest';
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@nikitaevg nikitaevg assigned seanlip and unassigned nikitaevg Feb 16, 2024
Copy link
Member

@seanlip seanlip left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @nikitaevg -- just one more thing and then I think it's good to go!

Also please update the first comment of this PR thread with a description of changes, thanks.


if (!hasFlakyOutput(inputs.flakyTestOutputLines, output)) {
return exitCode;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah thanks, I missed that, sorry -- but I think the call to info() is in the wrong place. Can we move it to this function?

Based on its name, hasFlakyOutput() is something that would be expected to just return a boolean and shouldn't have any meaningful side effects, whereas we do want printing the log to be a deliberate action that we take in the execution.

I also suggest adding "Restarting test" or similar to that message since it connects the restart with the error.

@seanlip seanlip assigned nikitaevg and unassigned seanlip Feb 17, 2024
@nikitaevg
Copy link
Collaborator Author

@seanlip PTAL!

@nikitaevg nikitaevg assigned seanlip and unassigned nikitaevg Feb 17, 2024
Copy link
Member

@seanlip seanlip left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @nikitaevg -- this looks good, thanks! But I want to get the tests to run. Do you know how to add tests to the CI so that we can ensure this (and subsequent changes don't break anything)?

I'll try closing and reopening this PR to see if that works...

@seanlip seanlip closed this Feb 17, 2024
@seanlip seanlip reopened this Feb 17, 2024
@seanlip
Copy link
Member

seanlip commented Feb 17, 2024

Ok, hm. Could you go to .github/workflows/ci_cd.yml and clean up the unnecessary stuff? You can view runs here: https://github.com/oppia/retry/actions

@seanlip seanlip assigned nikitaevg and unassigned seanlip Feb 17, 2024
@nikitaevg
Copy link
Collaborator Author

Ok, hm. Could you go to .github/workflows/ci_cd.yml and clean up the unnecessary stuff? You can view runs here: https://github.com/oppia/retry/actions

Ohhh, I didn't notice that file. It has so many tests, but I think the tests I provided are good enough.

So I want to leave ci_unit only and remove other jobs, would that be ok for you?

Also, maybe I'll do it in a separate PR? This PR becomes too big.

@nikitaevg
Copy link
Collaborator Author

@seanlip PTAL

@nikitaevg nikitaevg assigned seanlip and unassigned nikitaevg Feb 17, 2024
@seanlip
Copy link
Member

seanlip commented Feb 17, 2024

I suggest keeping ci_unit but dropping the codecov part. I defer to your judgment on integration -- but in general I suggest keeping tests that align with the remaining functionality (ok to write new ones in a separate PR).

Agree in general with not wanting PRs to be too big, but I think we do need some tests to run on presubmit before we can merge this. So I suggest fixing that in this PR since this is where you also modify the behaviour (I thought of doing them in a separate PR that gets merged before this one but I think that wouldn't work).

@seanlip seanlip assigned nikitaevg and unassigned seanlip Feb 17, 2024
@nikitaevg
Copy link
Collaborator Author

@seanlip Let me remove all integration tests in this PR and add them in the following one, sounds good? I fixed the github actions, see the latest commit.

@nikitaevg nikitaevg assigned seanlip and unassigned nikitaevg Feb 17, 2024
Copy link
Member

@seanlip seanlip left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup seems good. Thanks!

@seanlip seanlip merged commit a9fb265 into master Feb 17, 2024
1 check passed
@seanlip seanlip deleted the develop branch February 17, 2024 19:06
@seanlip seanlip mentioned this pull request Feb 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants