Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(788)

Unified Diff: net/dns/dns_config_service_posix_unittest.cc

Issue 7518028: DnsConfigService and a posix implementation (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Changed Delegate -> Observer(List); internal handling of Watch failures. Created 9 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: net/dns/dns_config_service_posix_unittest.cc
diff --git a/net/dns/dns_config_service_posix_unittest.cc b/net/dns/dns_config_service_posix_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..262db5a404c9bef4209dbaabc59dd603de400de3
--- /dev/null
+++ b/net/dns/dns_config_service_posix_unittest.cc
@@ -0,0 +1,128 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <resolv.h> // POSIX only
+
+#include "base/bind.h"
+#include "base/message_loop.h"
+#include "base/message_loop_proxy.h"
+#include "base/synchronization/waitable_event.h"
+#include "base/threading/thread.h"
+#include "net/base/ip_endpoint.h"
+#include "net/dns/dns_config_service.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+
+namespace {
+
+// strategy similar to testing FilePathWatcher
+
+// A mock DnsConfigService::Delegate for testing.
+// This is RefCountedThreadSafe to make sure it's cleaned up.
+struct TestObserver : public DnsConfigService::Observer,
+ public base::RefCountedThreadSafe<TestObserver> {
+ explicit TestObserver(base::WaitableEvent* completion)
+ : completion(completion) {}
+ virtual ~TestObserver() {}
+
+ void StartWatch() {
+ service.reset(DnsConfigService::CreateSystemService());
+ service->AddObserver(this);
+ }
+
+ virtual void OnConfigChanged(const DnsConfig& new_config) OVERRIDE {
+ config = new_config;
+ completion->Signal();
+ // we must destroy the service on the same thread that called Watch
+ delete service.release();
+ }
+
+ DnsConfig config;
+ scoped_ptr<DnsConfigService> service;
+ base::WaitableEvent* completion;
+
+ DISALLOW_COPY_AND_ASSIGN(TestObserver);
+};
+
+
+// run DnsConfigService::Watch on the separate |service_thread_|
+class DnsConfigServiceTest : public testing::Test {
+ public:
+ DnsConfigServiceTest()
+ : completion_(false, false),
+ delegate_(new TestObserver(&completion_)),
+ service_thread_("DnsConfigServiceTest") {}
+
+ virtual ~DnsConfigServiceTest() {}
+
+ protected:
+ virtual void SetUp() OVERRIDE {
+ // Create a separate thread on which we call Watch and the Delegate methods
+ // TestDelegate will make it quit in OnConfigChanged
+ base::Thread::Options options(MessageLoop::TYPE_IO, 0);
+ ASSERT_TRUE(service_thread_.StartWithOptions(options));
+ }
+
+ virtual void TearDown() OVERRIDE {
+ service_thread_.Stop();
+ }
+
+ void StartWatch() {
+ completion_.Reset(); // is this needed?
+ service_thread_.message_loop()->PostTask(
+ FROM_HERE,
+ base::Bind(&TestObserver::StartWatch, delegate_.get()));
+ }
+
+ void CheckConfig(const struct __res_state &res) {
+ const DnsConfig& config = delegate_->config;
+ EXPECT_EQ(config.ndots, static_cast<int>(res.ndots));
+ EXPECT_EQ(config.edns0, res.options & RES_USE_EDNS0);
+ EXPECT_EQ(config.rotate, res.options & RES_ROTATE);
+ EXPECT_EQ(config.timeout, res.retrans);
+ EXPECT_EQ(config.attempts, res.retry);
+ // compare nameservers
+ ASSERT_EQ(config.nameservers.size(), static_cast<size_t>(res.nscount));
+ for (int i = 0; i < res.nscount; ++i) {
+ IPEndPoint ipe;
+ ASSERT_TRUE(ipe.FromSockAddr(
+ reinterpret_cast<const struct sockaddr*>(&res.nsaddr_list[i]),
+ sizeof res.nsaddr_list[i]));
+ EXPECT_EQ(config.nameservers[i], ipe);
+ }
+ // compare search
+ ASSERT_TRUE(res.dnsrch[config.search.size()] == NULL);
+ for (unsigned i = 0; i < config.search.size(); ++i) {
+ EXPECT_EQ(config.search[i], res.dnsrch[i]);
+ }
+ }
+
+ bool WaitForConfig() WARN_UNUSED_RESULT {
+ return completion_.Wait(); // TODO(szym): add timeout?
+ }
+
+ private:
+ base::WaitableEvent completion_;
+ scoped_refptr<TestObserver> delegate_;
+ base::Thread service_thread_;
+};
+
+TEST_F(DnsConfigServiceTest, VerifyWithResInit) {
+ StartWatch();
+ // NOTE: res_init() initializes __res_state.retry (DnsConfig::attempts) to 4
+ // while res_ninit() initializes it to 2, so we can't mix them in this test.
+ struct __res_state res;
+ 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.
+
+ ASSERT_TRUE(res.options & RES_INIT);
+ ASSERT_TRUE(WaitForConfig());
+ CheckConfig(res);
+}
+
+// TODO(szym) do the same but touch /etc/resolv.conf
+}
+
+} // namespace net
+

Powered by Google App Engine
This is Rietveld 408576698