Skip to content

Commit

Permalink
Implement ros node args loader
Browse files Browse the repository at this point in the history
  • Loading branch information
g-arjones committed Aug 4, 2019
1 parent 6e7f4ed commit 29621c2
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 0 deletions.
60 changes: 60 additions & 0 deletions src/nodeArguments.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import * as child_process from "child_process";
import * as path from "path";

export interface IArguments {
error: string;
args: string[];
env: any;
}

export class NodeArguments {
private _cachedArgs: any;
private _stderr: string;
private _helper: string[];

constructor(private _parentEnv: any, launchFile: string, nodeName: string) {
this._stderr = "";
this._helper = [
path.join(__dirname, "..", "..", "helpers", "node_args.py"),
launchFile,
nodeName,
];
}

public stderr(): string {
return this._stderr;
}

public args(): Promise<IArguments> {
if (!this._cachedArgs) { this.reload(); }
return this._cachedArgs;
}

public reload(): Promise<IArguments> {
this._stderr = "";
this._cachedArgs = new Promise((resolve, reject) => {
let stdout = "";
const processOptions: child_process.SpawnOptions = {
env: this._parentEnv,
};

const proc = child_process.spawn(this._helper[0], this._helper.slice(1), processOptions);
proc.stdout.setEncoding("utf8");
proc.stderr.setEncoding("utf8");
proc.stderr.on("data", (chunk: string) => this._stderr += chunk);
proc.stdout.on("data", (chunk: string) => stdout += chunk);
proc.on("exit", (code: number, signal: string) => {
if (code === 0) {
try {
resolve(JSON.parse(stdout));
} catch (e) {
reject(new Error("Internal error"));
}
} else {
reject(new Error(`Could not parse node arguments (code ${code})`));
}
});
});
return this._cachedArgs;
}
}
40 changes: 40 additions & 0 deletions test/nodeArguments.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import * as assert from "assert";
import { NodeArguments } from "../src/nodeArguments";
import * as helpers from "./helpers";

describe("NodeArguments", () => {
let subject: NodeArguments;
beforeEach(() => {
subject = new NodeArguments(process.env, "upload.launch", "/test_node");
(subject as any)._helper = [
"bash",
"-c",
"echo \"{ \\\"error\\\": \\\"test\\\", \\\"env\\\": \\\"foo\\\", \\\"args\\\": [\\\"bar\\\"] }\"",
];
});
describe("args()", () => {
it("returns the parsed node arguments", async () => {
const args = await subject.args();
assert.equal("test", args.error);
assert.equal("foo", args.env);
assert.deepEqual(["bar"], args.args);
});
it("returns the helper's stderr", async () => {
(subject as any)._helper = [
"bash",
"-c",
"echo test >&2; echo foo; echo bar >&2; echo test2; exit 1",
];
await helpers.assertThrowsAsync(subject.args(), /Could not parse node arguments/);
assert.equal("test\nbar\n", subject.stderr());
});
it("throws if helper output is invalid", async () => {
(subject as any)._helper = [
"bash",
"-c",
"echo test",
];
await helpers.assertThrowsAsync(subject.args(), /Internal error/);
});
});
});

0 comments on commit 29621c2

Please sign in to comment.