Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/dns/dns_config_service.h" | 5 #include "net/dns/dns_config_service.h" |
| 6 | 6 |
| 7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
| 8 #include "base/bind.h" | 8 #include "base/bind.h" |
| 9 #include "base/cancelable_callback.h" | 9 #include "base/cancelable_callback.h" |
| 10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
| 11 #include "base/message_loop.h" | 11 #include "base/message_loop.h" |
| 12 #include "base/test/test_timeouts.h" | 12 #include "base/test/test_timeouts.h" |
| 13 #include "testing/gtest/include/gtest/gtest.h" | 13 #include "testing/gtest/include/gtest/gtest.h" |
| 14 | 14 |
| 15 namespace net { | 15 namespace net { |
| 16 | 16 |
| 17 namespace { | 17 namespace { |
| 18 | 18 |
| 19 class DnsConfigServiceTest : public testing::Test { | 19 class DnsConfigServiceTest : public testing::Test { |
| 20 public: | 20 public: |
| 21 void OnConfigChanged(const DnsConfig& config) { | 21 void OnConfigChanged(const DnsConfig& config) { |
| 22 EXPECT_FALSE(config.Equals(last_config_)) << | |
| 23 "Config must be different from last call."; | |
| 24 last_config_ = config; | 22 last_config_ = config; |
| 25 if (quit_on_config_) | 23 if (quit_on_config_) |
| 26 MessageLoop::current()->Quit(); | 24 MessageLoop::current()->Quit(); |
| 27 } | 25 } |
| 28 | 26 |
| 29 protected: | 27 protected: |
| 30 class TestDnsConfigService : public DnsConfigService { | 28 class TestDnsConfigService : public DnsConfigService { |
| 31 public: | 29 public: |
| 32 virtual void OnDNSChanged(unsigned detail) OVERRIDE {} | 30 virtual void ReadNow() OVERRIDE {} |
| 31 virtual bool StartWatching() OVERRIDE { return true; } | |
| 33 | 32 |
| 34 // Expose the protected methods to this test suite. | 33 // Expose the protected methods to this test suite. |
| 35 void InvalidateConfig() { | 34 void InvalidateConfig() { |
| 36 DnsConfigService::InvalidateConfig(); | 35 DnsConfigService::InvalidateConfig(); |
| 37 } | 36 } |
| 38 | 37 |
| 39 void InvalidateHosts() { | 38 void InvalidateHosts() { |
| 40 DnsConfigService::InvalidateHosts(); | 39 DnsConfigService::InvalidateHosts(); |
| 41 } | 40 } |
| 42 | 41 |
| 43 void OnConfigRead(const DnsConfig& config) { | 42 void OnConfigRead(const DnsConfig& config) { |
| 44 DnsConfigService::OnConfigRead(config); | 43 DnsConfigService::OnConfigRead(config); |
| 45 } | 44 } |
| 46 | 45 |
| 47 void OnHostsRead(const DnsHosts& hosts) { | 46 void OnHostsRead(const DnsHosts& hosts) { |
| 48 DnsConfigService::OnHostsRead(hosts); | 47 DnsConfigService::OnHostsRead(hosts); |
| 49 } | 48 } |
| 49 | |
| 50 void set_watch_failed(bool value) { | |
| 51 DnsConfigService::set_watch_failed(value); | |
| 52 } | |
| 50 }; | 53 }; |
| 51 | 54 |
| 52 void WaitForConfig(base::TimeDelta timeout) { | 55 void WaitForConfig(base::TimeDelta timeout) { |
| 56 DnsConfig config = last_config_; | |
|
mmenke
2012/08/31 15:05:59
This doesn't seem to be needed.
| |
| 53 base::CancelableClosure closure(MessageLoop::QuitClosure()); | 57 base::CancelableClosure closure(MessageLoop::QuitClosure()); |
| 54 MessageLoop::current()->PostDelayedTask(FROM_HERE, | 58 MessageLoop::current()->PostDelayedTask(FROM_HERE, |
| 55 closure.callback(), | 59 closure.callback(), |
| 56 timeout); | 60 timeout); |
| 57 quit_on_config_ = true; | 61 quit_on_config_ = true; |
| 58 MessageLoop::current()->Run(); | 62 MessageLoop::current()->Run(); |
| 59 quit_on_config_ = false; | 63 quit_on_config_ = false; |
| 60 closure.Cancel(); | 64 closure.Cancel(); |
| 61 } | 65 } |
| 62 | 66 |
| 63 // Generate a config using the given seed.. | 67 // Generate a config using the given seed.. |
| 64 DnsConfig MakeConfig(unsigned seed) { | 68 DnsConfig MakeConfig(unsigned seed) { |
| 65 DnsConfig config; | 69 DnsConfig config; |
| 66 IPAddressNumber ip; | 70 IPAddressNumber ip; |
| 67 EXPECT_TRUE(ParseIPLiteralToNumber("1.2.3.4", &ip)); | 71 CHECK(ParseIPLiteralToNumber("1.2.3.4", &ip)); |
| 68 config.nameservers.push_back(IPEndPoint(ip, seed & 0xFFFF)); | 72 config.nameservers.push_back(IPEndPoint(ip, seed & 0xFFFF)); |
| 69 EXPECT_TRUE(config.IsValid()); | 73 EXPECT_TRUE(config.IsValid()); |
| 70 return config; | 74 return config; |
| 71 } | 75 } |
| 72 | 76 |
| 73 // Generate hosts using the given seed. | 77 // Generate hosts using the given seed. |
| 74 DnsHosts MakeHosts(unsigned seed) { | 78 DnsHosts MakeHosts(unsigned seed) { |
| 75 DnsHosts hosts; | 79 DnsHosts hosts; |
| 76 std::string hosts_content = "127.0.0.1 localhost"; | 80 std::string hosts_content = "127.0.0.1 localhost"; |
| 77 hosts_content.append(seed, '1'); | 81 hosts_content.append(seed, '1'); |
| 78 ParseHosts(hosts_content, &hosts); | 82 ParseHosts(hosts_content, &hosts); |
| 79 EXPECT_FALSE(hosts.empty()); | 83 EXPECT_FALSE(hosts.empty()); |
| 80 return hosts; | 84 return hosts; |
| 81 } | 85 } |
| 82 | 86 |
| 83 virtual void SetUp() OVERRIDE { | 87 virtual void SetUp() OVERRIDE { |
| 84 quit_on_config_ = false; | 88 quit_on_config_ = false; |
| 85 | 89 |
| 86 service_.reset(new TestDnsConfigService()); | 90 service_.reset(new TestDnsConfigService()); |
| 87 service_->Watch(base::Bind(&DnsConfigServiceTest::OnConfigChanged, | 91 service_->WatchConfig(base::Bind(&DnsConfigServiceTest::OnConfigChanged, |
| 88 base::Unretained(this))); | 92 base::Unretained(this))); |
| 89 EXPECT_FALSE(last_config_.IsValid()); | 93 EXPECT_FALSE(last_config_.IsValid()); |
| 90 } | 94 } |
| 91 | 95 |
| 92 DnsConfig last_config_; | 96 DnsConfig last_config_; |
| 93 bool quit_on_config_; | 97 bool quit_on_config_; |
| 94 | 98 |
| 95 // Service under test. | 99 // Service under test. |
| 96 scoped_ptr<TestDnsConfigService> service_; | 100 scoped_ptr<TestDnsConfigService> service_; |
| 97 }; | 101 }; |
| 98 | 102 |
| 99 } // namespace | 103 } // namespace |
| 100 | 104 |
| 101 TEST_F(DnsConfigServiceTest, FirstConfig) { | 105 TEST_F(DnsConfigServiceTest, FirstConfig) { |
| 102 DnsConfig config = MakeConfig(1); | 106 DnsConfig config = MakeConfig(1); |
| 103 | 107 |
| 104 service_->OnConfigRead(config); | 108 service_->OnConfigRead(config); |
| 105 // No hosts yet, so no config. | 109 // No hosts yet, so no config. |
| 106 EXPECT_FALSE(last_config_.IsValid()); | 110 EXPECT_TRUE(last_config_.Equals(DnsConfig())); |
| 107 | 111 |
| 108 service_->OnHostsRead(config.hosts); | 112 service_->OnHostsRead(config.hosts); |
| 109 // Empty hosts is acceptable. | |
| 110 EXPECT_TRUE(last_config_.IsValid()); | |
| 111 EXPECT_TRUE(last_config_.Equals(config)); | 113 EXPECT_TRUE(last_config_.Equals(config)); |
|
mmenke
2012/08/31 15:05:59
We're depending an awful lot on Equals returning t
| |
| 112 } | 114 } |
| 113 | 115 |
| 114 TEST_F(DnsConfigServiceTest, Timeout) { | 116 TEST_F(DnsConfigServiceTest, Timeout) { |
| 115 DnsConfig config = MakeConfig(1); | 117 DnsConfig config = MakeConfig(1); |
| 116 config.hosts = MakeHosts(1); | 118 config.hosts = MakeHosts(1); |
| 117 ASSERT_TRUE(config.IsValid()); | 119 ASSERT_TRUE(config.IsValid()); |
| 118 | 120 |
| 119 service_->OnConfigRead(config); | 121 service_->OnConfigRead(config); |
| 120 service_->OnHostsRead(config.hosts); | 122 service_->OnHostsRead(config.hosts); |
| 121 EXPECT_TRUE(last_config_.IsValid()); | |
| 122 EXPECT_TRUE(last_config_.Equals(config)); | 123 EXPECT_TRUE(last_config_.Equals(config)); |
| 123 | 124 |
| 124 service_->InvalidateConfig(); | 125 service_->InvalidateConfig(); |
| 125 WaitForConfig(TestTimeouts::action_timeout()); | 126 WaitForConfig(TestTimeouts::action_timeout()); |
| 126 EXPECT_FALSE(last_config_.IsValid()); | 127 EXPECT_TRUE(last_config_.Equals(DnsConfig())); |
| 127 | 128 |
| 128 service_->OnConfigRead(config); | 129 service_->OnConfigRead(config); |
| 129 EXPECT_TRUE(last_config_.Equals(config)); | 130 EXPECT_TRUE(last_config_.Equals(config)); |
| 130 | 131 |
| 131 service_->InvalidateHosts(); | 132 service_->InvalidateHosts(); |
| 132 WaitForConfig(TestTimeouts::action_timeout()); | 133 WaitForConfig(TestTimeouts::action_timeout()); |
| 133 EXPECT_FALSE(last_config_.IsValid()); | 134 EXPECT_TRUE(last_config_.Equals(DnsConfig())); |
| 134 | 135 |
| 136 DnsConfig bad_config = last_config_ = MakeConfig(0xBAD); | |
| 135 service_->InvalidateConfig(); | 137 service_->InvalidateConfig(); |
| 136 // We don't expect an update. This should time out. If we get an update, | 138 // We don't expect an update. This should time out. |
| 137 // we'll detect unchanged config. | |
| 138 WaitForConfig(base::TimeDelta::FromMilliseconds(100) + | 139 WaitForConfig(base::TimeDelta::FromMilliseconds(100) + |
| 139 TestTimeouts::tiny_timeout()); | 140 TestTimeouts::tiny_timeout()); |
| 140 EXPECT_FALSE(last_config_.IsValid()); | 141 EXPECT_TRUE(last_config_.Equals(bad_config)) << "Unexpected change"; |
| 141 | 142 |
| 143 last_config_ = DnsConfig(); | |
| 142 service_->OnConfigRead(config); | 144 service_->OnConfigRead(config); |
| 143 service_->OnHostsRead(config.hosts); | 145 service_->OnHostsRead(config.hosts); |
| 144 EXPECT_TRUE(last_config_.Equals(config)); | 146 EXPECT_TRUE(last_config_.Equals(config)); |
| 145 } | 147 } |
| 146 | 148 |
| 147 TEST_F(DnsConfigServiceTest, SameConfig) { | 149 TEST_F(DnsConfigServiceTest, SameConfig) { |
| 148 DnsConfig config = MakeConfig(1); | 150 DnsConfig config = MakeConfig(1); |
| 149 config.hosts = MakeHosts(1); | 151 config.hosts = MakeHosts(1); |
| 150 | 152 |
| 151 service_->OnConfigRead(config); | 153 service_->OnConfigRead(config); |
| 152 service_->OnHostsRead(config.hosts); | 154 service_->OnHostsRead(config.hosts); |
| 153 EXPECT_TRUE(last_config_.Equals(config)); | 155 EXPECT_TRUE(last_config_.Equals(config)); |
| 154 | 156 |
| 155 // OnConfigChanged will catch if there was no change. | 157 last_config_ = DnsConfig(); |
| 156 service_->OnConfigRead(config); | 158 service_->OnConfigRead(config); |
| 157 EXPECT_TRUE(last_config_.Equals(config)); | 159 EXPECT_TRUE(last_config_.Equals(DnsConfig())) << "Unexpected change"; |
| 158 | 160 |
| 159 service_->OnHostsRead(config.hosts); | 161 service_->OnHostsRead(config.hosts); |
| 160 EXPECT_TRUE(last_config_.Equals(config)); | 162 EXPECT_TRUE(last_config_.Equals(DnsConfig())) << "Unexpected change"; |
| 161 } | 163 } |
| 162 | 164 |
| 163 TEST_F(DnsConfigServiceTest, DifferentConfig) { | 165 TEST_F(DnsConfigServiceTest, DifferentConfig) { |
| 164 DnsConfig config1 = MakeConfig(1); | 166 DnsConfig config1 = MakeConfig(1); |
| 165 DnsConfig config2 = MakeConfig(2); | 167 DnsConfig config2 = MakeConfig(2); |
| 166 DnsConfig config3 = MakeConfig(1); | 168 DnsConfig config3 = MakeConfig(1); |
| 167 config1.hosts = MakeHosts(1); | 169 config1.hosts = MakeHosts(1); |
| 168 config2.hosts = MakeHosts(1); | 170 config2.hosts = MakeHosts(1); |
| 169 config3.hosts = MakeHosts(2); | 171 config3.hosts = MakeHosts(2); |
| 170 ASSERT_TRUE(config1.EqualsIgnoreHosts(config3)); | 172 ASSERT_TRUE(config1.EqualsIgnoreHosts(config3)); |
| 171 ASSERT_FALSE(config1.Equals(config2)); | 173 ASSERT_FALSE(config1.Equals(config2)); |
| 172 ASSERT_FALSE(config1.Equals(config3)); | 174 ASSERT_FALSE(config1.Equals(config3)); |
| 173 ASSERT_FALSE(config2.Equals(config3)); | 175 ASSERT_FALSE(config2.Equals(config3)); |
| 174 | 176 |
| 175 service_->OnConfigRead(config1); | 177 service_->OnConfigRead(config1); |
| 176 service_->OnHostsRead(config1.hosts); | 178 service_->OnHostsRead(config1.hosts); |
| 177 EXPECT_TRUE(last_config_.Equals(config1)); | 179 EXPECT_TRUE(last_config_.Equals(config1)); |
| 178 | 180 |
| 179 // It doesn't matter for this tests, but increases coverage. | 181 // It doesn't matter for this tests, but increases coverage. |
| 180 service_->InvalidateConfig(); | 182 service_->InvalidateConfig(); |
| 181 service_->InvalidateHosts(); | 183 service_->InvalidateHosts(); |
| 182 | 184 |
| 183 service_->OnConfigRead(config2); | 185 service_->OnConfigRead(config2); |
| 184 service_->OnHostsRead(config2.hosts); | 186 EXPECT_TRUE(last_config_.Equals(config1)) << "Unexpected change"; |
| 187 service_->OnHostsRead(config2.hosts); // Not an actual change. | |
| 185 EXPECT_TRUE(last_config_.Equals(config2)); | 188 EXPECT_TRUE(last_config_.Equals(config2)); |
| 186 | 189 |
| 187 service_->OnConfigRead(config3); | 190 service_->OnConfigRead(config3); |
| 191 EXPECT_TRUE(last_config_.EqualsIgnoreHosts(config3)); | |
| 188 service_->OnHostsRead(config3.hosts); | 192 service_->OnHostsRead(config3.hosts); |
| 189 EXPECT_TRUE(last_config_.Equals(config3)); | 193 EXPECT_TRUE(last_config_.Equals(config3)); |
| 190 } | 194 } |
| 191 | 195 |
| 196 TEST_F(DnsConfigServiceTest, WatchFailure) { | |
| 197 DnsConfig config1 = MakeConfig(1); | |
| 198 DnsConfig config2 = MakeConfig(2); | |
| 199 config1.hosts = MakeHosts(1); | |
| 200 config2.hosts = MakeHosts(2); | |
| 201 | |
| 202 service_->OnConfigRead(config1); | |
| 203 service_->OnHostsRead(config1.hosts); | |
| 204 EXPECT_TRUE(last_config_.Equals(config1)); | |
| 205 | |
| 206 // Simulate watch failure. | |
| 207 service_->InvalidateConfig(); | |
| 208 service_->set_watch_failed(true); | |
| 209 WaitForConfig(TestTimeouts::action_timeout()); | |
| 210 EXPECT_TRUE(last_config_.Equals(DnsConfig())); | |
| 211 | |
| 212 DnsConfig bad_config = last_config_ = MakeConfig(0xBAD); | |
| 213 service_->OnConfigRead(config1); | |
| 214 // We don't expect an update. This should time out. | |
| 215 WaitForConfig(base::TimeDelta::FromMilliseconds(100) + | |
| 216 TestTimeouts::tiny_timeout()); | |
| 217 EXPECT_TRUE(last_config_.Equals(bad_config)); | |
| 218 | |
| 219 // Actual change in config, so expect an update, but it should be empty. | |
| 220 service_->InvalidateConfig(); | |
| 221 service_->OnConfigRead(config2); | |
| 222 WaitForConfig(TestTimeouts::action_timeout()); | |
| 223 EXPECT_TRUE(last_config_.Equals(DnsConfig())); | |
| 224 } | |
| 225 | |
| 192 #if (defined(OS_POSIX) && !defined(OS_ANDROID)) || defined(OS_WIN) | 226 #if (defined(OS_POSIX) && !defined(OS_ANDROID)) || defined(OS_WIN) |
| 193 // TODO(szym): This is really an integration test and can time out if HOSTS is | 227 // TODO(szym): This is really an integration test and can time out if HOSTS is |
| 194 // huge. http://crbug.com/107810 | 228 // huge. http://crbug.com/107810 |
| 195 TEST_F(DnsConfigServiceTest, FLAKY_GetSystemConfig) { | 229 TEST_F(DnsConfigServiceTest, FLAKY_GetSystemConfig) { |
| 196 service_.reset(); | 230 service_.reset(); |
| 197 scoped_ptr<DnsConfigService> service(DnsConfigService::CreateSystemService()); | 231 scoped_ptr<DnsConfigService> service(DnsConfigService::CreateSystemService()); |
| 198 | 232 |
| 199 service->Read(base::Bind(&DnsConfigServiceTest::OnConfigChanged, | 233 service->ReadConfig(base::Bind(&DnsConfigServiceTest::OnConfigChanged, |
| 200 base::Unretained(this))); | 234 base::Unretained(this))); |
| 201 base::TimeDelta kTimeout = TestTimeouts::action_max_timeout(); | 235 base::TimeDelta kTimeout = TestTimeouts::action_max_timeout(); |
| 202 WaitForConfig(kTimeout); | 236 WaitForConfig(kTimeout); |
| 203 ASSERT_TRUE(last_config_.IsValid()) << "Did not receive DnsConfig in " << | 237 ASSERT_TRUE(last_config_.IsValid()) << "Did not receive DnsConfig in " << |
| 204 kTimeout.InSecondsF() << "s"; | 238 kTimeout.InSecondsF() << "s"; |
| 205 } | 239 } |
| 206 #endif // OS_POSIX || OS_WIN | 240 #endif // OS_POSIX || OS_WIN |
| 207 | 241 |
| 208 } // namespace net | 242 } // namespace net |
| 209 | 243 |
| OLD | NEW |