mirror of
https://gitlab.com/veilid/veilid.git
synced 2024-11-25 18:20:41 -06:00
(wasm) basic working unit tests
This commit is contained in:
parent
6b7301a963
commit
5aeda006a4
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -5879,6 +5879,7 @@ dependencies = [
|
|||||||
"gloo-utils 0.2.0",
|
"gloo-utils 0.2.0",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
|
"parking_lot 0.12.1",
|
||||||
"send_wrapper 0.6.0",
|
"send_wrapper 0.6.0",
|
||||||
"serde",
|
"serde",
|
||||||
"serde-wasm-bindgen",
|
"serde-wasm-bindgen",
|
||||||
|
@ -39,3 +39,4 @@ serde-wasm-bindgen = "0.5.0"
|
|||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
wasm-bindgen-test = "^0"
|
wasm-bindgen-test = "^0"
|
||||||
|
parking_lot = "0.12.1"
|
||||||
|
@ -1,182 +1,218 @@
|
|||||||
//! Test suite for the Web and headless browsers.
|
//! Test suite for the Web and headless browsers.
|
||||||
|
//! These tests only work with WASM_BINDGEN_USE_NO_MODULE=true env var,
|
||||||
//XXXXXXXXXXXXXXX
|
//! as otherwise there's no way to access the generated wasm bindings from inside JS.
|
||||||
//XXX DOES NOT WORK.
|
|
||||||
|
|
||||||
#![cfg(target_arch = "wasm32")]
|
#![cfg(target_arch = "wasm32")]
|
||||||
|
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
extern crate wasm_bindgen_test;
|
extern crate wasm_bindgen_test;
|
||||||
use core::sync::atomic::AtomicBool;
|
use js_sys::*;
|
||||||
|
use parking_lot::Once;
|
||||||
use veilid_wasm::*;
|
use veilid_wasm::*;
|
||||||
|
use wasm_bindgen::*;
|
||||||
|
use wasm_bindgen_futures::*;
|
||||||
use wasm_bindgen_test::*;
|
use wasm_bindgen_test::*;
|
||||||
|
|
||||||
wasm_bindgen_test_configure!(run_in_browser);
|
wasm_bindgen_test_configure!(run_in_browser);
|
||||||
|
|
||||||
static SETUP_ONCE: AtomicBool = AtomicBool::new(false);
|
static SETUP_ONCE: Once = Once::new();
|
||||||
pub fn setup() -> () {
|
pub fn setup() -> () {
|
||||||
if SETUP_ONCE
|
SETUP_ONCE.call_once(|| {
|
||||||
.compare_exchange(false, true, Ordering::Relaxed, Ordering::Relaxed)
|
console_log!("setup()");
|
||||||
.is_ok()
|
|
||||||
{
|
|
||||||
console_log("setup()");
|
|
||||||
console_error_panic_hook::set_once();
|
console_error_panic_hook::set_once();
|
||||||
wasm_logger::init(wasm_logger::Config::new(Level::Trace));
|
|
||||||
init_callbacks();
|
init_callbacks();
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
// xxx needs updating to new keys and veilid_api object
|
|
||||||
fn init_callbacks() {
|
fn init_callbacks() {
|
||||||
assert_eq!(js_sys::eval(r#"
|
assert_eq!(js_sys::eval(r#"
|
||||||
window.sleep = (milliseconds) => { return new Promise(resolve => setTimeout(resolve, milliseconds)) };
|
window.sleep = (milliseconds) => { return new Promise(resolve => setTimeout(resolve, milliseconds)) };
|
||||||
window.stateChangeCallback = async (stateChange) => { console.log("State change: " + stateChange); };
|
window.stateChangeCallback = async (stateChange) => {
|
||||||
window.configCallback = (configKey) => {
|
delete stateChange.peers; // makes logs less verbose
|
||||||
switch(configKey) {
|
console.log("State change: ", JSON.stringify(stateChange, null, 2));
|
||||||
case "namespace": return "";
|
|
||||||
case "capabilities.disable": return [];
|
|
||||||
case "tablestore.directory": return "";
|
|
||||||
case "network.routing_table.node_id": return [];
|
|
||||||
case "network.routing_table.node_id_secret": return [];
|
|
||||||
case "network.routing_table.bootstrap": return [];
|
|
||||||
case "network.routing_table.limit_over_attached": return 64;
|
|
||||||
case "network.routing_table.limit_fully_attached": return 32;
|
|
||||||
case "network.routing_table.limit_attached_strong": return 16;
|
|
||||||
case "network.routing_table.limit_attached_good": return 8;
|
|
||||||
case "network.routing_table.limit_attached_weak": return 4;
|
|
||||||
case "network.rpc.concurrency": return 2;
|
|
||||||
case "network.rpc.queue_size": return 128;
|
|
||||||
case "network.rpc.max_timestamp_behind": return 10000000;
|
|
||||||
case "network.rpc.max_timestamp_ahead": return 10000000;
|
|
||||||
case "network.rpc.timeout": return 10000000;
|
|
||||||
case "network.rpc.max_route_hop_count": return 4;
|
|
||||||
case "network.rpc.default_route_hop_count": return 1;
|
|
||||||
case "network.dht.max_find_node_count": return 20;
|
|
||||||
case "network.dht.resolve_node_timeout": return 10000;
|
|
||||||
case "network.dht.resolve_node_count": return 1;
|
|
||||||
case "network.dht.resolve_node_fanout": return 4;
|
|
||||||
case "network.dht.get_value_timeout": return 10000;
|
|
||||||
case "network.dht.get_value_count": return 3;
|
|
||||||
case "network.dht.get_value_fanout": return 4;
|
|
||||||
case "network.dht.set_value_timeout": return 10000;
|
|
||||||
case "network.dht.set_value_count": return 5;
|
|
||||||
case "network.dht.set_value_fanout": return 4;
|
|
||||||
case "network.dht.min_peer_count": return 20;
|
|
||||||
case "network.dht.min_peer_refresh_time": return 2000000;
|
|
||||||
case "network.dht.validate_dial_info_receipt_time": return 5000000;
|
|
||||||
case "network.upnp": return false;
|
|
||||||
case "network.detect_address_changes": return true;
|
|
||||||
case "network.address_filter": return true;
|
|
||||||
case "network.restricted_nat_retries": return 3;
|
|
||||||
case "network.tls.certificate_path": return "";
|
|
||||||
case "network.tls.private_key_path": return "";
|
|
||||||
case "network.application.path": return "/app";
|
|
||||||
case "network.application.https.enabled": return false;
|
|
||||||
case "network.application.https.listen_address": return "";
|
|
||||||
case "network.application.http.enabled": return false;
|
|
||||||
case "network.application.http.listen_address": return "";
|
|
||||||
case "network.protocol.udp.enabled": return false;
|
|
||||||
case "network.protocol.udp.socket_pool_size": return 0;
|
|
||||||
case "network.protocol.udp.listen_address": return "";
|
|
||||||
case "network.protocol.udp.public_address": return "";
|
|
||||||
case "network.protocol.tcp.connect": return false;
|
|
||||||
case "network.protocol.tcp.listen": return false;
|
|
||||||
case "network.protocol.tcp.max_connections": return 32;
|
|
||||||
case "network.protocol.tcp.listen_address": return "";
|
|
||||||
case "network.protocol.tcp.public_address": return "";
|
|
||||||
case "network.protocol.ws.connect": return true;
|
|
||||||
case "network.protocol.ws.listen": return false;
|
|
||||||
case "network.protocol.ws.max_connections": return 16;
|
|
||||||
case "network.protocol.ws.listen_address": return "";
|
|
||||||
case "network.protocol.ws.path": return "/ws";
|
|
||||||
case "network.protocol.ws.public_address": return "";
|
|
||||||
case "network.protocol.wss.connect": return true;
|
|
||||||
case "network.protocol.wss.listen": return false;
|
|
||||||
case "network.protocol.wss.max_connections": return 16;
|
|
||||||
case "network.protocol.wss.listen_address": return "";
|
|
||||||
case "network.protocol.wss.path": return "/ws";
|
|
||||||
case "network.protocol.wss.public_address": return "";
|
|
||||||
default:
|
|
||||||
console.log("config key '" + key +"' doesn't exist"); break;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
window.veilidCoreInitConfig = {
|
||||||
|
logging: {
|
||||||
|
api: {
|
||||||
|
enabled: true,
|
||||||
|
level: 'Info',
|
||||||
|
},
|
||||||
|
performance: {
|
||||||
|
enabled: false,
|
||||||
|
level: 'Info',
|
||||||
|
logs_in_timings: false,
|
||||||
|
logs_in_console: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
window.veilidCoreStartupConfig = {
|
||||||
|
program_name: 'veilid-wasm-test',
|
||||||
|
namespace: '',
|
||||||
|
capabilities: {
|
||||||
|
disable: [],
|
||||||
|
},
|
||||||
|
protected_store: {
|
||||||
|
allow_insecure_fallback: true,
|
||||||
|
always_use_insecure_storage: true,
|
||||||
|
directory: '',
|
||||||
|
delete: false,
|
||||||
|
device_encryption_key_password: 'some-user-secret-value',
|
||||||
|
// "new_device_encryption_key_password": "an-updated-user-secret-value"
|
||||||
|
},
|
||||||
|
table_store: {
|
||||||
|
directory: '',
|
||||||
|
delete: false,
|
||||||
|
},
|
||||||
|
block_store: {
|
||||||
|
directory: '',
|
||||||
|
delete: false,
|
||||||
|
},
|
||||||
|
network: {
|
||||||
|
connection_initial_timeout_ms: 2000,
|
||||||
|
connection_inactivity_timeout_ms: 60000,
|
||||||
|
max_connections_per_ip4: 32,
|
||||||
|
max_connections_per_ip6_prefix: 32,
|
||||||
|
max_connections_per_ip6_prefix_size: 56,
|
||||||
|
max_connection_frequency_per_min: 128,
|
||||||
|
client_whitelist_timeout_ms: 300000,
|
||||||
|
reverse_connection_receipt_time_ms: 5000,
|
||||||
|
hole_punch_receipt_time_ms: 5000,
|
||||||
|
network_key_password: '',
|
||||||
|
disable_capabilites: [],
|
||||||
|
routing_table: {
|
||||||
|
node_id: [],
|
||||||
|
node_id_secret: [],
|
||||||
|
bootstrap: [
|
||||||
|
'ws://bootstrap.veilid.net:5150/ws',
|
||||||
|
],
|
||||||
|
limit_over_attached: 64,
|
||||||
|
limit_fully_attached: 32,
|
||||||
|
limit_attached_strong: 16,
|
||||||
|
limit_attached_good: 8,
|
||||||
|
limit_attached_weak: 4,
|
||||||
|
},
|
||||||
|
rpc: {
|
||||||
|
concurrency: 0,
|
||||||
|
queue_size: 1024,
|
||||||
|
max_timestamp_behind_ms: 10000,
|
||||||
|
max_timestamp_ahead_ms: 10000,
|
||||||
|
timeout_ms: 5000,
|
||||||
|
max_route_hop_count: 4,
|
||||||
|
default_route_hop_count: 1,
|
||||||
|
},
|
||||||
|
dht: {
|
||||||
|
max_find_node_count: 20,
|
||||||
|
resolve_node_timeout_ms: 10000,
|
||||||
|
resolve_node_count: 1,
|
||||||
|
resolve_node_fanout: 4,
|
||||||
|
get_value_timeout_ms: 10000,
|
||||||
|
get_value_count: 3,
|
||||||
|
get_value_fanout: 4,
|
||||||
|
set_value_timeout_ms: 10000,
|
||||||
|
set_value_count: 5,
|
||||||
|
set_value_fanout: 4,
|
||||||
|
min_peer_count: 20,
|
||||||
|
min_peer_refresh_time_ms: 60000,
|
||||||
|
validate_dial_info_receipt_time_ms: 2000,
|
||||||
|
local_subkey_cache_size: 128,
|
||||||
|
local_max_subkey_cache_memory_mb: 256,
|
||||||
|
remote_subkey_cache_size: 1024,
|
||||||
|
remote_max_records: 65536,
|
||||||
|
remote_max_subkey_cache_memory_mb: 256,
|
||||||
|
remote_max_storage_space_mb: 0,
|
||||||
|
},
|
||||||
|
upnp: true,
|
||||||
|
detect_address_changes: true,
|
||||||
|
restricted_nat_retries: 0,
|
||||||
|
tls: {
|
||||||
|
certificate_path: '',
|
||||||
|
private_key_path: '',
|
||||||
|
connection_initial_timeout_ms: 2000,
|
||||||
|
},
|
||||||
|
application: {
|
||||||
|
https: {
|
||||||
|
enabled: false,
|
||||||
|
listen_address: ':5150',
|
||||||
|
path: 'app',
|
||||||
|
},
|
||||||
|
http: {
|
||||||
|
enabled: false,
|
||||||
|
listen_address: ':5150',
|
||||||
|
path: 'app',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
protocol: {
|
||||||
|
udp: {
|
||||||
|
enabled: false,
|
||||||
|
socket_pool_size: 0,
|
||||||
|
listen_address: '',
|
||||||
|
},
|
||||||
|
tcp: {
|
||||||
|
connect: false,
|
||||||
|
listen: false,
|
||||||
|
max_connections: 32,
|
||||||
|
listen_address: '',
|
||||||
|
},
|
||||||
|
ws: {
|
||||||
|
connect: true,
|
||||||
|
listen: true,
|
||||||
|
max_connections: 16,
|
||||||
|
listen_address: ':5150',
|
||||||
|
path: 'ws',
|
||||||
|
},
|
||||||
|
wss: {
|
||||||
|
connect: true,
|
||||||
|
listen: false,
|
||||||
|
max_connections: 16,
|
||||||
|
listen_address: '',
|
||||||
|
path: 'ws',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
true
|
true
|
||||||
"#).expect("failed to eval"), JsValue::TRUE);
|
"#).expect("failed to eval"), JsValue::TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
/// Helper for converting an eval Promise result into a JsValue
|
||||||
///
|
async fn eval_promise(source: &str) -> JsValue {
|
||||||
|
JsFuture::from(
|
||||||
#[wasm_bindgen_test]
|
eval(source)
|
||||||
fn test_construct() {
|
.expect("Failed to eval")
|
||||||
setup();
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
js_sys::eval(
|
|
||||||
r#"
|
|
||||||
let vc = new VeilidCore();
|
|
||||||
true
|
|
||||||
"#
|
|
||||||
)
|
|
||||||
.expect("failed to eval"),
|
|
||||||
JsValue::TRUE
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[wasm_bindgen_test(async)]
|
|
||||||
async fn test_startup_shutdown() {
|
|
||||||
setup();
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
JsFuture::from(
|
|
||||||
js_sys::eval(
|
|
||||||
r#"
|
|
||||||
(async function() {
|
|
||||||
let vc = new VeilidCore();
|
|
||||||
await vc.startup(window.stateChangeCallback, window.configCallback);
|
|
||||||
await vc.shutdown();
|
|
||||||
return true;
|
|
||||||
})().then(v => {
|
|
||||||
console.log("finished: " + v);
|
|
||||||
return v;
|
|
||||||
});
|
|
||||||
"#
|
|
||||||
)
|
|
||||||
.expect("failed to eval")
|
|
||||||
.dyn_into::<Promise>()
|
.dyn_into::<Promise>()
|
||||||
.unwrap()
|
.unwrap(),
|
||||||
)
|
)
|
||||||
.await,
|
.await
|
||||||
Ok(JsValue::TRUE)
|
.unwrap()
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[wasm_bindgen_test(async)]
|
// ----------------------------------------------------------------
|
||||||
async fn test_attach_detach() {
|
|
||||||
|
// TODO: now that veilidClient uses a single instance of VeilidAPI,
|
||||||
|
// subsequent tests fail because veilidCore has already been initialized.
|
||||||
|
#[wasm_bindgen_test()]
|
||||||
|
async fn test_kitchen_sink() {
|
||||||
setup();
|
setup();
|
||||||
|
|
||||||
assert_eq!(
|
let res = eval_promise(
|
||||||
JsFuture::from(
|
r#"
|
||||||
js_sys::eval(
|
(async function () {
|
||||||
r#"
|
const { veilidClient } = wasm_bindgen; // only accessible in no_module mode.
|
||||||
(async function() {
|
veilidClient.initializeCore(window.veilidCoreInitConfig);
|
||||||
let vc = new VeilidCore();
|
await veilidClient.startupCore(window.stateChangeCallback, JSON.stringify(window.veilidCoreStartupConfig));
|
||||||
await vc.startup(window.stateChangeCallback, window.configCallback);
|
|
||||||
await vc.attach();
|
console.log(veilidClient.versionString());
|
||||||
await window.sleep(1000);
|
await veilidClient.attach();
|
||||||
await vc.detach();
|
|
||||||
await vc.shutdown();
|
await sleep(10000);
|
||||||
return true;
|
await veilidClient.detach();
|
||||||
})().then(v => {
|
await veilidClient.shutdownCore();
|
||||||
console.log("finished: " + v);
|
|
||||||
return v;
|
return true;
|
||||||
});
|
})();
|
||||||
"#
|
"#,
|
||||||
)
|
).await;
|
||||||
.expect("failed to eval")
|
|
||||||
.dyn_into::<Promise>()
|
assert_eq!(res, JsValue::TRUE);
|
||||||
.unwrap()
|
|
||||||
)
|
|
||||||
.await,
|
|
||||||
Ok(JsValue::TRUE)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
4
veilid-wasm/wasm_test.sh
Executable file
4
veilid-wasm/wasm_test.sh
Executable file
@ -0,0 +1,4 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -eo pipefail
|
||||||
|
|
||||||
|
WASM_BINDGEN_USE_NO_MODULE=true wasm-pack test --firefox "$@"
|
Loading…
Reference in New Issue
Block a user