blob: 6c343fc122aba6fb9c15a62638a050c719c2883b [file] [log] [blame]
Sebastian Jansson9eb38862018-06-14 16:47:42 +02001/*
2 * Copyright 2018 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#include "rtc_base/experiments/field_trial_parser.h"
11#include "rtc_base/gunit.h"
12#include "system_wrappers/include/field_trial.h"
13#include "test/field_trial.h"
14
15namespace webrtc {
16namespace {
17const char kDummyExperiment[] = "WebRTC-DummyExperiment";
18
19struct DummyExperiment {
20 FieldTrialFlag enabled = FieldTrialFlag("Enabled");
21 FieldTrialParameter<double> factor = FieldTrialParameter<double>("f", 0.5);
22 FieldTrialParameter<int> retries = FieldTrialParameter<int>("r", 5);
23 FieldTrialParameter<bool> ping = FieldTrialParameter<bool>("p", 0);
24 FieldTrialParameter<std::string> hash =
25 FieldTrialParameter<std::string>("h", "a80");
26
27 explicit DummyExperiment(std::string field_trial) {
28 ParseFieldTrial({&enabled, &factor, &retries, &ping, &hash}, field_trial);
29 }
30 DummyExperiment() {
31 std::string trial_string = field_trial::FindFullName(kDummyExperiment);
32 ParseFieldTrial({&enabled, &factor, &retries, &ping, &hash}, trial_string);
33 }
34};
35
36enum class CustomEnum {
37 kDefault,
38 kRed,
39 kBlue,
40};
41} // namespace
42
43// Providing a custom parser for an enum can make the trial string easier to
44// read, but also adds more code and makes the string more verbose.
45template <>
46rtc::Optional<CustomEnum> ParseTypedParameter<CustomEnum>(std::string str) {
47 if (str == "default")
48 return CustomEnum::kDefault;
49 else if (str == "red")
50 return CustomEnum::kRed;
51 else if (str == "blue")
52 return CustomEnum::kBlue;
53 return rtc::nullopt;
54}
55
56TEST(FieldTrialParserTest, ParsesValidParameters) {
57 DummyExperiment exp("Enabled,f:-1.7,r:2,p:1,h:x7c");
58 EXPECT_TRUE(exp.enabled.Get());
59 EXPECT_EQ(exp.factor.Get(), -1.7);
60 EXPECT_EQ(exp.retries.Get(), 2);
61 EXPECT_EQ(exp.ping.Get(), true);
62 EXPECT_EQ(exp.hash.Get(), "x7c");
63}
64TEST(FieldTrialParserTest, InitializesFromFieldTrial) {
65 test::ScopedFieldTrials field_trials(
66 "WebRTC-OtherExperiment/Disabled/"
67 "WebRTC-DummyExperiment/Enabled,f:-1.7,r:2,p:1,h:x7c/"
68 "WebRTC-AnotherExperiment/Enabled,f:-3.1,otherstuff:beef/");
69 DummyExperiment exp;
70 EXPECT_TRUE(exp.enabled.Get());
71 EXPECT_EQ(exp.factor.Get(), -1.7);
72 EXPECT_EQ(exp.retries.Get(), 2);
73 EXPECT_EQ(exp.ping.Get(), true);
74 EXPECT_EQ(exp.hash.Get(), "x7c");
75}
76TEST(FieldTrialParserTest, UsesDefaults) {
77 DummyExperiment exp("");
78 EXPECT_FALSE(exp.enabled.Get());
79 EXPECT_EQ(exp.factor.Get(), 0.5);
80 EXPECT_EQ(exp.retries.Get(), 5);
81 EXPECT_EQ(exp.ping.Get(), false);
82 EXPECT_EQ(exp.hash.Get(), "a80");
83}
84TEST(FieldTrialParserTest, CanHandleMixedInput) {
85 DummyExperiment exp("p:true,h:,Enabled");
86 EXPECT_TRUE(exp.enabled.Get());
87 EXPECT_EQ(exp.factor.Get(), 0.5);
88 EXPECT_EQ(exp.retries.Get(), 5);
89 EXPECT_EQ(exp.ping.Get(), true);
90 EXPECT_EQ(exp.hash.Get(), "");
91}
92TEST(FieldTrialParserTest, IgnoresNewKey) {
93 DummyExperiment exp("Disabled,r:-11,foo");
94 EXPECT_FALSE(exp.enabled.Get());
95 EXPECT_EQ(exp.factor.Get(), 0.5);
96 EXPECT_EQ(exp.retries.Get(), -11);
97}
98TEST(FieldTrialParserTest, IgnoresInvalid) {
99 DummyExperiment exp("Enabled,f,p:,r:%,,:foo,h");
100 EXPECT_TRUE(exp.enabled.Get());
101 EXPECT_EQ(exp.factor.Get(), 0.5);
102 EXPECT_EQ(exp.retries.Get(), 5);
103 EXPECT_EQ(exp.ping.Get(), false);
104 EXPECT_EQ(exp.hash.Get(), "a80");
105}
106TEST(FieldTrialParserTest, ParsesOptionalParameters) {
107 FieldTrialOptional<int> max_count("c", rtc::nullopt);
108 ParseFieldTrial({&max_count}, "");
109 EXPECT_FALSE(max_count.Get().has_value());
110 ParseFieldTrial({&max_count}, "c:10");
111 EXPECT_EQ(max_count.Get().value(), 10);
112 ParseFieldTrial({&max_count}, "c");
113 EXPECT_FALSE(max_count.Get().has_value());
114 ParseFieldTrial({&max_count}, "c:20");
115 EXPECT_EQ(max_count.Get().value(), 20);
116 ParseFieldTrial({&max_count}, "c:");
117 EXPECT_EQ(max_count.Get().value(), 20);
118 FieldTrialOptional<std::string> optional_string("s", std::string("ab"));
119 ParseFieldTrial({&optional_string}, "s:");
120 EXPECT_EQ(optional_string.Get().value(), "");
121 ParseFieldTrial({&optional_string}, "s");
122 EXPECT_FALSE(optional_string.Get().has_value());
123}
124TEST(FieldTrialParserTest, ParsesCustomEnumParameter) {
125 FieldTrialParameter<CustomEnum> my_enum("e", CustomEnum::kDefault);
126 ParseFieldTrial({&my_enum}, "");
127 EXPECT_EQ(my_enum.Get(), CustomEnum::kDefault);
128 ParseFieldTrial({&my_enum}, "e:red");
129 EXPECT_EQ(my_enum.Get(), CustomEnum::kRed);
130}
131} // namespace webrtc