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 |