|
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 var testGenerator = testSteps(); |
|
10 |
|
11 function testSteps() |
|
12 { |
|
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(event) { |
|
51 ok(true, "Completed transaction " + ++completedTransactionCount + |
|
52 " (We may hang after this!)"); |
|
53 }; |
|
54 } else if (i == abortedTransactionIndex) { |
|
55 // Special transaction that we abort outside the normal event flow. |
|
56 transaction.onerror = function(event) { |
|
57 ok(true, "Aborted transaction " + ++completedTransactionCount + |
|
58 " (We didn't hang!)"); |
|
59 is(event.target.error.name, "AbortError", |
|
60 "AbortError set as the error on the request"); |
|
61 is(event.target.transaction.error, null, |
|
62 "No error set on the transaction"); |
|
63 ok(!caughtError, "Haven't seen the error event yet"); |
|
64 caughtError = true; |
|
65 event.preventDefault(); |
|
66 }; |
|
67 // This has to happen after the we return to the event loop but before the |
|
68 // transaction starts running. |
|
69 executeSoon(function() { transaction.abort(); }); |
|
70 } else { |
|
71 transaction.oncomplete = function(event) { |
|
72 ok(true, "Completed transaction " + ++completedTransactionCount); |
|
73 }; |
|
74 } |
|
75 |
|
76 if (readonly) { |
|
77 transaction.objectStore(objStoreName).get(0); |
|
78 } else { |
|
79 try { transaction.objectStore(objStoreName).add({}); } catch(e) { } |
|
80 } |
|
81 } |
|
82 ok(true, "Created all transactions"); |
|
83 |
|
84 event = yield undefined; |
|
85 |
|
86 ok(true, "Completed transaction " + ++completedTransactionCount); |
|
87 ok(caughtError, "Caught the error event when we aborted the transaction"); |
|
88 |
|
89 finishTest(); |
|
90 yield undefined; |
|
91 } |