Bug 1279006 - Clean up webaudioeditor node destruction tests, and fix another race condition. r=bgrins, a=test-only
--- a/devtools/client/webaudioeditor/test/browser_wa_destroy-node-01.js
+++ b/devtools/client/webaudioeditor/test/browser_wa_destroy-node-01.js
@@ -13,32 +13,32 @@ add_task(function* () {
let { target, panel } = yield initWebAudioEditor(DESTROY_NODES_URL);
let { panelWin } = panel;
let { gFront, $, $$, gAudioNodes } = panelWin;
let started = once(gFront, "start-context");
reload(target);
- let destroyed = getN(gAudioNodes, "remove", 10);
-
let [created] = yield Promise.all([
getNSpread(gAudioNodes, "add", 13),
waitForGraphRendered(panelWin, 13, 2)
]);
// Flatten arrays of event arguments and take the first (AudioNodeModel)
// and get its ID.
let actorIDs = created.map(ev => ev[0].id);
// Click a soon-to-be dead buffer node
yield clickGraphNode(panelWin, actorIDs[5]);
+ let destroyed = getN(gAudioNodes, "remove", 10);
+
// Force a CC in the child process to collect the orphaned nodes.
- forceCC();
+ forceNodeCollection();
// Wait for destruction and graph to re-render
yield Promise.all([destroyed, waitForGraphRendered(panelWin, 3, 2)]);
// Test internal storage
is(panelWin.gAudioNodes.length, 3, "All nodes should be GC'd except one gain, osc and dest node.");
// Test graph rendering
--- a/devtools/client/webaudioeditor/test/browser_webaudio-actor-destroy-node.js
+++ b/devtools/client/webaudioeditor/test/browser_webaudio-actor-destroy-node.js
@@ -3,30 +3,28 @@
/**
* Test `destroy-node` event on WebAudioActor.
*/
add_task(function* () {
let { target, front } = yield initBackend(DESTROY_NODES_URL);
- let waitUntilDestroyed = getN(front, "destroy-node", 10);
let [, , created] = yield Promise.all([
front.setup({ reload: true }),
once(front, "start-context"),
- // Should create 1 destination node and 10 disposable buffer nodes
+ // Should create dest, gain, and oscillator node and 10
+ // disposable buffer nodes
getN(front, "create-node", 13)
]);
- // Wait for a tick before gc to prevent this test from intermittent timeout
- // where the node never get collected.
- yield DevToolsUtils.waitForTick();
+ let waitUntilDestroyed = getN(front, "destroy-node", 10);
// Force CC so we can ensure it's run to clear out dead AudioNodes
- forceCC();
+ forceNodeCollection();
let destroyed = yield waitUntilDestroyed;
destroyed.forEach((node, i) => {
ok(node.type, "AudioBufferSourceNode", "Only buffer nodes are destroyed");
ok(actorIsInList(created, destroyed[i]),
"`destroy-node` called only on AudioNodes in current document.");
});
--- a/devtools/client/webaudioeditor/test/doc_destroy-nodes.html
+++ b/devtools/client/webaudioeditor/test/doc_destroy-nodes.html
@@ -7,23 +7,27 @@
<meta charset="utf-8"/>
<title>Web Audio Editor test page</title>
</head>
<body>
<script type="text/javascript;version=1.8">
"use strict";
+ // Keep the nodes we want to GC alive until we are ready for them to
+ // be collected. We will zero this reference by force from the devtools
+ // side.
+ var keepAlive = [];
(function () {
let ctx = new AudioContext();
let osc = ctx.createOscillator();
let gain = ctx.createGain();
for (let i = 0; i < 10; i++) {
- ctx.createBufferSource();
+ keepAlive.push(ctx.createBufferSource());
}
osc.connect(gain);
gain.connect(ctx.destination);
gain.gain.value = 0;
osc.start();
})();
</script>
--- a/devtools/client/webaudioeditor/test/head.js
+++ b/devtools/client/webaudioeditor/test/head.js
@@ -415,18 +415,22 @@ function countGraphObjects(win) {
nodes: win.document.querySelectorAll(".nodes > .audionode").length,
edges: win.document.querySelectorAll(".edgePaths > .edgePath").length
};
}
/**
* Forces cycle collection and GC, used in AudioNode destruction tests.
*/
-function forceCC() {
+function forceNodeCollection() {
ContentTask.spawn(gBrowser.selectedBrowser, {}, function*() {
+ // Kill the reference keeping stuff alive.
+ content.wrappedJSObject.keepAlive = null;
+
+ // Collect the now-deceased nodes.
Cu.forceGC();
Cu.forceCC();
Cu.forceGC();
Cu.forceCC();
});
}
/**