Index: chrome/browser/history/most_visited_tiles_experiment_unittest.cc |
diff --git a/chrome/browser/history/most_visited_tiles_experiment_unittest.cc b/chrome/browser/history/most_visited_tiles_experiment_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..382913b19a44ee2caef25ed9e359dc460d5da078 |
--- /dev/null |
+++ b/chrome/browser/history/most_visited_tiles_experiment_unittest.cc |
@@ -0,0 +1,371 @@ |
+// Copyright (c) 2013 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include <algorithm> |
+#include <sstream> |
+ |
+#include "base/metrics/field_trial.h" |
+#include "base/metrics/histogram.h" |
+#include "base/metrics/statistics_recorder.h" |
+#include "base/strings/string_util.h" |
+#include "base/values.h" |
+#include "chrome/browser/history/history_types.h" |
+#include "chrome/browser/history/most_visited_tiles_experiment.h" |
+#include "chrome/common/instant_types.h" |
+#include "chrome/common/metrics/entropy_provider.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+#include "url/gurl.h" |
+ |
+namespace history { |
+ |
+namespace { |
+ |
+// Constants for the most visited tile placement field trial. |
+// See field trial config (MostVisitedTilePlacement.json) for details. |
+const char kMostVisitedFieldTrialName[] = "MostVisitedTilePlacement"; |
+const char kOneEightAGroupName[] = "OneEight_A_Flipped"; |
+const char kOneFourAGroupName[] = "OneFour_A_Flipped"; |
+const char kDontShowOpenURLsGroupName[] = "DontShowOpenTabs"; |
+const char kGmailURL[] = "http://www.gmail.com/"; |
+ |
+// The indices of the tiles that are affected in the experiment. |
+enum FlippedIndexes { |
+ TILE_ONE = 0, |
+ TILE_FOUR = 3, |
+ TILE_EIGHT = 7 |
+}; |
+ |
+// Creates a test url string: "http://www.test" + |num| + ".com". |
+static void MakeTestURLString(const int& num, std::string* url) { |
+ std::stringstream out; |
+ url->append("http://www.test"); |
+ out << num; |
+ url->append(out.str()); |
+ url->append(".com"); |
+} |
+ |
+// Creates a DictionaryValue using |url| and appends to |list|. |
+static void AppendURLToListValue(const std::string& url_string, |
+ base::ListValue* list) { |
+ DictionaryValue* page_value = new DictionaryValue(); |
+ page_value->SetString("url", url_string); |
+ list->Append(page_value); |
+} |
+ |
+// Creates an InstantMostVisitedItem using |url| and appends to |list|. |
+static void AppendInstantURLToVector( |
+ const std::string& url_string, |
+ std::vector<InstantMostVisitedItem>* list) { |
+ InstantMostVisitedItem item; |
+ item.url = GURL(url_string); |
+ list->push_back(item); |
+} |
+ |
+// Creates an MostVisitedURL using |url| and appends to |list|. |
+static void AppendMostVisitedURLToVector( |
+ const std::string& url_string, |
+ std::vector<history::MostVisitedURL>* list) { |
+ history::MostVisitedURL most_visited; |
+ most_visited.url = GURL(url_string); |
+ list->push_back(most_visited); |
+} |
+ |
+void SetUpMaybeShuffle(const int& max_urls, |
+ MostVisitedURLList* most_visited_urls, |
+ MostVisitedURLList* test_urls) { |
+ // |most_visited_urls| must have > 8 MostVisitedURLs for any URLs to be |
+ // flipped by experiment. |
+ for (int i = 0; i < max_urls; ++i) { |
+ std::string url; |
+ MakeTestURLString(i, &url); |
+ AppendMostVisitedURLToVector(url, most_visited_urls); |
+ AppendMostVisitedURLToVector(url, test_urls); |
+ } |
+} |
+ |
+} // namespace |
+ |
+class MostVisitedTilesExperimentTest : public testing::Test { |
+ public: |
+ MostVisitedTilesExperimentTest() : histogram_(NULL) { |
+ } |
+ |
+ ~MostVisitedTilesExperimentTest() {} |
+ |
+ protected: |
+ virtual void SetUp() { |
+ field_trial_list_.reset(new base::FieldTrialList( |
+ new metrics::SHA1EntropyProvider("foo"))); |
+ base::StatisticsRecorder::Initialize(); |
+ previous_metrics_count_.resize(NUM_NTP_TILE_EXPERIMENT_ACTIONS, 0); |
+ base::HistogramBase* histogram = GetHistogram(); |
+ if (histogram) { |
+ scoped_ptr<base::HistogramSamples> samples(histogram->SnapshotSamples()); |
+ if (samples.get()) { |
+ for (int state = NTP_TILE_EXPERIMENT_ACTION_REMOVED_URL; |
+ state < NUM_NTP_TILE_EXPERIMENT_ACTIONS; |
+ ++state) { |
+ previous_metrics_count_[state] = samples->GetCount(state); |
+ } |
+ } |
+ } |
+ } |
+ |
+ void ValidateMetrics(const base::HistogramBase::Sample& value) { |
+ base::HistogramBase* histogram = GetHistogram(); |
+ if (histogram) { |
+ scoped_ptr<base::HistogramSamples> samples(histogram->SnapshotSamples()); |
+ if (samples.get()) { |
+ for (int state = NTP_TILE_EXPERIMENT_ACTION_REMOVED_URL; |
+ state < NUM_NTP_TILE_EXPERIMENT_ACTIONS; |
+ ++state) { |
+ if (state == value) { |
+ EXPECT_EQ(previous_metrics_count_[state] + 1, |
+ samples->GetCount(state)); |
+ } else { |
+ EXPECT_EQ(previous_metrics_count_[state], samples->GetCount(state)); |
+ } |
+ } |
+ } |
+ } |
+ } |
+ |
+ private: |
+ base::HistogramBase* GetHistogram() { |
+ if (!histogram_) { |
+ histogram_ = base::StatisticsRecorder::FindHistogram( |
+ MostVisitedTilesExperiment::kMostVisitedExperimentHistogramName); |
+ } |
+ return histogram_; |
+ } |
+ |
+ base::HistogramBase* histogram_; |
+ scoped_ptr<base::FieldTrialList> field_trial_list_; |
+ std::vector<int> previous_metrics_count_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(MostVisitedTilesExperimentTest); |
+}; |
+ |
+// For pre-instant extended clients. |
+TEST_F(MostVisitedTilesExperimentTest, |
+ RemovePageValuesMatchingOpenTabsTooFewURLs) { |
+ base::FieldTrialList::CreateFieldTrial(kMostVisitedFieldTrialName, |
+ kDontShowOpenURLsGroupName); |
+ |
+ // Ensure the field trial is created with the correct group. |
+ EXPECT_TRUE(MostVisitedTilesExperiment::IsDontShowOpenURLsEnabled()); |
+ |
+ std::set<std::string> open_urls; |
+ open_urls.insert(kGmailURL); |
+ |
+ scoped_ptr<base::ListValue> pages_value(new ListValue()); |
+ AppendURLToListValue(kGmailURL, pages_value.get()); |
+ |
+ // Test the method when there are not enough URLs to force removal. |
+ MostVisitedTilesExperiment::RemovePageValuesMatchingOpenTabs( |
+ open_urls, pages_value.get()); |
+ DictionaryValue gmail_value; |
+ gmail_value.SetString("url", kGmailURL); |
+ // Ensure the open url has not been removed from |pages_value|. |
+ EXPECT_NE(pages_value.get()->end(), pages_value.get()->Find(gmail_value)); |
+ |
+ // Ensure counts have been incremented correctly. |
+ ValidateMetrics(NTP_TILE_EXPERIMENT_ACTION_DID_NOT_REMOVE_URL); |
+} |
+ |
+// For pre-instant extended clients. |
+TEST_F(MostVisitedTilesExperimentTest, RemovePageValuesMatchingOpenTabs) { |
+ base::FieldTrialList::CreateFieldTrial(kMostVisitedFieldTrialName, |
+ kDontShowOpenURLsGroupName); |
+ |
+ // Ensure the field trial is created with the correct group. |
+ EXPECT_TRUE(MostVisitedTilesExperiment::IsDontShowOpenURLsEnabled()); |
+ |
+ std::set<std::string> open_urls; |
+ open_urls.insert(kGmailURL); |
+ |
+ scoped_ptr<base::ListValue> pages_value(new ListValue()); |
+ AppendURLToListValue(kGmailURL, pages_value.get()); |
+ |
+ // |pages_value| must have > 8 page values for any URLs to be removed by |
+ // experiment. |
+ for (size_t i = 0; i < MostVisitedTilesExperiment::kMinUrlSuggestions; ++i) { |
+ std::string url; |
+ MakeTestURLString(i, &url); |
+ AppendURLToListValue(url, pages_value.get()); |
+ } |
+ |
+ // Call method with enough URLs to force removal. |
+ MostVisitedTilesExperiment::RemovePageValuesMatchingOpenTabs( |
+ open_urls, pages_value.get()); |
+ // Ensure the open url has been removed from |pages_value|. |
+ DictionaryValue gmail_value; |
+ gmail_value.SetString("url", kGmailURL); |
+ EXPECT_EQ(pages_value.get()->end(), pages_value.get()->Find(gmail_value)); |
+ |
+ // Ensure counts have been incremented correctly. |
+ ValidateMetrics(NTP_TILE_EXPERIMENT_ACTION_REMOVED_URL); |
+} |
+ |
+// For instant extended clients. |
+TEST_F(MostVisitedTilesExperimentTest, RemoveItemsMatchingOpenTabsTooFewURLs) { |
+ base::FieldTrialList::CreateFieldTrial(kMostVisitedFieldTrialName, |
+ kDontShowOpenURLsGroupName); |
+ |
+ // Ensure the field trial is created with the correct group. |
+ EXPECT_TRUE(MostVisitedTilesExperiment::IsDontShowOpenURLsEnabled()); |
+ |
+ std::set<std::string> open_urls; |
+ open_urls.insert(kGmailURL); |
+ std::vector<InstantMostVisitedItem> items; |
+ AppendInstantURLToVector(kGmailURL, &items); |
+ |
+ // Call the method when there are not enough URLs to force removal. |
+ MostVisitedTilesExperiment::RemoveItemsMatchingOpenTabs(open_urls, &items); |
+ |
+ // Ensure the open url has not been removed from |items|. |
+ for (size_t i = 0; i < items.size(); i++) { |
+ const std::string& item_url = items[i].url.spec(); |
+ EXPECT_NE(0u, open_urls.count(item_url)); |
+ } |
+ |
+ // Ensure counts have been incremented correctly. |
+ ValidateMetrics(NTP_TILE_EXPERIMENT_ACTION_DID_NOT_REMOVE_URL); |
+} |
+ |
+// For instant extended clients. |
+TEST_F(MostVisitedTilesExperimentTest, RemoveItemsMatchingOpenTabs) { |
+ base::FieldTrialList::CreateFieldTrial( |
+ kMostVisitedFieldTrialName, |
+ kDontShowOpenURLsGroupName); |
+ |
+ // Ensure the field trial is created with the correct group. |
+ EXPECT_TRUE(MostVisitedTilesExperiment::IsDontShowOpenURLsEnabled()); |
+ |
+ std::set<std::string> open_urls; |
+ open_urls.insert(kGmailURL); |
+ std::vector<InstantMostVisitedItem> items; |
+ AppendInstantURLToVector(kGmailURL, &items); |
+ |
+ // |items| must have > 8 InstantMostVisitedItems for any URLs to be removed by |
+ // experiment. |
+ for (size_t i = 0; i < MostVisitedTilesExperiment::kMinUrlSuggestions; ++i) { |
+ std::string url; |
+ MakeTestURLString(i, &url); |
+ AppendInstantURLToVector(url, &items); |
+ } |
+ |
+ // Call method with enough URLs to force removal. |
+ MostVisitedTilesExperiment::RemoveItemsMatchingOpenTabs(open_urls, &items); |
+ |
+ // Ensure the open URL has been removed from |items|. |
+ for (size_t i = 0; i < items.size(); i++) { |
+ const std::string& item_url = items[i].url.spec(); |
+ EXPECT_EQ(0u, open_urls.count(item_url)); |
+ } |
+ |
+ // Ensure counts have been incremented correctly. |
+ ValidateMetrics(NTP_TILE_EXPERIMENT_ACTION_REMOVED_URL); |
+} |
+ |
+TEST_F(MostVisitedTilesExperimentTest, MaybeShuffleOneEight) { |
+ base::FieldTrialList::CreateFieldTrial(kMostVisitedFieldTrialName, |
+ kOneEightAGroupName); |
+ |
+ // Ensure the field trial is created with the correct group. |
+ EXPECT_EQ(kOneEightAGroupName, |
+ base::FieldTrialList::FindFullName(kMostVisitedFieldTrialName)); |
+ |
+ MostVisitedURLList most_visited_urls; |
+ MostVisitedURLList test_urls; |
+ SetUpMaybeShuffle(MostVisitedTilesExperiment::kMinUrlSuggestions, |
+ &most_visited_urls, |
+ &test_urls); |
+ |
+ history::MostVisitedTilesExperiment::MaybeShuffle(&most_visited_urls); |
+ // Ensure the 1st and 8th URLs have been switched. |
+ EXPECT_EQ(most_visited_urls[TILE_ONE].url.spec(), |
+ test_urls[TILE_EIGHT].url.spec()); |
+ |
+ // Ensure counts are correct. |
+ ValidateMetrics(NUM_NTP_TILE_EXPERIMENT_ACTIONS); |
+} |
+ |
+TEST_F(MostVisitedTilesExperimentTest, MaybeShuffleOneEightTooFewURLs) { |
+ base::FieldTrialList::CreateFieldTrial(kMostVisitedFieldTrialName, |
+ kOneEightAGroupName); |
+ |
+ // Ensure the field trial is created with the correct group. |
+ EXPECT_EQ(kOneEightAGroupName, |
+ base::FieldTrialList::FindFullName(kMostVisitedFieldTrialName)); |
+ |
+ MostVisitedURLList most_visited_urls; |
+ MostVisitedURLList test_urls; |
+ // If |most_visited_urls| has < 8 URLs, experiment will not flip any tiles. |
+ SetUpMaybeShuffle(MostVisitedTilesExperiment::kMinUrlSuggestions - 1, |
+ &most_visited_urls, |
+ &test_urls); |
+ |
+ history::MostVisitedTilesExperiment::MaybeShuffle(&most_visited_urls); |
+ // Ensure no URLs have been switched. |
+ EXPECT_EQ(most_visited_urls[TILE_ONE].url.spec(), |
+ test_urls[TILE_ONE].url.spec()); |
+ EXPECT_EQ(most_visited_urls[TILE_EIGHT - 1].url.spec(), |
+ test_urls[TILE_EIGHT - 1].url.spec()); |
+ |
+ // Ensure counts are correct. |
+ ValidateMetrics(NTP_TILE_EXPERIMENT_ACTION_TOO_FEW_URLS_TILES_1_8); |
+} |
+ |
+TEST_F(MostVisitedTilesExperimentTest, MaybeShuffleOneFour) { |
+ base::FieldTrialList::CreateFieldTrial(kMostVisitedFieldTrialName, |
+ kOneFourAGroupName); |
+ |
+ // Ensure the field trial is created with the correct group. |
+ EXPECT_EQ(kOneFourAGroupName, |
+ base::FieldTrialList::FindFullName(kMostVisitedFieldTrialName)); |
+ |
+ MostVisitedURLList most_visited_urls; |
+ MostVisitedURLList test_urls; |
+ SetUpMaybeShuffle(MostVisitedTilesExperiment::kMinUrlSuggestions, |
+ &most_visited_urls, |
+ &test_urls); |
+ |
+ history::MostVisitedTilesExperiment::MaybeShuffle(&most_visited_urls); |
+ // Ensure the 1st and 4th URLs have been switched. |
+ EXPECT_EQ(most_visited_urls[TILE_ONE].url.spec(), |
+ test_urls[TILE_FOUR].url.spec()); |
+ |
+ // Ensure counts are correct. |
+ ValidateMetrics(NUM_NTP_TILE_EXPERIMENT_ACTIONS); |
+} |
+ |
+TEST_F(MostVisitedTilesExperimentTest, MaybeShuffleOneFourTooFewURLs) { |
+ base::FieldTrialList::CreateFieldTrial( |
+ kMostVisitedFieldTrialName, |
+ kOneFourAGroupName); |
+ |
+ // Ensure the field trial is created with the correct group. |
+ EXPECT_EQ(kOneFourAGroupName, |
+ base::FieldTrialList::FindFullName(kMostVisitedFieldTrialName)); |
+ |
+ MostVisitedURLList most_visited_urls; |
+ MostVisitedURLList test_urls; |
+ // If |most_visited_urls| has < 4 URLs, experiment will not flip any tiles. |
+ SetUpMaybeShuffle(MostVisitedTilesExperiment::kMinUrlSuggestions - 5, |
+ &most_visited_urls, |
+ &test_urls); |
+ |
+ history::MostVisitedTilesExperiment::MaybeShuffle(&most_visited_urls); |
+ // Ensure no URLs have been switched. |
+ EXPECT_EQ(most_visited_urls[TILE_ONE].url.spec(), |
+ test_urls[TILE_ONE].url.spec()); |
+ EXPECT_EQ(most_visited_urls[TILE_FOUR-1].url.spec(), |
+ test_urls[TILE_FOUR-1].url.spec()); |
+ |
+ // Ensure counts are correct. |
+ ValidateMetrics(NTP_TILE_EXPERIMENT_ACTION_TOO_FEW_URLS_TILES_1_4); |
+} |
+ |
+} // namespace history |