OLD | NEW |
| (Empty) |
1 <!DOCTYPE html> | |
2 <title>IndexedDB: aborting transactions reverts multiple operations on the same
metadata</title> | |
3 <link rel="help" href="https://w3c.github.io/IndexedDB/#abort-transaction"> | |
4 <link rel="author" href="pwnall@chromium.org" title="Victor Costan"> | |
5 <script src="/resources/testharness.js"></script> | |
6 <script src="/resources/testharnessreport.js"></script> | |
7 <script src="support-promises.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 |