Bug 1422335 - Using a sandbox on main-thread when deserializing data for IDB - part 5 - Test, r=baku
authorAndrew Sutherland <asutherland@asutherland.org>
Wed, 17 Jan 2018 08:56:15 -0500
changeset 454137 71516540db51fd17d6d938ea224c3231fe636fd5
parent 454136 bfa90e7a245f0496e9434796681674f7b5f54ace
child 454138 a98f615965d73f6462924188fc2b1f2a620337bb
push id1648
push usermtabara@mozilla.com
push dateThu, 01 Mar 2018 12:45:47 +0000
treeherdermozilla-release@cbb9688c2eeb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbaku
bugs1422335
milestone59.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1422335 - Using a sandbox on main-thread when deserializing data for IDB - part 5 - Test, r=baku
dom/indexedDB/test/helpers.js
dom/indexedDB/test/mochitest.ini
dom/indexedDB/test/test_upgrade_add_index.html
dom/indexedDB/test/unit/test_upgrade_add_index.js
dom/indexedDB/test/unit/xpcshell-shared.ini
--- a/dom/indexedDB/test/helpers.js
+++ b/dom/indexedDB/test/helpers.js
@@ -362,16 +362,29 @@ function isWasmSupported()
 function getWasmBinarySync(text)
 {
   let testingFunctions = SpecialPowers.Cu.getJSTestingFunctions();
   let wasmTextToBinary = SpecialPowers.unwrap(testingFunctions.wasmTextToBinary);
   let binary = wasmTextToBinary(text);
   return binary;
 }
 
+// (Async versions to imitate the on-worker behavior where getWasmBinarySync is
+// not available.)
+function getWasmBinary(text) {
+  let binary = getWasmBinarySync(text);
+  SimpleTest.executeSoon(function() {
+    testGenerator.next(binary);
+  });
+}
+function getWasmModule(_binary_) {
+  let module = new WebAssembly.Module(_binary_);
+  return module;
+}
+
 function workerScript() {
   "use strict";
 
   self.wasmSupported = false;
 
   self.repr = function(_thing_) {
     if (typeof(_thing_) == "undefined") {
       return "undefined";
--- a/dom/indexedDB/test/mochitest.ini
+++ b/dom/indexedDB/test/mochitest.ini
@@ -103,16 +103,17 @@ support-files =
   unit/test_traffic_jam.js
   unit/test_transaction_abort.js
   unit/test_transaction_abort_hang.js
   unit/test_transaction_duplicate_store_names.js
   unit/test_transaction_error.js
   unit/test_transaction_lifetimes.js
   unit/test_transaction_lifetimes_nested.js
   unit/test_transaction_ordering.js
+  unit/test_upgrade_add_index.js
   unit/test_unique_index_update.js
   unit/test_view_put_get_values.js
   unit/test_wasm_cursors.js
   unit/test_wasm_getAll.js
   unit/test_wasm_index_getAllObjects.js
   unit/test_wasm_indexes.js
   unit/test_wasm_put_get_values.js
   unit/test_wasm_serialize_tiering.js
@@ -256,15 +257,16 @@ scheme=https
 [test_transaction_abort.html]
 [test_transaction_abort_hang.html]
 [test_transaction_duplicate_store_names.html]
 [test_transaction_error.html]
 [test_transaction_lifetimes.html]
 [test_transaction_lifetimes_nested.html]
 [test_transaction_ordering.html]
 [test_unique_index_update.html]
+[test_upgrade_add_index.html]
 [test_view_put_get_values.html]
 [test_wasm_cursors.html]
 [test_wasm_getAll.html]
 [test_wasm_index_getAllObjects.html]
 [test_wasm_indexes.html]
 [test_wasm_put_get_values.html]
 [test_wasm_serialize_tiering.html]
new file mode 100644
--- /dev/null
+++ b/dom/indexedDB/test/test_upgrade_add_index.html
@@ -0,0 +1,18 @@
+<!--
+  Any copyright is dedicated to the Public Domain.
+  http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html>
+<head>
+  <title>Indexed Database Test</title>
+
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+
+  <script type="text/javascript" src="unit/test_upgrade_add_index.js"></script>
+  <script type="text/javascript" src="helpers.js"></script>
+</head>
+
+<body onload="runTest();"></body>
+
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/indexedDB/test/unit/test_upgrade_add_index.js
@@ -0,0 +1,114 @@
+/**
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+var testGenerator = testSteps();
+
+function generateKey() {
+  let algorithm = {
+    name: "RSASSA-PKCS1-v1_5",
+    hash: "SHA-256",
+    modulusLength: 1024,
+    publicExponent: new Uint8Array([0x01, 0x00, 0x01])
+  };
+
+  return crypto.subtle.generateKey(algorithm, true, ["sign", "verify"]);
+}
+
+const hasCrypto = "crypto" in this;
+
+/**
+ * Test addition of a new index when the existing values in the referenced
+ * object store have potentially unusual structured clone participants.
+ *
+ * When a new index is created, the existing object store's contents need to be
+ * processed to derive the index values.  This is a special event because
+ * normally index values are extracted at add()/put() time in the content
+ * process using the page/worker's JS context (modulo some spec stuff).  But
+ * the index creation operation is actually running in the parent process on the
+ * I/O thread for the given database.  So the JS context scenario is suddenly
+ * a lot more complicated, and we need extra test coverage, in particular for
+ * unusual structured clone payloads.
+ *
+ * Relationship to other test:
+ * - test_create_index_with_integer_keys.js: This test is derived from that one.
+ */
+function* testSteps()
+{
+  // -- Create our fancy data that has interesting structured clone issues.
+  const allData = [];
+
+  // the xpcshell tests normalize self into existence.
+  if (hasCrypto) {
+    info("creating crypto key");
+    // (all IDB tests badly need a test driver update...)
+    generateKey().then(grabEventAndContinueHandler);
+    let key = yield undefined;
+    allData.push({
+      id: 1,
+      what: "crypto",
+      data: key
+    });
+  } else {
+    info("not storing crypto key");
+  }
+
+  if (isWasmSupported()) {
+    info("creating wasm");
+    getWasmBinary("(module (func (nop)))");
+    let binary = yield undefined;
+    allData.push({
+      id: 2,
+      what: "wasm",
+      data: getWasmModule(binary)
+    });
+  } else {
+    info("not storing wasm");
+  }
+
+  // -- Create the IDB and populate it with the base data.
+  info("opening initial database");
+  let request = indexedDB.open(this.window ? window.location.pathname : "Splendid Test", 1);
+  request.onerror = errorHandler;
+  request.onupgradeneeded = grabEventAndContinueHandler; // advance onupgradeneeded
+  let event = yield undefined; // wait for onupgradeneeded.
+
+  let db = event.target.result;
+  db.onerror = errorHandler;
+
+  event.target.onsuccess = continueToNextStep; // advance when the open completes
+
+  // Make object store, add data.
+  let objectStore = db.createObjectStore("foo", { keyPath: "id" });
+  for (let datum of allData) {
+    info(`add()ing ${datum.what}`);
+    objectStore.add(datum);
+  }
+  // wait for the open to complete following our upgrade transaction self-closing
+  yield undefined;
+  // explicitly close the database so we can open it again.  We don't wait for
+  // this, but the upgrade open will block until the close actually happens.
+  info("closing initial database");
+  db.close();
+
+  // -- Trigger an upgrade, adding a new index.
+  info("opening database for upgrade to v2");
+  request = indexedDB.open(this.window ? window.location.pathname : "Splendid Test", 2);
+  request.onerror = errorHandler;
+  request.onupgradeneeded = grabEventAndContinueHandler; // advance onupgradeneeded
+  event = yield undefined; // wait for onupgradeneeded
+
+  let db2 = event.target.result;
+  db2.onerror = errorHandler;
+
+  event.target.onsuccess = continueToNextStep; // advance when the open completes
+
+  // Create index.
+  info("in upgrade, creating index");
+  event.target.transaction.objectStore("foo").createIndex("foo", "what");
+  yield undefined; // wait for the open to complete
+  info("upgrade completed");
+
+  finishTest();
+}
--- a/dom/indexedDB/test/unit/xpcshell-shared.ini
+++ b/dom/indexedDB/test/unit/xpcshell-shared.ini
@@ -88,9 +88,10 @@ skip-if = toolkit == 'android' # bug 864
 [test_transaction_abort.js]
 [test_transaction_abort_hang.js]
 [test_transaction_duplicate_store_names.js]
 [test_transaction_error.js]
 [test_transaction_lifetimes.js]
 [test_transaction_lifetimes_nested.js]
 [test_transaction_ordering.js]
 [test_unique_index_update.js]
+[test_upgrade_add_index.js]
 [test_writer_starvation.js]