Skip to content

Commit

Permalink
fix: close AudioContext between tests
Browse files Browse the repository at this point in the history
  • Loading branch information
b-ma committed Jun 7, 2024
1 parent 9e7e0f8 commit 139038b
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 12 deletions.
25 changes: 19 additions & 6 deletions .scripts/wpt-harness.mjs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Blob } from 'node:buffer';
import EventEmitter from 'node:events';

import path from 'path';
import wptRunner from 'wpt-runner';
Expand All @@ -15,7 +16,7 @@ import { requestAnimationFrame, cancelAnimationFrame } from './wpt-mock/requestA
program
.option('--list', 'List the name of the test files')
.option('--with_crashtests', 'Also run crashtests')
.option('--filter <string...>', 'Filter executed OR listed test files', '.*');
.option('--filter <string...>', 'Filter executed OR listed test files', ['.*']);

program.parse(process.argv);

Expand All @@ -38,15 +39,23 @@ const wptRootPath = path.join('wpt');
const testsPath = path.join('wpt','webaudio');
const rootURL = 'webaudio';

// wpt tests are all run in the same process, but some tests using AudioContext
// do not explicitely call the `close` method. As setup is called before each test
// file we emit a glbal event so that AudioContext created in previous test file
// can close themselves. This prevents them to pile up and waste CPU
process.WPT_TEST_RUNNER = new EventEmitter();

// monkey patch `window` with our web audio API
const setup = window => {
process.WPT_TEST_RUNNER.emit('cleanup');

// monkey patch innerText with textContent
Object.defineProperty(window.HTMLScriptElement.prototype, 'innerText', {
get: function() {
return this.textContent;
},
})
// return;

// This is meant to make some idlharness tests pass:
// cf. wpt-runnner/testharness/idlharness.js line 1466-1472
// These tests, which assess the descriptor of the classes according to window,
Expand Down Expand Up @@ -106,18 +115,22 @@ const filterRe = new RegExp(`${options.filter.join('|')}`);

const filter = (name) => {
if (!options.with_crashtests && name.includes('/crashtests/')) {
return false;
return false;
}
if (name.includes('/resources/')) {
return false;
return false;
}

// TODO <https://github.com/ircam-ismm/node-web-audio-api/issues/57>
// these tests make the runner crash
if (
name.includes('the-audiocontext-interface/suspend-with-navigation.html') // timeouts
// timeouts
name.includes('the-audiocontext-interface/suspend-with-navigation.html')
// somehow crahshes the-constantsourcenode-interface/constant-source-basic.html test
// npm run wpt:only -- --filter the-channelmergernode-interface/active-processing.https.html the-constantsourcenode-interface/constant-source-basic.html
|| name.includes('the-channelmergernode-interface/active-processing.https.html')
) {
return false;
return false;
}

if (filterRe.test(name)) {
Expand Down
6 changes: 5 additions & 1 deletion js/AudioContext.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,6 @@ module.exports = function(jsExport, nativeBinding) {
});
// keep process awake until context is closed
const keepAwakeId = setInterval(() => {}, 10 * 1000);

// clear on close
this.addEventListener('statechange', () => {
if (this.state === 'closed') {
Expand All @@ -126,6 +125,11 @@ module.exports = function(jsExport, nativeBinding) {
clearTimeout(keepAwakeId);
}
});

// for wpt tests, see ./.scripts/wpt_harness.mjs for informations
if (process.WPT_TEST_RUNNER) {
process.WPT_TEST_RUNNER.once('cleanup', () => this.close());
}
}

get baseLatency() {
Expand Down
8 changes: 3 additions & 5 deletions js/AudioWorkletGlobalScope.js
Original file line number Diff line number Diff line change
Expand Up @@ -234,13 +234,11 @@ globalThis.registerProcessor = function registerProcessor(name, processorCtor) {
// NOTE: Authors that register an event listener on the "message" event of this
// port should call close on either end of the MessageChannel (either in the
// AudioWorklet or the AudioWorkletGlobalScope side) to allow for resources to be collected.
parentPort.on('exit', () => {
process.stdout.write('closing worklet');
});
// parentPort.on('exit', () => {
// process.stdout.write('closing worklet');
// });

parentPort.on('message', event => {
console.log(event.cmd + '\n');

switch (event.cmd) {
case 'node-web-audio-api:worklet:init': {
const { workletId, processors, promiseId } = event;
Expand Down

0 comments on commit 139038b

Please sign in to comment.