#include "chrome/browser/browsing_data/counters/cache_counter.h"
#include <memory>
#include "base/functional/bind.h"
#include "base/test/test_future.h"
#include "build/build_config.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/browsing_data/core/browsing_data_utils.h"
#include "components/browsing_data/core/counters/browsing_data_counter.h"
#include "components/browsing_data/core/pref_names.h"
#include "components/prefs/pref_service.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/simple_url_loader_test_helper.h"
#include "net/test/embedded_test_server/default_handlers.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "services/network/public/cpp/resource_request.h"
#include "services/network/public/cpp/simple_url_loader.h"
#include "services/network/public/mojom/clear_data_filter.mojom.h"
#include "services/network/public/mojom/network_context.mojom.h"
using content::BrowserContext;
using content::BrowserThread;
namespace {
typedef base::test::TestFuture<
std::unique_ptr<browsing_data::BrowsingDataCounter::Result>>
CounterFuture;
class CacheCounterTest : public InProcessBrowserTest {
public:
CacheCounterTest() = default;
void SetUpOnMainThread() override {
SetCacheDeletionPref(true);
SetDeletionPeriodPref(browsing_data::TimePeriod::ALL_TIME);
ASSERT_TRUE(embedded_test_server()->InitializeAndListen());
net::test_server::RegisterDefaultHandlers(embedded_test_server());
embedded_test_server()->StartAcceptingConnections();
}
void SetCacheDeletionPref(bool value) {
browser()->profile()->GetPrefs()->SetBoolean(
browsing_data::prefs::kDeleteCache, value);
}
void SetDeletionPeriodPref(browsing_data::TimePeriod period) {
browser()->profile()->GetPrefs()->SetInteger(
browsing_data::prefs::kDeleteTimePeriod, static_cast<int>(period));
}
void CreateCacheEntry() {
std::unique_ptr<network::ResourceRequest> request =
std::make_unique<network::ResourceRequest>();
request->url = embedded_test_server()->GetURL("/cachetime/yay");
url::Origin origin =
url::Origin::Create(embedded_test_server()->base_url());
request->trusted_params = network::ResourceRequest::TrustedParams();
request->trusted_params->isolation_info =
net::IsolationInfo::CreateForInternalRequest(origin);
request->site_for_cookies =
request->trusted_params->isolation_info.site_for_cookies();
content::SimpleURLLoaderTestHelper simple_loader_helper;
std::unique_ptr<network::SimpleURLLoader> simple_loader =
network::SimpleURLLoader::Create(std::move(request),
TRAFFIC_ANNOTATION_FOR_TESTS);
simple_loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
browser()
->profile()
->GetDefaultStoragePartition()
->GetURLLoaderFactoryForBrowserProcess()
.get(),
simple_loader_helper.GetCallback());
simple_loader_helper.WaitForCallback();
}
protected:
CounterFuture future;
};
int64_t WaitForCountingResultAndReturnCacheSize(CounterFuture& future) {
std::unique_ptr<browsing_data::BrowsingDataCounter::Result> result =
future.Take();
while (!result->Finished()) {
future.Clear();
result = future.Take();
}
CacheCounter::CacheResult* finished_result =
static_cast<CacheCounter::CacheResult*>(result.get());
return finished_result->cache_size();
}
void WaitForCountingResult(CounterFuture& future) {
std::unique_ptr<browsing_data::BrowsingDataCounter::Result> result =
future.Take();
while (!result->Finished()) {
future.Clear();
result = future.Take();
}
}
IN_PROC_BROWSER_TEST_F(CacheCounterTest, Empty) {
base::test::TestFuture<void> clean_cache_future;
Profile* profile = browser()->profile();
browser()
->profile()
->GetDefaultStoragePartition()
->GetNetworkContext()
->ClearHttpCache(base::Time(), base::Time::Max(), nullptr,
clean_cache_future.GetRepeatingCallback());
int64_t result_cache_size;
while (true) {
CacheCounter counter(profile);
counter.Init(profile->GetPrefs(),
browsing_data::ClearBrowsingDataTab::ADVANCED,
future.GetRepeatingCallback());
counter.Restart();
result_cache_size = WaitForCountingResultAndReturnCacheSize(future);
if (result_cache_size == 0u) {
break;
}
base::PlatformThread::Sleep(base::Milliseconds(100));
}
EXPECT_EQ(0u, result_cache_size);
}
IN_PROC_BROWSER_TEST_F(CacheCounterTest, NonEmpty) {
CreateCacheEntry();
Profile* profile = browser()->profile();
CacheCounter counter(profile);
counter.Init(profile->GetPrefs(),
browsing_data::ClearBrowsingDataTab::ADVANCED,
future.GetRepeatingCallback());
counter.Restart();
EXPECT_NE(0u, WaitForCountingResultAndReturnCacheSize(future));
}
IN_PROC_BROWSER_TEST_F(CacheCounterTest, AfterDoom) {
base::test::TestFuture<void> clean_cache_future;
CreateCacheEntry();
Profile* profile = browser()->profile();
CacheCounter counter(profile);
counter.Init(profile->GetPrefs(),
browsing_data::ClearBrowsingDataTab::ADVANCED,
future.GetRepeatingCallback());
browser()
->profile()
->GetDefaultStoragePartition()
->GetNetworkContext()
->ClearHttpCache(
base::Time(), base::Time::Max(), nullptr,
base::BindOnce(&CacheCounter::Restart, base::Unretained(&counter)));
EXPECT_EQ(0u, WaitForCountingResultAndReturnCacheSize(future));
}
IN_PROC_BROWSER_TEST_F(CacheCounterTest, PrefChanged) {
SetCacheDeletionPref(false);
Profile* profile = browser()->profile();
CacheCounter counter(profile);
counter.Init(profile->GetPrefs(),
browsing_data::ClearBrowsingDataTab::ADVANCED,
future.GetRepeatingCallback());
SetCacheDeletionPref(true);
ASSERT_TRUE(future.Wait()) << "Init did not call back";
}
IN_PROC_BROWSER_TEST_F(CacheCounterTest, PeriodChanged) {
CreateCacheEntry();
Profile* profile = browser()->profile();
CacheCounter counter(profile);
counter.Init(profile->GetPrefs(),
browsing_data::ClearBrowsingDataTab::ADVANCED,
future.GetRepeatingCallback());
SetDeletionPeriodPref(browsing_data::TimePeriod::LAST_HOUR);
WaitForCountingResult(future);
SetDeletionPeriodPref(browsing_data::TimePeriod::LAST_DAY);
WaitForCountingResult(future);
SetDeletionPeriodPref(browsing_data::TimePeriod::LAST_WEEK);
WaitForCountingResult(future);
SetDeletionPeriodPref(browsing_data::TimePeriod::FOUR_WEEKS);
WaitForCountingResult(future);
SetDeletionPeriodPref(browsing_data::TimePeriod::ALL_TIME);
WaitForCountingResult(future);
}
}