OLD | NEW |
(Empty) | |
| 1 <!DOCTYPE html> |
| 2 <title>IndexedDB: aborting transactions reverts index metadata</title> |
| 3 <script src='../../resources/testharness.js'></script> |
| 4 <link rel="help" href="https://w3c.github.io/IndexedDB/#abort-transaction"> |
| 5 <link rel="author" href="pwnall@chromium.org" title="Victor Costan"> |
| 6 <script src='../../resources/testharnessreport.js'></script> |
| 7 <script src='resources/rename-common.js'></script> |
| 8 <script> |
| 9 |
| 10 promise_test(testCase => { |
| 11 let store = null, index = null; |
| 12 return createDatabase(testCase, (database, transaction) => { |
| 13 createBooksStore(testCase, database); |
| 14 }).then(database => { |
| 15 database.close(); |
| 16 }).then(() => migrateDatabase(testCase, 2, (database, transaction) => { |
| 17 store = createNotBooksStore(testCase, database); |
| 18 index = store.index('not_by_author'); |
| 19 assert_array_equals( |
| 20 store.indexNames, ['not_by_author', 'not_by_title'], |
| 21 'IDBObjectStore.indexNames should include newly created indexes ' + |
| 22 'before the transaction is aborted'); |
| 23 |
| 24 transaction.abort(); |
| 25 assert_throws( |
| 26 'InvalidStateError', () => index.get('query'), |
| 27 'IDBIndex.get should throw InvalidStateError, indicating that ' + |
| 28 'the index is marked for deletion, immediately after ' + |
| 29 'IDBTransaction.abort() returns'); |
| 30 assert_array_equals( |
| 31 store.indexNames, [], |
| 32 'IDBObjectStore.indexNames should stop including the newly ' + |
| 33 'created indexes immediately after IDBTransaction.abort() returns'); |
| 34 })).then(() => { |
| 35 assert_throws( |
| 36 'InvalidStateError', () => index.get('query'), |
| 37 'IDBIndex.get should throw InvalidStateError, indicating that ' + |
| 38 'the index is marked for deletion, after the transaction is ' + |
| 39 'aborted'); |
| 40 assert_array_equals( |
| 41 store.indexNames, [], |
| 42 'IDBObjectStore.indexNames should stop including the newly ' + |
| 43 'created indexes after the transaction is aborted'); |
| 44 }); |
| 45 }, 'Created stores get their indexes marked as deleted after the transaction ' + |
| 46 'that created them aborts'); |
| 47 |
| 48 promise_test(testCase => { |
| 49 let store = null, index = null; |
| 50 return createDatabase(testCase, (database, transaction) => { |
| 51 createBooksStore(testCase, database); |
| 52 createNotBooksStore(testCase, database); |
| 53 }).then(database => { |
| 54 database.close(); |
| 55 }).then(() => migrateDatabase(testCase, 2, (database, transaction) => { |
| 56 store = transaction.objectStore('not_books'); |
| 57 index = store.index('not_by_author'); |
| 58 |
| 59 database.deleteObjectStore('not_books'); |
| 60 assert_throws( |
| 61 'InvalidStateError', () => index.get('query'), |
| 62 'IDBIndex.get should throw InvalidStateError, indicating that ' + |
| 63 'the index is marked for deletion, immediately after ' + |
| 64 'IDBDatabase.deleteObjectStore() returns'); |
| 65 assert_array_equals( |
| 66 store.indexNames, [], |
| 67 'IDBObjectStore.indexNames should be empty immediately after ' + |
| 68 'IDBDatabase.deleteObjectStore() returns'); |
| 69 |
| 70 transaction.abort(); |
| 71 assert_throws( |
| 72 'TransactionInactiveError', () => index.get('query'), |
| 73 'IDBIndex.get should throw TransactionInactiveError, indicating ' + |
| 74 'that the index is no longer marked for deletion, immediately ' + |
| 75 'after IDBTransaction.abort() returns'); |
| 76 assert_array_equals( |
| 77 store.indexNames, ['not_by_author', 'not_by_title'], |
| 78 'IDBObjectStore.indexNames should include the deleted indexes ' + |
| 79 'immediately after IDBTransaction.abort() returns'); |
| 80 })).then(() => { |
| 81 assert_throws( |
| 82 'TransactionInactiveError', () => index.get('query'), |
| 83 'IDBIndex.get should throw TransactionInactiveError, indicating ' + |
| 84 'that the index is no longer marked for deletion, after the ' + |
| 85 'transaction is aborted'); |
| 86 assert_array_equals( |
| 87 store.indexNames, ['not_by_author', 'not_by_title'], |
| 88 'IDBObjectStore.indexNames should include the deleted indexes ' + |
| 89 'after the transaction is aborted'); |
| 90 }); |
| 91 }, 'Deleted stores get their indexes marked as not-deleted after the ' + |
| 92 'transaction that deleted them aborts'); |
| 93 |
| 94 promise_test(testCase => { |
| 95 let store = null, index = null; |
| 96 return createDatabase(testCase, (database, transaction) => { |
| 97 createBooksStore(testCase, database); |
| 98 }).then(database => { |
| 99 database.close(); |
| 100 }).then(() => migrateDatabase(testCase, 2, (database, transaction) => { |
| 101 store = createNotBooksStore(testCase, database); |
| 102 index = store.index('not_by_author'); |
| 103 assert_array_equals( |
| 104 store.indexNames, ['not_by_author', 'not_by_title'], |
| 105 'IDBObjectStore.indexNames should include newly created indexes ' + |
| 106 'before the transaction is aborted'); |
| 107 |
| 108 database.deleteObjectStore('not_books'); |
| 109 assert_throws( |
| 110 'InvalidStateError', () => index.get('query'), |
| 111 'IDBIndex.get should throw InvalidStateError, indicating that ' + |
| 112 'the index is marked for deletion, immediately after ' + |
| 113 'IDBDatabase.deleteObjectStore() returns'); |
| 114 assert_array_equals( |
| 115 store.indexNames, [], |
| 116 'IDBObjectStore.indexNames should be empty immediately after ' + |
| 117 'IDBDatabase.deleteObjectStore() returns'); |
| 118 |
| 119 transaction.abort(); |
| 120 assert_throws( |
| 121 'InvalidStateError', () => index.get('query'), |
| 122 'IDBIndex.get should throw InvalidStateError, indicating that ' + |
| 123 'the index is still marked for deletion, immediately after ' + |
| 124 'IDBTransaction.abort() returns'); |
| 125 assert_array_equals( |
| 126 store.indexNames, [], |
| 127 'IDBObjectStore.indexNames should not include the newly ' + |
| 128 'created indexes immediately after IDBTransaction.abort() returns'); |
| 129 })).then(() => { |
| 130 assert_throws( |
| 131 'InvalidStateError', () => index.get('query'), |
| 132 'IDBIndex.get should throw InvalidStateError, indicating that ' + |
| 133 'the index is still marked for deletion, after the transaction ' + |
| 134 'is aborted'); |
| 135 assert_array_equals( |
| 136 store.indexNames, [], |
| 137 'IDBObjectStore.indexNames should not include the newly ' + |
| 138 'created indexes after the transaction is aborted'); |
| 139 }); |
| 140 }, 'Created+deleted stores still have their indexes marked as deleted after ' + |
| 141 'the transaction aborts'); |
| 142 |
| 143 promise_test(testCase => { |
| 144 let store = null, index = null; |
| 145 return createDatabase(testCase, (database, transaction) => { |
| 146 createBooksStore(testCase, database); |
| 147 createNotBooksStore(testCase, database); |
| 148 }).then(database => { |
| 149 database.close(); |
| 150 }).then(() => migrateDatabase(testCase, 2, (database, transaction) => { |
| 151 store = transaction.objectStore('not_books'); |
| 152 index = store.createIndex('not_by_isbn', 'isbn'); |
| 153 assert_array_equals( |
| 154 store.indexNames, ['not_by_author', 'not_by_isbn', 'not_by_title'], |
| 155 'IDBObjectStore.indexNames should include newly created indexes ' + |
| 156 'before the transaction is aborted'); |
| 157 |
| 158 transaction.abort(); |
| 159 assert_throws( |
| 160 'InvalidStateError', () => index.get('query'), |
| 161 'IDBIndex.get should throw InvalidStateError, indicating that ' + |
| 162 'the index is marked for deletion, immediately after ' + |
| 163 'IDBTransaction.abort() returns'); |
| 164 assert_array_equals( |
| 165 store.indexNames, ['not_by_author', 'not_by_title'], |
| 166 'IDBObjectStore.indexNames should stop including the newly ' + |
| 167 'created index immediately after IDBTransaction.abort() returns'); |
| 168 })).then(() => { |
| 169 assert_throws( |
| 170 'InvalidStateError', () => index.get('query'), |
| 171 'IDBIndex.get should throw InvalidStateError, indicating that ' + |
| 172 'the index is marked for deletion, after the transaction is ' + |
| 173 'aborted'); |
| 174 assert_array_equals( |
| 175 store.indexNames, ['not_by_author', 'not_by_title'], |
| 176 'IDBObjectStore.indexNames should stop including the newly ' + |
| 177 'created index after the transaction is aborted'); |
| 178 }); |
| 179 }, 'Created indexes get marked as deleted after their transaction aborts'); |
| 180 |
| 181 promise_test(testCase => { |
| 182 let store = null, index = null; |
| 183 return createDatabase(testCase, (database, transaction) => { |
| 184 createBooksStore(testCase, database); |
| 185 createNotBooksStore(testCase, database); |
| 186 }).then(database => { |
| 187 database.close(); |
| 188 }).then(() => migrateDatabase(testCase, 2, (database, transaction) => { |
| 189 store = transaction.objectStore('not_books'); |
| 190 index = store.index('not_by_author'); |
| 191 |
| 192 store.deleteIndex('not_by_author'); |
| 193 assert_throws( |
| 194 'InvalidStateError', () => index.get('query'), |
| 195 'IDBIndex.get should throw InvalidStateError, indicating that ' + |
| 196 'the index is marked for deletion, immediately after ' + |
| 197 'IDBObjectStore.deleteIndex() returns'); |
| 198 assert_array_equals( |
| 199 store.indexNames, ['not_by_title'], |
| 200 'IDBObjectStore.indexNames should not include the deleted index ' + |
| 201 'immediately after IDBObjectStore.deleteIndex() returns'); |
| 202 |
| 203 transaction.abort(); |
| 204 assert_throws( |
| 205 'TransactionInactiveError', () => index.get('query'), |
| 206 'IDBIndex.get should throw TransactionInactiveError, indicating ' + |
| 207 'that the index is no longer marked for deletion, immediately ' + |
| 208 'after IDBTransaction.abort() returns'); |
| 209 assert_array_equals( |
| 210 store.indexNames, ['not_by_author', 'not_by_title'], |
| 211 'IDBObjectStore.indexNames should include the deleted indexes ' + |
| 212 'immediately after IDBTransaction.abort() returns'); |
| 213 })).then(() => { |
| 214 assert_throws( |
| 215 'TransactionInactiveError', () => index.get('query'), |
| 216 'IDBIndex.get should throw TransactionInactiveError, indicating ' + |
| 217 'that the index is no longer marked for deletion, after the ' + |
| 218 'transaction is aborted'); |
| 219 assert_array_equals( |
| 220 store.indexNames, ['not_by_author', 'not_by_title'], |
| 221 'IDBObjectStore.indexNames should include the deleted indexes ' + |
| 222 'after the transaction is aborted'); |
| 223 }); |
| 224 }, 'Deleted indexes get marked as not-deleted after the transaction aborts'); |
| 225 |
| 226 promise_test(testCase => { |
| 227 let store = null, index = null; |
| 228 return createDatabase(testCase, (database, transaction) => { |
| 229 createBooksStore(testCase, database); |
| 230 createNotBooksStore(testCase, database); |
| 231 }).then(database => { |
| 232 database.close(); |
| 233 }).then(() => migrateDatabase(testCase, 2, (database, transaction) => { |
| 234 store = transaction.objectStore('not_books'); |
| 235 index = store.createIndex('not_by_isbn', 'isbn'); |
| 236 assert_array_equals( |
| 237 store.indexNames, ['not_by_author', 'not_by_isbn', 'not_by_title'], |
| 238 'IDBObjectStore.indexNames should include newly created indexes ' + |
| 239 'before the transaction is aborted'); |
| 240 |
| 241 store.deleteIndex('not_by_isbn'); |
| 242 assert_throws( |
| 243 'InvalidStateError', () => index.get('query'), |
| 244 'IDBIndex.get should throw InvalidStateError, indicating that ' + |
| 245 'the index is marked for deletion, immediately after ' + |
| 246 'IDBObjectStore.deleteIndex() returns'); |
| 247 assert_array_equals( |
| 248 store.indexNames, ['not_by_author', 'not_by_title'], |
| 249 'IDBObjectStore.indexNames should not include the deleted index ' + |
| 250 'immediately after IDBObjectStore.deleteIndex() returns'); |
| 251 |
| 252 transaction.abort(); |
| 253 assert_throws( |
| 254 'InvalidStateError', () => index.get('query'), |
| 255 'IDBIndex.get should throw InvalidStateError, indicating that ' + |
| 256 'the index is still marked for deletion, immediately after ' + |
| 257 'IDBTransaction.abort() returns'); |
| 258 assert_array_equals( |
| 259 store.indexNames, ['not_by_author', 'not_by_title'], |
| 260 'IDBObjectStore.indexNames should stop including the newly ' + |
| 261 'created index immediately after IDBTransaction.abort() returns'); |
| 262 })).then(() => { |
| 263 assert_throws( |
| 264 'InvalidStateError', () => index.get('query'), |
| 265 'IDBIndex.get should throw InvalidStateError, indicating that ' + |
| 266 'the index is marked for deletion, after the transaction is ' + |
| 267 'aborted'); |
| 268 assert_array_equals( |
| 269 store.indexNames, ['not_by_author', 'not_by_title'], |
| 270 'IDBObjectStore.indexNames should stop including the newly ' + |
| 271 'created index after the transaction is aborted'); |
| 272 }); |
| 273 }, 'Created+deleted indexes are still marked as deleted after their ' + |
| 274 'transaction aborts'); |
| 275 |
| 276 </script> |
OLD | NEW |