Add WebUSB testing via node-usb

This commit is contained in:
Ingvar Stepanyan
2023-11-25 01:13:42 +00:00
committed by Tormod Volden
parent 9de0fefb31
commit fd315026f4
10 changed files with 99 additions and 3 deletions

1
.gitignore vendored
View File

@@ -7,6 +7,7 @@ Makefile.in
*.lo
*.o
*.js
!/tests/webusb-test-shim/*.js
*.wasm
*.html
libtool

View File

@@ -3,6 +3,7 @@
set -e
builddir=
scriptdir=$(dirname $(readlink -f "$0"))
install=no
test=yes
asan=yes
@@ -79,6 +80,8 @@ echo "Building ..."
make -j4 -k
if [ "${test}" = "yes" ]; then
# Load custom shim for WebUSB tests that simulates Web environment.
export NODE_OPTIONS="--require ${scriptdir}/../tests/webusb-test-shim/"
for test_name in init_context set_option stress stress_mt; do
echo ""
echo "Running test '${test_name}' ..."

View File

@@ -227,9 +227,8 @@ windows)
LT_LDFLAGS="${LT_LDFLAGS} -avoid-version"
;;
emscripten)
AC_SUBST(EXEEXT, [.html])
# Note: LT_LDFLAGS is not enough here because we need link flags for executable.
AM_LDFLAGS="${AM_LDFLAGS} --bind -s ASYNCIFY -s ASSERTIONS -s ALLOW_MEMORY_GROWTH -s INVOKE_RUN=0 -s EXPORTED_RUNTIME_METHODS=['callMain']"
AM_LDFLAGS="${AM_LDFLAGS} --bind -s ASYNCIFY -s ASSERTIONS -s ALLOW_MEMORY_GROWTH"
;;
*)
dnl no special handling required

View File

@@ -1 +1 @@
#define LIBUSB_NANO 11826
#define LIBUSB_NANO 11827

View File

@@ -7,6 +7,14 @@ stress_mt_SOURCES = stress_mt.c
set_option_SOURCES = set_option.c testlib.c
init_context_SOURCES = init_context.c testlib.c
if OS_EMSCRIPTEN
# On the Web you can't block the main thread as this blocks the event loop itself,
# causing deadlocks when trying to use async APIs like WebUSB.
# We use the PROXY_TO_PTHREAD Emscripten's feature to move the main app to a separate thread
# where it can block safely.
stress_mt_LDFLAGS = ${AM_LDFLAGS} -s PROXY_TO_PTHREAD -s EXIT_RUNTIME
endif
noinst_HEADERS = libusb_testlib.h
noinst_PROGRAMS = stress stress_mt set_option init_context

View File

@@ -161,8 +161,12 @@ int main(void)
printf("Running multithreaded init/exit test...\n");
errs += test_multi_init(0);
#ifdef __EMSCRIPTEN__
printf("Skipping enumeration test on Emscripten. Multithreading is not supported yet.\n");
#else
printf("Running multithreaded init/exit test with enumeration...\n");
errs += test_multi_init(1);
#endif
printf("All done, %d errors\n", errs);
return errs != 0;

1
tests/webusb-test-shim/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/node_modules

View File

@@ -0,0 +1,20 @@
// It's not yet possible to automate actual Chrome's device selection, so
// for now run automated tests via Node.js WebUSB implementation.
//
// It might differ from browser one, but should be enough to catch most obvious issues.
const { WebUSB } = require('usb');
globalThis.navigator = {
usb: new WebUSB({
allowAllDevices: true
})
};
// events_posix uses Web events on the global scope (for now), but Node.js doesn't have them.
const fakeEventTarget = new EventTarget();
for (let method in fakeEventTarget) {
globalThis[method] = fakeEventTarget[method].bind(fakeEventTarget);
}

50
tests/webusb-test-shim/package-lock.json generated Normal file
View File

@@ -0,0 +1,50 @@
{
"name": "webusb-test-runner",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "webusb-test-runner",
"version": "1.0.0",
"license": "ISC",
"dependencies": {
"usb": "^2.11.0"
}
},
"node_modules/@types/w3c-web-usb": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/@types/w3c-web-usb/-/w3c-web-usb-1.0.10.tgz",
"integrity": "sha512-CHgUI5kTc/QLMP8hODUHhge0D4vx+9UiAwIGiT0sTy/B2XpdX1U5rJt6JSISgr6ikRT7vxV9EVAFeYZqUnl1gQ=="
},
"node_modules/node-addon-api": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.0.0.tgz",
"integrity": "sha512-vgbBJTS4m5/KkE16t5Ly0WW9hz46swAstv0hYYwMtbG7AznRhNyfLRe8HZAiWIpcHzoO7HxhLuBQj9rJ/Ho0ZA=="
},
"node_modules/node-gyp-build": {
"version": "4.7.0",
"resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.7.0.tgz",
"integrity": "sha512-PbZERfeFdrHQOOXiAKOY0VPbykZy90ndPKk0d+CFDegTKmWp1VgOTz2xACVbr1BjCWxrQp68CXtvNsveFhqDJg==",
"bin": {
"node-gyp-build": "bin.js",
"node-gyp-build-optional": "optional.js",
"node-gyp-build-test": "build-test.js"
}
},
"node_modules/usb": {
"version": "2.11.0",
"resolved": "https://registry.npmjs.org/usb/-/usb-2.11.0.tgz",
"integrity": "sha512-u5+NZ6DtoW8TIBtuSArQGAZZ/K15i3lYvZBAYmcgI+RcDS9G50/KPrUd3CrU8M92ahyCvg5e0gc8BDvr5Hwejg==",
"hasInstallScript": true,
"dependencies": {
"@types/w3c-web-usb": "^1.0.6",
"node-addon-api": "^7.0.0",
"node-gyp-build": "^4.5.0"
},
"engines": {
"node": ">=12.22.0 <13.0 || >=14.17.0"
}
}
}
}

View File

@@ -0,0 +1,10 @@
{
"name": "webusb-test-runner",
"private": true,
"license": "LGPL-2.1",
"main": "index.js",
"author": "Ingvar Stepanyan <me@rreverser.com>",
"dependencies": {
"usb": "^2.11.0"
}
}