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