blob: 462eadbd5301724b0d6e06071eeb678ff103e488 [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
[email protected]b4481b222012-03-16 17:13:117#include "base/basictypes.h"
[email protected]76d7f722011-10-10 17:22:418#include "base/bind.h"
[email protected]b4481b222012-03-16 17:13:119#include "base/cancelable_callback.h"
[email protected]76d7f722011-10-10 17:22:4110#include "base/memory/scoped_ptr.h"
[email protected]6998a662011-09-03 00:17:2911#include "base/message_loop.h"
[email protected]6998a662011-09-03 00:17:2912#include "base/test/test_timeouts.h"
13#include "testing/gtest/include/gtest/gtest.h"
14
15namespace net {
16
17namespace {
18
[email protected]b4481b222012-03-16 17:13:1119class DnsConfigServiceTest : public testing::Test {
[email protected]6998a662011-09-03 00:17:2920 public:
[email protected]b4481b222012-03-16 17:13:1121 void OnConfigChanged(const DnsConfig& config) {
[email protected]6998a662011-09-03 00:17:2922 EXPECT_FALSE(config.Equals(last_config_)) <<
23 "Config must be different from last call.";
24 last_config_ = config;
25 if (quit_on_config_)
26 MessageLoop::current()->Quit();
27 }
[email protected]6998a662011-09-03 00:17:2928
29 protected:
[email protected]b4481b222012-03-16 17:13:1130 class TestDnsConfigService : public DnsConfigService {
31 public:
[email protected]05aad32d2012-05-16 18:10:5332 virtual void OnDNSChanged(unsigned detail) OVERRIDE {}
[email protected]b4481b222012-03-16 17:13:1133
34 // Expose the protected methods to this test suite.
35 void InvalidateConfig() {
36 DnsConfigService::InvalidateConfig();
37 }
38
39 void InvalidateHosts() {
40 DnsConfigService::InvalidateHosts();
41 }
42
43 void OnConfigRead(const DnsConfig& config) {
44 DnsConfigService::OnConfigRead(config);
45 }
46
47 void OnHostsRead(const DnsHosts& hosts) {
48 DnsConfigService::OnHostsRead(hosts);
49 }
50 };
51
52 void WaitForConfig(base::TimeDelta timeout) {
53 base::CancelableClosure closure(MessageLoop::QuitClosure());
54 MessageLoop::current()->PostDelayedTask(FROM_HERE,
55 closure.callback(),
56 timeout);
57 quit_on_config_ = true;
58 MessageLoop::current()->Run();
[email protected]6998a662011-09-03 00:17:2959 quit_on_config_ = false;
[email protected]b4481b222012-03-16 17:13:1160 closure.Cancel();
61 }
62
63 // Generate a config using the given seed..
64 DnsConfig MakeConfig(unsigned seed) {
65 DnsConfig config;
66 IPAddressNumber ip;
67 EXPECT_TRUE(ParseIPLiteralToNumber("1.2.3.4", &ip));
68 config.nameservers.push_back(IPEndPoint(ip, seed & 0xFFFF));
69 EXPECT_TRUE(config.IsValid());
70 return config;
71 }
72
73 // Generate hosts using the given seed.
74 DnsHosts MakeHosts(unsigned seed) {
75 DnsHosts hosts;
76 std::string hosts_content = "127.0.0.1 localhost";
77 hosts_content.append(seed, '1');
78 ParseHosts(hosts_content, &hosts);
79 EXPECT_FALSE(hosts.empty());
80 return hosts;
81 }
82
83 virtual void SetUp() OVERRIDE {
84 quit_on_config_ = false;
85
86 service_.reset(new TestDnsConfigService());
87 service_->Watch(base::Bind(&DnsConfigServiceTest::OnConfigChanged,
88 base::Unretained(this)));
89 EXPECT_FALSE(last_config_.IsValid());
[email protected]6998a662011-09-03 00:17:2990 }
91
92 DnsConfig last_config_;
93 bool quit_on_config_;
94
95 // Service under test.
[email protected]b4481b222012-03-16 17:13:1196 scoped_ptr<TestDnsConfigService> service_;
[email protected]6998a662011-09-03 00:17:2997};
98
99} // namespace
100
[email protected]b4481b222012-03-16 17:13:11101TEST_F(DnsConfigServiceTest, FirstConfig) {
102 DnsConfig config = MakeConfig(1);
[email protected]6998a662011-09-03 00:17:29103
[email protected]6998a662011-09-03 00:17:29104 service_->OnConfigRead(config);
[email protected]b4481b222012-03-16 17:13:11105 // No hosts yet, so no config.
106 EXPECT_FALSE(last_config_.IsValid());
[email protected]6998a662011-09-03 00:17:29107
[email protected]b4481b222012-03-16 17:13:11108 service_->OnHostsRead(config.hosts);
109 // Empty hosts is acceptable.
110 EXPECT_TRUE(last_config_.IsValid());
111 EXPECT_TRUE(last_config_.Equals(config));
112}
[email protected]6998a662011-09-03 00:17:29113
[email protected]b4481b222012-03-16 17:13:11114TEST_F(DnsConfigServiceTest, Timeout) {
115 DnsConfig config = MakeConfig(1);
116 config.hosts = MakeHosts(1);
[email protected]163d9b22012-06-12 19:50:36117 ASSERT_TRUE(config.IsValid());
[email protected]6998a662011-09-03 00:17:29118
[email protected]6998a662011-09-03 00:17:29119 service_->OnConfigRead(config);
[email protected]b4481b222012-03-16 17:13:11120 service_->OnHostsRead(config.hosts);
121 EXPECT_TRUE(last_config_.IsValid());
122 EXPECT_TRUE(last_config_.Equals(config));
[email protected]6998a662011-09-03 00:17:29123
[email protected]b4481b222012-03-16 17:13:11124 service_->InvalidateConfig();
125 WaitForConfig(TestTimeouts::action_timeout());
126 EXPECT_FALSE(last_config_.IsValid());
127
128 service_->OnConfigRead(config);
129 EXPECT_TRUE(last_config_.Equals(config));
130
131 service_->InvalidateHosts();
132 WaitForConfig(TestTimeouts::action_timeout());
133 EXPECT_FALSE(last_config_.IsValid());
134
[email protected]163d9b22012-06-12 19:50:36135 service_->InvalidateConfig();
136 // We don't expect an update. This should time out. If we get an update,
137 // we'll detect unchanged config.
138 WaitForConfig(base::TimeDelta::FromMilliseconds(100) +
139 TestTimeouts::tiny_timeout());
140 EXPECT_FALSE(last_config_.IsValid());
141
142 service_->OnConfigRead(config);
[email protected]b4481b222012-03-16 17:13:11143 service_->OnHostsRead(config.hosts);
144 EXPECT_TRUE(last_config_.Equals(config));
145}
146
147TEST_F(DnsConfigServiceTest, SameConfig) {
148 DnsConfig config = MakeConfig(1);
149 config.hosts = MakeHosts(1);
150
151 service_->OnConfigRead(config);
152 service_->OnHostsRead(config.hosts);
153 EXPECT_TRUE(last_config_.Equals(config));
154
155 // OnConfigChanged will catch if there was no change.
156 service_->OnConfigRead(config);
157 EXPECT_TRUE(last_config_.Equals(config));
158
159 service_->OnHostsRead(config.hosts);
160 EXPECT_TRUE(last_config_.Equals(config));
161}
162
163TEST_F(DnsConfigServiceTest, DifferentConfig) {
164 DnsConfig config1 = MakeConfig(1);
165 DnsConfig config2 = MakeConfig(2);
166 DnsConfig config3 = MakeConfig(1);
167 config1.hosts = MakeHosts(1);
168 config2.hosts = MakeHosts(1);
169 config3.hosts = MakeHosts(2);
170 ASSERT_TRUE(config1.EqualsIgnoreHosts(config3));
171 ASSERT_FALSE(config1.Equals(config2));
172 ASSERT_FALSE(config1.Equals(config3));
173 ASSERT_FALSE(config2.Equals(config3));
174
175 service_->OnConfigRead(config1);
176 service_->OnHostsRead(config1.hosts);
177 EXPECT_TRUE(last_config_.Equals(config1));
178
179 // It doesn't matter for this tests, but increases coverage.
180 service_->InvalidateConfig();
181 service_->InvalidateHosts();
182
183 service_->OnConfigRead(config2);
184 service_->OnHostsRead(config2.hosts);
185 EXPECT_TRUE(last_config_.Equals(config2));
186
187 service_->OnConfigRead(config3);
188 service_->OnHostsRead(config3.hosts);
189 EXPECT_TRUE(last_config_.Equals(config3));
[email protected]6998a662011-09-03 00:17:29190}
191
[email protected]76d7f722011-10-10 17:22:41192#if defined(OS_POSIX) || defined(OS_WIN)
[email protected]b4481b222012-03-16 17:13:11193// TODO(szym): This is really an integration test and can time out if HOSTS is
194// huge. http://crbug.com/107810
195TEST_F(DnsConfigServiceTest, FLAKY_GetSystemConfig) {
196 service_.reset();
[email protected]6998a662011-09-03 00:17:29197 scoped_ptr<DnsConfigService> service(DnsConfigService::CreateSystemService());
198
[email protected]05aad32d2012-05-16 18:10:53199 service->Read(base::Bind(&DnsConfigServiceTest::OnConfigChanged,
200 base::Unretained(this)));
[email protected]b4481b222012-03-16 17:13:11201 base::TimeDelta kTimeout = TestTimeouts::action_max_timeout();
202 WaitForConfig(kTimeout);
[email protected]6998a662011-09-03 00:17:29203 ASSERT_TRUE(last_config_.IsValid()) << "Did not receive DnsConfig in " <<
[email protected]b4481b222012-03-16 17:13:11204 kTimeout.InSecondsF() << "s";
[email protected]6998a662011-09-03 00:17:29205}
[email protected]76d7f722011-10-10 17:22:41206#endif // OS_POSIX || OS_WIN
[email protected]6998a662011-09-03 00:17:29207
208} // namespace net
209