]> git.proxmox.com Git - ceph.git/blob - ceph/src/test/common/dns_resolve.cc
bump version to 18.2.2-pve1
[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 using namespace std;
30
31 using ::testing::Return;
32 using ::testing::_;
33 using ::testing::SetArrayArgument;
34 using ::testing::DoAll;
35 using ::testing::StrEq;
36
37 class DNSResolverTest : public ::testing::Test {
38 protected:
39 void SetUp() override {
40 g_ceph_context->_conf->subsys.set_log_level(dout_subsys, TEST_DEBUG);
41 }
42
43 void TearDown() override {
44 DNSResolver::get_instance(nullptr);
45 }
46 };
47
48 TEST_F(DNSResolverTest, resolve_ip_addr) {
49 MockResolvHWrapper *resolvH = new MockResolvHWrapper();
50
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)));
56 #else
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)));
60 #endif
61
62 entity_addr_t addr;
63 DNSResolver::get_instance(resolvH)->resolve_ip_addr(g_ceph_context,
64 "mon.a.ceph.com", &addr);
65
66 std::ostringstream os;
67 os << addr;
68 ASSERT_EQ(os.str(), "v2:192.168.1.11:0/0");
69 }
70
71 TEST_F(DNSResolverTest, resolve_ip_addr_fail) {
72 MockResolvHWrapper *resolvH = new MockResolvHWrapper();
73
74 #ifdef HAVE_RES_NQUERY
75 EXPECT_CALL(*resolvH, res_nquery(_,StrEq("not_exists.com"), C_IN, T_A,_,_))
76 .WillOnce(Return(0));
77 #else
78 EXPECT_CALL(*resolvH, res_query(StrEq("not_exists.com"), C_IN, T_A,_,_))
79 .WillOnce(Return(0));
80 #endif
81
82 entity_addr_t addr;
83 int ret = DNSResolver::get_instance(resolvH)->resolve_ip_addr(g_ceph_context,
84 "not_exists.com", &addr);
85
86 ASSERT_EQ(ret, -1);
87 std::ostringstream os;
88 os << addr;
89 ASSERT_EQ(os.str(), "-");
90 }
91
92
93 TEST_F(DNSResolverTest, resolve_srv_hosts_empty_domain) {
94 MockResolvHWrapper *resolvH = new MockResolvHWrapper();
95
96
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);
101
102 using ::testing::InSequence;
103 {
104 InSequence s;
105
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)));
110
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)));
114
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)));
118
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)));
122 #else
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)));
126
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)));
130
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)));
134
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)));
138 #endif
139 }
140
141 map<string, DNSResolver::Record> records;
142 DNSResolver::get_instance(resolvH)->resolve_srv_hosts(g_ceph_context, "cephmon",
143 DNSResolver::SRV_Protocol::TCP, &records);
144
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");
151 os.str("");
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");
158 os.str("");
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);
167 }
168
169 TEST_F(DNSResolverTest, resolve_srv_hosts_full_domain) {
170 MockResolvHWrapper *resolvH = new MockResolvHWrapper();
171
172
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);
177
178 using ::testing::InSequence;
179 {
180 InSequence s;
181
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)));
186
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)));
190
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)));
194
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)));
198 #else
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)));
202
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)));
206
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)));
210
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)));
214 #endif
215 }
216
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);
220
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");
227 os.str("");
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");
232 os.str("");
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");
237 }
238
239 TEST_F(DNSResolverTest, resolve_srv_hosts_fail) {
240 MockResolvHWrapper *resolvH = new MockResolvHWrapper();
241
242
243 using ::testing::InSequence;
244 {
245 InSequence s;
246
247 #ifdef HAVE_RES_NQUERY
248 EXPECT_CALL(*resolvH, res_nsearch(_, StrEq("_noservice._tcp"), C_IN, T_SRV, _, _))
249 .WillOnce(Return(0));
250 #else
251 EXPECT_CALL(*resolvH, res_search(StrEq("_noservice._tcp"), C_IN, T_SRV, _, _))
252 .WillOnce(Return(0));
253 #endif
254 }
255
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);
259
260 ASSERT_EQ(0, ret);
261 ASSERT_TRUE(records.empty());
262 }
263