tor-browser

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

test_shutdownDuringAllTemporaryOriginsInitialization2.js (5458B)


      1 /**
      2 * Any copyright is dedicated to the Public Domain.
      3 * http://creativecommons.org/publicdomain/zero/1.0/
      4 */
      5 
      6 const { PrincipalUtils } = ChromeUtils.importESModule(
      7  "resource://testing-common/dom/quota/test/modules/PrincipalUtils.sys.mjs"
      8 );
      9 const { QuotaUtils } = ChromeUtils.importESModule(
     10  "resource://testing-common/dom/quota/test/modules/QuotaUtils.sys.mjs"
     11 );
     12 const { TestUtils } = ChromeUtils.importESModule(
     13  "resource://testing-common/TestUtils.sys.mjs"
     14 );
     15 
     16 /**
     17 * This test verifies the behavior when a shutdown occurs during the
     18 * initialization of all temporary origins in the background.
     19 *
     20 * Test Setup & Procedure:
     21 * 1. Lazy Origin Initialization Enabled
     22 *    - The test runs with lazy origin initialization enabled, meaning that
     23 *      calling `Services.qms.initTemporaryStorage` does not initialize
     24 *      individual origins.
     25 *
     26 * 2. Preparation of Existing Profile
     27 *    - Two origins belonging to different eTLD+1 groups are created.
     28 *
     29 * 3. Triggering Initialization of All Temporary Origins
     30 *    - The test explicitly triggers the initialization of all temporary
     31 *      origins by calling `Services.qms.initializeAllTemporaryOrigins`.
     32 *
     33 * 4. Inducing a Controlled Shutdown
     34 *    - The test waits for the first origin to begin initialization.
     35 *    - Once initialization starts, shutdown is triggered.
     36 *    - A 2-second delay is introduced in origin initialization to ensure
     37 *      the shutdown signal has time to propagate.
     38 *
     39 * 5. Expected Behavior & Verification
     40 *    - Due to the shutdown, the second origin does not initialize.
     41 *    - Since active operations are not available during shutdown, the test
     42 *      verifies the shutdown behavior by waiting for the initialization of
     43 *      all temporary origins to finish and expecting an exception.
     44 *    - The operation is expected to fail with `NS_ERROR_ABORT`.
     45 *
     46 * Notes & Justification:
     47 * - This approach has been successfully used in other tests to handle
     48 *   shutdown scenarios.
     49 * - See also:
     50 *   https://searchfox.org/mozilla-central/rev/d5baa11e35e0186c3c867f4948010f0742198467/modules/libpref/init/StaticPrefList.yaml#3789-3846
     51 */
     52 async function testShutdownDuringAllTemporaryOriginsInitialization2() {
     53  // This test creates two origins belonging to different eTLD+1 groups on
     54  // purpose to test specific shutdown check.
     55  const principal1 = PrincipalUtils.createPrincipal("https://example1.com");
     56  const principal2 = PrincipalUtils.createPrincipal("https://example2.com");
     57 
     58  // Preparation phase: simulating an existing profile with pre-existing
     59  // storage. At least two temporary origins must already exist.
     60  info("Clearing storage");
     61 
     62  {
     63    const request = Services.qms.clear();
     64    await QuotaUtils.requestFinished(request);
     65  }
     66 
     67  info("Initializing storage");
     68 
     69  {
     70    const request = Services.qms.init();
     71    await QuotaUtils.requestFinished(request);
     72  }
     73 
     74  info("Initializing temporary storage");
     75 
     76  {
     77    const request = Services.qms.initTemporaryStorage();
     78    await QuotaUtils.requestFinished(request);
     79  }
     80 
     81  info("Initializing temporary origin");
     82 
     83  {
     84    const request = Services.qms.initializeTemporaryOrigin(
     85      "default",
     86      principal1,
     87      /* aCreateIfNonExistent */ true
     88    );
     89    await QuotaUtils.requestFinished(request);
     90  }
     91 
     92  info("Initializing temporary origin");
     93 
     94  {
     95    const request = Services.qms.initializeTemporaryOrigin(
     96      "default",
     97      principal2,
     98      /* aCreateIfNonExistent */ true
     99    );
    100    await QuotaUtils.requestFinished(request);
    101  }
    102 
    103  // Restore the original uninitialized state to force reinitialization of both
    104  // storage and temporary storage.
    105  info("Shutting down storage");
    106 
    107  {
    108    const request = Services.qms.reset();
    109    await QuotaUtils.requestFinished(request);
    110  }
    111 
    112  // Reinitialize storage and temporary storage.
    113  info("Initializing storage");
    114 
    115  {
    116    const request = Services.qms.init();
    117    await QuotaUtils.requestFinished(request);
    118  }
    119 
    120  info("Initializing temporary storage");
    121 
    122  {
    123    const request = Services.qms.initTemporaryStorage();
    124    await QuotaUtils.requestFinished(request);
    125  }
    126 
    127  // Now trigger the initialization of all temporary origins, which normally
    128  // happens automatically when incremental origin initialization is enabled
    129  // and temporary storage initialization is complete.
    130  info("Starting all temporary origins initialization");
    131 
    132  const initPromise = (async function () {
    133    const request = Services.qms.initializeAllTemporaryOrigins();
    134    const promise = QuotaUtils.requestFinished(request);
    135    return promise;
    136  })();
    137 
    138  info("Waiting for group initialization to start");
    139 
    140  await TestUtils.topicObserved("QuotaManager::GroupInitializationStarted");
    141 
    142  info("Starting shutdown");
    143 
    144  QuotaUtils.startShutdown();
    145 
    146  info("Waiting for all temoporary origins initialization to finish");
    147 
    148  try {
    149    await initPromise;
    150    Assert.ok(false, "Should have thrown");
    151  } catch (e) {
    152    Assert.ok(true, "Should have thrown");
    153    Assert.strictEqual(
    154      e.resultCode,
    155      Cr.NS_ERROR_ABORT,
    156      "Threw right result code"
    157    );
    158  }
    159 }
    160 
    161 /* exported testSteps */
    162 async function testSteps() {
    163  add_task(
    164    {
    165      pref_set: [
    166        ["dom.quotaManager.temporaryStorage.lazyOriginInitialization", true],
    167        ["dom.quotaManager.loadQuotaFromCache", false],
    168        ["dom.quotaManager.groupInitialization.pauseOnIOThreadMs", 2000],
    169      ],
    170    },
    171    testShutdownDuringAllTemporaryOriginsInitialization2
    172  );
    173 }