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

Side by Side Diff: chrome/browser/budget_service/budget_manager_unittest.cc

Issue 2281673002: Full hookup of BudgetManager interfaces to BudgetDatabase. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@manager
Patch Set: nits Created 4 years, 3 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
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <stdint.h> 5 #include <stdint.h>
6 #include <string> 6 #include <string>
7 7
8 #include "base/memory/ptr_util.h" 8 #include "base/memory/ptr_util.h"
9 #include "base/run_loop.h" 9 #include "base/run_loop.h"
10 #include "base/test/simple_test_clock.h"
11 #include "chrome/browser/budget_service/budget_manager.h" 10 #include "chrome/browser/budget_service/budget_manager.h"
12 #include "chrome/browser/budget_service/budget_manager_factory.h" 11 #include "chrome/browser/budget_service/budget_manager_factory.h"
13 #include "chrome/browser/engagement/site_engagement_service.h" 12 #include "chrome/browser/engagement/site_engagement_service.h"
14 #include "chrome/common/pref_names.h" 13 #include "chrome/common/pref_names.h"
15 #include "chrome/test/base/testing_profile.h" 14 #include "chrome/test/base/testing_profile.h"
16 #include "components/prefs/pref_service.h" 15 #include "components/prefs/pref_service.h"
17 #include "components/prefs/scoped_user_pref_update.h" 16 #include "components/prefs/scoped_user_pref_update.h"
18 #include "content/public/test/test_browser_thread_bundle.h" 17 #include "content/public/test/test_browser_thread_bundle.h"
19 #include "testing/gtest/include/gtest/gtest.h" 18 #include "testing/gtest/include/gtest/gtest.h"
20 #include "third_party/WebKit/public/platform/modules/budget_service/budget_servi ce.mojom.h" 19 #include "third_party/WebKit/public/platform/modules/budget_service/budget_servi ce.mojom.h"
21 20
22 namespace { 21 namespace {
23 22
24 const char kTestOrigin[] = "https://example.com"; 23 const char kTestOrigin[] = "https://example.com";
25 const double kTestBudget = 10.0;
26 const double kTestSES = 48.0; 24 const double kTestSES = 48.0;
27 const double kLowSES = 1.0;
28 const double kMaxSES = 100.0;
29 // Mirrors definition in BudgetManager, this is 10 days of seconds.
30 const double kSecondsToAccumulate = 864000.0;
31 25
32 } // namespace 26 } // namespace
33 27
34 class BudgetManagerTest : public testing::Test { 28 class BudgetManagerTest : public testing::Test {
35 public: 29 public:
36 BudgetManagerTest() : budget_(0.0) {}
37 ~BudgetManagerTest() override {} 30 ~BudgetManagerTest() override {}
38 31
39 BudgetManager* GetManager() { 32 BudgetManager* GetManager() {
40 return BudgetManagerFactory::GetForProfile(&profile_); 33 return BudgetManagerFactory::GetForProfile(&profile_);
41 } 34 }
42 35
43 void SetSiteEngagementScore(const GURL& url, double score) { 36 void SetSiteEngagementScore(const GURL& url, double score) {
44 SiteEngagementService* service = SiteEngagementService::Get(&profile_); 37 SiteEngagementService* service = SiteEngagementService::Get(&profile_);
45 service->ResetScoreForURL(url, score); 38 service->ResetScoreForURL(url, score);
46 } 39 }
47 40
48 Profile* profile() { return &profile_; } 41 Profile* profile() { return &profile_; }
49 42
50 base::SimpleTestClock* SetClockForTesting() {
51 base::SimpleTestClock* clock = new base::SimpleTestClock();
52 BudgetManagerFactory::GetForProfile(&profile_)->SetClockForTesting(
53 base::WrapUnique(clock));
54 return clock;
55 }
56
57 double GetBudget() {
58 const GURL origin(kTestOrigin);
59 base::RunLoop run_loop;
60 GetManager()->GetBudget(
61 origin, base::Bind(&BudgetManagerTest::GotBudget,
62 base::Unretained(this), run_loop.QuitClosure()));
63 run_loop.Run();
64 return budget_;
65 }
66
67 void GotBudget(base::Closure run_loop_closure, double budget) {
68 budget_ = budget;
69 run_loop_closure.Run();
70 }
71
72 void StoreBudget(double budget) {
73 const GURL origin(kTestOrigin);
74 base::RunLoop run_loop;
75 GetManager()->StoreBudget(origin, budget, run_loop.QuitClosure());
76 run_loop.Run();
77 }
78
79 void StatusCallback(base::Closure run_loop_closure, bool success) { 43 void StatusCallback(base::Closure run_loop_closure, bool success) {
80 success_ = success; 44 success_ = success;
81 run_loop_closure.Run(); 45 run_loop_closure.Run();
82 } 46 }
83 47
84 bool ReserveBudget(blink::mojom::BudgetOperationType type) { 48 bool ReserveBudget(blink::mojom::BudgetOperationType type) {
85 const GURL origin(kTestOrigin); 49 const GURL origin(kTestOrigin);
86 base::RunLoop run_loop; 50 base::RunLoop run_loop;
87 GetManager()->Reserve( 51 GetManager()->Reserve(
88 origin, type, 52 origin, type,
89 base::Bind(&BudgetManagerTest::StatusCallback, base::Unretained(this), 53 base::Bind(&BudgetManagerTest::StatusCallback, base::Unretained(this),
90 run_loop.QuitClosure())); 54 run_loop.QuitClosure()));
55 run_loop.Run();
56 return success_;
57 }
58
59 bool ConsumeBudget(blink::mojom::BudgetOperationType type) {
60 const GURL origin(kTestOrigin);
61 base::RunLoop run_loop;
62 GetManager()->Consume(
63 origin, type,
64 base::Bind(&BudgetManagerTest::StatusCallback, base::Unretained(this),
65 run_loop.QuitClosure()));
91 run_loop.Run(); 66 run_loop.Run();
92 return success_; 67 return success_;
93 } 68 }
94 69
95 // Members for callbacks to set. 70 // Members for callbacks to set.
96 double budget_;
97 bool success_; 71 bool success_;
98 72
99 private: 73 private:
100 content::TestBrowserThreadBundle thread_bundle_; 74 content::TestBrowserThreadBundle thread_bundle_;
101 TestingProfile profile_; 75 TestingProfile profile_;
102 }; 76 };
103 77
104 TEST_F(BudgetManagerTest, GetBudgetNoBudgetOrSES) { 78 TEST_F(BudgetManagerTest, GetBudgetConsumedOverTime) {
105 EXPECT_DOUBLE_EQ(GetBudget(), 0.0); 79 // Set initial SES. The first time we try to spend budget, the
106 } 80 // engagement award will be granted which is 48.0.
107
108 TEST_F(BudgetManagerTest, GetBudgetNoBudgetSESExists) {
109 // Set a starting SES for the url but no stored budget info.
110 const GURL origin(kTestOrigin); 81 const GURL origin(kTestOrigin);
111 SetSiteEngagementScore(origin, kTestSES); 82 SetSiteEngagementScore(origin, kTestSES);
83 const blink::mojom::BudgetOperationType type =
84 blink::mojom::BudgetOperationType::SILENT_PUSH;
112 85
113 EXPECT_DOUBLE_EQ(GetBudget(), kTestSES); 86 // Spend for 24 silent push messages. This should consume all the original
87 // budget grant.
88 for (int i = 0; i < 24; i++)
89 ASSERT_TRUE(ReserveBudget(type));
90
91 // Try to send one final silent push. The origin should be out of budget.
92 ASSERT_FALSE(ReserveBudget(type));
93
94 // Try to consume for the 24 messages reserved.
95 for (int i = 0; i < 24; i++)
96 ASSERT_TRUE(ConsumeBudget(type));
97
98 // The next consume should fail, since there is no reservation or budget
99 // available.
100 ASSERT_FALSE(ConsumeBudget(type));
114 } 101 }
115
116 TEST_F(BudgetManagerTest, GetBudgetNoElapsedTime) {
117 StoreBudget(kTestBudget);
118 EXPECT_DOUBLE_EQ(GetBudget(), kTestBudget);
119 }
120
121 TEST_F(BudgetManagerTest, GetBudgetElapsedTime) {
122 // Manually construct a BudgetManager with a clock that the test
123 // can control so that we can fast forward in time.
124 base::SimpleTestClock* clock = SetClockForTesting();
125 base::Time starting_time = clock->Now();
126
127 // Set initial SES and budget values.
128 const GURL origin(kTestOrigin);
129 SetSiteEngagementScore(origin, kTestSES);
130 StoreBudget(kTestBudget);
131
132 double budget = GetBudget();
133 EXPECT_DOUBLE_EQ(budget, kTestBudget);
134
135 // Query for the budget after 1 second has passed.
136 clock->SetNow(starting_time + base::TimeDelta::FromSeconds(1));
137 budget = GetBudget();
138 EXPECT_LT(budget, kTestBudget + kTestSES * 1.0 / kSecondsToAccumulate);
139 EXPECT_GT(budget, kTestBudget);
140
141 // Query for the budget after 1 hour has passed.
142 clock->SetNow(starting_time + base::TimeDelta::FromHours(1));
143 budget = GetBudget();
144 EXPECT_LT(budget, kTestBudget + kTestSES * 3600.0 / kSecondsToAccumulate);
145 EXPECT_GT(budget, kTestBudget);
146
147 // Query for the budget after 5 days have passed. The budget should be
148 // increasing, but not up the SES score.
149 clock->SetNow(starting_time + base::TimeDelta::FromDays(5));
150 budget = GetBudget();
151 EXPECT_GT(budget, kTestBudget);
152 EXPECT_LT(budget, kTestSES);
153 double moderate_ses_budget = budget;
154
155 // Query for the budget after 10 days have passed. By this point, the budget
156 // should converge to the SES score.
157 clock->SetNow(starting_time + base::TimeDelta::FromDays(10));
158 budget = GetBudget();
159 EXPECT_DOUBLE_EQ(budget, kTestSES);
160
161 // Now, change the SES score to the maximum amount and reinitialize budget.
162 SetSiteEngagementScore(origin, kMaxSES);
163 StoreBudget(kTestBudget);
164 starting_time = clock->Now();
165
166 // Query for the budget after 1 second has passed.
167 clock->SetNow(starting_time + base::TimeDelta::FromSeconds(1));
168 budget = GetBudget();
169 EXPECT_LT(budget, kTestBudget + kMaxSES * 1.0 / kSecondsToAccumulate);
170
171 // Query for the budget after 5 days have passed. Again, the budget should be
172 // approaching the SES, but not have reached it.
173 clock->SetNow(starting_time + base::TimeDelta::FromDays(5));
174 budget = GetBudget();
175 EXPECT_GT(budget, kTestBudget);
176 EXPECT_LT(budget, kMaxSES);
177
178 // The budget after 5 days with max SES should be greater than the budget
179 // after 5 days with moderate SES.
180 EXPECT_GT(budget, moderate_ses_budget);
181
182 // Now, change the SES score to a low amount and reinitialize budget.
183 SetSiteEngagementScore(origin, kLowSES);
184 StoreBudget(kTestBudget);
185 starting_time = clock->Now();
186
187 // Query for the budget after 5 days have passed. Again, the budget should be
188 // approaching the SES, this time decreasing, but not have reached it.
189 clock->SetNow(starting_time + base::TimeDelta::FromDays(5));
190 budget = GetBudget();
191 EXPECT_LT(budget, kTestBudget);
192 EXPECT_GT(budget, kLowSES);
193 }
194
195 TEST_F(BudgetManagerTest, GetBudgetConsumedOverTime) {
196 // Manually construct a BudgetManager with a clock that the test
197 // can control so that we can fast forward in time.
198 base::SimpleTestClock* clock = SetClockForTesting();
199
200 // Set initial SES and budget values.
201 const GURL origin(kTestOrigin);
202 SetSiteEngagementScore(origin, kTestSES);
203 StoreBudget(kTestBudget);
204 double budget = 0.0;
205
206 // Measure over 200 hours. In each hour a message is received, and for 1 in
207 // 10, budget is consumed.
208 for (int i = 0; i < 200; i++) {
209 // Query for the budget after 1 hour has passed.
210 clock->Advance(base::TimeDelta::FromHours(1));
211 budget = GetBudget();
212
213 if (i % 10 == 0) {
214 double cost = BudgetManager::GetCost(
215 blink::mojom::BudgetOperationType::SILENT_PUSH);
216 StoreBudget(budget - cost);
217 }
218 }
219
220 // With a SES of 48.0, the origin will get a budget of 2.4 per day, but the
221 // old budget will also decay. At the end, we expect the budget to be lower
222 // than the starting budget.
223 EXPECT_GT(budget, 0.0);
224 EXPECT_LT(budget, kTestBudget);
225 }
226
227 TEST_F(BudgetManagerTest, GetBudgetInvalidBudget) {
228 const GURL origin(kTestOrigin);
229
230 // Set a starting SES for the url.
231 SetSiteEngagementScore(origin, kTestSES);
232
233 // Set a badly formatted budget in the user preferences.
234 DictionaryPrefUpdate update(profile()->GetPrefs(),
235 prefs::kBackgroundBudgetMap);
236 base::DictionaryValue* update_map = update.Get();
237 update_map->SetStringWithoutPathExpansion(origin.spec(), "20#2.0");
238
239 // Get the budget, expect that it will return SES.
240 EXPECT_DOUBLE_EQ(GetBudget(), kTestSES);
241 }
242
243 TEST_F(BudgetManagerTest, GetBudgetNegativeTime) {
244 // Manually construct a BudgetManager with a clock that the test
245 // can control so that we can fast forward in time.
246 base::SimpleTestClock* clock = SetClockForTesting();
247 base::Time starting_time = clock->Now();
248
249 // Set initial SES and budget values.
250 const GURL origin(kTestOrigin);
251 SetSiteEngagementScore(origin, kTestSES);
252 StoreBudget(kTestBudget);
253
254 // Move time forward an hour and get the budget.
255 clock->SetNow(starting_time + base::TimeDelta::FromHours(1));
256 double original_budget = GetBudget();
257
258 // Store the updated budget.
259 StoreBudget(original_budget);
260 EXPECT_NE(kTestBudget, original_budget);
261
262 // Now move time backwards a day and make sure that the current
263 // budget matches the budget of the most foward time.
264 clock->SetNow(starting_time - base::TimeDelta::FromDays(1));
265 EXPECT_NEAR(original_budget, GetBudget(), 0.01);
266 }
267
268 TEST_F(BudgetManagerTest, ReserveBudgetTest) {
269 // Reserve without any budget allocated should fail.
270 ASSERT_FALSE(ReserveBudget(blink::mojom::BudgetOperationType::SILENT_PUSH));
271 }
OLDNEW
« no previous file with comments | « chrome/browser/budget_service/budget_manager.cc ('k') | chrome/browser/budget_service/budget_service_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698