• 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 #ifndef NET_REPORTING_REPORTING_TEST_UTIL_H_
6 #define NET_REPORTING_REPORTING_TEST_UTIL_H_
7 
8 #include <memory>
9 #include <optional>
10 #include <set>
11 #include <string>
12 #include <vector>
13 
14 #include "base/memory/raw_ptr.h"
15 #include "base/test/simple_test_clock.h"
16 #include "base/test/simple_test_tick_clock.h"
17 #include "base/unguessable_token.h"
18 #include "net/base/network_anonymization_key.h"
19 #include "net/base/rand_callback.h"
20 #include "net/reporting/reporting_cache.h"
21 #include "net/reporting/reporting_context.h"
22 #include "net/reporting/reporting_delegate.h"
23 #include "net/reporting/reporting_service.h"
24 #include "net/reporting/reporting_target_type.h"
25 #include "net/reporting/reporting_uploader.h"
26 #include "net/test/test_with_task_environment.h"
27 #include "testing/gmock/include/gmock/gmock.h"
28 #include "testing/gtest/include/gtest/gtest.h"
29 #include "url/gurl.h"
30 
31 namespace base {
32 class MockOneShotTimer;
33 class SimpleTestClock;
34 class SimpleTestTickClock;
35 class Value;
36 }  // namespace base
37 
38 namespace url {
39 class Origin;
40 }  // namespace url
41 
42 namespace net {
43 
44 class IsolationInfo;
45 struct ReportingEndpoint;
46 class ReportingGarbageCollector;
47 
48 // A matcher for ReportingReports, which checks that the url of the report is
49 // the given url.
50 // Usage: EXPECT_THAT(report, ReportUrlIs(url));
51 // EXPECT_THAT(reports(),
52 //             testing::ElementsAre(ReportUrlIs(url1), ReportUrlIs(url2)));
53 MATCHER_P(ReportUrlIs, url, "") {
54   return arg.url == url;
55 }
56 
57 RandIntCallback TestReportingRandIntCallback();
58 
59 // A test implementation of ReportingUploader that holds uploads for tests to
60 // examine and complete with a specified outcome.
61 class TestReportingUploader : public ReportingUploader {
62  public:
63   class PendingUpload {
64    public:
65     virtual ~PendingUpload();
66 
67     virtual const url::Origin& report_origin() const = 0;
68     virtual const GURL& url() const = 0;
69     virtual const std::string& json() const = 0;
70     virtual std::optional<base::Value> GetValue() const = 0;
71 
72     virtual void Complete(Outcome outcome) = 0;
73 
74    protected:
75     PendingUpload();
76   };
77 
78   TestReportingUploader();
79 
80   TestReportingUploader(const TestReportingUploader&) = delete;
81   TestReportingUploader& operator=(const TestReportingUploader&) = delete;
82 
83   ~TestReportingUploader() override;
84 
pending_uploads()85   const std::vector<std::unique_ptr<PendingUpload>>& pending_uploads() const {
86     return pending_uploads_;
87   }
88 
89   // ReportingUploader implementation:
90 
91   void StartUpload(const url::Origin& report_origin,
92                    const GURL& url,
93                    const IsolationInfo& isolation_info,
94                    const std::string& json,
95                    int max_depth,
96                    bool eligible_for_credentials,
97                    UploadCallback callback) override;
98 
99   void OnShutdown() override;
100 
101   int GetPendingUploadCountForTesting() const override;
102 
103  private:
104   std::vector<std::unique_ptr<PendingUpload>> pending_uploads_;
105 };
106 
107 // Allows all permissions unless set_disallow_report_uploads is called; uses
108 // the real ReportingDelegate for JSON parsing to exercise depth and size
109 // limits.
110 class TestReportingDelegate : public ReportingDelegate {
111  public:
112   TestReportingDelegate();
113 
114   TestReportingDelegate(const TestReportingDelegate&) = delete;
115   TestReportingDelegate& operator=(const TestReportingDelegate&) = delete;
116 
117   // ReportingDelegate implementation:
118 
119   ~TestReportingDelegate() override;
120 
set_disallow_report_uploads(bool disallow_report_uploads)121   void set_disallow_report_uploads(bool disallow_report_uploads) {
122     disallow_report_uploads_ = disallow_report_uploads;
123   }
124 
set_pause_permissions_check(bool pause_permissions_check)125   void set_pause_permissions_check(bool pause_permissions_check) {
126     pause_permissions_check_ = pause_permissions_check;
127   }
128 
129   bool CanQueueReport(const url::Origin& origin) const override;
130 
131   void CanSendReports(std::set<url::Origin> origins,
132                       base::OnceCallback<void(std::set<url::Origin>)>
133                           result_callback) const override;
134 
135   bool PermissionsCheckPaused() const;
136   void ResumePermissionsCheck();
137 
138   bool CanSetClient(const url::Origin& origin,
139                     const GURL& endpoint) const override;
140 
141   bool CanUseClient(const url::Origin& origin,
142                     const GURL& endpoint) const override;
143 
144  private:
145   bool disallow_report_uploads_ = false;
146   bool pause_permissions_check_ = false;
147 
148   mutable std::set<url::Origin> saved_origins_;
149   mutable base::OnceCallback<void(std::set<url::Origin>)>
150       permissions_check_callback_;
151 };
152 
153 // A test implementation of ReportingContext that uses test versions of
154 // Clock, TickClock, Timer, and ReportingUploader.
155 class TestReportingContext : public ReportingContext {
156  public:
157   TestReportingContext(
158       base::Clock* clock,
159       const base::TickClock* tick_clock,
160       const ReportingPolicy& policy,
161       ReportingCache::PersistentReportingStore* store = nullptr,
162       const base::flat_map<std::string, GURL>& enterprise_reporting_endpoints =
163           {});
164 
165   TestReportingContext(const TestReportingContext&) = delete;
166   TestReportingContext& operator=(const TestReportingContext&) = delete;
167 
168   ~TestReportingContext() override;
169 
test_delivery_timer()170   base::MockOneShotTimer* test_delivery_timer() { return delivery_timer_; }
test_garbage_collection_timer()171   base::MockOneShotTimer* test_garbage_collection_timer() {
172     return garbage_collection_timer_;
173   }
test_uploader()174   TestReportingUploader* test_uploader() {
175     return reinterpret_cast<TestReportingUploader*>(uploader());
176   }
test_delegate()177   TestReportingDelegate* test_delegate() {
178     return reinterpret_cast<TestReportingDelegate*>(delegate());
179   }
180 
181  private:
182   // Owned by the DeliveryAgent and GarbageCollector, respectively, but
183   // referenced here to preserve type:
184 
185   raw_ptr<base::MockOneShotTimer> delivery_timer_;
186   raw_ptr<base::MockOneShotTimer> garbage_collection_timer_;
187 };
188 
189 // A unit test base class that provides a TestReportingContext and shorthand
190 // getters.
191 class ReportingTestBase : public TestWithTaskEnvironment {
192  public:
193   ReportingTestBase(const ReportingTestBase&) = delete;
194   ReportingTestBase& operator=(const ReportingTestBase&) = delete;
195 
196  protected:
197   ReportingTestBase();
198   ~ReportingTestBase() override;
199 
200   void UsePolicy(const ReportingPolicy& policy);
201   void UseStore(
202       std::unique_ptr<ReportingCache::PersistentReportingStore> store);
203 
204   // Finds a particular endpoint in the cache and returns it (or an invalid
205   // ReportingEndpoint, if not found).
206   const ReportingEndpoint FindEndpointInCache(
207       const ReportingEndpointGroupKey& group_key,
208       const GURL& url);
209 
210   // Sets an endpoint with the given properties in a group with the given
211   // properties, bypassing header parsing. Note that the endpoint is not
212   // guaranteed to exist in the cache after calling this function, if endpoint
213   // eviction is triggered. Returns whether the endpoint was successfully set.
214   bool SetEndpointInCache(
215       const ReportingEndpointGroupKey& group_key,
216       const GURL& url,
217       base::Time expires,
218       OriginSubdomains include_subdomains = OriginSubdomains::DEFAULT,
219       int priority = ReportingEndpoint::EndpointInfo::kDefaultPriority,
220       int weight = ReportingEndpoint::EndpointInfo::kDefaultWeight);
221 
222   // Sets an endpoint with the given group_key and url as origin in the document
223   // endpoints map using |reporting_source| as key.
224   void SetV1EndpointInCache(const ReportingEndpointGroupKey& group_key,
225                             const base::UnguessableToken& reporting_source,
226                             const IsolationInfo& isolation_info,
227                             const GURL& url);
228 
229   // Sets an enterprise endpoint with the given group_key and url as origin in
230   // the enterprise endpoints vector.
231   void SetEnterpriseEndpointInCache(const ReportingEndpointGroupKey& group_key,
232                                     const GURL& url);
233 
234   // Returns whether an endpoint with the given properties exists in the cache.
235   bool EndpointExistsInCache(const ReportingEndpointGroupKey& group_key,
236                              const GURL& url);
237 
238   // Gets the statistics for a given endpoint, if it exists.
239   ReportingEndpoint::Statistics GetEndpointStatistics(
240       const ReportingEndpointGroupKey& group_key,
241       const GURL& url);
242 
243   // Returns whether an endpoint group with exactly the given properties exists
244   // in the cache. |expires| can be omitted, in which case it will not be
245   // checked.
246   bool EndpointGroupExistsInCache(const ReportingEndpointGroupKey& group_key,
247                                   OriginSubdomains include_subdomains,
248                                   base::Time expires = base::Time());
249 
250   // Returns whether a client for the given origin exists in the cache.
251   bool ClientExistsInCacheForOrigin(const url::Origin& origin);
252 
253   // Makes a unique URL with the provided index.
254   GURL MakeURL(size_t index);
255 
256   // Simulates an embedder restart, preserving the ReportingPolicy.
257   //
258   // Advances the Clock by |delta|, and the TickClock by |delta_ticks|. Both can
259   // be zero or negative.
260   void SimulateRestart(base::TimeDelta delta, base::TimeDelta delta_ticks);
261 
context()262   TestReportingContext* context() { return context_.get(); }
263 
policy()264   const ReportingPolicy& policy() { return context_->policy(); }
265 
clock()266   base::SimpleTestClock* clock() { return &clock_; }
tick_clock()267   base::SimpleTestTickClock* tick_clock() { return &tick_clock_; }
delivery_timer()268   base::MockOneShotTimer* delivery_timer() {
269     return context_->test_delivery_timer();
270   }
garbage_collection_timer()271   base::MockOneShotTimer* garbage_collection_timer() {
272     return context_->test_garbage_collection_timer();
273   }
uploader()274   TestReportingUploader* uploader() { return context_->test_uploader(); }
275 
cache()276   ReportingCache* cache() { return context_->cache(); }
delivery_agent()277   ReportingDeliveryAgent* delivery_agent() {
278     return context_->delivery_agent();
279   }
garbage_collector()280   ReportingGarbageCollector* garbage_collector() {
281     return context_->garbage_collector();
282   }
store()283   ReportingCache::PersistentReportingStore* store() { return store_.get(); }
284 
285   base::TimeTicks yesterday();
286   base::TimeTicks now();
287   base::TimeTicks tomorrow();
288 
289   const std::vector<std::unique_ptr<TestReportingUploader::PendingUpload>>&
pending_uploads()290   pending_uploads() {
291     return uploader()->pending_uploads();
292   }
293 
294  private:
295   void CreateContext(const ReportingPolicy& policy,
296                      base::Time now,
297                      base::TimeTicks now_ticks);
298 
299   base::SimpleTestClock clock_;
300   base::SimpleTestTickClock tick_clock_;
301   std::unique_ptr<ReportingCache::PersistentReportingStore> store_;
302   std::unique_ptr<TestReportingContext> context_;
303 };
304 
305 class TestReportingService : public ReportingService {
306  public:
307   struct Report {
308     Report();
309 
310     Report(const Report&) = delete;
311 
312     Report(Report&& other);
313 
314     Report(const GURL& url,
315            const NetworkAnonymizationKey& network_anonymization_key,
316            const std::string& user_agent,
317            const std::string& group,
318            const std::string& type,
319            std::unique_ptr<const base::Value> body,
320            int depth);
321 
322     ~Report();
323 
324     GURL url;
325     NetworkAnonymizationKey network_anonymization_key;
326     std::string user_agent;
327     std::string group;
328     std::string type;
329     std::unique_ptr<const base::Value> body;
330     int depth;
331   };
332 
333   TestReportingService();
334 
335   TestReportingService(const TestReportingService&) = delete;
336   TestReportingService& operator=(const TestReportingService&) = delete;
337 
reports()338   const std::vector<Report>& reports() const { return reports_; }
339 
340   // ReportingService implementation:
341 
342   ~TestReportingService() override;
343 
SetDocumentReportingEndpoints(const base::UnguessableToken & reporting_source,const url::Origin & origin,const IsolationInfo & isolation_info,const base::flat_map<std::string,std::string> & endpoints)344   void SetDocumentReportingEndpoints(
345       const base::UnguessableToken& reporting_source,
346       const url::Origin& origin,
347       const IsolationInfo& isolation_info,
348       const base::flat_map<std::string, std::string>& endpoints) override {}
349 
SetEnterpriseReportingEndpoints(const base::flat_map<std::string,GURL> & endpoints)350   void SetEnterpriseReportingEndpoints(
351       const base::flat_map<std::string, GURL>& endpoints) override {}
352 
SendReportsAndRemoveSource(const base::UnguessableToken & reporting_source)353   void SendReportsAndRemoveSource(
354       const base::UnguessableToken& reporting_source) override {}
355 
356   void QueueReport(
357       const GURL& url,
358       const std::optional<base::UnguessableToken>& reporting_source,
359       const NetworkAnonymizationKey& network_anonymization_key,
360       const std::string& user_agent,
361       const std::string& group,
362       const std::string& type,
363       base::Value::Dict body,
364       int depth,
365       ReportingTargetType target_type) override;
366 
367   void ProcessReportToHeader(
368       const url::Origin& url,
369       const NetworkAnonymizationKey& network_anonymization_key,
370       const std::string& header_value) override;
371 
372   void RemoveBrowsingData(
373       uint64_t data_type_mask,
374       const base::RepeatingCallback<bool(const url::Origin&)>& origin_filter)
375       override;
376 
377   void RemoveAllBrowsingData(uint64_t data_type_mask) override;
378 
379   void OnShutdown() override;
380 
381   const ReportingPolicy& GetPolicy() const override;
382 
383   ReportingContext* GetContextForTesting() const override;
384 
385   std::vector<raw_ptr<const ReportingReport, VectorExperimental>> GetReports()
386       const override;
387   base::flat_map<url::Origin, std::vector<ReportingEndpoint>>
388   GetV1ReportingEndpointsByOrigin() const override;
389   void AddReportingCacheObserver(ReportingCacheObserver* observer) override;
390   void RemoveReportingCacheObserver(ReportingCacheObserver* observer) override;
391 
392  private:
393   std::vector<Report> reports_;
394 };
395 
396 }  // namespace net
397 
398 #endif  // NET_REPORTING_REPORTING_TEST_UTIL_H_
399