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

refactor(cli): move runTests() and runBenchmarks() to rust #18563

Merged
merged 14 commits into from
Apr 13, 2023

Conversation

nayeemrmn
Copy link
Collaborator

@nayeemrmn nayeemrmn commented Apr 2, 2023

Stores the test/bench functions in rust op state during registration. The functions are wrapped in JS first so that they return a directly convertible TestResult/BenchResult. Test steps are still mostly handled in JS since they are pretty much invoked by the user. Allows removing a bunch of infrastructure for communicating between JS and rust. Allows using rust utilities for things like shuffling tests (Vec::shuffle). We can progressively move op and resource sanitization to rust as well.

Fixes #17122.
Fixes #17312.

runtime/js/99_main.js Outdated Show resolved Hide resolved
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 like what this PR is changing. Seeing a 100 line count reduction is also welcome. @nayeemrmn could you check how long does it take to run tests now? While driving them from Rust is beneficial overall I have a slight worry that it might add additional overhead - calling hundreds of function from Rust will most likely affect the time it takes to run all the tests.

cli/ops/bench.rs Outdated Show resolved Hide resolved
cli/ops/testing.rs Outdated Show resolved Hide resolved
cli/worker.rs Outdated
Comment on lines 403 to 411
let earlier = SystemTime::now();
let promise = {
let scope = &mut self.worker.js_runtime.handle_scope();
let cb = function.open(scope);
let this = v8::undefined(scope).into();
let promise = cb.call(scope, this, &[]).unwrap();
v8::Global::new(scope, promise)
};
let result = self.worker.js_runtime.resolve_value(promise).await?;
Copy link
Member

Choose a reason for hiding this comment

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

I like this. This gives us a clear path to implementing test timeout, that will be able to handle blocking sync code. We can now spawn a separate "watchdog" thread that will call IsolateHandle::terminate_execution if the test doesn't complete before the deadline 👍

@nayeemrmn
Copy link
Collaborator Author

1.32.2: 2.987ms per test
This PR: 2.999ms per test (+0.4%)

const n = 5000;
let start: number;

addEventListener("load", () => {
  start = performance.now();
});

addEventListener("unload", () => {
  console.log((performance.now() - start) / n);
});

for (let i = 0; i < n; i++) {
  Deno.test(`${i}`, () => {
    // @ts-expect-error _
    console.assert(i == i.toString());
  });
}

// 12th Gen Intel(R) Core(TM) i9-12900K

cli/worker.rs Outdated Show resolved Hide resolved
@bartlomieju bartlomieju added this to the 1.33 milestone Apr 11, 2023
@bartlomieju
Copy link
Member

@nayeemrmn I just checked on v1.32.4 and the issues that this PR fixes are no longer occurring. Should we remove this linkage?

@nayeemrmn
Copy link
Collaborator Author

@nayeemrmn I just checked on v1.32.4 and the issues that this PR fixes are no longer occurring. Should we remove this linkage?

You can see it with

Deno.test("1", () => { Promise.reject() });
Deno.test("2", () => {});
Deno.test("3", () => {});
Deno.test("4", () => {});
// deno test --filter 1 temp.ts

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.

LGTM, besides fixing the issue at hand I think it's a step in the right direction to add timeouts to tests.

@dsherret do you wanna review before merging?

Copy link
Member

@dsherret dsherret left a comment

Choose a reason for hiding this comment

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

LGTM too. Thanks @nayeemrmn!

@bartlomieju bartlomieju merged commit 6e8618a into denoland:main Apr 13, 2023
@nayeemrmn nayeemrmn deleted the test-runner-to-rust branch April 13, 2023 17:45
levex pushed a commit that referenced this pull request Apr 18, 2023
Stores the test/bench functions in rust op state during registration.
The functions are wrapped in JS first so that they return a directly
convertible `TestResult`/`BenchResult`. Test steps are still mostly
handled in JS since they are pretty much invoked by the user. Allows
removing a bunch of infrastructure for communicating between JS and
rust. Allows using rust utilities for things like shuffling tests
(`Vec::shuffle`). We can progressively move op and resource sanitization
to rust as well.

Fixes #17122.
Fixes #17312.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants