 Chromium Code Reviews
 Chromium Code Reviews Issue 2556373003:
  Tests for exceptions related to IndexedDB upgrade transaction lifecycle.  (Closed)
    
  
    Issue 2556373003:
  Tests for exceptions related to IndexedDB upgrade transaction lifecycle.  (Closed) 
  | OLD | NEW | 
|---|---|
| (Empty) | |
| 1 <!doctype html> | |
| 2 <title>IndexedDB: backend-aborted versionchange transaction lifecycle</title> | |
| 3 <link rel="help" | |
| 4 href="https://w3c.github.io/IndexedDB/#upgrade-transaction-steps"> | |
| 5 <link rel="help" | |
| 6 href="https://w3c.github.io/IndexedDB/#dom-idbdatabase-createobjectstore"> | |
| 7 <link rel="help" | |
| 8 href="https://w3c.github.io/IndexedDB/#dom-idbdatabase-deleteobjectstore"> | |
| 9 <link rel="author" href="pwnall@chromium.org" title="Victor Costan"> | |
| 10 <script src="../../resources/testharness.js"></script> | |
| 11 <script src="../../resources/testharnessreport.js"></script> | |
| 12 <script src="resources/support-promises.js"></script> | |
| 13 <script> | |
| 14 'use strict'; | |
| 15 | |
| 16 promise_test(t => { | |
| 17 let timeoutPromise = null, abortPromise = null; | |
| 18 return createDatabase(t, database => { | |
| 19 createBooksStore(t, database); | |
| 20 }).then(database => { | |
| 21 database.close(); | |
| 22 }).then(() => migrateDatabase(t, 2, (database, transaction, request) => { | |
| 23 createNotBooksStore(t, database); | |
| 24 | |
| 25 // Queue I/O operations to make sure the transaction does not complete | |
| 
jsbell
2016/12/19 18:01:30
This isn't guaranteed. The setTimeout(0) could fir
 
pwnall
2016/12/20 02:46:34
Yes :(
I don't know how to do better here, though.
 | |
| 26 // before setTimeout's callback is called. | |
| 27 const store = transaction.objectStore('books'); | |
| 28 for (let i = 0; i < 1000; ++i) | |
| 29 store.put({ title: 'Bedrock Nights ' + i, author: 'Barney' }); | |
| 30 | |
| 31 let abortFired = false; | |
| 32 abortPromise = new Promise((resolve, reject) => { | |
| 33 transaction.addEventListener('abort', () => { | |
| 34 abortFired = true; | |
| 35 resolve(); | |
| 36 }, false); | |
| 37 }); | |
| 38 | |
| 39 timeoutPromise = new Promise((resolve, reject) => { | |
| 40 setTimeout(() => { | |
| 41 const testStepPromise = new Promise((resolve, reject) => { | |
| 42 assert_false( | |
| 43 abortFired, | |
| 44 'The abort event should fire after setTimeout expires'); | |
| 45 assert_equals( | |
| 46 request.transaction, transaction, | |
| 47 "The open request's transaction should be reset after onabort"); | |
| 48 assert_throws( | |
| 49 'TransactionInactiveError', | |
| 50 () => { database.createObjectStore('books2'); }, | |
| 51 'createObjectStore exception should reflect that the ' + | |
| 52 'transaction is still running'); | |
| 53 assert_throws( | |
| 54 'TransactionInactiveError', | |
| 55 () => { database.deleteObjectStore('books'); }, | |
| 56 'deleteObjectStore exception should reflect that the ' + | |
| 57 'transaction is still running'); | |
| 58 resolve(); | |
| 59 }); | |
| 60 resolve(testStepPromise); | |
| 61 }, 0); | |
| 62 }); | |
| 63 | |
| 64 transaction.objectStore('books').add(BOOKS_RECORD_DATA[0]); | |
| 65 transaction._willBeAborted(); | |
| 66 })).then(() => Promise.all([timeoutPromise, abortPromise])); | |
| 67 }, 'in a setTimeout(0) callback after a failing request is issued, before ' + | |
| 
jsbell
2016/12/19 18:01:30
I'm not sure you'll be able to reliably test for t
 
pwnall
2016/12/20 02:46:34
Ack :(
I agree with the statements above. It's tem
 | |
| 68 'the abort event is fired'); | |
| 69 | |
| 70 promise_test(t => { | |
| 71 let abortPromise = null; | |
| 72 return createDatabase(t, database => { | |
| 73 createBooksStore(t, database); | |
| 74 }).then(database => { | |
| 75 database.close(); | |
| 76 }).then(() => migrateDatabase(t, 2, (database, transaction, request) => { | |
| 
jsbell
2016/12/19 18:01:30
I think the test would be more readable if this fu
 
pwnall
2016/12/20 02:46:34
Done.
I hadn't done that before because migrateDat
 | |
| 77 abortPromise = new Promise((resolve, reject) => { | |
| 78 transaction.addEventListener('abort', () => { | |
| 79 const testStepPromise = new Promise((resolve, reject) => { | |
| 
jsbell
2016/12/19 18:01:30
I don't think this Promise does anything useful he
 
pwnall
2016/12/20 02:46:34
Unfortunately, some sort of wrapping is required t
 | |
| 80 assert_equals( | |
| 81 request.transaction, transaction, | |
| 82 "The open request's transaction should be reset after onabort"); | |
| 83 assert_throws( | |
| 84 'InvalidStateError', | |
| 85 () => { database.createObjectStore('books2'); }, | |
| 86 'createObjectStore exception should reflect that the ' + | |
| 87 'transaction is no longer running'); | |
| 88 assert_throws( | |
| 89 'InvalidStateError', | |
| 90 () => { database.deleteObjectStore('books'); }, | |
| 91 'deleteObjectStore exception should reflect that the ' + | |
| 92 'transaction is no longer running'); | |
| 93 | |
| 94 resolve(); | |
| 95 }); | |
| 96 resolve(testStepPromise); | |
| 97 }, false); | |
| 98 transaction.objectStore('books').add(BOOKS_RECORD_DATA[0]); | |
| 99 transaction._willBeAborted(); | |
| 100 }); | |
| 101 })).then(() => abortPromise); | |
| 102 }, 'while the abort event is fired due to a bad request'); | |
| 
jsbell
2016/12/19 18:01:30
Can you reword this description? It looks like it'
 
pwnall
2016/12/20 02:46:34
Done.
I tried to use better descriptions.
 | |
| 103 | |
| 104 promise_test(t => { | |
| 105 let abortPromise = null; | |
| 106 return createDatabase(t, database => { | |
| 107 createBooksStore(t, database); | |
| 108 }).then(database => { | |
| 109 database.close(); | |
| 110 }).then(() => migrateDatabase(t, 2, (database, transaction, request) => { | |
| 
jsbell
2016/12/19 18:01:30
Same as above; this can just return abortPromise
 
pwnall
2016/12/20 02:46:34
Done.
 | |
| 111 abortPromise = new Promise((resolve, reject) => { | |
| 112 transaction.addEventListener('abort', () => { | |
| 113 const timeoutPromise = new Promise((resolve, reject) => { | |
| 114 setTimeout(() => { | |
| 115 const testStepPromise = new Promise((resolve, reject) => { | |
| 
jsbell
2016/12/19 18:01:30
Same comment here about testStepPromise above - it
 
pwnall
2016/12/20 02:46:34
Done.
 | |
| 116 assert_equals( | |
| 117 request.transaction, null, | |
| 118 "The open request's transaction should be reset after " + | |
| 119 'onabort microtasks'); | |
| 120 assert_throws( | |
| 121 'InvalidStateError', | |
| 122 () => { database.createObjectStore('books2'); }, | |
| 123 'createObjectStore exception should reflect that the ' + | |
| 124 'transaction is no longer running'); | |
| 125 assert_throws( | |
| 126 'InvalidStateError', | |
| 127 () => { database.deleteObjectStore('books'); }, | |
| 128 'deleteObjectStore exception should reflect that the ' + | |
| 129 'transaction is no longer running'); | |
| 130 resolve(); | |
| 131 }); | |
| 132 resolve(testStepPromise); | |
| 133 }, 0); | |
| 134 }); | |
| 135 resolve(timeoutPromise); | |
| 136 }, false); | |
| 137 transaction.objectStore('books').add(BOOKS_RECORD_DATA[0]); | |
| 138 transaction._willBeAborted(); | |
| 139 }); | |
| 140 })).then(() => abortPromise); | |
| 141 }, 'in a setTimeout(0) callback after the abort event is fired due to a bad ' + | |
| 142 'request'); | |
| 143 | |
| 144 </script> | |
| OLD | NEW |