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

Unified Diff: chrome/browser/profiles/profile_statistics_browsertest.cc

Issue 1579433002: Make profile statistics tasks inspectable by tests (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Respond to comments Created 4 years, 11 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | chrome/chrome_tests.gypi » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/profiles/profile_statistics_browsertest.cc
diff --git a/chrome/browser/profiles/profile_statistics_browsertest.cc b/chrome/browser/profiles/profile_statistics_browsertest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..15f9b09470601284bd582bab10257bcf8a83741f
--- /dev/null
+++ b/chrome/browser/profiles/profile_statistics_browsertest.cc
@@ -0,0 +1,244 @@
+// Copyright (c) 2012 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 <stddef.h>
+
+#include "base/bind.h"
+#include "base/macros.h"
+#include "base/strings/stringprintf.h"
+#include "build/build_config.h"
+#include "chrome/browser/password_manager/password_store_factory.h"
+#include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/browser/profiles/profile_statistics.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/test/base/in_process_browser_test.h"
+#include "components/password_manager/core/browser/password_manager_test_utils.h"
+#include "components/password_manager/core/browser/test_password_store.h"
+#include "content/public/test/test_utils.h"
+
+namespace {
+
+const std::set<std::string> stats_categories {
+ profiles::kProfileStatisticsBrowsingHistory,
+ profiles::kProfileStatisticsPasswords,
+ profiles::kProfileStatisticsBookmarks,
+ profiles::kProfileStatisticsSettings};
+
lwchkg 2016/01/13 17:21:55 Do you know why this empty row is marked as differ
Mike Lerman 2016/01/14 15:21:53 It's been added; it doesn't exist on the left (e.g
lwchkg 2016/01/16 18:07:50 Thanks. Didn't notice this one.
+const size_t num_of_stats_categories = stats_categories.size();
+
+bool IsProfileCategoryStatEqual(const profiles::ProfileCategoryStat& a,
+ const profiles::ProfileCategoryStat& b) {
+ return a.category == b.category && a.count == b.count &&
+ a.success == b.success;
+}
+
+std::string ProfileCategoryStatToString(
+ const profiles::ProfileCategoryStat& a) {
+ return base::StringPrintf("category = %s, count = %d, success = %s",
+ a.category.c_str(), a.count, a.success ? "true" : "false");
+}
+
+::testing::AssertionResult AssertionProfileCategoryStatEqual(
+ const char* actual_expression,
+ const char* expected_expression,
+ const profiles::ProfileCategoryStat& actual_value,
+ const profiles::ProfileCategoryStat& expected_value) {
+ if (IsProfileCategoryStatEqual(actual_value, expected_value)) {
+ return ::testing::AssertionSuccess();
+ } else {
+ return ::testing::AssertionFailure()
+ << "Value of: " << actual_expression
+ << "\n Actual: " << ProfileCategoryStatToString(actual_value)
+ << "\nExpected: " << expected_expression
+ << "\nWhich is: " << ProfileCategoryStatToString(expected_value);
+ }
+}
+
+::testing::AssertionResult AssertionProfileCategoryStatsEqual(
+ const char* actual_expression,
+ const char* expected_expression,
+ const profiles::ProfileCategoryStats& actual_value,
Mike Lerman 2016/01/14 15:21:53 don't use "value", it conveys nothing. actual_cate
lwchkg 2016/01/16 18:07:50 Acknowledged.
+ const profiles::ProfileCategoryStats& expected_value) {
lwchkg 2016/01/13 17:21:55 Here's some sample output of the function. e:\chr
Mike Lerman 2016/01/14 15:21:53 Why only print the unmatched rows?? Why not just p
lwchkg 2016/01/16 18:07:50 I see. I'd print out the whole statistics since co
+ size_t actual_count = actual_value.size();
+ size_t expected_count = expected_value.size();
+ std::vector<bool> actual_unused(actual_count, true);
+ std::vector<bool> expected_unused(expected_count, true);
+
+ bool match_failed = actual_count != expected_count;
Mike Lerman 2016/01/14 15:21:53 match of what? of counts. Perhaps call this counts
lwchkg 2016/01/16 18:07:51 Looks like I've named the variable incorrectly, so
anthonyvd 2016/01/18 15:47:08 You could probably just add a comment with the abo
lwchkg 2016/01/18 18:01:19 Thanks. So comments will be added in the next patc
lwchkg 2016/02/11 17:13:09 Turns out std::is_permutation() was approved, so I
+ for (size_t actual_pos = 0; actual_pos < actual_count; actual_pos++) {
+ for (size_t expected_pos = 0; expected_pos < expected_count;
+ expected_pos++) {
+ if (expected_unused[expected_pos] &&
+ IsProfileCategoryStatEqual(actual_value[actual_pos],
+ expected_value[expected_pos])) {
+ actual_unused[actual_pos] = false;
+ expected_unused[expected_pos] = false;
+ break;
+ }
+ }
+
+ if (actual_unused[actual_pos])
+ match_failed = true;
+ }
+
+ if (!match_failed) {
+ return ::testing::AssertionSuccess();
+ } else {
+ ::testing::AssertionResult result = testing::AssertionFailure();
+ result << "ProfileCategoryStats are not equal.";
+
+ result << "\n Actual: " << actual_expression;
+ bool actual_printed = false;
+ for (size_t i = 0; i < actual_count; i++) {
+ if (actual_unused[i]) {
+ result << "\n"
+ << (actual_printed ? " " : "Unmatched rows: ")
+ << ProfileCategoryStatToString(actual_value[i]);
+ actual_printed = true;
+ }
+ }
+ if (!actual_printed)
+ result << "(no unmatched rows found in actual value)";
+
+
+ result << "\nExpected: " << expected_expression;
+ bool expected_printed = false;
+ for (size_t i = 0; i < expected_count; i++) {
+ if (expected_unused[i]) {
+ result << "\n"
+ << (expected_printed ? " " : "Unmatched rows: ")
+ << ProfileCategoryStatToString(expected_value[i]);
+ expected_printed = true;
+ }
+ }
+ if (!expected_printed)
+ result << "(no unmatched rows found in expected value)";
+
+ return result;
+ }
+}
+
+class ProfileStatisticsAggregatorState {
+ public:
+ void callback(base::RunLoop* run_loop,
+ profiles::ProfileCategoryStats stats_return) {
+ size_t oldCount = stats_.size();
+ size_t newCount = stats_return.size();
+
+ EXPECT_LT(oldCount, newCount);
+ if (oldCount < newCount) {
+ for (size_t i = 0; i < oldCount; i++) {
+ // Exisiting statistics must be the same.
+ EXPECT_PRED_FORMAT2(AssertionProfileCategoryStatEqual,
+ stats_[i], stats_return[i]);
+ // The new statistic categories must be different.
+ for (size_t j = oldCount; j < newCount; j++)
+ EXPECT_NE(stats_[i].category, stats_return[j].category);
+ }
+
+ for (size_t j = oldCount; j < newCount; j++) {
+ EXPECT_EQ(1u, stats_categories.count(stats_return[j].category));
+ // Count the number of statistics failures (incrementally).
+ if (!stats_return[j].success)
+ num_of_fails_++;
+ }
+ stats_ = stats_return;
+ }
+
+ EXPECT_GE(num_of_stats_categories, newCount);
+ if (num_of_stats_categories <= newCount)
+ run_loop->Quit();
+ }
+
+ profiles::ProfileCategoryStats GetStats() const { return stats_; }
+ int GetNumOfFails() const { return num_of_fails_; }
+
+ private:
+ profiles::ProfileCategoryStats stats_;
+ int num_of_fails_ = 0;
+};
+
+void WaitMilliseconds(int time_in_milliseconds) {
+ base::RunLoop run_loop;
+ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+ FROM_HERE, run_loop.QuitClosure(),
+ base::TimeDelta::FromMilliseconds(time_in_milliseconds));
+ run_loop.Run();
+}
+
+} // namespace
+
+class ProfileStatisticsBrowserTest : public InProcessBrowserTest {
+ public:
+ void SetUpOnMainThread() override {
+ // Use TestPasswordStore to remove a possible race. Normally the
+ // PasswordStore does its database manipulation on the DB thread, which
+ // creates a possible race during navigation. Specifically the
+ // PasswordManager will ignore any forms in a page if the load from the
+ // PasswordStore has not completed.
+ PasswordStoreFactory::GetInstance()->SetTestingFactory(
+ browser()->profile(),
+ password_manager::BuildPasswordStore<
+ content::BrowserContext, password_manager::TestPasswordStore>);
+ }
+};
+
+using ProfileStatisticsBrowserDeathTest = ProfileStatisticsBrowserTest;
+
+IN_PROC_BROWSER_TEST_F(ProfileStatisticsBrowserTest, GatherStatistics) {
+ Profile* profile = ProfileManager::GetActiveUserProfile();
+ ASSERT_TRUE(profile);
+
+ ProfileStatisticsAggregatorState state;
+
+ base::RunLoop run_loop;
+ profiles::GatherProfileStatistics(
+ profile,
+ base::Bind(&ProfileStatisticsAggregatorState::callback,
+ base::Unretained(&state), &run_loop),
+ nullptr);
+ run_loop.Run();
+
+ EXPECT_EQ(0, state.GetNumOfFails());
+
+ profiles::ProfileCategoryStats stats = state.GetStats();
+ for (const auto& stat : stats) {
+ if (stat.category != profiles::kProfileStatisticsSettings)
+ EXPECT_EQ(0, stat.count);
+ }
+
+ EXPECT_PRED_FORMAT2(AssertionProfileCategoryStatsEqual, stats,
+ profiles::GetProfileStatisticsFromCache(profile->GetPath()));
+}
+
+IN_PROC_BROWSER_TEST_F(ProfileStatisticsBrowserTest, CloseBrowser) {
+ Profile* profile = ProfileManager::GetActiveUserProfile();
+ ASSERT_TRUE(profile);
+
+ CloseBrowserSynchronously(browser());
+
+ profiles::ProfileCategoryStats stats;
+ // Wait for at most 2 seconds for the statistics to be gathered.
anthonyvd 2016/01/18 15:47:08 This looks to me like it has the potential to be f
lwchkg 2016/01/18 18:01:19 The same topic is still being discussed in patch #
+ for (int i = 0; i < 10; i++) {
+ WaitMilliseconds(200);
+ stats = profiles::GetProfileStatisticsFromCache(profile->GetPath());
+ EXPECT_EQ(num_of_stats_categories, stats.size());
+
+ bool allSucceed = true;
+ for (const auto& stat : stats)
+ allSucceed &= stat.success;
+ if (allSucceed)
+ break;
+ }
+
+ for (const auto& stat : stats) {
+ EXPECT_EQ(1u, stats_categories.count(stat.category));
+ EXPECT_TRUE(stat.success);
+ if (stat.category != profiles::kProfileStatisticsSettings)
+ EXPECT_EQ(0, stat.count);
+ }
+ // Wait for background tasks to complete, otherwise some warning about
+ // the failure to post a task will be displayed.
+ WaitMilliseconds(500);
+}
« no previous file with comments | « no previous file | chrome/chrome_tests.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698