tor-browser

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

QuotaManagerDependencyFixture.h (10240B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      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 file,
      5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #ifndef DOM_QUOTA_TEST_GTEST_QUOTAMANAGERDEPENDENCYFIXTURE_H_
      8 #define DOM_QUOTA_TEST_GTEST_QUOTAMANAGERDEPENDENCYFIXTURE_H_
      9 
     10 #include "gtest/gtest.h"
     11 #include "mozilla/MozPromise.h"
     12 #include "mozilla/SpinEventLoopUntil.h"
     13 #include "mozilla/dom/quota/ClientDirectoryLock.h"
     14 #include "mozilla/dom/quota/ClientDirectoryLockHandle.h"
     15 #include "mozilla/dom/quota/DirectoryLock.h"
     16 #include "mozilla/dom/quota/DirectoryLockInlines.h"
     17 #include "mozilla/dom/quota/ForwardDecls.h"
     18 #include "mozilla/dom/quota/QuotaManager.h"
     19 
     20 // ENSURE_NO_FATAL_FAILURE is useful in non-void functions where
     21 // ASSERT_NO_FATAL_FAILURE can't be used.
     22 #define ENSURE_NO_FATAL_FAILURE(expr, ret) \
     23  (expr);                                  \
     24  if (HasFatalFailure()) {                 \
     25    return ret;                            \
     26  }
     27 
     28 #define QM_TEST_FAIL [](nsresult) { FAIL(); }
     29 
     30 namespace mozilla::dom::quota::test {
     31 
     32 class QuotaManagerDependencyFixture : public testing::Test {
     33 public:
     34  static void InitializeFixture();
     35  static void ShutdownFixture();
     36 
     37  static void InitializeStorage();
     38  static void StorageInitialized(bool* aResult);
     39  static void AssertStorageInitialized();
     40  static void AssertStorageNotInitialized();
     41  static void ClearStorage();
     42  static void ShutdownStorage();
     43 
     44  static void InitializeTemporaryStorage();
     45  static void TemporaryStorageInitialized(bool* aResult);
     46  static void AssertTemporaryStorageInitialized();
     47  static void AssertTemporaryStorageNotInitialized();
     48  static void ShutdownTemporaryStorage();
     49 
     50  static void InitializeTemporaryOrigin(const OriginMetadata& aOriginMetadata,
     51                                        bool aCreateIfNonExistent = true);
     52  static void TemporaryOriginInitialized(const OriginMetadata& aOriginMetadata,
     53                                         bool* aResult);
     54  static void AssertTemporaryOriginInitialized(
     55      const OriginMetadata& aOriginMetadata);
     56  static void AssertTemporaryOriginNotInitialized(
     57      const OriginMetadata& aOriginMetadata);
     58 
     59  // For more complex testing, use of this helper is optional.
     60  static void SaveOriginAccessTime(const OriginMetadata& aOriginMetadata);
     61 
     62  static void GetOriginUsage(const OriginMetadata& aOriginMetadata,
     63                             UsageInfo* aResult);
     64  static void GetCachedOriginUsage(const OriginMetadata& aOriginMetadata,
     65                                   UsageInfo* aResult);
     66  static void ClearStoragesForOrigin(const OriginMetadata& aOriginMetadata);
     67 
     68  static void InitializePersistentClient(const ClientMetadata& aClientMetadata);
     69  static void InitializeTemporaryClient(const ClientMetadata& aClientMetadata,
     70                                        bool aCreateIfNonExistent = true);
     71 
     72  static CStringArray ListOrigins();
     73  static CStringArray ListCachedOrigins();
     74 
     75  static void ClearStoragesForOriginAttributesPattern(
     76      const nsAString& aPattern);
     77 
     78  static void ProcessPendingNormalOriginOperations();
     79 
     80  static Maybe<OriginStateMetadata> GetOriginStateMetadata(
     81      const OriginMetadata& aOriginMetadata);
     82 
     83  static Maybe<OriginStateMetadata> LoadDirectoryMetadataHeader(
     84      const OriginMetadata& aOriginMetadata);
     85 
     86  static uint64_t TotalDirectoryIterations();
     87 
     88  static uint64_t SaveOriginAccessTimeCount();
     89  static uint64_t SaveOriginAccessTimeCountInternal();
     90 
     91  /* Convenience method for tasks which must be called on PBackground thread */
     92  template <class Invokable, class... Args>
     93  static auto PerformOnBackgroundThread(Invokable&& aInvokable, Args&&... aArgs)
     94      -> std::invoke_result_t<Invokable, Args...> {
     95    return PerformOnThread(BackgroundTargetStrongRef(),
     96                           std::forward<Invokable>(aInvokable),
     97                           std::forward<Args>(aArgs)...);
     98  }
     99 
    100  /* Convenience method for tasks which must be executed on IO thread */
    101  template <class Invokable, class... Args>
    102  static auto PerformOnIOThread(Invokable&& aInvokable, Args&&... aArgs)
    103      -> std::invoke_result_t<Invokable, Args...> {
    104    QuotaManager* quotaManager = QuotaManager::Get();
    105    MOZ_RELEASE_ASSERT(quotaManager);
    106 
    107    return PerformOnThread(quotaManager->IOThread(),
    108                           std::forward<Invokable>(aInvokable),
    109                           std::forward<Args>(aArgs)...);
    110  }
    111 
    112  template <class Invokable, class... Args,
    113            bool ReturnTypeIsVoid =
    114                std::is_same_v<std::invoke_result_t<Invokable, Args...>, void>>
    115  static auto PerformOnThread(nsISerialEventTarget* aTarget,
    116                              Invokable&& aInvokable, Args&&... aArgs)
    117      -> std::invoke_result_t<Invokable, Args...> {
    118    using ReturnType =
    119        std::conditional_t<ReturnTypeIsVoid, bool,
    120                           std::invoke_result_t<Invokable, Args...>>;
    121 
    122    bool done = false;
    123    auto boundTask =
    124        // For c++17, bind is cleaner than tuple for parameter pack forwarding
    125        // NOLINTNEXTLINE(modernize-avoid-bind)
    126        std::bind(std::forward<Invokable>(aInvokable),
    127                  std::forward<Args>(aArgs)...);
    128    Maybe<ReturnType> maybeReturnValue;
    129    InvokeAsync(
    130        aTarget, __func__,
    131        [boundTask = std::move(boundTask), &maybeReturnValue]() mutable {
    132          if constexpr (ReturnTypeIsVoid) {
    133            boundTask();
    134            (void)maybeReturnValue;
    135          } else {
    136            maybeReturnValue.emplace(boundTask());
    137          }
    138          return BoolPromise::CreateAndResolve(true, __func__);
    139        })
    140        ->Then(GetCurrentSerialEventTarget(), __func__,
    141               [&done](const BoolPromise::ResolveOrRejectValue& /* aValue */) {
    142                 done = true;
    143               });
    144 
    145    SpinEventLoopUntil("Promise is fulfilled"_ns, [&done]() { return done; });
    146 
    147    if constexpr (!ReturnTypeIsVoid) {
    148      return maybeReturnValue.extract();
    149    }
    150  }
    151 
    152  // Acquire and await a client directory lock and pass it to the given task.
    153  template <class Task>
    154  static void PerformClientDirectoryLockTest(
    155      const ClientMetadata& aClientMetadata, Task&& aTask) {
    156    PerformOnBackgroundThread(
    157        [clientMetadata = aClientMetadata, task = std::forward<Task>(aTask)]() {
    158          QuotaManager* quotaManager = QuotaManager::Get();
    159          ASSERT_TRUE(quotaManager);
    160 
    161          RefPtr<ClientDirectoryLock> directoryLock =
    162              quotaManager->CreateDirectoryLock(clientMetadata,
    163                                                /* aExclusive */ false);
    164 
    165          auto value = Await(directoryLock->Acquire());
    166          ASSERT_TRUE(value.IsResolve());
    167 
    168          task(std::move(directoryLock));
    169        });
    170  }
    171 
    172  template <class Task>
    173  static void PerformClientDirectoryTest(const ClientMetadata& aClientMetadata,
    174                                         Task&& aTask) {
    175    PerformOnBackgroundThread([clientMetadata = aClientMetadata,
    176                               task = std::forward<Task>(aTask)]() mutable {
    177      ClientDirectoryLockHandle directoryLockHandle;
    178 
    179      QuotaManager* quotaManager = QuotaManager::Get();
    180      ASSERT_TRUE(quotaManager);
    181 
    182      bool done = false;
    183 
    184      quotaManager->OpenClientDirectory(clientMetadata)
    185          ->Then(
    186              GetCurrentSerialEventTarget(), __func__,
    187              [&directoryLockHandle,
    188               &done](ClientDirectoryLockHandle&& aResolveValue) {
    189                directoryLockHandle = std::move(aResolveValue);
    190 
    191                done = true;
    192              },
    193              [&done](const nsresult aRejectValue) {
    194                ASSERT_TRUE(false);
    195 
    196                done = true;
    197              });
    198 
    199      SpinEventLoopUntil("Promise is fulfilled"_ns, [&done]() { return done; });
    200 
    201      ASSERT_TRUE(directoryLockHandle);
    202 
    203      PerformOnIOThread(std::move(task), directoryLockHandle->Id());
    204 
    205      {
    206        auto destroyingDirectoryLockHandle = std::move(directoryLockHandle);
    207      }
    208    });
    209  }
    210 
    211  /* Convenience method for defering execution of code until the promise has
    212   * been resolved or rejected */
    213  template <typename ResolveValueT, typename RejectValueT, bool IsExclusive>
    214  static typename MozPromise<ResolveValueT, RejectValueT,
    215                             IsExclusive>::ResolveOrRejectValue
    216  Await(RefPtr<MozPromise<ResolveValueT, RejectValueT, IsExclusive>> aPromise) {
    217    using PromiseType = MozPromise<ResolveValueT, RejectValueT, IsExclusive>;
    218    using ResolveOrRejectValue = typename PromiseType::ResolveOrRejectValue;
    219 
    220    ResolveOrRejectValue value;
    221 
    222    bool done = false;
    223 
    224    auto SelectResolveOrRejectCallback = [&value, &done]() {
    225      if constexpr (IsExclusive) {
    226        return [&value, &done](ResolveOrRejectValue&& aValue) {
    227          value = std::move(aValue);
    228 
    229          done = true;
    230        };
    231      } else {
    232        return [&value, &done](const ResolveOrRejectValue& aValue) {
    233          value = aValue;
    234 
    235          done = true;
    236        };
    237      }
    238    };
    239 
    240    aPromise->Then(GetCurrentSerialEventTarget(), __func__,
    241                   SelectResolveOrRejectCallback());
    242 
    243    SpinEventLoopUntil("Promise is fulfilled"_ns, [&done]() { return done; });
    244 
    245    return value;
    246  }
    247 
    248  static const nsCOMPtr<nsISerialEventTarget>& BackgroundTargetStrongRef() {
    249    return sBackgroundTarget;
    250  }
    251 
    252  static PrincipalMetadata GetTestPrincipalMetadata();
    253  static OriginMetadata GetTestPersistentOriginMetadata();
    254  static ClientMetadata GetTestPersistentClientMetadata();
    255  static OriginMetadata GetTestOriginMetadata();
    256  static ClientMetadata GetTestClientMetadata();
    257  static OriginMetadata GetTestPrivateOriginMetadata();
    258  static ClientMetadata GetTestPrivateClientMetadata();
    259 
    260  static PrincipalMetadata GetOtherTestPrincipalMetadata();
    261  static OriginMetadata GetOtherTestOriginMetadata();
    262  static ClientMetadata GetOtherTestClientMetadata();
    263 
    264 private:
    265  static void EnsureQuotaManager();
    266 
    267  static nsCOMPtr<nsISerialEventTarget> sBackgroundTarget;
    268 };
    269 
    270 }  // namespace mozilla::dom::quota::test
    271 
    272 #endif  // DOM_QUOTA_TEST_GTEST_QUOTAMANAGERDEPENDENCYFIXTURE_H_