chromium/third_party/blink/web_tests/fast/workers/worker-sharedarraybuffer-transfer.html

<!DOCTYPE html>
<html>
<body>
<p>Test sharing SharedArrayBuffers between dedicated workers.</p>
<div id="result"></div>
<script type="text/javascript">
function log(message)
{
    document.getElementById("result").innerHTML += message + "</br>";
}

var testCases = [
    "testSendSharedArrayBuffer",
    "testSendInt8Array",
    "testSendUint8Array",
    "testSendUint8ClampedArray",
    "testSendInt16Array",
    "testSendUint16Array",
    "testSendInt32Array",
    "testSendUint32Array",
    "testSendFloat32Array",
    "testSendFloat64Array",
    "testSendSharedArrayBufferTwice",
    "testTransferArrayBufferAndSharedArrayBuffer",
    "testSharedArrayBufferInTransferListViaMessagePort",
];
var testIndex = 0;

function runNextTest()
{
    if (testIndex < testCases.length) {
        testIndex++;
        try {
            window[testCases[testIndex - 1]]();
        } catch (ex) {
            log("FAIL: unexpected exception " + ex);
            runNextTest();
        }
    } else {
        log("DONE");
        if (window.testRunner)
            testRunner.notifyDone();
    }
}

function testSendSharedArrayBuffer()
{
    runSendTest("SharedArrayBuffer");
}

function testSendInt8Array()
{
    runSendTest("Int8Array");
}

function testSendUint8Array()
{
    runSendTest("Uint8Array");
}

function testSendUint8ClampedArray()
{
    runSendTest("Uint8ClampedArray");
}

function testSendInt16Array()
{
    runSendTest("Int16Array");
}

function testSendUint16Array()
{
    runSendTest("Uint16Array");
}

function testSendInt32Array()
{
    runSendTest("Int32Array");
}

function testSendUint32Array()
{
    runSendTest("Uint32Array");
}

function testSendFloat32Array()
{
    runSendTest("Float32Array");
}

function testSendFloat64Array()
{
    runSendTest("Float64Array");
}

function initializeTypedArray(ta, length) {
    var i;
    for (i = 0; i < length; ++i)
        ta[i] = i;
}

function runSendTest(name)
{
    var length = 8;
    var type = window[name];
    var sab;
    var ta;
    var msg;

    log("Running " + name + " test case");

    if (name == 'SharedArrayBuffer') {
        sab = new SharedArrayBuffer(length);
        ta = new Uint8Array(sab);
        msg = {name: name, data: sab, length: length};
    } else {
        sab = new SharedArrayBuffer(length * type.BYTES_PER_ELEMENT);
        ta = new type(sab);
        msg = {name: name, data: ta, length: length};
    }

    initializeTypedArray(ta, length);

    // Don't allow passing a SharedArrayBuffer in the transfer list.
    try {
      worker.postMessage(msg, [sab]);
      log("FAIL: Passing SharedArrayBuffer in the transfer list did not throw.");
    } catch (e) {
      log("PASS: Passing SharedArrayBuffer in the transfer list threw.");
    }

    // Without Atomics, we can't safely test modifying the contents of the
    // SharedArrayBuffer. All we can test for now is that the SharedArrayBuffer
    // is not neutered when transferred to a Worker.
    worker.postMessage(msg);

    if (sab.length === 0)
        log("FAIL: SharedArrayBuffer was neutered during transfer.");
    else
        log("PASS: SharedArrayBuffer not neutered during transfer.");

    // Ensure the data wasn't changed.
    for (i = 0; i < length; ++i) {
        if (ta[i] != i) {
            log("FAIL: Original data changed during transfer. Expected " + i +
                " got " + ta[i]);
            break;
        }
    }
    if (i == length)
        log("PASS: Original data not changed during transfer.");
}

function testTransferArrayBufferAndSharedArrayBuffer() {
    var ab = new ArrayBuffer(4);
    var sab = new SharedArrayBuffer(16);
    var msg = {
      name : 'ArrayBufferAndSharedArrayBuffer',
      ab: ab,
      abLength: ab.byteLength,
      sab: sab,
      sabLength: sab.byteLength,
    };

    log("Running TransferArrayBufferAndSharedArrayBuffer test case");

    initializeTypedArray(new Uint8Array(ab), ab.byteLength);
    initializeTypedArray(new Uint8Array(sab), sab.byteLength);

    worker.postMessage(msg, [ab]);

    if (ab.byteLength === 0)
        log("PASS: ArrayBuffer was neutered during transfer.");
    else
        log("FAIL: ArrayBuffer was not neutered during transfer.");
}

function testSendSharedArrayBufferTwice() {
    var sab = new SharedArrayBuffer(16);
    var msg = {
      name : 'SharedArrayBufferTwice',
      sab: sab,
      sabLength: sab.byteLength,
      sab2: sab,
      sab2Length: sab.byteLength,
    };

    log("Running SendSharedArrayBufferTwice test case");

    initializeTypedArray(new Uint8Array(sab), sab.byteLength);

    worker.postMessage(msg);
}

function testSharedArrayBufferInTransferListViaMessagePort() {
    var ab1 = new ArrayBuffer(4);
    var ab2 = new ArrayBuffer(4);
    var sab1 = new SharedArrayBuffer(16);
    var sab2 = new SharedArrayBuffer(16);
    var msg = {
      name : 'SharedArrayBufferInTransferListViaMessagePort',
      ab1: ab1,
      ab2: ab2,
      sab1: sab1,
      sab2: sab2,
    };

    var channel = new MessageChannel();

    channel.port2.onmessage = function() {
        log("FAIL: Message should not be sent.");
    };

    log("Running SharedArrayBufferInTransferListViaMessagePort test case");

    try {
        channel.port1.postMessage(msg, [ab1, sab1, ab2, sab2]);
        log("FAIL: Passing SharedArrayBuffer in the transfer list did not throw.");
    } catch (e) {
        log("PASS: Passing SharedArrayBuffer in the transfer list threw.");
    }

    if (ab1.byteLength === 0)
        log("FAIL: ArrayBuffer 'ab1' was neutered.");
    else
        log("PASS: ArrayBuffer 'ab1' was not neutered.");

    if (ab2.byteLength === 0)
        log("FAIL: ArrayBuffer 'ab2' was neutered.");
    else
        log("PASS: ArrayBuffer 'ab2' was not neutered.");

    runNextTest();
}

if (window.testRunner) {
    testRunner.dumpAsText();
    testRunner.waitUntilDone();
}

if (window.SharedArrayBuffer) {
    var worker = new Worker('resources/worker-sharedarraybuffer-transfer.js');

    runNextTest();

    worker.onmessage = function(e) {
        if (e.data != 'DONE') {
            // The worker sent a pass/fail message.
            log(e.data);
        } else {
            runNextTest();
        }
    };
} else {
    log("SharedArrayBuffers are not enabled -- skipping test.");
    testRunner.notifyDone();
}

</script>
</body>
</html>