OLD | NEW |
---|---|
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 "chrome/browser/safe_browsing/permission_reporter.h" | 5 #include "chrome/browser/safe_browsing/permission_reporter.h" |
6 | 6 |
7 #include "base/feature_list.h" | 7 #include "base/feature_list.h" |
8 #include "base/memory/ptr_util.h" | 8 #include "base/memory/ptr_util.h" |
9 #include "base/metrics/field_trial.h" | 9 #include "base/metrics/field_trial.h" |
10 #include "base/test/simple_test_clock.h" | |
11 #include "base/time/time.h" | |
10 #include "chrome/common/safe_browsing/permission_report.pb.h" | 12 #include "chrome/common/safe_browsing/permission_report.pb.h" |
11 #include "components/variations/active_field_trials.h" | 13 #include "components/variations/active_field_trials.h" |
12 #include "content/public/browser/permission_type.h" | 14 #include "content/public/browser/permission_type.h" |
13 #include "net/url_request/report_sender.h" | 15 #include "net/url_request/report_sender.h" |
14 #include "testing/gtest/include/gtest/gtest.h" | 16 #include "testing/gtest/include/gtest/gtest.h" |
15 | 17 |
16 using content::PermissionType; | 18 using content::PermissionType; |
17 | 19 |
18 namespace safe_browsing { | 20 namespace safe_browsing { |
19 | 21 |
20 namespace { | 22 namespace { |
21 | 23 |
22 // URL to upload permission action reports. | 24 // URL to upload permission action reports. |
23 const char kPermissionActionReportingUploadUrl[] = | 25 const char kPermissionActionReportingUploadUrl[] = |
24 "http://safebrowsing.googleusercontent.com/safebrowsing/clientreport/" | 26 "http://safebrowsing.googleusercontent.com/safebrowsing/clientreport/" |
25 "permission-action"; | 27 "permission-action"; |
26 | 28 |
27 const char kDummyOrigin[] = "http://example.test/"; | 29 const int kMaximumReportsPerOriginPerPermissionPerMinute = 5; |
28 const PermissionType kDummyPermission = PermissionType::GEOLOCATION; | 30 |
31 const char kDummyOriginOne[] = "http://example.test/"; | |
32 const char kDummyOriginTwo[] = "http://example2.test/"; | |
33 const PermissionType kDummyPermissionOne = PermissionType::GEOLOCATION; | |
34 const PermissionType kDummyPermissionTwo = PermissionType::NOTIFICATIONS; | |
29 const PermissionAction kDummyAction = GRANTED; | 35 const PermissionAction kDummyAction = GRANTED; |
30 const PermissionReport::PermissionType kDummyPermissionReportPermission = | |
31 PermissionReport::GEOLOCATION; | |
32 const PermissionReport::Action kDummyPermissionReportAction = | |
33 PermissionReport::GRANTED; | |
34 | 36 |
35 const char kDummyTrialOne[] = "trial one"; | 37 const char kDummyTrialOne[] = "trial one"; |
36 const char kDummyGroupOne[] = "group one"; | 38 const char kDummyGroupOne[] = "group one"; |
37 const char kDummyTrialTwo[] = "trial two"; | 39 const char kDummyTrialTwo[] = "trial two"; |
38 const char kDummyGroupTwo[] = "group two"; | 40 const char kDummyGroupTwo[] = "group two"; |
39 | 41 |
40 const char kFeatureOnByDefaultName[] = "OnByDefault"; | 42 const char kFeatureOnByDefaultName[] = "OnByDefault"; |
41 struct base::Feature kFeatureOnByDefault { | 43 struct base::Feature kFeatureOnByDefault { |
42 kFeatureOnByDefaultName, base::FEATURE_ENABLED_BY_DEFAULT | 44 kFeatureOnByDefaultName, base::FEATURE_ENABLED_BY_DEFAULT |
43 }; | 45 }; |
44 | 46 |
45 const char kFeatureOffByDefaultName[] = "OffByDefault"; | 47 const char kFeatureOffByDefaultName[] = "OffByDefault"; |
46 struct base::Feature kFeatureOffByDefault { | 48 struct base::Feature kFeatureOffByDefault { |
47 kFeatureOffByDefaultName, base::FEATURE_DISABLED_BY_DEFAULT | 49 kFeatureOffByDefaultName, base::FEATURE_DISABLED_BY_DEFAULT |
48 }; | 50 }; |
49 | 51 |
50 // A mock ReportSender that keeps track of the last report sent. | 52 // A mock ReportSender that keeps track of the last report sent. |
51 class MockReportSender : public net::ReportSender { | 53 class MockReportSender : public net::ReportSender { |
52 public: | 54 public: |
53 MockReportSender() : net::ReportSender(nullptr, DO_NOT_SEND_COOKIES) {} | 55 MockReportSender() : net::ReportSender(nullptr, DO_NOT_SEND_COOKIES) { |
56 number_of_reports_ = 0; | |
57 } | |
58 | |
54 ~MockReportSender() override {} | 59 ~MockReportSender() override {} |
55 | 60 |
56 void Send(const GURL& report_uri, const std::string& report) override { | 61 void Send(const GURL& report_uri, const std::string& report) override { |
57 latest_report_uri_ = report_uri; | 62 latest_report_uri_ = report_uri; |
58 latest_report_ = report; | 63 latest_report_ = report; |
64 number_of_reports_++; | |
59 } | 65 } |
60 | 66 |
61 const GURL& latest_report_uri() { return latest_report_uri_; } | 67 const GURL& latest_report_uri() { return latest_report_uri_; } |
62 | 68 |
63 const std::string& latest_report() { return latest_report_; } | 69 const std::string& latest_report() { return latest_report_; } |
64 | 70 |
71 int GetAndResetNumberReports() { | |
kcarattini
2016/07/06 06:28:20
How about "GetAndResetNumberOfReportsSent"?
stefanocs
2016/07/06 07:17:38
Done.
| |
72 int new_reports = number_of_reports_; | |
73 number_of_reports_ = 0; | |
74 return new_reports; | |
75 } | |
76 | |
65 private: | 77 private: |
66 GURL latest_report_uri_; | 78 GURL latest_report_uri_; |
67 std::string latest_report_; | 79 std::string latest_report_; |
80 int number_of_reports_; | |
68 | 81 |
69 DISALLOW_COPY_AND_ASSIGN(MockReportSender); | 82 DISALLOW_COPY_AND_ASSIGN(MockReportSender); |
70 }; | 83 }; |
71 | 84 |
72 } // namespace | 85 } // namespace |
73 | 86 |
74 class PermissionReporterTest : public ::testing::Test { | 87 class PermissionReporterTest : public ::testing::Test { |
75 protected: | 88 protected: |
76 PermissionReporterTest() | 89 void SetUp() override { |
77 : mock_report_sender_(new MockReportSender()), | 90 mock_report_sender_ = new MockReportSender; |
78 permission_reporter_( | 91 clock_ = new base::SimpleTestClock; |
79 new PermissionReporter(base::WrapUnique(mock_report_sender_))) {} | 92 permission_reporter_.reset(new PermissionReporter( |
93 base::WrapUnique(mock_report_sender_), base::WrapUnique(clock_))); | |
94 } | |
80 | 95 |
81 // Owned by |permission_reporter_|. | 96 // Owned by |permission_reporter_|. |
82 MockReportSender* mock_report_sender_; | 97 MockReportSender* mock_report_sender_; |
83 | 98 |
99 // Owned by |permission_reporter_|. | |
100 base::SimpleTestClock* clock_; | |
101 | |
84 std::unique_ptr<PermissionReporter> permission_reporter_; | 102 std::unique_ptr<PermissionReporter> permission_reporter_; |
85 }; | 103 }; |
86 | 104 |
87 // Test that PermissionReporter::SendReport sends a serialized report string to | 105 // Test that PermissionReporter::SendReport sends a serialized report string to |
88 // SafeBrowsing CSD servers. | 106 // SafeBrowsing CSD servers. |
89 TEST_F(PermissionReporterTest, SendReport) { | 107 TEST_F(PermissionReporterTest, SendReport) { |
90 permission_reporter_->SendReport(GURL(kDummyOrigin), kDummyPermission, | 108 permission_reporter_->SendReport(GURL(kDummyOriginOne), kDummyPermissionOne, |
91 kDummyAction); | 109 kDummyAction); |
92 | 110 |
93 PermissionReport permission_report; | 111 PermissionReport permission_report; |
94 ASSERT_TRUE( | 112 ASSERT_TRUE( |
95 permission_report.ParseFromString(mock_report_sender_->latest_report())); | 113 permission_report.ParseFromString(mock_report_sender_->latest_report())); |
96 EXPECT_EQ(kDummyPermissionReportPermission, permission_report.permission()); | 114 EXPECT_EQ(PermissionReport::GEOLOCATION, permission_report.permission()); |
97 EXPECT_EQ(kDummyPermissionReportAction, permission_report.action()); | 115 EXPECT_EQ(PermissionReport::GRANTED, permission_report.action()); |
98 EXPECT_EQ(kDummyOrigin, permission_report.origin()); | 116 EXPECT_EQ(kDummyOriginOne, permission_report.origin()); |
99 #if defined(OS_ANDROID) | 117 #if defined(OS_ANDROID) |
100 EXPECT_EQ(PermissionReport::ANDROID_PLATFORM, | 118 EXPECT_EQ(PermissionReport::ANDROID_PLATFORM, |
101 permission_report.platform_type()); | 119 permission_report.platform_type()); |
102 #elif defined(OS_MACOSX) || defined(OS_WIN) || defined(OS_CHROMEOS) || \ | 120 #elif defined(OS_MACOSX) || defined(OS_WIN) || defined(OS_CHROMEOS) || \ |
103 defined(OS_LINUX) | 121 defined(OS_LINUX) |
104 EXPECT_EQ(PermissionReport::DESKTOP_PLATFORM, | 122 EXPECT_EQ(PermissionReport::DESKTOP_PLATFORM, |
105 permission_report.platform_type()); | 123 permission_report.platform_type()); |
106 #endif | 124 #endif |
107 | 125 |
108 EXPECT_EQ(GURL(kPermissionActionReportingUploadUrl), | 126 EXPECT_EQ(GURL(kPermissionActionReportingUploadUrl), |
(...skipping 24 matching lines...) Expand all Loading... | |
133 base::FeatureList::ClearInstanceForTesting(); | 151 base::FeatureList::ClearInstanceForTesting(); |
134 base::FeatureList::SetInstance(std::move(feature_list)); | 152 base::FeatureList::SetInstance(std::move(feature_list)); |
135 | 153 |
136 // This is necessary to activate both field trials. | 154 // This is necessary to activate both field trials. |
137 base::FeatureList::IsEnabled(kFeatureOnByDefault); | 155 base::FeatureList::IsEnabled(kFeatureOnByDefault); |
138 base::FeatureList::IsEnabled(kFeatureOffByDefault); | 156 base::FeatureList::IsEnabled(kFeatureOffByDefault); |
139 | 157 |
140 EXPECT_TRUE(base::FieldTrialList::IsTrialActive(trial_one->trial_name())); | 158 EXPECT_TRUE(base::FieldTrialList::IsTrialActive(trial_one->trial_name())); |
141 EXPECT_TRUE(base::FieldTrialList::IsTrialActive(trial_two->trial_name())); | 159 EXPECT_TRUE(base::FieldTrialList::IsTrialActive(trial_two->trial_name())); |
142 | 160 |
143 permission_reporter_->SendReport(GURL(kDummyOrigin), kDummyPermission, | 161 permission_reporter_->SendReport(GURL(kDummyOriginOne), kDummyPermissionOne, |
144 kDummyAction); | 162 kDummyAction); |
145 | 163 |
146 PermissionReport permission_report; | 164 PermissionReport permission_report; |
147 ASSERT_TRUE( | 165 ASSERT_TRUE( |
148 permission_report.ParseFromString(mock_report_sender_->latest_report())); | 166 permission_report.ParseFromString(mock_report_sender_->latest_report())); |
149 | 167 |
150 variations::ActiveGroupId field_trial_one = | 168 variations::ActiveGroupId field_trial_one = |
151 variations::MakeActiveGroupId(kDummyTrialOne, kDummyGroupOne); | 169 variations::MakeActiveGroupId(kDummyTrialOne, kDummyGroupOne); |
152 variations::ActiveGroupId field_trial_two = | 170 variations::ActiveGroupId field_trial_two = |
153 variations::MakeActiveGroupId(kDummyTrialTwo, kDummyGroupTwo); | 171 variations::MakeActiveGroupId(kDummyTrialTwo, kDummyGroupTwo); |
154 ActiveGroupIdSet expected_group_ids = {field_trial_one, field_trial_two}; | 172 ActiveGroupIdSet expected_group_ids = {field_trial_one, field_trial_two}; |
155 | 173 |
156 EXPECT_EQ(2, permission_report.field_trials().size()); | 174 EXPECT_EQ(2, permission_report.field_trials().size()); |
157 for (auto field_trial : permission_report.field_trials()) { | 175 for (auto field_trial : permission_report.field_trials()) { |
158 variations::ActiveGroupId group_id = {field_trial.name_id(), | 176 variations::ActiveGroupId group_id = {field_trial.name_id(), |
159 field_trial.group_id()}; | 177 field_trial.group_id()}; |
160 EXPECT_EQ(1U, expected_group_ids.erase(group_id)); | 178 EXPECT_EQ(1U, expected_group_ids.erase(group_id)); |
161 } | 179 } |
162 EXPECT_EQ(0U, expected_group_ids.size()); | 180 EXPECT_EQ(0U, expected_group_ids.size()); |
163 } | 181 } |
164 | 182 |
183 // Test that PermissionReporter::IsAllowedToSend returns true only when the | |
184 // number of reports sent in the last one minute per origin per permission is | |
185 // under a threshold. | |
186 TEST_F(PermissionReporterTest, IsAllowedToSend) { | |
187 EXPECT_EQ(0, mock_report_sender_->GetAndResetNumberReports()); | |
188 | |
189 int reports_to_send = kMaximumReportsPerOriginPerPermissionPerMinute; | |
190 while (reports_to_send--) | |
191 permission_reporter_->SendReport(GURL(kDummyOriginOne), kDummyPermissionOne, | |
192 kDummyAction); | |
193 EXPECT_EQ(5, mock_report_sender_->GetAndResetNumberReports()); | |
194 | |
195 permission_reporter_->SendReport(GURL(kDummyOriginOne), kDummyPermissionOne, | |
196 kDummyAction); | |
197 EXPECT_EQ(0, mock_report_sender_->GetAndResetNumberReports()); | |
198 | |
199 permission_reporter_->SendReport(GURL(kDummyOriginOne), kDummyPermissionTwo, | |
200 kDummyAction); | |
201 EXPECT_EQ(1, mock_report_sender_->GetAndResetNumberReports()); | |
202 | |
203 permission_reporter_->SendReport(GURL(kDummyOriginTwo), kDummyPermissionOne, | |
204 kDummyAction); | |
205 EXPECT_EQ(1, mock_report_sender_->GetAndResetNumberReports()); | |
206 | |
207 clock_->Advance(base::TimeDelta::FromMinutes(1)); | |
208 permission_reporter_->SendReport(GURL(kDummyOriginOne), kDummyPermissionOne, | |
209 kDummyAction); | |
210 EXPECT_EQ(0, mock_report_sender_->GetAndResetNumberReports()); | |
211 | |
212 clock_->Advance(base::TimeDelta::FromMicroseconds(1)); | |
213 permission_reporter_->SendReport(GURL(kDummyOriginOne), kDummyPermissionOne, | |
214 kDummyAction); | |
215 EXPECT_EQ(1, mock_report_sender_->GetAndResetNumberReports()); | |
216 | |
217 clock_->Advance(base::TimeDelta::FromMinutes(1)); | |
218 reports_to_send = 12; | |
219 while (reports_to_send--) { | |
220 clock_->Advance(base::TimeDelta::FromSeconds(5)); | |
221 permission_reporter_->SendReport(GURL(kDummyOriginOne), kDummyPermissionOne, | |
222 kDummyAction); | |
223 } | |
224 EXPECT_EQ(kMaximumReportsPerOriginPerPermissionPerMinute, | |
225 mock_report_sender_->GetAndResetNumberReports()); | |
226 } | |
227 | |
165 } // namespace safe_browsing | 228 } // namespace safe_browsing |
OLD | NEW |