xpcom/tests/TestExpirationTracker.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* vim:set ts=2 sw=2 sts=2 et cindent: */
     3 /* This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 #include <stdlib.h>
     8 #include <stdio.h>
     9 #include <prthread.h>
    10 #include "nsExpirationTracker.h"
    11 #include "nsMemory.h"
    12 #include "nsAutoPtr.h"
    13 #include "nsString.h"
    14 #include "nsDirectoryServiceDefs.h"
    15 #include "nsDirectoryServiceUtils.h"
    16 #include "nsComponentManagerUtils.h"
    17 #include "nsXPCOM.h"
    18 #include "nsIFile.h"
    19 #include "prinrval.h"
    20 #include "nsThreadUtils.h"
    22 namespace TestExpirationTracker {
    24 struct Object {
    25   Object() : mExpired(false) { Touch(); }
    26   void Touch() { mLastUsed = PR_IntervalNow(); mExpired = false; }
    28   nsExpirationState mExpiration;
    29   nsExpirationState* GetExpirationState() { return &mExpiration; }
    31   PRIntervalTime mLastUsed;
    32   bool           mExpired;
    33 };
    35 static bool error;
    36 static uint32_t periodMS = 100;
    37 static uint32_t ops = 1000;
    38 static uint32_t iterations = 2;
    39 static bool logging = 0;
    40 static uint32_t sleepPeriodMS = 50;
    41 static uint32_t slackMS = 20; // allow this much error
    43 static void SignalError() {
    44   printf("ERROR!\n");
    45   error = true;
    46 }
    48 template <uint32_t K> class Tracker : public nsExpirationTracker<Object,K> {
    49 public:
    50   Tracker() : nsExpirationTracker<Object,K>(periodMS) {
    51     Object* obj = new Object();
    52     mUniverse.AppendElement(obj);
    53     LogAction(obj, "Created");
    54   }
    56   nsTArray<nsAutoArrayPtr<Object> > mUniverse;
    58   void LogAction(Object* aObj, const char* aAction) {
    59     if (logging) {
    60       printf("%d %p(%d): %s\n", PR_IntervalNow(),
    61              static_cast<void*>(aObj), aObj->mLastUsed, aAction);
    62     }
    63   }
    65   void DoRandomOperation() {
    66     Object* obj;
    67     switch (rand() & 0x7) {
    68     case 0: {
    69       if (mUniverse.Length() < 50) {
    70         obj = new Object();
    71         mUniverse.AppendElement(obj);
    72         nsExpirationTracker<Object,K>::AddObject(obj);
    73         LogAction(obj, "Created and added");
    74       }
    75       break;
    76     }
    77     case 4: {
    78       if (mUniverse.Length() < 50) {
    79         obj = new Object();
    80         mUniverse.AppendElement(obj);
    81         LogAction(obj, "Created");
    82       }
    83       break;
    84     }
    85     case 1: {
    86       obj = mUniverse[uint32_t(rand())%mUniverse.Length()];
    87       if (obj->mExpiration.IsTracked()) {
    88         nsExpirationTracker<Object,K>::RemoveObject(obj);
    89         LogAction(obj, "Removed");
    90       }
    91       break;
    92     }
    93     case 2: {
    94       obj = mUniverse[uint32_t(rand())%mUniverse.Length()];
    95       if (!obj->mExpiration.IsTracked()) {
    96         obj->Touch();
    97         nsExpirationTracker<Object,K>::AddObject(obj);
    98         LogAction(obj, "Added");
    99       }
   100       break;
   101     }
   102     case 3: {
   103       obj = mUniverse[uint32_t(rand())%mUniverse.Length()];
   104       if (obj->mExpiration.IsTracked()) {
   105         obj->Touch();
   106         nsExpirationTracker<Object,K>::MarkUsed(obj);
   107         LogAction(obj, "Marked used");
   108       }
   109       break;
   110     }
   111     }
   112   }
   114 protected:
   115   void NotifyExpired(Object* aObj) {
   116     LogAction(aObj, "Expired");
   117     PRIntervalTime now = PR_IntervalNow();
   118     uint32_t timeDiffMS = (now - aObj->mLastUsed)*1000/PR_TicksPerSecond();
   119     // See the comment for NotifyExpired in nsExpirationTracker.h for these
   120     // bounds
   121     uint32_t lowerBoundMS = (K-1)*periodMS - slackMS;
   122     uint32_t upperBoundMS = K*(periodMS + sleepPeriodMS) + slackMS;
   123     if (logging) {
   124       printf("Checking: %d-%d = %d [%d,%d]\n",
   125              now, aObj->mLastUsed, timeDiffMS, lowerBoundMS, upperBoundMS);
   126     }
   127     if (timeDiffMS < lowerBoundMS || timeDiffMS > upperBoundMS) {
   128       if (timeDiffMS < periodMS && aObj->mExpired) {
   129         // This is probably OK, it probably just expired twice
   130       } else {
   131         SignalError();
   132       }
   133     }
   134     aObj->Touch();
   135     aObj->mExpired = true;
   136     DoRandomOperation();
   137     DoRandomOperation();
   138     DoRandomOperation();
   139   }
   140 };
   142 template <uint32_t K> static bool test_random() {
   143   srand(K);
   144   error = false;
   146   for (uint32_t j = 0; j < iterations; ++j) {
   147     Tracker<K> tracker;
   149     uint32_t i = 0;
   150     for (i = 0; i < ops; ++i) {
   151       if ((rand() & 0xF) == 0) {
   152         // Simulate work that takes time
   153         if (logging) {
   154           printf("SLEEPING for %dms (%d)\n", sleepPeriodMS, PR_IntervalNow());
   155         }
   156         PR_Sleep(PR_MillisecondsToInterval(sleepPeriodMS));
   157         // Process pending timer events
   158         NS_ProcessPendingEvents(nullptr);
   159       }
   160       tracker.DoRandomOperation();
   161     }
   162   }
   164   return !error;
   165 }
   167 static bool test_random3() { return test_random<3>(); }
   168 static bool test_random4() { return test_random<4>(); }
   169 static bool test_random8() { return test_random<8>(); }
   171 typedef bool (*TestFunc)();
   172 #define DECL_TEST(name) { #name, name }
   174 static const struct Test {
   175   const char* name;
   176   TestFunc    func;
   177 } tests[] = {
   178   DECL_TEST(test_random3),
   179   DECL_TEST(test_random4),
   180   DECL_TEST(test_random8),
   181   { nullptr, nullptr }
   182 };
   184 }
   186 using namespace TestExpirationTracker;
   188 int main(int argc, char **argv) {
   189   int count = 1;
   190   if (argc > 1)
   191     count = atoi(argv[1]);
   193   if (NS_FAILED(NS_InitXPCOM2(nullptr, nullptr, nullptr)))
   194     return -1;
   196   while (count--) {
   197     for (const Test* t = tests; t->name != nullptr; ++t) {
   198       printf("%25s : %s\n", t->name, t->func() ? "SUCCESS" : "FAILURE");
   199     }
   200   }
   202   NS_ShutdownXPCOM(nullptr);
   203   return 0;
   204 }

mercurial