Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(222)

Side by Side Diff: chrome/browser/history/most_visited_tiles_experiment_unittest.cc

Issue 17114002: Field trial removing tiles from NTP if URL is already open - for 1993 clients (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressed comments plus rebase Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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 <algorithm>
6 #include <sstream>
7
8 #include "base/metrics/field_trial.h"
9 #include "base/metrics/histogram.h"
10 #include "base/metrics/statistics_recorder.h"
11 #include "base/strings/string_util.h"
12 #include "base/values.h"
13 #include "chrome/browser/history/history_types.h"
14 #include "chrome/browser/history/most_visited_tiles_experiment.h"
15 #include "chrome/common/instant_types.h"
16 #include "chrome/common/metrics/entropy_provider.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18 #include "url/gurl.h"
19
20 namespace history {
21
22 namespace {
23
24 // Constants for the most visited tile placement field trial.
25 // See field trial config (MostVisitedTilePlacement.json) for details.
26 const char kMostVisitedFieldTrialName[] = "MostVisitedTilePlacement";
27 const char kOneEightAGroupName[] = "OneEight_A_Flipped";
28 const char kOneFourAGroupName[] = "OneFour_A_Flipped";
29 const char kDontShowOpenURLsGroupName[] = "DontShowOpenTabs";
30 const char kGmailURL[] = "http://www.gmail.com/";
31 // Name of histogram tracking types of actions carried out by the field trial.
32 const char kMostVisitedExperimentHistogramName[] =
33 "NewTabPage.MostVisitedTilePlacementExperiment";
34 // Minimum number of Most Visited suggestions required in order for the Most
35 // Visited Field Trial to remove a URL already open in the browser.
36 const size_t kMinUrlSuggestions = 8;
37
38 // The indexes of the tiles that are affected in the experiment.
39 enum FlippedIndexes {
40 TILE_ONE = 0,
41 TILE_FOUR = 3,
42 TILE_EIGHT = 7
43 };
44
45 // Creates a test url string: "http://www.test" + |num| + ".com".
46 static void MakeTestURLString(const int& num, std::string* url) {
Alexei Svitkine (slow) 2013/07/23 20:10:51 No need for any of these functions to be static si
annark1 2013/07/24 01:23:58 Done.
47 std::stringstream out;
48 url->append("http://www.test");
49 out << num;
50 url->append(out.str());
51 url->append(".com");
52 }
53
54 // Creates a DictionaryValue using |url| and appends to |list|.
55 static void AppendURLToListValue(const std::string& url_string,
56 base::ListValue* list) {
57 DictionaryValue* page_value = new DictionaryValue();
58 page_value->SetString("url", url_string);
59 list->Append(page_value);
60 }
61
62 // Creates an InstantMostVisitedItem using |url| and appends to |list|.
63 static void AppendInstantURLToVector(
64 const std::string& url_string,
65 std::vector<InstantMostVisitedItem>* list) {
66 InstantMostVisitedItem item;
67 item.url = GURL(url_string);
68 list->push_back(item);
69 }
70
71 // Creates an MostVisitedURL using |url| and appends to |list|.
72 static void AppendMostVisitedURLToVector(
73 const std::string& url_string,
74 std::vector<history::MostVisitedURL>* list) {
75 history::MostVisitedURL most_visited;
76 most_visited.url = GURL(url_string);
77 list->push_back(most_visited);
78 }
79
80 void SetUpMaybeShuffle(const int& max_urls,
81 MostVisitedURLList* most_visited_urls,
82 MostVisitedURLList* test_urls) {
83 // |most_visited_urls| must have > 8 MostVisitedURLs for any URLs to be
84 // flipped by experiment.
85 for (int i = 0; i < max_urls; ++i) {
86 std::string url;
87 MakeTestURLString(i, &url);
88 AppendMostVisitedURLToVector(url, most_visited_urls);
89 AppendMostVisitedURLToVector(url, test_urls);
90 }
91 }
92
93 } // namespace
94
95 class MostVisitedTilesExperimentTest : public testing::Test {
96 public:
97 MostVisitedTilesExperimentTest() : histogram_(NULL) {
98 }
99
100 ~MostVisitedTilesExperimentTest() {}
101
102 protected:
103 virtual void SetUp() {
Alexei Svitkine (slow) 2013/07/23 20:10:51 OVERRIDE
annark1 2013/07/24 01:23:58 Done.
104 field_trial_list_.reset(new base::FieldTrialList(
105 new metrics::SHA1EntropyProvider("foo")));
106 base::StatisticsRecorder::Initialize();
107 previous_metrics_count_.resize(NUM_NTP_TILE_EXPERIMENT_ACTIONS, 0);
108 base::HistogramBase* histogram = GetHistogram();
109 if (histogram) {
110 scoped_ptr<base::HistogramSamples> samples(histogram->SnapshotSamples());
111 if (samples.get()) {
112 for (int state = NTP_TILE_EXPERIMENT_ACTION_REMOVED_URL;
113 state < NUM_NTP_TILE_EXPERIMENT_ACTIONS;
114 ++state) {
115 previous_metrics_count_[state] = samples->GetCount(state);
116 }
117 }
118 }
119 }
120
121 void ValidateMetrics(const base::HistogramBase::Sample& value) {
122 base::HistogramBase* histogram = GetHistogram();
123 if (histogram) {
Alexei Svitkine (slow) 2013/07/23 20:10:51 Shouldn't it fail if the histogram doesn't exist?
annark1 2013/07/24 01:23:58 I've done this here, but not in SetUp, because for
124 scoped_ptr<base::HistogramSamples> samples(histogram->SnapshotSamples());
125 if (samples.get()) {
126 for (int state = NTP_TILE_EXPERIMENT_ACTION_REMOVED_URL;
127 state < NUM_NTP_TILE_EXPERIMENT_ACTIONS;
128 ++state) {
129 if (state == value) {
130 EXPECT_EQ(previous_metrics_count_[state] + 1,
131 samples->GetCount(state));
132 } else {
133 EXPECT_EQ(previous_metrics_count_[state], samples->GetCount(state));
134 }
135 }
136 }
137 }
138 }
139
140 private:
141 base::HistogramBase* GetHistogram() {
142 if (!histogram_) {
143 histogram_ = base::StatisticsRecorder::FindHistogram(
144 kMostVisitedExperimentHistogramName);
145 }
146 return histogram_;
147 }
148
149 base::HistogramBase* histogram_;
150 scoped_ptr<base::FieldTrialList> field_trial_list_;
151 std::vector<int> previous_metrics_count_;
152
153 DISALLOW_COPY_AND_ASSIGN(MostVisitedTilesExperimentTest);
154 };
155
156 // For pre-instant extended clients.
157 TEST_F(MostVisitedTilesExperimentTest,
158 RemovePageValuesMatchingOpenTabsTooFewURLs) {
159 base::FieldTrialList::CreateFieldTrial(kMostVisitedFieldTrialName,
160 kDontShowOpenURLsGroupName);
161
162 // Ensure the field trial is created with the correct group.
163 EXPECT_TRUE(MostVisitedTilesExperiment::IsDontShowOpenURLsEnabled());
164
165 std::set<std::string> open_urls;
166 open_urls.insert(kGmailURL);
167
168 scoped_ptr<base::ListValue> pages_value(new ListValue());
169 AppendURLToListValue(kGmailURL, pages_value.get());
170
171 // Test the method when there are not enough URLs to force removal.
172 MostVisitedTilesExperiment::RemovePageValuesMatchingOpenTabs(
173 open_urls, pages_value.get());
174 DictionaryValue gmail_value;
175 gmail_value.SetString("url", kGmailURL);
176 // Ensure the open url has not been removed from |pages_value|.
177 EXPECT_NE(pages_value.get()->end(), pages_value.get()->Find(gmail_value));
178
179 // Ensure counts have been incremented correctly.
180 ValidateMetrics(NTP_TILE_EXPERIMENT_ACTION_DID_NOT_REMOVE_URL);
181 }
182
183 // For pre-instant extended clients.
184 TEST_F(MostVisitedTilesExperimentTest, RemovePageValuesMatchingOpenTabs) {
185 base::FieldTrialList::CreateFieldTrial(kMostVisitedFieldTrialName,
186 kDontShowOpenURLsGroupName);
187
188 // Ensure the field trial is created with the correct group.
189 EXPECT_TRUE(MostVisitedTilesExperiment::IsDontShowOpenURLsEnabled());
190
191 std::set<std::string> open_urls;
192 open_urls.insert(kGmailURL);
193
194 scoped_ptr<base::ListValue> pages_value(new ListValue());
195 AppendURLToListValue(kGmailURL, pages_value.get());
196
197 // |pages_value| must have > 8 page values for any URLs to be removed by
198 // experiment.
199 for (size_t i = 0; i < kMinUrlSuggestions; ++i) {
200 std::string url;
201 MakeTestURLString(i, &url);
202 AppendURLToListValue(url, pages_value.get());
203 }
204
205 // Call method with enough URLs to force removal.
206 MostVisitedTilesExperiment::RemovePageValuesMatchingOpenTabs(
207 open_urls, pages_value.get());
208 // Ensure the open url has been removed from |pages_value|.
209 DictionaryValue gmail_value;
210 gmail_value.SetString("url", kGmailURL);
211 EXPECT_EQ(pages_value.get()->end(), pages_value.get()->Find(gmail_value));
212
213 // Ensure counts have been incremented correctly.
214 ValidateMetrics(NTP_TILE_EXPERIMENT_ACTION_REMOVED_URL);
215 }
216
217 // For instant extended clients.
218 TEST_F(MostVisitedTilesExperimentTest, RemoveItemsMatchingOpenTabsTooFewURLs) {
219 base::FieldTrialList::CreateFieldTrial(kMostVisitedFieldTrialName,
220 kDontShowOpenURLsGroupName);
221
222 // Ensure the field trial is created with the correct group.
223 EXPECT_TRUE(MostVisitedTilesExperiment::IsDontShowOpenURLsEnabled());
224
225 std::set<std::string> open_urls;
226 open_urls.insert(kGmailURL);
227 std::vector<InstantMostVisitedItem> items;
228 AppendInstantURLToVector(kGmailURL, &items);
229
230 // Call the method when there are not enough URLs to force removal.
231 MostVisitedTilesExperiment::RemoveItemsMatchingOpenTabs(open_urls, &items);
232
233 // Ensure the open url has not been removed from |items|.
234 for (size_t i = 0; i < items.size(); i++) {
235 const std::string& item_url = items[i].url.spec();
236 EXPECT_NE(0u, open_urls.count(item_url));
237 }
238
239 // Ensure counts have been incremented correctly.
240 ValidateMetrics(NTP_TILE_EXPERIMENT_ACTION_DID_NOT_REMOVE_URL);
241 }
242
243 // For instant extended clients.
244 TEST_F(MostVisitedTilesExperimentTest, RemoveItemsMatchingOpenTabs) {
245 base::FieldTrialList::CreateFieldTrial(
246 kMostVisitedFieldTrialName,
247 kDontShowOpenURLsGroupName);
248
249 // Ensure the field trial is created with the correct group.
250 EXPECT_TRUE(MostVisitedTilesExperiment::IsDontShowOpenURLsEnabled());
251
252 std::set<std::string> open_urls;
253 open_urls.insert(kGmailURL);
254 std::vector<InstantMostVisitedItem> items;
255 AppendInstantURLToVector(kGmailURL, &items);
256
257 // |items| must have > 8 InstantMostVisitedItems for any URLs to be removed by
258 // experiment.
259 for (size_t i = 0; i < kMinUrlSuggestions; ++i) {
260 std::string url;
261 MakeTestURLString(i, &url);
262 AppendInstantURLToVector(url, &items);
263 }
264
265 // Call method with enough URLs to force removal.
266 MostVisitedTilesExperiment::RemoveItemsMatchingOpenTabs(open_urls, &items);
267
268 // Ensure the open URL has been removed from |items|.
269 for (size_t i = 0; i < items.size(); i++) {
270 const std::string& item_url = items[i].url.spec();
271 EXPECT_EQ(0u, open_urls.count(item_url));
272 }
273
274 // Ensure counts have been incremented correctly.
275 ValidateMetrics(NTP_TILE_EXPERIMENT_ACTION_REMOVED_URL);
276 }
277
278 TEST_F(MostVisitedTilesExperimentTest, MaybeShuffleOneEight) {
279 base::FieldTrialList::CreateFieldTrial(kMostVisitedFieldTrialName,
280 kOneEightAGroupName);
281
282 // Ensure the field trial is created with the correct group.
283 EXPECT_EQ(kOneEightAGroupName,
284 base::FieldTrialList::FindFullName(kMostVisitedFieldTrialName));
285
286 MostVisitedURLList most_visited_urls;
287 MostVisitedURLList test_urls;
288 SetUpMaybeShuffle(kMinUrlSuggestions, &most_visited_urls, &test_urls);
289
290 history::MostVisitedTilesExperiment::MaybeShuffle(&most_visited_urls);
291 // Ensure the 1st and 8th URLs have been switched.
292 EXPECT_EQ(most_visited_urls[TILE_ONE].url.spec(),
293 test_urls[TILE_EIGHT].url.spec());
294
295 // Ensure counts are correct.
296 ValidateMetrics(NUM_NTP_TILE_EXPERIMENT_ACTIONS);
297 }
298
299 TEST_F(MostVisitedTilesExperimentTest, MaybeShuffleOneEightTooFewURLs) {
300 base::FieldTrialList::CreateFieldTrial(kMostVisitedFieldTrialName,
301 kOneEightAGroupName);
302
303 // Ensure the field trial is created with the correct group.
304 EXPECT_EQ(kOneEightAGroupName,
305 base::FieldTrialList::FindFullName(kMostVisitedFieldTrialName));
306
307 MostVisitedURLList most_visited_urls;
308 MostVisitedURLList test_urls;
309 // If |most_visited_urls| has < 8 URLs, experiment will not flip any tiles.
310 SetUpMaybeShuffle(kMinUrlSuggestions - 1, &most_visited_urls, &test_urls);
311
312 history::MostVisitedTilesExperiment::MaybeShuffle(&most_visited_urls);
313 // Ensure no URLs have been switched.
314 EXPECT_EQ(most_visited_urls[TILE_ONE].url.spec(),
315 test_urls[TILE_ONE].url.spec());
316 EXPECT_EQ(most_visited_urls[TILE_EIGHT - 1].url.spec(),
317 test_urls[TILE_EIGHT - 1].url.spec());
318
319 // Ensure counts are correct.
320 ValidateMetrics(NTP_TILE_EXPERIMENT_ACTION_TOO_FEW_URLS_TILES_1_8);
321 }
322
323 TEST_F(MostVisitedTilesExperimentTest, MaybeShuffleOneFour) {
324 base::FieldTrialList::CreateFieldTrial(kMostVisitedFieldTrialName,
325 kOneFourAGroupName);
326
327 // Ensure the field trial is created with the correct group.
328 EXPECT_EQ(kOneFourAGroupName,
329 base::FieldTrialList::FindFullName(kMostVisitedFieldTrialName));
330
331 MostVisitedURLList most_visited_urls;
332 MostVisitedURLList test_urls;
333 SetUpMaybeShuffle(kMinUrlSuggestions, &most_visited_urls, &test_urls);
334
335 history::MostVisitedTilesExperiment::MaybeShuffle(&most_visited_urls);
336 // Ensure the 1st and 4th URLs have been switched.
337 EXPECT_EQ(most_visited_urls[TILE_ONE].url.spec(),
338 test_urls[TILE_FOUR].url.spec());
339
340 // Ensure counts are correct.
341 ValidateMetrics(NUM_NTP_TILE_EXPERIMENT_ACTIONS);
342 }
343
344 TEST_F(MostVisitedTilesExperimentTest, MaybeShuffleOneFourTooFewURLs) {
345 base::FieldTrialList::CreateFieldTrial(
346 kMostVisitedFieldTrialName,
347 kOneFourAGroupName);
348
349 // Ensure the field trial is created with the correct group.
350 EXPECT_EQ(kOneFourAGroupName,
351 base::FieldTrialList::FindFullName(kMostVisitedFieldTrialName));
352
353 MostVisitedURLList most_visited_urls;
354 MostVisitedURLList test_urls;
355 // If |most_visited_urls| has < 4 URLs, experiment will not flip any tiles.
356 SetUpMaybeShuffle(kMinUrlSuggestions - 5, &most_visited_urls, &test_urls);
357
358 history::MostVisitedTilesExperiment::MaybeShuffle(&most_visited_urls);
359 // Ensure no URLs have been switched.
360 EXPECT_EQ(most_visited_urls[TILE_ONE].url.spec(),
361 test_urls[TILE_ONE].url.spec());
362 EXPECT_EQ(most_visited_urls[TILE_FOUR-1].url.spec(),
363 test_urls[TILE_FOUR-1].url.spec());
364
365 // Ensure counts are correct.
366 ValidateMetrics(NTP_TILE_EXPERIMENT_ACTION_TOO_FEW_URLS_TILES_1_4);
367 }
368
369 } // namespace history
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698