Index: components/cronet/host_cache_persistence_manager_unittest.cc |
diff --git a/components/cronet/host_cache_persistence_manager_unittest.cc b/components/cronet/host_cache_persistence_manager_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..7a8eaae86f93c5018960f29c75d5cce4b421a7be |
--- /dev/null |
+++ b/components/cronet/host_cache_persistence_manager_unittest.cc |
@@ -0,0 +1,182 @@ |
+// Copyright 2017 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "components/cronet/host_cache_persistence_manager.h" |
+ |
+#include "base/test/scoped_mock_time_message_loop_task_runner.h" |
+#include "base/test/scoped_task_environment.h" |
+#include "base/values.h" |
+#include "components/prefs/pref_registry_simple.h" |
+#include "components/prefs/testing_pref_service.h" |
+#include "net/base/net_errors.h" |
+#include "net/dns/host_cache.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+ |
+namespace cronet { |
+ |
+class HostCachePersistenceManagerTest : public testing::Test { |
+ protected: |
+ void SetUp() override { |
+ cache_ = net::HostCache::CreateDefaultCache(); |
+ pref_service_ = base::MakeUnique<TestingPrefServiceSimple>(); |
+ pref_service_->registry()->RegisterListPref(kPrefName); |
+ } |
+ |
+ void MakePersistenceManager(base::TimeDelta delay) { |
+ persistence_manager_ = base::MakeUnique<HostCachePersistenceManager>( |
+ cache_.get(), pref_service_.get(), kPrefName, delay); |
+ } |
+ |
+ // Sets an entry in the HostCache in order to trigger a pref write. The |
+ // caller is responsible for making sure this is a change that will trigger |
+ // a write, and the HostCache's interaction with its PersistenceDelegate is |
+ // assumed to work (it's tested in net/dns/host_cache_unittest.cc). |
+ void WriteToCache(const std::string& host) { |
+ net::HostCache::Key key(host, net::ADDRESS_FAMILY_UNSPECIFIED, 0); |
+ net::HostCache::Entry entry(net::OK, net::AddressList()); |
+ cache_->Set(key, entry, base::TimeTicks::Now(), |
+ base::TimeDelta::FromSeconds(1)); |
+ } |
+ |
+ // Reads the current value of the pref from the TestingPrefServiceSimple |
+ // and deserializes it into a temporary new HostCache. Only checks the size, |
+ // not the full contents, since the tests in this file are only intended |
+ // to test that writes happen when they're supposed to, not serialization |
+ // correctness. |
+ void CheckPref(uint size) { |
+ const base::Value* value = pref_service_->GetUserPref(kPrefName); |
+ base::ListValue list; |
+ if (value) |
+ list = base::ListValue(value->GetList()); |
+ net::HostCache temp_cache(10); |
+ temp_cache.RestoreFromListValue(list); |
+ ASSERT_EQ(size, temp_cache.size()); |
+ } |
+ |
+ // Generates a temporary HostCache with a few entries and uses it to |
+ // initialize the value in prefs. |
+ void InitializePref() { |
+ net::HostCache temp_cache(10); |
+ |
+ net::HostCache::Key key1("1", net::ADDRESS_FAMILY_UNSPECIFIED, 0); |
+ net::HostCache::Key key2("2", net::ADDRESS_FAMILY_UNSPECIFIED, 0); |
+ net::HostCache::Key key3("3", net::ADDRESS_FAMILY_UNSPECIFIED, 0); |
+ net::HostCache::Entry entry(net::OK, net::AddressList()); |
+ |
+ temp_cache.Set(key1, entry, base::TimeTicks::Now(), |
+ base::TimeDelta::FromSeconds(1)); |
+ temp_cache.Set(key2, entry, base::TimeTicks::Now(), |
+ base::TimeDelta::FromSeconds(1)); |
+ temp_cache.Set(key3, entry, base::TimeTicks::Now(), |
+ base::TimeDelta::FromSeconds(1)); |
+ |
+ base::ListValue value; |
+ temp_cache.GetAsListValue(&value, false); |
+ pref_service_->Set(kPrefName, value); |
+ } |
+ |
+ static const char kPrefName[]; |
+ |
+ base::test::ScopedTaskEnvironment scoped_task_environment_; |
+ base::ScopedMockTimeMessageLoopTaskRunner task_runner_; |
+ |
+ // The HostCache and PrefService have to outlive the |
+ // HostCachePersistenceManager. |
+ std::unique_ptr<net::HostCache> cache_; |
+ std::unique_ptr<TestingPrefServiceSimple> pref_service_; |
+ std::unique_ptr<HostCachePersistenceManager> persistence_manager_; |
+}; |
+ |
+const char HostCachePersistenceManagerTest::kPrefName[] = "net.test"; |
+ |
+// Make a single change to the HostCache and make sure that it's written |
+// when the timer expires. Then repeat. |
+TEST_F(HostCachePersistenceManagerTest, SeparateWrites) { |
+ MakePersistenceManager(base::TimeDelta::FromSeconds(60)); |
+ |
+ WriteToCache("1"); |
+ task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(59)); |
+ CheckPref(0); |
+ task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(1)); |
+ CheckPref(1); |
+ |
+ WriteToCache("2"); |
+ task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(59)); |
+ CheckPref(1); |
+ task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(1)); |
+ CheckPref(2); |
+} |
+ |
+// Write to the HostCache multiple times and make sure that all changes |
+// are written to prefs at the appropriate times. |
+TEST_F(HostCachePersistenceManagerTest, MultipleWrites) { |
+ MakePersistenceManager(base::TimeDelta::FromSeconds(300)); |
+ |
+ WriteToCache("1"); |
+ WriteToCache("2"); |
+ task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(299)); |
+ CheckPref(0); |
+ task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(1)); |
+ CheckPref(2); |
+ |
+ WriteToCache("3"); |
+ WriteToCache("4"); |
+ task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(299)); |
+ CheckPref(2); |
+ task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(1)); |
+ CheckPref(4); |
+} |
+ |
+// Make changes to the HostCache at different times and ensure that the writes |
+// to prefs are batched as expected. |
+TEST_F(HostCachePersistenceManagerTest, BatchedWrites) { |
+ MakePersistenceManager(base::TimeDelta::FromMilliseconds(100)); |
+ |
+ WriteToCache("1"); |
+ task_runner_->FastForwardBy(base::TimeDelta::FromMilliseconds(30)); |
+ WriteToCache("2"); |
+ task_runner_->FastForwardBy(base::TimeDelta::FromMilliseconds(30)); |
+ WriteToCache("3"); |
+ CheckPref(0); |
+ task_runner_->FastForwardBy(base::TimeDelta::FromMilliseconds(40)); |
+ CheckPref(3); |
+ |
+ // Add a delay in between batches. |
+ task_runner_->FastForwardBy(base::TimeDelta::FromMilliseconds(50)); |
+ |
+ WriteToCache("4"); |
+ task_runner_->FastForwardBy(base::TimeDelta::FromMilliseconds(30)); |
+ WriteToCache("5"); |
+ task_runner_->FastForwardBy(base::TimeDelta::FromMilliseconds(30)); |
+ WriteToCache("6"); |
+ CheckPref(3); |
+ task_runner_->FastForwardBy(base::TimeDelta::FromMilliseconds(40)); |
+ CheckPref(6); |
+} |
+ |
+// Set the pref before the HostCachePersistenceManager is created, and make |
+// sure it gets picked up by the HostCache. |
+TEST_F(HostCachePersistenceManagerTest, InitAfterPrefs) { |
+ CheckPref(0); |
+ InitializePref(); |
+ CheckPref(3); |
+ |
+ MakePersistenceManager(base::TimeDelta::FromSeconds(1)); |
+ task_runner_->RunUntilIdle(); |
+ ASSERT_EQ(3u, cache_->size()); |
+} |
+ |
+// Set the pref after the HostCachePersistenceManager is created, and make |
+// sure it gets picked up by the HostCache. |
+TEST_F(HostCachePersistenceManagerTest, InitBeforePrefs) { |
+ MakePersistenceManager(base::TimeDelta::FromSeconds(1)); |
+ ASSERT_EQ(0u, cache_->size()); |
+ |
+ CheckPref(0); |
+ InitializePref(); |
+ CheckPref(3); |
+ ASSERT_EQ(3u, cache_->size()); |
+} |
+ |
+} // namespace cronet |