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