]> git.proxmox.com Git - ceph.git/blob - ceph/src/test/common/dns_resolve.cc
e5b1e5f7b9defb83650c14ecc6d4478b4457a363
[ceph.git] / ceph / src / test / common / dns_resolve.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3 /*
4 * Ceph - scalable distributed file system
5 *
6 * Copyright (C) 2016 SUSE LINUX GmbH
7 *
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.
12 *
13 */
14 #include <arpa/nameser_compat.h>
15
16 #include "common/dns_resolve.h"
17 #include "test/common/dns_messages.h"
18
19 #include "common/debug.h"
20 #include "gmock/gmock.h"
21
22
23 #include <sstream>
24
25 #define TEST_DEBUG 20
26
27 #define dout_subsys ceph_subsys_
28
29
30 using ::testing::Return;
31 using ::testing::_;
32 using ::testing::SetArrayArgument;
33 using ::testing::DoAll;
34 using ::testing::StrEq;
35
36 class DNSResolverTest : public ::testing::Test {
37 protected:
38 void SetUp() override {
39 g_ceph_context->_conf->subsys.set_log_level(dout_subsys, TEST_DEBUG);
40 }
41
42 void TearDown() override {
43 DNSResolver::get_instance(nullptr);
44 }
45 };
46
47 TEST_F(DNSResolverTest, resolve_ip_addr) {
48 MockResolvHWrapper *resolvH = new MockResolvHWrapper();
49
50 int lena = sizeof(ns_query_msg_mon_a_payload);
51 #ifdef HAVE_RES_NQUERY
52 EXPECT_CALL(*resolvH, res_nquery(_,StrEq("mon.a.ceph.com"), C_IN, T_A,_,_))
53 .WillOnce(DoAll(SetArrayArgument<4>(ns_query_msg_mon_a_payload,
54 ns_query_msg_mon_a_payload+lena), Return(lena)));
55 #else
56 EXPECT_CALL(*resolvH, res_query(StrEq("mon.a.ceph.com"), C_IN, T_A,_,_))
57 .WillOnce(DoAll(SetArrayArgument<3>(ns_query_msg_mon_a_payload,
58 ns_query_msg_mon_a_payload+lena), Return(lena)));
59 #endif
60
61 entity_addr_t addr;
62 DNSResolver::get_instance(resolvH)->resolve_ip_addr(g_ceph_context,
63 "mon.a.ceph.com", &addr);
64
65 std::ostringstream os;
66 os << addr;
67 ASSERT_EQ(os.str(), "v2:192.168.1.11:0/0");
68 }
69
70 TEST_F(DNSResolverTest, resolve_ip_addr_fail) {
71 MockResolvHWrapper *resolvH = new MockResolvHWrapper();
72
73 #ifdef HAVE_RES_NQUERY
74 EXPECT_CALL(*resolvH, res_nquery(_,StrEq("not_exists.com"), C_IN, T_A,_,_))
75 .WillOnce(Return(0));
76 #else
77 EXPECT_CALL(*resolvH, res_query(StrEq("not_exists.com"), C_IN, T_A,_,_))
78 .WillOnce(Return(0));
79 #endif
80
81 entity_addr_t addr;
82 int ret = DNSResolver::get_instance(resolvH)->resolve_ip_addr(g_ceph_context,
83 "not_exists.com", &addr);
84
85 ASSERT_EQ(ret, -1);
86 std::ostringstream os;
87 os << addr;
88 ASSERT_EQ(os.str(), "-");
89 }
90
91
92 TEST_F(DNSResolverTest, resolve_srv_hosts_empty_domain) {
93 MockResolvHWrapper *resolvH = new MockResolvHWrapper();
94
95
96 int len = sizeof(ns_search_msg_ok_payload);
97 int lena = sizeof(ns_query_msg_mon_a_payload);
98 int lenb = sizeof(ns_query_msg_mon_b_payload);
99 int lenc = sizeof(ns_query_msg_mon_c_payload);
100
101 using ::testing::InSequence;
102 {
103 InSequence s;
104
105 #ifdef HAVE_RES_NQUERY
106 EXPECT_CALL(*resolvH, res_nsearch(_, StrEq("_cephmon._tcp"), C_IN, T_SRV, _, _))
107 .WillOnce(DoAll(SetArrayArgument<4>(ns_search_msg_ok_payload,
108 ns_search_msg_ok_payload+len), Return(len)));
109
110 EXPECT_CALL(*resolvH, res_nquery(_,StrEq("mon.a.ceph.com"), C_IN, T_A,_,_))
111 .WillOnce(DoAll(SetArrayArgument<4>(ns_query_msg_mon_a_payload,
112 ns_query_msg_mon_a_payload+lena), Return(lena)));
113
114 EXPECT_CALL(*resolvH, res_nquery(_, StrEq("mon.c.ceph.com"), C_IN, T_A,_,_))
115 .WillOnce(DoAll(SetArrayArgument<4>(ns_query_msg_mon_c_payload,
116 ns_query_msg_mon_c_payload+lenc), Return(lenc)));
117
118 EXPECT_CALL(*resolvH, res_nquery(_,StrEq("mon.b.ceph.com"), C_IN, T_A, _,_))
119 .WillOnce(DoAll(SetArrayArgument<4>(ns_query_msg_mon_b_payload,
120 ns_query_msg_mon_b_payload+lenb), Return(lenb)));
121 #else
122 EXPECT_CALL(*resolvH, res_search(StrEq("_cephmon._tcp"), C_IN, T_SRV, _, _))
123 .WillOnce(DoAll(SetArrayArgument<3>(ns_search_msg_ok_payload,
124 ns_search_msg_ok_payload+len), Return(len)));
125
126 EXPECT_CALL(*resolvH, res_query(StrEq("mon.a.ceph.com"), C_IN, T_A,_,_))
127 .WillOnce(DoAll(SetArrayArgument<3>(ns_query_msg_mon_a_payload,
128 ns_query_msg_mon_a_payload+lena), Return(lena)));
129
130 EXPECT_CALL(*resolvH, res_query(StrEq("mon.c.ceph.com"), C_IN, T_A,_,_))
131 .WillOnce(DoAll(SetArrayArgument<3>(ns_query_msg_mon_c_payload,
132 ns_query_msg_mon_c_payload+lenc), Return(lenc)));
133
134 EXPECT_CALL(*resolvH, res_query(StrEq("mon.b.ceph.com"), C_IN, T_A, _,_))
135 .WillOnce(DoAll(SetArrayArgument<3>(ns_query_msg_mon_b_payload,
136 ns_query_msg_mon_b_payload+lenb), Return(lenb)));
137 #endif
138 }
139
140 map<string, DNSResolver::Record> records;
141 DNSResolver::get_instance(resolvH)->resolve_srv_hosts(g_ceph_context, "cephmon",
142 DNSResolver::SRV_Protocol::TCP, &records);
143
144 ASSERT_EQ(records.size(), (unsigned int)3);
145 auto it = records.find("mon.a");
146 ASSERT_NE(it, records.end());
147 std::ostringstream os;
148 os << it->second.addr;
149 ASSERT_EQ(os.str(), "v2:192.168.1.11:6789/0");
150 os.str("");
151 ASSERT_EQ(it->second.priority, 10);
152 ASSERT_EQ(it->second.weight, 40);
153 it = records.find("mon.b");
154 ASSERT_NE(it, records.end());
155 os << it->second.addr;
156 ASSERT_EQ(os.str(), "v2:192.168.1.12:6789/0");
157 os.str("");
158 ASSERT_EQ(it->second.priority, 10);
159 ASSERT_EQ(it->second.weight, 35);
160 it = records.find("mon.c");
161 ASSERT_NE(it, records.end());
162 os << it->second.addr;
163 ASSERT_EQ(os.str(), "v2:192.168.1.13:6789/0");
164 ASSERT_EQ(it->second.priority, 10);
165 ASSERT_EQ(it->second.weight, 25);
166 }
167
168 TEST_F(DNSResolverTest, resolve_srv_hosts_full_domain) {
169 MockResolvHWrapper *resolvH = new MockResolvHWrapper();
170
171
172 int len = sizeof(ns_search_msg_ok_payload);
173 int lena = sizeof(ns_query_msg_mon_a_payload);
174 int lenb = sizeof(ns_query_msg_mon_b_payload);
175 int lenc = sizeof(ns_query_msg_mon_c_payload);
176
177 using ::testing::InSequence;
178 {
179 InSequence s;
180
181 #ifdef HAVE_RES_NQUERY
182 EXPECT_CALL(*resolvH, res_nsearch(_, StrEq("_cephmon._tcp.ceph.com"), C_IN, T_SRV, _, _))
183 .WillOnce(DoAll(SetArrayArgument<4>(ns_search_msg_ok_payload,
184 ns_search_msg_ok_payload+len), Return(len)));
185
186 EXPECT_CALL(*resolvH, res_nquery(_,StrEq("mon.a.ceph.com"), C_IN, T_A,_,_))
187 .WillOnce(DoAll(SetArrayArgument<4>(ns_query_msg_mon_a_payload,
188 ns_query_msg_mon_a_payload+lena), Return(lena)));
189
190 EXPECT_CALL(*resolvH, res_nquery(_, StrEq("mon.c.ceph.com"), C_IN, T_A,_,_))
191 .WillOnce(DoAll(SetArrayArgument<4>(ns_query_msg_mon_c_payload,
192 ns_query_msg_mon_c_payload+lenc), Return(lenc)));
193
194 EXPECT_CALL(*resolvH, res_nquery(_,StrEq("mon.b.ceph.com"), C_IN, T_A, _,_))
195 .WillOnce(DoAll(SetArrayArgument<4>(ns_query_msg_mon_b_payload,
196 ns_query_msg_mon_b_payload+lenb), Return(lenb)));
197 #else
198 EXPECT_CALL(*resolvH, res_search(StrEq("_cephmon._tcp.ceph.com"), C_IN, T_SRV, _, _))
199 .WillOnce(DoAll(SetArrayArgument<3>(ns_search_msg_ok_payload,
200 ns_search_msg_ok_payload+len), Return(len)));
201
202 EXPECT_CALL(*resolvH, res_query(StrEq("mon.a.ceph.com"), C_IN, T_A,_,_))
203 .WillOnce(DoAll(SetArrayArgument<3>(ns_query_msg_mon_a_payload,
204 ns_query_msg_mon_a_payload+lena), Return(lena)));
205
206 EXPECT_CALL(*resolvH, res_query(StrEq("mon.c.ceph.com"), C_IN, T_A,_,_))
207 .WillOnce(DoAll(SetArrayArgument<3>(ns_query_msg_mon_c_payload,
208 ns_query_msg_mon_c_payload+lenc), Return(lenc)));
209
210 EXPECT_CALL(*resolvH, res_query(StrEq("mon.b.ceph.com"), C_IN, T_A, _,_))
211 .WillOnce(DoAll(SetArrayArgument<3>(ns_query_msg_mon_b_payload,
212 ns_query_msg_mon_b_payload+lenb), Return(lenb)));
213 #endif
214 }
215
216 map<string, DNSResolver::Record> records;
217 DNSResolver::get_instance(resolvH)->resolve_srv_hosts(g_ceph_context, "cephmon",
218 DNSResolver::SRV_Protocol::TCP, "ceph.com", &records);
219
220 ASSERT_EQ(records.size(), (unsigned int)3);
221 auto it = records.find("mon.a");
222 ASSERT_NE(it, records.end());
223 std::ostringstream os;
224 os << it->second.addr;
225 ASSERT_EQ(os.str(), "v2:192.168.1.11:6789/0");
226 os.str("");
227 it = records.find("mon.b");
228 ASSERT_NE(it, records.end());
229 os << it->second.addr;
230 ASSERT_EQ(os.str(), "v2:192.168.1.12:6789/0");
231 os.str("");
232 it = records.find("mon.c");
233 ASSERT_NE(it, records.end());
234 os << it->second.addr;
235 ASSERT_EQ(os.str(), "v2:192.168.1.13:6789/0");
236 }
237
238 TEST_F(DNSResolverTest, resolve_srv_hosts_fail) {
239 MockResolvHWrapper *resolvH = new MockResolvHWrapper();
240
241
242 using ::testing::InSequence;
243 {
244 InSequence s;
245
246 #ifdef HAVE_RES_NQUERY
247 EXPECT_CALL(*resolvH, res_nsearch(_, StrEq("_noservice._tcp"), C_IN, T_SRV, _, _))
248 .WillOnce(Return(0));
249 #else
250 EXPECT_CALL(*resolvH, res_search(StrEq("_noservice._tcp"), C_IN, T_SRV, _, _))
251 .WillOnce(Return(0));
252 #endif
253 }
254
255 map<string, DNSResolver::Record> records;
256 int ret = DNSResolver::get_instance(resolvH)->resolve_srv_hosts(
257 g_ceph_context, "noservice", DNSResolver::SRV_Protocol::TCP, "", &records);
258
259 ASSERT_EQ(0, ret);
260 ASSERT_TRUE(records.empty());
261 }
262