blob: 5436aa97eee9359e641e3ee2cd06265f78651207 [file] [log] [blame]
[email protected]5761ab9c2012-02-04 16:44:531// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]6998a662011-09-03 00:17:292// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "net/dns/dns_config_service.h"
6
danakj22f90e72016-04-16 01:55:407#include <memory>
8
[email protected]76d7f722011-10-10 17:22:419#include "base/bind.h"
[email protected]b4481b222012-03-16 17:13:1110#include "base/cancelable_callback.h"
skyostil4891b25b2015-06-11 11:43:4511#include "base/location.h"
[email protected]5ee20982013-07-17 21:51:1812#include "base/message_loop/message_loop.h"
skyostil4891b25b2015-06-11 11:43:4513#include "base/single_thread_task_runner.h"
[email protected]e4e522d2014-03-12 05:08:0614#include "base/strings/string_split.h"
[email protected]6998a662011-09-03 00:17:2915#include "base/test/test_timeouts.h"
skyostil4891b25b2015-06-11 11:43:4516#include "base/thread_task_runner_handle.h"
[email protected]e4e522d2014-03-12 05:08:0617#include "net/dns/dns_protocol.h"
[email protected]6998a662011-09-03 00:17:2918#include "testing/gtest/include/gtest/gtest.h"
19
20namespace net {
21
22namespace {
23
[email protected]b4481b222012-03-16 17:13:1124class DnsConfigServiceTest : public testing::Test {
[email protected]6998a662011-09-03 00:17:2925 public:
[email protected]b4481b222012-03-16 17:13:1126 void OnConfigChanged(const DnsConfig& config) {
[email protected]6998a662011-09-03 00:17:2927 last_config_ = config;
28 if (quit_on_config_)
ki.stfu375812e2015-10-09 20:23:1729 base::MessageLoop::current()->QuitWhenIdle();
[email protected]6998a662011-09-03 00:17:2930 }
[email protected]6998a662011-09-03 00:17:2931
32 protected:
[email protected]b4481b222012-03-16 17:13:1133 class TestDnsConfigService : public DnsConfigService {
34 public:
dchengb03027d2014-10-21 12:00:2035 void ReadNow() override {}
36 bool StartWatching() override { return true; }
[email protected]b4481b222012-03-16 17:13:1137
38 // Expose the protected methods to this test suite.
39 void InvalidateConfig() {
40 DnsConfigService::InvalidateConfig();
41 }
42
43 void InvalidateHosts() {
44 DnsConfigService::InvalidateHosts();
45 }
46
47 void OnConfigRead(const DnsConfig& config) {
48 DnsConfigService::OnConfigRead(config);
49 }
50
51 void OnHostsRead(const DnsHosts& hosts) {
52 DnsConfigService::OnHostsRead(hosts);
53 }
[email protected]bb0e34542012-08-31 19:52:4054
55 void set_watch_failed(bool value) {
56 DnsConfigService::set_watch_failed(value);
57 }
[email protected]b4481b222012-03-16 17:13:1158 };
59
60 void WaitForConfig(base::TimeDelta timeout) {
ki.stfu375812e2015-10-09 20:23:1761 base::CancelableClosure closure(base::MessageLoop::QuitWhenIdleClosure());
skyostil4891b25b2015-06-11 11:43:4562 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
[email protected]2da659e2013-05-23 20:51:3463 FROM_HERE, closure.callback(), timeout);
[email protected]b4481b222012-03-16 17:13:1164 quit_on_config_ = true;
[email protected]2da659e2013-05-23 20:51:3465 base::MessageLoop::current()->Run();
[email protected]6998a662011-09-03 00:17:2966 quit_on_config_ = false;
[email protected]b4481b222012-03-16 17:13:1167 closure.Cancel();
68 }
69
70 // Generate a config using the given seed..
71 DnsConfig MakeConfig(unsigned seed) {
72 DnsConfig config;
martijna23c8962016-03-04 18:18:5173 config.nameservers.push_back(
74 IPEndPoint(IPAddress(1, 2, 3, 4), seed & 0xFFFF));
[email protected]b4481b222012-03-16 17:13:1175 EXPECT_TRUE(config.IsValid());
76 return config;
77 }
78
79 // Generate hosts using the given seed.
80 DnsHosts MakeHosts(unsigned seed) {
81 DnsHosts hosts;
82 std::string hosts_content = "127.0.0.1 localhost";
83 hosts_content.append(seed, '1');
84 ParseHosts(hosts_content, &hosts);
85 EXPECT_FALSE(hosts.empty());
86 return hosts;
87 }
88
dcheng67be2b1f2014-10-27 21:47:2989 void SetUp() override {
[email protected]b4481b222012-03-16 17:13:1190 quit_on_config_ = false;
91
92 service_.reset(new TestDnsConfigService());
[email protected]bb0e34542012-08-31 19:52:4093 service_->WatchConfig(base::Bind(&DnsConfigServiceTest::OnConfigChanged,
94 base::Unretained(this)));
[email protected]b4481b222012-03-16 17:13:1195 EXPECT_FALSE(last_config_.IsValid());
[email protected]6998a662011-09-03 00:17:2996 }
97
98 DnsConfig last_config_;
99 bool quit_on_config_;
100
101 // Service under test.
danakj22f90e72016-04-16 01:55:40102 std::unique_ptr<TestDnsConfigService> service_;
[email protected]6998a662011-09-03 00:17:29103};
104
105} // namespace
106
[email protected]b4481b222012-03-16 17:13:11107TEST_F(DnsConfigServiceTest, FirstConfig) {
108 DnsConfig config = MakeConfig(1);
[email protected]6998a662011-09-03 00:17:29109
[email protected]6998a662011-09-03 00:17:29110 service_->OnConfigRead(config);
[email protected]b4481b222012-03-16 17:13:11111 // No hosts yet, so no config.
[email protected]bb0e34542012-08-31 19:52:40112 EXPECT_TRUE(last_config_.Equals(DnsConfig()));
[email protected]6998a662011-09-03 00:17:29113
[email protected]b4481b222012-03-16 17:13:11114 service_->OnHostsRead(config.hosts);
[email protected]b4481b222012-03-16 17:13:11115 EXPECT_TRUE(last_config_.Equals(config));
116}
[email protected]6998a662011-09-03 00:17:29117
[email protected]b4481b222012-03-16 17:13:11118TEST_F(DnsConfigServiceTest, Timeout) {
119 DnsConfig config = MakeConfig(1);
120 config.hosts = MakeHosts(1);
[email protected]163d9b22012-06-12 19:50:36121 ASSERT_TRUE(config.IsValid());
[email protected]6998a662011-09-03 00:17:29122
[email protected]6998a662011-09-03 00:17:29123 service_->OnConfigRead(config);
[email protected]b4481b222012-03-16 17:13:11124 service_->OnHostsRead(config.hosts);
[email protected]bb0e34542012-08-31 19:52:40125 EXPECT_FALSE(last_config_.Equals(DnsConfig()));
[email protected]b4481b222012-03-16 17:13:11126 EXPECT_TRUE(last_config_.Equals(config));
[email protected]6998a662011-09-03 00:17:29127
[email protected]b4481b222012-03-16 17:13:11128 service_->InvalidateConfig();
129 WaitForConfig(TestTimeouts::action_timeout());
[email protected]bb0e34542012-08-31 19:52:40130 EXPECT_FALSE(last_config_.Equals(config));
131 EXPECT_TRUE(last_config_.Equals(DnsConfig()));
[email protected]b4481b222012-03-16 17:13:11132
133 service_->OnConfigRead(config);
[email protected]bb0e34542012-08-31 19:52:40134 EXPECT_FALSE(last_config_.Equals(DnsConfig()));
[email protected]b4481b222012-03-16 17:13:11135 EXPECT_TRUE(last_config_.Equals(config));
136
137 service_->InvalidateHosts();
138 WaitForConfig(TestTimeouts::action_timeout());
[email protected]bb0e34542012-08-31 19:52:40139 EXPECT_FALSE(last_config_.Equals(config));
140 EXPECT_TRUE(last_config_.Equals(DnsConfig()));
[email protected]b4481b222012-03-16 17:13:11141
[email protected]bb0e34542012-08-31 19:52:40142 DnsConfig bad_config = last_config_ = MakeConfig(0xBAD);
[email protected]163d9b22012-06-12 19:50:36143 service_->InvalidateConfig();
[email protected]bb0e34542012-08-31 19:52:40144 // We don't expect an update. This should time out.
[email protected]163d9b22012-06-12 19:50:36145 WaitForConfig(base::TimeDelta::FromMilliseconds(100) +
146 TestTimeouts::tiny_timeout());
[email protected]bb0e34542012-08-31 19:52:40147 EXPECT_TRUE(last_config_.Equals(bad_config)) << "Unexpected change";
[email protected]163d9b22012-06-12 19:50:36148
[email protected]bb0e34542012-08-31 19:52:40149 last_config_ = DnsConfig();
[email protected]163d9b22012-06-12 19:50:36150 service_->OnConfigRead(config);
[email protected]b4481b222012-03-16 17:13:11151 service_->OnHostsRead(config.hosts);
[email protected]bb0e34542012-08-31 19:52:40152 EXPECT_FALSE(last_config_.Equals(DnsConfig()));
[email protected]b4481b222012-03-16 17:13:11153 EXPECT_TRUE(last_config_.Equals(config));
154}
155
156TEST_F(DnsConfigServiceTest, SameConfig) {
157 DnsConfig config = MakeConfig(1);
158 config.hosts = MakeHosts(1);
159
160 service_->OnConfigRead(config);
161 service_->OnHostsRead(config.hosts);
[email protected]bb0e34542012-08-31 19:52:40162 EXPECT_FALSE(last_config_.Equals(DnsConfig()));
[email protected]b4481b222012-03-16 17:13:11163 EXPECT_TRUE(last_config_.Equals(config));
164
[email protected]bb0e34542012-08-31 19:52:40165 last_config_ = DnsConfig();
[email protected]b4481b222012-03-16 17:13:11166 service_->OnConfigRead(config);
[email protected]bb0e34542012-08-31 19:52:40167 EXPECT_TRUE(last_config_.Equals(DnsConfig())) << "Unexpected change";
[email protected]b4481b222012-03-16 17:13:11168
169 service_->OnHostsRead(config.hosts);
[email protected]bb0e34542012-08-31 19:52:40170 EXPECT_TRUE(last_config_.Equals(DnsConfig())) << "Unexpected change";
[email protected]b4481b222012-03-16 17:13:11171}
172
173TEST_F(DnsConfigServiceTest, DifferentConfig) {
174 DnsConfig config1 = MakeConfig(1);
175 DnsConfig config2 = MakeConfig(2);
176 DnsConfig config3 = MakeConfig(1);
177 config1.hosts = MakeHosts(1);
178 config2.hosts = MakeHosts(1);
179 config3.hosts = MakeHosts(2);
180 ASSERT_TRUE(config1.EqualsIgnoreHosts(config3));
181 ASSERT_FALSE(config1.Equals(config2));
182 ASSERT_FALSE(config1.Equals(config3));
183 ASSERT_FALSE(config2.Equals(config3));
184
185 service_->OnConfigRead(config1);
186 service_->OnHostsRead(config1.hosts);
[email protected]bb0e34542012-08-31 19:52:40187 EXPECT_FALSE(last_config_.Equals(DnsConfig()));
[email protected]b4481b222012-03-16 17:13:11188 EXPECT_TRUE(last_config_.Equals(config1));
189
190 // It doesn't matter for this tests, but increases coverage.
191 service_->InvalidateConfig();
192 service_->InvalidateHosts();
193
194 service_->OnConfigRead(config2);
[email protected]bb0e34542012-08-31 19:52:40195 EXPECT_TRUE(last_config_.Equals(config1)) << "Unexpected change";
196 service_->OnHostsRead(config2.hosts); // Not an actual change.
197 EXPECT_FALSE(last_config_.Equals(config1));
[email protected]b4481b222012-03-16 17:13:11198 EXPECT_TRUE(last_config_.Equals(config2));
199
200 service_->OnConfigRead(config3);
[email protected]bb0e34542012-08-31 19:52:40201 EXPECT_TRUE(last_config_.EqualsIgnoreHosts(config3));
[email protected]b4481b222012-03-16 17:13:11202 service_->OnHostsRead(config3.hosts);
[email protected]bb0e34542012-08-31 19:52:40203 EXPECT_FALSE(last_config_.Equals(config2));
[email protected]b4481b222012-03-16 17:13:11204 EXPECT_TRUE(last_config_.Equals(config3));
[email protected]6998a662011-09-03 00:17:29205}
206
[email protected]bb0e34542012-08-31 19:52:40207TEST_F(DnsConfigServiceTest, WatchFailure) {
208 DnsConfig config1 = MakeConfig(1);
209 DnsConfig config2 = MakeConfig(2);
210 config1.hosts = MakeHosts(1);
211 config2.hosts = MakeHosts(2);
212
213 service_->OnConfigRead(config1);
214 service_->OnHostsRead(config1.hosts);
215 EXPECT_FALSE(last_config_.Equals(DnsConfig()));
216 EXPECT_TRUE(last_config_.Equals(config1));
217
218 // Simulate watch failure.
219 service_->set_watch_failed(true);
220 service_->InvalidateConfig();
221 WaitForConfig(TestTimeouts::action_timeout());
222 EXPECT_FALSE(last_config_.Equals(config1));
223 EXPECT_TRUE(last_config_.Equals(DnsConfig()));
224
225 DnsConfig bad_config = last_config_ = MakeConfig(0xBAD);
226 // Actual change in config, so expect an update, but it should be empty.
227 service_->OnConfigRead(config1);
228 EXPECT_FALSE(last_config_.Equals(bad_config));
229 EXPECT_TRUE(last_config_.Equals(DnsConfig()));
230
231 last_config_ = bad_config;
232 // Actual change in config, so expect an update, but it should be empty.
233 service_->InvalidateConfig();
234 service_->OnConfigRead(config2);
235 EXPECT_FALSE(last_config_.Equals(bad_config));
236 EXPECT_TRUE(last_config_.Equals(DnsConfig()));
237
238 last_config_ = bad_config;
239 // No change, so no update.
240 service_->InvalidateConfig();
241 service_->OnConfigRead(config2);
242 EXPECT_TRUE(last_config_.Equals(bad_config));
243}
244
[email protected]6998a662011-09-03 00:17:29245} // namespace net
246