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_garbage_collector.h"
6
7 #include <string>
8
9 #include "base/test/simple_test_tick_clock.h"
10 #include "base/time/time.h"
11 #include "base/timer/mock_timer.h"
12 #include "net/base/isolation_info.h"
13 #include "net/base/network_anonymization_key.h"
14 #include "net/reporting/reporting_cache.h"
15 #include "net/reporting/reporting_policy.h"
16 #include "net/reporting/reporting_report.h"
17 #include "net/reporting/reporting_test_util.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19 #include "third_party/abseil-cpp/absl/types/optional.h"
20
21 namespace net {
22 namespace {
23
24 class ReportingGarbageCollectorTest : public ReportingTestBase {
25 protected:
report_count()26 size_t report_count() {
27 std::vector<const ReportingReport*> reports;
28 cache()->GetReports(&reports);
29 return reports.size();
30 }
31
32 const absl::optional<base::UnguessableToken> kReportingSource_ =
33 base::UnguessableToken::Create();
34 const NetworkAnonymizationKey kNik_;
35 const IsolationInfo kIsolationInfo_;
36 const GURL kUrl_ = GURL("https://origin/path");
37 const std::string kUserAgent_ = "Mozilla/1.0";
38 const std::string kGroup_ = "group";
39 const std::string kType_ = "default";
40 };
41
42 // Make sure the garbage collector is actually present in the context.
TEST_F(ReportingGarbageCollectorTest,Created)43 TEST_F(ReportingGarbageCollectorTest, Created) {
44 EXPECT_NE(nullptr, garbage_collector());
45 }
46
47 // Make sure that the garbage collection timer is started and stopped correctly.
TEST_F(ReportingGarbageCollectorTest,Timer)48 TEST_F(ReportingGarbageCollectorTest, Timer) {
49 EXPECT_FALSE(garbage_collection_timer()->IsRunning());
50
51 cache()->AddReport(absl::nullopt, kNik_, kUrl_, kUserAgent_, kGroup_, kType_,
52 base::Value::Dict(), 0, tick_clock()->NowTicks(), 0);
53
54 EXPECT_TRUE(garbage_collection_timer()->IsRunning());
55
56 garbage_collection_timer()->Fire();
57
58 EXPECT_FALSE(garbage_collection_timer()->IsRunning());
59 }
60
TEST_F(ReportingGarbageCollectorTest,Report)61 TEST_F(ReportingGarbageCollectorTest, Report) {
62 cache()->AddReport(absl::nullopt, kNik_, kUrl_, kUserAgent_, kGroup_, kType_,
63 base::Value::Dict(), 0, tick_clock()->NowTicks(), 0);
64 garbage_collection_timer()->Fire();
65
66 EXPECT_EQ(1u, report_count());
67 }
68
TEST_F(ReportingGarbageCollectorTest,ExpiredReport)69 TEST_F(ReportingGarbageCollectorTest, ExpiredReport) {
70 cache()->AddReport(absl::nullopt, kNik_, kUrl_, kUserAgent_, kGroup_, kType_,
71 base::Value::Dict(), 0, tick_clock()->NowTicks(), 0);
72 tick_clock()->Advance(2 * policy().max_report_age);
73 garbage_collection_timer()->Fire();
74
75 EXPECT_EQ(0u, report_count());
76 }
77
TEST_F(ReportingGarbageCollectorTest,FailedReport)78 TEST_F(ReportingGarbageCollectorTest, FailedReport) {
79 cache()->AddReport(absl::nullopt, kNik_, kUrl_, kUserAgent_, kGroup_, kType_,
80 base::Value::Dict(), 0, tick_clock()->NowTicks(), 0);
81
82 std::vector<const ReportingReport*> reports;
83 cache()->GetReports(&reports);
84 for (int i = 0; i < policy().max_report_attempts; i++) {
85 cache()->IncrementReportsAttempts(reports);
86 }
87
88 garbage_collection_timer()->Fire();
89
90 EXPECT_EQ(0u, report_count());
91 }
92
TEST_F(ReportingGarbageCollectorTest,ExpiredSource)93 TEST_F(ReportingGarbageCollectorTest, ExpiredSource) {
94 ReportingEndpointGroupKey group_key(kNik_, kReportingSource_,
95 url::Origin::Create(kUrl_), kGroup_);
96 cache()->SetV1EndpointForTesting(group_key, *kReportingSource_,
97 kIsolationInfo_, kUrl_);
98
99 // Mark the source as expired. The source should be removed as soon as
100 // garbage collection runs, as there are no queued reports for it.
101 cache()->SetExpiredSource(*kReportingSource_);
102
103 // Before garbage collection, the endpoint should still exist.
104 EXPECT_EQ(1u, cache()->GetReportingSourceCountForTesting());
105 EXPECT_TRUE(cache()->GetV1EndpointForTesting(*kReportingSource_, kGroup_));
106
107 // Fire garbage collection. The endpoint configuration should be removed.
108 garbage_collection_timer()->Fire();
109 EXPECT_EQ(0u, cache()->GetReportingSourceCountForTesting());
110 EXPECT_FALSE(cache()->GetV1EndpointForTesting(*kReportingSource_, kGroup_));
111 }
112
TEST_F(ReportingGarbageCollectorTest,ExpiredSourceWithPendingReports)113 TEST_F(ReportingGarbageCollectorTest, ExpiredSourceWithPendingReports) {
114 ReportingEndpointGroupKey group_key(kNik_, kReportingSource_,
115 url::Origin::Create(kUrl_), kGroup_);
116 cache()->SetV1EndpointForTesting(group_key, *kReportingSource_,
117 kIsolationInfo_, kUrl_);
118 cache()->AddReport(kReportingSource_, kNik_, kUrl_, kUserAgent_, kGroup_,
119 kType_, base::Value::Dict(), 0, tick_clock()->NowTicks(),
120 0);
121 // Mark the source as expired. The source data should be removed as soon as
122 // all reports are delivered.
123 cache()->SetExpiredSource(*kReportingSource_);
124
125 // Even though expired, GC should not delete the source as there is still a
126 // queued report.
127 garbage_collection_timer()->Fire();
128 EXPECT_EQ(1u, report_count());
129 EXPECT_EQ(1u, cache()->GetReportingSourceCountForTesting());
130 EXPECT_TRUE(cache()->GetV1EndpointForTesting(*kReportingSource_, kGroup_));
131
132 // Deliver report.
133 std::vector<const ReportingReport*> reports;
134 cache()->GetReports(&reports);
135 cache()->RemoveReports(reports);
136 EXPECT_EQ(0u, report_count());
137
138 // Fire garbage collection again. The endpoint configuration should be
139 // removed.
140 garbage_collection_timer()->Fire();
141 EXPECT_EQ(0u, cache()->GetReportingSourceCountForTesting());
142 EXPECT_FALSE(cache()->GetV1EndpointForTesting(*kReportingSource_, kGroup_));
143 }
144
145 } // namespace
146 } // namespace net
147