2019-02-19 21:30:56 +00:00
|
|
|
import { ChildProcess } from "child_process";
|
|
|
|
import * as path from "path";
|
|
|
|
import { Readable } from "stream";
|
|
|
|
import * as util from "util";
|
|
|
|
import { createClient } from "@coder/protocol/test";
|
2019-03-26 18:01:25 +00:00
|
|
|
import { Module } from "../src/common/proxy";
|
2019-02-19 21:30:56 +00:00
|
|
|
|
|
|
|
describe("child_process", () => {
|
2019-03-26 18:01:25 +00:00
|
|
|
const client = createClient();
|
|
|
|
const cp = client.modules[Module.ChildProcess];
|
|
|
|
|
2019-02-19 21:30:56 +00:00
|
|
|
const getStdout = async (proc: ChildProcess): Promise<string> => {
|
2019-04-24 15:38:21 +00:00
|
|
|
return new Promise((r): Readable => proc.stdout!.once("data", r))
|
2019-02-19 21:30:56 +00:00
|
|
|
.then((s) => s.toString());
|
|
|
|
};
|
|
|
|
|
|
|
|
describe("exec", () => {
|
|
|
|
it("should get exec stdout", async () => {
|
|
|
|
await expect(util.promisify(cp.exec)("echo test", { encoding: "utf8" }))
|
|
|
|
.resolves.toEqual({
|
|
|
|
stdout: "test\n",
|
|
|
|
stderr: "",
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe("spawn", () => {
|
|
|
|
it("should get spawn stdout", async () => {
|
|
|
|
const proc = cp.spawn("echo", ["test"]);
|
|
|
|
await expect(Promise.all([
|
|
|
|
getStdout(proc),
|
|
|
|
new Promise((r): ChildProcess => proc.on("exit", r)),
|
|
|
|
]).then((values) => values[0])).resolves.toEqual("test\n");
|
|
|
|
});
|
|
|
|
|
|
|
|
it("should cat", async () => {
|
|
|
|
const proc = cp.spawn("cat", []);
|
|
|
|
expect(proc.pid).toBe(-1);
|
2019-04-02 22:44:28 +00:00
|
|
|
proc.stdin!.write("banana");
|
2019-02-19 21:30:56 +00:00
|
|
|
await expect(getStdout(proc)).resolves.toBe("banana");
|
|
|
|
|
2019-04-02 22:44:28 +00:00
|
|
|
proc.stdin!.end();
|
2019-02-19 21:30:56 +00:00
|
|
|
proc.kill();
|
|
|
|
|
|
|
|
expect(proc.pid).toBeGreaterThan(-1);
|
|
|
|
await new Promise((r): ChildProcess => proc.on("exit", r));
|
|
|
|
});
|
|
|
|
|
|
|
|
it("should print env", async () => {
|
|
|
|
const proc = cp.spawn("env", [], {
|
|
|
|
env: { hi: "donkey" },
|
|
|
|
});
|
|
|
|
|
|
|
|
await expect(getStdout(proc)).resolves.toContain("hi=donkey\n");
|
|
|
|
});
|
2019-04-04 23:24:21 +00:00
|
|
|
|
|
|
|
it("should eval", async () => {
|
|
|
|
const proc = cp.spawn("node", ["-e", "console.log('foo')"]);
|
|
|
|
await expect(getStdout(proc)).resolves.toContain("foo");
|
|
|
|
});
|
2019-02-19 21:30:56 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
describe("fork", () => {
|
|
|
|
it("should echo messages", async () => {
|
|
|
|
const proc = cp.fork(path.join(__dirname, "forker.js"));
|
|
|
|
|
|
|
|
proc.send({ bananas: true });
|
|
|
|
|
|
|
|
await expect(new Promise((r): ChildProcess => proc.on("message", r)))
|
|
|
|
.resolves.toMatchObject({
|
|
|
|
bananas: true,
|
|
|
|
});
|
|
|
|
|
|
|
|
proc.kill();
|
|
|
|
|
|
|
|
await new Promise((r): ChildProcess => proc.on("exit", r));
|
|
|
|
});
|
|
|
|
});
|
2019-03-26 18:01:25 +00:00
|
|
|
|
|
|
|
it("should dispose", (done) => {
|
|
|
|
setTimeout(() => {
|
|
|
|
client.dispose();
|
|
|
|
done();
|
|
|
|
}, 100);
|
|
|
|
});
|
|
|
|
|
|
|
|
it("should disconnect", async () => {
|
|
|
|
const client = createClient();
|
|
|
|
const cp = client.modules[Module.ChildProcess];
|
|
|
|
const proc = cp.fork(path.join(__dirname, "forker.js"));
|
|
|
|
const fn = jest.fn();
|
|
|
|
proc.on("error", fn);
|
|
|
|
|
|
|
|
proc.send({ bananas: true });
|
|
|
|
await expect(new Promise((r): ChildProcess => proc.on("message", r)))
|
|
|
|
.resolves.toMatchObject({
|
|
|
|
bananas: true,
|
|
|
|
});
|
|
|
|
|
|
|
|
client.dispose();
|
|
|
|
expect(fn).toHaveBeenCalledWith(new Error("disconnected"));
|
|
|
|
});
|
2019-02-19 21:30:56 +00:00
|
|
|
});
|