blob: 92649b4bf1cd4bccefe5e2a9a15cdc40ef783a45 [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"
Jonas Olsson97d84ef2019-04-11 11:53:26 +020011
12#include "rtc_base/experiments/field_trial_list.h"
Sebastian Jansson9eb38862018-06-14 16:47:42 +020013#include "rtc_base/gunit.h"
14#include "system_wrappers/include/field_trial.h"
15#include "test/field_trial.h"
Jonas Olsson97d84ef2019-04-11 11:53:26 +020016#include "test/gmock.h"
Sebastian Jansson9eb38862018-06-14 16:47:42 +020017
18namespace webrtc {
19namespace {
20const char kDummyExperiment[] = "WebRTC-DummyExperiment";
21
22struct DummyExperiment {
23 FieldTrialFlag enabled = FieldTrialFlag("Enabled");
24 FieldTrialParameter<double> factor = FieldTrialParameter<double>("f", 0.5);
25 FieldTrialParameter<int> retries = FieldTrialParameter<int>("r", 5);
Bjorn Terelius9f00f0e2019-08-30 09:39:31 +020026 FieldTrialParameter<unsigned> size = FieldTrialParameter<unsigned>("s", 3);
Sebastian Jansson9eb38862018-06-14 16:47:42 +020027 FieldTrialParameter<bool> ping = FieldTrialParameter<bool>("p", 0);
Sebastian Jansson9eb38862018-06-14 16:47:42 +020028
29 explicit DummyExperiment(std::string field_trial) {
Sebastian Janssone74156f2019-09-04 12:54:42 +020030 ParseFieldTrial({&enabled, &factor, &retries, &size, &ping}, field_trial);
Sebastian Jansson9eb38862018-06-14 16:47:42 +020031 }
32 DummyExperiment() {
33 std::string trial_string = field_trial::FindFullName(kDummyExperiment);
Sebastian Janssone74156f2019-09-04 12:54:42 +020034 ParseFieldTrial({&enabled, &factor, &retries, &size, &ping}, trial_string);
Sebastian Jansson9eb38862018-06-14 16:47:42 +020035 }
36};
37
38enum class CustomEnum {
Sebastian Jansson2c74d852018-06-26 10:30:16 +020039 kDefault = 0,
40 kRed = 1,
41 kBlue = 2,
Sebastian Jansson9eb38862018-06-14 16:47:42 +020042};
Jonas Olsson97d84ef2019-04-11 11:53:26 +020043
Sebastian Jansson9eb38862018-06-14 16:47:42 +020044} // namespace
45
Sebastian Jansson9eb38862018-06-14 16:47:42 +020046TEST(FieldTrialParserTest, ParsesValidParameters) {
Sebastian Janssone74156f2019-09-04 12:54:42 +020047 DummyExperiment exp("Enabled,f:-1.7,r:2,s:10,p:1");
Sebastian Jansson9eb38862018-06-14 16:47:42 +020048 EXPECT_TRUE(exp.enabled.Get());
49 EXPECT_EQ(exp.factor.Get(), -1.7);
50 EXPECT_EQ(exp.retries.Get(), 2);
Bjorn Terelius9f00f0e2019-08-30 09:39:31 +020051 EXPECT_EQ(exp.size.Get(), 10u);
Sebastian Jansson9eb38862018-06-14 16:47:42 +020052 EXPECT_EQ(exp.ping.Get(), true);
Sebastian Jansson9eb38862018-06-14 16:47:42 +020053}
54TEST(FieldTrialParserTest, InitializesFromFieldTrial) {
55 test::ScopedFieldTrials field_trials(
56 "WebRTC-OtherExperiment/Disabled/"
Sebastian Janssone74156f2019-09-04 12:54:42 +020057 "WebRTC-DummyExperiment/Enabled,f:-1.7,r:2,s:10,p:1/"
Sebastian Jansson9eb38862018-06-14 16:47:42 +020058 "WebRTC-AnotherExperiment/Enabled,f:-3.1,otherstuff:beef/");
59 DummyExperiment exp;
60 EXPECT_TRUE(exp.enabled.Get());
61 EXPECT_EQ(exp.factor.Get(), -1.7);
62 EXPECT_EQ(exp.retries.Get(), 2);
Bjorn Terelius9f00f0e2019-08-30 09:39:31 +020063 EXPECT_EQ(exp.size.Get(), 10u);
Sebastian Jansson9eb38862018-06-14 16:47:42 +020064 EXPECT_EQ(exp.ping.Get(), true);
Sebastian Jansson9eb38862018-06-14 16:47:42 +020065}
66TEST(FieldTrialParserTest, UsesDefaults) {
67 DummyExperiment exp("");
68 EXPECT_FALSE(exp.enabled.Get());
69 EXPECT_EQ(exp.factor.Get(), 0.5);
70 EXPECT_EQ(exp.retries.Get(), 5);
Bjorn Terelius9f00f0e2019-08-30 09:39:31 +020071 EXPECT_EQ(exp.size.Get(), 3u);
Sebastian Jansson9eb38862018-06-14 16:47:42 +020072 EXPECT_EQ(exp.ping.Get(), false);
Sebastian Jansson9eb38862018-06-14 16:47:42 +020073}
74TEST(FieldTrialParserTest, CanHandleMixedInput) {
75 DummyExperiment exp("p:true,h:,Enabled");
76 EXPECT_TRUE(exp.enabled.Get());
77 EXPECT_EQ(exp.factor.Get(), 0.5);
78 EXPECT_EQ(exp.retries.Get(), 5);
Bjorn Terelius9f00f0e2019-08-30 09:39:31 +020079 EXPECT_EQ(exp.size.Get(), 3u);
Sebastian Jansson9eb38862018-06-14 16:47:42 +020080 EXPECT_EQ(exp.ping.Get(), true);
Sebastian Jansson9eb38862018-06-14 16:47:42 +020081}
Sebastian Janssonec764662018-09-03 11:31:26 +020082TEST(FieldTrialParserTest, ParsesDoubleParameter) {
83 FieldTrialParameter<double> double_param("f", 0.0);
84 ParseFieldTrial({&double_param}, "f:45%");
85 EXPECT_EQ(double_param.Get(), 0.45);
86 ParseFieldTrial({&double_param}, "f:34 %");
87 EXPECT_EQ(double_param.Get(), 0.34);
88 ParseFieldTrial({&double_param}, "f:0.67");
89 EXPECT_EQ(double_param.Get(), 0.67);
90}
Sebastian Jansson9eb38862018-06-14 16:47:42 +020091TEST(FieldTrialParserTest, IgnoresNewKey) {
92 DummyExperiment exp("Disabled,r:-11,foo");
93 EXPECT_FALSE(exp.enabled.Get());
94 EXPECT_EQ(exp.factor.Get(), 0.5);
95 EXPECT_EQ(exp.retries.Get(), -11);
96}
97TEST(FieldTrialParserTest, IgnoresInvalid) {
Bjorn Terelius9f00f0e2019-08-30 09:39:31 +020098 DummyExperiment exp("Enabled,f,p:,r:%,,s:-1,:foo,h");
Sebastian Jansson9eb38862018-06-14 16:47:42 +020099 EXPECT_TRUE(exp.enabled.Get());
100 EXPECT_EQ(exp.factor.Get(), 0.5);
101 EXPECT_EQ(exp.retries.Get(), 5);
Bjorn Terelius9f00f0e2019-08-30 09:39:31 +0200102 EXPECT_EQ(exp.size.Get(), 3u);
Sebastian Jansson9eb38862018-06-14 16:47:42 +0200103 EXPECT_EQ(exp.ping.Get(), false);
Sebastian Jansson9eb38862018-06-14 16:47:42 +0200104}
Sebastian Janssonb22f0772018-11-19 17:44:33 +0100105TEST(FieldTrialParserTest, IgnoresOutOfRange) {
106 FieldTrialConstrained<double> low("low", 10, absl::nullopt, 100);
107 FieldTrialConstrained<double> high("high", 10, 5, absl::nullopt);
108 ParseFieldTrial({&low, &high}, "low:1000,high:0");
109 EXPECT_EQ(low.Get(), 10);
110 EXPECT_EQ(high.Get(), 10);
111 ParseFieldTrial({&low, &high}, "low:inf,high:nan");
112 EXPECT_EQ(low.Get(), 10);
113 EXPECT_EQ(high.Get(), 10);
114 ParseFieldTrial({&low, &high}, "low:20,high:20");
115 EXPECT_EQ(low.Get(), 20);
116 EXPECT_EQ(high.Get(), 20);
Bjorn Terelius9f00f0e2019-08-30 09:39:31 +0200117
118 FieldTrialConstrained<unsigned> size("size", 5, 1, 10);
119 ParseFieldTrial({&size}, "size:0");
120 EXPECT_EQ(size.Get(), 5u);
Sebastian Janssonb22f0772018-11-19 17:44:33 +0100121}
Sebastian Janssond69998a2018-12-20 12:25:19 +0100122TEST(FieldTrialParserTest, ReadsValuesFromFieldWithoutKey) {
123 FieldTrialFlag enabled("Enabled");
124 FieldTrialParameter<int> req("", 10);
125 ParseFieldTrial({&enabled, &req}, "Enabled,20");
126 EXPECT_EQ(req.Get(), 20);
127 ParseFieldTrial({&req}, "30");
128 EXPECT_EQ(req.Get(), 30);
129}
Sebastian Jansson9eb38862018-06-14 16:47:42 +0200130TEST(FieldTrialParserTest, ParsesOptionalParameters) {
Danil Chapovalov0a1d1892018-06-21 11:48:25 +0200131 FieldTrialOptional<int> max_count("c", absl::nullopt);
Sebastian Jansson9eb38862018-06-14 16:47:42 +0200132 ParseFieldTrial({&max_count}, "");
Sebastian Janssonfea46372018-09-03 10:15:13 +0200133 EXPECT_FALSE(max_count.GetOptional().has_value());
Sebastian Jansson9eb38862018-06-14 16:47:42 +0200134 ParseFieldTrial({&max_count}, "c:10");
Sebastian Janssonfea46372018-09-03 10:15:13 +0200135 EXPECT_EQ(max_count.GetOptional().value(), 10);
Sebastian Jansson9eb38862018-06-14 16:47:42 +0200136 ParseFieldTrial({&max_count}, "c");
Sebastian Janssonfea46372018-09-03 10:15:13 +0200137 EXPECT_FALSE(max_count.GetOptional().has_value());
Sebastian Jansson9eb38862018-06-14 16:47:42 +0200138 ParseFieldTrial({&max_count}, "c:20");
Sebastian Janssonfea46372018-09-03 10:15:13 +0200139 EXPECT_EQ(max_count.GetOptional().value(), 20);
Sebastian Jansson9eb38862018-06-14 16:47:42 +0200140 ParseFieldTrial({&max_count}, "c:");
Sebastian Janssonfea46372018-09-03 10:15:13 +0200141 EXPECT_EQ(max_count.GetOptional().value(), 20);
Bjorn Terelius9f00f0e2019-08-30 09:39:31 +0200142
143 FieldTrialOptional<unsigned> max_size("c", absl::nullopt);
144 ParseFieldTrial({&max_size}, "");
145 EXPECT_FALSE(max_size.GetOptional().has_value());
146 ParseFieldTrial({&max_size}, "c:10");
147 EXPECT_EQ(max_size.GetOptional().value(), 10u);
148 ParseFieldTrial({&max_size}, "c");
149 EXPECT_FALSE(max_size.GetOptional().has_value());
150 ParseFieldTrial({&max_size}, "c:20");
151 EXPECT_EQ(max_size.GetOptional().value(), 20u);
152
Sebastian Jansson9eb38862018-06-14 16:47:42 +0200153}
154TEST(FieldTrialParserTest, ParsesCustomEnumParameter) {
Sebastian Jansson2c74d852018-06-26 10:30:16 +0200155 FieldTrialEnum<CustomEnum> my_enum("e", CustomEnum::kDefault,
156 {{"default", CustomEnum::kDefault},
157 {"red", CustomEnum::kRed},
158 {"blue", CustomEnum::kBlue}});
Sebastian Jansson9eb38862018-06-14 16:47:42 +0200159 ParseFieldTrial({&my_enum}, "");
160 EXPECT_EQ(my_enum.Get(), CustomEnum::kDefault);
161 ParseFieldTrial({&my_enum}, "e:red");
162 EXPECT_EQ(my_enum.Get(), CustomEnum::kRed);
Sebastian Jansson2c74d852018-06-26 10:30:16 +0200163 ParseFieldTrial({&my_enum}, "e:2");
164 EXPECT_EQ(my_enum.Get(), CustomEnum::kBlue);
165 ParseFieldTrial({&my_enum}, "e:5");
166 EXPECT_EQ(my_enum.Get(), CustomEnum::kBlue);
Sebastian Jansson9eb38862018-06-14 16:47:42 +0200167}
Jonas Olsson97d84ef2019-04-11 11:53:26 +0200168
Sebastian Jansson9eb38862018-06-14 16:47:42 +0200169} // namespace webrtc