test_transaction_abort_hang.js (3046B)
1 /** 2 * Any copyright is dedicated to the Public Domain. 3 * http://creativecommons.org/publicdomain/zero/1.0/ 4 */ 5 "use strict"; 6 7 var self = this; 8 9 /* exported testGenerator */ 10 var testGenerator = testSteps(); 11 12 function* testSteps() { 13 const dbName = self.window 14 ? window.location.pathname 15 : "test_transaction_abort_hang"; 16 const objStoreName = "foo"; 17 const transactionCount = 30; 18 19 let completedTransactionCount = 0; 20 let caughtError = false; 21 22 let abortedTransactionIndex = Math.floor(transactionCount / 2); 23 if (abortedTransactionIndex % 2 == 0) { 24 abortedTransactionIndex++; 25 } 26 27 let request = indexedDB.open(dbName, 1); 28 request.onerror = errorHandler; 29 request.onupgradeneeded = grabEventAndContinueHandler; 30 let event = yield undefined; 31 32 request.result.createObjectStore(objStoreName, { autoIncrement: true }); 33 34 request.onupgradeneeded = null; 35 request.onsuccess = grabEventAndContinueHandler; 36 event = yield undefined; 37 38 let db = event.target.result; 39 40 for (let i = 0; i < transactionCount; i++) { 41 const readonly = i % 2 == 0; 42 const mode = readonly ? "readonly" : "readwrite"; 43 44 let transaction = db.transaction(objStoreName, mode); 45 46 if (i == transactionCount - 1) { 47 // Last one, finish the test. 48 transaction.oncomplete = grabEventAndContinueHandler; 49 } else if (i == abortedTransactionIndex - 1) { 50 transaction.oncomplete = function () { 51 ok( 52 true, 53 "Completed transaction " + 54 ++completedTransactionCount + 55 " (We may hang after this!)" 56 ); 57 }; 58 } else if (i == abortedTransactionIndex) { 59 // Special transaction that we abort outside the normal event flow. 60 transaction.onerror = function (event) { 61 ok( 62 true, 63 "Aborted transaction " + 64 ++completedTransactionCount + 65 " (We didn't hang!)" 66 ); 67 is( 68 event.target.error.name, 69 "AbortError", 70 "AbortError set as the error on the request" 71 ); 72 is( 73 event.target.transaction.error, 74 null, 75 "No error set on the transaction" 76 ); 77 ok(!caughtError, "Haven't seen the error event yet"); 78 caughtError = true; 79 event.preventDefault(); 80 }; 81 // This has to happen after the we return to the event loop but before the 82 // transaction starts running. 83 executeSoon(function () { 84 transaction.abort(); 85 }); 86 } else { 87 transaction.oncomplete = function () { 88 ok(true, "Completed transaction " + ++completedTransactionCount); 89 }; 90 } 91 92 if (readonly) { 93 transaction.objectStore(objStoreName).get(0); 94 } else { 95 try { 96 transaction.objectStore(objStoreName).add({}); 97 } catch (e) {} 98 } 99 } 100 ok(true, "Created all transactions"); 101 102 event = yield undefined; 103 104 ok(true, "Completed transaction " + ++completedTransactionCount); 105 ok(caughtError, "Caught the error event when we aborted the transaction"); 106 107 finishTest(); 108 }