tor-browser

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

environment_unittest.cc (10405B)


      1 /*
      2 *  Copyright (c) 2023 The WebRTC project authors. All Rights Reserved.
      3 *
      4 *  Use of this source code is governed by a BSD-style license
      5 *  that can be found in the LICENSE file in the root of the source
      6 *  tree. An additional intellectual property rights grant can be found
      7 *  in the file PATENTS.  All contributing project authors may
      8 *  be found in the AUTHORS file in the root of the source tree.
      9 */
     10 
     11 #include "api/environment/environment.h"
     12 
     13 #include <memory>
     14 #include <optional>
     15 #include <string>
     16 #include <utility>
     17 #include <vector>
     18 
     19 #include "absl/functional/any_invocable.h"
     20 #include "absl/strings/string_view.h"
     21 #include "api/environment/environment_factory.h"
     22 #include "api/field_trials_view.h"
     23 #include "api/rtc_event_log/rtc_event.h"
     24 #include "api/rtc_event_log/rtc_event_log.h"
     25 #include "api/task_queue/task_queue_base.h"
     26 #include "api/task_queue/task_queue_factory.h"
     27 #include "api/units/timestamp.h"
     28 #include "system_wrappers/include/clock.h"
     29 #include "test/gmock.h"
     30 #include "test/gtest.h"
     31 
     32 namespace webrtc {
     33 namespace {
     34 
     35 using ::testing::ElementsAre;
     36 using ::testing::IsEmpty;
     37 using ::testing::Not;
     38 using ::testing::NotNull;
     39 using ::testing::Ref;
     40 
     41 class FakeEvent : public RtcEvent {
     42 public:
     43  Type GetType() const override { return RtcEvent::Type::FakeEvent; }
     44  bool IsConfigEvent() const override { return false; }
     45 };
     46 
     47 class FakeFieldTrials : public FieldTrialsView {
     48 public:
     49  explicit FakeFieldTrials(absl::AnyInvocable<void() &&> on_destroyed = nullptr)
     50      : on_destroyed_(std::move(on_destroyed)) {}
     51  ~FakeFieldTrials() override {
     52    if (on_destroyed_ != nullptr) {
     53      std::move(on_destroyed_)();
     54    }
     55  }
     56 
     57  std::string Lookup(absl::string_view /* key */) const override {
     58    return "fake";
     59  }
     60 
     61  std::unique_ptr<FieldTrialsView> CreateCopy() const override {
     62    return std::make_unique<FakeFieldTrials>([] {});
     63  }
     64 
     65 private:
     66  absl::AnyInvocable<void() &&> on_destroyed_;
     67 };
     68 
     69 class FakeTaskQueueFactory : public TaskQueueFactory {
     70 public:
     71  explicit FakeTaskQueueFactory(
     72      absl::AnyInvocable<void() &&> on_destroyed = nullptr)
     73      : on_destroyed_(std::move(on_destroyed)) {}
     74  ~FakeTaskQueueFactory() override {
     75    if (on_destroyed_ != nullptr) {
     76      std::move(on_destroyed_)();
     77    }
     78  }
     79 
     80  std::unique_ptr<TaskQueueBase, TaskQueueDeleter> CreateTaskQueue(
     81      absl::string_view /* name */,
     82      Priority /* priority */) const override {
     83    return nullptr;
     84  }
     85 
     86 private:
     87  absl::AnyInvocable<void() &&> on_destroyed_;
     88 };
     89 
     90 TEST(EnvironmentTest, DefaultEnvironmentHasAllUtilities) {
     91  Environment env = EnvironmentFactory().Create();
     92 
     93  // Try to use each utility, expect no crashes.
     94  env.clock().CurrentTime();
     95  EXPECT_THAT(env.task_queue_factory().CreateTaskQueue(
     96                  "test", TaskQueueFactory::Priority::NORMAL),
     97              NotNull());
     98  env.event_log().Log(std::make_unique<FakeEvent>());
     99  env.field_trials().Lookup("WebRTC-Debugging-RtpDump");
    100 }
    101 
    102 TEST(EnvironmentTest, UsesProvidedUtilitiesWithOwnership) {
    103  auto owned_field_trials = std::make_unique<FakeFieldTrials>();
    104  auto owned_task_queue_factory = std::make_unique<FakeTaskQueueFactory>();
    105  auto owned_clock = std::make_unique<SimulatedClock>(Timestamp::Zero());
    106  auto owned_event_log = std::make_unique<RtcEventLogNull>();
    107 
    108  FieldTrialsView& field_trials = *owned_field_trials;
    109  TaskQueueFactory& task_queue_factory = *owned_task_queue_factory;
    110  Clock& clock = *owned_clock;
    111  RtcEventLog& event_log = *owned_event_log;
    112 
    113  Environment env = CreateEnvironment(
    114      std::move(owned_field_trials), std::move(owned_clock),
    115      std::move(owned_task_queue_factory), std::move(owned_event_log));
    116 
    117  EXPECT_THAT(env.field_trials(), Ref(field_trials));
    118  EXPECT_THAT(env.task_queue_factory(), Ref(task_queue_factory));
    119  EXPECT_THAT(env.clock(), Ref(clock));
    120  EXPECT_THAT(env.event_log(), Ref(event_log));
    121 }
    122 
    123 TEST(EnvironmentTest, UsesProvidedUtilitiesWithoutOwnership) {
    124  FakeFieldTrials field_trials;
    125  FakeTaskQueueFactory task_queue_factory;
    126  SimulatedClock clock(Timestamp::Zero());
    127  RtcEventLogNull event_log;
    128 
    129  Environment env =
    130      CreateEnvironment(&field_trials, &clock, &task_queue_factory, &event_log);
    131 
    132  EXPECT_THAT(env.field_trials(), Ref(field_trials));
    133  EXPECT_THAT(env.task_queue_factory(), Ref(task_queue_factory));
    134  EXPECT_THAT(env.clock(), Ref(clock));
    135  EXPECT_THAT(env.event_log(), Ref(event_log));
    136 }
    137 
    138 TEST(EnvironmentTest, UsesLastProvidedUtility) {
    139  auto owned_field_trials1 = std::make_unique<FakeFieldTrials>();
    140  auto owned_field_trials2 = std::make_unique<FakeFieldTrials>();
    141  FieldTrialsView& field_trials2 = *owned_field_trials2;
    142 
    143  Environment env = CreateEnvironment(std::move(owned_field_trials1),
    144                                      std::move(owned_field_trials2));
    145 
    146  EXPECT_THAT(env.field_trials(), Ref(field_trials2));
    147 }
    148 
    149 // Utilities can be provided from different sources, and when some source
    150 // choose not to provide an utility, it is usually expressed with nullptr.
    151 // When utility is not provided, it is natural to use previously set one.
    152 // E.g. Both PeerConnectionFactoryDependencies and PeerConnectionDependencies
    153 // provide field trials. When PeerConnectionDependencies::trials == nullptr,
    154 // then trials from the PeerConnectionFactoryDependencies should be used.
    155 // With nullptr accepted and ignored this can be expressed by
    156 // `Environemt env = CreateEnvironment(pcf_deps.trials, pc_deps.trials);`
    157 // That would use pc_deps.trials when not nullptr, pcf_deps.trials when
    158 // pc_deps.trials is nullptr, but pcf_deps.trials is not, and default field
    159 // trials when both are nullptr.
    160 TEST(EnvironmentTest, IgnoresProvidedNullptrUtility) {
    161  auto owned_field_trials = std::make_unique<FakeFieldTrials>();
    162  std::unique_ptr<FieldTrialsView> null_field_trials = nullptr;
    163  FieldTrialsView& field_trials = *owned_field_trials;
    164 
    165  Environment env = CreateEnvironment(std::move(owned_field_trials),
    166                                      std::move(null_field_trials));
    167 
    168  EXPECT_THAT(env.field_trials(), Ref(field_trials));
    169 }
    170 
    171 TEST(EnvironmentTest, KeepsUtilityAliveWhileEnvironmentIsAlive) {
    172  bool utility_destroyed = false;
    173  auto field_trials = std::make_unique<FakeFieldTrials>(
    174      /*on_destroyed=*/[&] { utility_destroyed = true; });
    175 
    176  // Wrap Environment into optional to have explicit control when it is deleted.
    177  std::optional<Environment> env = CreateEnvironment(std::move(field_trials));
    178 
    179  EXPECT_FALSE(utility_destroyed);
    180  env = std::nullopt;
    181  EXPECT_TRUE(utility_destroyed);
    182 }
    183 
    184 TEST(EnvironmentTest, KeepsUtilityAliveWhileCopyOfEnvironmentIsAlive) {
    185  bool utility_destroyed = false;
    186  auto field_trials = std::make_unique<FakeFieldTrials>(
    187      /*on_destroyed=*/[&] { utility_destroyed = true; });
    188 
    189  std::optional<Environment> env1 = CreateEnvironment(std::move(field_trials));
    190  std::optional<Environment> env2 = env1;
    191 
    192  EXPECT_FALSE(utility_destroyed);
    193  env1 = std::nullopt;
    194  EXPECT_FALSE(utility_destroyed);
    195  env2 = std::nullopt;
    196  EXPECT_TRUE(utility_destroyed);
    197 }
    198 
    199 TEST(EnvironmentTest, FactoryCanBeReusedToCreateDifferentEnvironments) {
    200  auto owned_task_queue_factory = std::make_unique<FakeTaskQueueFactory>();
    201  auto owned_field_trials1 = std::make_unique<FakeFieldTrials>();
    202  auto owned_field_trials2 = std::make_unique<FakeFieldTrials>();
    203  TaskQueueFactory& task_queue_factory = *owned_task_queue_factory;
    204  FieldTrialsView& field_trials1 = *owned_field_trials1;
    205  FieldTrialsView& field_trials2 = *owned_field_trials2;
    206 
    207  EnvironmentFactory factory;
    208  factory.Set(std::move(owned_task_queue_factory));
    209  factory.Set(std::move(owned_field_trials1));
    210  Environment env1 = factory.Create();
    211  factory.Set(std::move(owned_field_trials2));
    212  Environment env2 = factory.Create();
    213 
    214  // Environments share the same custom task queue factory.
    215  EXPECT_THAT(env1.task_queue_factory(), Ref(task_queue_factory));
    216  EXPECT_THAT(env2.task_queue_factory(), Ref(task_queue_factory));
    217 
    218  // Environments have different field trials.
    219  EXPECT_THAT(env1.field_trials(), Ref(field_trials1));
    220  EXPECT_THAT(env2.field_trials(), Ref(field_trials2));
    221 }
    222 
    223 TEST(EnvironmentTest, FactoryCanCreateNewEnvironmentFromExistingOne) {
    224  Environment env1 =
    225      CreateEnvironment(std::make_unique<FakeTaskQueueFactory>());
    226  EnvironmentFactory factory(env1);
    227  factory.Set(std::make_unique<FakeFieldTrials>());
    228  Environment env2 = factory.Create();
    229 
    230  // Environments share the same default clock.
    231  EXPECT_THAT(env2.clock(), Ref(env1.clock()));
    232 
    233  // Environments share the same custom task queue factory.
    234  EXPECT_THAT(env2.task_queue_factory(), Ref(env1.task_queue_factory()));
    235 
    236  // Environments have different field trials.
    237  EXPECT_THAT(env2.field_trials(), Not(Ref(env1.field_trials())));
    238 }
    239 
    240 TEST(EnvironmentTest, KeepsOwnershipsWhenCreateNewEnvironmentFromExistingOne) {
    241  bool utility1_destroyed = false;
    242  bool utility2_destroyed = false;
    243  std::optional<Environment> env1 =
    244      CreateEnvironment(std::make_unique<FakeTaskQueueFactory>(
    245          /*on_destroyed=*/[&] { utility1_destroyed = true; }));
    246 
    247  std::optional<EnvironmentFactory> factory = EnvironmentFactory(*env1);
    248 
    249  // Destroy env1, check utility1 it was using is still alive.
    250  env1 = std::nullopt;
    251  EXPECT_FALSE(utility1_destroyed);
    252 
    253  factory->Set(std::make_unique<FakeFieldTrials>(
    254      /*on_destroyed=*/[&] { utility2_destroyed = true; }));
    255  std::optional<Environment> env2 = factory->Create();
    256 
    257  // Destroy the factory, check all utilities used by env2 are alive.
    258  factory = std::nullopt;
    259  EXPECT_FALSE(utility1_destroyed);
    260  EXPECT_FALSE(utility2_destroyed);
    261 
    262  // Once last Environment object is deleted, utilties should be deleted too.
    263  env2 = std::nullopt;
    264  EXPECT_TRUE(utility1_destroyed);
    265  EXPECT_TRUE(utility2_destroyed);
    266 }
    267 
    268 TEST(EnvironmentTest, DestroysUtilitiesInReverseProvidedOrder) {
    269  std::vector<std::string> destroyed;
    270  auto field_trials = std::make_unique<FakeFieldTrials>(
    271      /*on_destroyed=*/[&] { destroyed.push_back("field_trials"); });
    272  auto task_queue_factory = std::make_unique<FakeTaskQueueFactory>(
    273      /*on_destroyed=*/[&] { destroyed.push_back("task_queue_factory"); });
    274 
    275  std::optional<Environment> env =
    276      CreateEnvironment(std::move(field_trials), std::move(task_queue_factory));
    277 
    278  ASSERT_THAT(destroyed, IsEmpty());
    279  env = std::nullopt;
    280  EXPECT_THAT(destroyed, ElementsAre("task_queue_factory", "field_trials"));
    281 }
    282 
    283 }  // namespace
    284 }  // namespace webrtc