summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/api/environment/environment_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/libwebrtc/api/environment/environment_unittest.cc')
-rw-r--r--third_party/libwebrtc/api/environment/environment_unittest.cc275
1 files changed, 275 insertions, 0 deletions
diff --git a/third_party/libwebrtc/api/environment/environment_unittest.cc b/third_party/libwebrtc/api/environment/environment_unittest.cc
new file mode 100644
index 0000000000..07bd8793bc
--- /dev/null
+++ b/third_party/libwebrtc/api/environment/environment_unittest.cc
@@ -0,0 +1,275 @@
+/*
+ * Copyright (c) 2023 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/environment/environment.h"
+
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "absl/functional/any_invocable.h"
+#include "absl/types/optional.h"
+#include "api/environment/environment_factory.h"
+#include "api/field_trials_view.h"
+#include "api/rtc_event_log/rtc_event_log.h"
+#include "api/task_queue/task_queue_factory.h"
+#include "api/units/timestamp.h"
+#include "system_wrappers/include/clock.h"
+#include "test/gmock.h"
+#include "test/gtest.h"
+
+namespace webrtc {
+namespace {
+
+using ::testing::ElementsAre;
+using ::testing::IsEmpty;
+using ::testing::Not;
+using ::testing::NotNull;
+using ::testing::Ref;
+
+class FakeEvent : public RtcEvent {
+ public:
+ Type GetType() const override { return RtcEvent::Type::FakeEvent; }
+ bool IsConfigEvent() const override { return false; }
+};
+
+class FakeFieldTrials : public FieldTrialsView {
+ public:
+ explicit FakeFieldTrials(absl::AnyInvocable<void() &&> on_destroyed = nullptr)
+ : on_destroyed_(std::move(on_destroyed)) {}
+ ~FakeFieldTrials() override {
+ if (on_destroyed_ != nullptr) {
+ std::move(on_destroyed_)();
+ }
+ }
+
+ std::string Lookup(absl::string_view key) const override { return "fake"; }
+
+ private:
+ absl::AnyInvocable<void() &&> on_destroyed_;
+};
+
+class FakeTaskQueueFactory : public TaskQueueFactory {
+ public:
+ explicit FakeTaskQueueFactory(
+ absl::AnyInvocable<void() &&> on_destroyed = nullptr)
+ : on_destroyed_(std::move(on_destroyed)) {}
+ ~FakeTaskQueueFactory() override {
+ if (on_destroyed_ != nullptr) {
+ std::move(on_destroyed_)();
+ }
+ }
+
+ std::unique_ptr<TaskQueueBase, TaskQueueDeleter> CreateTaskQueue(
+ absl::string_view name,
+ Priority priority) const override {
+ return nullptr;
+ }
+
+ private:
+ absl::AnyInvocable<void() &&> on_destroyed_;
+};
+
+TEST(EnvironmentTest, DefaultEnvironmentHasAllUtilities) {
+ Environment env = EnvironmentFactory().Create();
+
+ // Try to use each utility, expect no crashes.
+ env.clock().CurrentTime();
+ EXPECT_THAT(env.task_queue_factory().CreateTaskQueue(
+ "test", TaskQueueFactory::Priority::NORMAL),
+ NotNull());
+ env.event_log().Log(std::make_unique<FakeEvent>());
+ env.field_trials().Lookup("WebRTC-Debugging-RtpDump");
+}
+
+TEST(EnvironmentTest, UsesProvidedUtilitiesWithOwnership) {
+ auto owned_field_trials = std::make_unique<FakeFieldTrials>();
+ auto owned_task_queue_factory = std::make_unique<FakeTaskQueueFactory>();
+ auto owned_clock = std::make_unique<SimulatedClock>(Timestamp::Zero());
+ auto owned_event_log = std::make_unique<RtcEventLogNull>();
+
+ FieldTrialsView& field_trials = *owned_field_trials;
+ TaskQueueFactory& task_queue_factory = *owned_task_queue_factory;
+ Clock& clock = *owned_clock;
+ RtcEventLog& event_log = *owned_event_log;
+
+ Environment env = CreateEnvironment(
+ std::move(owned_field_trials), std::move(owned_clock),
+ std::move(owned_task_queue_factory), std::move(owned_event_log));
+
+ EXPECT_THAT(env.field_trials(), Ref(field_trials));
+ EXPECT_THAT(env.task_queue_factory(), Ref(task_queue_factory));
+ EXPECT_THAT(env.clock(), Ref(clock));
+ EXPECT_THAT(env.event_log(), Ref(event_log));
+}
+
+TEST(EnvironmentTest, UsesProvidedUtilitiesWithoutOwnership) {
+ FakeFieldTrials field_trials;
+ FakeTaskQueueFactory task_queue_factory;
+ SimulatedClock clock(Timestamp::Zero());
+ RtcEventLogNull event_log;
+
+ Environment env =
+ CreateEnvironment(&field_trials, &clock, &task_queue_factory, &event_log);
+
+ EXPECT_THAT(env.field_trials(), Ref(field_trials));
+ EXPECT_THAT(env.task_queue_factory(), Ref(task_queue_factory));
+ EXPECT_THAT(env.clock(), Ref(clock));
+ EXPECT_THAT(env.event_log(), Ref(event_log));
+}
+
+TEST(EnvironmentTest, UsesLastProvidedUtility) {
+ auto owned_field_trials1 = std::make_unique<FakeFieldTrials>();
+ auto owned_field_trials2 = std::make_unique<FakeFieldTrials>();
+ FieldTrialsView& field_trials2 = *owned_field_trials2;
+
+ Environment env = CreateEnvironment(std::move(owned_field_trials1),
+ std::move(owned_field_trials2));
+
+ EXPECT_THAT(env.field_trials(), Ref(field_trials2));
+}
+
+// Utilities can be provided from different sources, and when some source
+// choose not to provide an utility, it is usually expressed with nullptr.
+// When utility is not provided, it is natural to use previously set one.
+// E.g. Both PeerConnectionFactoryDependencies and PeerConnectionDependencies
+// provide field trials. When PeerConnectionDependencies::trials == nullptr,
+// then trials from the PeerConnectionFactoryDependencies should be used.
+// With nullptr accepted and ignored this can be expressed by
+// `Environemt env = CreateEnvironment(pcf_deps.trials, pc_deps.trials);`
+// That would use pc_deps.trials when not nullptr, pcf_deps.trials when
+// pc_deps.trials is nullptr, but pcf_deps.trials is not, and default field
+// trials when both are nullptr.
+TEST(EnvironmentTest, IgnoresProvidedNullptrUtility) {
+ auto owned_field_trials = std::make_unique<FakeFieldTrials>();
+ std::unique_ptr<FieldTrialsView> null_field_trials = nullptr;
+ FieldTrialsView& field_trials = *owned_field_trials;
+
+ Environment env = CreateEnvironment(std::move(owned_field_trials),
+ std::move(null_field_trials));
+
+ EXPECT_THAT(env.field_trials(), Ref(field_trials));
+}
+
+TEST(EnvironmentTest, KeepsUtilityAliveWhileEnvironmentIsAlive) {
+ bool utility_destroyed = false;
+ auto field_trials = std::make_unique<FakeFieldTrials>(
+ /*on_destroyed=*/[&] { utility_destroyed = true; });
+
+ // Wrap Environment into optional to have explicit control when it is deleted.
+ absl::optional<Environment> env = CreateEnvironment(std::move(field_trials));
+
+ EXPECT_FALSE(utility_destroyed);
+ env = absl::nullopt;
+ EXPECT_TRUE(utility_destroyed);
+}
+
+TEST(EnvironmentTest, KeepsUtilityAliveWhileCopyOfEnvironmentIsAlive) {
+ bool utility_destroyed = false;
+ auto field_trials = std::make_unique<FakeFieldTrials>(
+ /*on_destroyed=*/[&] { utility_destroyed = true; });
+
+ absl::optional<Environment> env1 = CreateEnvironment(std::move(field_trials));
+ absl::optional<Environment> env2 = env1;
+
+ EXPECT_FALSE(utility_destroyed);
+ env1 = absl::nullopt;
+ EXPECT_FALSE(utility_destroyed);
+ env2 = absl::nullopt;
+ EXPECT_TRUE(utility_destroyed);
+}
+
+TEST(EnvironmentTest, FactoryCanBeReusedToCreateDifferentEnvironments) {
+ auto owned_task_queue_factory = std::make_unique<FakeTaskQueueFactory>();
+ auto owned_field_trials1 = std::make_unique<FakeFieldTrials>();
+ auto owned_field_trials2 = std::make_unique<FakeFieldTrials>();
+ TaskQueueFactory& task_queue_factory = *owned_task_queue_factory;
+ FieldTrialsView& field_trials1 = *owned_field_trials1;
+ FieldTrialsView& field_trials2 = *owned_field_trials2;
+
+ EnvironmentFactory factory;
+ factory.Set(std::move(owned_task_queue_factory));
+ factory.Set(std::move(owned_field_trials1));
+ Environment env1 = factory.Create();
+ factory.Set(std::move(owned_field_trials2));
+ Environment env2 = factory.Create();
+
+ // Environments share the same custom task queue factory.
+ EXPECT_THAT(env1.task_queue_factory(), Ref(task_queue_factory));
+ EXPECT_THAT(env2.task_queue_factory(), Ref(task_queue_factory));
+
+ // Environments have different field trials.
+ EXPECT_THAT(env1.field_trials(), Ref(field_trials1));
+ EXPECT_THAT(env2.field_trials(), Ref(field_trials2));
+}
+
+TEST(EnvironmentTest, FactoryCanCreateNewEnvironmentFromExistingOne) {
+ Environment env1 =
+ CreateEnvironment(std::make_unique<FakeTaskQueueFactory>());
+ EnvironmentFactory factory(env1);
+ factory.Set(std::make_unique<FakeFieldTrials>());
+ Environment env2 = factory.Create();
+
+ // Environments share the same default clock.
+ EXPECT_THAT(env2.clock(), Ref(env1.clock()));
+
+ // Environments share the same custom task queue factory.
+ EXPECT_THAT(env2.task_queue_factory(), Ref(env1.task_queue_factory()));
+
+ // Environments have different field trials.
+ EXPECT_THAT(env2.field_trials(), Not(Ref(env1.field_trials())));
+}
+
+TEST(EnvironmentTest, KeepsOwnershipsWhenCreateNewEnvironmentFromExistingOne) {
+ bool utility1_destroyed = false;
+ bool utility2_destroyed = false;
+ absl::optional<Environment> env1 =
+ CreateEnvironment(std::make_unique<FakeTaskQueueFactory>(
+ /*on_destroyed=*/[&] { utility1_destroyed = true; }));
+
+ absl::optional<EnvironmentFactory> factory = EnvironmentFactory(*env1);
+
+ // Destroy env1, check utility1 it was using is still alive.
+ env1 = absl::nullopt;
+ EXPECT_FALSE(utility1_destroyed);
+
+ factory->Set(std::make_unique<FakeFieldTrials>(
+ /*on_destroyed=*/[&] { utility2_destroyed = true; }));
+ absl::optional<Environment> env2 = factory->Create();
+
+ // Destroy the factory, check all utilities used by env2 are alive.
+ factory = absl::nullopt;
+ EXPECT_FALSE(utility1_destroyed);
+ EXPECT_FALSE(utility2_destroyed);
+
+ // Once last Environment object is deleted, utilties should be deleted too.
+ env2 = absl::nullopt;
+ EXPECT_TRUE(utility1_destroyed);
+ EXPECT_TRUE(utility2_destroyed);
+}
+
+TEST(EnvironmentTest, DestroysUtilitiesInReverseProvidedOrder) {
+ std::vector<std::string> destroyed;
+ auto field_trials = std::make_unique<FakeFieldTrials>(
+ /*on_destroyed=*/[&] { destroyed.push_back("field_trials"); });
+ auto task_queue_factory = std::make_unique<FakeTaskQueueFactory>(
+ /*on_destroyed=*/[&] { destroyed.push_back("task_queue_factory"); });
+
+ absl::optional<Environment> env =
+ CreateEnvironment(std::move(field_trials), std::move(task_queue_factory));
+
+ ASSERT_THAT(destroyed, IsEmpty());
+ env = absl::nullopt;
+ EXPECT_THAT(destroyed, ElementsAre("task_queue_factory", "field_trials"));
+}
+
+} // namespace
+} // namespace webrtc