wasm unit tests work and attachment manager fix

This commit is contained in:
Christien Rioux 2024-03-14 21:30:09 -04:00
parent ff28273a59
commit ee54358c27
11 changed files with 195 additions and 172 deletions

View file

@ -12,7 +12,7 @@ import {
veilidCrypto,
} from 'veilid-wasm';
import { textEncoder, textDecoder } from './utils/marshalling-utils';
import { waitForMs } from './utils/wait-utils';
import { asyncCallWithTimeout, waitForPublicAttachment } from './utils/wait-utils';
describe('VeilidRoutingContext', () => {
before('veilid startup', async () => {
@ -23,10 +23,12 @@ describe('VeilidRoutingContext', () => {
// }
}, JSON.stringify(veilidCoreStartupConfig));
await veilidClient.attach();
await waitForMs(2000);
await asyncCallWithTimeout(waitForPublicAttachment(), 10000);
//console.log("---Started Up---");
});
after('veilid shutdown', async () => {
//console.log("---Shutting Down---");
await veilidClient.detach();
await veilidClient.shutdownCore();
});
@ -35,22 +37,16 @@ describe('VeilidRoutingContext', () => {
it('should create using .create()', async () => {
const routingContext = VeilidRoutingContext.create();
expect(routingContext instanceof VeilidRoutingContext).toBe(true);
routingContext.free();
});
it('should create using new', async () => {
const routingContext = new VeilidRoutingContext();
expect(routingContext instanceof VeilidRoutingContext).toBe(true);
routingContext.free();
});
it('should create with default safety', async () => {
const routingContext = VeilidRoutingContext.create().withDefaultSafety();
expect(routingContext instanceof VeilidRoutingContext).toBe(true);
routingContext.free();
});
it('should create with safety', async () => {
@ -62,16 +58,12 @@ describe('VeilidRoutingContext', () => {
},
});
expect(routingContext instanceof VeilidRoutingContext).toBe(true);
routingContext.free();
});
it('should create with sequencing', async () => {
const routingContext =
VeilidRoutingContext.create().withSequencing('EnsureOrdered');
expect(routingContext instanceof VeilidRoutingContext).toBe(true);
routingContext.free();
});
});
@ -79,19 +71,16 @@ describe('VeilidRoutingContext', () => {
let routingContext: VeilidRoutingContext;
before('create routing context', () => {
routingContext = VeilidRoutingContext.create()
.withSequencing('EnsureOrdered');
routingContext = VeilidRoutingContext.create().withSafety({
Unsafe: 'EnsureOrdered',
});
});
after('free routing context', () => {
routingContext.free();
});
describe('DHT kitchen sink', async () => {
describe('DHT kitchen sink', () => {
let dhtRecord: DHTRecordDescriptor;
const data = '🚀 This example DHT data with unicode a Ā 𐀀 文 🚀';
before('create dht record', async () => {
beforeEach('create dht record', async () => {
const bestKind = veilidCrypto.bestCryptoKind();
dhtRecord = await routingContext.createDhtRecord(
{
@ -107,7 +96,7 @@ describe('VeilidRoutingContext', () => {
expect(dhtRecord.schema).toEqual({ kind: 'DFLT', o_cnt: 1 });
});
after('free dht record', async () => {
afterEach('free dht record', async () => {
await routingContext.deleteDhtRecord(dhtRecord.key);
});
@ -121,6 +110,14 @@ describe('VeilidRoutingContext', () => {
});
it('should get value with force refresh', async () => {
const setValueRes = await routingContext.setDhtValue(
dhtRecord.key,
0,
textEncoder.encode(data)
);
expect(setValueRes).toBeUndefined();
const getValueRes = await routingContext.getDhtValue(
dhtRecord.key,
0,
@ -192,6 +189,57 @@ describe('VeilidRoutingContext', () => {
);
expect(setValueRes).toBeUndefined();
});
it('should watch value and cancel watch', async () => {
const setValueRes = await routingContext.setDhtValue(
dhtRecord.key,
0,
textEncoder.encode(data)
);
expect(setValueRes).toBeUndefined();
// With typical values
const watchValueRes = await routingContext.watchDhtValues(
dhtRecord.key,
[[0, 0]],
"0",
0xFFFFFFFF,
);
expect(watchValueRes).toBeDefined();
expect(watchValueRes).not.toEqual("");
expect(watchValueRes).not.toEqual("0");
const cancelValueRes = await routingContext.cancelDhtWatch(
dhtRecord.key,
[],
)
expect(cancelValueRes).toEqual(false);
});
it('should watch value and cancel watch with default values', async () => {
const setValueRes = await routingContext.setDhtValue(
dhtRecord.key,
0,
textEncoder.encode(data)
);
expect(setValueRes).toBeUndefined();
// Again with default values
const watchValueRes = await routingContext.watchDhtValues(
dhtRecord.key,
);
expect(watchValueRes).toBeDefined();
expect(watchValueRes).not.toEqual("");
expect(watchValueRes).not.toEqual("0");
const cancelValueRes = await routingContext.cancelDhtWatch(
dhtRecord.key,
)
expect(cancelValueRes).toEqual(false);
});
});
});
});

View file

@ -1,4 +1,5 @@
import type { VeilidWASMConfig } from 'veilid-wasm';
import { veilidClient } from 'veilid-wasm';
export const veilidCoreInitConfig: VeilidWASMConfig = {
logging: {
@ -17,129 +18,10 @@ export const veilidCoreInitConfig: VeilidWASMConfig = {
},
};
export const 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_allowlist_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,
public_watch_limit: 32,
member_watch_limit: 8,
max_watch_expiration_ms: 600000,
},
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',
},
},
},
};
export var veilidCoreStartupConfig = (() => {
var defaultConfig = JSON.parse(veilidClient.defaultConfig());
defaultConfig.program_name = 'veilid-wasm-test';
defaultConfig.network.routing_table.bootstrap = ['ws://bootstrap.dev.veilid.net:5150/ws'];
defaultConfig.network.network_key_password = 'dev';
return defaultConfig;
})();

View file

@ -1,3 +1,61 @@
import { veilidClient } from 'veilid-wasm';
export const waitForMs = (milliseconds: number) => {
return new Promise((resolve) => setTimeout(resolve, milliseconds));
};
export const asyncCallWithTimeout = async<T>(asyncPromise: Promise<T>, timeLimit: number) => {
let timeoutHandle: ReturnType<typeof setTimeout>;
const timeoutPromise = new Promise((_resolve, reject) => {
timeoutHandle = setTimeout(
() => reject(new Error('Async call timeout limit reached')),
timeLimit
);
});
return Promise.race([asyncPromise, timeoutPromise]).then(result => {
clearTimeout(timeoutHandle);
return result;
})
}
export const waitForPublicAttachment = async () => {
while (true) {
let state = await veilidClient.getState();
if (state.attachment.public_internet_ready) {
var attached = false
switch (state.attachment.state) {
case "Detached":
case "Detaching":
case "Attaching":
break;
default:
attached = true;
break;
}
if (attached) {
break;
}
}
await waitForMs(1000);
}
}
export const waitForDetached = async () => {
while (true) {
let state = await veilidClient.getState();
var detached = false
switch (state.attachment.state) {
case "Detached":
detached = true;
break;
default:
break;
}
if (detached) {
break;
}
await waitForMs(1000);
}
}

View file

@ -6,29 +6,29 @@ import {
} from './utils/veilid-config';
import { VeilidState, veilidClient } from 'veilid-wasm';
import { waitForMs } from './utils/wait-utils';
import { asyncCallWithTimeout, waitForPublicAttachment } from './utils/wait-utils';
describe('veilidClient', () => {
before('veilid startup', async () => {
describe('veilidClient', function () {
before('veilid startup', async function () {
veilidClient.initializeCore(veilidCoreInitConfig);
await veilidClient.startupCore((_update) => {
await veilidClient.startupCore(function (_update) {
// if (_update.kind === 'Log') {
// console.log(_update.message);
// }
}, JSON.stringify(veilidCoreStartupConfig));
});
after('veilid shutdown', async () => {
after('veilid shutdown', async function () {
await veilidClient.shutdownCore();
});
it('should print version', async () => {
it('should print version', async function () {
const version = veilidClient.versionString();
expect(typeof version).toBe('string');
expect(version.length).toBeGreaterThan(0);
});
it('should get config string', async () => {
it('should get config string', async function () {
const defaultConfig = veilidClient.defaultConfig();
expect(typeof defaultConfig).toBe('string');
expect(defaultConfig.length).toBeGreaterThan(0);
@ -41,29 +41,32 @@ describe('veilidClient', () => {
expect(defaultConfigStr).toEqual(defaultConfigStr2);
});
it('should attach and detach', async () => {
it('should attach and detach', async function () {
await veilidClient.attach();
await waitForMs(2000);
await asyncCallWithTimeout(waitForPublicAttachment(), 10000);
await veilidClient.detach();
});
describe('kitchen sink', () => {
before('attach', async () => {
describe('kitchen sink', function () {
before('attach', async function () {
await veilidClient.attach();
await waitForMs(2000);
await waitForPublicAttachment();
});
after('detach', async function () {
await veilidClient.detach();
});
after('detach', () => veilidClient.detach());
let state: VeilidState;
it('should get state', async () => {
it('should get state', async function () {
state = await veilidClient.getState();
expect(state.attachment).toBeDefined();
expect(state.config.config).toBeDefined();
expect(state.network).toBeDefined();
});
it('should call debug command', async () => {
it('should call debug command', async function () {
const response = await veilidClient.debug('txtrecord');
expect(response).toBeDefined();
expect(response.length).toBeGreaterThan(0);

View file

@ -142,7 +142,7 @@ describe('veilidCrypto', () => {
}).not.toThrow();
});
describe('contants', () => {
describe('constants', () => {
it('CRYPTO_KEY_LENGTH', () => {
expect(typeof veilidCrypto.CRYPTO_KEY_LENGTH).toBe('number');
});