Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / prefs / pref_hash_browsertest.cc
index 1bcc0fd..b3108e5 100644 (file)
@@ -6,20 +6,30 @@
 #include <vector>
 
 #include "base/bind.h"
+#include "base/command_line.h"
 #include "base/files/file_path.h"
+#include "base/macros.h"
 #include "base/message_loop/message_loop.h"
+#include "base/metrics/histogram_base.h"
+#include "base/metrics/histogram_samples.h"
+#include "base/metrics/statistics_recorder.h"
 #include "base/prefs/pref_service.h"
 #include "base/strings/string16.h"
+#include "base/threading/sequenced_worker_pool.h"
 #include "base/values.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/prefs/chrome_pref_service_factory.h"
+#include "chrome/browser/prefs/pref_hash_store.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/profiles/profile_impl.h"
 #include "chrome/browser/profiles/profile_info_cache.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/profiles/profiles_state.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/in_process_browser_test.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/common/content_switches.h"
 #include "content/public/test/test_utils.h"
+#include "testing/gtest/include/gtest/gtest.h"
 
 namespace {
 
@@ -58,11 +68,70 @@ base::FilePath GetUnloadedProfilePath() {
   return base::FilePath();
 }
 
+// Returns the number of times |histogram_name| was reported so far; adding the
+// results of the first 100 buckets (there are only ~14 reporting IDs as of this
+// writting; varies depending on the platform). If |expect_zero| is true, this
+// method will explicitly report IDs that are non-zero for ease of diagnosis.
+int GetTrackedPrefHistogramCount(const char* histogram_name, bool expect_zero) {
+  const base::HistogramBase* histogram =
+      base::StatisticsRecorder::FindHistogram(histogram_name);
+  if (!histogram)
+    return 0;
+
+  scoped_ptr<base::HistogramSamples> samples(histogram->SnapshotSamples());
+  int sum = 0;
+  for (int i = 0; i < 100; ++i) {
+    int count_for_id = samples->GetCount(i);
+    sum += count_for_id;
+
+    if (expect_zero)
+      EXPECT_EQ(0, count_for_id) << "Faulty reporting_id: " << i;
+  }
+  return sum;
+}
+
 }  // namespace
 
-typedef InProcessBrowserTest PrefHashBrowserTest;
+class PrefHashBrowserTest : public InProcessBrowserTest,
+                            public testing::WithParamInterface<std::string> {
+ public:
+  PrefHashBrowserTest()
+      : is_unloaded_profile_seeding_allowed_(
+            GetParam() !=
+            chrome_prefs::internals::kSettingsEnforcementGroupEnforceAlways) {}
+
+  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
+    InProcessBrowserTest::SetUpCommandLine(command_line);
+    command_line->AppendSwitchASCII(
+        switches::kForceFieldTrials,
+        std::string(chrome_prefs::internals::kSettingsEnforcementTrialName) +
+            "/" + GetParam() + "/");
+  }
+
+  virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
+    // Force the delayed PrefHashStore update task to happen immediately.
+    chrome_prefs::EnableZeroDelayPrefHashStoreUpdateForTesting();
+  }
+
+  virtual void SetUpOnMainThread() OVERRIDE {
+    // content::RunAllPendingInMessageLoop() is already called before
+    // SetUpOnMainThread() in in_process_browser_test.cc which guarantees that
+    // UpdateAllPrefHashStoresIfRequired() has already been called.
+
+    // Now flush the blocking pool to force any pending JsonPrefStore async read
+    // requests.
+    content::BrowserThread::GetBlockingPool()->FlushForTesting();
+
+    // And finally run tasks on this message loop again to process the OnRead()
+    // callbacks resulting from the file reads above.
+    content::RunAllPendingInMessageLoop();
+  }
+
+ protected:
+  const bool is_unloaded_profile_seeding_allowed_;
+};
 
-IN_PROC_BROWSER_TEST_F(PrefHashBrowserTest,
+IN_PROC_BROWSER_TEST_P(PrefHashBrowserTest,
                        PRE_PRE_InitializeUnloadedProfiles) {
   if (!profiles::IsMultipleProfilesEnabled())
     return;
@@ -83,9 +152,16 @@ IN_PROC_BROWSER_TEST_F(PrefHashBrowserTest,
   // Spin to allow profile creation to take place, loop is terminated
   // by OnUnblockOnProfileCreation when the profile is created.
   runner->Run();
+
+  // No profile should have gone through the unloaded profile initialization in
+  // this phase as both profiles should have been loaded normally.
+  EXPECT_EQ(
+      0, GetTrackedPrefHistogramCount(
+             "Settings.TrackedPreferencesInitializedForUnloadedProfile",
+             true));
 }
 
-IN_PROC_BROWSER_TEST_F(PrefHashBrowserTest,
+IN_PROC_BROWSER_TEST_P(PrefHashBrowserTest,
                        PRE_InitializeUnloadedProfiles) {
   if (!profiles::IsMultipleProfilesEnabled())
     return;
@@ -102,18 +178,27 @@ IN_PROC_BROWSER_TEST_F(PrefHashBrowserTest,
       g_browser_process->local_state()->GetDictionary(
           prefs::kProfilePreferenceHashes);
 
-  // 3 is for hash_of_hashes, default profile, and new profile.
-  ASSERT_EQ(3U, hashes->size());
+  // 4 is for hash_of_hashes, versions_dict, default profile, and new profile.
+  EXPECT_EQ(4U, hashes->size());
 
   // One of the two profiles should not have been loaded. Reset its hash store.
   const base::FilePath unloaded_profile_path = GetUnloadedProfilePath();
-  ProfileImpl::ResetPrefHashStore(unloaded_profile_path);
+  chrome_prefs::ResetPrefHashStore(unloaded_profile_path);
 
   // One of the profile hash collections should be gone.
-  ASSERT_EQ(2U, hashes->size());
+  EXPECT_EQ(3U, hashes->size());
+
+  // No profile should have gone through the unloaded profile initialization in
+  // this phase as both profiles were already initialized at the beginning of
+  // this phase (resetting the unloaded profile's PrefHashStore should only
+  // force initialization in the next phase's startup).
+  EXPECT_EQ(
+      0, GetTrackedPrefHistogramCount(
+             "Settings.TrackedPreferencesAlternateStoreVersionUpdatedFrom",
+             true));
 }
 
-IN_PROC_BROWSER_TEST_F(PrefHashBrowserTest,
+IN_PROC_BROWSER_TEST_P(PrefHashBrowserTest,
                        InitializeUnloadedProfiles) {
   if (!profiles::IsMultipleProfilesEnabled())
     return;
@@ -122,16 +207,90 @@ IN_PROC_BROWSER_TEST_F(PrefHashBrowserTest,
       g_browser_process->local_state()->GetDictionary(
           prefs::kProfilePreferenceHashes);
 
-  // The deleted hash collection should be restored.
-  ASSERT_EQ(3U, hashes->size());
+  // The deleted hash collection should be restored only if the current
+  // SettingsEnforcement group allows it.
+  if (is_unloaded_profile_seeding_allowed_) {
+    EXPECT_EQ(4U, hashes->size());
+
+    // Verify that the initialization truly did occur in this phase's startup;
+    // rather than in the previous phase's shutdown.
+    EXPECT_EQ(
+        1, GetTrackedPrefHistogramCount(
+               "Settings.TrackedPreferencesAlternateStoreVersionUpdatedFrom",
+               false));
+  } else {
+    EXPECT_EQ(3U, hashes->size());
+
+    EXPECT_EQ(
+        0, GetTrackedPrefHistogramCount(
+               "Settings.TrackedPreferencesAlternateStoreVersionUpdatedFrom",
+               true));
+  }
 
   ProfileManager* profile_manager = g_browser_process->profile_manager();
-  const std::vector<Profile*> loaded_profiles =
-      profile_manager->GetLoadedProfiles();
 
   // Verify that only one profile was loaded. We assume that the unloaded
   // profile is the same one that wasn't loaded in the last launch (i.e., it's
   // the one whose hash store we reset, and the fact that it is now restored is
   // evidence that we restored the hashes of an unloaded profile.).
-  ASSERT_EQ(1U, loaded_profiles.size());
+  ASSERT_EQ(1U, profile_manager->GetLoadedProfiles().size());
+
+  // Loading the first profile should only have produced unchanged reports.
+  EXPECT_EQ(
+      0, GetTrackedPrefHistogramCount(
+             "Settings.TrackedPreferenceChanged", true));
+  EXPECT_EQ(
+      0, GetTrackedPrefHistogramCount(
+             "Settings.TrackedPreferenceCleared", true));
+  EXPECT_EQ(
+      0, GetTrackedPrefHistogramCount(
+             "Settings.TrackedPreferenceInitialized", true));
+  EXPECT_EQ(
+      0, GetTrackedPrefHistogramCount(
+             "Settings.TrackedPreferenceTrustedInitialized", true));
+  EXPECT_EQ(
+      0, GetTrackedPrefHistogramCount(
+             "Settings.TrackedPreferenceMigrated", true));
+  int initial_unchanged_count =
+      GetTrackedPrefHistogramCount("Settings.TrackedPreferenceUnchanged",
+                                   false);
+  EXPECT_GT(initial_unchanged_count, 0);
+
+  if (is_unloaded_profile_seeding_allowed_) {
+    // Explicitly load the unloaded profile.
+    profile_manager->GetProfile(GetUnloadedProfilePath());
+    ASSERT_EQ(2U, profile_manager->GetLoadedProfiles().size());
+
+    // Loading the unloaded profile should only generate unchanged pings; and
+    // should have produced as many of them as loading the first profile.
+    EXPECT_EQ(
+        0, GetTrackedPrefHistogramCount(
+               "Settings.TrackedPreferenceChanged", true));
+    EXPECT_EQ(
+        0, GetTrackedPrefHistogramCount(
+               "Settings.TrackedPreferenceCleared", true));
+    EXPECT_EQ(
+        0, GetTrackedPrefHistogramCount(
+               "Settings.TrackedPreferenceInitialized", true));
+    EXPECT_EQ(
+        0, GetTrackedPrefHistogramCount(
+               "Settings.TrackedPreferenceTrustedInitialized", true));
+    EXPECT_EQ(
+        0, GetTrackedPrefHistogramCount(
+               "Settings.TrackedPreferenceMigrated", true));
+    EXPECT_EQ(
+        initial_unchanged_count * 2,
+        GetTrackedPrefHistogramCount("Settings.TrackedPreferenceUnchanged",
+                                     false));
+  }
 }
+
+// TODO(gab): Also test kSettingsEnforcementGroupEnforceAlways below; for some
+// reason it doesn't pass on the try bots, yet I can't repro the failure
+// locally, it's as if GROUP_NO_ENFORCEMENT is always picked on bots..?
+INSTANTIATE_TEST_CASE_P(
+    PrefHashBrowserTestInstance,
+    PrefHashBrowserTest,
+    testing::Values(
+        chrome_prefs::internals::kSettingsEnforcementGroupNoEnforcement,
+        chrome_prefs::internals::kSettingsEnforcementGroupEnforceOnload));