tor-browser

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

test_BackupResource.js (8414B)


      1 /* Any copyright is dedicated to the Public Domain.
      2 http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 "use strict";
      5 
      6 const { bytesToFuzzyKilobytes } = ChromeUtils.importESModule(
      7  "resource:///modules/backup/BackupResource.sys.mjs"
      8 );
      9 
     10 const { BookmarksBackupResource } = ChromeUtils.importESModule(
     11  "resource:///modules/backup/BookmarksBackupResource.sys.mjs"
     12 );
     13 
     14 const { PlacesBackupResource } = ChromeUtils.importESModule(
     15  "resource:///modules/backup/PlacesBackupResource.sys.mjs"
     16 );
     17 
     18 const EXPECTED_KILOBYTES_FOR_XULSTORE = 1;
     19 
     20 /**
     21 * Tests that BackupService.getFileSize will get the size of a file in kilobytes.
     22 */
     23 add_task(async function test_getFileSize() {
     24  let file = do_get_file("data/test_xulstore.json");
     25 
     26  let testFilePath = PathUtils.join(PathUtils.profileDir, "test_xulstore.json");
     27 
     28  await IOUtils.copy(file.path, PathUtils.profileDir);
     29 
     30  let size = await BackupResource.getFileSize(testFilePath);
     31 
     32  Assert.equal(
     33    size,
     34    EXPECTED_KILOBYTES_FOR_XULSTORE,
     35    "Size of the test_xulstore.json is rounded up to the nearest kilobyte."
     36  );
     37 
     38  await IOUtils.remove(testFilePath);
     39 });
     40 
     41 /**
     42 * Tests that BackupService.getDirectorySize will get the total size of all the
     43 * files in a directory and it's children in kilobytes.
     44 */
     45 add_task(async function test_getDirectorySize() {
     46  let file = do_get_file("data/test_xulstore.json");
     47 
     48  // Create a test directory with the test json file in it.
     49  let testDir = PathUtils.join(PathUtils.profileDir, "testDir");
     50  await IOUtils.makeDirectory(testDir);
     51  await IOUtils.copy(file.path, testDir);
     52 
     53  // Create another test directory inside of that one.
     54  let nestedTestDir = PathUtils.join(testDir, "testDir");
     55  await IOUtils.makeDirectory(nestedTestDir);
     56  await IOUtils.copy(file.path, nestedTestDir);
     57 
     58  let size = await BackupResource.getDirectorySize(testDir);
     59 
     60  Assert.equal(
     61    size,
     62    EXPECTED_KILOBYTES_FOR_XULSTORE * 2,
     63    `Total size of the directory is rounded up to the nearest kilobyte
     64    and is equal to twice the size of the test_xulstore.json file`
     65  );
     66 
     67  await IOUtils.remove(testDir, { recursive: true });
     68 });
     69 
     70 /**
     71 * Tests that bytesToFuzzyKilobytes will convert bytes to kilobytes
     72 * and round to the nearest tenth kilobyte.
     73 */
     74 add_task(async function test_bytesToFuzzyKilobytes() {
     75  let largeSize = bytesToFuzzyKilobytes(1234000);
     76 
     77  Assert.equal(
     78    largeSize,
     79    1230,
     80    "1234 bytes is rounded to the nearest mulitple of ten kilobytes, 1230"
     81  );
     82 
     83  let smallSize = bytesToFuzzyKilobytes(3);
     84 
     85  Assert.equal(smallSize, 1, "Sizes under 10 kilobytes return 1 kilobyte");
     86 });
     87 
     88 /**
     89 * Tests that BackupResource.copySqliteDatabases will call `backup` on a new
     90 * read-only connection on each database file.
     91 */
     92 add_task(async function test_copySqliteDatabases() {
     93  let sandbox = sinon.createSandbox();
     94  const SQLITE_PAGES_PER_STEP_PREF = "browser.backup.sqlite.pages_per_step";
     95  const SQLITE_STEP_DELAY_MS_PREF = "browser.backup.sqlite.step_delay_ms";
     96  const DEFAULT_SQLITE_PAGES_PER_STEP = Services.prefs.getIntPref(
     97    SQLITE_PAGES_PER_STEP_PREF
     98  );
     99  const DEFAULT_SQLITE_STEP_DELAY_MS = Services.prefs.getIntPref(
    100    SQLITE_STEP_DELAY_MS_PREF
    101  );
    102 
    103  let sourcePath = await IOUtils.createUniqueDirectory(
    104    PathUtils.tempDir,
    105    "BackupResource-source-test"
    106  );
    107  let destPath = await IOUtils.createUniqueDirectory(
    108    PathUtils.tempDir,
    109    "BackupResource-dest-test"
    110  );
    111  let pretendDatabases = ["places.sqlite", "favicons.sqlite"];
    112  await createTestFiles(
    113    sourcePath,
    114    pretendDatabases.map(f => ({ path: f }))
    115  );
    116 
    117  let fakeConnection = {
    118    backup: sandbox.stub().resolves(true),
    119    close: sandbox.stub().resolves(true),
    120  };
    121  sandbox.stub(Sqlite, "openConnection").returns(fakeConnection);
    122 
    123  await BackupResource.copySqliteDatabases(
    124    sourcePath,
    125    destPath,
    126    pretendDatabases
    127  );
    128 
    129  Assert.ok(
    130    Sqlite.openConnection.calledTwice,
    131    "Sqlite.openConnection called twice"
    132  );
    133  Assert.ok(
    134    Sqlite.openConnection.firstCall.calledWith({
    135      path: PathUtils.join(sourcePath, "places.sqlite"),
    136      readOnly: true,
    137    }),
    138    "openConnection called with places.sqlite as read-only"
    139  );
    140  Assert.ok(
    141    Sqlite.openConnection.secondCall.calledWith({
    142      path: PathUtils.join(sourcePath, "favicons.sqlite"),
    143      readOnly: true,
    144    }),
    145    "openConnection called with favicons.sqlite as read-only"
    146  );
    147 
    148  Assert.ok(
    149    fakeConnection.backup.calledTwice,
    150    "backup on an Sqlite connection called twice"
    151  );
    152  Assert.ok(
    153    fakeConnection.backup.firstCall.calledWith(
    154      PathUtils.join(destPath, "places.sqlite"),
    155      DEFAULT_SQLITE_PAGES_PER_STEP,
    156      DEFAULT_SQLITE_STEP_DELAY_MS
    157    ),
    158    "backup called with places.sqlite to the destination path with the right " +
    159      "pages per step and step delay"
    160  );
    161  Assert.ok(
    162    fakeConnection.backup.secondCall.calledWith(
    163      PathUtils.join(destPath, "favicons.sqlite"),
    164      DEFAULT_SQLITE_PAGES_PER_STEP,
    165      DEFAULT_SQLITE_STEP_DELAY_MS
    166    ),
    167    "backup called with favicons.sqlite to the destination path with the " +
    168      "right pages per step and step delay"
    169  );
    170 
    171  Assert.ok(
    172    fakeConnection.close.calledTwice,
    173    "close on an Sqlite connection called twice"
    174  );
    175 
    176  // Now check that we can override the default pages per step and step delay.
    177  fakeConnection.backup.resetHistory();
    178  const NEW_SQLITE_PAGES_PER_STEP = 10;
    179  const NEW_SQLITE_STEP_DELAY_MS = 500;
    180  Services.prefs.setIntPref(
    181    SQLITE_PAGES_PER_STEP_PREF,
    182    NEW_SQLITE_PAGES_PER_STEP
    183  );
    184  Services.prefs.setIntPref(
    185    SQLITE_STEP_DELAY_MS_PREF,
    186    NEW_SQLITE_STEP_DELAY_MS
    187  );
    188  await BackupResource.copySqliteDatabases(
    189    sourcePath,
    190    destPath,
    191    pretendDatabases
    192  );
    193  Assert.ok(
    194    fakeConnection.backup.calledTwice,
    195    "backup on an Sqlite connection called twice"
    196  );
    197  Assert.ok(
    198    fakeConnection.backup.firstCall.calledWith(
    199      PathUtils.join(destPath, "places.sqlite"),
    200      NEW_SQLITE_PAGES_PER_STEP,
    201      NEW_SQLITE_STEP_DELAY_MS
    202    ),
    203    "backup called with places.sqlite to the destination path with the right " +
    204      "pages per step and step delay"
    205  );
    206  Assert.ok(
    207    fakeConnection.backup.secondCall.calledWith(
    208      PathUtils.join(destPath, "favicons.sqlite"),
    209      NEW_SQLITE_PAGES_PER_STEP,
    210      NEW_SQLITE_STEP_DELAY_MS
    211    ),
    212    "backup called with favicons.sqlite to the destination path with the " +
    213      "right pages per step and step delay"
    214  );
    215 
    216  await maybeRemovePath(sourcePath);
    217  await maybeRemovePath(destPath);
    218  sandbox.restore();
    219 });
    220 
    221 /**
    222 * Tests that BackupResource.copyFiles will copy files from one directory to
    223 * another.
    224 */
    225 add_task(async function test_copyFiles() {
    226  let sourcePath = await IOUtils.createUniqueDirectory(
    227    PathUtils.tempDir,
    228    "BackupResource-source-test"
    229  );
    230  let destPath = await IOUtils.createUniqueDirectory(
    231    PathUtils.tempDir,
    232    "BackupResource-dest-test"
    233  );
    234 
    235  const testFiles = [
    236    { path: "file1.txt" },
    237    { path: ["some", "nested", "file", "file2.txt"] },
    238    { path: "file3.txt" },
    239  ];
    240 
    241  await createTestFiles(sourcePath, testFiles);
    242 
    243  await BackupResource.copyFiles(sourcePath, destPath, [
    244    "file1.txt",
    245    "some",
    246    "file3.txt",
    247    "does-not-exist.txt",
    248  ]);
    249 
    250  await assertFilesExist(destPath, testFiles);
    251  Assert.ok(
    252    !(await IOUtils.exists(PathUtils.join(destPath, "does-not-exist.txt"))),
    253    "does-not-exist.txt wasn't somehow written to."
    254  );
    255 
    256  await maybeRemovePath(sourcePath);
    257  await maybeRemovePath(destPath);
    258 });
    259 
    260 add_task(async function test_bookmarks_places_backup_relation() {
    261  // If places can be backed up, we don't need to backup bookmarks separately
    262  Services.prefs.setBoolPref(HISTORY_ENABLED_PREF, true);
    263  Services.prefs.setBoolPref(SANITIZE_ON_SHUTDOWN_PREF, false);
    264 
    265  Assert.ok(PlacesBackupResource.canBackupResource, "Places can be backed up");
    266 
    267  Assert.ok(
    268    !BookmarksBackupResource.canBackupResource,
    269    "Bookmarks won't be backed up separately"
    270  );
    271 
    272  // If places can't be backed up, we need to backup bookmarks separately
    273  Services.prefs.setBoolPref(SANITIZE_ON_SHUTDOWN_PREF, true);
    274 
    275  Assert.ok(
    276    !PlacesBackupResource.canBackupResource,
    277    "Places can not be backed up"
    278  );
    279 
    280  Assert.ok(
    281    BookmarksBackupResource.canBackupResource,
    282    "Bookmarks will be backed up separately"
    283  );
    284 
    285  Services.prefs.clearUserPref(HISTORY_ENABLED_PREF);
    286  Services.prefs.clearUserPref(SANITIZE_ON_SHUTDOWN_PREF);
    287 });