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(timers): Refactor timers to use one async op per timer #12862

Merged
merged 16 commits into from
Dec 7, 2021
6 changes: 6 additions & 0 deletions cli/tests/integration/test_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,12 @@ itest!(ops_sanitizer_timeout_failure {
output: "test/ops_sanitizer_timeout_failure.out",
});

itest!(ops_sanitizer_multiple_timeout_tests {
args: "test test/ops_sanitizer_multiple_timeout_tests.ts",
exit_code: 1,
output: "test/ops_sanitizer_multiple_timeout_tests.out",
});

itest!(ops_sanitizer_nexttick {
args: "test test/ops_sanitizer_nexttick.ts",
output: "test/ops_sanitizer_nexttick.out",
Expand Down
57 changes: 57 additions & 0 deletions cli/tests/testdata/test/ops_sanitizer_multiple_timeout_tests.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
Check [WILDCARD]/testdata/test/ops_sanitizer_multiple_timeout_tests.ts
running 2 tests from [WILDCARD]/testdata/test/ops_sanitizer_multiple_timeout_tests.ts
test test 1 ... FAILED ([WILDCARD])
test test 2 ... FAILED ([WILDCARD])

failures:

test 1
AssertionError: Test case is leaking async ops.
Before:
- dispatched: 0
- completed: 0
After:
- dispatched: [WILDCARD]
- completed: [WILDCARD]
Ops:
op_sleep:
Before:
- dispatched: 0
- completed: 0
After:
- dispatched: [WILDCARD]
- completed: [WILDCARD]

Make sure to await all promises returned from Deno APIs before
finishing test case.
at [WILDCARD]

test 2
AssertionError: Test case is leaking async ops.
Before:
- dispatched: [WILDCARD]
- completed: [WILDCARD]
After:
- dispatched: [WILDCARD]
- completed: [WILDCARD]
Ops:
op_sleep:
Before:
- dispatched: [WILDCARD]
- completed: [WILDCARD]
After:
- dispatched: [WILDCARD]
- completed: [WILDCARD]

Make sure to await all promises returned from Deno APIs before
finishing test case.
at [WILDCARD]

failures:

test 1
test 2

test result: FAILED. 0 passed; 2 failed; 0 ignored; 0 measured; 0 filtered out ([WILDCARD])

error: Test failed
10 changes: 10 additions & 0 deletions cli/tests/testdata/test/ops_sanitizer_multiple_timeout_tests.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// https://github.com/denoland/deno/issues/8965

function test() {
setTimeout(() => {}, 10000);
setTimeout(() => {}, 10001);
}

Deno.test("test 1", test);

Deno.test("test 2", test);
10 changes: 5 additions & 5 deletions cli/tests/testdata/test/ops_sanitizer_unstable.out
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,16 @@ Before:
- dispatched: 1
- completed: 1
After:
- dispatched: 3
- completed: 2
- dispatched: [WILDCARD]
- completed: [WILDCARD]
Ops:
op_global_timer:
op_sleep:
Before:
- dispatched: 1
- completed: 1
After:
- dispatched: 3
- completed: 2
- dispatched: [WILDCARD]
- completed: [WILDCARD]

Make sure to await all promises returned from Deno APIs before
finishing test case.
Expand Down
2 changes: 1 addition & 1 deletion cli/tests/testdata/worker_drop_handle_race.js.out
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ error: Uncaught (in worker "") Error
throw new Error();
^
at [WILDCARD]/workers/drop_handle_race.js:2:9
at fire (deno:ext/timers/[WILDCARD])
at Object.action (deno:ext/timers/[WILDCARD])
at handleTimerMacrotask (deno:ext/timers/[WILDCARD])
error: Uncaught (in promise) Error: Unhandled error event in child worker.
at Worker.#pollControl (deno:runtime/js/11_workers.js:[WILDCARD])
74 changes: 74 additions & 0 deletions cli/tests/unit/timers_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,60 @@ Deno.test(function intervalCancelInvalidSilentFail() {
clearInterval(2147483647);
});

Deno.test(async function callbackTakesLongerThanInterval() {
const promise = deferred();

let timeEndOfFirstCallback: number | undefined;
const interval = setInterval(() => {
if (timeEndOfFirstCallback === undefined) {
// First callback
Deno.sleepSync(300);
timeEndOfFirstCallback = Date.now();
} else {
// Second callback
assert(Date.now() - 100 >= timeEndOfFirstCallback);
clearInterval(interval);
promise.resolve();
}
}, 100);

await promise;
});

// https://github.com/denoland/deno/issues/11398
Deno.test(async function clearTimeoutAfterNextTimerIsDue1() {
const promise = deferred();

setTimeout(() => {
promise.resolve();
}, 300);

const interval = setInterval(() => {
Deno.sleepSync(400);
// Both the interval and the timeout's due times are now in the past.
clearTimeout(interval);
andreubotella marked this conversation as resolved.
Show resolved Hide resolved
}, 100);

await promise;
});

// https://github.com/denoland/deno/issues/11398
Deno.test(async function clearTimeoutAfterNextTimerIsDue2() {
const promise = deferred();

const timeout1 = setTimeout(() => {}, 100);
andreubotella marked this conversation as resolved.
Show resolved Hide resolved

setTimeout(() => {
promise.resolve();
}, 200);

Deno.sleepSync(300);
// Both of the timeouts' due times are now in the past.
clearTimeout(timeout1);

await promise;
});

Deno.test(async function fireCallbackImmediatelyWhenDelayOverMaxValue() {
let count = 0;
setTimeout(() => {
Expand Down Expand Up @@ -346,6 +400,26 @@ Deno.test(async function timerMaxCpuBug() {
assert(opsDispatched_ - opsDispatched < 10);
});

Deno.test(async function timerOrdering() {
const array: number[] = [];
setTimeout(() => {
array.push(1);
setTimeout(() => array.push(4));
}, 0);
setTimeout(() => {
array.push(2);
setTimeout(() => array.push(5));
}, 0);
setTimeout(() => {
array.push(3);
setTimeout(() => array.push(6));
}, 0);

await delay(10);

assertEquals(array, [1, 2, 3, 4, 5, 6]);
});

Deno.test(async function timerBasicMicrotaskOrdering() {
let s = "";
let count = 0;
Expand Down
Loading