tor-browser

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

test_cache2-30d-pinning-WasEvicted-API.js (4128B)


      1 /*
      2 
      3 This test exercises the CacheFileContextEvictor::WasEvicted API and code using it.
      4 
      5 - We store 10+10 (pinned and non-pinned) entries to the cache, wait for them being written.
      6 - Then we purge the memory pools.
      7 - Now the IO thread is suspended on the EVICT (7) level to prevent actual deletion of the files.
      8 - Index is disabled.
      9 - We do clear() of the cache, this creates the "ce_*" file and posts to the EVICT level
     10  the eviction loop mechanics.
     11 - We open again those 10+10 entries previously stored.
     12 - IO is resumed
     13 - We expect to get all the pinned and
     14  loose all the non-pinned (common) entries.
     15 
     16 */
     17 
     18 "use strict";
     19 
     20 const kENTRYCOUNT = 10;
     21 
     22 function log_(msg) {
     23  if (true) {
     24    dump(">>>>>>>>>>>>> " + msg + "\n");
     25  }
     26 }
     27 
     28 function run_test() {
     29  do_get_profile();
     30 
     31  var lci = Services.loadContextInfo.default;
     32  var testingInterface = Services.cache2.QueryInterface(Ci.nsICacheTesting);
     33  Assert.ok(testingInterface);
     34 
     35  var mc = new MultipleCallbacks(
     36    1,
     37    function () {
     38      // (2)
     39 
     40      mc = new MultipleCallbacks(1, finish_cache2_test);
     41      // Release all references to cache entries so that they can be purged
     42      // Calling gc() four times is needed to force it to actually release
     43      // entries that are obviously unreferenced.  Yeah, I know, this is wacky...
     44      gc();
     45      gc();
     46      executeSoon(() => {
     47        gc();
     48        gc();
     49        log_("purging");
     50 
     51        // Invokes cacheservice:purge-memory-pools when done.
     52        Services.cache2.purgeFromMemory(
     53          Ci.nsICacheStorageService.PURGE_EVERYTHING
     54        ); // goes to (3)
     55      });
     56    },
     57    true
     58  );
     59 
     60  // (1), here we start
     61 
     62  log_("first set of opens");
     63  var i;
     64  for (i = 0; i < kENTRYCOUNT; ++i) {
     65    // Callbacks 1-20
     66    mc.add();
     67    asyncOpenCacheEntry(
     68      "http://pinned" + i + "/",
     69      "pin",
     70      Ci.nsICacheStorage.OPEN_TRUNCATE,
     71      lci,
     72      new OpenCallback(NEW | WAITFORWRITE, "m" + i, "p" + i, function () {
     73        mc.fired();
     74      })
     75    );
     76 
     77    mc.add();
     78    asyncOpenCacheEntry(
     79      "http://common" + i + "/",
     80      "disk",
     81      Ci.nsICacheStorage.OPEN_TRUNCATE,
     82      lci,
     83      new OpenCallback(NEW | WAITFORWRITE, "m" + i, "d" + i, function () {
     84        mc.fired();
     85      })
     86    );
     87  }
     88 
     89  mc.fired(); // Goes to (2)
     90 
     91  Services.obs.addObserver(
     92    {
     93      observe() {
     94        // (3)
     95 
     96        log_("after purge");
     97        // Prevent the I/O thread from evicting physically the data.  We first want to re-open the entries.
     98        // This deterministically emulates a slow hard drive.
     99        testingInterface.suspendCacheIOThread(7);
    100 
    101        log_("clearing");
    102        // Now clear everything except pinned.  Stores the "ce_*" file and schedules background eviction.
    103        Services.cache2.clear();
    104        log_("cleared");
    105 
    106        log_("second set of opens");
    107        // Now open again.  Pinned entries should be there, disk entries should be the renewed entries.
    108        // Callbacks 21-40
    109        for (i = 0; i < kENTRYCOUNT; ++i) {
    110          mc.add();
    111          asyncOpenCacheEntry(
    112            "http://pinned" + i + "/",
    113            "disk",
    114            Ci.nsICacheStorage.OPEN_NORMALLY,
    115            lci,
    116            new OpenCallback(NORMAL, "m" + i, "p" + i, function () {
    117              mc.fired();
    118            })
    119          );
    120 
    121          mc.add();
    122          asyncOpenCacheEntry(
    123            "http://common" + i + "/",
    124            "disk",
    125            Ci.nsICacheStorage.OPEN_NORMALLY,
    126            lci,
    127            new OpenCallback(NEW, "m2" + i, "d2" + i, function () {
    128              mc.fired();
    129            })
    130          );
    131        }
    132 
    133        // Resume IO, this will just pop-off the CacheFileContextEvictor::EvictEntries() because of
    134        // an early check on CacheIOThread::YieldAndRerun() in that method.
    135        // CacheFileIOManager::OpenFileInternal should now run and CacheFileContextEvictor::WasEvicted
    136        // should be checked on.
    137        log_("resuming");
    138        testingInterface.resumeCacheIOThread();
    139        log_("resumed");
    140 
    141        mc.fired(); // Finishes this test
    142      },
    143    },
    144    "cacheservice:purge-memory-pools"
    145  );
    146 
    147  do_test_pending();
    148 }