Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2011 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 <resolv.h> // POSIX only | |
| 6 | |
| 7 #include "base/bind.h" | |
| 8 #include "base/message_loop.h" | |
| 9 #include "base/message_loop_proxy.h" | |
| 10 #include "base/synchronization/waitable_event.h" | |
| 11 #include "base/threading/thread.h" | |
| 12 #include "net/base/ip_endpoint.h" | |
| 13 #include "net/dns/dns_config_service.h" | |
| 14 #include "testing/gtest/include/gtest/gtest.h" | |
| 15 | |
| 16 namespace net { | |
| 17 | |
| 18 namespace { | |
| 19 | |
| 20 // strategy similar to testing FilePathWatcher | |
| 21 | |
| 22 // A mock DnsConfigService::Delegate for testing. | |
| 23 // This is RefCountedThreadSafe to make sure it's cleaned up. | |
| 24 struct TestObserver : public DnsConfigService::Observer, | |
| 25 public base::RefCountedThreadSafe<TestObserver> { | |
| 26 explicit TestObserver(base::WaitableEvent* completion) | |
| 27 : completion(completion) {} | |
| 28 virtual ~TestObserver() {} | |
| 29 | |
| 30 void StartWatch() { | |
| 31 service.reset(DnsConfigService::CreateSystemService()); | |
| 32 service->AddObserver(this); | |
| 33 } | |
| 34 | |
| 35 virtual void OnConfigChanged(const DnsConfig& new_config) OVERRIDE { | |
| 36 config = new_config; | |
| 37 completion->Signal(); | |
| 38 // we must destroy the service on the same thread that called Watch | |
| 39 delete service.release(); | |
| 40 } | |
| 41 | |
| 42 DnsConfig config; | |
| 43 scoped_ptr<DnsConfigService> service; | |
| 44 base::WaitableEvent* completion; | |
| 45 | |
| 46 DISALLOW_COPY_AND_ASSIGN(TestObserver); | |
| 47 }; | |
| 48 | |
| 49 | |
| 50 // run DnsConfigService::Watch on the separate |service_thread_| | |
| 51 class DnsConfigServiceTest : public testing::Test { | |
| 52 public: | |
| 53 DnsConfigServiceTest() | |
| 54 : completion_(false, false), | |
| 55 delegate_(new TestObserver(&completion_)), | |
| 56 service_thread_("DnsConfigServiceTest") {} | |
| 57 | |
| 58 virtual ~DnsConfigServiceTest() {} | |
| 59 | |
| 60 protected: | |
| 61 virtual void SetUp() OVERRIDE { | |
| 62 // Create a separate thread on which we call Watch and the Delegate methods | |
| 63 // TestDelegate will make it quit in OnConfigChanged | |
| 64 base::Thread::Options options(MessageLoop::TYPE_IO, 0); | |
| 65 ASSERT_TRUE(service_thread_.StartWithOptions(options)); | |
| 66 } | |
| 67 | |
| 68 virtual void TearDown() OVERRIDE { | |
| 69 service_thread_.Stop(); | |
| 70 } | |
| 71 | |
| 72 void StartWatch() { | |
| 73 completion_.Reset(); // is this needed? | |
| 74 service_thread_.message_loop()->PostTask( | |
| 75 FROM_HERE, | |
| 76 base::Bind(&TestObserver::StartWatch, delegate_.get())); | |
| 77 } | |
| 78 | |
| 79 void CheckConfig(const struct __res_state &res) { | |
| 80 const DnsConfig& config = delegate_->config; | |
| 81 EXPECT_EQ(config.ndots, static_cast<int>(res.ndots)); | |
| 82 EXPECT_EQ(config.edns0, res.options & RES_USE_EDNS0); | |
| 83 EXPECT_EQ(config.rotate, res.options & RES_ROTATE); | |
| 84 EXPECT_EQ(config.timeout, res.retrans); | |
| 85 EXPECT_EQ(config.attempts, res.retry); | |
| 86 // compare nameservers | |
| 87 ASSERT_EQ(config.nameservers.size(), static_cast<size_t>(res.nscount)); | |
| 88 for (int i = 0; i < res.nscount; ++i) { | |
| 89 IPEndPoint ipe; | |
| 90 ASSERT_TRUE(ipe.FromSockAddr( | |
| 91 reinterpret_cast<const struct sockaddr*>(&res.nsaddr_list[i]), | |
| 92 sizeof res.nsaddr_list[i])); | |
| 93 EXPECT_EQ(config.nameservers[i], ipe); | |
| 94 } | |
| 95 // compare search | |
| 96 ASSERT_TRUE(res.dnsrch[config.search.size()] == NULL); | |
| 97 for (unsigned i = 0; i < config.search.size(); ++i) { | |
| 98 EXPECT_EQ(config.search[i], res.dnsrch[i]); | |
| 99 } | |
| 100 } | |
| 101 | |
| 102 bool WaitForConfig() WARN_UNUSED_RESULT { | |
| 103 return completion_.Wait(); // TODO(szym): add timeout? | |
| 104 } | |
| 105 | |
| 106 private: | |
| 107 base::WaitableEvent completion_; | |
| 108 scoped_refptr<TestObserver> delegate_; | |
| 109 base::Thread service_thread_; | |
| 110 }; | |
| 111 | |
| 112 TEST_F(DnsConfigServiceTest, VerifyWithResInit) { | |
| 113 StartWatch(); | |
| 114 // NOTE: res_init() initializes __res_state.retry (DnsConfig::attempts) to 4 | |
| 115 // while res_ninit() initializes it to 2, so we can't mix them in this test. | |
| 116 struct __res_state res; | |
| 117 ASSERT_EQ(res_ninit(&res), 0); | |
|
cbentzel
2011/08/05 19:11:39
This seems flaky and won't get code coverage of re
szym
2011/08/15 14:27:42
Done.
| |
| 118 | |
| 119 ASSERT_TRUE(res.options & RES_INIT); | |
| 120 ASSERT_TRUE(WaitForConfig()); | |
| 121 CheckConfig(res); | |
| 122 } | |
| 123 | |
| 124 // TODO(szym) do the same but touch /etc/resolv.conf | |
| 125 } | |
| 126 | |
| 127 } // namespace net | |
| 128 | |
| OLD | NEW |