Files
releases/wasm/test.js
T
Torin Sandall 90bda056b4 Add C library implementing operations for WASM
These changes add a C library that implements low-level data operations
and JSON parsing for WASM policies. The output of the WASM build process
are checked into the repository so that OPA can easily access the
bytecode for test and other purposes.

Signed-off-by: Torin Sandall <torinsandall@gmail.com>
2018-10-08 17:29:18 -07:00

114 lines
2.9 KiB
JavaScript

const { readFileSync } = require('fs');
function stringDecoder(mem) {
return function(addr) {
const i8 = new Int8Array(mem.buffer);
const start = addr;
var s = "";
while (i8[addr] != 0) {
s += String.fromCharCode(i8[addr++]);
}
return s;
}
}
function red(text) {
return '\x1b[0m\x1b[31m' + text + '\x1b[0m';
}
function green(text) {
return '\x1b[0m\x1b[32m' + text + '\x1b[0m';
}
function yellow(text) {
return '\x1b[0m\x1b[33m' + text + '\x1b[0m';
}
function namespace(cache, func, note)
{
let key = func+note;
if (key in cache) {
cache[key] += 1;
note = note + ' (' + cache[key] + ')'
} else {
cache[key] = 0;
}
return note;
}
function report(passed, error, msg) {
if (passed === true) {
if (process.env.VERBOSE === '1') {
console.log(green('PASS'), msg);
}
} else if (error === undefined) {
console.log(yellow('FAIL'), msg);
} else {
console.log(red('ERROR'), msg, error);
}
}
async function test(executable) {
const mem = new WebAssembly.Memory({initial: 5});
const addr2string = stringDecoder(mem);
let cache = {};
let failedOrErrored = 0;
let seenFuncs = {};
const module = await WebAssembly.instantiate(readFileSync(executable), {
env: {
memory: mem,
opa_println: (msg) => {
console.log(addr2string(msg));
},
opa_abort: (msg) => {
throw 'abort: ' + addr2string(msg);
},
opa_test_pass: (note, func) => {
note = addr2string(note);
func = addr2string(func);
note = namespace(cache, func, note);
seenFuncs[func] = true;
let key = func + '/' + note
report(true, undefined, key);
},
opa_test_fail: (note, func, file, line) => {
note = addr2string(note);
func = addr2string(func);
note = namespace(cache, func, note);
seenFuncs[func] = true;
let key = func + '/' + note;
failedOrErrored++;
report(false, undefined, key + ' ' + addr2string(file) + ':' + line);
},
}
});
for (let key in module.instance.exports) {
if (key.startsWith("test_")) {
try {
module.instance.exports[key]();
if (!(key in seenFuncs))
{
report(true, undefined, key);
}
} catch(e) {
report(false, e, key)
}
}
}
if (failedOrErrored > 0) {
process.exit(1);
}
}
if (process.argv.length != 3) {
console.log(process.argv[1] + " <test executable path>");
process.exit(1);
}
test(process.argv[2]);