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