diff options
author | Leo Kettmeir <crowlkats@toaxl.com> | 2022-05-18 22:00:11 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-05-18 22:00:11 +0200 |
commit | 4e1ca1d1787f25ab9f0a72ccf9d8028f70b3a7ed (patch) | |
tree | 2d0062ec1dd864c7ed98301119ac5f1c133f844a | |
parent | 5ad8919d642b646caa3328930dd1a3f290bc587e (diff) |
refactor: use spawn API across codebase (#14414)
-rw-r--r-- | .github/workflows/ci.yml | 2 | ||||
-rw-r--r-- | cli/tests/integration/run_tests.rs | 14 | ||||
-rw-r--r-- | cli/tests/testdata/045_proxy_test.ts | 44 | ||||
-rw-r--r-- | cli/tests/testdata/089_run_allow_list.ts | 11 | ||||
-rw-r--r-- | cli/tests/testdata/lock_write_fetch.ts | 24 | ||||
-rw-r--r-- | cli/tests/testdata/no_prompt.ts | 5 | ||||
-rw-r--r-- | cli/tests/testdata/permission_test.ts | 9 | ||||
-rw-r--r-- | cli/tests/unit/chown_test.ts | 20 | ||||
-rw-r--r-- | cli/tests/unit/flock_test.ts | 33 | ||||
-rw-r--r-- | cli/tests/unit/http_test.ts | 148 | ||||
-rw-r--r-- | cli/tests/unit/os_test.ts | 20 | ||||
-rw-r--r-- | cli/tests/unit/remove_test.ts | 15 | ||||
-rw-r--r-- | cli/tests/unit/signal_test.ts | 9 | ||||
-rw-r--r-- | cli/tests/unit/test_util.ts | 10 | ||||
-rw-r--r-- | cli/tests/unit/tls_test.ts | 16 | ||||
-rw-r--r-- | cli/tests/unit/tty_color_test.ts | 8 | ||||
-rw-r--r-- | runtime/js/40_spawn.js | 3 | ||||
-rwxr-xr-x | tools/flamebench.js | 25 | ||||
-rwxr-xr-x | tools/format.js | 22 | ||||
-rwxr-xr-x | tools/lint.js | 32 | ||||
-rw-r--r-- | tools/util.js | 19 | ||||
-rwxr-xr-x | tools/wgpu_sync.js | 14 | ||||
-rwxr-xr-x | tools/wpt.ts | 7 | ||||
-rw-r--r-- | tools/wpt/runner.ts | 30 | ||||
-rw-r--r-- | tools/wpt/utils.ts | 53 |
25 files changed, 266 insertions, 327 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1b6e9ad22..e1a421f6a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -90,7 +90,7 @@ jobs: if: matrix.job == 'lint' uses: denoland/setup-deno@v1 with: - deno-version: v1.19.3 + deno-version: v1.x - name: Install Python uses: actions/setup-python@v1 diff --git a/cli/tests/integration/run_tests.rs b/cli/tests/integration/run_tests.rs index c1ed59f14..a9e7d93cc 100644 --- a/cli/tests/integration/run_tests.rs +++ b/cli/tests/integration/run_tests.rs @@ -182,8 +182,9 @@ itest!(_044_bad_resource { exit_code: 1, }); +// TODO(bartlomieju): remove --unstable once Deno.spawn is stabilized itest!(_045_proxy { - args: "run -L debug --allow-net --allow-env --allow-run --allow-read --reload --quiet 045_proxy_test.ts", + args: "run -L debug --unstable --allow-net --allow-env --allow-run --allow-read --reload --quiet 045_proxy_test.ts", output: "045_proxy_test.ts.out", http_server: true, }); @@ -509,8 +510,9 @@ itest!(_088_dynamic_import_already_evaluating { output: "088_dynamic_import_already_evaluating.ts.out", }); +// TODO(bartlomieju): remove --unstable once Deno.spawn is stabilized itest!(_089_run_allow_list { - args: "run --allow-run=curl 089_run_allow_list.ts", + args: "run --unstable --allow-run=curl 089_run_allow_list.ts", output: "089_run_allow_list.ts.out", }); @@ -588,9 +590,10 @@ itest!(lock_write_requires_lock { exit_code: 1, }); +// TODO(bartlomieju): remove --unstable once Deno.spawn is stabilized itest!(lock_write_fetch { args: - "run --quiet --allow-read --allow-write --allow-env --allow-run lock_write_fetch.ts", + "run --quiet --allow-read --allow-write --allow-env --allow-run --unstable lock_write_fetch.ts", output: "lock_write_fetch.ts.out", http_server: true, exit_code: 0, @@ -1861,12 +1864,14 @@ fn dont_cache_on_check_fail() { mod permissions { use test_util as util; + // TODO(bartlomieju): remove --unstable once Deno.spawn is stabilized #[test] fn with_allow() { for permission in &util::PERMISSION_VARIANTS { let status = util::deno_cmd() .current_dir(&util::testdata_path()) .arg("run") + .arg("--unstable") .arg(format!("--allow-{0}", permission)) .arg("permission_test.ts") .arg(format!("{0}Required", permission)) @@ -1878,12 +1883,13 @@ mod permissions { } } + // TODO(bartlomieju): remove --unstable once Deno.spawn is stabilized #[test] fn without_allow() { for permission in &util::PERMISSION_VARIANTS { let (_, err) = util::run_and_collect_output( false, - &format!("run permission_test.ts {0}Required", permission), + &format!("run --unstable permission_test.ts {0}Required", permission), None, None, false, diff --git a/cli/tests/testdata/045_proxy_test.ts b/cli/tests/testdata/045_proxy_test.ts index d6edf2be9..620e23e14 100644 --- a/cli/tests/testdata/045_proxy_test.ts +++ b/cli/tests/testdata/045_proxy_test.ts @@ -31,93 +31,76 @@ async function handler(req: Request): Promise<Response> { } async function testFetch() { - const c = Deno.run({ - cmd: [ - Deno.execPath(), + const { status } = await Deno.spawn(Deno.execPath(), { + args: [ "run", "--quiet", "--reload", "--allow-net", "045_proxy_client.ts", ], - stdout: "piped", env: { HTTP_PROXY: `http://${addr}`, }, }); - const status = await c.status(); assertEquals(status.code, 0); - c.close(); } async function testModuleDownload() { - const http = Deno.run({ - cmd: [ - Deno.execPath(), + const { status } = await Deno.spawn(Deno.execPath(), { + args: [ "cache", "--reload", "--quiet", "http://localhost:4545/045_mod.ts", ], - stdout: "piped", env: { HTTP_PROXY: `http://${addr}`, }, }); - const httpStatus = await http.status(); - assertEquals(httpStatus.code, 0); - http.close(); + assertEquals(status.code, 0); } async function testFetchNoProxy() { - const c = Deno.run({ - cmd: [ - Deno.execPath(), + const { status } = await Deno.spawn(Deno.execPath(), { + args: [ "run", "--quiet", "--reload", "--allow-net", "045_proxy_client.ts", ], - stdout: "piped", env: { HTTP_PROXY: "http://not.exising.proxy.server", NO_PROXY: "localhost", }, }); - const status = await c.status(); assertEquals(status.code, 0); - c.close(); } async function testModuleDownloadNoProxy() { - const http = Deno.run({ - cmd: [ - Deno.execPath(), + const { status } = await Deno.spawn(Deno.execPath(), { + args: [ "cache", "--reload", "--quiet", "http://localhost:4545/045_mod.ts", ], - stdout: "piped", env: { HTTP_PROXY: "http://not.exising.proxy.server", NO_PROXY: "localhost", }, }); - const httpStatus = await http.status(); - assertEquals(httpStatus.code, 0); - http.close(); + assertEquals(status.code, 0); } async function testFetchProgrammaticProxy() { - const c = Deno.run({ - cmd: [ - Deno.execPath(), + const { status } = await Deno.spawn(Deno.execPath(), { + args: [ "run", "--quiet", "--reload", @@ -125,11 +108,8 @@ async function testFetchProgrammaticProxy() { "--unstable", "045_programmatic_proxy_client.ts", ], - stdout: "piped", }); - const status = await c.status(); assertEquals(status.code, 0); - c.close(); } proxyServer(); diff --git a/cli/tests/testdata/089_run_allow_list.ts b/cli/tests/testdata/089_run_allow_list.ts index defb3196f..0eb79dcc2 100644 --- a/cli/tests/testdata/089_run_allow_list.ts +++ b/cli/tests/testdata/089_run_allow_list.ts @@ -1,13 +1,12 @@ try { - Deno.run({ - cmd: ["ls"], - }); + await Deno.spawn("ls"); } catch (e) { console.log(e); } -const proc = Deno.run({ - cmd: ["curl", "--help"], +const { status } = await Deno.spawn("curl", { + args: ["--help"], stdout: "null", + stderr: "inherit", }); -console.log((await proc.status()).success); +console.log(status.success); diff --git a/cli/tests/testdata/lock_write_fetch.ts b/cli/tests/testdata/lock_write_fetch.ts index b6ecf4747..7be6af84a 100644 --- a/cli/tests/testdata/lock_write_fetch.ts +++ b/cli/tests/testdata/lock_write_fetch.ts @@ -4,11 +4,10 @@ try { // pass } -const fetchProc = Deno.run({ +const fetchProc = await Deno.spawn(Deno.execPath(), { stdout: "null", stderr: "null", - cmd: [ - Deno.execPath(), + args: [ "cache", "--reload", "--lock=lock_write_fetch.json", @@ -18,14 +17,12 @@ const fetchProc = Deno.run({ ], }); -const fetchCode = (await fetchProc.status()).code; -console.log(`fetch code: ${fetchCode}`); +console.log(`fetch code: ${fetchProc.status.code}`); -const fetchCheckProc = Deno.run({ +const fetchCheckProc = await Deno.spawn(Deno.execPath(), { stdout: "null", stderr: "null", - cmd: [ - Deno.execPath(), + args: [ "cache", "--lock=lock_write_fetch.json", "--cert=tls/RootCA.pem", @@ -33,16 +30,14 @@ const fetchCheckProc = Deno.run({ ], }); -const fetchCheckProcCode = (await fetchCheckProc.status()).code; -console.log(`fetch check code: ${fetchCheckProcCode}`); +console.log(`fetch check code: ${fetchCheckProc.status.code}`); Deno.removeSync("./lock_write_fetch.json"); -const runProc = Deno.run({ +const runProc = await Deno.spawn(Deno.execPath(), { stdout: "null", stderr: "null", - cmd: [ - Deno.execPath(), + args: [ "run", "--lock=lock_write_fetch.json", "--lock-write", @@ -52,7 +47,6 @@ const runProc = Deno.run({ ], }); -const runCode = (await runProc.status()).code; -console.log(`run code: ${runCode}`); +console.log(`run code: ${runProc.status.code}`); Deno.removeSync("./lock_write_fetch.json"); diff --git a/cli/tests/testdata/no_prompt.ts b/cli/tests/testdata/no_prompt.ts index f3d503f63..7f9750995 100644 --- a/cli/tests/testdata/no_prompt.ts +++ b/cli/tests/testdata/no_prompt.ts @@ -1,7 +1,10 @@ new Worker("data:,setTimeout(() => Deno.exit(2), 200)", { type: "module" }); try { - await Deno.run({ cmd: ["ps"] }); + await Deno.spawn("ps", { + stdout: "inherit", + stderr: "inherit", + }); } catch { Deno.exit(0); } diff --git a/cli/tests/testdata/permission_test.ts b/cli/tests/testdata/permission_test.ts index a3a38f2a0..4b186a0a2 100644 --- a/cli/tests/testdata/permission_test.ts +++ b/cli/tests/testdata/permission_test.ts @@ -15,13 +15,10 @@ const test: { [key: string]: (...args: any[]) => void | Promise<void> } = { netRequired() { Deno.listen({ transport: "tcp", port: 4541 }); }, - runRequired() { - const p = Deno.run({ - cmd: Deno.build.os === "windows" - ? ["cmd.exe", "/c", "echo hello"] - : ["printf", "hello"], + async runRequired() { + await Deno.spawn(Deno.build.os === "windows" ? "cmd.exe" : "printf", { + args: Deno.build.os === "windows" ? ["/c", "echo hello"] : ["hello"], }); - p.close(); }, }; diff --git a/cli/tests/unit/chown_test.ts b/cli/tests/unit/chown_test.ts index 7a282d68b..b9d40f525 100644 --- a/cli/tests/unit/chown_test.ts +++ b/cli/tests/unit/chown_test.ts @@ -5,21 +5,17 @@ import { assertEquals, assertRejects, assertThrows } from "./test_util.ts"; async function getUidAndGid(): Promise<{ uid: number; gid: number }> { // get the user ID and group ID of the current process - const uidProc = Deno.run({ - stdout: "piped", - cmd: ["id", "-u"], + const uidProc = await Deno.spawn("id", { + args: ["-u"], }); - const gidProc = Deno.run({ - stdout: "piped", - cmd: ["id", "-g"], + const gidProc = await Deno.spawn("id", { + args: ["-g"], }); - assertEquals((await uidProc.status()).code, 0); - assertEquals((await gidProc.status()).code, 0); - const uid = parseInt(new TextDecoder("utf-8").decode(await uidProc.output())); - uidProc.close(); - const gid = parseInt(new TextDecoder("utf-8").decode(await gidProc.output())); - gidProc.close(); + assertEquals(uidProc.status.code, 0); + assertEquals(gidProc.status.code, 0); + const uid = parseInt(new TextDecoder("utf-8").decode(uidProc.stdout)); + const gid = parseInt(new TextDecoder("utf-8").decode(gidProc.stdout)); return { uid, gid }; } diff --git a/cli/tests/unit/flock_test.ts b/cli/tests/unit/flock_test.ts index 8ebda3f6c..3c73d0481 100644 --- a/cli/tests/unit/flock_test.ts +++ b/cli/tests/unit/flock_test.ts @@ -1,6 +1,5 @@ // Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. import { assertEquals } from "./test_util.ts"; -import { readAll } from "../../../test_util/std/io/util.ts"; Deno.test( { permissions: { read: true, run: true, hrtime: true } }, @@ -103,8 +102,8 @@ async function checkFirstBlocksSecond(opts: { const secondPsTimes = await secondProcess.getTimes(); return firstPsTimes.exitTime < secondPsTimes.enterTime; } finally { - firstProcess.close(); - secondProcess.close(); + await firstProcess.close(); + await secondProcess.close(); } } @@ -149,14 +148,21 @@ function runFlockTestProcess(opts: { exclusive: boolean; sync: boolean }) { console.log(JSON.stringify({ enterTime, exitTime })); `; - const process = Deno.run({ - cmd: [Deno.execPath(), "eval", "--unstable", scriptText], - stdout: "piped", + const process = Deno.spawnChild(Deno.execPath(), { + args: ["eval", "--unstable", scriptText], stdin: "piped", }); - const waitSignal = () => process.stdout.read(new Uint8Array(1)); - const signal = () => process.stdin.write(new Uint8Array(1)); + const waitSignal = async () => { + const reader = process.stdout.getReader({ mode: "byob" }); + await reader.read(new Uint8Array(1)); + reader.releaseLock(); + }; + const signal = async () => { + const writer = process.stdin.getWriter(); + await writer.write(new Uint8Array(1)); + writer.releaseLock(); + }; return { async waitStartup() { @@ -174,17 +180,16 @@ function runFlockTestProcess(opts: { exclusive: boolean; sync: boolean }) { await waitSignal(); }, getTimes: async () => { - const outputBytes = await readAll(process.stdout); - const text = new TextDecoder().decode(outputBytes); + const { stdout } = await process.output(); + const text = new TextDecoder().decode(stdout); return JSON.parse(text) as { enterTime: number; exitTime: number; }; }, - close: () => { - process.stdout.close(); - process.stdin.close(); - process.close(); + close: async () => { + await process.status; + await process.stdin.close(); }, }; } diff --git a/cli/tests/unit/http_test.ts b/cli/tests/unit/http_test.ts index 2a4b7df01..779f11e56 100644 --- a/cli/tests/unit/http_test.ts +++ b/cli/tests/unit/http_test.ts @@ -1165,11 +1165,13 @@ Deno.test( async function client() { const url = `http://${hostname}:${port}/`; - const cmd = ["curl", "-X", "DELETE", url]; - const proc = Deno.run({ cmd, stdout: "null", stderr: "null" }); - const status = await proc.status(); + const args = ["-X", "DELETE", url]; + const { status } = await Deno.spawn("curl", { + args, + stdout: "null", + stderr: "null", + }); assert(status.success); - proc.close(); } await Promise.all([server(), client()]); @@ -1277,8 +1279,7 @@ Deno.test({ async function client() { const url = `http://${hostname}:${port}/`; - const cmd = [ - "curl", + const args = [ "-i", "--request", "GET", @@ -1287,13 +1288,14 @@ Deno.test({ "--header", "Accept-Encoding: gzip, deflate, br", ]; - const proc = Deno.run({ cmd, stdout: "piped", stderr: "null" }); - const status = await proc.status(); + const { status, stdout } = await Deno.spawn("curl", { + args, + stderr: "null", + }); assert(status.success); - const output = decoder.decode(await proc.output()); + const output = decoder.decode(stdout); assert(output.includes("vary: Accept-Encoding\r\n")); assert(output.includes("content-encoding: gzip\r\n")); - proc.close(); } await Promise.all([server(), client()]); @@ -1327,8 +1329,7 @@ Deno.test({ async function client() { const url = `http://${hostname}:${port}/`; - const cmd = [ - "curl", + const args = [ "--request", "GET", "--url", @@ -1336,10 +1337,10 @@ Deno.test({ "--header", "Accept-Encoding: gzip, deflate, br", ]; - const proc = Deno.run({ cmd, stdout: "piped", stderr: "null" }); - const status = await proc.status(); + const proc = Deno.spawnChild("curl", { args, stderr: "null" }); + const status = await proc.status; assert(status.success); - const stdout = proc.stdout!.readable + const stdout = proc.stdout .pipeThrough(new DecompressionStream("gzip")) .pipeThrough(new TextDecoderStream()); let body = ""; @@ -1347,7 +1348,6 @@ Deno.test({ body += chunk; } assertEquals(JSON.parse(body), data); - proc.close(); } await Promise.all([server(), client()]); @@ -1382,8 +1382,7 @@ Deno.test({ async function client() { const url = `http://${hostname}:${port}/`; - const cmd = [ - "curl", + const args = [ "-i", "--request", "GET", @@ -1392,13 +1391,14 @@ Deno.test({ "--header", "Accept-Encoding: gzip, deflate, br", ]; - const proc = Deno.run({ cmd, stdout: "piped", stderr: "null" }); - const status = await proc.status(); + const { status, stdout } = await Deno.spawn("curl", { + args, + stderr: "null", + }); assert(status.success); - const output = decoder.decode(await proc.output()).toLocaleLowerCase(); + const output = decoder.decode(stdout).toLocaleLowerCase(); assert(output.includes("vary: accept-encoding\r\n")); assert(!output.includes("content-encoding: ")); - proc.close(); } await Promise.all([server(), client()]); @@ -1436,8 +1436,7 @@ Deno.test({ async function client() { const url = `http://${hostname}:${port}/`; - const cmd = [ - "curl", + const args = [ "-i", "--request", "GET", @@ -1446,13 +1445,14 @@ Deno.test({ "--header", "Accept-Encoding: gzip;q=0.8, br;q=1.0, *;q=0.1", ]; - const proc = Deno.run({ cmd, stdout: "piped", stderr: "null" }); - const status = await proc.status(); + const { status, stdout } = await Deno.spawn("curl", { + args, + stderr: "null", + }); assert(status.success); - const output = decoder.decode(await proc.output()); + const output = decoder.decode(stdout); assert(output.includes("vary: Accept-Encoding\r\n")); assert(output.includes("content-encoding: br\r\n")); - proc.close(); } await Promise.all([server(), client()]); @@ -1487,8 +1487,7 @@ Deno.test({ async function client() { const url = `http://${hostname}:${port}/`; - const cmd = [ - "curl", + const args = [ "-i", "--request", "GET", @@ -1497,13 +1496,14 @@ Deno.test({ "--header", "Accept-Encoding: gzip, deflate, br", ]; - const proc = Deno.run({ cmd, stdout: "piped", stderr: "null" }); - const status = await proc.status(); + const { status, stdout } = await Deno.spawn("curl", { + args, + stderr: "null", + }); assert(status.success); - const output = decoder.decode(await proc.output()); + const output = decoder.decode(stdout); assert(output.includes("vary: Accept-Encoding, Accept\r\n")); assert(output.includes("content-encoding: gzip\r\n")); - proc.close(); } await Promise.all([server(), client()]); @@ -1541,7 +1541,7 @@ Deno.test({ async function client() { const url = `http://${hostname}:${port}/`; - const cmd = [ + const args = [ "curl", "-i", "--request", @@ -1551,16 +1551,17 @@ Deno.test({ "--header", "Accept-Encoding: gzip, deflate, br", ]; - const proc = Deno.run({ cmd, stdout: "piped", stderr: "null" }); - const status = await proc.status(); + const { status, stdout } = await Deno.spawn("curl", { + args, + stderr: "null", + }); assert(status.success); - const output = decoder.decode(await proc.output()); + const output = decoder.decode(stdout); assert(output.includes("vary: Accept-Encoding\r\n")); assert( output.includes("etag: W/33a64df551425fcc55e4d42a148795d9f25f89d4\r\n"), ); assert(output.includes("content-encoding: gzip\r\n")); - proc.close(); } await Promise.all([server(), client()]); @@ -1598,8 +1599,7 @@ Deno.test({ async function client() { const url = `http://${hostname}:${port}/`; - const cmd = [ - "curl", + const args = [ "-i", "--request", "GET", @@ -1608,16 +1608,17 @@ Deno.test({ "--header", "Accept-Encoding: gzip, deflate, br", ]; - const proc = Deno.run({ cmd, stdout: "piped", stderr: "null" }); - const status = await proc.status(); + const { status, stdout } = await Deno.spawn("curl", { + args, + stderr: "null", + }); assert(status.success); - const output = decoder.decode(await proc.output()); + const output = decoder.decode(stdout); assert(output.includes("vary: Accept-Encoding\r\n")); assert( output.includes("etag: W/33a64df551425fcc55e4d42a148795d9f25f89d4\r\n"), ); assert(output.includes("content-encoding: gzip\r\n")); - proc.close(); } await Promise.all([server(), client()]); @@ -1655,8 +1656,7 @@ Deno.test({ async function client() { const url = `http://${hostname}:${port}/`; - const cmd = [ - "curl", + const args = [ "-i", "--request", "GET", @@ -1665,13 +1665,14 @@ Deno.test({ "--header", "Accept-Encoding: gzip, deflate, br", ]; - const proc = Deno.run({ cmd, stdout: "piped", stderr: "null" }); - const status = await proc.status(); + const { status, stdout } = await Deno.spawn("curl", { + args, + stderr: "null", + }); assert(status.success); - const output = decoder.decode(await proc.output()); + const output = decoder.decode(stdout); assert(output.includes("vary: Accept-Encoding\r\n")); assert(!output.includes("content-encoding: ")); - proc.close(); } await Promise.all([server(), client()]); @@ -1709,8 +1710,7 @@ Deno.test({ async function client() { const url = `http://${hostname}:${port}/`; - const cmd = [ - "curl", + const args = [ "-i", "--request", "GET", @@ -1719,13 +1719,14 @@ Deno.test({ "--header", "Accept-Encoding: gzip, deflate, br", ]; - const proc = Deno.run({ cmd, stdout: "piped", stderr: "null" }); - const status = await proc.status(); + const { status, stdout } = await Deno.spawn("curl", { + args, + stderr: "null", + }); assert(status.success); - const output = decoder.decode(await proc.output()); + const output = decoder.decode(stdout); assert(output.includes("vary: Accept-Encoding\r\n")); assert(!output.includes("content-encoding: ")); - proc.close(); } await Promise.all([server(), client()]); @@ -1768,7 +1769,7 @@ Deno.test({ async function client() { const url = `http://${hostname}:${port}/`; - const cmd = [ + const args = [ "curl", "-i", "--request", @@ -1778,13 +1779,14 @@ Deno.test({ "--header", "Accept-Encoding: gzip, deflate, br", ]; - const proc = Deno.run({ cmd, stdout: "piped", stderr: "null" }); - const status = await proc.status(); + const { status, stdout } = await Deno.spawn("curl", { + args, + stderr: "null", + }); assert(status.success); - const output = decoder.decode(await proc.output()); + const output = decoder.decode(stdout); assert(output.includes("vary: Accept-Encoding\r\n")); assert(output.includes("content-encoding: gzip\r\n")); - proc.close(); } await Promise.all([server(), client()]); @@ -1827,8 +1829,7 @@ Deno.test({ async function client() { const url = `http://${hostname}:${port}/`; - const cmd = [ - "curl", + const args = [ "--request", "GET", "--url", @@ -1836,10 +1837,10 @@ Deno.test({ "--header", "Accept-Encoding: gzip, deflate, br", ]; - const proc = Deno.run({ cmd, stdout: "piped", stderr: "null" }); - const status = await proc.status(); + const proc = Deno.spawnChild("curl", { args, stderr: "null" }); + const status = await proc.status; assert(status.success); - const stdout = proc.stdout.readable + const stdout = proc.stdout .pipeThrough(new DecompressionStream("gzip")) .pipeThrough(new TextDecoderStream()); let body = ""; @@ -1847,7 +1848,6 @@ Deno.test({ body += chunk; } assertEquals(JSON.parse(body), data); - proc.close(); } await Promise.all([server(), client()]); @@ -1892,8 +1892,7 @@ Deno.test({ async function client() { const url = `http://${hostname}:${port}/`; - const cmd = [ - "curl", + const args = [ "-i", "--request", "GET", @@ -1902,16 +1901,17 @@ Deno.test({ "--header", "Accept-Encoding: gzip, deflate, br", ]; - const proc = Deno.run({ cmd, stdout: "piped", stderr: "null" }); - const status = await proc.status(); + const { status, stdout } = await Deno.spawn("curl", { + args, + stderr: "null", + }); assert(status.success); - const output = decoder.decode(await proc.output()); + const output = decoder.decode(stdout); assert(output.includes("vary: Accept-Encoding\r\n")); assert(output.includes("content-encoding: gzip\r\n")); // Ensure the content-length header is updated. assert(!output.includes(`content-length: ${contentLength}\r\n`)); assert(output.includes("content-length: 72\r\n")); - proc.close(); } await Promise.all([server(), client()]); diff --git a/cli/tests/unit/os_test.ts b/cli/tests/unit/os_test.ts index a469c8c9f..6ed1126f1 100644 --- a/cli/tests/unit/os_test.ts +++ b/cli/tests/unit/os_test.ts @@ -74,19 +74,14 @@ Deno.test( console.log( ${JSON.stringify(Object.keys(expectedEnv))}.map(k => Deno.env.get(k)) )`; - const proc = Deno.run({ - cmd: [Deno.execPath(), "eval", src], + const { status, stdout } = await Deno.spawn(Deno.execPath(), { + args: ["eval", src], env: { ...inputEnv, NO_COLOR: "1" }, - stdout: "piped", }); - const status = await proc.status(); assertEquals(status.success, true); const expectedValues = Object.values(expectedEnv); - const actualValues = JSON.parse( - new TextDecoder().decode(await proc.output()), - ); + const actualValues = JSON.parse(new TextDecoder().decode(stdout)); assertEquals(actualValues, expectedValues); - proc.close(); }; assertEquals(Deno.env.get("path"), Deno.env.get("PATH")); @@ -133,16 +128,13 @@ Deno.test( { permissions: { run: true, read: true } }, async function osPpidIsEqualToPidOfParentProcess() { const decoder = new TextDecoder(); - const process = Deno.run({ - cmd: [Deno.execPath(), "eval", "-p", "--unstable", "Deno.ppid"], - stdout: "piped", + const { stdout } = await Deno.spawn(Deno.execPath(), { + args: ["eval", "-p", "--unstable", "Deno.ppid"], env: { NO_COLOR: "true" }, }); - const output = await process.output(); - process.close(); const expected = Deno.pid; - const actual = parseInt(decoder.decode(output)); + const actual = parseInt(decoder.decode(stdout)); assertEquals(actual, expected); }, ); diff --git a/cli/tests/unit/remove_test.ts b/cli/tests/unit/remove_test.ts index 04e50f39d..365cc4e45 100644 --- a/cli/tests/unit/remove_test.ts +++ b/cli/tests/unit/remove_test.ts @@ -262,13 +262,12 @@ if (Deno.build.os === "windows") { Deno.test( { permissions: { run: true, write: true, read: true } }, async function removeFileSymlink() { - const symlink = Deno.run({ - cmd: ["cmd", "/c", "mklink", "file_link", "bar"], + const { status } = await Deno.spawn("cmd", { + args: ["/c", "mklink", "file_link", "bar"], stdout: "null", }); - assert(await symlink.status()); - symlink.close(); + assert(status.success); await Deno.remove("file_link"); await assertRejects(async () => { await Deno.lstat("file_link"); @@ -279,14 +278,12 @@ if (Deno.build.os === "windows") { Deno.test( { permissions: { run: true, write: true, read: true } }, async function removeDirSymlink() { - const symlink = Deno.run({ - cmd: ["cmd", "/c", "mklink", "/d", "dir_link", "bar"], + const { status } = await Deno.spawn("cmd", { + args: ["/c", "mklink", "/d", "dir_link", "bar"], stdout: "null", }); - assert(await symlink.status()); - symlink.close(); - + assert(status.success); await Deno.remove("dir_link"); await assertRejects(async () => { await Deno.lstat("dir_link"); diff --git a/cli/tests/unit/signal_test.ts b/cli/tests/unit/signal_test.ts index 12c5046a5..4ff4d38e1 100644 --- a/cli/tests/unit/signal_test.ts +++ b/cli/tests/unit/signal_test.ts @@ -173,17 +173,14 @@ Deno.test( permissions: { run: true, read: true }, }, async function canExitWhileListeningToSignal() { - const p = Deno.run({ - cmd: [ - Deno.execPath(), + const { status } = await Deno.spawn(Deno.execPath(), { + args: [ "eval", "--unstable", "Deno.addSignalListener('SIGIO', () => {})", ], }); - const res = await p.status(); - assertEquals(res.code, 0); - p.close(); + assertEquals(status.code, 0); }, ); diff --git a/cli/tests/unit/test_util.ts b/cli/tests/unit/test_util.ts index 36ef8c0e7..18965fdab 100644 --- a/cli/tests/unit/test_util.ts +++ b/cli/tests/unit/test_util.ts @@ -31,17 +31,13 @@ export function pathToAbsoluteFileUrl(path: string): URL { const decoder = new TextDecoder(); export async function execCode(code: string): Promise<[number, string]> { - const p = Deno.run({ - cmd: [ - Deno.execPath(), + const { status, stdout } = await Deno.spawn(Deno.execPath(), { + args: [ "eval", "--unstable", "--no-check", code, ], - stdout: "piped", }); - const [status, output] = await Promise.all([p.status(), p.output()]); - p.close(); - return [status.code, decoder.decode(output)]; + return [status.code, decoder.decode(stdout)]; } diff --git a/cli/tests/unit/tls_test.ts b/cli/tests/unit/tls_test.ts index 05eced64e..c9f22b75b 100644 --- a/cli/tests/unit/tls_test.ts +++ b/cli/tests/unit/tls_test.ts @@ -1019,20 +1019,14 @@ function createHttpsListener(port: number): Deno.Listener { } async function curl(url: string): Promise<string> { - const curl = Deno.run({ - cmd: ["curl", "--insecure", url], - stdout: "piped", + const { status, stdout } = await Deno.spawn("curl", { + args: ["--insecure", url], }); - try { - const [status, output] = await Promise.all([curl.status(), curl.output()]); - if (!status.success) { - throw new Error(`curl ${url} failed: ${status.code}`); - } - return new TextDecoder().decode(output); - } finally { - curl.close(); + if (!status.success) { + throw new Error(`curl ${url} failed: ${status.code}`); } + return new TextDecoder().decode(stdout); } Deno.test( diff --git a/cli/tests/unit/tty_color_test.ts b/cli/tests/unit/tty_color_test.ts index c10c9ff1e..feb4dd470 100644 --- a/cli/tests/unit/tty_color_test.ts +++ b/cli/tests/unit/tty_color_test.ts @@ -6,12 +6,10 @@ import { assertEquals } from "./test_util.ts"; Deno.test( { permissions: { run: true, read: true } }, async function noColorIfNotTty() { - const p = Deno.run({ - cmd: [Deno.execPath(), "eval", "console.log(1)"], - stdout: "piped", + const { stdout } = await Deno.spawn(Deno.execPath(), { + args: ["eval", "console.log(1)"], }); - const output = new TextDecoder().decode(await p.output()); + const output = new TextDecoder().decode(stdout); assertEquals(output, "1\n"); - p.close(); }, ); diff --git a/runtime/js/40_spawn.js b/runtime/js/40_spawn.js index 4f680c7e1..77236ee2b 100644 --- a/runtime/js/40_spawn.js +++ b/runtime/js/40_spawn.js @@ -141,9 +141,6 @@ } async output() { - if (this.#rid === null) { - throw new TypeError("Child process has already terminated."); - } if (this.#stdout?.locked) { throw new TypeError( "Can't collect output because stdout is locked", diff --git a/tools/flamebench.js b/tools/flamebench.js index 35f739e1e..5293fa9a1 100755 --- a/tools/flamebench.js +++ b/tools/flamebench.js @@ -3,35 +3,34 @@ import { join, ROOT_PATH as ROOT } from "./util.js"; async function bashOut(subcmd) { - const p = Deno.run({ - cmd: ["bash", "-c", subcmd], + const { status, stdout } = await Deno.spawn("bash", { + args: ["-c", subcmd], stdout: "piped", stderr: "null", }); // Check for failure - const { success } = await p.status(); - if (!success) { + if (!status.success) { throw new Error("subcmd failed"); } // Gather output - const output = new TextDecoder().decode(await p.output()); - // Cleanup - p.close(); + const output = new TextDecoder().decode(stdout); return output.trim(); } async function bashThrough(subcmd, opts = {}) { - const p = Deno.run({ ...opts, cmd: ["bash", "-c", subcmd] }); + const { status } = await Deno.spawn("bash", { + ...opts, + args: ["-c", subcmd], + stdout: "inherit", + stderr: "inherit", + }); // Exit process on failure - const { success, code } = await p.status(); - if (!success) { - Deno.exit(code); + if (!status.success) { + Deno.exit(status.code); } - // Cleanup - p.close(); } async function availableBenches() { diff --git a/tools/format.js b/tools/format.js index a829c86dd..2cd90f622 100755 --- a/tools/format.js +++ b/tools/format.js @@ -5,14 +5,14 @@ import { getPrebuiltToolPath, join, ROOT_PATH } from "./util.js"; async function dprint() { const configFile = join(ROOT_PATH, ".dprint.json"); const execPath = getPrebuiltToolPath("dprint"); - const p = Deno.run({ - cmd: [execPath, "fmt", "--config=" + configFile], + const { status } = await Deno.spawn(execPath, { + args: ["fmt", "--config=" + configFile], + stdout: "inherit", + stderr: "inherit", }); - const { success } = await p.status(); - if (!success) { + if (!status.success) { throw new Error("dprint failed"); } - p.close(); } async function main() { @@ -20,17 +20,15 @@ async function main() { await dprint(); if (Deno.args.includes("--check")) { - const git = Deno.run({ - cmd: ["git", "status", "-uno", "--porcelain", "--ignore-submodules"], - stdout: "piped", + const { status, stdout } = await Deno.spawn("git", { + args: ["status", "-uno", "--porcelain", "--ignore-submodules"], + stderr: "inherit", }); - const { success } = await git.status(); - if (!success) { + if (!status.success) { throw new Error("git status failed"); } - const out = new TextDecoder().decode(await git.output()); - git.close(); + const out = new TextDecoder().decode(stdout); if (out) { console.log("run tools/format.js"); diff --git a/tools/lint.js b/tools/lint.js index a431e05c0..5ecf1c3c4 100755 --- a/tools/lint.js +++ b/tools/lint.js @@ -39,14 +39,14 @@ async function dlint() { const chunks = splitToChunks(sourceFiles, `${execPath} run`.length); for (const chunk of chunks) { - const p = Deno.run({ - cmd: [execPath, "run", "--config=" + configFile, ...chunk], + const { status } = await Deno.spawn(execPath, { + args: ["run", "--config=" + configFile, ...chunk], + stdout: "inherit", + stderr: "inherit", }); - const { success } = await p.status(); - if (!success) { + if (!status.success) { throw new Error("dlint failed"); } - p.close(); } } @@ -70,14 +70,14 @@ async function dlintPreferPrimordials() { const chunks = splitToChunks(sourceFiles, `${execPath} run`.length); for (const chunk of chunks) { - const p = Deno.run({ - cmd: [execPath, "run", "--rule", "prefer-primordials", ...chunk], + const { status } = await Deno.spawn(execPath, { + args: ["run", "--rule", "prefer-primordials", ...chunk], + stdout: "inherit", + stderr: "inherit", }); - const { success } = await p.status(); - if (!success) { + if (!status.success) { throw new Error("prefer-primordials failed"); } - p.close(); } } @@ -101,14 +101,14 @@ async function clippy() { console.log("clippy"); const currentBuildMode = buildMode(); - const cmd = ["cargo", "clippy", "--all-targets", "--locked"]; + const cmd = ["clippy", "--all-targets", "--locked"]; if (currentBuildMode != "debug") { cmd.push("--release"); } - const p = Deno.run({ - cmd: [ + const { status } = await Deno.spawn("cargo", { + args: [ ...cmd, "--", "-D", @@ -116,12 +116,12 @@ async function clippy() { "-D", "clippy::await_holding_refcell_ref", ], + stdout: "inherit", + stderr: "inherit", }); - const { success } = await p.status(); - if (!success) { + if (!status.success) { throw new Error("clippy failed"); } - p.close(); } async function main() { diff --git a/tools/util.js b/tools/util.js index fa62097d4..c76456b9a 100644 --- a/tools/util.js +++ b/tools/util.js @@ -8,24 +8,21 @@ import { } from "../test_util/std/path/mod.ts"; export { dirname, fromFileUrl, join, resolve, toFileUrl }; export { existsSync, walk } from "../test_util/std/fs/mod.ts"; -export { readLines } from "../test_util/std/io/mod.ts"; +export { TextLineStream } from "../test_util/std/streams/delimiter.ts"; export { delay } from "../test_util/std/async/delay.ts"; export const ROOT_PATH = dirname(dirname(fromFileUrl(import.meta.url))); -async function getFilesFromGit(baseDir, cmd) { - const p = Deno.run({ - cmd, - stdout: "piped", +async function getFilesFromGit(baseDir, args) { + const { status, stdout } = await Deno.spawn("git", { + stderr: "inherit", + args, }); - const output = new TextDecoder().decode(await p.output()); - const { success } = await p.status(); - if (!success) { + const output = new TextDecoder().decode(stdout); + if (!status.success) { throw new Error("gitLsFiles failed"); } - p.close(); - const files = output.split("\0").filter((line) => line.length > 0).map( (filePath) => { return Deno.realPathSync(join(baseDir, filePath)); @@ -38,7 +35,6 @@ async function getFilesFromGit(baseDir, cmd) { function gitLsFiles(baseDir, patterns) { baseDir = Deno.realPathSync(baseDir); const cmd = [ - "git", "-C", baseDir, "ls-files", @@ -57,7 +53,6 @@ function gitLsFiles(baseDir, patterns) { function gitStaged(baseDir, patterns) { baseDir = Deno.realPathSync(baseDir); const cmd = [ - "git", "-C", baseDir, "diff", diff --git a/tools/wgpu_sync.js b/tools/wgpu_sync.js index c5b6ffc45..3c6217709 100755 --- a/tools/wgpu_sync.js +++ b/tools/wgpu_sync.js @@ -10,15 +10,17 @@ const V_WGPU = "0.12"; const TARGET_DIR = join(ROOT_PATH, "ext", "webgpu"); async function bash(subcmd, opts = {}) { - const p = Deno.run({ ...opts, cmd: ["bash", "-c", subcmd] }); + const { status } = await Deno.spawn("bash", { + ...opts, + args: ["-c", subcmd], + stdout: "inherit", + sdterr: "inherit", + }); // Exit process on failure - const { success, code } = await p.status(); - if (!success) { - Deno.exit(code); + if (!status.success) { + Deno.exit(status.code); } - // Cleanup - p.close(); } async function clearTargetDir() { diff --git a/tools/wpt.ts b/tools/wpt.ts index 52d57ad28..615fbf752 100755 --- a/tools/wpt.ts +++ b/tools/wpt.ts @@ -90,10 +90,11 @@ async function setup() { `The WPT require certain entries to be present in your ${hostsPath} file. Should these be configured automatically?`, ); if (autoConfigure) { - const proc = runPy(["wpt", "make-hosts-file"], { stdout: "piped" }); - const status = await proc.status(); + const { status, stdout } = await runPy(["wpt", "make-hosts-file"], { + stdout: "piped", + }).output(); assert(status.success, "wpt make-hosts-file should not fail"); - const entries = new TextDecoder().decode(await proc.output()); + const entries = new TextDecoder().decode(stdout); const file = await Deno.open(hostsPath, { append: true }).catch((err) => { if (err instanceof Deno.errors.PermissionDenied) { throw new Error( diff --git a/tools/wpt/runner.ts b/tools/wpt/runner.ts index 5e0285e77..269e6ffd1 100644 --- a/tools/wpt/runner.ts +++ b/tools/wpt/runner.ts @@ -1,5 +1,5 @@ // Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. -import { delay, join, readLines, ROOT_PATH, toFileUrl } from "../util.js"; +import { delay, join, ROOT_PATH, TextLineStream, toFileUrl } from "../util.js"; import { assert, denoBinary, ManifestTestOptions, runPy } from "./utils.ts"; import { DOMParser } from "https://deno.land/x/deno_dom@v0.1.3-alpha2/deno-dom-wasm.ts"; @@ -32,8 +32,7 @@ export async function runWithTestUtil<T>( const passedTime = performance.now() - start; if (passedTime > 15000) { proc.kill("SIGINT"); - await proc.status(); - proc.close(); + await proc.status; throw new Error("Timed out while trying to start wpt test util."); } } @@ -45,8 +44,7 @@ export async function runWithTestUtil<T>( } finally { if (verbose) console.log("Killing wpt test util."); proc.kill("SIGINT"); - await proc.status(); - proc.close(); + await proc.status; } } @@ -89,21 +87,17 @@ export async function runSingleTest( const startTime = new Date().getTime(); - const cmd = [ - denoBinary(), + const args = [ "run", - ]; - - cmd.push( "-A", "--unstable", - ); + ]; if (inspectBrk) { - cmd.push("--inspect-brk"); + args.push("--inspect-brk"); } - cmd.push( + args.push( "--enable-testing-features-do-not-use", "--location", url.toString(), @@ -113,8 +107,8 @@ export async function runSingleTest( "[]", ); - const proc = Deno.run({ - cmd, + const proc = Deno.spawnChild(denoBinary(), { + args, env: { NO_COLOR: "1", }, @@ -127,7 +121,9 @@ export async function runSingleTest( let harnessStatus = null; - const lines = readLines(proc.stderr); + const lines = proc.stderr.pipeThrough(new TextDecoderStream()).pipeThrough( + new TextLineStream(), + ); for await (const line of lines) { if (line.startsWith("{")) { const data = JSON.parse(line); @@ -144,7 +140,7 @@ export async function runSingleTest( const duration = new Date().getTime() - startTime; - const { code } = await proc.status(); + const { code } = await proc.status; return { status: code, harnessStatus, diff --git a/tools/wpt/utils.ts b/tools/wpt/utils.ts index f64e20f8f..80580928c 100644 --- a/tools/wpt/utils.ts +++ b/tools/wpt/utils.ts @@ -53,7 +53,7 @@ export interface ManifestTestOptions { const MANIFEST_PATH = join(ROOT_PATH, "./tools/wpt/manifest.json"); export async function updateManifest() { - const proc = runPy( + const status = await runPy( [ "wpt", "manifest", @@ -64,8 +64,7 @@ export async function updateManifest() { ...(rebuild ? ["--rebuild"] : []), ], {}, - ); - const status = await proc.status(); + ).status; assert(status.success, "updating wpt manifest should succeed"); } @@ -119,23 +118,26 @@ export function assert(condition: unknown, message: string): asserts condition { } } -export function runPy( +export function runPy<T extends Omit<Deno.SpawnOptions, "cwd">>( args: string[], - options: Omit<Omit<Deno.RunOptions, "cmd">, "cwd">, -): Deno.Process { + options: T, +): Deno.Child<T> { const cmd = Deno.build.os == "windows" ? "python.exe" : "python3"; - return Deno.run({ - cmd: [cmd, ...args], - cwd: join(ROOT_PATH, "./test_util/wpt/"), + return Deno.spawnChild(cmd, { + args, + stdout: "inherit", + stderr: "inherit", ...options, + cwd: join(ROOT_PATH, "./test_util/wpt/"), }); } export async function checkPy3Available() { - const proc = runPy(["--version"], { stdout: "piped" }); - const status = await proc.status(); + const { status, stdout } = await runPy(["--version"], { + stdout: "piped", + }).output(); assert(status.success, "failed to run python --version"); - const output = new TextDecoder().decode(await proc.output()); + const output = new TextDecoder().decode(stdout); assert( output.includes("Python 3."), `The ${ @@ -146,12 +148,12 @@ export async function checkPy3Available() { export async function cargoBuild() { if (binary) return; - const proc = Deno.run({ - cmd: ["cargo", "build", ...(release ? ["--release"] : [])], + const { status } = await Deno.spawn("cargo", { + args: ["build", ...(release ? ["--release"] : [])], cwd: ROOT_PATH, + stdout: "inherit", + stderr: "inherit", }); - const status = await proc.status(); - proc.close(); assert(status.success, "cargo build failed"); } @@ -173,22 +175,17 @@ export async function generateRunInfo(): Promise<unknown> { "darwin": "mac", "linux": "linux", }; - const proc = Deno.run({ - cmd: ["git", "rev-parse", "HEAD"], + const proc = await Deno.spawn("git", { + args: ["rev-parse", "HEAD"], cwd: join(ROOT_PATH, "test_util", "wpt"), - stdout: "piped", + stderr: "inherit", }); - await proc.status(); - const revision = (new TextDecoder().decode(await proc.output())).trim(); - proc.close(); - const proc2 = Deno.run({ - cmd: [denoBinary(), "eval", "console.log(JSON.stringify(Deno.version))"], + const revision = (new TextDecoder().decode(proc.stdout)).trim(); + const proc2 = await Deno.spawn(denoBinary(), { + args: ["eval", "console.log(JSON.stringify(Deno.version))"], cwd: join(ROOT_PATH, "test_util", "wpt"), - stdout: "piped", }); - await proc2.status(); - const version = JSON.parse(new TextDecoder().decode(await proc2.output())); - proc2.close(); + const version = JSON.parse(new TextDecoder().decode(proc2.stdout)); const runInfo = { "os": oses[Deno.build.os], "processor": Deno.build.arch, |