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

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: Make ProfileStatisticsAggregator tasks trackable 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2012 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/macros.h"
15 #include "base/strings/stringprintf.h"
16 #include "build/build_config.h"
17 #include "chrome/browser/password_manager/password_store_factory.h"
18 #include "chrome/browser/profiles/profile_manager.h"
19 #include "chrome/browser/profiles/profile_statistics.h"
20 #include "chrome/browser/profiles/profile_statistics_aggregator.h"
21 #include "chrome/browser/profiles/profile_statistics_constants.h"
22 #include "chrome/browser/profiles/profile_statistics_types.h"
23 #include "chrome/browser/ui/browser.h"
24 #include "chrome/test/base/in_process_browser_test.h"
25 #include "components/password_manager/core/browser/password_manager_test_utils.h "
26 #include "components/password_manager/core/browser/test_password_store.h"
27 #include "content/public/test/test_utils.h"
28
29 namespace {
30
31 const std::set<std::string> stats_categories {
32 profiles::kProfileStatisticsBrowsingHistory,
33 profiles::kProfileStatisticsPasswords,
34 profiles::kProfileStatisticsBookmarks,
35 profiles::kProfileStatisticsSettings};
36
37 const size_t num_of_stats_categories = stats_categories.size();
38
39 bool IsProfileCategoryStatEqual(const profiles::ProfileCategoryStat& a,
40 const profiles::ProfileCategoryStat& b) {
41 return a.category == b.category && a.count == b.count &&
42 a.success == b.success;
43 }
44
45 std::string ProfileCategoryStatToString(
46 const profiles::ProfileCategoryStat& a) {
47 return base::StringPrintf("category = %s, count = %d, success = %s",
48 a.category.c_str(), a.count, a.success ? "true" : "false");
49 }
50
51 ::testing::AssertionResult AssertionProfileCategoryStatEqual(
52 const char* actual_expression,
53 const char* expected_expression,
54 const profiles::ProfileCategoryStat& actual_value,
55 const profiles::ProfileCategoryStat& expected_value) {
56 if (IsProfileCategoryStatEqual(actual_value, expected_value)) {
57 return ::testing::AssertionSuccess();
58 } else {
59 return ::testing::AssertionFailure()
60 << "Value of: " << actual_expression
61 << "\n Actual: " << ProfileCategoryStatToString(actual_value)
62 << "\nExpected: " << expected_expression
63 << "\nWhich is: " << ProfileCategoryStatToString(expected_value);
64 }
65 }
66
67 ::testing::AssertionResult AssertionProfileCategoryStatsEqual(
68 const char* actual_expression,
69 const char* expected_expression,
70 const profiles::ProfileCategoryStats& actual_value,
71 const profiles::ProfileCategoryStats& expected_value) {
72 size_t actual_count = actual_value.size();
73 size_t expected_count = expected_value.size();
74 std::vector<bool> actual_unused(actual_count, true);
75 std::vector<bool> expected_unused(expected_count, true);
76
77 bool match_failed = actual_count != expected_count;
78 for (size_t actual_pos = 0; actual_pos < actual_count; actual_pos++) {
79 for (size_t expected_pos = 0; expected_pos < expected_count;
80 expected_pos++) {
81 if (expected_unused[expected_pos] &&
82 IsProfileCategoryStatEqual(actual_value[actual_pos],
83 expected_value[expected_pos])) {
84 actual_unused[actual_pos] = false;
85 expected_unused[expected_pos] = false;
86 break;
87 }
88 }
89
90 if (actual_unused[actual_pos])
91 match_failed = true;
92 }
93
94 if (!match_failed) {
95 return ::testing::AssertionSuccess();
96 } else {
97 ::testing::AssertionResult result = testing::AssertionFailure();
98 result << "ProfileCategoryStats are not equal.";
99
100 result << "\n Actual: " << actual_expression;
101 bool actual_printed = false;
102 for (size_t i = 0; i < actual_count; i++) {
103 if (actual_unused[i]) {
104 result << "\n"
105 << (actual_printed ? " " : "Unmatched rows: ")
106 << ProfileCategoryStatToString(actual_value[i]);
107 actual_printed = true;
108 }
109 }
110 if (!actual_printed)
111 result << "(no unmatched rows found in actual value)";
112
113
114 result << "\nExpected: " << expected_expression;
115 bool expected_printed = false;
116 for (size_t i = 0; i < expected_count; i++) {
117 if (expected_unused[i]) {
118 result << "\n"
119 << (expected_printed ? " " : "Unmatched rows: ")
120 << ProfileCategoryStatToString(expected_value[i]);
121 expected_printed = true;
122 }
123 }
124 if (!expected_printed)
125 result << "(no unmatched rows found in expected value)";
126
127 return result;
128 }
129 }
130
131 class ProfileStatisticsAggregatorState {
132 public:
133 explicit ProfileStatisticsAggregatorState(base::RunLoop* run_loop)
134 : run_loop_(run_loop) {}
135
136 ProfileStatisticsAggregatorState(base::RunLoop* run_loop,
137 size_t required_stat_count)
138 : run_loop_(run_loop),
139 required_stat_count_(
140 std::min(num_of_stats_categories, required_stat_count)) {}
141
142 void callback(profiles::ProfileCategoryStats stats_return) {
143 size_t newCount = stats_return.size();
144 // If newCount is 1, then a new GatherStatistics task has started. Discard
145 // the old statistics by setting oldCount to 0 in this case.
146 size_t oldCount = newCount == 1 ? 0 : stats_.size();
147
148 EXPECT_LT(oldCount, newCount);
149 if (oldCount < newCount) {
150 for (size_t i = 0; i < oldCount; i++) {
151 // Exisiting statistics must be the same.
152 EXPECT_PRED_FORMAT2(AssertionProfileCategoryStatEqual,
153 stats_[i], stats_return[i]);
154 // The new statistic categories must be different.
155 for (size_t j = oldCount; j < newCount; j++)
156 EXPECT_NE(stats_[i].category, stats_return[j].category);
157 }
158
159 for (size_t j = oldCount; j < newCount; j++) {
160 EXPECT_EQ(1u, stats_categories.count(stats_return[j].category));
161 // Count the number of statistics failures (incrementally).
162 if (!stats_return[j].success)
163 num_of_fails_++;
164 }
165 }
166 stats_ = stats_return;
167
168 EXPECT_GE(num_of_stats_categories, newCount);
169 if (required_stat_count_ <= newCount)
170 run_loop_->Quit();
171 }
172
173 profiles::ProfileCategoryStats GetStats() const { return stats_; }
174 int GetNumOfFails() const { return num_of_fails_; }
175 void SetRunLoopAndRequiredStatCount(base::RunLoop* run_loop,
176 size_t required_stat_count) {
177 run_loop_ = run_loop;
178 required_stat_count_ = std::min(num_of_stats_categories,
179 required_stat_count);
180 }
181
182 private:
183 profiles::ProfileCategoryStats stats_;
184 int num_of_fails_ = 0;
185 base::RunLoop* run_loop_;
186 size_t required_stat_count_ = num_of_stats_categories;
187 };
188
189 void WaitMilliseconds(int time_in_milliseconds) {
190 base::RunLoop run_loop;
191 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
192 FROM_HERE, run_loop.QuitClosure(),
193 base::TimeDelta::FromMilliseconds(time_in_milliseconds));
194 run_loop.Run();
195 }
196
197 } // namespace
198
199 class ProfileStatisticsBrowserTest : public InProcessBrowserTest {
200 public:
201 void SetUpOnMainThread() override {
202 // Use TestPasswordStore to remove a possible race. Normally the
203 // PasswordStore does its database manipulation on the DB thread, which
204 // creates a possible race during navigation. Specifically the
205 // PasswordManager will ignore any forms in a page if the load from the
206 // PasswordStore has not completed.
207 PasswordStoreFactory::GetInstance()->SetTestingFactory(
208 browser()->profile(),
209 password_manager::BuildPasswordStore<
210 content::BrowserContext, password_manager::TestPasswordStore>);
211 }
212 };
213
214 using ProfileStatisticsBrowserDeathTest = ProfileStatisticsBrowserTest;
215
216 IN_PROC_BROWSER_TEST_F(ProfileStatisticsBrowserTest, GatherStatistics) {
217 Profile* profile = ProfileManager::GetActiveUserProfile();
218 ASSERT_TRUE(profile);
219
220 base::RunLoop run_loop;
221 ProfileStatisticsAggregatorState state(&run_loop);
222 EXPECT_EQ(false, ProfileStatistics::HasAggregator(profile));
223 ProfileStatistics::GatherProfileStatistics(
224 profile,
225 base::Bind(&ProfileStatisticsAggregatorState::callback,
226 base::Unretained(&state)));
227 EXPECT_EQ(true, ProfileStatistics::HasAggregator(profile));
228 EXPECT_EQ(1u, ProfileStatistics::GetAggregator(profile)->GetCallbackCount());
229 run_loop.Run();
230
231 EXPECT_EQ(0, state.GetNumOfFails());
232
233 profiles::ProfileCategoryStats stats = state.GetStats();
234 for (const auto& stat : stats) {
235 if (stat.category != profiles::kProfileStatisticsSettings)
236 EXPECT_EQ(0, stat.count);
237 }
238
239 EXPECT_PRED_FORMAT2(AssertionProfileCategoryStatsEqual, stats,
240 ProfileStatistics::GetProfileStatisticsFromCache(profile->GetPath()));
241 }
242
243 IN_PROC_BROWSER_TEST_F(ProfileStatisticsBrowserTest,
244 GatherStatisticsTwoCallbacks) {
245 Profile* profile = ProfileManager::GetActiveUserProfile();
246 ASSERT_TRUE(profile);
247
248 base::RunLoop run_loop1a;
249 base::RunLoop run_loop1b;
250 base::RunLoop run_loop2;
251 ProfileStatisticsAggregatorState state1(&run_loop1a, 1u);
252 ProfileStatisticsAggregatorState state2(&run_loop2);
253
254 EXPECT_EQ(false, ProfileStatistics::HasAggregator(profile));
255 ProfileStatistics::GatherProfileStatistics(
256 profile,
257 base::Bind(&ProfileStatisticsAggregatorState::callback,
258 base::Unretained(&state1)));
259 EXPECT_EQ(true, ProfileStatistics::HasAggregator(profile));
260 EXPECT_EQ(1u, ProfileStatistics::GetAggregator(profile)->GetCallbackCount());
261 run_loop1a.Run();
262
263 state1.SetRunLoopAndRequiredStatCount(&run_loop1b, SIZE_MAX);
264
265 ProfileStatistics::GatherProfileStatistics(
266 profile,
267 base::Bind(&ProfileStatisticsAggregatorState::callback,
268 base::Unretained(&state2)));
269 EXPECT_EQ(true, ProfileStatistics::HasAggregator(profile));
270 EXPECT_EQ(2u, ProfileStatistics::GetAggregator(profile)->GetCallbackCount());
271 run_loop1b.Run();
272 run_loop2.Run();
273
274 EXPECT_EQ(0, state1.GetNumOfFails());
275
276 EXPECT_PRED_FORMAT2(AssertionProfileCategoryStatsEqual,
277 state1.GetStats(), state2.GetStats());
278 }
279
280 IN_PROC_BROWSER_TEST_F(ProfileStatisticsBrowserTest, CloseBrowser) {
281 Profile* profile = ProfileManager::GetActiveUserProfile();
282 ASSERT_TRUE(profile);
283
284 EXPECT_EQ(false, ProfileStatistics::HasAggregator(profile));
285 CloseBrowserSynchronously(browser());
286 EXPECT_EQ(true, ProfileStatistics::HasAggregator(profile));
287 EXPECT_EQ(0u, ProfileStatistics::GetAggregator(profile)->GetCallbackCount());
288 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698