#include "components/cronet/host_cache_persistence_manager.h"
#include "base/test/scoped_mock_time_message_loop_task_runner.h"
#include "base/test/task_environment.h"
#include "base/values.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/testing_pref_service.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_errors.h"
#include "net/base/network_isolation_key.h"
#include "net/dns/host_cache.h"
#include "net/dns/public/dns_query_type.h"
#include "net/dns/public/host_resolver_source.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace cronet {
class HostCachePersistenceManagerTest : public testing::Test {
protected:
void SetUp() override {
cache_ = std::make_unique<net::HostCache>(1000);
pref_service_ = std::make_unique<TestingPrefServiceSimple>();
pref_service_->registry()->RegisterListPref(kPrefName);
}
void MakePersistenceManager(base::TimeDelta delay) {
persistence_manager_ = std::make_unique<HostCachePersistenceManager>(
cache_.get(), pref_service_.get(), kPrefName, delay, nullptr);
}
void WriteToCache(const std::string& host) {
net::HostCache::Key key(host, net::DnsQueryType::UNSPECIFIED, 0,
net::HostResolverSource::ANY,
net::NetworkAnonymizationKey());
net::HostCache::Entry entry(net::OK, {}, {},
net::HostCache::Entry::SOURCE_UNKNOWN);
cache_->Set(key, entry, base::TimeTicks::Now(), base::Seconds(1));
}
void CheckPref(size_t expected_size) {
const base::Value* value = pref_service_->GetUserPref(kPrefName);
net::HostCache temp_cache(10);
if (value)
temp_cache.RestoreFromListValue(value->GetList());
ASSERT_EQ(expected_size, temp_cache.size());
}
void InitializePref() {
net::HostCache temp_cache(10);
net::HostCache::Key key1("1.test", net::DnsQueryType::UNSPECIFIED, 0,
net::HostResolverSource::ANY,
net::NetworkAnonymizationKey());
net::HostCache::Key key2("2.test", net::DnsQueryType::UNSPECIFIED, 0,
net::HostResolverSource::ANY,
net::NetworkAnonymizationKey());
net::HostCache::Key key3("3.test", net::DnsQueryType::UNSPECIFIED, 0,
net::HostResolverSource::ANY,
net::NetworkAnonymizationKey());
net::HostCache::Entry entry(net::OK, {}, {},
net::HostCache::Entry::SOURCE_UNKNOWN);
temp_cache.Set(key1, entry, base::TimeTicks::Now(), base::Seconds(1));
temp_cache.Set(key2, entry, base::TimeTicks::Now(), base::Seconds(1));
temp_cache.Set(key3, entry, base::TimeTicks::Now(), base::Seconds(1));
base::Value::List list;
temp_cache.GetList(list, false ,
net::HostCache::SerializationType::kRestorable);
pref_service_->SetList(kPrefName, std::move(list));
}
static const char kPrefName[];
base::test::TaskEnvironment task_environment_;
base::ScopedMockTimeMessageLoopTaskRunner task_runner_;
std::unique_ptr<net::HostCache> cache_;
std::unique_ptr<TestingPrefServiceSimple> pref_service_;
std::unique_ptr<HostCachePersistenceManager> persistence_manager_;
};
const char HostCachePersistenceManagerTest::kPrefName[] = "net.test";
TEST_F(HostCachePersistenceManagerTest, SeparateWrites) {
MakePersistenceManager(base::Seconds(60));
WriteToCache("1.test");
task_runner_->FastForwardBy(base::Seconds(59));
CheckPref(0);
task_runner_->FastForwardBy(base::Seconds(1));
CheckPref(1);
WriteToCache("2.test");
task_runner_->FastForwardBy(base::Seconds(59));
CheckPref(1);
task_runner_->FastForwardBy(base::Seconds(1));
CheckPref(2);
}
TEST_F(HostCachePersistenceManagerTest, MultipleWrites) {
MakePersistenceManager(base::Seconds(300));
WriteToCache("1.test");
WriteToCache("2.test");
task_runner_->FastForwardBy(base::Seconds(299));
CheckPref(0);
task_runner_->FastForwardBy(base::Seconds(1));
CheckPref(2);
WriteToCache("3.test");
WriteToCache("4.test");
task_runner_->FastForwardBy(base::Seconds(299));
CheckPref(2);
task_runner_->FastForwardBy(base::Seconds(1));
CheckPref(4);
}
TEST_F(HostCachePersistenceManagerTest, BatchedWrites) {
MakePersistenceManager(base::Milliseconds(100));
WriteToCache("1.test");
task_runner_->FastForwardBy(base::Milliseconds(30));
WriteToCache("2.test");
task_runner_->FastForwardBy(base::Milliseconds(30));
WriteToCache("3.test");
CheckPref(0);
task_runner_->FastForwardBy(base::Milliseconds(40));
CheckPref(3);
task_runner_->FastForwardBy(base::Milliseconds(50));
WriteToCache("4.test");
task_runner_->FastForwardBy(base::Milliseconds(30));
WriteToCache("5.test");
task_runner_->FastForwardBy(base::Milliseconds(30));
WriteToCache("6.test");
CheckPref(3);
task_runner_->FastForwardBy(base::Milliseconds(40));
CheckPref(6);
}
TEST_F(HostCachePersistenceManagerTest, InitAfterPrefs) {
CheckPref(0);
InitializePref();
CheckPref(3);
MakePersistenceManager(base::Seconds(1));
task_runner_->RunUntilIdle();
ASSERT_EQ(3u, cache_->size());
}
TEST_F(HostCachePersistenceManagerTest, InitBeforePrefs) {
MakePersistenceManager(base::Seconds(1));
ASSERT_EQ(0u, cache_->size());
CheckPref(0);
InitializePref();
CheckPref(3);
ASSERT_EQ(3u, cache_->size());
}
}