blob: e87ce34327059a73528c018a6d8a1561d23d7743 [file] [log] [blame]
mgersh983dbf82017-06-23 20:17:061// Copyright 2017 The Chromium Authors. All rights reserved.
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 "components/cronet/host_cache_persistence_manager.h"
6
7#include "base/test/scoped_mock_time_message_loop_task_runner.h"
8#include "base/test/scoped_task_environment.h"
9#include "base/values.h"
10#include "components/prefs/pref_registry_simple.h"
11#include "components/prefs/testing_pref_service.h"
12#include "net/base/net_errors.h"
13#include "net/dns/host_cache.h"
14#include "testing/gtest/include/gtest/gtest.h"
15
16namespace cronet {
17
18class HostCachePersistenceManagerTest : public testing::Test {
19 protected:
20 void SetUp() override {
21 cache_ = net::HostCache::CreateDefaultCache();
Lily Houghtonef028852017-12-06 20:52:3022 pref_service_ = std::make_unique<TestingPrefServiceSimple>();
mgersh983dbf82017-06-23 20:17:0623 pref_service_->registry()->RegisterListPref(kPrefName);
24 }
25
26 void MakePersistenceManager(base::TimeDelta delay) {
Lily Houghtonef028852017-12-06 20:52:3027 persistence_manager_ = std::make_unique<HostCachePersistenceManager>(
mgersh00eb7a22017-06-29 22:47:5328 cache_.get(), pref_service_.get(), kPrefName, delay, nullptr);
mgersh983dbf82017-06-23 20:17:0629 }
30
31 // Sets an entry in the HostCache in order to trigger a pref write. The
32 // caller is responsible for making sure this is a change that will trigger
33 // a write, and the HostCache's interaction with its PersistenceDelegate is
34 // assumed to work (it's tested in net/dns/host_cache_unittest.cc).
35 void WriteToCache(const std::string& host) {
36 net::HostCache::Key key(host, net::ADDRESS_FAMILY_UNSPECIFIED, 0);
Rob Percival94f21ad2017-11-14 10:20:2437 net::HostCache::Entry entry(net::OK, net::AddressList(),
38 net::HostCache::Entry::SOURCE_UNKNOWN);
mgersh983dbf82017-06-23 20:17:0639 cache_->Set(key, entry, base::TimeTicks::Now(),
40 base::TimeDelta::FromSeconds(1));
41 }
42
43 // Reads the current value of the pref from the TestingPrefServiceSimple
44 // and deserializes it into a temporary new HostCache. Only checks the size,
45 // not the full contents, since the tests in this file are only intended
46 // to test that writes happen when they're supposed to, not serialization
47 // correctness.
Wez12ce94a2018-03-27 03:42:2548 void CheckPref(size_t size) {
mgersh983dbf82017-06-23 20:17:0649 const base::Value* value = pref_service_->GetUserPref(kPrefName);
50 base::ListValue list;
51 if (value)
52 list = base::ListValue(value->GetList());
53 net::HostCache temp_cache(10);
54 temp_cache.RestoreFromListValue(list);
55 ASSERT_EQ(size, temp_cache.size());
56 }
57
58 // Generates a temporary HostCache with a few entries and uses it to
59 // initialize the value in prefs.
60 void InitializePref() {
61 net::HostCache temp_cache(10);
62
63 net::HostCache::Key key1("1", net::ADDRESS_FAMILY_UNSPECIFIED, 0);
64 net::HostCache::Key key2("2", net::ADDRESS_FAMILY_UNSPECIFIED, 0);
65 net::HostCache::Key key3("3", net::ADDRESS_FAMILY_UNSPECIFIED, 0);
Rob Percival94f21ad2017-11-14 10:20:2466 net::HostCache::Entry entry(net::OK, net::AddressList(),
67 net::HostCache::Entry::SOURCE_UNKNOWN);
mgersh983dbf82017-06-23 20:17:0668
69 temp_cache.Set(key1, entry, base::TimeTicks::Now(),
70 base::TimeDelta::FromSeconds(1));
71 temp_cache.Set(key2, entry, base::TimeTicks::Now(),
72 base::TimeDelta::FromSeconds(1));
73 temp_cache.Set(key3, entry, base::TimeTicks::Now(),
74 base::TimeDelta::FromSeconds(1));
75
76 base::ListValue value;
77 temp_cache.GetAsListValue(&value, false);
78 pref_service_->Set(kPrefName, value);
79 }
80
81 static const char kPrefName[];
82
83 base::test::ScopedTaskEnvironment scoped_task_environment_;
84 base::ScopedMockTimeMessageLoopTaskRunner task_runner_;
85
86 // The HostCache and PrefService have to outlive the
87 // HostCachePersistenceManager.
88 std::unique_ptr<net::HostCache> cache_;
89 std::unique_ptr<TestingPrefServiceSimple> pref_service_;
90 std::unique_ptr<HostCachePersistenceManager> persistence_manager_;
91};
92
93const char HostCachePersistenceManagerTest::kPrefName[] = "net.test";
94
95// Make a single change to the HostCache and make sure that it's written
96// when the timer expires. Then repeat.
97TEST_F(HostCachePersistenceManagerTest, SeparateWrites) {
98 MakePersistenceManager(base::TimeDelta::FromSeconds(60));
99
100 WriteToCache("1");
101 task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(59));
102 CheckPref(0);
103 task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(1));
104 CheckPref(1);
105
106 WriteToCache("2");
107 task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(59));
108 CheckPref(1);
109 task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(1));
110 CheckPref(2);
111}
112
113// Write to the HostCache multiple times and make sure that all changes
114// are written to prefs at the appropriate times.
115TEST_F(HostCachePersistenceManagerTest, MultipleWrites) {
116 MakePersistenceManager(base::TimeDelta::FromSeconds(300));
117
118 WriteToCache("1");
119 WriteToCache("2");
120 task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(299));
121 CheckPref(0);
122 task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(1));
123 CheckPref(2);
124
125 WriteToCache("3");
126 WriteToCache("4");
127 task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(299));
128 CheckPref(2);
129 task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(1));
130 CheckPref(4);
131}
132
133// Make changes to the HostCache at different times and ensure that the writes
134// to prefs are batched as expected.
135TEST_F(HostCachePersistenceManagerTest, BatchedWrites) {
136 MakePersistenceManager(base::TimeDelta::FromMilliseconds(100));
137
138 WriteToCache("1");
139 task_runner_->FastForwardBy(base::TimeDelta::FromMilliseconds(30));
140 WriteToCache("2");
141 task_runner_->FastForwardBy(base::TimeDelta::FromMilliseconds(30));
142 WriteToCache("3");
143 CheckPref(0);
144 task_runner_->FastForwardBy(base::TimeDelta::FromMilliseconds(40));
145 CheckPref(3);
146
147 // Add a delay in between batches.
148 task_runner_->FastForwardBy(base::TimeDelta::FromMilliseconds(50));
149
150 WriteToCache("4");
151 task_runner_->FastForwardBy(base::TimeDelta::FromMilliseconds(30));
152 WriteToCache("5");
153 task_runner_->FastForwardBy(base::TimeDelta::FromMilliseconds(30));
154 WriteToCache("6");
155 CheckPref(3);
156 task_runner_->FastForwardBy(base::TimeDelta::FromMilliseconds(40));
157 CheckPref(6);
158}
159
160// Set the pref before the HostCachePersistenceManager is created, and make
161// sure it gets picked up by the HostCache.
162TEST_F(HostCachePersistenceManagerTest, InitAfterPrefs) {
163 CheckPref(0);
164 InitializePref();
165 CheckPref(3);
166
167 MakePersistenceManager(base::TimeDelta::FromSeconds(1));
168 task_runner_->RunUntilIdle();
169 ASSERT_EQ(3u, cache_->size());
170}
171
172// Set the pref after the HostCachePersistenceManager is created, and make
173// sure it gets picked up by the HostCache.
174TEST_F(HostCachePersistenceManagerTest, InitBeforePrefs) {
175 MakePersistenceManager(base::TimeDelta::FromSeconds(1));
176 ASSERT_EQ(0u, cache_->size());
177
178 CheckPref(0);
179 InitializePref();
180 CheckPref(3);
181 ASSERT_EQ(3u, cache_->size());
182}
183
184} // namespace cronet