test_upgrade_add_index.js (3610B)
1 /** 2 * Any copyright is dedicated to the Public Domain. 3 * http://creativecommons.org/publicdomain/zero/1.0/ 4 */ 5 6 /* exported testGenerator */ 7 var testGenerator = testSteps(); 8 9 function generateKey() { 10 let algorithm = { 11 name: "RSASSA-PKCS1-v1_5", 12 hash: "SHA-256", 13 modulusLength: 1024, 14 publicExponent: new Uint8Array([0x01, 0x00, 0x01]), 15 }; 16 17 return crypto.subtle.generateKey(algorithm, true, ["sign", "verify"]); 18 } 19 20 const hasCrypto = "crypto" in this; 21 22 /** 23 * Test addition of a new index when the existing values in the referenced 24 * object store have potentially unusual structured clone participants. 25 * 26 * When a new index is created, the existing object store's contents need to be 27 * processed to derive the index values. This is a special event because 28 * normally index values are extracted at add()/put() time in the content 29 * process using the page/worker's JS context (modulo some spec stuff). But 30 * the index creation operation is actually running in the parent process on the 31 * I/O thread for the given database. So the JS context scenario is suddenly 32 * a lot more complicated, and we need extra test coverage, in particular for 33 * unusual structured clone payloads. 34 * 35 * Relationship to other test: 36 * - test_create_index_with_integer_keys.js: This test is derived from that one. 37 */ 38 function* testSteps() { 39 // -- Create our fancy data that has interesting structured clone issues. 40 const allData = []; 41 42 // the xpcshell tests normalize self into existence. 43 if (hasCrypto) { 44 info("creating crypto key"); 45 // (all IDB tests badly need a test driver update...) 46 generateKey().then(grabEventAndContinueHandler); 47 let key = yield undefined; 48 allData.push({ 49 id: 1, 50 what: "crypto", 51 data: key, 52 }); 53 } else { 54 info("not storing crypto key"); 55 } 56 57 // -- Create the IDB and populate it with the base data. 58 info("opening initial database"); 59 let request = indexedDB.open( 60 this.window ? window.location.pathname : "Splendid Test", 61 1 62 ); 63 request.onerror = errorHandler; 64 request.onupgradeneeded = grabEventAndContinueHandler; // advance onupgradeneeded 65 let event = yield undefined; // wait for onupgradeneeded. 66 67 let db = event.target.result; 68 db.onerror = errorHandler; 69 70 event.target.onsuccess = continueToNextStep; // advance when the open completes 71 72 // Make object store, add data. 73 let objectStore = db.createObjectStore("foo", { keyPath: "id" }); 74 for (let datum of allData) { 75 info(`add()ing ${datum.what}`); 76 objectStore.add(datum); 77 } 78 // wait for the open to complete following our upgrade transaction self-closing 79 yield undefined; 80 // explicitly close the database so we can open it again. We don't wait for 81 // this, but the upgrade open will block until the close actually happens. 82 info("closing initial database"); 83 db.close(); 84 85 // -- Trigger an upgrade, adding a new index. 86 info("opening database for upgrade to v2"); 87 request = indexedDB.open( 88 this.window ? window.location.pathname : "Splendid Test", 89 2 90 ); 91 request.onerror = errorHandler; 92 request.onupgradeneeded = grabEventAndContinueHandler; // advance onupgradeneeded 93 event = yield undefined; // wait for onupgradeneeded 94 95 let db2 = event.target.result; 96 db2.onerror = errorHandler; 97 98 event.target.onsuccess = continueToNextStep; // advance when the open completes 99 100 // Create index. 101 info("in upgrade, creating index"); 102 event.target.transaction.objectStore("foo").createIndex("foo", "what"); 103 yield undefined; // wait for the open to complete 104 info("upgrade completed"); 105 106 finishTest(); 107 }