tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

transaction-abort-multiple-metadata-revert.any.js (18144B)


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