-
Notifications
You must be signed in to change notification settings - Fork 25
Open
Description
Hey @yuval-k, Happy easter.
The more I touch this project, the more I get excited about the possibilities... :D
I wanted to open a discussion with you about the project unit tests/integration tests.
First, just wanted to say that we need to find a way to create some unit tests for the project. I couldn't find the time to study that in detail, but maybe we can use a library like https://github.com/jtenner/as-pect.
But, what I really wanted to share is that I converted your example of integration tests implemented in an HTML file to a javascript file that can be triggered using node. Take a look at my example below:
const assert = require("assert");
const fs = require("fs");
const loader = require("@assemblyscript/loader");
const util = require('util');
const utf8Decoder = new util.TextDecoder('utf-8');
/**
* This function is used to inject values into Web Assembly VM memory.
*
* @param {String} value - value to be injected into WebAssembly memory
* @param {Number} value_ptr_ptr - pointer to the memory address that starts this variable
* @param {Number} value_size_ptr - pointer to the memory address with variable size
*/
function injectStringIntoMemory(value, value_ptr_ptr, value_size_ptr) {
const value_size = value.length;
let bytes = globalExports.malloc(value_size);
if (bytes === 0) {
throw "can't allocate";
}
var moduleMemory = globalExports.memory.buffer;
var confMem = new Uint8Array(moduleMemory, bytes, value_size);
for(let i = 0; i < value_size; i++){
confMem[i]=value.charCodeAt(i);
}
var confPtr = new Uint32Array(moduleMemory, value_ptr_ptr, 1);
confPtr[0] = bytes;
var confSizePtr = new Uint32Array(moduleMemory, value_size_ptr, 1);
confSizePtr[0] = value_size;
console.info("injectStringIntoMemory: " + value + " to " + value_ptr_ptr + ":" + value_size_ptr);
}
//Mocks and hardcoded values
const root_id_string = "expo_filter_root_id"
const config = "expo_filter_configuration_value1";
const imports = {
wasi_unstable: {
proc_exit: console.trace
},
env: {
memory: new WebAssembly.Memory({
initial: 1,
maximum: 1
}),
abort: console.trace,
proxy_log(level, logMessage, messageSize) {
var mem = new Uint8Array(globalExports.memory.buffer);
let buf = mem.slice(logMessage, logMessage + messageSize);
let msg = "proxy_log: " + utf8Decoder.decode(buf);
switch(level) {
case 1: {
console.debug(msg);
break;
}
case 2: {
console.info(msg);
break;
}
case 3: {
console.warn(msg);
break;
}
case 4: {
console.error(msg);
break;
}
default: {
console.trace(msg);
break;
}
}
return 0;
},
proxy_get_configuration(configuration_ptr, configuration_size) {
console.debug("proxy_get_configuration: " + config + ":" + configuration_ptr + ":" + configuration_size);
injectStringIntoMemory(config, configuration_ptr, configuration_size);
return config;
},
proxy_get_property(path_ptr, path_size, value_ptr_ptr, value_size_ptr) {
// we only support one property now, the root id.
const prop = root_id_string;
console.debug("proxy_get_property: " + prop + ":" + path_ptr + "-" + path_size + ":" + value_ptr_ptr + "-" + value_size_ptr);
injectStringIntoMemory(prop, value_ptr_ptr, value_size_ptr);
return prop;
},
proxy_get_status: console.trace,
proxy_set_tick_period_milliseconds: console.trace,
proxy_get_current_time_nanoseconds: console.trace,
proxy_set_property: console.trace,
proxy_continue_request: console.trace,
proxy_continue_response: console.trace,
proxy_send_local_response: console.trace,
proxy_clear_route_cache: console.trace,
proxy_get_shared_data: console.trace,
proxy_set_shared_data: console.trace,
proxy_register_shared_queue: console.trace,
proxy_resolve_shared_queue: console.trace,
proxy_dequeue_shared_queue: console.trace,
proxy_enqueue_shared_queue: console.trace,
proxy_add_header_map_value: console.trace,
proxy_get_header_map_value: console.trace,
proxy_get_header_map_pairs: console.trace,
proxy_set_header_map_pairs: console.trace,
proxy_replace_header_map_value: console.trace,
proxy_remove_header_map_value: console.trace,
proxy_get_header_map_size: console.trace,
proxy_get_buffer_bytes: console.trace,
proxy_get_buffer_status: console.trace,
proxy_http_call: console.trace,
proxy_grpc_call: console.trace,
proxy_grpc_stream: console.trace,
proxy_grpc_cancel: console.trace,
proxy_grpc_close: console.trace,
proxy_grpc_send: console.trace,
proxy_define_metric: console.trace,
proxy_increment_metric: console.trace,
proxy_record_metric: console.trace,
proxy_get_metric: console.trace,
proxy_set_effective_context: console.trace,
proxy_done: console.trace
}
}
/**
* Simple Unit test to check if the Filter can be initialized using wasm and making calls the proxy makes to initialize them.
*/
function testModuleLoading() {
var wasm = loader.instantiateSync(fs.readFileSync(__dirname + "/../build/untouched.wasm"), imports);
let exports = wasm;
globalExports = exports;
let context_id = 0;
const root_context_id = context_id++;
// Proxy calling Filter to initialize context
exports.proxy_on_context_create(context_id, root_context_id);
// Proxy calling Filter when VM is starting
assert(exports.proxy_on_vm_start(context_id, root_context_id) === 1, "Failed to start VM.");
// Initializing Filter
assert(exports.proxy_on_configure(context_id++, config.length) === 1, "Failed to start filter");
fs.writeFileSync("tests/memory.dump", new DataView(exports.memory.buffer, 0, exports.memory.buffer.byteLength));
//Trying to trigger a request to the filter
//const headers = [{"x-wmt-expo":"test"}];
//exports.proxy_on_context_create(context_id, root_context_id);
//let result = exports.proxy_on_request_headers(context_id, null);
//console.log(result);
};
testModuleLoading();
This way, we can trigger the tests by just running the "node tests" command.
Thanks,
Mario
Metadata
Metadata
Assignees
Labels
No labels