1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 * Ceph - scalable distributed file system
6 * Copyright (C) 2016 SUSE LINUX GmbH
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
14 #include <arpa/nameser_compat.h>
16 #include "common/dns_resolve.h"
17 #include "test/common/dns_messages.h"
19 #include "common/debug.h"
20 #include "gmock/gmock.h"
27 #define dout_subsys ceph_subsys_
31 using ::testing::Return
;
33 using ::testing::SetArrayArgument
;
34 using ::testing::DoAll
;
35 using ::testing::StrEq
;
37 class DNSResolverTest
: public ::testing::Test
{
39 void SetUp() override
{
40 g_ceph_context
->_conf
->subsys
.set_log_level(dout_subsys
, TEST_DEBUG
);
43 void TearDown() override
{
44 DNSResolver::get_instance(nullptr);
48 TEST_F(DNSResolverTest
, resolve_ip_addr
) {
49 MockResolvHWrapper
*resolvH
= new MockResolvHWrapper();
51 int lena
= sizeof(ns_query_msg_mon_a_payload
);
52 #ifdef HAVE_RES_NQUERY
53 EXPECT_CALL(*resolvH
, res_nquery(_
,StrEq("mon.a.ceph.com"), C_IN
, T_A
,_
,_
))
54 .WillOnce(DoAll(SetArrayArgument
<4>(ns_query_msg_mon_a_payload
,
55 ns_query_msg_mon_a_payload
+lena
), Return(lena
)));
57 EXPECT_CALL(*resolvH
, res_query(StrEq("mon.a.ceph.com"), C_IN
, T_A
,_
,_
))
58 .WillOnce(DoAll(SetArrayArgument
<3>(ns_query_msg_mon_a_payload
,
59 ns_query_msg_mon_a_payload
+lena
), Return(lena
)));
63 DNSResolver::get_instance(resolvH
)->resolve_ip_addr(g_ceph_context
,
64 "mon.a.ceph.com", &addr
);
66 std::ostringstream os
;
68 ASSERT_EQ(os
.str(), "v2:192.168.1.11:0/0");
71 TEST_F(DNSResolverTest
, resolve_ip_addr_fail
) {
72 MockResolvHWrapper
*resolvH
= new MockResolvHWrapper();
74 #ifdef HAVE_RES_NQUERY
75 EXPECT_CALL(*resolvH
, res_nquery(_
,StrEq("not_exists.com"), C_IN
, T_A
,_
,_
))
78 EXPECT_CALL(*resolvH
, res_query(StrEq("not_exists.com"), C_IN
, T_A
,_
,_
))
83 int ret
= DNSResolver::get_instance(resolvH
)->resolve_ip_addr(g_ceph_context
,
84 "not_exists.com", &addr
);
87 std::ostringstream os
;
89 ASSERT_EQ(os
.str(), "-");
93 TEST_F(DNSResolverTest
, resolve_srv_hosts_empty_domain
) {
94 MockResolvHWrapper
*resolvH
= new MockResolvHWrapper();
97 int len
= sizeof(ns_search_msg_ok_payload
);
98 int lena
= sizeof(ns_query_msg_mon_a_payload
);
99 int lenb
= sizeof(ns_query_msg_mon_b_payload
);
100 int lenc
= sizeof(ns_query_msg_mon_c_payload
);
102 using ::testing::InSequence
;
106 #ifdef HAVE_RES_NQUERY
107 EXPECT_CALL(*resolvH
, res_nsearch(_
, StrEq("_cephmon._tcp"), C_IN
, T_SRV
, _
, _
))
108 .WillOnce(DoAll(SetArrayArgument
<4>(ns_search_msg_ok_payload
,
109 ns_search_msg_ok_payload
+len
), Return(len
)));
111 EXPECT_CALL(*resolvH
, res_nquery(_
,StrEq("mon.a.ceph.com"), C_IN
, T_A
,_
,_
))
112 .WillOnce(DoAll(SetArrayArgument
<4>(ns_query_msg_mon_a_payload
,
113 ns_query_msg_mon_a_payload
+lena
), Return(lena
)));
115 EXPECT_CALL(*resolvH
, res_nquery(_
, StrEq("mon.c.ceph.com"), C_IN
, T_A
,_
,_
))
116 .WillOnce(DoAll(SetArrayArgument
<4>(ns_query_msg_mon_c_payload
,
117 ns_query_msg_mon_c_payload
+lenc
), Return(lenc
)));
119 EXPECT_CALL(*resolvH
, res_nquery(_
,StrEq("mon.b.ceph.com"), C_IN
, T_A
, _
,_
))
120 .WillOnce(DoAll(SetArrayArgument
<4>(ns_query_msg_mon_b_payload
,
121 ns_query_msg_mon_b_payload
+lenb
), Return(lenb
)));
123 EXPECT_CALL(*resolvH
, res_search(StrEq("_cephmon._tcp"), C_IN
, T_SRV
, _
, _
))
124 .WillOnce(DoAll(SetArrayArgument
<3>(ns_search_msg_ok_payload
,
125 ns_search_msg_ok_payload
+len
), Return(len
)));
127 EXPECT_CALL(*resolvH
, res_query(StrEq("mon.a.ceph.com"), C_IN
, T_A
,_
,_
))
128 .WillOnce(DoAll(SetArrayArgument
<3>(ns_query_msg_mon_a_payload
,
129 ns_query_msg_mon_a_payload
+lena
), Return(lena
)));
131 EXPECT_CALL(*resolvH
, res_query(StrEq("mon.c.ceph.com"), C_IN
, T_A
,_
,_
))
132 .WillOnce(DoAll(SetArrayArgument
<3>(ns_query_msg_mon_c_payload
,
133 ns_query_msg_mon_c_payload
+lenc
), Return(lenc
)));
135 EXPECT_CALL(*resolvH
, res_query(StrEq("mon.b.ceph.com"), C_IN
, T_A
, _
,_
))
136 .WillOnce(DoAll(SetArrayArgument
<3>(ns_query_msg_mon_b_payload
,
137 ns_query_msg_mon_b_payload
+lenb
), Return(lenb
)));
141 map
<string
, DNSResolver::Record
> records
;
142 DNSResolver::get_instance(resolvH
)->resolve_srv_hosts(g_ceph_context
, "cephmon",
143 DNSResolver::SRV_Protocol::TCP
, &records
);
145 ASSERT_EQ(records
.size(), (unsigned int)3);
146 auto it
= records
.find("mon.a");
147 ASSERT_NE(it
, records
.end());
148 std::ostringstream os
;
149 os
<< it
->second
.addr
;
150 ASSERT_EQ(os
.str(), "v2:192.168.1.11:6789/0");
152 ASSERT_EQ(it
->second
.priority
, 10);
153 ASSERT_EQ(it
->second
.weight
, 40);
154 it
= records
.find("mon.b");
155 ASSERT_NE(it
, records
.end());
156 os
<< it
->second
.addr
;
157 ASSERT_EQ(os
.str(), "v2:192.168.1.12:6789/0");
159 ASSERT_EQ(it
->second
.priority
, 10);
160 ASSERT_EQ(it
->second
.weight
, 35);
161 it
= records
.find("mon.c");
162 ASSERT_NE(it
, records
.end());
163 os
<< it
->second
.addr
;
164 ASSERT_EQ(os
.str(), "v2:192.168.1.13:6789/0");
165 ASSERT_EQ(it
->second
.priority
, 10);
166 ASSERT_EQ(it
->second
.weight
, 25);
169 TEST_F(DNSResolverTest
, resolve_srv_hosts_full_domain
) {
170 MockResolvHWrapper
*resolvH
= new MockResolvHWrapper();
173 int len
= sizeof(ns_search_msg_ok_payload
);
174 int lena
= sizeof(ns_query_msg_mon_a_payload
);
175 int lenb
= sizeof(ns_query_msg_mon_b_payload
);
176 int lenc
= sizeof(ns_query_msg_mon_c_payload
);
178 using ::testing::InSequence
;
182 #ifdef HAVE_RES_NQUERY
183 EXPECT_CALL(*resolvH
, res_nsearch(_
, StrEq("_cephmon._tcp.ceph.com"), C_IN
, T_SRV
, _
, _
))
184 .WillOnce(DoAll(SetArrayArgument
<4>(ns_search_msg_ok_payload
,
185 ns_search_msg_ok_payload
+len
), Return(len
)));
187 EXPECT_CALL(*resolvH
, res_nquery(_
,StrEq("mon.a.ceph.com"), C_IN
, T_A
,_
,_
))
188 .WillOnce(DoAll(SetArrayArgument
<4>(ns_query_msg_mon_a_payload
,
189 ns_query_msg_mon_a_payload
+lena
), Return(lena
)));
191 EXPECT_CALL(*resolvH
, res_nquery(_
, StrEq("mon.c.ceph.com"), C_IN
, T_A
,_
,_
))
192 .WillOnce(DoAll(SetArrayArgument
<4>(ns_query_msg_mon_c_payload
,
193 ns_query_msg_mon_c_payload
+lenc
), Return(lenc
)));
195 EXPECT_CALL(*resolvH
, res_nquery(_
,StrEq("mon.b.ceph.com"), C_IN
, T_A
, _
,_
))
196 .WillOnce(DoAll(SetArrayArgument
<4>(ns_query_msg_mon_b_payload
,
197 ns_query_msg_mon_b_payload
+lenb
), Return(lenb
)));
199 EXPECT_CALL(*resolvH
, res_search(StrEq("_cephmon._tcp.ceph.com"), C_IN
, T_SRV
, _
, _
))
200 .WillOnce(DoAll(SetArrayArgument
<3>(ns_search_msg_ok_payload
,
201 ns_search_msg_ok_payload
+len
), Return(len
)));
203 EXPECT_CALL(*resolvH
, res_query(StrEq("mon.a.ceph.com"), C_IN
, T_A
,_
,_
))
204 .WillOnce(DoAll(SetArrayArgument
<3>(ns_query_msg_mon_a_payload
,
205 ns_query_msg_mon_a_payload
+lena
), Return(lena
)));
207 EXPECT_CALL(*resolvH
, res_query(StrEq("mon.c.ceph.com"), C_IN
, T_A
,_
,_
))
208 .WillOnce(DoAll(SetArrayArgument
<3>(ns_query_msg_mon_c_payload
,
209 ns_query_msg_mon_c_payload
+lenc
), Return(lenc
)));
211 EXPECT_CALL(*resolvH
, res_query(StrEq("mon.b.ceph.com"), C_IN
, T_A
, _
,_
))
212 .WillOnce(DoAll(SetArrayArgument
<3>(ns_query_msg_mon_b_payload
,
213 ns_query_msg_mon_b_payload
+lenb
), Return(lenb
)));
217 map
<string
, DNSResolver::Record
> records
;
218 DNSResolver::get_instance(resolvH
)->resolve_srv_hosts(g_ceph_context
, "cephmon",
219 DNSResolver::SRV_Protocol::TCP
, "ceph.com", &records
);
221 ASSERT_EQ(records
.size(), (unsigned int)3);
222 auto it
= records
.find("mon.a");
223 ASSERT_NE(it
, records
.end());
224 std::ostringstream os
;
225 os
<< it
->second
.addr
;
226 ASSERT_EQ(os
.str(), "v2:192.168.1.11:6789/0");
228 it
= records
.find("mon.b");
229 ASSERT_NE(it
, records
.end());
230 os
<< it
->second
.addr
;
231 ASSERT_EQ(os
.str(), "v2:192.168.1.12:6789/0");
233 it
= records
.find("mon.c");
234 ASSERT_NE(it
, records
.end());
235 os
<< it
->second
.addr
;
236 ASSERT_EQ(os
.str(), "v2:192.168.1.13:6789/0");
239 TEST_F(DNSResolverTest
, resolve_srv_hosts_fail
) {
240 MockResolvHWrapper
*resolvH
= new MockResolvHWrapper();
243 using ::testing::InSequence
;
247 #ifdef HAVE_RES_NQUERY
248 EXPECT_CALL(*resolvH
, res_nsearch(_
, StrEq("_noservice._tcp"), C_IN
, T_SRV
, _
, _
))
249 .WillOnce(Return(0));
251 EXPECT_CALL(*resolvH
, res_search(StrEq("_noservice._tcp"), C_IN
, T_SRV
, _
, _
))
252 .WillOnce(Return(0));
256 map
<string
, DNSResolver::Record
> records
;
257 int ret
= DNSResolver::get_instance(resolvH
)->resolve_srv_hosts(
258 g_ceph_context
, "noservice", DNSResolver::SRV_Protocol::TCP
, "", &records
);
261 ASSERT_TRUE(records
.empty());