// Copyright 2017 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "net/reporting/reporting_garbage_collector.h" #include #include "base/test/simple_test_tick_clock.h" #include "base/time/time.h" #include "base/timer/mock_timer.h" #include "net/base/isolation_info.h" #include "net/base/network_anonymization_key.h" #include "net/reporting/reporting_cache.h" #include "net/reporting/reporting_policy.h" #include "net/reporting/reporting_report.h" #include "net/reporting/reporting_test_util.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/abseil-cpp/absl/types/optional.h" namespace net { namespace { class ReportingGarbageCollectorTest : public ReportingTestBase { protected: size_t report_count() { std::vector reports; cache()->GetReports(&reports); return reports.size(); } const absl::optional kReportingSource_ = base::UnguessableToken::Create(); const NetworkAnonymizationKey kNik_; const IsolationInfo kIsolationInfo_; const GURL kUrl_ = GURL("https://origin/path"); const std::string kUserAgent_ = "Mozilla/1.0"; const std::string kGroup_ = "group"; const std::string kType_ = "default"; }; // Make sure the garbage collector is actually present in the context. TEST_F(ReportingGarbageCollectorTest, Created) { EXPECT_NE(nullptr, garbage_collector()); } // Make sure that the garbage collection timer is started and stopped correctly. TEST_F(ReportingGarbageCollectorTest, Timer) { EXPECT_FALSE(garbage_collection_timer()->IsRunning()); cache()->AddReport(absl::nullopt, kNik_, kUrl_, kUserAgent_, kGroup_, kType_, base::Value::Dict(), 0, tick_clock()->NowTicks(), 0); EXPECT_TRUE(garbage_collection_timer()->IsRunning()); garbage_collection_timer()->Fire(); EXPECT_FALSE(garbage_collection_timer()->IsRunning()); } TEST_F(ReportingGarbageCollectorTest, Report) { cache()->AddReport(absl::nullopt, kNik_, kUrl_, kUserAgent_, kGroup_, kType_, base::Value::Dict(), 0, tick_clock()->NowTicks(), 0); garbage_collection_timer()->Fire(); EXPECT_EQ(1u, report_count()); } TEST_F(ReportingGarbageCollectorTest, ExpiredReport) { cache()->AddReport(absl::nullopt, kNik_, kUrl_, kUserAgent_, kGroup_, kType_, base::Value::Dict(), 0, tick_clock()->NowTicks(), 0); tick_clock()->Advance(2 * policy().max_report_age); garbage_collection_timer()->Fire(); EXPECT_EQ(0u, report_count()); } TEST_F(ReportingGarbageCollectorTest, FailedReport) { cache()->AddReport(absl::nullopt, kNik_, kUrl_, kUserAgent_, kGroup_, kType_, base::Value::Dict(), 0, tick_clock()->NowTicks(), 0); std::vector reports; cache()->GetReports(&reports); for (int i = 0; i < policy().max_report_attempts; i++) { cache()->IncrementReportsAttempts(reports); } garbage_collection_timer()->Fire(); EXPECT_EQ(0u, report_count()); } TEST_F(ReportingGarbageCollectorTest, ExpiredSource) { ReportingEndpointGroupKey group_key(kNik_, kReportingSource_, url::Origin::Create(kUrl_), kGroup_); cache()->SetV1EndpointForTesting(group_key, *kReportingSource_, kIsolationInfo_, kUrl_); // Mark the source as expired. The source should be removed as soon as // garbage collection runs, as there are no queued reports for it. cache()->SetExpiredSource(*kReportingSource_); // Before garbage collection, the endpoint should still exist. EXPECT_EQ(1u, cache()->GetReportingSourceCountForTesting()); EXPECT_TRUE(cache()->GetV1EndpointForTesting(*kReportingSource_, kGroup_)); // Fire garbage collection. The endpoint configuration should be removed. garbage_collection_timer()->Fire(); EXPECT_EQ(0u, cache()->GetReportingSourceCountForTesting()); EXPECT_FALSE(cache()->GetV1EndpointForTesting(*kReportingSource_, kGroup_)); } TEST_F(ReportingGarbageCollectorTest, ExpiredSourceWithPendingReports) { ReportingEndpointGroupKey group_key(kNik_, kReportingSource_, url::Origin::Create(kUrl_), kGroup_); cache()->SetV1EndpointForTesting(group_key, *kReportingSource_, kIsolationInfo_, kUrl_); cache()->AddReport(kReportingSource_, kNik_, kUrl_, kUserAgent_, kGroup_, kType_, base::Value::Dict(), 0, tick_clock()->NowTicks(), 0); // Mark the source as expired. The source data should be removed as soon as // all reports are delivered. cache()->SetExpiredSource(*kReportingSource_); // Even though expired, GC should not delete the source as there is still a // queued report. garbage_collection_timer()->Fire(); EXPECT_EQ(1u, report_count()); EXPECT_EQ(1u, cache()->GetReportingSourceCountForTesting()); EXPECT_TRUE(cache()->GetV1EndpointForTesting(*kReportingSource_, kGroup_)); // Deliver report. std::vector reports; cache()->GetReports(&reports); cache()->RemoveReports(reports); EXPECT_EQ(0u, report_count()); // Fire garbage collection again. The endpoint configuration should be // removed. garbage_collection_timer()->Fire(); EXPECT_EQ(0u, cache()->GetReportingSourceCountForTesting()); EXPECT_FALSE(cache()->GetV1EndpointForTesting(*kReportingSource_, kGroup_)); } } // namespace } // namespace net