OLD | NEW |
| (Empty) |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "chrome/browser/omnibox/omnibox_field_trial.h" | |
6 | |
7 #include "base/basictypes.h" | |
8 #include "base/command_line.h" | |
9 #include "base/memory/scoped_ptr.h" | |
10 #include "base/metrics/field_trial.h" | |
11 #include "base/strings/string16.h" | |
12 #include "chrome/common/chrome_switches.h" | |
13 #include "components/metrics/proto/omnibox_event.pb.h" | |
14 #include "components/search/search.h" | |
15 #include "components/variations/entropy_provider.h" | |
16 #include "components/variations/variations_associated_data.h" | |
17 #include "testing/gtest/include/gtest/gtest.h" | |
18 | |
19 using metrics::OmniboxEventProto; | |
20 | |
21 class OmniboxFieldTrialTest : public testing::Test { | |
22 public: | |
23 OmniboxFieldTrialTest() { | |
24 ResetFieldTrialList(); | |
25 } | |
26 | |
27 void ResetFieldTrialList() { | |
28 // Destroy the existing FieldTrialList before creating a new one to avoid | |
29 // a DCHECK. | |
30 field_trial_list_.reset(); | |
31 field_trial_list_.reset(new base::FieldTrialList( | |
32 new metrics::SHA1EntropyProvider("foo"))); | |
33 variations::testing::ClearAllVariationParams(); | |
34 OmniboxFieldTrial::ActivateDynamicTrials(); | |
35 } | |
36 | |
37 // Creates and activates a field trial. | |
38 static base::FieldTrial* CreateTestTrial(const std::string& name, | |
39 const std::string& group_name) { | |
40 base::FieldTrial* trial = base::FieldTrialList::CreateFieldTrial( | |
41 name, group_name); | |
42 trial->group(); | |
43 return trial; | |
44 } | |
45 | |
46 // Add a field trial disabling ZeroSuggest. | |
47 static void CreateDisableZeroSuggestTrial() { | |
48 std::map<std::string, std::string> params; | |
49 params[std::string(OmniboxFieldTrial::kZeroSuggestRule)] = "false"; | |
50 variations::AssociateVariationParams( | |
51 OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A", params); | |
52 base::FieldTrialList::CreateFieldTrial( | |
53 OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A"); | |
54 } | |
55 | |
56 // EXPECTS that demotions[match_type] exists with value expected_value. | |
57 static void VerifyDemotion( | |
58 const OmniboxFieldTrial::DemotionMultipliers& demotions, | |
59 AutocompleteMatchType::Type match_type, | |
60 float expected_value); | |
61 | |
62 // EXPECT()s that OmniboxFieldTrial::GetValueForRuleInContext(|rule|, | |
63 // |page_classification|) returns |rule_value|. | |
64 static void ExpectRuleValue( | |
65 const std::string& rule_value, | |
66 const std::string& rule, | |
67 OmniboxEventProto::PageClassification page_classification); | |
68 | |
69 private: | |
70 scoped_ptr<base::FieldTrialList> field_trial_list_; | |
71 | |
72 DISALLOW_COPY_AND_ASSIGN(OmniboxFieldTrialTest); | |
73 }; | |
74 | |
75 // static | |
76 void OmniboxFieldTrialTest::VerifyDemotion( | |
77 const OmniboxFieldTrial::DemotionMultipliers& demotions, | |
78 AutocompleteMatchType::Type match_type, | |
79 float expected_value) { | |
80 OmniboxFieldTrial::DemotionMultipliers::const_iterator demotion_it = | |
81 demotions.find(match_type); | |
82 ASSERT_TRUE(demotion_it != demotions.end()); | |
83 EXPECT_FLOAT_EQ(expected_value, demotion_it->second); | |
84 } | |
85 | |
86 // static | |
87 void OmniboxFieldTrialTest::ExpectRuleValue( | |
88 const std::string& rule_value, | |
89 const std::string& rule, | |
90 OmniboxEventProto::PageClassification page_classification) { | |
91 EXPECT_EQ(rule_value, | |
92 OmniboxFieldTrial::GetValueForRuleInContext( | |
93 rule, page_classification)); | |
94 } | |
95 | |
96 // Test if GetDisabledProviderTypes() properly parses various field trial | |
97 // group names. | |
98 TEST_F(OmniboxFieldTrialTest, GetDisabledProviderTypes) { | |
99 EXPECT_EQ(0, OmniboxFieldTrial::GetDisabledProviderTypes()); | |
100 | |
101 { | |
102 SCOPED_TRACE("Invalid groups"); | |
103 CreateTestTrial("AutocompleteDynamicTrial_0", "DisabledProviders_"); | |
104 EXPECT_EQ(0, OmniboxFieldTrial::GetDisabledProviderTypes()); | |
105 ResetFieldTrialList(); | |
106 CreateTestTrial("AutocompleteDynamicTrial_1", "DisabledProviders_XXX"); | |
107 EXPECT_EQ(0, OmniboxFieldTrial::GetDisabledProviderTypes()); | |
108 ResetFieldTrialList(); | |
109 CreateTestTrial("AutocompleteDynamicTrial_1", "DisabledProviders_12abc"); | |
110 EXPECT_EQ(0, OmniboxFieldTrial::GetDisabledProviderTypes()); | |
111 } | |
112 | |
113 { | |
114 SCOPED_TRACE("Valid group name, unsupported trial name."); | |
115 ResetFieldTrialList(); | |
116 CreateTestTrial("UnsupportedTrialName", "DisabledProviders_20"); | |
117 EXPECT_EQ(0, OmniboxFieldTrial::GetDisabledProviderTypes()); | |
118 } | |
119 | |
120 { | |
121 SCOPED_TRACE("Valid field and group name."); | |
122 ResetFieldTrialList(); | |
123 CreateTestTrial("AutocompleteDynamicTrial_2", "DisabledProviders_3"); | |
124 EXPECT_EQ(3, OmniboxFieldTrial::GetDisabledProviderTypes()); | |
125 // Two groups should be OR-ed together. | |
126 CreateTestTrial("AutocompleteDynamicTrial_3", "DisabledProviders_6"); | |
127 EXPECT_EQ(7, OmniboxFieldTrial::GetDisabledProviderTypes()); | |
128 } | |
129 } | |
130 | |
131 // Test if InZeroSuggestFieldTrial() properly parses various field trial | |
132 // group names. | |
133 TEST_F(OmniboxFieldTrialTest, ZeroSuggestFieldTrial) { | |
134 // Default ZeroSuggest setting depends on OS. | |
135 #if defined(OS_WIN) || defined(OS_CHROMEOS) || defined(OS_LINUX) || \ | |
136 (defined(OS_MACOSX) && !defined(OS_IOS)) | |
137 EXPECT_TRUE(OmniboxFieldTrial::InZeroSuggestFieldTrial()); | |
138 #else | |
139 EXPECT_FALSE(OmniboxFieldTrial::InZeroSuggestFieldTrial()); | |
140 #endif | |
141 | |
142 { | |
143 SCOPED_TRACE("Disable ZeroSuggest."); | |
144 ResetFieldTrialList(); | |
145 CreateDisableZeroSuggestTrial(); | |
146 EXPECT_FALSE(OmniboxFieldTrial::InZeroSuggestFieldTrial()); | |
147 } | |
148 | |
149 { | |
150 SCOPED_TRACE("Bundled field trial parameters."); | |
151 ResetFieldTrialList(); | |
152 std::map<std::string, std::string> params; | |
153 params[std::string(OmniboxFieldTrial::kZeroSuggestRule)] = "true"; | |
154 ASSERT_TRUE(variations::AssociateVariationParams( | |
155 OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A", params)); | |
156 base::FieldTrialList::CreateFieldTrial( | |
157 OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A"); | |
158 EXPECT_TRUE(OmniboxFieldTrial::InZeroSuggestFieldTrial()); | |
159 EXPECT_FALSE(OmniboxFieldTrial::InZeroSuggestMostVisitedFieldTrial()); | |
160 EXPECT_FALSE(OmniboxFieldTrial::InZeroSuggestAfterTypingFieldTrial()); | |
161 | |
162 ResetFieldTrialList(); | |
163 params[std::string(OmniboxFieldTrial::kZeroSuggestVariantRule)] = | |
164 "MostVisited"; | |
165 ASSERT_TRUE(variations::AssociateVariationParams( | |
166 OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A", params)); | |
167 base::FieldTrialList::CreateFieldTrial( | |
168 OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A"); | |
169 EXPECT_TRUE(OmniboxFieldTrial::InZeroSuggestFieldTrial()); | |
170 EXPECT_TRUE(OmniboxFieldTrial::InZeroSuggestMostVisitedFieldTrial()); | |
171 EXPECT_FALSE(OmniboxFieldTrial::InZeroSuggestAfterTypingFieldTrial()); | |
172 | |
173 ResetFieldTrialList(); | |
174 params[std::string(OmniboxFieldTrial::kZeroSuggestVariantRule)] = | |
175 "AfterTyping"; | |
176 base::FieldTrialList::CreateFieldTrial( | |
177 OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A"); | |
178 ASSERT_TRUE(variations::AssociateVariationParams( | |
179 OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A", params)); | |
180 EXPECT_TRUE(OmniboxFieldTrial::InZeroSuggestFieldTrial()); | |
181 EXPECT_FALSE(OmniboxFieldTrial::InZeroSuggestMostVisitedFieldTrial()); | |
182 EXPECT_TRUE(OmniboxFieldTrial::InZeroSuggestAfterTypingFieldTrial()); | |
183 } | |
184 } | |
185 | |
186 TEST_F(OmniboxFieldTrialTest, GetDemotionsByTypeWithFallback) { | |
187 { | |
188 std::map<std::string, std::string> params; | |
189 params[std::string(OmniboxFieldTrial::kDemoteByTypeRule) + ":1:*"] = | |
190 "1:50,2:0"; | |
191 params[std::string(OmniboxFieldTrial::kDemoteByTypeRule) + ":3:*"] = | |
192 "5:100"; | |
193 params[std::string(OmniboxFieldTrial::kDemoteByTypeRule) + ":*:*"] = "1:25"; | |
194 ASSERT_TRUE(variations::AssociateVariationParams( | |
195 OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A", params)); | |
196 } | |
197 base::FieldTrialList::CreateFieldTrial( | |
198 OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A"); | |
199 OmniboxFieldTrial::DemotionMultipliers demotions_by_type; | |
200 OmniboxFieldTrial::GetDemotionsByType( | |
201 OmniboxEventProto::NTP, &demotions_by_type); | |
202 ASSERT_EQ(2u, demotions_by_type.size()); | |
203 VerifyDemotion(demotions_by_type, AutocompleteMatchType::HISTORY_URL, 0.5); | |
204 VerifyDemotion(demotions_by_type, AutocompleteMatchType::HISTORY_TITLE, 0.0); | |
205 OmniboxFieldTrial::GetDemotionsByType( | |
206 OmniboxEventProto::HOME_PAGE, &demotions_by_type); | |
207 ASSERT_EQ(1u, demotions_by_type.size()); | |
208 VerifyDemotion(demotions_by_type, AutocompleteMatchType::NAVSUGGEST, 1.0); | |
209 OmniboxFieldTrial::GetDemotionsByType( | |
210 OmniboxEventProto::BLANK, &demotions_by_type); | |
211 ASSERT_EQ(1u, demotions_by_type.size()); | |
212 VerifyDemotion(demotions_by_type, AutocompleteMatchType::HISTORY_URL, 0.25); | |
213 } | |
214 | |
215 TEST_F(OmniboxFieldTrialTest, GetValueForRuleInContext) { | |
216 { | |
217 std::map<std::string, std::string> params; | |
218 // Rule 1 has some exact matches and fallbacks at every level. | |
219 params["rule1:1:0"] = "rule1-1-0-value"; // NTP | |
220 params["rule1:3:0"] = "rule1-3-0-value"; // HOME_PAGE | |
221 params["rule1:4:1"] = "rule1-4-1-value"; // OTHER | |
222 params["rule1:4:*"] = "rule1-4-*-value"; // OTHER | |
223 params["rule1:*:1"] = "rule1-*-1-value"; // global | |
224 params["rule1:*:*"] = "rule1-*-*-value"; // global | |
225 // Rule 2 has no exact matches but has fallbacks. | |
226 params["rule2:*:0"] = "rule2-*-0-value"; // global | |
227 params["rule2:1:*"] = "rule2-1-*-value"; // NTP | |
228 params["rule2:*:*"] = "rule2-*-*-value"; // global | |
229 // Rule 3 has only a global fallback. | |
230 params["rule3:*:*"] = "rule3-*-*-value"; // global | |
231 // Rule 4 has an exact match but no fallbacks. | |
232 params["rule4:4:0"] = "rule4-4-0-value"; // OTHER | |
233 // Add a malformed rule to make sure it doesn't screw things up. | |
234 params["unrecognized"] = "unrecognized-value"; | |
235 ASSERT_TRUE(variations::AssociateVariationParams( | |
236 OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A", params)); | |
237 } | |
238 | |
239 base::FieldTrialList::CreateFieldTrial( | |
240 OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A"); | |
241 | |
242 if (chrome::IsInstantExtendedAPIEnabled()) { | |
243 // Tests with Instant Extended enabled. | |
244 // Tests for rule 1. | |
245 ExpectRuleValue("rule1-4-1-value", | |
246 "rule1", OmniboxEventProto::OTHER); // exact match | |
247 ExpectRuleValue("rule1-*-1-value", | |
248 "rule1", OmniboxEventProto::BLANK); // partial fallback | |
249 ExpectRuleValue("rule1-*-1-value", | |
250 "rule1", | |
251 OmniboxEventProto::NTP); // partial fallback | |
252 | |
253 // Tests for rule 2. | |
254 ExpectRuleValue("rule2-1-*-value", | |
255 "rule2", | |
256 OmniboxEventProto::NTP); // partial fallback | |
257 ExpectRuleValue("rule2-*-*-value", | |
258 "rule2", OmniboxEventProto::OTHER); // global fallback | |
259 | |
260 // Tests for rule 3. | |
261 ExpectRuleValue("rule3-*-*-value", | |
262 "rule3", | |
263 OmniboxEventProto::HOME_PAGE); // global fallback | |
264 ExpectRuleValue("rule3-*-*-value", | |
265 "rule3", | |
266 OmniboxEventProto::OTHER); // global fallback | |
267 | |
268 // Tests for rule 4. | |
269 ExpectRuleValue("", | |
270 "rule4", | |
271 OmniboxEventProto::BLANK); // no global fallback | |
272 ExpectRuleValue("", | |
273 "rule4", | |
274 OmniboxEventProto::HOME_PAGE); // no global fallback | |
275 | |
276 // Tests for rule 5 (a missing rule). | |
277 ExpectRuleValue("", | |
278 "rule5", OmniboxEventProto::OTHER); // no rule at all | |
279 } else { | |
280 // Tests for rule 1. | |
281 ExpectRuleValue("rule1-1-0-value", | |
282 "rule1", OmniboxEventProto::NTP); // exact match | |
283 ExpectRuleValue("rule1-1-0-value", | |
284 "rule1", OmniboxEventProto::NTP); // exact match | |
285 ExpectRuleValue("rule1-*-*-value", | |
286 "rule1", OmniboxEventProto::BLANK); // fallback to global | |
287 ExpectRuleValue("rule1-3-0-value", | |
288 "rule1", | |
289 OmniboxEventProto::HOME_PAGE); // exact match | |
290 ExpectRuleValue("rule1-4-*-value", | |
291 "rule1", OmniboxEventProto::OTHER); // partial fallback | |
292 ExpectRuleValue("rule1-*-*-value", | |
293 "rule1", | |
294 OmniboxEventProto:: // fallback to global | |
295 SEARCH_RESULT_PAGE_DOING_SEARCH_TERM_REPLACEMENT); | |
296 // Tests for rule 2. | |
297 ExpectRuleValue("rule2-*-0-value", | |
298 "rule2", | |
299 OmniboxEventProto::HOME_PAGE); // partial fallback | |
300 ExpectRuleValue("rule2-*-0-value", | |
301 "rule2", OmniboxEventProto::OTHER); // partial fallback | |
302 | |
303 // Tests for rule 3. | |
304 ExpectRuleValue("rule3-*-*-value", | |
305 "rule3", | |
306 OmniboxEventProto::HOME_PAGE); // fallback to global | |
307 ExpectRuleValue("rule3-*-*-value", | |
308 "rule3", OmniboxEventProto::OTHER); // fallback to global | |
309 | |
310 // Tests for rule 4. | |
311 ExpectRuleValue("", | |
312 "rule4", OmniboxEventProto::BLANK); // no global fallback | |
313 ExpectRuleValue("", | |
314 "rule4", | |
315 OmniboxEventProto::HOME_PAGE); // no global fallback | |
316 ExpectRuleValue("rule4-4-0-value", | |
317 "rule4", OmniboxEventProto::OTHER); // exact match | |
318 | |
319 // Tests for rule 5 (a missing rule). | |
320 ExpectRuleValue("", | |
321 "rule5", OmniboxEventProto::OTHER); // no rule at all | |
322 } | |
323 } | |
324 | |
325 TEST_F(OmniboxFieldTrialTest, HUPNewScoringFieldTrial) { | |
326 { | |
327 std::map<std::string, std::string> params; | |
328 params[std::string(OmniboxFieldTrial::kHUPNewScoringEnabledParam)] = "1"; | |
329 params[std::string( | |
330 OmniboxFieldTrial::kHUPNewScoringTypedCountRelevanceCapParam)] = "56"; | |
331 params[std::string( | |
332 OmniboxFieldTrial::kHUPNewScoringTypedCountHalfLifeTimeParam)] = "77"; | |
333 params[std::string( | |
334 OmniboxFieldTrial::kHUPNewScoringTypedCountScoreBucketsParam)] = | |
335 "0.2:25,0.1:1001,2.3:777"; | |
336 params[std::string( | |
337 OmniboxFieldTrial::kHUPNewScoringVisitedCountRelevanceCapParam)] = "11"; | |
338 params[std::string( | |
339 OmniboxFieldTrial::kHUPNewScoringVisitedCountHalfLifeTimeParam)] = "31"; | |
340 params[std::string( | |
341 OmniboxFieldTrial::kHUPNewScoringVisitedCountScoreBucketsParam)] = | |
342 "5:300,0:200"; | |
343 ASSERT_TRUE(variations::AssociateVariationParams( | |
344 OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A", params)); | |
345 } | |
346 base::FieldTrialList::CreateFieldTrial( | |
347 OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A"); | |
348 | |
349 HUPScoringParams scoring_params; | |
350 OmniboxFieldTrial::GetExperimentalHUPScoringParams(&scoring_params); | |
351 EXPECT_TRUE(scoring_params.experimental_scoring_enabled); | |
352 EXPECT_EQ(56, scoring_params.typed_count_buckets.relevance_cap()); | |
353 EXPECT_EQ(77, scoring_params.typed_count_buckets.half_life_days()); | |
354 ASSERT_EQ(3u, scoring_params.typed_count_buckets.buckets().size()); | |
355 EXPECT_EQ(std::make_pair(2.3, 777), | |
356 scoring_params.typed_count_buckets.buckets()[0]); | |
357 EXPECT_EQ(std::make_pair(0.2, 25), | |
358 scoring_params.typed_count_buckets.buckets()[1]); | |
359 EXPECT_EQ(std::make_pair(0.1, 1001), | |
360 scoring_params.typed_count_buckets.buckets()[2]); | |
361 EXPECT_EQ(11, scoring_params.visited_count_buckets.relevance_cap()); | |
362 EXPECT_EQ(31, scoring_params.visited_count_buckets.half_life_days()); | |
363 ASSERT_EQ(2u, scoring_params.visited_count_buckets.buckets().size()); | |
364 EXPECT_EQ(std::make_pair(5.0, 300), | |
365 scoring_params.visited_count_buckets.buckets()[0]); | |
366 EXPECT_EQ(std::make_pair(0.0, 200), | |
367 scoring_params.visited_count_buckets.buckets()[1]); | |
368 } | |
369 | |
370 TEST_F(OmniboxFieldTrialTest, HalfLifeTimeDecay) { | |
371 HUPScoringParams::ScoreBuckets buckets; | |
372 | |
373 // No decay by default. | |
374 EXPECT_EQ(1.0, buckets.HalfLifeTimeDecay(base::TimeDelta::FromDays(7))); | |
375 | |
376 buckets.set_half_life_days(7); | |
377 EXPECT_EQ(0.5, buckets.HalfLifeTimeDecay(base::TimeDelta::FromDays(7))); | |
378 EXPECT_EQ(0.25, buckets.HalfLifeTimeDecay(base::TimeDelta::FromDays(14))); | |
379 EXPECT_EQ(1.0, buckets.HalfLifeTimeDecay(base::TimeDelta::FromDays(0))); | |
380 EXPECT_EQ(1.0, buckets.HalfLifeTimeDecay(base::TimeDelta::FromDays(-1))); | |
381 } | |
OLD | NEW |