• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2017 The Chromium Authors
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 "net/reporting/reporting_test_util.h"
6 
7 #include <memory>
8 #include <string>
9 #include <vector>
10 
11 #include "base/check_op.h"
12 #include "base/functional/bind.h"
13 #include "base/json/json_reader.h"
14 #include "base/memory/ptr_util.h"
15 #include "base/notreached.h"
16 #include "base/strings/stringprintf.h"
17 #include "base/test/simple_test_clock.h"
18 #include "base/test/simple_test_tick_clock.h"
19 #include "base/timer/mock_timer.h"
20 #include "net/base/isolation_info.h"
21 #include "net/base/network_anonymization_key.h"
22 #include "net/reporting/reporting_cache.h"
23 #include "net/reporting/reporting_context.h"
24 #include "net/reporting/reporting_delegate.h"
25 #include "net/reporting/reporting_delivery_agent.h"
26 #include "net/reporting/reporting_endpoint.h"
27 #include "net/reporting/reporting_garbage_collector.h"
28 #include "net/reporting/reporting_policy.h"
29 #include "net/reporting/reporting_uploader.h"
30 #include "testing/gtest/include/gtest/gtest.h"
31 #include "third_party/abseil-cpp/absl/types/optional.h"
32 #include "url/gurl.h"
33 #include "url/origin.h"
34 
35 namespace net {
36 
37 namespace {
38 
39 class PendingUploadImpl : public TestReportingUploader::PendingUpload {
40  public:
PendingUploadImpl(const url::Origin & report_origin,const GURL & url,const IsolationInfo & isolation_info,const std::string & json,ReportingUploader::UploadCallback callback,base::OnceCallback<void (PendingUpload *)> complete_callback)41   PendingUploadImpl(const url::Origin& report_origin,
42                     const GURL& url,
43                     const IsolationInfo& isolation_info,
44                     const std::string& json,
45                     ReportingUploader::UploadCallback callback,
46                     base::OnceCallback<void(PendingUpload*)> complete_callback)
47       : report_origin_(report_origin),
48         url_(url),
49         isolation_info_(isolation_info),
50         json_(json),
51         callback_(std::move(callback)),
52         complete_callback_(std::move(complete_callback)) {}
53 
54   ~PendingUploadImpl() override = default;
55 
56   // PendingUpload implementation:
report_origin() const57   const url::Origin& report_origin() const override { return report_origin_; }
url() const58   const GURL& url() const override { return url_; }
json() const59   const std::string& json() const override { return json_; }
GetValue() const60   absl::optional<base::Value> GetValue() const override {
61     return base::JSONReader::Read(json_);
62   }
63 
Complete(ReportingUploader::Outcome outcome)64   void Complete(ReportingUploader::Outcome outcome) override {
65     std::move(callback_).Run(outcome);
66     // Deletes |this|.
67     std::move(complete_callback_).Run(this);
68   }
69 
70  private:
71   url::Origin report_origin_;
72   GURL url_;
73   IsolationInfo isolation_info_;
74   std::string json_;
75   ReportingUploader::UploadCallback callback_;
76   base::OnceCallback<void(PendingUpload*)> complete_callback_;
77 };
78 
ErasePendingUpload(std::vector<std::unique_ptr<TestReportingUploader::PendingUpload>> * uploads,TestReportingUploader::PendingUpload * upload)79 void ErasePendingUpload(
80     std::vector<std::unique_ptr<TestReportingUploader::PendingUpload>>* uploads,
81     TestReportingUploader::PendingUpload* upload) {
82   for (auto it = uploads->begin(); it != uploads->end(); ++it) {
83     if (it->get() == upload) {
84       uploads->erase(it);
85       return;
86     }
87   }
88   NOTREACHED();
89 }
90 
91 }  // namespace
92 
TestReportingRandIntCallback()93 RandIntCallback TestReportingRandIntCallback() {
94   return base::BindRepeating(
95       [](int* rand_counter, int min, int max) {
96         DCHECK_LE(min, max);
97         return min + ((*rand_counter)++ % (max - min + 1));
98       },
99       base::Owned(std::make_unique<int>(0)));
100 }
101 
102 TestReportingUploader::PendingUpload::~PendingUpload() = default;
103 TestReportingUploader::PendingUpload::PendingUpload() = default;
104 
105 TestReportingUploader::TestReportingUploader() = default;
106 TestReportingUploader::~TestReportingUploader() = default;
107 
StartUpload(const url::Origin & report_origin,const GURL & url,const IsolationInfo & isolation_info,const std::string & json,int max_depth,bool eligible_for_credentials,UploadCallback callback)108 void TestReportingUploader::StartUpload(const url::Origin& report_origin,
109                                         const GURL& url,
110                                         const IsolationInfo& isolation_info,
111                                         const std::string& json,
112                                         int max_depth,
113                                         bool eligible_for_credentials,
114                                         UploadCallback callback) {
115   pending_uploads_.push_back(std::make_unique<PendingUploadImpl>(
116       report_origin, url, isolation_info, json, std::move(callback),
117       base::BindOnce(&ErasePendingUpload, &pending_uploads_)));
118 }
119 
OnShutdown()120 void TestReportingUploader::OnShutdown() {
121   pending_uploads_.clear();
122 }
123 
GetPendingUploadCountForTesting() const124 int TestReportingUploader::GetPendingUploadCountForTesting() const {
125   return pending_uploads_.size();
126 }
127 
128 TestReportingDelegate::TestReportingDelegate() = default;
129 
130 TestReportingDelegate::~TestReportingDelegate() = default;
131 
CanQueueReport(const url::Origin & origin) const132 bool TestReportingDelegate::CanQueueReport(const url::Origin& origin) const {
133   return true;
134 }
135 
CanSendReports(std::set<url::Origin> origins,base::OnceCallback<void (std::set<url::Origin>)> result_callback) const136 void TestReportingDelegate::CanSendReports(
137     std::set<url::Origin> origins,
138     base::OnceCallback<void(std::set<url::Origin>)> result_callback) const {
139   if (pause_permissions_check_) {
140     saved_origins_ = std::move(origins);
141     permissions_check_callback_ = std::move(result_callback);
142     return;
143   }
144 
145   if (disallow_report_uploads_)
146     origins.clear();
147   std::move(result_callback).Run(std::move(origins));
148 }
149 
PermissionsCheckPaused() const150 bool TestReportingDelegate::PermissionsCheckPaused() const {
151   return !permissions_check_callback_.is_null();
152 }
153 
ResumePermissionsCheck()154 void TestReportingDelegate::ResumePermissionsCheck() {
155   if (disallow_report_uploads_)
156     saved_origins_.clear();
157   std::move(permissions_check_callback_).Run(std::move(saved_origins_));
158 }
159 
CanSetClient(const url::Origin & origin,const GURL & endpoint) const160 bool TestReportingDelegate::CanSetClient(const url::Origin& origin,
161                                          const GURL& endpoint) const {
162   return true;
163 }
164 
CanUseClient(const url::Origin & origin,const GURL & endpoint) const165 bool TestReportingDelegate::CanUseClient(const url::Origin& origin,
166                                          const GURL& endpoint) const {
167   return true;
168 }
169 
TestReportingContext(base::Clock * clock,const base::TickClock * tick_clock,const ReportingPolicy & policy,ReportingCache::PersistentReportingStore * store)170 TestReportingContext::TestReportingContext(
171     base::Clock* clock,
172     const base::TickClock* tick_clock,
173     const ReportingPolicy& policy,
174     ReportingCache::PersistentReportingStore* store)
175     : ReportingContext(policy,
176                        clock,
177                        tick_clock,
178                        TestReportingRandIntCallback(),
179                        std::make_unique<TestReportingUploader>(),
180                        std::make_unique<TestReportingDelegate>(),
181                        store) {
182   auto delivery_timer = std::make_unique<base::MockOneShotTimer>();
183   delivery_timer_ = delivery_timer.get();
184   auto garbage_collection_timer = std::make_unique<base::MockOneShotTimer>();
185   garbage_collection_timer_ = garbage_collection_timer.get();
186   garbage_collector()->SetTimerForTesting(std::move(garbage_collection_timer));
187   delivery_agent()->SetTimerForTesting(std::move(delivery_timer));
188 }
189 
~TestReportingContext()190 TestReportingContext::~TestReportingContext() {
191   delivery_timer_ = nullptr;
192   garbage_collection_timer_ = nullptr;
193 }
194 
ReportingTestBase()195 ReportingTestBase::ReportingTestBase() {
196   // For tests, disable jitter.
197   ReportingPolicy policy;
198   policy.endpoint_backoff_policy.jitter_factor = 0.0;
199 
200   CreateContext(policy, base::Time::Now(), base::TimeTicks::Now());
201 }
202 
203 ReportingTestBase::~ReportingTestBase() = default;
204 
UsePolicy(const ReportingPolicy & new_policy)205 void ReportingTestBase::UsePolicy(const ReportingPolicy& new_policy) {
206   CreateContext(new_policy, clock()->Now(), tick_clock()->NowTicks());
207 }
208 
UseStore(ReportingCache::PersistentReportingStore * store)209 void ReportingTestBase::UseStore(
210     ReportingCache::PersistentReportingStore* store) {
211   store_ = store;
212   CreateContext(policy(), clock()->Now(), tick_clock()->NowTicks());
213 }
214 
FindEndpointInCache(const ReportingEndpointGroupKey & group_key,const GURL & url)215 const ReportingEndpoint ReportingTestBase::FindEndpointInCache(
216     const ReportingEndpointGroupKey& group_key,
217     const GURL& url) {
218   return cache()->GetEndpointForTesting(group_key, url);
219 }
220 
SetEndpointInCache(const ReportingEndpointGroupKey & group_key,const GURL & url,base::Time expires,OriginSubdomains include_subdomains,int priority,int weight)221 bool ReportingTestBase::SetEndpointInCache(
222     const ReportingEndpointGroupKey& group_key,
223     const GURL& url,
224     base::Time expires,
225     OriginSubdomains include_subdomains,
226     int priority,
227     int weight) {
228   cache()->SetEndpointForTesting(group_key, url, include_subdomains, expires,
229                                  priority, weight);
230   const ReportingEndpoint endpoint = FindEndpointInCache(group_key, url);
231   return endpoint.is_valid();
232 }
233 
SetV1EndpointInCache(const ReportingEndpointGroupKey & group_key,const base::UnguessableToken & reporting_source,const IsolationInfo & isolation_info,const GURL & url)234 void ReportingTestBase::SetV1EndpointInCache(
235     const ReportingEndpointGroupKey& group_key,
236     const base::UnguessableToken& reporting_source,
237     const IsolationInfo& isolation_info,
238     const GURL& url) {
239   cache()->SetV1EndpointForTesting(group_key, reporting_source, isolation_info,
240                                    url);
241 }
242 
EndpointExistsInCache(const ReportingEndpointGroupKey & group_key,const GURL & url)243 bool ReportingTestBase::EndpointExistsInCache(
244     const ReportingEndpointGroupKey& group_key,
245     const GURL& url) {
246   ReportingEndpoint endpoint = cache()->GetEndpointForTesting(group_key, url);
247   return endpoint.is_valid();
248 }
249 
GetEndpointStatistics(const ReportingEndpointGroupKey & group_key,const GURL & url)250 ReportingEndpoint::Statistics ReportingTestBase::GetEndpointStatistics(
251     const ReportingEndpointGroupKey& group_key,
252     const GURL& url) {
253   ReportingEndpoint endpoint;
254   if (group_key.IsDocumentEndpoint()) {
255     endpoint = cache()->GetV1EndpointForTesting(
256         group_key.reporting_source.value(), group_key.group_name);
257   } else {
258     endpoint = cache()->GetEndpointForTesting(group_key, url);
259   }
260   if (endpoint)
261     return endpoint.stats;
262   return ReportingEndpoint::Statistics();
263 }
264 
EndpointGroupExistsInCache(const ReportingEndpointGroupKey & group_key,OriginSubdomains include_subdomains,base::Time expires)265 bool ReportingTestBase::EndpointGroupExistsInCache(
266     const ReportingEndpointGroupKey& group_key,
267     OriginSubdomains include_subdomains,
268     base::Time expires) {
269   return cache()->EndpointGroupExistsForTesting(group_key, include_subdomains,
270                                                 expires);
271 }
272 
ClientExistsInCacheForOrigin(const url::Origin & origin)273 bool ReportingTestBase::ClientExistsInCacheForOrigin(
274     const url::Origin& origin) {
275   std::set<url::Origin> all_origins = cache()->GetAllOrigins();
276   return all_origins.find(origin) != all_origins.end();
277 }
278 
MakeURL(size_t index)279 GURL ReportingTestBase::MakeURL(size_t index) {
280   return GURL(base::StringPrintf("https://example%zd.test", index));
281 }
282 
SimulateRestart(base::TimeDelta delta,base::TimeDelta delta_ticks)283 void ReportingTestBase::SimulateRestart(base::TimeDelta delta,
284                                         base::TimeDelta delta_ticks) {
285   CreateContext(policy(), clock()->Now() + delta,
286                 tick_clock()->NowTicks() + delta_ticks);
287 }
288 
CreateContext(const ReportingPolicy & policy,base::Time now,base::TimeTicks now_ticks)289 void ReportingTestBase::CreateContext(const ReportingPolicy& policy,
290                                       base::Time now,
291                                       base::TimeTicks now_ticks) {
292   context_ = std::make_unique<TestReportingContext>(&clock_, &tick_clock_,
293                                                     policy, store_);
294   clock()->SetNow(now);
295   tick_clock()->SetNowTicks(now_ticks);
296 }
297 
yesterday()298 base::TimeTicks ReportingTestBase::yesterday() {
299   return tick_clock()->NowTicks() - base::Days(1);
300 }
301 
now()302 base::TimeTicks ReportingTestBase::now() {
303   return tick_clock()->NowTicks();
304 }
305 
tomorrow()306 base::TimeTicks ReportingTestBase::tomorrow() {
307   return tick_clock()->NowTicks() + base::Days(1);
308 }
309 
310 TestReportingService::Report::Report() = default;
311 
312 TestReportingService::Report::Report(Report&& other) = default;
313 
Report(const GURL & url,const NetworkAnonymizationKey & network_anonymization_key,const std::string & user_agent,const std::string & group,const std::string & type,std::unique_ptr<const base::Value> body,int depth)314 TestReportingService::Report::Report(
315     const GURL& url,
316     const NetworkAnonymizationKey& network_anonymization_key,
317     const std::string& user_agent,
318     const std::string& group,
319     const std::string& type,
320     std::unique_ptr<const base::Value> body,
321     int depth)
322     : url(url),
323       network_anonymization_key(network_anonymization_key),
324       user_agent(user_agent),
325       group(group),
326       type(type),
327       body(std::move(body)),
328       depth(depth) {}
329 
330 TestReportingService::Report::~Report() = default;
331 
332 TestReportingService::TestReportingService() = default;
333 
334 TestReportingService::~TestReportingService() = default;
335 
QueueReport(const GURL & url,const absl::optional<base::UnguessableToken> & reporting_source,const NetworkAnonymizationKey & network_anonymization_key,const std::string & user_agent,const std::string & group,const std::string & type,base::Value::Dict body,int depth)336 void TestReportingService::QueueReport(
337     const GURL& url,
338     const absl::optional<base::UnguessableToken>& reporting_source,
339     const NetworkAnonymizationKey& network_anonymization_key,
340     const std::string& user_agent,
341     const std::string& group,
342     const std::string& type,
343     base::Value::Dict body,
344     int depth) {
345   reports_.emplace_back(
346       Report(url, network_anonymization_key, user_agent, group, type,
347              std::make_unique<base::Value>(std::move(body)), depth));
348 }
349 
ProcessReportToHeader(const url::Origin & origin,const NetworkAnonymizationKey & network_anonymization_key,const std::string & header_value)350 void TestReportingService::ProcessReportToHeader(
351     const url::Origin& origin,
352     const NetworkAnonymizationKey& network_anonymization_key,
353     const std::string& header_value) {
354   NOTREACHED();
355 }
356 
RemoveBrowsingData(uint64_t data_type_mask,const base::RepeatingCallback<bool (const url::Origin &)> & origin_filter)357 void TestReportingService::RemoveBrowsingData(
358     uint64_t data_type_mask,
359     const base::RepeatingCallback<bool(const url::Origin&)>& origin_filter) {
360   NOTREACHED();
361 }
362 
RemoveAllBrowsingData(uint64_t data_type_mask)363 void TestReportingService::RemoveAllBrowsingData(uint64_t data_type_mask) {
364   NOTREACHED();
365 }
366 
OnShutdown()367 void TestReportingService::OnShutdown() {}
368 
GetPolicy() const369 const ReportingPolicy& TestReportingService::GetPolicy() const {
370   NOTREACHED();
371   return dummy_policy_;
372 }
373 
GetContextForTesting() const374 ReportingContext* TestReportingService::GetContextForTesting() const {
375   NOTREACHED();
376   return nullptr;
377 }
378 
GetReports() const379 std::vector<const ReportingReport*> TestReportingService::GetReports() const {
380   NOTREACHED();
381   return std::vector<const ReportingReport*>();
382 }
383 
384 base::flat_map<url::Origin, std::vector<ReportingEndpoint>>
GetV1ReportingEndpointsByOrigin() const385 TestReportingService::GetV1ReportingEndpointsByOrigin() const {
386   NOTREACHED();
387   return base::flat_map<url::Origin, std::vector<ReportingEndpoint>>();
388 }
389 
AddReportingCacheObserver(ReportingCacheObserver * observer)390 void TestReportingService::AddReportingCacheObserver(
391     ReportingCacheObserver* observer) {
392   NOTREACHED();
393 }
394 
RemoveReportingCacheObserver(ReportingCacheObserver * observer)395 void TestReportingService::RemoveReportingCacheObserver(
396     ReportingCacheObserver* observer) {
397   NOTREACHED();
398 }
399 
400 }  // namespace net
401