|  | /* | 
|  | *  Copyright 2022 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/field_trials.h" | 
|  |  | 
|  | #include <memory> | 
|  | #include <utility> | 
|  |  | 
|  | #include "absl/strings/string_view.h" | 
|  | #include "api/transport/field_trial_based_config.h" | 
|  | #include "rtc_base/containers/flat_set.h" | 
|  | #include "system_wrappers/include/field_trial.h" | 
|  | #include "test/field_trial.h" | 
|  | #include "test/gmock.h" | 
|  | #include "test/gtest.h" | 
|  |  | 
|  | #if GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) | 
|  | #include "test/testsupport/rtc_expect_death.h" | 
|  | #endif  // GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) | 
|  |  | 
|  | namespace webrtc { | 
|  | namespace { | 
|  |  | 
|  | using ::testing::NotNull; | 
|  | using ::webrtc::field_trial::FieldTrialsAllowedInScopeForTesting; | 
|  | using ::webrtc::test::ScopedFieldTrials; | 
|  |  | 
|  | TEST(FieldTrialsTest, EmptyStringHasNoEffect) { | 
|  | FieldTrialsAllowedInScopeForTesting k({"MyCoolTrial"}); | 
|  | FieldTrials f(""); | 
|  | f.RegisterKeysForTesting({"MyCoolTrial"}); | 
|  |  | 
|  | EXPECT_FALSE(f.IsEnabled("MyCoolTrial")); | 
|  | EXPECT_FALSE(f.IsDisabled("MyCoolTrial")); | 
|  | } | 
|  |  | 
|  | TEST(FieldTrialsTest, EnabledDisabledMustBeFirstInValue) { | 
|  | FieldTrials f( | 
|  | "MyCoolTrial/EnabledFoo/" | 
|  | "MyUncoolTrial/DisabledBar/" | 
|  | "AnotherTrial/BazEnabled/"); | 
|  | f.RegisterKeysForTesting({"MyCoolTrial", "MyUncoolTrial", "AnotherTrial"}); | 
|  |  | 
|  | EXPECT_TRUE(f.IsEnabled("MyCoolTrial")); | 
|  | EXPECT_TRUE(f.IsDisabled("MyUncoolTrial")); | 
|  | EXPECT_FALSE(f.IsEnabled("AnotherTrial")); | 
|  | } | 
|  |  | 
|  | TEST(FieldTrialsTest, FieldTrialsDoesNotReadGlobalString) { | 
|  | FieldTrialsAllowedInScopeForTesting k({"MyCoolTrial", "MyUncoolTrial"}); | 
|  | ScopedFieldTrials g("MyCoolTrial/Enabled/MyUncoolTrial/Disabled/"); | 
|  | FieldTrials f(""); | 
|  | f.RegisterKeysForTesting({"MyCoolTrial", "MyUncoolTrial"}); | 
|  |  | 
|  | EXPECT_FALSE(f.IsEnabled("MyCoolTrial")); | 
|  | EXPECT_FALSE(f.IsDisabled("MyUncoolTrial")); | 
|  | } | 
|  |  | 
|  | TEST(FieldTrialsTest, FieldTrialsWritesGlobalString) { | 
|  | FieldTrialsAllowedInScopeForTesting k({"MyCoolTrial", "MyUncoolTrial"}); | 
|  | FieldTrials f("MyCoolTrial/Enabled/MyUncoolTrial/Disabled/"); | 
|  | EXPECT_TRUE(webrtc::field_trial::IsEnabled("MyCoolTrial")); | 
|  | EXPECT_TRUE(webrtc::field_trial::IsDisabled("MyUncoolTrial")); | 
|  | } | 
|  |  | 
|  | TEST(FieldTrialsTest, FieldTrialsRestoresGlobalStringAfterDestruction) { | 
|  | static constexpr char s[] = "SomeString/Enabled/"; | 
|  | ScopedFieldTrials g(s); | 
|  | { | 
|  | FieldTrials f("SomeOtherString/Enabled/"); | 
|  | EXPECT_STREQ(webrtc::field_trial::GetFieldTrialString(), | 
|  | "SomeOtherString/Enabled/"); | 
|  | } | 
|  | EXPECT_STREQ(webrtc::field_trial::GetFieldTrialString(), s); | 
|  | } | 
|  |  | 
|  | #if GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) | 
|  | TEST(FieldTrialsTest, FieldTrialsDoesNotSupportSimultaneousInstances) { | 
|  | FieldTrials f("SomeString/Enabled/"); | 
|  | RTC_EXPECT_DEATH(FieldTrials("SomeOtherString/Enabled/").Lookup("Whatever"), | 
|  | "Only one instance"); | 
|  | } | 
|  | #endif  // GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) | 
|  |  | 
|  | TEST(FieldTrialsTest, FieldTrialsSupportsSeparateInstances) { | 
|  | { FieldTrials f("SomeString/Enabled/"); } | 
|  | { FieldTrials f("SomeOtherString/Enabled/"); } | 
|  | } | 
|  |  | 
|  | TEST(FieldTrialsTest, NonGlobalFieldTrialsInstanceDoesNotModifyGlobalString) { | 
|  | FieldTrialsAllowedInScopeForTesting k({"SomeString"}); | 
|  | std::unique_ptr<FieldTrials> f = | 
|  | FieldTrials::CreateNoGlobal("SomeString/Enabled/"); | 
|  | ASSERT_THAT(f, NotNull()); | 
|  | f->RegisterKeysForTesting({"SomeString"}); | 
|  |  | 
|  | EXPECT_TRUE(f->IsEnabled("SomeString")); | 
|  | EXPECT_FALSE(webrtc::field_trial::IsEnabled("SomeString")); | 
|  | } | 
|  |  | 
|  | TEST(FieldTrialsTest, NonGlobalFieldTrialsSupportSimultaneousInstances) { | 
|  | std::unique_ptr<FieldTrials> f1 = | 
|  | FieldTrials::CreateNoGlobal("SomeString/Enabled/"); | 
|  | std::unique_ptr<FieldTrials> f2 = | 
|  | FieldTrials::CreateNoGlobal("SomeOtherString/Enabled/"); | 
|  | ASSERT_THAT(f1, NotNull()); | 
|  | ASSERT_THAT(f2, NotNull()); | 
|  | f1->RegisterKeysForTesting({"SomeString", "SomeOtherString"}); | 
|  | f2->RegisterKeysForTesting({"SomeString", "SomeOtherString"}); | 
|  |  | 
|  | EXPECT_TRUE(f1->IsEnabled("SomeString")); | 
|  | EXPECT_FALSE(f1->IsEnabled("SomeOtherString")); | 
|  |  | 
|  | EXPECT_FALSE(f2->IsEnabled("SomeString")); | 
|  | EXPECT_TRUE(f2->IsEnabled("SomeOtherString")); | 
|  | } | 
|  |  | 
|  | TEST(FieldTrialsTest, GlobalAndNonGlobalFieldTrialsAreDisjoint) { | 
|  | FieldTrialsAllowedInScopeForTesting k({"SomeString", "SomeOtherString"}); | 
|  | FieldTrials f1("SomeString/Enabled/"); | 
|  | std::unique_ptr<FieldTrials> f2 = | 
|  | FieldTrials::CreateNoGlobal("SomeOtherString/Enabled/"); | 
|  | ASSERT_THAT(f2, NotNull()); | 
|  | f1.RegisterKeysForTesting({"SomeString", "SomeOtherString"}); | 
|  | f2->RegisterKeysForTesting({"SomeString", "SomeOtherString"}); | 
|  |  | 
|  | EXPECT_TRUE(f1.IsEnabled("SomeString")); | 
|  | EXPECT_FALSE(f1.IsEnabled("SomeOtherString")); | 
|  |  | 
|  | EXPECT_FALSE(f2->IsEnabled("SomeString")); | 
|  | EXPECT_TRUE(f2->IsEnabled("SomeOtherString")); | 
|  | } | 
|  |  | 
|  | TEST(FieldTrialsTest, FieldTrialBasedConfigReadsGlobalString) { | 
|  | FieldTrialsAllowedInScopeForTesting k({"MyCoolTrial", "MyUncoolTrial"}); | 
|  | ScopedFieldTrials g("MyCoolTrial/Enabled/MyUncoolTrial/Disabled/"); | 
|  | FieldTrialBasedConfig f; | 
|  | f.RegisterKeysForTesting({"MyCoolTrial", "MyUncoolTrial"}); | 
|  |  | 
|  | EXPECT_TRUE(f.IsEnabled("MyCoolTrial")); | 
|  | EXPECT_TRUE(f.IsDisabled("MyUncoolTrial")); | 
|  | } | 
|  |  | 
|  | }  // namespace | 
|  | }  // namespace webrtc |