diff options
author | David Sherret <dsherret@users.noreply.github.com> | 2022-07-13 11:16:42 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-07-13 11:16:42 -0400 |
commit | 667812a297a538863695c20bf5d8228301298db5 (patch) | |
tree | d6f884ee4f0102831283f077ffd5d797a9eada5e /cli/tests | |
parent | 7470b2d2a765396a283bfd169b5fa9bacf0c01d0 (diff) |
fix(cli): synchronize async stdio/file reads and writes (#15092)
Fixes a regression where async writes and reads could get out of order.
Diffstat (limited to 'cli/tests')
-rw-r--r-- | cli/tests/integration/run_tests.rs | 10 | ||||
-rw-r--r-- | cli/tests/testdata/run/stdin_read_all.out | 1 | ||||
-rw-r--r-- | cli/tests/testdata/run/stdin_read_all.ts | 17 | ||||
-rw-r--r-- | cli/tests/testdata/run/stdout_write_all.out | 100 | ||||
-rw-r--r-- | cli/tests/testdata/run/stdout_write_all.ts | 13 | ||||
-rw-r--r-- | cli/tests/testdata/stdout_write_all.out | 1 | ||||
-rw-r--r-- | cli/tests/testdata/stdout_write_all.ts | 8 | ||||
-rw-r--r-- | cli/tests/unit/files_test.ts | 32 |
8 files changed, 171 insertions, 11 deletions
diff --git a/cli/tests/integration/run_tests.rs b/cli/tests/integration/run_tests.rs index e8bf3682a..b450d0d44 100644 --- a/cli/tests/integration/run_tests.rs +++ b/cli/tests/integration/run_tests.rs @@ -8,8 +8,14 @@ use test_util::TempDir; use util::assert_contains; itest!(stdout_write_all { - args: "run --quiet stdout_write_all.ts", - output: "stdout_write_all.out", + args: "run --quiet run/stdout_write_all.ts", + output: "run/stdout_write_all.out", +}); + +itest!(stdin_read_all { + args: "run --quiet run/stdin_read_all.ts", + output: "run/stdin_read_all.out", + input: Some("01234567890123456789012345678901234567890123456789"), }); itest!(_001_hello { diff --git a/cli/tests/testdata/run/stdin_read_all.out b/cli/tests/testdata/run/stdin_read_all.out new file mode 100644 index 000000000..2f0dfb71a --- /dev/null +++ b/cli/tests/testdata/run/stdin_read_all.out @@ -0,0 +1 @@ +01234567890123456789012345678901234567890123456789 diff --git a/cli/tests/testdata/run/stdin_read_all.ts b/cli/tests/testdata/run/stdin_read_all.ts new file mode 100644 index 000000000..d683a2bf6 --- /dev/null +++ b/cli/tests/testdata/run/stdin_read_all.ts @@ -0,0 +1,17 @@ +const encoder = new TextEncoder(); + +const pending = []; + +// do this a bunch of times to ensure it doesn't race +// and everything happens in order +for (let i = 0; i < 50; i++) { + const buf = new Uint8Array(1); + pending.push( + Deno.stdin.read(buf).then(() => { + return Deno.stdout.write(buf); + }), + ); +} + +await Promise.all(pending); +await Deno.stdout.write(encoder.encode("\n")); diff --git a/cli/tests/testdata/run/stdout_write_all.out b/cli/tests/testdata/run/stdout_write_all.out new file mode 100644 index 000000000..d0e667fd4 --- /dev/null +++ b/cli/tests/testdata/run/stdout_write_all.out @@ -0,0 +1,100 @@ +Hello, world! 0 +Hello, world! 1 +Hello, world! 2 +Hello, world! 3 +Hello, world! 4 +Hello, world! 5 +Hello, world! 6 +Hello, world! 7 +Hello, world! 8 +Hello, world! 9 +Hello, world! 10 +Hello, world! 11 +Hello, world! 12 +Hello, world! 13 +Hello, world! 14 +Hello, world! 15 +Hello, world! 16 +Hello, world! 17 +Hello, world! 18 +Hello, world! 19 +Hello, world! 20 +Hello, world! 21 +Hello, world! 22 +Hello, world! 23 +Hello, world! 24 +Hello, world! 25 +Hello, world! 26 +Hello, world! 27 +Hello, world! 28 +Hello, world! 29 +Hello, world! 30 +Hello, world! 31 +Hello, world! 32 +Hello, world! 33 +Hello, world! 34 +Hello, world! 35 +Hello, world! 36 +Hello, world! 37 +Hello, world! 38 +Hello, world! 39 +Hello, world! 40 +Hello, world! 41 +Hello, world! 42 +Hello, world! 43 +Hello, world! 44 +Hello, world! 45 +Hello, world! 46 +Hello, world! 47 +Hello, world! 48 +Hello, world! 49 +Hello, world! 50 +Hello, world! 51 +Hello, world! 52 +Hello, world! 53 +Hello, world! 54 +Hello, world! 55 +Hello, world! 56 +Hello, world! 57 +Hello, world! 58 +Hello, world! 59 +Hello, world! 60 +Hello, world! 61 +Hello, world! 62 +Hello, world! 63 +Hello, world! 64 +Hello, world! 65 +Hello, world! 66 +Hello, world! 67 +Hello, world! 68 +Hello, world! 69 +Hello, world! 70 +Hello, world! 71 +Hello, world! 72 +Hello, world! 73 +Hello, world! 74 +Hello, world! 75 +Hello, world! 76 +Hello, world! 77 +Hello, world! 78 +Hello, world! 79 +Hello, world! 80 +Hello, world! 81 +Hello, world! 82 +Hello, world! 83 +Hello, world! 84 +Hello, world! 85 +Hello, world! 86 +Hello, world! 87 +Hello, world! 88 +Hello, world! 89 +Hello, world! 90 +Hello, world! 91 +Hello, world! 92 +Hello, world! 93 +Hello, world! 94 +Hello, world! 95 +Hello, world! 96 +Hello, world! 97 +Hello, world! 98 +Hello, world! 99 diff --git a/cli/tests/testdata/run/stdout_write_all.ts b/cli/tests/testdata/run/stdout_write_all.ts new file mode 100644 index 000000000..cfb2981e4 --- /dev/null +++ b/cli/tests/testdata/run/stdout_write_all.ts @@ -0,0 +1,13 @@ +const encoder = new TextEncoder(); + +const pending = []; + +// do this a bunch of times to ensure it doesn't race +// and everything happens in order +for (let i = 0; i < 100; i++) { + pending.push(Deno.stdout.write(encoder.encode("Hello, "))); + pending.push(Deno.stdout.write(encoder.encode(`world! ${i}`))); + pending.push(Deno.stdout.write(encoder.encode("\n"))); +} + +await Promise.all(pending); diff --git a/cli/tests/testdata/stdout_write_all.out b/cli/tests/testdata/stdout_write_all.out deleted file mode 100644 index af5626b4a..000000000 --- a/cli/tests/testdata/stdout_write_all.out +++ /dev/null @@ -1 +0,0 @@ -Hello, world! diff --git a/cli/tests/testdata/stdout_write_all.ts b/cli/tests/testdata/stdout_write_all.ts deleted file mode 100644 index 623bd8f53..000000000 --- a/cli/tests/testdata/stdout_write_all.ts +++ /dev/null @@ -1,8 +0,0 @@ -const encoder = new TextEncoder(); -const pending = [ - Deno.stdout.write(encoder.encode("Hello, ")), - Deno.stdout.write(encoder.encode("world!")), -]; - -await Promise.all(pending); -await Deno.stdout.write(encoder.encode("\n")); diff --git a/cli/tests/unit/files_test.ts b/cli/tests/unit/files_test.ts index d15f1f538..5fb590d72 100644 --- a/cli/tests/unit/files_test.ts +++ b/cli/tests/unit/files_test.ts @@ -263,6 +263,38 @@ Deno.test( }, ); +Deno.test( + { permissions: { write: true } }, + async function writeSyncWhileAsyncFails() { + const tempDir = await Deno.makeTempDir(); + try { + const filePath = tempDir + "/file.txt"; + const file = await Deno.open(filePath, { create: true, write: true }); + const rid = file.rid; + try { + // set a file lock so the async write will be held up + await Deno.flock(rid, true); + let p: Promise<number> | undefined; + try { + p = Deno.write(rid, new TextEncoder().encode("test")); + assertThrows( + () => Deno.writeSync(rid, new TextEncoder().encode("test")), + Error, + "Resource is unavailable because it is in use by a promise", + ); + } finally { + await Deno.funlock(rid); + } + await p; + } finally { + file.close(); + } + } finally { + Deno.removeSync(tempDir, { recursive: true }); + } + }, +); + Deno.test(async function openOptions() { const filename = "cli/tests/testdata/fixture.json"; await assertRejects( |