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

feat(test): print pending tests on sigint #18246

Merged
merged 27 commits into from
Mar 25, 2023

Conversation

nayeemrmn
Copy link
Collaborator

@nayeemrmn nayeemrmn commented Mar 17, 2023

Moves test validation/sanitization error formatting to Rust. Moves the
buffer system for reporting concurrent test steps to Rust.

Output is improved:

  • Sanitization and other non-user-thrown errors no longer have loud JS
    error stacks.
  • Test step failures are now included in the summary.
  • Test failures that defer to other test failures (e.g.
    error: 1 test step failed) are no longer included in the summary.
    Summaries only contain meaningful errors.
  • Fix quirks and inconsistencies caused by the old buffer system.

Closes #17788.

setInterval(() => {}, 10000);

Deno.test({
  name: "test",
  sanitizeOps: false,
  sanitizeExit: false,
  sanitizeResources: false,
  async fn(t) {
    await t.step("step 1", async (t) => {
      await t.step("step 2", async () => {
        await new Promise(() => {});
      });
    });
  },
});

image

The vast majority of this PR is the prerequisite of refactoring the concurrent-test-step buffer system to Rust. The buffering logic should be easier to reason about. Instead of changing output streaming behaviour based on sanitizers, it just buffers any test result whose output doesn't belong in the current scope and flushes it when a test on the same scope has finished reporting.

cli/js/40_testing.js Show resolved Hide resolved
@@ -9,9 +9,6 @@ top level missing await ... FAILED ([WILDCARD])
inner missing await ...
step ...
inner ... pending ([WILDCARD])
error: Error: Parent scope completed before test step finished execution. Ensure all steps are awaited (ex. `await t.step(...)`).
at [WILDCARD]
at async TestContext.step [WILDCARD]
Copy link
Member

Choose a reason for hiding this comment

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

Why was this removed?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This is a redundant error, the parent's error combined with ... pending represents this. It appears inconsistently as well. For example, turning sanitizers on for inner missing await strangely gets rid of it. And it's only reported if the root test scope happens to be open still. Combine that with it creating the need for the error value contained in TestStepResult::Pending(), no reason to have it.

Copy link
Member

Choose a reason for hiding this comment

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

pending isn't very instructive for users though. Can we output an instructive message still?

It appears inconsistently as well.

We should fix that bug in that case.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Can we output an instructive message still?

Yes, when a pending test step result is printed in rust we can follow that up with any message along with that step's location.

I also wanted to follow up with a change that moved all validation errors to structured error variants which are formatted in Rust instead. We can print a nicely formatted location next to them rather than those loud JS error stacks. It's probably better to do it all at once in this PR.

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
image

@bartlomieju bartlomieju self-requested a review March 19, 2023 00:25
Copy link
Member

@bartlomieju bartlomieju left a comment

Choose a reason for hiding this comment

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

I really like how a lot of the logic has been moved from JS to Rust. I have one concern related to signal though - once we install listener for ctrl+c then even if it's dropped the process won't exit anymore on SIGINT.

Is there a chance this can happen with this change? Also how will it interact if the code in tests registers a signal listener for SIGINT event?

@nayeemrmn
Copy link
Collaborator Author

once we install listener for ctrl+c then even if it's dropped the process won't exit anymore on SIGINT.

Is there a chance this can happen with this change?

The only consequence is it's no longer possible to interrupt the process in the window between the test runner finishing up and the process normally ending after that. Or the transition window for deno test --watch.

If there was a real reason to overcome this upstream limitation, it's the effect on Deno.removeSignalHandler("SIGINT") and having compatible behaviour for Node's process.on("SIGINT") IMO.

Also how will it interact if the code in tests registers a signal listener for SIGINT event?

The user's handler doesn't run because the process exits in our handler. I think that's fine, they should use subprocesses / integration tests for things like that.

@bartlomieju
Copy link
Member

Thanks for detailed explanation, totally makes sense.

If there was a real reason to overcome this upstream limitation, it's the effect on Deno.removeSignalHandler("SIGINT") and having compatible behaviour for Node's process.on("SIGINT") IMO.

Agreed, we should have one "custom" listener that just switches its actions once Deno.removeSignalHandler("SIGINT") is called.

Copy link
Collaborator

@aapoalas aapoalas left a comment

Choose a reason for hiding this comment

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

LGTM. Left one absolutely useless nitpick about list of strings formatting.

question: Does the color crate automatically handle NO_COLOR flag, or should that be manually added to the added uses here? Current test reporter does respect the flag.

cli/tools/test.rs Show resolved Hide resolved
@nayeemrmn
Copy link
Collaborator Author

question: Does the color crate automatically handle NO_COLOR flag, or should that be manually added to the added uses here? Current test reporter does respect the flag.

It's a local utility, yeah

deno/runtime/colors.rs

Lines 43 to 45 in e4c60bc

if !use_color() {
return String::from(s.as_ref());
}

@aapoalas
Copy link
Collaborator

@nayeemrmn Can we merge this?

@nayeemrmn
Copy link
Collaborator Author

Yeah no more changes to make

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.

Disabling test sanitizers causes test steps to not be logged in time.
4 participants