xref: /aosp_15_r20/external/webrtc/rtc_base/experiments/field_trial_list_unittest.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1 /*
2  *  Copyright 2019 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 
11 #include "rtc_base/experiments/field_trial_list.h"
12 
13 #include "absl/strings/string_view.h"
14 #include "rtc_base/gunit.h"
15 #include "test/gmock.h"
16 
17 using testing::ElementsAre;
18 using testing::IsEmpty;
19 
20 namespace webrtc {
21 
22 struct Garment {
23   int price = 0;
24   std::string color = "";
25   bool has_glitter = false;
26 
27   // Only needed for testing.
28   Garment() = default;
Garmentwebrtc::Garment29   Garment(int p, absl::string_view c, bool g)
30       : price(p), color(c), has_glitter(g) {}
31 
operator ==webrtc::Garment32   bool operator==(const Garment& other) const {
33     return price == other.price && color == other.color &&
34            has_glitter == other.has_glitter;
35   }
36 };
37 
TEST(FieldTrialListTest,ParsesListParameter)38 TEST(FieldTrialListTest, ParsesListParameter) {
39   FieldTrialList<int> my_list("l", {5});
40   EXPECT_THAT(my_list.Get(), ElementsAre(5));
41   // If one element is invalid the list is unchanged.
42   ParseFieldTrial({&my_list}, "l:1|2|hat");
43   EXPECT_THAT(my_list.Get(), ElementsAre(5));
44   ParseFieldTrial({&my_list}, "l");
45   EXPECT_THAT(my_list.Get(), IsEmpty());
46   ParseFieldTrial({&my_list}, "l:1|2|3");
47   EXPECT_THAT(my_list.Get(), ElementsAre(1, 2, 3));
48   ParseFieldTrial({&my_list}, "l:-1");
49   EXPECT_THAT(my_list.Get(), ElementsAre(-1));
50 
51   FieldTrialList<std::string> another_list("l", {"hat"});
52   EXPECT_THAT(another_list.Get(), ElementsAre("hat"));
53   ParseFieldTrial({&another_list}, "l");
54   EXPECT_THAT(another_list.Get(), IsEmpty());
55   ParseFieldTrial({&another_list}, "l:");
56   EXPECT_THAT(another_list.Get(), ElementsAre(""));
57   ParseFieldTrial({&another_list}, "l:scarf|hat|mittens");
58   EXPECT_THAT(another_list.Get(), ElementsAre("scarf", "hat", "mittens"));
59   ParseFieldTrial({&another_list}, "l:scarf");
60   EXPECT_THAT(another_list.Get(), ElementsAre("scarf"));
61 }
62 
63 // Normal usage.
TEST(FieldTrialListTest,ParsesStructList)64 TEST(FieldTrialListTest, ParsesStructList) {
65   FieldTrialStructList<Garment> my_list(
66       {FieldTrialStructMember("color", [](Garment* g) { return &g->color; }),
67        FieldTrialStructMember("price", [](Garment* g) { return &g->price; }),
68        FieldTrialStructMember("has_glitter",
69                               [](Garment* g) { return &g->has_glitter; })},
70       {{1, "blue", false}, {2, "red", true}});
71 
72   ParseFieldTrial({&my_list},
73                   "color:mauve|red|gold,"
74                   "price:10|20|30,"
75                   "has_glitter:1|0|1,"
76                   "other_param:asdf");
77 
78   ASSERT_THAT(my_list.Get(),
79               ElementsAre(Garment{10, "mauve", true}, Garment{20, "red", false},
80                           Garment{30, "gold", true}));
81 }
82 
83 // One FieldTrialList has the wrong length, so we use the user-provided default
84 // list.
TEST(FieldTrialListTest,StructListKeepsDefaultWithMismatchingLength)85 TEST(FieldTrialListTest, StructListKeepsDefaultWithMismatchingLength) {
86   FieldTrialStructList<Garment> my_list(
87       {FieldTrialStructMember("wrong_length",
88                               [](Garment* g) { return &g->color; }),
89        FieldTrialStructMember("price", [](Garment* g) { return &g->price; })},
90       {{1, "blue", true}, {2, "red", false}});
91 
92   ParseFieldTrial({&my_list},
93                   "wrong_length:mauve|magenta|chartreuse|indigo,"
94                   "garment:hat|hat|crown,"
95                   "price:10|20|30");
96 
97   ASSERT_THAT(my_list.Get(),
98               ElementsAre(Garment{1, "blue", true}, Garment{2, "red", false}));
99 }
100 
101 // One list is missing. We set the values we're given, and the others remain
102 // as whatever the Garment default constructor set them to.
TEST(FieldTrialListTest,StructListUsesDefaultForMissingList)103 TEST(FieldTrialListTest, StructListUsesDefaultForMissingList) {
104   FieldTrialStructList<Garment> my_list(
105       {FieldTrialStructMember("color", [](Garment* g) { return &g->color; }),
106        FieldTrialStructMember("price", [](Garment* g) { return &g->price; })},
107       {{1, "blue", true}, {2, "red", false}});
108 
109   ParseFieldTrial({&my_list}, "price:10|20|30");
110 
111   ASSERT_THAT(my_list.Get(),
112               ElementsAre(Garment{10, "", false}, Garment{20, "", false},
113                           Garment{30, "", false}));
114 }
115 
116 // The user haven't provided values for any lists, so we use the default list.
TEST(FieldTrialListTest,StructListUsesDefaultListWithoutValues)117 TEST(FieldTrialListTest, StructListUsesDefaultListWithoutValues) {
118   FieldTrialStructList<Garment> my_list(
119       {FieldTrialStructMember("color", [](Garment* g) { return &g->color; }),
120        FieldTrialStructMember("price", [](Garment* g) { return &g->price; })},
121       {{1, "blue", true}, {2, "red", false}});
122 
123   ParseFieldTrial({&my_list}, "");
124 
125   ASSERT_THAT(my_list.Get(),
126               ElementsAre(Garment{1, "blue", true}, Garment{2, "red", false}));
127 }
128 
129 // Some lists are provided and all are empty, so we return a empty list.
TEST(FieldTrialListTest,StructListHandlesEmptyLists)130 TEST(FieldTrialListTest, StructListHandlesEmptyLists) {
131   FieldTrialStructList<Garment> my_list(
132       {FieldTrialStructMember("color", [](Garment* g) { return &g->color; }),
133        FieldTrialStructMember("price", [](Garment* g) { return &g->price; })},
134       {{1, "blue", true}, {2, "red", false}});
135 
136   ParseFieldTrial({&my_list}, "color,price");
137 
138   ASSERT_EQ(my_list.Get().size(), 0u);
139 }
140 
141 }  // namespace webrtc
142