/* * 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 #include #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 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 f1 = FieldTrials::CreateNoGlobal("SomeString/Enabled/"); std::unique_ptr 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 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