diff options
Diffstat (limited to 'cli/tests/unit/process_test.ts')
-rw-r--r-- | cli/tests/unit/process_test.ts | 566 |
1 files changed, 310 insertions, 256 deletions
diff --git a/cli/tests/unit/process_test.ts b/cli/tests/unit/process_test.ts index 43d848916..1e1342729 100644 --- a/cli/tests/unit/process_test.ts +++ b/cli/tests/unit/process_test.ts @@ -7,94 +7,102 @@ import { unitTest, } from "./test_util.ts"; -unitTest(function runPermissions(): void { +unitTest({ perms: { read: true } }, function runPermissions(): void { assertThrows(() => { - Deno.run({ cmd: ["python", "-c", "print('hello world')"] }); + Deno.run({ cmd: [Deno.execPath(), "eval", "console.log('hello world')"] }); }, Deno.errors.PermissionDenied); }); -unitTest({ perms: { run: true } }, async function runSuccess(): Promise<void> { - const p = Deno.run({ - cmd: ["python", "-c", "print('hello world')"], - stdout: "piped", - stderr: "null", - }); - const status = await p.status(); - assertEquals(status.success, true); - assertEquals(status.code, 0); - assertEquals(status.signal, undefined); - p.stdout.close(); - p.close(); -}); - -unitTest({ perms: { run: true } }, async function runUrl(): Promise<void> { - const q = Deno.run({ - cmd: ["python", "-c", "import sys; print sys.executable"], - stdout: "piped", - }); - await q.status(); - const pythonPath = new TextDecoder().decode(await q.output()).trim(); - q.close(); +unitTest( + { perms: { run: true, read: true } }, + async function runSuccess(): Promise<void> { + const p = Deno.run({ + cmd: [Deno.execPath(), "eval", "console.log('hello world')"], + stdout: "piped", + stderr: "null", + }); + const status = await p.status(); + assertEquals(status.success, true); + assertEquals(status.code, 0); + assertEquals(status.signal, undefined); + p.stdout.close(); + p.close(); + }, +); - const p = Deno.run({ - cmd: [new URL(`file:///${pythonPath}`), "-c", "print('hello world')"], - stdout: "piped", - stderr: "null", - }); - const status = await p.status(); - assertEquals(status.success, true); - assertEquals(status.code, 0); - assertEquals(status.signal, undefined); - p.stdout.close(); - p.close(); -}); +unitTest( + { perms: { run: true, read: true } }, + async function runUrl(): Promise<void> { + const p = Deno.run({ + cmd: [ + new URL(`file:///${Deno.execPath()}`), + "eval", + "console.log('hello world')", + ], + stdout: "piped", + stderr: "null", + }); + const status = await p.status(); + assertEquals(status.success, true); + assertEquals(status.code, 0); + assertEquals(status.signal, undefined); + p.stdout.close(); + p.close(); + }, +); -unitTest({ perms: { run: true } }, async function runStdinRid0(): Promise< - void -> { - const p = Deno.run({ - cmd: ["python", "-c", "print('hello world')"], - stdin: 0, - stdout: "piped", - stderr: "null", - }); - const status = await p.status(); - assertEquals(status.success, true); - assertEquals(status.code, 0); - assertEquals(status.signal, undefined); - p.stdout.close(); - p.close(); -}); +unitTest( + { perms: { run: true, read: true } }, + async function runStdinRid0(): Promise< + void + > { + const p = Deno.run({ + cmd: [Deno.execPath(), "eval", "console.log('hello world')"], + stdin: 0, + stdout: "piped", + stderr: "null", + }); + const status = await p.status(); + assertEquals(status.success, true); + assertEquals(status.code, 0); + assertEquals(status.signal, undefined); + p.stdout.close(); + p.close(); + }, +); -unitTest({ perms: { run: true } }, function runInvalidStdio(): void { - assertThrows(() => - Deno.run({ - cmd: ["python", "-c", "print('hello world')"], - // @ts-expect-error because Deno.run should throw on invalid stdin. - stdin: "a", - }) - ); - assertThrows(() => - Deno.run({ - cmd: ["python", "-c", "print('hello world')"], - // @ts-expect-error because Deno.run should throw on invalid stdout. - stdout: "b", - }) - ); - assertThrows(() => - Deno.run({ - cmd: ["python", "-c", "print('hello world')"], - // @ts-expect-error because Deno.run should throw on invalid stderr. - stderr: "c", - }) - ); -}); +unitTest( + { perms: { run: true, read: true } }, + function runInvalidStdio(): void { + assertThrows(() => + Deno.run({ + cmd: [Deno.execPath(), "eval", "console.log('hello world')"], + // @ts-expect-error because Deno.run should throw on invalid stdin. + stdin: "a", + }) + ); + assertThrows(() => + Deno.run({ + cmd: [Deno.execPath(), "eval", "console.log('hello world')"], + // @ts-expect-error because Deno.run should throw on invalid stdout. + stdout: "b", + }) + ); + assertThrows(() => + Deno.run({ + cmd: [Deno.execPath(), "eval", "console.log('hello world')"], + // @ts-expect-error because Deno.run should throw on invalid stderr. + stderr: "c", + }) + ); + }, +); unitTest( - { perms: { run: true } }, + { perms: { run: true, read: true } }, async function runCommandFailedWithCode(): Promise<void> { const p = Deno.run({ - cmd: ["python", "-c", "import sys;sys.exit(41 + 1)"], + cmd: [Deno.execPath(), "eval", "Deno.exit(41 + 1)"], }); const status = await p.status(); assertEquals(status.success, false); @@ -108,11 +116,11 @@ unitTest( { // No signals on windows. ignore: Deno.build.os === "windows", - perms: { run: true }, + perms: { run: true, read: true }, }, async function runCommandFailedWithSignal(): Promise<void> { const p = Deno.run({ - cmd: ["python", "-c", "import os;os.kill(os.getpid(), 9)"], + cmd: [Deno.execPath(), "eval", "--unstable", "Deno.kill(Deno.pid, 9)"], }); const status = await p.status(); assertEquals(status.success, false); @@ -134,36 +142,34 @@ unitTest({ perms: { run: true } }, function runNotFound(): void { }); unitTest( - { perms: { write: true, run: true } }, + { perms: { write: true, run: true, read: true } }, async function runWithCwdIsAsync(): Promise<void> { const enc = new TextEncoder(); const cwd = await Deno.makeTempDir({ prefix: "deno_command_test" }); const exitCodeFile = "deno_was_here"; - const pyProgramFile = "poll_exit.py"; - const pyProgram = ` -from sys import exit -from time import sleep - -while True: - try: - with open("${exitCodeFile}", "r") as f: - line = f.readline() - code = int(line) - exit(code) - except IOError: - # Retry if we got here before deno wrote the file. - sleep(0.01) - pass + const programFile = "poll_exit.ts"; + const program = ` +async function tryExit() { + try { + const code = parseInt(await Deno.readTextFile("${exitCodeFile}")); + Deno.exit(code); + } catch { + // Retry if we got here before deno wrote the file. + setTimeout(tryExit, 0.01); + } +} + +tryExit(); `; - Deno.writeFileSync(`${cwd}/${pyProgramFile}.py`, enc.encode(pyProgram)); + Deno.writeFileSync(`${cwd}/${programFile}`, enc.encode(program)); const p = Deno.run({ cwd, - cmd: ["python", `${pyProgramFile}.py`], + cmd: [Deno.execPath(), "run", "--allow-read", programFile], }); - // Write the expected exit code *after* starting python. + // Write the expected exit code *after* starting deno. // This is how we verify that `run()` is actually asynchronous. const code = 84; Deno.writeFileSync(`${cwd}/${exitCodeFile}`, enc.encode(`${code}`)); @@ -176,111 +182,146 @@ while True: }, ); -unitTest({ perms: { run: true } }, async function runStdinPiped(): Promise< - void -> { - const p = Deno.run({ - cmd: ["python", "-c", "import sys; assert 'hello' == sys.stdin.read();"], - stdin: "piped", - }); - assert(p.stdin); - assert(!p.stdout); - assert(!p.stderr); +unitTest( + { perms: { run: true, read: true } }, + async function runStdinPiped(): Promise< + void + > { + const p = Deno.run({ + cmd: [ + Deno.execPath(), + "eval", + "if (new TextDecoder().decode(await Deno.readAll(Deno.stdin)) !== 'hello') throw new Error('Expected \\'hello\\'')", + ], + stdin: "piped", + }); + assert(p.stdin); + assert(!p.stdout); + assert(!p.stderr); - const msg = new TextEncoder().encode("hello"); - const n = await p.stdin.write(msg); - assertEquals(n, msg.byteLength); + const msg = new TextEncoder().encode("hello"); + const n = await p.stdin.write(msg); + assertEquals(n, msg.byteLength); - p.stdin.close(); + p.stdin.close(); - const status = await p.status(); - assertEquals(status.success, true); - assertEquals(status.code, 0); - assertEquals(status.signal, undefined); - p.close(); -}); + const status = await p.status(); + assertEquals(status.success, true); + assertEquals(status.code, 0); + assertEquals(status.signal, undefined); + p.close(); + }, +); -unitTest({ perms: { run: true } }, async function runStdoutPiped(): Promise< - void -> { - const p = Deno.run({ - cmd: ["python", "-c", "import sys; sys.stdout.write('hello')"], - stdout: "piped", - }); - assert(!p.stdin); - assert(!p.stderr); +unitTest( + { perms: { run: true, read: true } }, + async function runStdoutPiped(): Promise< + void + > { + const p = Deno.run({ + cmd: [ + Deno.execPath(), + "eval", + "await Deno.stdout.write(new TextEncoder().encode('hello'))", + ], + stdout: "piped", + }); + assert(!p.stdin); + assert(!p.stderr); + + const data = new Uint8Array(10); + let r = await p.stdout.read(data); + if (r === null) { + throw new Error("p.stdout.read(...) should not be null"); + } + assertEquals(r, 5); + const s = new TextDecoder().decode(data.subarray(0, r)); + assertEquals(s, "hello"); + r = await p.stdout.read(data); + assertEquals(r, null); + p.stdout.close(); - const data = new Uint8Array(10); - let r = await p.stdout.read(data); - if (r === null) { - throw new Error("p.stdout.read(...) should not be null"); - } - assertEquals(r, 5); - const s = new TextDecoder().decode(data.subarray(0, r)); - assertEquals(s, "hello"); - r = await p.stdout.read(data); - assertEquals(r, null); - p.stdout.close(); - - const status = await p.status(); - assertEquals(status.success, true); - assertEquals(status.code, 0); - assertEquals(status.signal, undefined); - p.close(); -}); + const status = await p.status(); + assertEquals(status.success, true); + assertEquals(status.code, 0); + assertEquals(status.signal, undefined); + p.close(); + }, +); -unitTest({ perms: { run: true } }, async function runStderrPiped(): Promise< - void -> { - const p = Deno.run({ - cmd: ["python", "-c", "import sys; sys.stderr.write('hello')"], - stderr: "piped", - }); - assert(!p.stdin); - assert(!p.stdout); +unitTest( + { perms: { run: true, read: true } }, + async function runStderrPiped(): Promise< + void + > { + const p = Deno.run({ + cmd: [ + Deno.execPath(), + "eval", + "await Deno.stderr.write(new TextEncoder().encode('hello'))", + ], + stderr: "piped", + }); + assert(!p.stdin); + assert(!p.stdout); + + const data = new Uint8Array(10); + let r = await p.stderr.read(data); + if (r === null) { + throw new Error("p.stderr.read should not return null here"); + } + assertEquals(r, 5); + const s = new TextDecoder().decode(data.subarray(0, r)); + assertEquals(s, "hello"); + r = await p.stderr.read(data); + assertEquals(r, null); + p.stderr!.close(); - const data = new Uint8Array(10); - let r = await p.stderr.read(data); - if (r === null) { - throw new Error("p.stderr.read should not return null here"); - } - assertEquals(r, 5); - const s = new TextDecoder().decode(data.subarray(0, r)); - assertEquals(s, "hello"); - r = await p.stderr.read(data); - assertEquals(r, null); - p.stderr!.close(); - - const status = await p.status(); - assertEquals(status.success, true); - assertEquals(status.code, 0); - assertEquals(status.signal, undefined); - p.close(); -}); + const status = await p.status(); + assertEquals(status.success, true); + assertEquals(status.code, 0); + assertEquals(status.signal, undefined); + p.close(); + }, +); -unitTest({ perms: { run: true } }, async function runOutput(): Promise<void> { - const p = Deno.run({ - cmd: ["python", "-c", "import sys; sys.stdout.write('hello')"], - stdout: "piped", - }); - const output = await p.output(); - const s = new TextDecoder().decode(output); - assertEquals(s, "hello"); - p.close(); -}); +unitTest( + { perms: { run: true, read: true } }, + async function runOutput(): Promise<void> { + const p = Deno.run({ + cmd: [ + Deno.execPath(), + "eval", + "await Deno.stdout.write(new TextEncoder().encode('hello'))", + ], + stdout: "piped", + }); + const output = await p.output(); + const s = new TextDecoder().decode(output); + assertEquals(s, "hello"); + p.close(); + }, +); -unitTest({ perms: { run: true } }, async function runStderrOutput(): Promise< - void -> { - const p = Deno.run({ - cmd: ["python", "-c", "import sys; sys.stderr.write('error')"], - stderr: "piped", - }); - const error = await p.stderrOutput(); - const s = new TextDecoder().decode(error); - assertEquals(s, "error"); - p.close(); -}); +unitTest( + { perms: { run: true, read: true } }, + async function runStderrOutput(): Promise< + void + > { + const p = Deno.run({ + cmd: [ + Deno.execPath(), + "eval", + "await Deno.stderr.write(new TextEncoder().encode('error'))", + ], + stderr: "piped", + }); + const error = await p.stderrOutput(); + const s = new TextDecoder().decode(error); + assertEquals(s, "error"); + p.close(); + }, +); unitTest( { perms: { run: true, write: true, read: true } }, @@ -294,9 +335,9 @@ unitTest( const p = Deno.run({ cmd: [ - "python", - "-c", - "import sys; sys.stderr.write('error\\n'); sys.stdout.write('output\\n');", + Deno.execPath(), + "eval", + "Deno.stderr.write(new TextEncoder().encode('error\\n')); Deno.stdout.write(new TextEncoder().encode('output\\n'));", ], stdout: file.rid, stderr: file.rid, @@ -325,7 +366,11 @@ unitTest( const file = await Deno.open(fileName); const p = Deno.run({ - cmd: ["python", "-c", "import sys; assert 'hello' == sys.stdin.read();"], + cmd: [ + Deno.execPath(), + "eval", + "if (new TextDecoder().decode(await Deno.readAll(Deno.stdin)) !== 'hello') throw new Error('Expected \\'hello\\'')", + ], stdin: file.rid, }); @@ -336,50 +381,56 @@ unitTest( }, ); -unitTest({ perms: { run: true } }, async function runEnv(): Promise<void> { - const p = Deno.run({ - cmd: [ - "python", - "-c", - "import os, sys; sys.stdout.write(os.environ.get('FOO', '') + os.environ.get('BAR', ''))", - ], - env: { - FOO: "0123", - BAR: "4567", - }, - stdout: "piped", - }); - const output = await p.output(); - const s = new TextDecoder().decode(output); - assertEquals(s, "01234567"); - p.close(); -}); +unitTest( + { perms: { run: true, read: true } }, + async function runEnv(): Promise<void> { + const p = Deno.run({ + cmd: [ + Deno.execPath(), + "eval", + "Deno.stdout.write(new TextEncoder().encode(Deno.env.get('FOO') + Deno.env.get('BAR')))", + ], + env: { + FOO: "0123", + BAR: "4567", + }, + stdout: "piped", + }); + const output = await p.output(); + const s = new TextDecoder().decode(output); + assertEquals(s, "01234567"); + p.close(); + }, +); -unitTest({ perms: { run: true } }, async function runClose(): Promise<void> { - const p = Deno.run({ - cmd: [ - "python", - "-c", - "from time import sleep; import sys; sleep(10000); sys.stderr.write('error')", - ], - stderr: "piped", - }); - assert(!p.stdin); - assert(!p.stdout); +unitTest( + { perms: { run: true, read: true } }, + async function runClose(): Promise<void> { + const p = Deno.run({ + cmd: [ + Deno.execPath(), + "eval", + "setTimeout(() => Deno.stdout.write(new TextEncoder().encode('error')), 10000)", + ], + stderr: "piped", + }); + assert(!p.stdin); + assert(!p.stdout); - p.close(); + p.close(); - const data = new Uint8Array(10); - const r = await p.stderr.read(data); - assertEquals(r, null); - p.stderr.close(); -}); + const data = new Uint8Array(10); + const r = await p.stderr.read(data); + assertEquals(r, null); + p.stderr.close(); + }, +); unitTest( - { perms: { run: true } }, + { perms: { run: true, read: true } }, async function runKillAfterStatus(): Promise<void> { const p = Deno.run({ - cmd: ["python", "-c", 'print("hello")'], + cmd: [Deno.execPath(), "eval", 'console.log("hello")'], }); await p.status(); @@ -417,31 +468,34 @@ unitTest(function killPermissions(): void { }, Deno.errors.PermissionDenied); }); -unitTest({ perms: { run: true } }, async function killSuccess(): Promise<void> { - const p = Deno.run({ - cmd: ["python", "-c", "from time import sleep; sleep(10000)"], - }); +unitTest( + { perms: { run: true, read: true } }, + async function killSuccess(): Promise<void> { + const p = Deno.run({ + cmd: [Deno.execPath(), "eval", "setTimeout(() => {}, 10000)"], + }); - assertEquals(Deno.Signal.SIGINT, 2); - Deno.kill(p.pid, Deno.Signal.SIGINT); - const status = await p.status(); + assertEquals(Deno.Signal.SIGINT, 2); + Deno.kill(p.pid, Deno.Signal.SIGINT); + const status = await p.status(); - assertEquals(status.success, false); - try { - assertEquals(status.code, 128 + Deno.Signal.SIGINT); - assertEquals(status.signal, Deno.Signal.SIGINT); - } catch { - // TODO(nayeemrmn): On Windows sometimes the following values are given - // instead. Investigate and remove this catch when fixed. - assertEquals(status.code, 1); - assertEquals(status.signal, undefined); - } - p.close(); -}); + assertEquals(status.success, false); + try { + assertEquals(status.code, 128 + Deno.Signal.SIGINT); + assertEquals(status.signal, Deno.Signal.SIGINT); + } catch { + // TODO(nayeemrmn): On Windows sometimes the following values are given + // instead. Investigate and remove this catch when fixed. + assertEquals(status.code, 1); + assertEquals(status.signal, undefined); + } + p.close(); + }, +); -unitTest({ perms: { run: true } }, function killFailed(): void { +unitTest({ perms: { run: true, read: true } }, function killFailed(): void { const p = Deno.run({ - cmd: ["python", "-c", "from time import sleep; sleep(10000)"], + cmd: [Deno.execPath(), "eval", "setTimeout(() => {}, 10000)"], }); assert(!p.stdin); assert(!p.stdout); |