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

Side by Side 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: Renamed ProfileAttributesStorage related functions in profile_statistics.* Created 4 years, 9 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) 2016 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 <stddef.h>
6 #include <stdint.h>
7
8 #include <algorithm>
9 #include <set>
10 #include <string>
11 #include <vector>
12
13 #include "base/bind.h"
14 #include "base/callback_forward.h"
15 #include "base/macros.h"
16 #include "base/run_loop.h"
17 #include "base/strings/stringprintf.h"
18 #include "build/build_config.h"
19 #include "chrome/browser/password_manager/password_store_factory.h"
20 #include "chrome/browser/profiles/profile_manager.h"
21 #include "chrome/browser/profiles/profile_statistics.h"
22 #include "chrome/browser/profiles/profile_statistics_aggregator.h"
23 #include "chrome/browser/profiles/profile_statistics_common.h"
24 #include "chrome/browser/profiles/profile_statistics_factory.h"
25 #include "chrome/browser/ui/browser.h"
26 #include "chrome/test/base/in_process_browser_test.h"
27 #include "components/password_manager/core/browser/password_manager_test_utils.h "
28 #include "components/password_manager/core/browser/test_password_store.h"
29 #include "content/public/test/test_utils.h"
30
31 namespace {
32
33 std::set<std::string> stats_categories() {
34 std::set<std::string> categories;
35 categories.insert(profiles::kProfileStatisticsBrowsingHistory);
36 categories.insert(profiles::kProfileStatisticsPasswords);
37 categories.insert(profiles::kProfileStatisticsBookmarks);
38 categories.insert(profiles::kProfileStatisticsSettings);
39 EXPECT_EQ(4u, categories.size());
40 return categories;
41 }
42
43 bool IsProfileCategoryStatEqual(const profiles::ProfileCategoryStat& a,
44 const profiles::ProfileCategoryStat& b) {
45 return a.category == b.category && a.count == b.count &&
46 a.success == b.success;
47 }
48
49 std::string ProfileCategoryStatToString(
50 const profiles::ProfileCategoryStat& a) {
51 return base::StringPrintf("category = %s, count = %d, success = %s",
52 a.category.c_str(), a.count, a.success ? "true" : "false");
53 }
54
55 ::testing::AssertionResult AssertionProfileCategoryStatEqual(
56 const char* actual_expression,
57 const char* expected_expression,
58 const profiles::ProfileCategoryStat& actual_value,
59 const profiles::ProfileCategoryStat& expected_value) {
60 if (IsProfileCategoryStatEqual(actual_value, expected_value)) {
61 return ::testing::AssertionSuccess();
62 } else {
63 return ::testing::AssertionFailure()
64 << "Value of: " << actual_expression
65 << "\n Actual: " << ProfileCategoryStatToString(actual_value)
66 << "\nExpected: " << expected_expression
67 << "\nWhich is: " << ProfileCategoryStatToString(expected_value);
68 }
69 }
70
71 ::testing::AssertionResult AssertionProfileCategoryStatsEqual(
72 const char* actual_expression,
73 const char* expected_expression,
74 const profiles::ProfileCategoryStats& actual_value,
75 const profiles::ProfileCategoryStats& expected_value) {
76 if (actual_value.size() == expected_value.size() &&
77 std::is_permutation(actual_value.cbegin(),
78 actual_value.cend(),
79 expected_value.cbegin(),
80 IsProfileCategoryStatEqual)) {
81 return ::testing::AssertionSuccess();
82 } else {
83 ::testing::AssertionResult result = testing::AssertionFailure();
84 result << "ProfileCategoryStats are not equal.";
85
86 result << "\n Actual: " << actual_expression << "\nWhich is:";
87 for (const auto& value : actual_value)
88 result << "\n " << ProfileCategoryStatToString(value);
89
90 result << "\nExpected: " << expected_expression << "\nWhich is:";
91 for (const auto& value : expected_value)
92 result << "\n " << ProfileCategoryStatToString(value);
93
94 return result;
95 }
96 }
97
98 class ProfileStatisticsAggregatorState {
99 public:
100 ProfileStatisticsAggregatorState()
101 : ProfileStatisticsAggregatorState(stats_categories().size()) {}
102
103 explicit ProfileStatisticsAggregatorState(size_t required_stat_count) {
104 stats_categories_ = stats_categories();
105 num_of_stats_categories_ = stats_categories_.size();
106 SetRequiredStatCountAndCreateRunLoop(required_stat_count);
107 }
108
109 void SetRequiredStatCountAndCreateRunLoop(size_t required_stat_count) {
110 EXPECT_GE(num_of_stats_categories_, required_stat_count);
111 required_stat_count_ = required_stat_count;
112 run_loop_.reset(new base::RunLoop());
113 }
114
115 void WaitForStats() {
116 run_loop_->Run();
117 run_loop_.reset();
118 }
119
120 profiles::ProfileCategoryStats GetStats() const { return stats_; }
121 int GetNumOfFails() const { return num_of_fails_; }
122
123 void StatsCallback(profiles::ProfileCategoryStats stats_return) {
124 size_t newCount = stats_return.size();
125 // If newCount is 1, then a new GatherStatistics task has started. Discard
126 // the old statistics by setting oldCount to 0 in this case.
127 size_t oldCount = newCount == 1u ? 0u : stats_.size();
128
129 // Only one new statistic arrives at a time.
130 EXPECT_EQ(oldCount + 1u, newCount);
131 for (size_t i = 0u; i < oldCount; i++) {
132 // Exisiting statistics must be the same.
133 EXPECT_PRED_FORMAT2(AssertionProfileCategoryStatEqual,
134 stats_[i], stats_return[i]);
135 }
136
137 num_of_fails_ = 0;
138 for (size_t i = 0u; i < newCount; i++) {
139 // The category must be a valid category.
140 EXPECT_EQ(1u, stats_categories_.count(stats_return[i].category));
141 // The categories in |stats_return| must all different.
142 for (size_t j = 0u; j < i; j++)
143 EXPECT_NE(stats_return[i].category, stats_return[j].category);
144 // Count the number of statistics failures.
145 if (!stats_return[i].success)
146 num_of_fails_++;
147 }
148 stats_ = stats_return;
149
150 EXPECT_GE(num_of_stats_categories_, newCount);
151 if (required_stat_count_ <= newCount)
152 run_loop_->Quit();
153 }
154
155 private:
156 std::set<std::string> stats_categories_;
157 size_t num_of_stats_categories_;
158 size_t required_stat_count_;
159 scoped_ptr<base::RunLoop> run_loop_;
160
161 profiles::ProfileCategoryStats stats_;
162 int num_of_fails_ = 0;
163 };
164
165 } // namespace
166
167 class ProfileStatisticsBrowserTest : public InProcessBrowserTest {
168 public:
169 void SetUpOnMainThread() override {
170 // Use TestPasswordStore to remove a possible race. Normally the
171 // PasswordStore does its database manipulation on the DB thread, which
172 // creates a possible race during navigation. Specifically the
173 // PasswordManager will ignore any forms in a page if the load from the
174 // PasswordStore has not completed.
175 PasswordStoreFactory::GetInstance()->SetTestingFactory(
176 browser()->profile(),
177 password_manager::BuildPasswordStore<
178 content::BrowserContext, password_manager::TestPasswordStore>);
179 }
180 };
181
182 using ProfileStatisticsBrowserDeathTest = ProfileStatisticsBrowserTest;
183
184 IN_PROC_BROWSER_TEST_F(ProfileStatisticsBrowserTest, GatherStatistics) {
185 Profile* profile = ProfileManager::GetActiveUserProfile();
186 ASSERT_TRUE(profile);
187 ProfileStatistics* profile_stat =
188 ProfileStatisticsFactory::GetForProfile(profile);
189
190 ProfileStatisticsAggregatorState state;
191 EXPECT_FALSE(profile_stat->HasAggregator());
192 profile_stat->GatherStatistics(
193 base::Bind(&ProfileStatisticsAggregatorState::StatsCallback,
194 base::Unretained(&state)));
195 ASSERT_TRUE(profile_stat->HasAggregator());
196 EXPECT_EQ(1u, profile_stat->GetAggregator()->GetCallbackCount());
197 state.WaitForStats();
198
199 EXPECT_EQ(0, state.GetNumOfFails());
200
201 profiles::ProfileCategoryStats stats = state.GetStats();
202 for (const auto& stat : stats) {
203 if (stat.category != profiles::kProfileStatisticsSettings)
204 EXPECT_EQ(0, stat.count);
205 }
206
207 EXPECT_PRED_FORMAT2(AssertionProfileCategoryStatsEqual, stats,
208 ProfileStatistics::GetProfileStatisticsFromAttributesStorage(
209 profile->GetPath()));
210 }
211
212 IN_PROC_BROWSER_TEST_F(ProfileStatisticsBrowserTest,
213 GatherStatisticsTwoCallbacks) {
214 Profile* profile = ProfileManager::GetActiveUserProfile();
215 ASSERT_TRUE(profile);
216 ProfileStatistics* profile_stat =
217 ProfileStatisticsFactory::GetForProfile(profile);
218
219 ProfileStatisticsAggregatorState state1(1u);
220 ProfileStatisticsAggregatorState state2;
221
222 EXPECT_FALSE(profile_stat->HasAggregator());
223 profile_stat->GatherStatistics(
224 base::Bind(&ProfileStatisticsAggregatorState::StatsCallback,
225 base::Unretained(&state1)));
226 ASSERT_TRUE(profile_stat->HasAggregator());
227 EXPECT_EQ(1u, profile_stat->GetAggregator()->GetCallbackCount());
228 state1.WaitForStats();
229
230 ASSERT_TRUE(profile_stat->HasAggregator());
231 EXPECT_EQ(1u, profile_stat->GetAggregator()->GetCallbackCount());
232
233 state1.SetRequiredStatCountAndCreateRunLoop(stats_categories().size());
234
235 profile_stat->GatherStatistics(
236 base::Bind(&ProfileStatisticsAggregatorState::StatsCallback,
237 base::Unretained(&state2)));
238 ASSERT_TRUE(profile_stat->HasAggregator());
239 EXPECT_EQ(2u, profile_stat->GetAggregator()->GetCallbackCount());
240 state1.WaitForStats();
241 state2.WaitForStats();
242
243 EXPECT_EQ(0, state1.GetNumOfFails());
244
245 EXPECT_PRED_FORMAT2(AssertionProfileCategoryStatsEqual,
246 state1.GetStats(), state2.GetStats());
247 }
248
249 IN_PROC_BROWSER_TEST_F(ProfileStatisticsBrowserTest, CloseBrowser) {
250 Profile* profile = ProfileManager::GetActiveUserProfile();
251 ASSERT_TRUE(profile);
252 ProfileStatistics* profile_stat =
253 ProfileStatisticsFactory::GetForProfile(profile);
254
255 EXPECT_FALSE(profile_stat->HasAggregator());
256 CloseBrowserSynchronously(browser());
257 // The statistics task should be either running or finished.
258 if (profile_stat->HasAggregator()) {
259 EXPECT_EQ(0u, profile_stat->GetAggregator()->GetCallbackCount());
260 } else {
261 // Some of the statistics (e.g. settings) do always succeed. If all the
262 // statistics "failed", it means nothing is stored in profile attributes
263 // storage, and the statistics task was not run.
264 profiles::ProfileCategoryStats stats =
265 ProfileStatistics::GetProfileStatisticsFromAttributesStorage(
266 profile->GetPath());
267 bool has_stats = false;
268 for (const profiles::ProfileCategoryStat& stat : stats) {
269 if (stat.success) {
270 has_stats = true;
271 break;
272 }
273 }
274 EXPECT_TRUE(has_stats);
275 }
276 }
OLDNEW
« no previous file with comments | « chrome/browser/profiles/profile_statistics_aggregator.cc ('k') | chrome/browser/profiles/profile_statistics_common.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698