summaryrefslogtreecommitdiff
path: root/cli/tests/unit/process_test.ts
diff options
context:
space:
mode:
authorMatt Mastracci <matthew@mastracci.com>2024-02-10 13:22:13 -0700
committerGitHub <noreply@github.com>2024-02-10 20:22:13 +0000
commitf5e46c9bf2f50d66a953fa133161fc829cecff06 (patch)
tree8faf2f5831c1c7b11d842cd9908d141082c869a5 /cli/tests/unit/process_test.ts
parentd2477f780630a812bfd65e3987b70c0d309385bb (diff)
chore: move cli/tests/ -> tests/ (#22369)
This looks like a massive PR, but it's only a move from cli/tests -> tests, and updates of relative paths for files. This is the first step towards aggregate all of the integration test files under tests/, which will lead to a set of integration tests that can run without the CLI binary being built. While we could leave these tests under `cli`, it would require us to keep a more complex directory structure for the various test runners. In addition, we have a lot of complexity to ignore various test files in the `cli` project itself (cargo publish exclusion rules, autotests = false, etc). And finally, the `tests/` folder will eventually house the `test_ffi`, `test_napi` and other testing code, reducing the size of the root repo directory. For easier review, the extremely large and noisy "move" is in the first commit (with no changes -- just a move), while the remainder of the changes to actual files is in the second commit.
Diffstat (limited to 'cli/tests/unit/process_test.ts')
-rw-r--r--cli/tests/unit/process_test.ts689
1 files changed, 0 insertions, 689 deletions
diff --git a/cli/tests/unit/process_test.ts b/cli/tests/unit/process_test.ts
deleted file mode 100644
index 0cc4e99aa..000000000
--- a/cli/tests/unit/process_test.ts
+++ /dev/null
@@ -1,689 +0,0 @@
-// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
-import {
- assert,
- assertEquals,
- assertStrictEquals,
- assertStringIncludes,
- assertThrows,
-} from "./test_util.ts";
-
-Deno.test(
- { permissions: { read: true, run: false } },
- function runPermissions() {
- assertThrows(() => {
- // deno-lint-ignore no-deprecated-deno-api
- Deno.run({
- cmd: [Deno.execPath(), "eval", "console.log('hello world')"],
- });
- }, Deno.errors.PermissionDenied);
- },
-);
-
-Deno.test(
- { permissions: { run: true, read: true } },
- async function runSuccess() {
- // deno-lint-ignore no-deprecated-deno-api
- const p = Deno.run({
- // freeze the array to ensure it's not modified
- cmd: Object.freeze([
- 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();
- },
-);
-
-Deno.test(
- { permissions: { run: true, read: true } },
- async function runUrl() {
- // deno-lint-ignore no-deprecated-deno-api
- 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();
- },
-);
-
-Deno.test(
- { permissions: { run: true, read: true } },
- async function runStdinRid0(): Promise<
- void
- > {
- // deno-lint-ignore no-deprecated-deno-api
- 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();
- },
-);
-
-Deno.test(
- { permissions: { run: true, read: true } },
- function runInvalidStdio() {
- assertThrows(() =>
- // deno-lint-ignore no-deprecated-deno-api
- 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-lint-ignore no-deprecated-deno-api
- 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-lint-ignore no-deprecated-deno-api
- Deno.run({
- cmd: [Deno.execPath(), "eval", "console.log('hello world')"],
- // @ts-expect-error because Deno.run should throw on invalid stderr.
- stderr: "c",
- })
- );
- },
-);
-
-Deno.test(
- { permissions: { run: true, read: true } },
- async function runCommandFailedWithCode() {
- // deno-lint-ignore no-deprecated-deno-api
- const p = Deno.run({
- cmd: [Deno.execPath(), "eval", "Deno.exit(41 + 1)"],
- });
- const status = await p.status();
- assertEquals(status.success, false);
- assertEquals(status.code, 42);
- assertEquals(status.signal, undefined);
- p.close();
- },
-);
-
-Deno.test(
- {
- permissions: { run: true, read: true },
- },
- async function runCommandFailedWithSignal() {
- // deno-lint-ignore no-deprecated-deno-api
- const p = Deno.run({
- cmd: [
- Deno.execPath(),
- "eval",
- "Deno.kill(Deno.pid, 'SIGKILL')",
- ],
- });
- const status = await p.status();
- assertEquals(status.success, false);
- if (Deno.build.os === "windows") {
- assertEquals(status.code, 1);
- assertEquals(status.signal, undefined);
- } else {
- assertEquals(status.code, 128 + 9);
- assertEquals(status.signal, 9);
- }
- p.close();
- },
-);
-
-Deno.test({ permissions: { run: true } }, function runNotFound() {
- let error;
- try {
- // deno-lint-ignore no-deprecated-deno-api
- Deno.run({ cmd: ["this file hopefully doesn't exist"] });
- } catch (e) {
- error = e;
- }
- assert(error !== undefined);
- assert(error instanceof Deno.errors.NotFound);
-});
-
-Deno.test(
- { permissions: { write: true, run: true, read: true } },
- async function runWithCwdIsAsync() {
- const enc = new TextEncoder();
- const cwd = await Deno.makeTempDir({ prefix: "deno_command_test" });
-
- const exitCodeFile = "deno_was_here";
- 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}/${programFile}`, enc.encode(program));
- // deno-lint-ignore no-deprecated-deno-api
- const p = Deno.run({
- cwd,
- cmd: [Deno.execPath(), "run", "--allow-read", programFile],
- });
-
- // 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}`));
-
- const status = await p.status();
- assertEquals(status.success, false);
- assertEquals(status.code, code);
- assertEquals(status.signal, undefined);
- p.close();
- },
-);
-
-Deno.test(
- { permissions: { run: true, read: true } },
- async function runStdinPiped(): Promise<
- void
- > {
- // deno-lint-ignore no-deprecated-deno-api
- 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);
-
- p.stdin.close();
-
- const status = await p.status();
- assertEquals(status.success, true);
- assertEquals(status.code, 0);
- assertEquals(status.signal, undefined);
- p.close();
- },
-);
-
-Deno.test(
- { permissions: { run: true, read: true } },
- async function runStdoutPiped(): Promise<
- void
- > {
- // deno-lint-ignore no-deprecated-deno-api
- 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 status = await p.status();
- assertEquals(status.success, true);
- assertEquals(status.code, 0);
- assertEquals(status.signal, undefined);
- p.close();
- },
-);
-
-Deno.test(
- { permissions: { run: true, read: true } },
- async function runStderrPiped(): Promise<
- void
- > {
- // deno-lint-ignore no-deprecated-deno-api
- 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 status = await p.status();
- assertEquals(status.success, true);
- assertEquals(status.code, 0);
- assertEquals(status.signal, undefined);
- p.close();
- },
-);
-
-Deno.test(
- { permissions: { run: true, read: true } },
- async function runOutput() {
- // deno-lint-ignore no-deprecated-deno-api
- 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();
- },
-);
-
-Deno.test(
- { permissions: { run: true, read: true } },
- async function runStderrOutput(): Promise<
- void
- > {
- // deno-lint-ignore no-deprecated-deno-api
- 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();
- },
-);
-
-Deno.test(
- { permissions: { run: true, write: true, read: true } },
- async function runRedirectStdoutStderr() {
- const tempDir = await Deno.makeTempDir();
- const fileName = tempDir + "/redirected_stdio.txt";
- using file = await Deno.open(fileName, {
- create: true,
- write: true,
- });
-
- // deno-lint-ignore no-deprecated-deno-api
- const p = Deno.run({
- cmd: [
- 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,
- });
-
- await p.status();
- p.close();
-
- const fileContents = await Deno.readFile(fileName);
- const decoder = new TextDecoder();
- const text = decoder.decode(fileContents);
-
- assertStringIncludes(text, "error");
- assertStringIncludes(text, "output");
- },
-);
-
-Deno.test(
- { permissions: { run: true, write: true, read: true } },
- async function runRedirectStdin() {
- const tempDir = await Deno.makeTempDir();
- const fileName = tempDir + "/redirected_stdio.txt";
- await Deno.writeTextFile(fileName, "hello");
- using file = await Deno.open(fileName);
-
- // deno-lint-ignore no-deprecated-deno-api
- const p = Deno.run({
- cmd: [
- Deno.execPath(),
- "eval",
- "if (new TextDecoder().decode(await Deno.readAll(Deno.stdin)) !== 'hello') throw new Error('Expected \\'hello\\'')",
- ],
- stdin: file.rid,
- });
-
- const status = await p.status();
- assertEquals(status.code, 0);
- p.close();
- },
-);
-
-Deno.test(
- { permissions: { run: true, read: true } },
- async function runEnv() {
- // deno-lint-ignore no-deprecated-deno-api
- 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();
- },
-);
-
-Deno.test(
- { permissions: { run: true, read: true } },
- async function runClose() {
- // deno-lint-ignore no-deprecated-deno-api
- 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();
-
- const data = new Uint8Array(10);
- const r = await p.stderr.read(data);
- assertEquals(r, null);
- p.stderr.close();
- },
-);
-
-Deno.test(
- { permissions: { run: true, read: true } },
- async function runKillAfterStatus() {
- // deno-lint-ignore no-deprecated-deno-api
- const p = Deno.run({
- cmd: [Deno.execPath(), "eval", 'console.log("hello")'],
- });
- await p.status();
-
- let error = null;
- try {
- p.kill("SIGTERM");
- } catch (e) {
- error = e;
- }
-
- assert(
- error instanceof Deno.errors.NotFound ||
- // On Windows, the underlying Windows API may return
- // `ERROR_ACCESS_DENIED` when the process has exited, but hasn't been
- // completely cleaned up yet and its `pid` is still valid.
- (Deno.build.os === "windows" &&
- error instanceof Deno.errors.PermissionDenied),
- );
-
- p.close();
- },
-);
-
-Deno.test({ permissions: { run: false } }, function killPermissions() {
- assertThrows(() => {
- // Unlike the other test cases, we don't have permission to spawn a
- // subprocess we can safely kill. Instead we send SIGCONT to the current
- // process - assuming that Deno does not have a special handler set for it
- // and will just continue even if a signal is erroneously sent.
- Deno.kill(Deno.pid, "SIGCONT");
- }, Deno.errors.PermissionDenied);
-});
-
-Deno.test(
- { ignore: Deno.build.os !== "windows", permissions: { run: true } },
- function negativePidInvalidWindows() {
- assertThrows(() => {
- Deno.kill(-1, "SIGTERM");
- }, TypeError);
- },
-);
-
-Deno.test(
- { ignore: Deno.build.os !== "windows", permissions: { run: true } },
- function invalidSignalNameWindows() {
- assertThrows(() => {
- Deno.kill(Deno.pid, "SIGUSR1");
- }, TypeError);
- },
-);
-
-Deno.test(
- { permissions: { run: true, read: true } },
- async function killSuccess() {
- // deno-lint-ignore no-deprecated-deno-api
- const p = Deno.run({
- cmd: [Deno.execPath(), "eval", "setTimeout(() => {}, 10000)"],
- });
-
- try {
- Deno.kill(p.pid, "SIGKILL");
- const status = await p.status();
-
- assertEquals(status.success, false);
- if (Deno.build.os === "windows") {
- assertEquals(status.code, 1);
- assertEquals(status.signal, undefined);
- } else {
- assertEquals(status.code, 137);
- assertEquals(status.signal, 9);
- }
- } finally {
- p.close();
- }
- },
-);
-
-Deno.test({ permissions: { run: true, read: true } }, function killFailed() {
- // deno-lint-ignore no-deprecated-deno-api
- const p = Deno.run({
- cmd: [Deno.execPath(), "eval", "setTimeout(() => {}, 10000)"],
- });
- assert(!p.stdin);
- assert(!p.stdout);
-
- assertThrows(() => {
- // @ts-expect-error testing runtime error of bad signal
- Deno.kill(p.pid, "foobar");
- }, TypeError);
-
- p.close();
-});
-
-Deno.test(
- { permissions: { run: true, read: true, env: true } },
- async function clearEnv(): Promise<void> {
- // deno-lint-ignore no-deprecated-deno-api
- const p = Deno.run({
- cmd: [
- Deno.execPath(),
- "eval",
- "-p",
- "JSON.stringify(Deno.env.toObject())",
- ],
- stdout: "piped",
- clearEnv: true,
- env: {
- FOO: "23147",
- },
- });
-
- const obj = JSON.parse(new TextDecoder().decode(await p.output()));
-
- // can't check for object equality because the OS may set additional env
- // vars for processes, so we check if PATH isn't present as that is a common
- // env var across OS's and isn't set for processes.
- assertEquals(obj.FOO, "23147");
- assert(!("PATH" in obj));
-
- p.close();
- },
-);
-
-Deno.test(
- {
- permissions: { run: true, read: true },
- ignore: Deno.build.os === "windows",
- },
- async function uid(): Promise<void> {
- // deno-lint-ignore no-deprecated-deno-api
- const p = Deno.run({
- cmd: [
- "id",
- "-u",
- ],
- stdout: "piped",
- });
-
- const currentUid = new TextDecoder().decode(await p.output());
- p.close();
-
- if (currentUid !== "0") {
- assertThrows(() => {
- // deno-lint-ignore no-deprecated-deno-api
- Deno.run({
- cmd: [
- "echo",
- "fhqwhgads",
- ],
- uid: 0,
- });
- }, Deno.errors.PermissionDenied);
- }
- },
-);
-
-Deno.test(
- {
- permissions: { run: true, read: true },
- ignore: Deno.build.os === "windows",
- },
- async function gid(): Promise<void> {
- // deno-lint-ignore no-deprecated-deno-api
- const p = Deno.run({
- cmd: [
- "id",
- "-g",
- ],
- stdout: "piped",
- });
-
- const currentGid = new TextDecoder().decode(await p.output());
- p.close();
-
- if (currentGid !== "0") {
- assertThrows(() => {
- // deno-lint-ignore no-deprecated-deno-api
- Deno.run({
- cmd: [
- "echo",
- "fhqwhgads",
- ],
- gid: 0,
- });
- }, Deno.errors.PermissionDenied);
- }
- },
-);
-
-Deno.test(
- {
- permissions: { run: true, read: true, write: true },
- ignore: Deno.build.os === "windows",
- },
- async function non_existent_cwd(): Promise<void> {
- // deno-lint-ignore no-deprecated-deno-api
- const p = Deno.run({
- cmd: [
- Deno.execPath(),
- "eval",
- `const dir = Deno.makeTempDirSync();
- Deno.chdir(dir);
- Deno.removeSync(dir);
- const p = Deno.run({cmd:[Deno.execPath(), "eval", "console.log(1);"]});
- const { code } = await p.status();
- p.close();
- Deno.exit(code);
- `,
- ],
- stdout: "piped",
- stderr: "piped",
- });
-
- const { code } = await p.status();
- const stderr = new TextDecoder().decode(await p.stderrOutput());
- p.close();
- p.stdout.close();
- assertStrictEquals(code, 1);
- assertStringIncludes(stderr, "Failed getting cwd.");
- },
-);