tor-browser

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

test_storage_adapter.js (10582B)


      1 /* Any copyright is dedicated to the Public Domain.
      2   http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 const { Sqlite } = ChromeUtils.importESModule(
      5  "resource://gre/modules/Sqlite.sys.mjs"
      6 );
      7 const { FirefoxAdapter } = ChromeUtils.importESModule(
      8  "resource://services-common/kinto-storage-adapter.sys.mjs"
      9 );
     10 
     11 // set up what we need to make storage adapters
     12 const kintoFilename = "kinto.sqlite";
     13 
     14 function do_get_kinto_connection() {
     15  return FirefoxAdapter.openConnection({ path: kintoFilename });
     16 }
     17 
     18 function do_get_kinto_adapter(sqliteHandle) {
     19  return new FirefoxAdapter("test", { sqliteHandle });
     20 }
     21 
     22 function do_get_kinto_db() {
     23  let profile = do_get_profile();
     24  let kintoDB = profile.clone();
     25  kintoDB.append(kintoFilename);
     26  return kintoDB;
     27 }
     28 
     29 function cleanup_kinto() {
     30  add_test(function cleanup_kinto_files() {
     31    let kintoDB = do_get_kinto_db();
     32    // clean up the db
     33    kintoDB.remove(false);
     34    run_next_test();
     35  });
     36 }
     37 
     38 function test_collection_operations() {
     39  add_task(async function test_kinto_clear() {
     40    let sqliteHandle = await do_get_kinto_connection();
     41    let adapter = do_get_kinto_adapter(sqliteHandle);
     42    await adapter.clear();
     43    await sqliteHandle.close();
     44  });
     45 
     46  // test creating new records... and getting them again
     47  add_task(async function test_kinto_create_new_get_existing() {
     48    let sqliteHandle = await do_get_kinto_connection();
     49    let adapter = do_get_kinto_adapter(sqliteHandle);
     50    let record = { id: "test-id", foo: "bar" };
     51    await adapter.execute(transaction => transaction.create(record));
     52    let newRecord = await adapter.get("test-id");
     53    // ensure the record is the same as when it was added
     54    deepEqual(record, newRecord);
     55    await sqliteHandle.close();
     56  });
     57 
     58  // test removing records
     59  add_task(async function test_kinto_can_remove_some_records() {
     60    let sqliteHandle = await do_get_kinto_connection();
     61    let adapter = do_get_kinto_adapter(sqliteHandle);
     62    // create a second record
     63    let record = { id: "test-id-2", foo: "baz" };
     64    await adapter.execute(transaction => transaction.create(record));
     65    let newRecord = await adapter.get("test-id-2");
     66    deepEqual(record, newRecord);
     67    // delete the record
     68    await adapter.execute(transaction => transaction.delete(record.id));
     69    newRecord = await adapter.get(record.id);
     70    // ... and ensure it's no longer there
     71    Assert.equal(newRecord, undefined);
     72    // ensure the other record still exists
     73    newRecord = await adapter.get("test-id");
     74    Assert.notEqual(newRecord, undefined);
     75    await sqliteHandle.close();
     76  });
     77 
     78  // test getting records that don't exist
     79  add_task(async function test_kinto_get_non_existant() {
     80    let sqliteHandle = await do_get_kinto_connection();
     81    let adapter = do_get_kinto_adapter(sqliteHandle);
     82    // Kinto expects adapters to either:
     83    let newRecord = await adapter.get("missing-test-id");
     84    // resolve with an undefined record
     85    Assert.equal(newRecord, undefined);
     86    await sqliteHandle.close();
     87  });
     88 
     89  // test updating records... and getting them again
     90  add_task(async function test_kinto_update_get_existing() {
     91    let sqliteHandle = await do_get_kinto_connection();
     92    let adapter = do_get_kinto_adapter(sqliteHandle);
     93    let originalRecord = { id: "test-id", foo: "bar" };
     94    let updatedRecord = { id: "test-id", foo: "baz" };
     95    await adapter.clear();
     96    await adapter.execute(transaction => transaction.create(originalRecord));
     97    await adapter.execute(transaction => transaction.update(updatedRecord));
     98    // ensure the record exists
     99    let newRecord = await adapter.get("test-id");
    100    // ensure the record is the same as when it was added
    101    deepEqual(updatedRecord, newRecord);
    102    await sqliteHandle.close();
    103  });
    104 
    105  // test listing records
    106  add_task(async function test_kinto_list() {
    107    let sqliteHandle = await do_get_kinto_connection();
    108    let adapter = do_get_kinto_adapter(sqliteHandle);
    109    let originalRecord = { id: "test-id-1", foo: "bar" };
    110    let records = await adapter.list();
    111    Assert.equal(records.length, 1);
    112    await adapter.execute(transaction => transaction.create(originalRecord));
    113    records = await adapter.list();
    114    Assert.equal(records.length, 2);
    115    await sqliteHandle.close();
    116  });
    117 
    118  // test aborting transaction
    119  add_task(async function test_kinto_aborting_transaction() {
    120    let sqliteHandle = await do_get_kinto_connection();
    121    let adapter = do_get_kinto_adapter(sqliteHandle);
    122    await adapter.clear();
    123    let record = { id: 1, foo: "bar" };
    124    let error = null;
    125    try {
    126      await adapter.execute(transaction => {
    127        transaction.create(record);
    128        throw new Error("unexpected");
    129      });
    130    } catch (e) {
    131      error = e;
    132    }
    133    Assert.notEqual(error, null);
    134    let records = await adapter.list();
    135    Assert.equal(records.length, 0);
    136    await sqliteHandle.close();
    137  });
    138 
    139  // test save and get last modified
    140  add_task(async function test_kinto_last_modified() {
    141    const initialValue = 0;
    142    const intendedValue = 12345678;
    143 
    144    let sqliteHandle = await do_get_kinto_connection();
    145    let adapter = do_get_kinto_adapter(sqliteHandle);
    146    let lastModified = await adapter.getLastModified();
    147    Assert.equal(lastModified, initialValue);
    148    let result = await adapter.saveLastModified(intendedValue);
    149    Assert.equal(result, intendedValue);
    150    lastModified = await adapter.getLastModified();
    151    Assert.equal(lastModified, intendedValue);
    152 
    153    // test saveLastModified parses values correctly
    154    result = await adapter.saveLastModified(" " + intendedValue + " blah");
    155    // should resolve with the parsed int
    156    Assert.equal(result, intendedValue);
    157    // and should have saved correctly
    158    lastModified = await adapter.getLastModified();
    159    Assert.equal(lastModified, intendedValue);
    160    await sqliteHandle.close();
    161  });
    162 
    163  // test loadDump(records)
    164  add_task(async function test_kinto_import_records() {
    165    let sqliteHandle = await do_get_kinto_connection();
    166    let adapter = do_get_kinto_adapter(sqliteHandle);
    167    let record1 = { id: 1, foo: "bar" };
    168    let record2 = { id: 2, foo: "baz" };
    169    let impactedRecords = await adapter.loadDump([record1, record2]);
    170    Assert.equal(impactedRecords.length, 2);
    171    let newRecord1 = await adapter.get("1");
    172    // ensure the record is the same as when it was added
    173    deepEqual(record1, newRecord1);
    174    let newRecord2 = await adapter.get("2");
    175    // ensure the record is the same as when it was added
    176    deepEqual(record2, newRecord2);
    177    await sqliteHandle.close();
    178  });
    179 
    180  add_task(async function test_kinto_import_records_should_override_existing() {
    181    let sqliteHandle = await do_get_kinto_connection();
    182    let adapter = do_get_kinto_adapter(sqliteHandle);
    183    await adapter.clear();
    184    let records = await adapter.list();
    185    Assert.equal(records.length, 0);
    186    let impactedRecords = await adapter.loadDump([
    187      { id: 1, foo: "bar" },
    188      { id: 2, foo: "baz" },
    189    ]);
    190    Assert.equal(impactedRecords.length, 2);
    191    await adapter.loadDump([
    192      { id: 1, foo: "baz" },
    193      { id: 3, foo: "bab" },
    194    ]);
    195    records = await adapter.list();
    196    Assert.equal(records.length, 3);
    197    let newRecord1 = await adapter.get("1");
    198    deepEqual(newRecord1.foo, "baz");
    199    await sqliteHandle.close();
    200  });
    201 
    202  add_task(async function test_import_updates_lastModified() {
    203    let sqliteHandle = await do_get_kinto_connection();
    204    let adapter = do_get_kinto_adapter(sqliteHandle);
    205    await adapter.loadDump([
    206      { id: 1, foo: "bar", last_modified: 1457896541 },
    207      { id: 2, foo: "baz", last_modified: 1458796542 },
    208    ]);
    209    let lastModified = await adapter.getLastModified();
    210    Assert.equal(lastModified, 1458796542);
    211    await sqliteHandle.close();
    212  });
    213 
    214  add_task(async function test_import_preserves_older_lastModified() {
    215    let sqliteHandle = await do_get_kinto_connection();
    216    let adapter = do_get_kinto_adapter(sqliteHandle);
    217    await adapter.saveLastModified(1458796543);
    218 
    219    await adapter.loadDump([
    220      { id: 1, foo: "bar", last_modified: 1457896541 },
    221      { id: 2, foo: "baz", last_modified: 1458796542 },
    222    ]);
    223    let lastModified = await adapter.getLastModified();
    224    Assert.equal(lastModified, 1458796543);
    225    await sqliteHandle.close();
    226  });
    227 
    228  add_task(async function test_save_metadata_preserves_lastModified() {
    229    let sqliteHandle = await do_get_kinto_connection();
    230 
    231    let adapter = do_get_kinto_adapter(sqliteHandle);
    232    await adapter.saveLastModified(42);
    233 
    234    await adapter.saveMetadata({ id: "col" });
    235 
    236    let lastModified = await adapter.getLastModified();
    237    Assert.equal(lastModified, 42);
    238    await sqliteHandle.close();
    239  });
    240 }
    241 
    242 // test kinto db setup and operations in various scenarios
    243 // test from scratch - no current existing database
    244 add_test(function test_db_creation() {
    245  add_test(function test_create_from_scratch() {
    246    // ensure the file does not exist in the profile
    247    let kintoDB = do_get_kinto_db();
    248    Assert.ok(!kintoDB.exists());
    249    run_next_test();
    250  });
    251 
    252  test_collection_operations();
    253 
    254  cleanup_kinto();
    255  run_next_test();
    256 });
    257 
    258 // this is the closest we can get to a schema version upgrade at v1 - test an
    259 // existing database
    260 add_test(function test_creation_from_empty_db() {
    261  add_test(function test_create_from_empty_db() {
    262    // place an empty kinto db file in the profile
    263    let profile = do_get_profile();
    264 
    265    let emptyDB = do_get_file("test_storage_adapter/empty.sqlite");
    266    emptyDB.copyTo(profile, kintoFilename);
    267 
    268    run_next_test();
    269  });
    270 
    271  test_collection_operations();
    272 
    273  cleanup_kinto();
    274  run_next_test();
    275 });
    276 
    277 // test schema version upgrade at v2
    278 add_test(function test_migration_from_v1_to_v2() {
    279  add_test(function test_migrate_from_v1_to_v2() {
    280    // place an empty kinto db file in the profile
    281    let profile = do_get_profile();
    282 
    283    let v1DB = do_get_file("test_storage_adapter/v1.sqlite");
    284    v1DB.copyTo(profile, kintoFilename);
    285 
    286    run_next_test();
    287  });
    288 
    289  add_test(async function schema_is_update_from_1_to_2() {
    290    // The `v1.sqlite` has schema version 1.
    291    let sqliteHandle = await Sqlite.openConnection({ path: kintoFilename });
    292    Assert.equal(await sqliteHandle.getSchemaVersion(), 1);
    293    await sqliteHandle.close();
    294 
    295    // The `.openConnection()` migrates it to version 2.
    296    sqliteHandle = await FirefoxAdapter.openConnection({ path: kintoFilename });
    297    Assert.equal(await sqliteHandle.getSchemaVersion(), 2);
    298    await sqliteHandle.close();
    299 
    300    run_next_test();
    301  });
    302 
    303  test_collection_operations();
    304 
    305  cleanup_kinto();
    306  run_next_test();
    307 });