summaryrefslogtreecommitdiffstats
path: root/tests/lib/testhelp.js
diff options
context:
space:
mode:
Diffstat (limited to 'tests/lib/testhelp.js')
-rw-r--r--tests/lib/testhelp.js121
1 files changed, 121 insertions, 0 deletions
diff --git a/tests/lib/testhelp.js b/tests/lib/testhelp.js
new file mode 100644
index 0000000..ae1ab69
--- /dev/null
+++ b/tests/lib/testhelp.js
@@ -0,0 +1,121 @@
+var Zmodem = require('./zmodem');
+
+module.exports = {
+ /**
+ * Return an array with the given number of random octet values.
+ *
+ * @param {Array} count - The number of octet values to return.
+ *
+ * @returns {Array} The octet values.
+ */
+ get_random_octets(count) {
+ if (!(count > 0)) throw( "Must be positive, not " + count );
+
+ var octets = [];
+
+ //This assigns backwards both for convenience and so that
+ //the initial assignment allocates the needed size.
+ while (count) {
+ octets[count - 1] = Math.floor( Math.random() * 256 );
+ count--;
+ }
+
+ return octets;
+ },
+
+ //This is meant NOT to do UTF-8 stuff since it handles \xXX.
+ string_to_octets(string) {
+ return string.split("").map( (c) => c.charCodeAt(0) );
+ },
+
+ make_temp_dir() {
+ return require('tmp').dirSync().name;
+ },
+
+ make_temp_file(size) {
+ const fs = require('fs');
+ const tmp = require('tmp');
+
+ var tmpobj = tmp.fileSync();
+ var content = Array(size).fill("x").join("");
+ fs.writeSync( tmpobj.fd, content );
+ fs.writeSync( tmpobj.fd, "=THE_END" );
+ fs.closeSync( tmpobj.fd );
+
+ return tmpobj.name;
+ },
+
+ make_empty_temp_file() {
+ const fs = require('fs');
+ const tmp = require('tmp');
+
+ var tmpobj = tmp.fileSync();
+ fs.closeSync( tmpobj.fd );
+
+ return tmpobj.name;
+ },
+
+ exec_lrzsz_steps(t, binpath, z_args, steps) {
+ const spawn = require('child_process').spawn;
+
+ var child;
+
+ var zsession;
+ var zsentry = new Zmodem.Sentry( {
+ to_terminal: Object,
+ on_detect: (d) => { zsession = d.confirm() },
+ on_retract: console.error.bind(console),
+ sender: (d) => {
+ child.stdin.write( new Buffer(d) );
+ },
+ } );
+
+ var step = 0;
+ var inputs = [];
+
+ child = spawn(binpath, z_args);
+ console.log("child PID:", child.pid);
+
+ child.on("error", console.error.bind(console));
+
+ child.stdin.on("close", () => console.log(`# PID ${child.pid} STDIN closed`));
+ child.stdout.on("close", () => console.log(`# PID ${child.pid} STDOUT closed`));
+ child.stderr.on("close", () => console.log(`# PID ${child.pid} STDERR closed`));
+
+ //We can’t just pipe this on through because there can be lone CR
+ //bytes which screw up TAP::Harness.
+ child.stderr.on("data", (d) => {
+ d = d.toString().replace(/\r\n?/g, "\n");
+ if (d.substr(-1) !== "\n") d += "\n";
+ process.stderr.write(`STDERR: ${d}`);
+ });
+
+ child.stdout.on("data", (d) => {
+ //console.log(`STDOUT from PID ${child.pid}`, d);
+ inputs.push( Array.from(d) );
+
+ zsentry.consume( Array.from(d) );
+
+ if (zsession) {
+ if ( steps[step] ) {
+ if ( steps[step](zsession, child) ) {
+ step++;
+ }
+ }
+ else {
+ console.log(`End of task list; closing PID ${child.pid}’s STDIN`);
+ child.stdin.end();
+ }
+ }
+ });
+
+ var exit_promise = new Promise( (res, rej) => {
+ child.on("exit", (code, signal) => {
+ console.log(`# "${binpath}" exit: code ${code}, signal ${signal}`);
+ res([code, signal]);
+ } );
+ } );
+
+ return exit_promise.then( () => { return inputs } );
+ },
+};