diff options
Diffstat (limited to 'js/src/tests/shell')
-rw-r--r-- | js/src/tests/shell/README | 1 | ||||
-rw-r--r-- | js/src/tests/shell/futex-apis.js | 113 | ||||
-rw-r--r-- | js/src/tests/shell/futex.js | 160 | ||||
-rw-r--r-- | js/src/tests/shell/gcstats.js | 60 | ||||
-rw-r--r-- | js/src/tests/shell/os.js | 39 | ||||
-rw-r--r-- | js/src/tests/shell/shell.js | 4 | ||||
-rw-r--r-- | js/src/tests/shell/warning.js | 34 |
7 files changed, 411 insertions, 0 deletions
diff --git a/js/src/tests/shell/README b/js/src/tests/shell/README new file mode 100644 index 000000000..0c7a3d149 --- /dev/null +++ b/js/src/tests/shell/README @@ -0,0 +1 @@ +Tests for JS shell-only functions diff --git a/js/src/tests/shell/futex-apis.js b/js/src/tests/shell/futex-apis.js new file mode 100644 index 000000000..b3e0acd55 --- /dev/null +++ b/js/src/tests/shell/futex-apis.js @@ -0,0 +1,113 @@ +// |reftest| skip-if(!xulRuntime.shell) +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +if (!(this.SharedArrayBuffer && this.Atomics)) { + reportCompare(true,true); + quit(0); +} + +// Checks for parameter validation of wait/wake API. All of these test +// cases should throw exceptions during parameter validation, before +// we check whether any waiting should be done. + +let ab = new ArrayBuffer(16); +let sab = new SharedArrayBuffer(16); + +////////////////////////////////////////////////////////////////////// +// +// The view must be an Int32Array on a SharedArrayBuffer. + +// Check against non-TypedArray cases. + +{ + let values = [null, + undefined, + true, + false, + new Boolean(true), + 10, + 3.14, + new Number(4), + "Hi there", + new Date, + /a*utomaton/g, + { password: "qumquat" }, + new DataView(new ArrayBuffer(10)), + new ArrayBuffer(128), + new SharedArrayBuffer(128), + new Error("Ouch"), + [1,1,2,3,5,8], + ((x) => -x), + new Map(), + new Set(), + new WeakMap(), + new WeakSet(), + this.Promise ? new Promise(() => "done") : null, + Symbol("halleluja"), + // TODO: Proxy? + Object, + Int32Array, + Date, + Math, + Atomics ]; + + for ( let i=0 ; i < values.length ; i++ ) { + let view = values[i]; + assertThrowsInstanceOf(() => Atomics.wait(view, 0, 0), TypeError); + assertThrowsInstanceOf(() => Atomics.wake(view, 0), TypeError); + } +} + +// Check against TypedArray on non-shared memory cases. + +{ + let views = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array]; + + for ( let View of views ) { + let view = new View(ab); + + assertThrowsInstanceOf(() => Atomics.wait(view, 0, 0), TypeError); + assertThrowsInstanceOf(() => Atomics.wake(view, 0), TypeError); + } +} + +// Check against TypedArray on shared memory, but wrong view type + +{ + let views = [Int8Array, Uint8Array, Int16Array, Uint16Array, Uint32Array, + Uint8ClampedArray, Float32Array, Float64Array]; + + for ( let View of views ) { + let view = new View(sab); + + assertThrowsInstanceOf(() => Atomics.wait(view, 0, 0), TypeError); + assertThrowsInstanceOf(() => Atomics.wake(view, 0), TypeError); + } +} + +////////////////////////////////////////////////////////////////////// +// +// The indices must be in the range of the array + +{ + let view = new Int32Array(sab); + + let indices = [ (view) => -1, + (view) => view.length, + (view) => view.length*2, + (view) => undefined, + (view) => '3.5', + (view) => { password: "qumquat" } ]; + + for ( let iidx=0 ; iidx < indices.length ; iidx++ ) { + let Idx = indices[iidx](view); + assertThrowsInstanceOf(() => Atomics.wait(view, Idx, 10), RangeError); + assertThrowsInstanceOf(() => Atomics.wake(view, Idx), RangeError); + } +} + +reportCompare(true,true); diff --git a/js/src/tests/shell/futex.js b/js/src/tests/shell/futex.js new file mode 100644 index 000000000..b0951f12e --- /dev/null +++ b/js/src/tests/shell/futex.js @@ -0,0 +1,160 @@ +// |reftest| skip-if(!xulRuntime.shell) +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +if (!(this.SharedArrayBuffer && this.getSharedArrayBuffer && this.setSharedArrayBuffer)) { + reportCompare(true,true); + quit(0); +} + +var DEBUG = false; + +function dprint(s) { + if (DEBUG) print(s); +} + +// Tests the SharedArrayBuffer mailbox in the shell. +// Tests the wait/wake functionality in the shell. + +var sab = new SharedArrayBuffer(12); +var mem = new Int32Array(sab); + +// SharedArrayBuffer mailbox tests + +assertEq(getSharedArrayBuffer(), null); // Mbx starts empty + +assertEq(setSharedArrayBuffer(mem.buffer), undefined); // Setter returns undefined +assertEq(getSharedArrayBuffer() == null, false); // And then the mbx is not empty + +var v = getSharedArrayBuffer(); +assertEq(v.byteLength, mem.buffer.byteLength); // Looks like what we put in? +var w = new Int32Array(v); +mem[0] = 314159; +assertEq(w[0], 314159); // Shares memory (locally) with what we put in? +mem[0] = 0; + +setSharedArrayBuffer(null); // Setting to null clears to null +assertEq(getSharedArrayBuffer(), null); + +setSharedArrayBuffer(mem.buffer); +setSharedArrayBuffer(undefined); // Setting to undefined clears to null +assertEq(getSharedArrayBuffer(), null); + +setSharedArrayBuffer(mem.buffer); +setSharedArrayBuffer(); // Setting without arguments clears to null +assertEq(getSharedArrayBuffer(), null); + +// Only SharedArrayBuffer can be stored in the mbx + +assertThrowsInstanceOf(() => setSharedArrayBuffer({x:10, y:20}), Error); +assertThrowsInstanceOf(() => setSharedArrayBuffer([1,2]), Error); +assertThrowsInstanceOf(() => setSharedArrayBuffer(new ArrayBuffer(10)), Error); +assertThrowsInstanceOf(() => setSharedArrayBuffer(new Int32Array(10)), Error); +assertThrowsInstanceOf(() => setSharedArrayBuffer(false), Error); +assertThrowsInstanceOf(() => setSharedArrayBuffer(3.14), Error); +assertThrowsInstanceOf(() => setSharedArrayBuffer(mem), Error); +assertThrowsInstanceOf(() => setSharedArrayBuffer("abracadabra"), Error); +assertThrowsInstanceOf(() => setSharedArrayBuffer(() => 37), Error); + +// Futex test + +if (helperThreadCount() === 0) { + // Abort if there is no helper thread. + reportCompare(true,true); + quit(); +} + +//////////////////////////////////////////////////////////// + +// wait() returns "not-equal" if the value is not the expected one. + +mem[0] = 42; + +assertEq(Atomics.wait(mem, 0, 33), "not-equal"); + +// wait() returns "timed-out" if it times out + +assertEq(Atomics.wait(mem, 0, 42, 100), "timed-out"); + +//////////////////////////////////////////////////////////// + +// Main is sharing the buffer with the worker; the worker is clearing +// the buffer. + +mem[0] = 42; +mem[1] = 37; +mem[2] = DEBUG; + +setSharedArrayBuffer(mem.buffer); + +evalInWorker(` +var mem = new Int32Array(getSharedArrayBuffer()); +function dprint(s) { + if (mem[2]) print(s); +} +assertEq(mem[0], 42); // what was written in the main thread +assertEq(mem[1], 37); // is read in the worker +mem[1] = 1337; +dprint("Sleeping for 2 seconds"); +sleep(2); +dprint("Waking the main thread now"); +setSharedArrayBuffer(null); +assertEq(Atomics.wake(mem, 0, 1), 1); // Can fail spuriously but very unlikely +`); + +var then = Date.now(); +assertEq(Atomics.wait(mem, 0, 42), "ok"); +dprint("Woke up as I should have in " + (Date.now() - then)/1000 + "s"); +assertEq(mem[1], 1337); // what was written in the worker is read in the main thread +assertEq(getSharedArrayBuffer(), null); // The worker's clearing of the mbx is visible + +//////////////////////////////////////////////////////////// + +// Test the default argument to atomics.wake() + +setSharedArrayBuffer(mem.buffer); + +evalInWorker(` +var mem = new Int32Array(getSharedArrayBuffer()); +sleep(2); // Probably long enough to avoid a spurious error next +assertEq(Atomics.wake(mem, 0), 1); // Last argument to wake should default to +Infinity +`); + +var then = Date.now(); +dprint("Main thread waiting on wakeup (2s)"); +assertEq(Atomics.wait(mem, 0, 42), "ok"); +dprint("Woke up as I should have in " + (Date.now() - then)/1000 + "s"); + +//////////////////////////////////////////////////////////// + +// A tricky case: while in the wait there will be an interrupt, and in +// the interrupt handler we will execute a wait. This is +// explicitly prohibited (for now), so there should be a catchable exception. + +var exn = false; +timeout(2, function () { + dprint("In the interrupt, starting inner wait with timeout 2s"); + try { + Atomics.wait(mem, 0, 42); // Should throw + } catch (e) { + dprint("Got the interrupt exception!"); + exn = true; + } + return true; +}); +try { + dprint("Starting outer wait"); + assertEq(Atomics.wait(mem, 0, 42, 5000), "timed-out"); +} +finally { + timeout(-1); +} +assertEq(exn, true); + +//////////////////////////////////////////////////////////// + +dprint("Done"); +reportCompare(true,true); diff --git a/js/src/tests/shell/gcstats.js b/js/src/tests/shell/gcstats.js new file mode 100644 index 000000000..6343b56bb --- /dev/null +++ b/js/src/tests/shell/gcstats.js @@ -0,0 +1,60 @@ +// |reftest| skip-if(!xulRuntime.shell) +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +function garbage() { + var x; + for (var i = 0; i < 100000; i++) + x = { 'i': i }; +} + +setGCCallback({ + action: "majorGC", + depth: 1, + phases: "both" +}); + +gc(); +garbage(); + +setGCCallback({ + action: "majorGC", + depth: 2, + phases: "both" +}); + +gc(); +garbage(); + +setGCCallback({ + action: "majorGC", + depth: 10, + phases: "begin" +}); + +gc(); +garbage(); + +setGCCallback({ + action: "minorGC", + phases: "both" +}); + +gc(); +garbage(); + +var caught = false; +try { + setGCCallback({ + action: "majorGC", + depth: 10000, + phases: "begin" + }); +} catch (e) { + caught = ((""+e).indexOf("Nesting depth too large") >= 0); +} + +reportCompare(caught, true); diff --git a/js/src/tests/shell/os.js b/js/src/tests/shell/os.js new file mode 100644 index 000000000..06e08f683 --- /dev/null +++ b/js/src/tests/shell/os.js @@ -0,0 +1,39 @@ +// |reftest| skip-if(!xulRuntime.shell||xulRuntime.OS=="WINNT") +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +var pid = os.getpid(); +assertEq(pid > 0, true); + +var PATH = os.getenv("PATH"); +assertEq(PATH.indexOf("bin") > 0, true); +assertEq(os.getenv("SQUAMMISH_HILLBILLY_GOAT_SQUEEZERS"), undefined); + +assertEq(os.system("true"), 0, "/bin/true should exit 0"); +assertEq(os.system("false") != 0, true, "/bin/false should exit nonzero"); + +var kidpid = os.spawn("sleep 60"); +assertEq(kidpid > 0, true, "spawning sleep"); +var info = os.waitpid(kidpid, true); +assertEq(info.hasOwnProperty("pid"), false); +assertEq(info.hasOwnProperty("exitStatus"), false); + +os.kill(kidpid); + +info = os.waitpid(kidpid); +assertEq(info.hasOwnProperty("pid"), true, "waiting on dead process should return pid"); +assertEq(info.pid, kidpid); +assertEq(info.hasOwnProperty("exitStatus"), false, "killed process should not have exitStatus"); + +kidpid = os.spawn("false"); +assertEq(kidpid > 0, true, "spawning /bin/false"); +info = os.waitpid(kidpid); +assertEq(info.hasOwnProperty("pid"), true, "waiting on dead process should return pid"); +assertEq(info.pid, kidpid); +assertEq(info.hasOwnProperty("exitStatus"), true, "process should have exitStatus"); +assertEq(info.exitStatus, 1, "/bin/false should exit 1"); + +reportCompare(true, true); diff --git a/js/src/tests/shell/shell.js b/js/src/tests/shell/shell.js new file mode 100644 index 000000000..7584133da --- /dev/null +++ b/js/src/tests/shell/shell.js @@ -0,0 +1,4 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ diff --git a/js/src/tests/shell/warning.js b/js/src/tests/shell/warning.js new file mode 100644 index 000000000..550c10bc5 --- /dev/null +++ b/js/src/tests/shell/warning.js @@ -0,0 +1,34 @@ +// |reftest| skip-if(!xulRuntime.shell) + +var BUGNUMBER = 1170716; +var summary = 'Add js shell functions to get last warning'; + +print(BUGNUMBER + ": " + summary); + +// Warning with JSEXN_SYNTAXERR. + +enableLastWarning(); +options("strict"); +eval(`var a; if (a=0) {}`); + +warning = getLastWarning(); +assertEq(warning !== null, true); +assertEq(warning.name, "SyntaxError"); +assertEq(warning.message.includes("equality"), true); +assertEq(warning.lineNumber, 1); +assertEq(warning.columnNumber, 14); + +// Disabled. + +disableLastWarning(); + +eval(`var a; if (a=0) {}`); + +enableLastWarning(); +warning = getLastWarning(); +assertEq(warning, null); + +disableLastWarning(); + +if (typeof reportCompare === "function") + reportCompare(true, true); |