blob: cf483d7334c0770f4c66da9f652cc6eecb7840f9 [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);
26 FieldTrialParameter<bool> ping = FieldTrialParameter<bool>("p", 0);
27 FieldTrialParameter<std::string> hash =
28 FieldTrialParameter<std::string>("h", "a80");
29
30 explicit DummyExperiment(std::string field_trial) {
31 ParseFieldTrial({&enabled, &factor, &retries, &ping, &hash}, field_trial);
32 }
33 DummyExperiment() {
34 std::string trial_string = field_trial::FindFullName(kDummyExperiment);
35 ParseFieldTrial({&enabled, &factor, &retries, &ping, &hash}, trial_string);
36 }
37};
38
39enum class CustomEnum {
Sebastian Jansson2c74d852018-06-26 10:30:16 +020040 kDefault = 0,
41 kRed = 1,
42 kBlue = 2,
Sebastian Jansson9eb38862018-06-14 16:47:42 +020043};
Jonas Olsson97d84ef2019-04-11 11:53:26 +020044
Sebastian Jansson9eb38862018-06-14 16:47:42 +020045} // namespace
46
Sebastian Jansson9eb38862018-06-14 16:47:42 +020047TEST(FieldTrialParserTest, ParsesValidParameters) {
48 DummyExperiment exp("Enabled,f:-1.7,r:2,p:1,h:x7c");
49 EXPECT_TRUE(exp.enabled.Get());
50 EXPECT_EQ(exp.factor.Get(), -1.7);
51 EXPECT_EQ(exp.retries.Get(), 2);
52 EXPECT_EQ(exp.ping.Get(), true);
53 EXPECT_EQ(exp.hash.Get(), "x7c");
54}
55TEST(FieldTrialParserTest, InitializesFromFieldTrial) {
56 test::ScopedFieldTrials field_trials(
57 "WebRTC-OtherExperiment/Disabled/"
58 "WebRTC-DummyExperiment/Enabled,f:-1.7,r:2,p:1,h:x7c/"
59 "WebRTC-AnotherExperiment/Enabled,f:-3.1,otherstuff:beef/");
60 DummyExperiment exp;
61 EXPECT_TRUE(exp.enabled.Get());
62 EXPECT_EQ(exp.factor.Get(), -1.7);
63 EXPECT_EQ(exp.retries.Get(), 2);
64 EXPECT_EQ(exp.ping.Get(), true);
65 EXPECT_EQ(exp.hash.Get(), "x7c");
66}
67TEST(FieldTrialParserTest, UsesDefaults) {
68 DummyExperiment exp("");
69 EXPECT_FALSE(exp.enabled.Get());
70 EXPECT_EQ(exp.factor.Get(), 0.5);
71 EXPECT_EQ(exp.retries.Get(), 5);
72 EXPECT_EQ(exp.ping.Get(), false);
73 EXPECT_EQ(exp.hash.Get(), "a80");
74}
75TEST(FieldTrialParserTest, CanHandleMixedInput) {
76 DummyExperiment exp("p:true,h:,Enabled");
77 EXPECT_TRUE(exp.enabled.Get());
78 EXPECT_EQ(exp.factor.Get(), 0.5);
79 EXPECT_EQ(exp.retries.Get(), 5);
80 EXPECT_EQ(exp.ping.Get(), true);
81 EXPECT_EQ(exp.hash.Get(), "");
82}
Sebastian Janssonec764662018-09-03 11:31:26 +020083TEST(FieldTrialParserTest, ParsesDoubleParameter) {
84 FieldTrialParameter<double> double_param("f", 0.0);
85 ParseFieldTrial({&double_param}, "f:45%");
86 EXPECT_EQ(double_param.Get(), 0.45);
87 ParseFieldTrial({&double_param}, "f:34 %");
88 EXPECT_EQ(double_param.Get(), 0.34);
89 ParseFieldTrial({&double_param}, "f:0.67");
90 EXPECT_EQ(double_param.Get(), 0.67);
91}
Sebastian Jansson9eb38862018-06-14 16:47:42 +020092TEST(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}
Sebastian Janssonb22f0772018-11-19 17:44:33 +0100106TEST(FieldTrialParserTest, IgnoresOutOfRange) {
107 FieldTrialConstrained<double> low("low", 10, absl::nullopt, 100);
108 FieldTrialConstrained<double> high("high", 10, 5, absl::nullopt);
109 ParseFieldTrial({&low, &high}, "low:1000,high:0");
110 EXPECT_EQ(low.Get(), 10);
111 EXPECT_EQ(high.Get(), 10);
112 ParseFieldTrial({&low, &high}, "low:inf,high:nan");
113 EXPECT_EQ(low.Get(), 10);
114 EXPECT_EQ(high.Get(), 10);
115 ParseFieldTrial({&low, &high}, "low:20,high:20");
116 EXPECT_EQ(low.Get(), 20);
117 EXPECT_EQ(high.Get(), 20);
118}
Sebastian Janssond69998a2018-12-20 12:25:19 +0100119TEST(FieldTrialParserTest, ReadsValuesFromFieldWithoutKey) {
120 FieldTrialFlag enabled("Enabled");
121 FieldTrialParameter<int> req("", 10);
122 ParseFieldTrial({&enabled, &req}, "Enabled,20");
123 EXPECT_EQ(req.Get(), 20);
124 ParseFieldTrial({&req}, "30");
125 EXPECT_EQ(req.Get(), 30);
126}
Sebastian Jansson9eb38862018-06-14 16:47:42 +0200127TEST(FieldTrialParserTest, ParsesOptionalParameters) {
Danil Chapovalov0a1d1892018-06-21 11:48:25 +0200128 FieldTrialOptional<int> max_count("c", absl::nullopt);
Sebastian Jansson9eb38862018-06-14 16:47:42 +0200129 ParseFieldTrial({&max_count}, "");
Sebastian Janssonfea46372018-09-03 10:15:13 +0200130 EXPECT_FALSE(max_count.GetOptional().has_value());
Sebastian Jansson9eb38862018-06-14 16:47:42 +0200131 ParseFieldTrial({&max_count}, "c:10");
Sebastian Janssonfea46372018-09-03 10:15:13 +0200132 EXPECT_EQ(max_count.GetOptional().value(), 10);
Sebastian Jansson9eb38862018-06-14 16:47:42 +0200133 ParseFieldTrial({&max_count}, "c");
Sebastian Janssonfea46372018-09-03 10:15:13 +0200134 EXPECT_FALSE(max_count.GetOptional().has_value());
Sebastian Jansson9eb38862018-06-14 16:47:42 +0200135 ParseFieldTrial({&max_count}, "c:20");
Sebastian Janssonfea46372018-09-03 10:15:13 +0200136 EXPECT_EQ(max_count.GetOptional().value(), 20);
Sebastian Jansson9eb38862018-06-14 16:47:42 +0200137 ParseFieldTrial({&max_count}, "c:");
Sebastian Janssonfea46372018-09-03 10:15:13 +0200138 EXPECT_EQ(max_count.GetOptional().value(), 20);
Sebastian Jansson9eb38862018-06-14 16:47:42 +0200139 FieldTrialOptional<std::string> optional_string("s", std::string("ab"));
140 ParseFieldTrial({&optional_string}, "s:");
Sebastian Janssonfea46372018-09-03 10:15:13 +0200141 EXPECT_EQ(optional_string.GetOptional().value(), "");
Sebastian Jansson9eb38862018-06-14 16:47:42 +0200142 ParseFieldTrial({&optional_string}, "s");
Sebastian Janssonfea46372018-09-03 10:15:13 +0200143 EXPECT_FALSE(optional_string.GetOptional().has_value());
Sebastian Jansson9eb38862018-06-14 16:47:42 +0200144}
145TEST(FieldTrialParserTest, ParsesCustomEnumParameter) {
Sebastian Jansson2c74d852018-06-26 10:30:16 +0200146 FieldTrialEnum<CustomEnum> my_enum("e", CustomEnum::kDefault,
147 {{"default", CustomEnum::kDefault},
148 {"red", CustomEnum::kRed},
149 {"blue", CustomEnum::kBlue}});
Sebastian Jansson9eb38862018-06-14 16:47:42 +0200150 ParseFieldTrial({&my_enum}, "");
151 EXPECT_EQ(my_enum.Get(), CustomEnum::kDefault);
152 ParseFieldTrial({&my_enum}, "e:red");
153 EXPECT_EQ(my_enum.Get(), CustomEnum::kRed);
Sebastian Jansson2c74d852018-06-26 10:30:16 +0200154 ParseFieldTrial({&my_enum}, "e:2");
155 EXPECT_EQ(my_enum.Get(), CustomEnum::kBlue);
156 ParseFieldTrial({&my_enum}, "e:5");
157 EXPECT_EQ(my_enum.Get(), CustomEnum::kBlue);
Sebastian Jansson9eb38862018-06-14 16:47:42 +0200158}
Jonas Olsson97d84ef2019-04-11 11:53:26 +0200159
Sebastian Jansson9eb38862018-06-14 16:47:42 +0200160} // namespace webrtc