forked from mirrors/gecko-dev
		
	# ignore-this-changeset Differential Revision: https://phabricator.services.mozilla.com/D36042 --HG-- extra : source : d3afcafdce650a6f36cebbc126ee93b17f13cf52
		
			
				
	
	
		
			197 lines
		
	
	
	
		
			5.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			197 lines
		
	
	
	
		
			5.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
/* Any copyright is dedicated to the Public Domain.
 | 
						|
   http://creativecommons.org/publicdomain/zero/1.0/ */
 | 
						|
 | 
						|
ChromeUtils.import("resource://gre/modules/Services.jsm", this);
 | 
						|
ChromeUtils.import("resource://gre/modules/osfile.jsm", this);
 | 
						|
ChromeUtils.import("resource://gre/modules/Preferences.jsm", this);
 | 
						|
 | 
						|
const Paths = SessionFile.Paths;
 | 
						|
const PREF_UPGRADE = "browser.sessionstore.upgradeBackup.latestBuildID";
 | 
						|
const PREF_MAX_UPGRADE_BACKUPS =
 | 
						|
  "browser.sessionstore.upgradeBackup.maxUpgradeBackups";
 | 
						|
 | 
						|
/**
 | 
						|
 * Prepares tests by retrieving the current platform's build ID, clearing the
 | 
						|
 * build where the last backup was created and creating arbitrary JSON data
 | 
						|
 * for a new backup.
 | 
						|
 */
 | 
						|
function prepareTest() {
 | 
						|
  let result = {};
 | 
						|
 | 
						|
  result.buildID = Services.appinfo.platformBuildID;
 | 
						|
  Services.prefs.setCharPref(PREF_UPGRADE, "");
 | 
						|
  result.contents = JSON.stringify({
 | 
						|
    "browser_upgrade_backup.js": Math.random(),
 | 
						|
  });
 | 
						|
 | 
						|
  return result;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Retrieves all upgrade backups and returns them in an array.
 | 
						|
 */
 | 
						|
async function getUpgradeBackups() {
 | 
						|
  let iterator;
 | 
						|
  let backups = [];
 | 
						|
 | 
						|
  try {
 | 
						|
    iterator = new OS.File.DirectoryIterator(Paths.backups);
 | 
						|
 | 
						|
    // iterate over all files in the backup directory
 | 
						|
    await iterator.forEach(function(file) {
 | 
						|
      // check the upgradeBackupPrefix
 | 
						|
      if (file.path.startsWith(Paths.upgradeBackupPrefix)) {
 | 
						|
        // the file is a backup
 | 
						|
        backups.push(file.path);
 | 
						|
      }
 | 
						|
    }, this);
 | 
						|
  } finally {
 | 
						|
    if (iterator) {
 | 
						|
      iterator.close();
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  // return results
 | 
						|
  return backups;
 | 
						|
}
 | 
						|
 | 
						|
add_task(async function init() {
 | 
						|
  // Wait until initialization is complete
 | 
						|
  await SessionStore.promiseInitialized;
 | 
						|
});
 | 
						|
 | 
						|
add_task(async function test_upgrade_backup() {
 | 
						|
  let test = prepareTest();
 | 
						|
  info("Let's check if we create an upgrade backup");
 | 
						|
  await SessionFile.wipe();
 | 
						|
  await OS.File.writeAtomic(Paths.clean, test.contents, {
 | 
						|
    encoding: "utf-8",
 | 
						|
    compression: "lz4",
 | 
						|
  });
 | 
						|
  await SessionFile.read(); // First call to read() initializes the SessionWorker
 | 
						|
  await SessionFile.write(""); // First call to write() triggers the backup
 | 
						|
 | 
						|
  is(
 | 
						|
    Services.prefs.getCharPref(PREF_UPGRADE),
 | 
						|
    test.buildID,
 | 
						|
    "upgrade backup should be set"
 | 
						|
  );
 | 
						|
 | 
						|
  is(
 | 
						|
    await OS.File.exists(Paths.upgradeBackup),
 | 
						|
    true,
 | 
						|
    "upgrade backup file has been created"
 | 
						|
  );
 | 
						|
 | 
						|
  let data = await OS.File.read(Paths.upgradeBackup, { compression: "lz4" });
 | 
						|
  is(
 | 
						|
    test.contents,
 | 
						|
    new TextDecoder().decode(data),
 | 
						|
    "upgrade backup contains the expected contents"
 | 
						|
  );
 | 
						|
 | 
						|
  info("Let's check that we don't overwrite this upgrade backup");
 | 
						|
  let newContents = JSON.stringify({
 | 
						|
    "something else entirely": Math.random(),
 | 
						|
  });
 | 
						|
  await OS.File.writeAtomic(Paths.clean, newContents, {
 | 
						|
    encoding: "utf-8",
 | 
						|
    compression: "lz4",
 | 
						|
  });
 | 
						|
  await SessionFile.read(); // Reinitialize the SessionWorker
 | 
						|
  await SessionFile.write(""); // Next call to write() shouldn't trigger the backup
 | 
						|
  data = await OS.File.read(Paths.upgradeBackup, { compression: "lz4" });
 | 
						|
  is(
 | 
						|
    test.contents,
 | 
						|
    new TextDecoder().decode(data),
 | 
						|
    "upgrade backup hasn't changed"
 | 
						|
  );
 | 
						|
});
 | 
						|
 | 
						|
add_task(async function test_upgrade_backup_removal() {
 | 
						|
  let test = prepareTest();
 | 
						|
  let maxUpgradeBackups = Preferences.get(PREF_MAX_UPGRADE_BACKUPS, 3);
 | 
						|
  info("Let's see if we remove backups if there are too many");
 | 
						|
  await SessionFile.wipe();
 | 
						|
  await OS.File.makeDir(Paths.backups);
 | 
						|
  await OS.File.writeAtomic(Paths.clean, test.contents, {
 | 
						|
    encoding: "utf-8",
 | 
						|
    compression: "lz4",
 | 
						|
  });
 | 
						|
 | 
						|
  // if the nextUpgradeBackup already exists (from another test), remove it
 | 
						|
  if (OS.File.exists(Paths.nextUpgradeBackup)) {
 | 
						|
    await OS.File.remove(Paths.nextUpgradeBackup);
 | 
						|
  }
 | 
						|
 | 
						|
  // create dummy backups
 | 
						|
  await OS.File.writeAtomic(Paths.upgradeBackupPrefix + "20080101010101", "", {
 | 
						|
    encoding: "utf-8",
 | 
						|
    compression: "lz4",
 | 
						|
  });
 | 
						|
  await OS.File.writeAtomic(Paths.upgradeBackupPrefix + "20090101010101", "", {
 | 
						|
    encoding: "utf-8",
 | 
						|
    compression: "lz4",
 | 
						|
  });
 | 
						|
  await OS.File.writeAtomic(Paths.upgradeBackupPrefix + "20100101010101", "", {
 | 
						|
    encoding: "utf-8",
 | 
						|
    compression: "lz4",
 | 
						|
  });
 | 
						|
  await OS.File.writeAtomic(Paths.upgradeBackupPrefix + "20110101010101", "", {
 | 
						|
    encoding: "utf-8",
 | 
						|
    compression: "lz4",
 | 
						|
  });
 | 
						|
  await OS.File.writeAtomic(Paths.upgradeBackupPrefix + "20120101010101", "", {
 | 
						|
    encoding: "utf-8",
 | 
						|
    compression: "lz4",
 | 
						|
  });
 | 
						|
  await OS.File.writeAtomic(Paths.upgradeBackupPrefix + "20130101010101", "", {
 | 
						|
    encoding: "utf-8",
 | 
						|
    compression: "lz4",
 | 
						|
  });
 | 
						|
 | 
						|
  // get currently existing backups
 | 
						|
  let backups = await getUpgradeBackups();
 | 
						|
 | 
						|
  // trigger new backup
 | 
						|
  await SessionFile.read(); // First call to read() initializes the SessionWorker
 | 
						|
  await SessionFile.write(""); // First call to write() triggers the backup and the cleanup
 | 
						|
 | 
						|
  // a new backup should have been created (and still exist)
 | 
						|
  is(
 | 
						|
    Services.prefs.getCharPref(PREF_UPGRADE),
 | 
						|
    test.buildID,
 | 
						|
    "upgrade backup should be set"
 | 
						|
  );
 | 
						|
  is(
 | 
						|
    await OS.File.exists(Paths.upgradeBackup),
 | 
						|
    true,
 | 
						|
    "upgrade backup file has been created"
 | 
						|
  );
 | 
						|
 | 
						|
  // get currently existing backups and check their count
 | 
						|
  let newBackups = await getUpgradeBackups();
 | 
						|
  is(
 | 
						|
    newBackups.length,
 | 
						|
    maxUpgradeBackups,
 | 
						|
    "expected number of backups are present after removing old backups"
 | 
						|
  );
 | 
						|
 | 
						|
  // find all backups that were created during the last call to `SessionFile.write("");`
 | 
						|
  // ie, filter out all the backups that have already been present before the call
 | 
						|
  newBackups = newBackups.filter(function(backup) {
 | 
						|
    return !backups.includes(backup);
 | 
						|
  });
 | 
						|
 | 
						|
  // check that exactly one new backup was created
 | 
						|
  is(newBackups.length, 1, "one new backup was created that was not removed");
 | 
						|
 | 
						|
  await SessionFile.write(""); // Second call to write() should not trigger anything
 | 
						|
 | 
						|
  backups = await getUpgradeBackups();
 | 
						|
  is(
 | 
						|
    backups.length,
 | 
						|
    maxUpgradeBackups,
 | 
						|
    "second call to SessionFile.write() didn't create or remove more backups"
 | 
						|
  );
 | 
						|
});
 |