tor-browser

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

test_final_write_cleanup.js (3821B)


      1 "use strict";
      2 
      3 /**
      4 * This test ensures that we correctly clean up the session state when
      5 * writing with isFinalWrite, which is used on shutdown. It tests that each
      6 * tab's shistory is capped to a maximum number of preceding and succeeding
      7 * entries.
      8 */
      9 
     10 const { SessionWriter } = ChromeUtils.importESModule(
     11  "resource:///modules/sessionstore/SessionWriter.sys.mjs"
     12 );
     13 
     14 // Make sure that we have a profile before initializing SessionFile.
     15 do_get_profile();
     16 const {
     17  SessionFile: { Paths },
     18 } = ChromeUtils.importESModule(
     19  "resource:///modules/sessionstore/SessionFile.sys.mjs"
     20 );
     21 
     22 const MAX_ENTRIES = 9;
     23 const URL = "http://example.com/#";
     24 
     25 async function prepareWithLimit(back, fwd) {
     26  SessionWriter.init("empty", false, Paths, {
     27    maxSerializeBack: back,
     28    maxSerializeForward: fwd,
     29    maxUpgradeBackups: 3,
     30  });
     31  await SessionWriter.wipe();
     32 }
     33 
     34 add_setup(async function () {
     35  registerCleanupFunction(() => SessionWriter.wipe());
     36 });
     37 
     38 function createSessionState(index) {
     39  // Generate the tab state entries and set the one-based
     40  // tab-state index to the middle session history entry.
     41  let tabState = { entries: [], index };
     42  for (let i = 0; i < MAX_ENTRIES; i++) {
     43    tabState.entries.push({ url: URL + i });
     44  }
     45 
     46  return { windows: [{ tabs: [tabState] }] };
     47 }
     48 
     49 async function writeAndParse(state, path, options = {}) {
     50  // We clone here because `write` can change the data passed.
     51  let data = structuredClone(state);
     52  await SessionWriter.write(data, options);
     53  return IOUtils.readJSON(path, { decompress: true });
     54 }
     55 
     56 add_task(async function test_shistory_cap_none() {
     57  let state = createSessionState(5);
     58 
     59  // Don't limit the number of shistory entries.
     60  await prepareWithLimit(-1, -1);
     61 
     62  // Check that no caps are applied.
     63  let diskState = await writeAndParse(state, Paths.clean, {
     64    isFinalWrite: true,
     65  });
     66  Assert.deepEqual(state, diskState, "no cap applied");
     67 });
     68 
     69 add_task(async function test_shistory_cap_middle() {
     70  let state = createSessionState(5);
     71  await prepareWithLimit(2, 3);
     72 
     73  // Cap is only applied on clean shutdown.
     74  let diskState = await writeAndParse(state, Paths.recovery);
     75  Assert.deepEqual(state, diskState, "no cap applied");
     76 
     77  // Check that the right number of shistory entries was discarded
     78  // and the shistory index updated accordingly.
     79  diskState = await writeAndParse(state, Paths.clean, { isFinalWrite: true });
     80  let tabState = state.windows[0].tabs[0];
     81  tabState.entries = tabState.entries.slice(2, 8);
     82  tabState.index = 3;
     83  Assert.deepEqual(state, diskState, "cap applied");
     84 });
     85 
     86 add_task(async function test_shistory_cap_lower_bound() {
     87  let state = createSessionState(1);
     88  await prepareWithLimit(5, 5);
     89 
     90  // Cap is only applied on clean shutdown.
     91  let diskState = await writeAndParse(state, Paths.recovery);
     92  Assert.deepEqual(state, diskState, "no cap applied");
     93 
     94  // Check that the right number of shistory entries was discarded.
     95  diskState = await writeAndParse(state, Paths.clean, { isFinalWrite: true });
     96  let tabState = state.windows[0].tabs[0];
     97  tabState.entries = tabState.entries.slice(0, 6);
     98  Assert.deepEqual(state, diskState, "cap applied");
     99 });
    100 
    101 add_task(async function test_shistory_cap_upper_bound() {
    102  let state = createSessionState(MAX_ENTRIES);
    103  await prepareWithLimit(5, 5);
    104 
    105  // Cap is only applied on clean shutdown.
    106  let diskState = await writeAndParse(state, Paths.recovery);
    107  Assert.deepEqual(state, diskState, "no cap applied");
    108 
    109  // Check that the right number of shistory entries was discarded
    110  // and the shistory index updated accordingly.
    111  diskState = await writeAndParse(state, Paths.clean, { isFinalWrite: true });
    112  let tabState = state.windows[0].tabs[0];
    113  tabState.entries = tabState.entries.slice(3);
    114  tabState.index = 6;
    115  Assert.deepEqual(state, diskState, "cap applied");
    116 });