OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "chrome/browser/android/data_usage/external_data_use_observer.h" | 5 #include "chrome/browser/android/data_usage/external_data_use_observer.h" |
6 | 6 |
7 #include <stddef.h> | |
8 #include <stdint.h> | 7 #include <stdint.h> |
9 | 8 |
10 #include <map> | 9 #include <map> |
11 #include <memory> | 10 #include <memory> |
12 #include <string> | 11 #include <string> |
13 #include <vector> | 12 #include <vector> |
14 | 13 |
15 #include "base/metrics/field_trial.h" | 14 #include "base/metrics/field_trial.h" |
16 #include "base/run_loop.h" | 15 #include "base/run_loop.h" |
17 #include "base/single_thread_task_runner.h" | 16 #include "base/single_thread_task_runner.h" |
18 #include "base/strings/string_number_conversions.h" | 17 #include "base/strings/string_number_conversions.h" |
19 #include "base/test/histogram_tester.h" | 18 #include "base/test/histogram_tester.h" |
20 #include "base/threading/thread_task_runner_handle.h" | 19 #include "base/threading/thread_task_runner_handle.h" |
21 #include "chrome/browser/android/data_usage/data_use_tab_model.h" | 20 #include "chrome/browser/android/data_usage/data_use_tab_model.h" |
| 21 #include "chrome/browser/android/data_usage/external_data_use_reporter.h" |
22 #include "components/data_usage/core/data_use.h" | 22 #include "components/data_usage/core/data_use.h" |
23 #include "components/data_usage/core/data_use_aggregator.h" | 23 #include "components/data_usage/core/data_use_aggregator.h" |
24 #include "components/data_usage/core/data_use_amortizer.h" | |
25 #include "components/data_usage/core/data_use_annotator.h" | |
26 #include "components/sessions/core/session_id.h" | 24 #include "components/sessions/core/session_id.h" |
27 #include "components/variations/variations_associated_data.h" | 25 #include "components/variations/variations_associated_data.h" |
28 #include "content/public/browser/browser_thread.h" | 26 #include "content/public/browser/browser_thread.h" |
29 #include "content/public/test/test_browser_thread_bundle.h" | 27 #include "content/public/test/test_browser_thread_bundle.h" |
30 #include "net/base/network_change_notifier.h" | 28 #include "net/base/network_change_notifier.h" |
31 #include "testing/gtest/include/gtest/gtest.h" | 29 #include "testing/gtest/include/gtest/gtest.h" |
32 #include "url/gurl.h" | 30 #include "url/gurl.h" |
33 | 31 |
34 namespace { | 32 namespace { |
35 | 33 |
36 const char kUMAMatchingRuleFirstFetchDurationHistogram[] = | |
37 "DataUsage.Perf.MatchingRuleFirstFetchDuration"; | |
38 const char kUMAReportSubmissionDurationHistogram[] = | |
39 "DataUsage.Perf.ReportSubmissionDuration"; | |
40 | |
41 const char kDefaultLabel[] = "label"; | 34 const char kDefaultLabel[] = "label"; |
42 const SessionID::id_type kDefaultTabId = 0; | 35 const SessionID::id_type kDefaultTabId = 0; |
43 const char kDefaultURL[] = "http://www.google.com/#q=abc"; | 36 const char kDefaultURL[] = "http://www.google.com/#q=abc"; |
44 const char kFooMccMnc[] = "foo_mccmnc"; | |
45 const char kBarMccMnc[] = "bar_mccmnc"; | |
46 const char kBazMccMnc[] = "baz_mccmnc"; | |
47 const char kFooLabel[] = "foo_label"; | |
48 const char kBarLabel[] = "bar_label"; | |
49 | 37 |
50 } // namespace | 38 } // namespace |
51 | 39 |
52 namespace chrome { | 40 namespace chrome { |
53 | 41 |
54 namespace android { | 42 namespace android { |
55 | 43 |
56 class ExternalDataUseObserverTest : public testing::Test { | 44 class ExternalDataUseObserverTest : public testing::Test { |
57 public: | 45 public: |
58 void SetUp() override { | 46 void SetUp() override { |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
105 void AddDefaultMatchingRule() { | 93 void AddDefaultMatchingRule() { |
106 std::vector<std::string> url_regexes; | 94 std::vector<std::string> url_regexes; |
107 url_regexes.push_back( | 95 url_regexes.push_back( |
108 "http://www[.]google[.]com/#q=.*|https://www[.]google[.]com/#q=.*"); | 96 "http://www[.]google[.]com/#q=.*|https://www[.]google[.]com/#q=.*"); |
109 FetchMatchingRulesDone( | 97 FetchMatchingRulesDone( |
110 std::vector<std::string>(url_regexes.size(), std::string()), | 98 std::vector<std::string>(url_regexes.size(), std::string()), |
111 url_regexes, | 99 url_regexes, |
112 std::vector<std::string>(url_regexes.size(), kDefaultLabel)); | 100 std::vector<std::string>(url_regexes.size(), kDefaultLabel)); |
113 } | 101 } |
114 | 102 |
115 // Notifies DataUseTabModel that tab tracking has started on kDefaultTabId. | |
116 void TriggerTabTrackingOnDefaultTab() { | |
117 external_data_use_observer_->GetDataUseTabModel()->OnNavigationEvent( | |
118 kDefaultTabId, DataUseTabModel::TRANSITION_OMNIBOX_SEARCH, | |
119 GURL(kDefaultURL), std::string(), nullptr); | |
120 } | |
121 | |
122 // Returns a default data_usage::DataUse object. | 103 // Returns a default data_usage::DataUse object. |
123 data_usage::DataUse default_data_use() { | 104 data_usage::DataUse default_data_use() { |
124 return data_usage::DataUse( | 105 return data_usage::DataUse(GURL(kDefaultURL), base::TimeTicks::Now(), |
125 GURL(kDefaultURL), base::TimeTicks::Now(), GURL(), kDefaultTabId, | 106 GURL(), kDefaultTabId, |
126 net::NetworkChangeNotifier::CONNECTION_UNKNOWN, "", | 107 net::NetworkChangeNotifier::CONNECTION_UNKNOWN, |
127 default_upload_bytes(), default_download_bytes()); | 108 "", 1 /* upload bytes*/, 1 /* download bytes */); |
128 } | 109 } |
129 | 110 |
130 void OnDataUse(const data_usage::DataUse& data_use) { | 111 void OnDataUse(const data_usage::DataUse& data_use) { |
131 external_data_use_observer_->OnDataUse(data_use); | 112 external_data_use_observer_->OnDataUse(data_use); |
132 base::RunLoop().RunUntilIdle(); | 113 base::RunLoop().RunUntilIdle(); |
133 } | 114 } |
134 | 115 |
135 ExternalDataUseObserver* external_data_use_observer() const { | 116 ExternalDataUseObserver* external_data_use_observer() const { |
136 return external_data_use_observer_.get(); | 117 return external_data_use_observer_.get(); |
137 } | 118 } |
138 | 119 |
139 const ExternalDataUseObserver::DataUseReports& buffered_data_reports() const { | |
140 return external_data_use_observer_->buffered_data_reports_; | |
141 } | |
142 | |
143 int64_t default_upload_bytes() const { return 1; } | |
144 | |
145 int64_t default_download_bytes() const { | |
146 return external_data_use_observer_->data_use_report_min_bytes_; | |
147 } | |
148 | |
149 private: | 120 private: |
150 std::unique_ptr<content::TestBrowserThreadBundle> thread_bundle_; | 121 std::unique_ptr<content::TestBrowserThreadBundle> thread_bundle_; |
151 std::unique_ptr<data_usage::DataUseAggregator> data_use_aggregator_; | 122 std::unique_ptr<data_usage::DataUseAggregator> data_use_aggregator_; |
152 std::unique_ptr<ExternalDataUseObserver> external_data_use_observer_; | 123 std::unique_ptr<ExternalDataUseObserver> external_data_use_observer_; |
153 | 124 |
154 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_; | 125 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_; |
155 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_; | 126 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_; |
156 }; | 127 }; |
157 | 128 |
158 // Verifies that the external data use observer is registered as an observer | 129 // Verifies that the external data use observer is registered as an observer |
159 // only when at least one matching rule is present. | 130 // only when at least one matching rule is present. |
160 TEST_F(ExternalDataUseObserverTest, RegisteredAsDataUseObserver) { | 131 TEST_F(ExternalDataUseObserverTest, RegisteredAsDataUseObserver) { |
161 EXPECT_FALSE(external_data_use_observer()->registered_as_data_use_observer_); | 132 EXPECT_FALSE(external_data_use_observer()->registered_as_data_use_observer_); |
162 | 133 |
163 AddDefaultMatchingRule(); | 134 AddDefaultMatchingRule(); |
164 EXPECT_TRUE(external_data_use_observer()->registered_as_data_use_observer_); | 135 EXPECT_TRUE(external_data_use_observer()->registered_as_data_use_observer_); |
165 | 136 |
166 // Push an empty vector. Since no matching rules are present, | 137 // Push an empty vector. Since no matching rules are present, |
167 // |external_data_use_observer| should no longer be registered as a data use | 138 // |external_data_use_observer| should no longer be registered as a data use |
168 // observer. | 139 // observer. |
169 FetchMatchingRulesDone(std::vector<std::string>(), std::vector<std::string>(), | 140 FetchMatchingRulesDone(std::vector<std::string>(), std::vector<std::string>(), |
170 std::vector<std::string>()); | 141 std::vector<std::string>()); |
171 base::RunLoop().RunUntilIdle(); | 142 base::RunLoop().RunUntilIdle(); |
172 EXPECT_FALSE(external_data_use_observer()->registered_as_data_use_observer_); | 143 EXPECT_FALSE(external_data_use_observer()->registered_as_data_use_observer_); |
173 } | 144 } |
174 | 145 |
175 // Verifies that buffer size does not exceed the specified limit. | |
176 TEST_F(ExternalDataUseObserverTest, BufferSize) { | |
177 base::HistogramTester histogram_tester; | |
178 | |
179 AddDefaultMatchingRule(); | |
180 TriggerTabTrackingOnDefaultTab(); | |
181 | |
182 // Push more entries than the buffer size. Buffer size should not be exceeded. | |
183 for (size_t i = 0; i < ExternalDataUseObserver::kMaxBufferSize * 2; ++i) { | |
184 data_usage::DataUse data_use = default_data_use(); | |
185 data_use.mcc_mnc = "mccmnc" + base::Int64ToString(i); | |
186 OnDataUse(data_use); | |
187 } | |
188 | |
189 EXPECT_LE(0, external_data_use_observer()->total_bytes_buffered_); | |
190 | |
191 // Verify that total buffered bytes is computed correctly. | |
192 EXPECT_EQ( | |
193 static_cast<int64_t>(ExternalDataUseObserver::kMaxBufferSize * | |
194 (default_upload_bytes() + default_download_bytes())), | |
195 external_data_use_observer()->total_bytes_buffered_); | |
196 EXPECT_EQ(ExternalDataUseObserver::kMaxBufferSize, | |
197 buffered_data_reports().size()); | |
198 | |
199 // Verify the label of the data use report. | |
200 for (const auto& it : buffered_data_reports()) | |
201 EXPECT_EQ(kDefaultLabel, it.first.label); | |
202 | |
203 // Verify that metrics were updated correctly for the lost reports. | |
204 histogram_tester.ExpectUniqueSample( | |
205 "DataUsage.ReportSubmissionResult", | |
206 ExternalDataUseObserver::DATAUSAGE_REPORT_SUBMISSION_LOST, | |
207 ExternalDataUseObserver::kMaxBufferSize - 1); | |
208 histogram_tester.ExpectUniqueSample( | |
209 "DataUsage.ReportSubmission.Bytes.Lost", | |
210 default_upload_bytes() + default_download_bytes(), | |
211 ExternalDataUseObserver::kMaxBufferSize - 1); | |
212 } | |
213 | |
214 // Tests that buffered data use reports are merged correctly. | |
215 TEST_F(ExternalDataUseObserverTest, ReportsMergedCorrectly) { | |
216 AddDefaultMatchingRule(); | |
217 TriggerTabTrackingOnDefaultTab(); | |
218 | |
219 const size_t num_iterations = ExternalDataUseObserver::kMaxBufferSize * 2; | |
220 | |
221 for (size_t i = 0; i < num_iterations; ++i) { | |
222 data_usage::DataUse data_use_foo = default_data_use(); | |
223 data_use_foo.mcc_mnc = kFooMccMnc; | |
224 OnDataUse(data_use_foo); | |
225 | |
226 data_usage::DataUse data_use_bar = default_data_use(); | |
227 data_use_bar.mcc_mnc = kBarMccMnc; | |
228 OnDataUse(data_use_bar); | |
229 | |
230 data_usage::DataUse data_use_baz = default_data_use(); | |
231 data_use_baz.mcc_mnc = kBazMccMnc; | |
232 OnDataUse(data_use_baz); | |
233 } | |
234 | |
235 ASSERT_EQ(3U, buffered_data_reports().size()); | |
236 | |
237 // One of the foo reports should have been submitted, and all the other foo | |
238 // reports should have been merged together. All of the bar and baz reports | |
239 // should have been merged together respectively. | |
240 const struct { | |
241 std::string mcc_mnc; | |
242 size_t number_of_merged_reports; | |
243 } expected_data_use_reports[] = {{kFooMccMnc, num_iterations - 1}, | |
244 {kBarMccMnc, num_iterations}, | |
245 {kBazMccMnc, num_iterations}}; | |
246 | |
247 for (const auto& expected_report : expected_data_use_reports) { | |
248 const ExternalDataUseObserver::DataUseReportKey key( | |
249 kDefaultLabel, DataUseTabModel::kDefaultTag, | |
250 net::NetworkChangeNotifier::CONNECTION_UNKNOWN, | |
251 expected_report.mcc_mnc); | |
252 | |
253 EXPECT_NE(buffered_data_reports().end(), buffered_data_reports().find(key)); | |
254 EXPECT_EQ(static_cast<int64_t>(expected_report.number_of_merged_reports) * | |
255 (default_download_bytes()), | |
256 buffered_data_reports().find(key)->second.bytes_downloaded); | |
257 EXPECT_EQ(static_cast<int64_t>(expected_report.number_of_merged_reports * | |
258 (default_upload_bytes())), | |
259 buffered_data_reports().find(key)->second.bytes_uploaded); | |
260 } | |
261 } | |
262 | |
263 // Tests that timestamps of merged reports is correct. | |
264 TEST_F(ExternalDataUseObserverTest, TimestampsMergedCorrectly) { | |
265 AddDefaultMatchingRule(); | |
266 | |
267 const size_t num_iterations = ExternalDataUseObserver::kMaxBufferSize * 2; | |
268 | |
269 base::Time start_timestamp = base::Time::UnixEpoch(); | |
270 base::Time end_timestamp = start_timestamp + base::TimeDelta::FromSeconds(1); | |
271 for (size_t i = 0; i < num_iterations; ++i) { | |
272 external_data_use_observer()->BufferDataUseReport( | |
273 default_data_use(), kDefaultLabel, DataUseTabModel::kDefaultTag, | |
274 start_timestamp, end_timestamp); | |
275 | |
276 start_timestamp += base::TimeDelta::FromSeconds(1); | |
277 end_timestamp += base::TimeDelta::FromSeconds(1); | |
278 } | |
279 | |
280 EXPECT_EQ(1U, buffered_data_reports().size()); | |
281 EXPECT_EQ(0, buffered_data_reports().begin()->second.start_time.ToJavaTime()); | |
282 // Convert from seconds to milliseconds. | |
283 EXPECT_EQ(static_cast<int64_t>(num_iterations * 1000), | |
284 buffered_data_reports().begin()->second.end_time.ToJavaTime()); | |
285 } | |
286 | |
287 // Tests the behavior when multiple matching rules are available for URL and | |
288 // package name matching. | |
289 TEST_F(ExternalDataUseObserverTest, MultipleMatchingRules) { | |
290 std::vector<std::string> url_regexes; | |
291 url_regexes.push_back( | |
292 "http://www[.]foo[.]com/#q=.*|https://www[.]foo[.]com/#q=.*"); | |
293 url_regexes.push_back( | |
294 "http://www[.]bar[.]com/#q=.*|https://www[.]bar[.]com/#q=.*"); | |
295 | |
296 std::vector<std::string> labels; | |
297 labels.push_back(kFooLabel); | |
298 labels.push_back(kBarLabel); | |
299 | |
300 std::vector<std::string> app_package_names; | |
301 const char kAppFoo[] = "com.example.foo"; | |
302 const char kAppBar[] = "com.example.bar"; | |
303 app_package_names.push_back(kAppFoo); | |
304 app_package_names.push_back(kAppBar); | |
305 | |
306 FetchMatchingRulesDone(app_package_names, url_regexes, labels); | |
307 | |
308 external_data_use_observer()->GetDataUseTabModel()->OnNavigationEvent( | |
309 kDefaultTabId, DataUseTabModel::TRANSITION_OMNIBOX_SEARCH, | |
310 GURL("http://www.foo.com/#q=abc"), std::string(), nullptr); | |
311 | |
312 external_data_use_observer()->GetDataUseTabModel()->OnNavigationEvent( | |
313 kDefaultTabId + 1, DataUseTabModel::TRANSITION_OMNIBOX_SEARCH, | |
314 GURL("http://www.bar.com/#q=abc"), std::string(), nullptr); | |
315 | |
316 EXPECT_EQ(0U, external_data_use_observer()->buffered_data_reports_.size()); | |
317 EXPECT_TRUE(external_data_use_observer() | |
318 ->last_data_report_submitted_ticks_.is_null()); | |
319 | |
320 // Check |kLabelFoo| matching rule. | |
321 data_usage::DataUse data_foo = default_data_use(); | |
322 data_foo.url = GURL("http://www.foo.com/#q=abc"); | |
323 data_foo.mcc_mnc = kFooMccMnc; | |
324 OnDataUse(data_foo); | |
325 | |
326 // Check |kLabelBar| matching rule. | |
327 data_usage::DataUse data_bar = default_data_use(); | |
328 data_bar.tab_id = kDefaultTabId + 1; | |
329 data_bar.url = GURL("http://www.bar.com/#q=abc"); | |
330 data_bar.mcc_mnc = kBarMccMnc; | |
331 OnDataUse(data_bar); | |
332 | |
333 // bar report should be present. | |
334 EXPECT_EQ(1U, buffered_data_reports().size()); | |
335 | |
336 const ExternalDataUseObserver::DataUseReportKey key_bar( | |
337 kBarLabel, DataUseTabModel::kDefaultTag, | |
338 net::NetworkChangeNotifier::CONNECTION_UNKNOWN, kBarMccMnc); | |
339 EXPECT_NE(buffered_data_reports().end(), | |
340 buffered_data_reports().find(key_bar)); | |
341 } | |
342 | |
343 // Tests that hash function reports distinct values. This test may fail if there | |
344 // is a hash collision, however the chances of that happening are very low. | |
345 TEST_F(ExternalDataUseObserverTest, HashFunction) { | |
346 ExternalDataUseObserver::DataUseReportKeyHash hash; | |
347 | |
348 ExternalDataUseObserver::DataUseReportKey foo( | |
349 kFooLabel, DataUseTabModel::kDefaultTag, | |
350 net::NetworkChangeNotifier::CONNECTION_UNKNOWN, kFooMccMnc); | |
351 ExternalDataUseObserver::DataUseReportKey bar_label( | |
352 kBarLabel, DataUseTabModel::kDefaultTag, | |
353 net::NetworkChangeNotifier::CONNECTION_UNKNOWN, kFooMccMnc); | |
354 ExternalDataUseObserver::DataUseReportKey bar_custom_tab_tag( | |
355 kBarLabel, DataUseTabModel::kCustomTabTag, | |
356 net::NetworkChangeNotifier::CONNECTION_UNKNOWN, kFooMccMnc); | |
357 ExternalDataUseObserver::DataUseReportKey bar_network_type( | |
358 kFooLabel, DataUseTabModel::kDefaultTag, | |
359 net::NetworkChangeNotifier::CONNECTION_WIFI, kFooMccMnc); | |
360 ExternalDataUseObserver::DataUseReportKey bar_mcc_mnc( | |
361 kFooLabel, DataUseTabModel::kDefaultTag, | |
362 net::NetworkChangeNotifier::CONNECTION_UNKNOWN, kBarMccMnc); | |
363 | |
364 EXPECT_NE(hash(foo), hash(bar_label)); | |
365 EXPECT_NE(hash(foo), hash(bar_custom_tab_tag)); | |
366 EXPECT_NE(hash(foo), hash(bar_network_type)); | |
367 EXPECT_NE(hash(foo), hash(bar_mcc_mnc)); | |
368 } | |
369 | |
370 // Tests if matching rules are fetched periodically. | 146 // Tests if matching rules are fetched periodically. |
371 TEST_F(ExternalDataUseObserverTest, PeriodicFetchMatchingRules) { | 147 TEST_F(ExternalDataUseObserverTest, PeriodicFetchMatchingRules) { |
372 AddDefaultMatchingRule(); | 148 AddDefaultMatchingRule(); |
373 | 149 |
374 EXPECT_FALSE( | 150 EXPECT_FALSE( |
375 external_data_use_observer()->last_matching_rules_fetch_time_.is_null()); | 151 external_data_use_observer()->last_matching_rules_fetch_time_.is_null()); |
376 | 152 |
377 // Change the time when the fetching rules were fetched. | 153 // Change the time when the fetching rules were fetched. |
378 external_data_use_observer()->last_matching_rules_fetch_time_ = | 154 external_data_use_observer()->last_matching_rules_fetch_time_ = |
379 base::TimeTicks::Now() - | 155 base::TimeTicks::Now() - |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
446 ->last_matching_rules_fetch_time_.is_null()); | 222 ->last_matching_rules_fetch_time_.is_null()); |
447 base::HistogramTester histogram_tester; | 223 base::HistogramTester histogram_tester; |
448 external_data_use_observer()->data_use_tab_model_->OnNavigationEvent( | 224 external_data_use_observer()->data_use_tab_model_->OnNavigationEvent( |
449 kDefaultTabId, DataUseTabModel::TRANSITION_LINK, GURL(kDefaultURL), | 225 kDefaultTabId, DataUseTabModel::TRANSITION_LINK, GURL(kDefaultURL), |
450 std::string(), nullptr); | 226 std::string(), nullptr); |
451 base::RunLoop().RunUntilIdle(); | 227 base::RunLoop().RunUntilIdle(); |
452 histogram_tester.ExpectTotalCount("DataUsage.MatchingRulesCount.Valid", 0); | 228 histogram_tester.ExpectTotalCount("DataUsage.MatchingRulesCount.Valid", 0); |
453 } | 229 } |
454 } | 230 } |
455 | 231 |
456 // Tests if data use reports are sent only after the total bytes sent/received | |
457 // across all buffered reports have reached the specified threshold. | |
458 TEST_F(ExternalDataUseObserverTest, BufferDataUseReports) { | |
459 AddDefaultMatchingRule(); | |
460 TriggerTabTrackingOnDefaultTab(); | |
461 | |
462 // This tests reports 1024 bytes in each loop iteration. For the test to work | |
463 // properly, |data_use_report_min_bytes_| should be a multiple of 1024. | |
464 ASSERT_EQ(0, external_data_use_observer()->data_use_report_min_bytes_ % 1024); | |
465 | |
466 const size_t num_iterations = | |
467 external_data_use_observer()->data_use_report_min_bytes_ / 1024; | |
468 | |
469 for (size_t i = 0; i < num_iterations; ++i) { | |
470 data_usage::DataUse data_use = default_data_use(); | |
471 data_use.tx_bytes = 1024; | |
472 data_use.rx_bytes = 0; | |
473 OnDataUse(data_use); | |
474 | |
475 if (i != num_iterations - 1) { | |
476 // Total buffered bytes is less than the minimum threshold. Data use | |
477 // report should not be sent. | |
478 EXPECT_TRUE(external_data_use_observer() | |
479 ->last_data_report_submitted_ticks_.is_null()); | |
480 EXPECT_EQ(static_cast<int64_t>(i + 1), | |
481 external_data_use_observer()->total_bytes_buffered_ / 1024); | |
482 EXPECT_EQ(0, external_data_use_observer()->pending_report_bytes_); | |
483 | |
484 } else { | |
485 // Total bytes is at least the minimum threshold. This should trigger | |
486 // submitting of the buffered data use report. | |
487 EXPECT_FALSE(external_data_use_observer() | |
488 ->last_data_report_submitted_ticks_.is_null()); | |
489 EXPECT_EQ(0, external_data_use_observer()->total_bytes_buffered_); | |
490 } | |
491 } | |
492 EXPECT_EQ(0, external_data_use_observer()->total_bytes_buffered_); | |
493 EXPECT_EQ(static_cast<int64_t>(num_iterations), | |
494 external_data_use_observer()->pending_report_bytes_ / 1024); | |
495 | |
496 base::HistogramTester histogram_tester; | |
497 external_data_use_observer()->OnReportDataUseDone(true); | |
498 | |
499 // Verify that metrics were updated correctly for the report that was | |
500 // successfully submitted. | |
501 histogram_tester.ExpectUniqueSample( | |
502 "DataUsage.ReportSubmissionResult", | |
503 ExternalDataUseObserver::DATAUSAGE_REPORT_SUBMISSION_SUCCESSFUL, 1); | |
504 histogram_tester.ExpectUniqueSample( | |
505 "DataUsage.ReportSubmission.Bytes.Successful", | |
506 external_data_use_observer()->data_use_report_min_bytes_, 1); | |
507 histogram_tester.ExpectTotalCount(kUMAReportSubmissionDurationHistogram, 1); | |
508 | |
509 // Verify that metrics were updated correctly for the report that was not | |
510 // successfully submitted. | |
511 OnDataUse(default_data_use()); | |
512 external_data_use_observer()->OnReportDataUseDone(false); | |
513 histogram_tester.ExpectTotalCount("DataUsage.ReportSubmissionResult", 2); | |
514 histogram_tester.ExpectBucketCount( | |
515 "DataUsage.ReportSubmissionResult", | |
516 ExternalDataUseObserver::DATAUSAGE_REPORT_SUBMISSION_FAILED, 1); | |
517 histogram_tester.ExpectUniqueSample( | |
518 "DataUsage.ReportSubmission.Bytes.Failed", | |
519 external_data_use_observer()->data_use_report_min_bytes_, 1); | |
520 histogram_tester.ExpectTotalCount(kUMAReportSubmissionDurationHistogram, 2); | |
521 } | |
522 | |
523 #if defined(OS_ANDROID) | |
524 // Tests data use report submission when application status callback is called. | |
525 // Report should be submitted even if the number of bytes is less than the | |
526 // threshold. Report should not be submitted if there is a pending report. | |
527 TEST_F(ExternalDataUseObserverTest, DataUseReportingOnApplicationStatusChange) { | |
528 base::HistogramTester histogram_tester; | |
529 AddDefaultMatchingRule(); | |
530 TriggerTabTrackingOnDefaultTab(); | |
531 | |
532 // Report with less than threshold bytes should be reported, on application | |
533 // state change to background. | |
534 data_usage::DataUse data_use = default_data_use(); | |
535 data_use.tx_bytes = 1; | |
536 data_use.rx_bytes = 1; | |
537 OnDataUse(data_use); | |
538 EXPECT_TRUE(external_data_use_observer() | |
539 ->last_data_report_submitted_ticks_.is_null()); | |
540 EXPECT_EQ(2, external_data_use_observer()->total_bytes_buffered_); | |
541 EXPECT_EQ(0, external_data_use_observer()->pending_report_bytes_); | |
542 | |
543 external_data_use_observer()->OnApplicationStateChange( | |
544 base::android::APPLICATION_STATE_HAS_PAUSED_ACTIVITIES); | |
545 EXPECT_FALSE(external_data_use_observer() | |
546 ->last_data_report_submitted_ticks_.is_null()); | |
547 EXPECT_EQ(0, external_data_use_observer()->total_bytes_buffered_); | |
548 EXPECT_EQ(2, external_data_use_observer()->pending_report_bytes_); | |
549 external_data_use_observer()->OnReportDataUseDone(true); | |
550 histogram_tester.ExpectTotalCount(kUMAReportSubmissionDurationHistogram, 1); | |
551 | |
552 // Create pending report. | |
553 OnDataUse(default_data_use()); | |
554 EXPECT_FALSE(external_data_use_observer() | |
555 ->last_data_report_submitted_ticks_.is_null()); | |
556 EXPECT_EQ(0, external_data_use_observer()->total_bytes_buffered_); | |
557 EXPECT_EQ(default_upload_bytes() + default_download_bytes(), | |
558 external_data_use_observer()->pending_report_bytes_); | |
559 | |
560 // Application state change should not submit if there is a pending report. | |
561 data_use.tx_bytes = 1; | |
562 data_use.rx_bytes = 1; | |
563 OnDataUse(data_use); | |
564 external_data_use_observer()->OnApplicationStateChange( | |
565 base::android::APPLICATION_STATE_HAS_PAUSED_ACTIVITIES); | |
566 EXPECT_FALSE(external_data_use_observer() | |
567 ->last_data_report_submitted_ticks_.is_null()); | |
568 EXPECT_EQ(2, external_data_use_observer()->total_bytes_buffered_); | |
569 EXPECT_EQ(default_upload_bytes() + default_download_bytes(), | |
570 external_data_use_observer()->pending_report_bytes_); | |
571 histogram_tester.ExpectTotalCount(kUMAReportSubmissionDurationHistogram, 1); | |
572 | |
573 // Once pending report submission done callback was received, report should be | |
574 // submitted on next application state change. | |
575 external_data_use_observer()->OnReportDataUseDone(true); | |
576 external_data_use_observer()->OnApplicationStateChange( | |
577 base::android::APPLICATION_STATE_HAS_PAUSED_ACTIVITIES); | |
578 EXPECT_EQ(0, external_data_use_observer()->total_bytes_buffered_); | |
579 EXPECT_EQ(2, external_data_use_observer()->pending_report_bytes_); | |
580 histogram_tester.ExpectTotalCount(kUMAReportSubmissionDurationHistogram, 2); | |
581 } | |
582 #endif // OS_ANDROID | |
583 | |
584 // Tests if the parameters from the field trial are populated correctly. | 232 // Tests if the parameters from the field trial are populated correctly. |
585 TEST_F(ExternalDataUseObserverTest, Variations) { | 233 TEST_F(ExternalDataUseObserverTest, Variations) { |
586 std::map<std::string, std::string> variation_params; | 234 std::map<std::string, std::string> variation_params; |
587 | 235 |
588 const int kFetchMatchingRulesDurationSeconds = 10000; | 236 const int kFetchMatchingRulesDurationSeconds = 10000; |
589 const int kDefaultMaxDataReportSubmitWaitMsec = 20000; | 237 const int kDefaultMaxDataReportSubmitWaitMsec = 20000; |
590 const int64_t kDataUseReportMinBytes = 5000; | 238 const int64_t kDataUseReportMinBytes = 5000; |
591 variation_params["fetch_matching_rules_duration_seconds"] = | 239 variation_params["fetch_matching_rules_duration_seconds"] = |
592 base::Int64ToString(kFetchMatchingRulesDurationSeconds); | 240 base::Int64ToString(kFetchMatchingRulesDurationSeconds); |
593 variation_params["data_report_submit_timeout_msec"] = | 241 variation_params["data_report_submit_timeout_msec"] = |
594 base::Int64ToString(kDefaultMaxDataReportSubmitWaitMsec); | 242 base::Int64ToString(kDefaultMaxDataReportSubmitWaitMsec); |
595 variation_params["data_use_report_min_bytes"] = | 243 variation_params["data_use_report_min_bytes"] = |
596 base::Int64ToString(kDataUseReportMinBytes); | 244 base::Int64ToString(kDataUseReportMinBytes); |
597 | 245 |
598 // Create another ExternalDataUseObserver object. | 246 // Create another ExternalDataUseObserver object. |
599 ReplaceExternalDataUseObserver(variation_params); | 247 ReplaceExternalDataUseObserver(variation_params); |
600 EXPECT_EQ(base::TimeDelta::FromSeconds(kFetchMatchingRulesDurationSeconds), | 248 EXPECT_EQ(base::TimeDelta::FromSeconds(kFetchMatchingRulesDurationSeconds), |
601 external_data_use_observer()->fetch_matching_rules_duration_); | 249 external_data_use_observer()->fetch_matching_rules_duration_); |
602 EXPECT_EQ( | 250 EXPECT_EQ( |
603 base::TimeDelta::FromMilliseconds(kDefaultMaxDataReportSubmitWaitMsec), | 251 base::TimeDelta::FromMilliseconds(kDefaultMaxDataReportSubmitWaitMsec), |
604 external_data_use_observer()->data_report_submit_timeout_); | 252 external_data_use_observer() |
| 253 ->external_data_use_reporter_->data_report_submit_timeout_); |
605 EXPECT_EQ(kDataUseReportMinBytes, | 254 EXPECT_EQ(kDataUseReportMinBytes, |
606 external_data_use_observer()->data_use_report_min_bytes_); | 255 external_data_use_observer() |
607 } | 256 ->external_data_use_reporter_->data_use_report_min_bytes_); |
608 | |
609 // Tests if the metrics are recorded correctly. | |
610 TEST_F(ExternalDataUseObserverTest, DataUseReportTimedOut) { | |
611 base::HistogramTester histogram_tester; | |
612 std::map<std::string, std::string> variation_params; | |
613 variation_params["data_report_submit_timeout_msec"] = "0"; | |
614 variation_params["data_use_report_min_bytes"] = "0"; | |
615 | |
616 // Create another ExternalDataUseObserver object. | |
617 ReplaceExternalDataUseObserver(variation_params); | |
618 histogram_tester.ExpectTotalCount(kUMAMatchingRuleFirstFetchDurationHistogram, | |
619 0); | |
620 | |
621 // Trigger the control app install, and matching rules will be fetched. | |
622 external_data_use_observer() | |
623 ->GetDataUseTabModel() | |
624 ->OnControlAppInstallStateChange(true); | |
625 base::RunLoop().RunUntilIdle(); | |
626 histogram_tester.ExpectTotalCount(kUMAMatchingRuleFirstFetchDurationHistogram, | |
627 1); | |
628 | |
629 // Verify that matching rules are fetched on every navigation after the | |
630 // control app is installed, since there are no valid rules yet. | |
631 external_data_use_observer()->GetDataUseTabModel()->OnNavigationEvent( | |
632 kDefaultTabId, DataUseTabModel::TRANSITION_OMNIBOX_SEARCH, | |
633 GURL(kDefaultURL), std::string(), nullptr); | |
634 base::RunLoop().RunUntilIdle(); | |
635 histogram_tester.ExpectTotalCount(kUMAMatchingRuleFirstFetchDurationHistogram, | |
636 1); | |
637 | |
638 AddDefaultMatchingRule(); | |
639 TriggerTabTrackingOnDefaultTab(); | |
640 OnDataUse(default_data_use()); | |
641 OnDataUse(default_data_use()); | |
642 // First data use report should be marked as timed out. | |
643 histogram_tester.ExpectUniqueSample( | |
644 "DataUsage.ReportSubmissionResult", | |
645 ExternalDataUseObserver::DATAUSAGE_REPORT_SUBMISSION_TIMED_OUT, 1); | |
646 histogram_tester.ExpectUniqueSample( | |
647 "DataUsage.ReportSubmission.Bytes.TimedOut", | |
648 default_upload_bytes() + default_download_bytes(), 1); | |
649 histogram_tester.ExpectTotalCount(kUMAReportSubmissionDurationHistogram, 0); | |
650 } | 257 } |
651 | 258 |
652 } // namespace android | 259 } // namespace android |
653 | 260 |
654 } // namespace chrome | 261 } // namespace chrome |
OLD | NEW |