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 "common/dns_resolve.h"
15 #include "test/common/dns_messages.h"
17 #include "common/debug.h"
18 #include "gmock/gmock.h"
25 #define dout_subsys ceph_subsys_
28 using ::testing::Return;
30 using ::testing::SetArrayArgument;
31 using ::testing::DoAll;
32 using ::testing::StrEq;
34 class DNSResolverTest : public ::testing::Test {
36 void SetUp() override {
37 g_ceph_context->_conf->subsys.set_log_level(dout_subsys, TEST_DEBUG);
40 void TearDown() override {
41 DNSResolver::get_instance(nullptr);
45 TEST_F(DNSResolverTest, resolve_ip_addr) {
46 MockResolvHWrapper *resolvH = new MockResolvHWrapper();
48 int lena = sizeof(ns_query_msg_mon_a_payload);
49 #ifdef HAVE_RES_NQUERY
50 EXPECT_CALL(*resolvH, res_nquery(_,StrEq("mon.a.ceph.com"), C_IN, T_A,_,_))
51 .WillOnce(DoAll(SetArrayArgument<4>(ns_query_msg_mon_a_payload,
52 ns_query_msg_mon_a_payload+lena), Return(lena)));
54 EXPECT_CALL(*resolvH, res_query(StrEq("mon.a.ceph.com"), C_IN, T_A,_,_))
55 .WillOnce(DoAll(SetArrayArgument<3>(ns_query_msg_mon_a_payload,
56 ns_query_msg_mon_a_payload+lena), Return(lena)));
60 DNSResolver::get_instance(resolvH)->resolve_ip_addr(g_ceph_context,
61 "mon.a.ceph.com", &addr);
63 std::ostringstream os;
65 ASSERT_EQ(os.str(), "192.168.1.11:0/0");
68 TEST_F(DNSResolverTest, resolve_ip_addr_fail) {
69 MockResolvHWrapper *resolvH = new MockResolvHWrapper();
71 #ifdef HAVE_RES_NQUERY
72 EXPECT_CALL(*resolvH, res_nquery(_,StrEq("not_exists.com"), C_IN, T_A,_,_))
75 EXPECT_CALL(*resolvH, res_query(StrEq("not_exists.com"), C_IN, T_A,_,_))
80 int ret = DNSResolver::get_instance(resolvH)->resolve_ip_addr(g_ceph_context,
81 "not_exists.com", &addr);
84 std::ostringstream os;
86 ASSERT_EQ(os.str(), "-");
90 TEST_F(DNSResolverTest, resolve_srv_hosts_empty_domain) {
91 MockResolvHWrapper *resolvH = new MockResolvHWrapper();
94 int len = sizeof(ns_search_msg_ok_payload);
95 int lena = sizeof(ns_query_msg_mon_a_payload);
96 int lenb = sizeof(ns_query_msg_mon_b_payload);
97 int lenc = sizeof(ns_query_msg_mon_c_payload);
99 using ::testing::InSequence;
103 #ifdef HAVE_RES_NQUERY
104 EXPECT_CALL(*resolvH, res_nsearch(_, StrEq("_cephmon._tcp"), C_IN, T_SRV, _, _))
105 .WillOnce(DoAll(SetArrayArgument<4>(ns_search_msg_ok_payload,
106 ns_search_msg_ok_payload+len), Return(len)));
108 EXPECT_CALL(*resolvH, res_nquery(_,StrEq("mon.a.ceph.com"), C_IN, T_A,_,_))
109 .WillOnce(DoAll(SetArrayArgument<4>(ns_query_msg_mon_a_payload,
110 ns_query_msg_mon_a_payload+lena), Return(lena)));
112 EXPECT_CALL(*resolvH, res_nquery(_, StrEq("mon.c.ceph.com"), C_IN, T_A,_,_))
113 .WillOnce(DoAll(SetArrayArgument<4>(ns_query_msg_mon_c_payload,
114 ns_query_msg_mon_c_payload+lenc), Return(lenc)));
116 EXPECT_CALL(*resolvH, res_nquery(_,StrEq("mon.b.ceph.com"), C_IN, T_A, _,_))
117 .WillOnce(DoAll(SetArrayArgument<4>(ns_query_msg_mon_b_payload,
118 ns_query_msg_mon_b_payload+lenb), Return(lenb)));
120 EXPECT_CALL(*resolvH, res_search(StrEq("_cephmon._tcp"), C_IN, T_SRV, _, _))
121 .WillOnce(DoAll(SetArrayArgument<3>(ns_search_msg_ok_payload,
122 ns_search_msg_ok_payload+len), Return(len)));
124 EXPECT_CALL(*resolvH, res_query(StrEq("mon.a.ceph.com"), C_IN, T_A,_,_))
125 .WillOnce(DoAll(SetArrayArgument<3>(ns_query_msg_mon_a_payload,
126 ns_query_msg_mon_a_payload+lena), Return(lena)));
128 EXPECT_CALL(*resolvH, res_query(StrEq("mon.c.ceph.com"), C_IN, T_A,_,_))
129 .WillOnce(DoAll(SetArrayArgument<3>(ns_query_msg_mon_c_payload,
130 ns_query_msg_mon_c_payload+lenc), Return(lenc)));
132 EXPECT_CALL(*resolvH, res_query(StrEq("mon.b.ceph.com"), C_IN, T_A, _,_))
133 .WillOnce(DoAll(SetArrayArgument<3>(ns_query_msg_mon_b_payload,
134 ns_query_msg_mon_b_payload+lenb), Return(lenb)));
138 map<string, DNSResolver::Record> records;
139 DNSResolver::get_instance(resolvH)->resolve_srv_hosts(g_ceph_context, "cephmon",
140 DNSResolver::SRV_Protocol::TCP, &records);
142 ASSERT_EQ(records.size(), (unsigned int)3);
143 auto it = records.find("mon.a");
144 ASSERT_NE(it, records.end());
145 std::ostringstream os;
146 os << it->second.addr;
147 ASSERT_EQ(os.str(), "192.168.1.11:6789/0");
149 it = records.find("mon.b");
150 ASSERT_NE(it, records.end());
151 os << it->second.addr;
152 ASSERT_EQ(os.str(), "192.168.1.12:6789/0");
154 it = records.find("mon.c");
155 ASSERT_NE(it, records.end());
156 os << it->second.addr;
157 ASSERT_EQ(os.str(), "192.168.1.13:6789/0");
160 TEST_F(DNSResolverTest, resolve_srv_hosts_full_domain) {
161 MockResolvHWrapper *resolvH = new MockResolvHWrapper();
164 int len = sizeof(ns_search_msg_ok_payload);
165 int lena = sizeof(ns_query_msg_mon_a_payload);
166 int lenb = sizeof(ns_query_msg_mon_b_payload);
167 int lenc = sizeof(ns_query_msg_mon_c_payload);
169 using ::testing::InSequence;
173 #ifdef HAVE_RES_NQUERY
174 EXPECT_CALL(*resolvH, res_nsearch(_, StrEq("_cephmon._tcp.ceph.com"), C_IN, T_SRV, _, _))
175 .WillOnce(DoAll(SetArrayArgument<4>(ns_search_msg_ok_payload,
176 ns_search_msg_ok_payload+len), Return(len)));
178 EXPECT_CALL(*resolvH, res_nquery(_,StrEq("mon.a.ceph.com"), C_IN, T_A,_,_))
179 .WillOnce(DoAll(SetArrayArgument<4>(ns_query_msg_mon_a_payload,
180 ns_query_msg_mon_a_payload+lena), Return(lena)));
182 EXPECT_CALL(*resolvH, res_nquery(_, StrEq("mon.c.ceph.com"), C_IN, T_A,_,_))
183 .WillOnce(DoAll(SetArrayArgument<4>(ns_query_msg_mon_c_payload,
184 ns_query_msg_mon_c_payload+lenc), Return(lenc)));
186 EXPECT_CALL(*resolvH, res_nquery(_,StrEq("mon.b.ceph.com"), C_IN, T_A, _,_))
187 .WillOnce(DoAll(SetArrayArgument<4>(ns_query_msg_mon_b_payload,
188 ns_query_msg_mon_b_payload+lenb), Return(lenb)));
190 EXPECT_CALL(*resolvH, res_search(StrEq("_cephmon._tcp.ceph.com"), C_IN, T_SRV, _, _))
191 .WillOnce(DoAll(SetArrayArgument<3>(ns_search_msg_ok_payload,
192 ns_search_msg_ok_payload+len), Return(len)));
194 EXPECT_CALL(*resolvH, res_query(StrEq("mon.a.ceph.com"), C_IN, T_A,_,_))
195 .WillOnce(DoAll(SetArrayArgument<3>(ns_query_msg_mon_a_payload,
196 ns_query_msg_mon_a_payload+lena), Return(lena)));
198 EXPECT_CALL(*resolvH, res_query(StrEq("mon.c.ceph.com"), C_IN, T_A,_,_))
199 .WillOnce(DoAll(SetArrayArgument<3>(ns_query_msg_mon_c_payload,
200 ns_query_msg_mon_c_payload+lenc), Return(lenc)));
202 EXPECT_CALL(*resolvH, res_query(StrEq("mon.b.ceph.com"), C_IN, T_A, _,_))
203 .WillOnce(DoAll(SetArrayArgument<3>(ns_query_msg_mon_b_payload,
204 ns_query_msg_mon_b_payload+lenb), Return(lenb)));
208 map<string, DNSResolver::Record> records;
209 DNSResolver::get_instance(resolvH)->resolve_srv_hosts(g_ceph_context, "cephmon",
210 DNSResolver::SRV_Protocol::TCP, "ceph.com", &records);
212 ASSERT_EQ(records.size(), (unsigned int)3);
213 auto it = records.find("mon.a");
214 ASSERT_NE(it, records.end());
215 std::ostringstream os;
216 os << it->second.addr;
217 ASSERT_EQ(os.str(), "192.168.1.11:6789/0");
219 it = records.find("mon.b");
220 ASSERT_NE(it, records.end());
221 os << it->second.addr;
222 ASSERT_EQ(os.str(), "192.168.1.12:6789/0");
224 it = records.find("mon.c");
225 ASSERT_NE(it, records.end());
226 os << it->second.addr;
227 ASSERT_EQ(os.str(), "192.168.1.13:6789/0");
230 TEST_F(DNSResolverTest, resolve_srv_hosts_fail) {
231 MockResolvHWrapper *resolvH = new MockResolvHWrapper();
234 using ::testing::InSequence;
238 #ifdef HAVE_RES_NQUERY
239 EXPECT_CALL(*resolvH, res_nsearch(_, StrEq("_noservice._tcp"), C_IN, T_SRV, _, _))
240 .WillOnce(Return(0));
242 EXPECT_CALL(*resolvH, res_search(StrEq("_noservice._tcp"), C_IN, T_SRV, _, _))
243 .WillOnce(Return(0));
247 map<string, DNSResolver::Record> records;
248 int ret = DNSResolver::get_instance(resolvH)->resolve_srv_hosts(
249 g_ceph_context, "noservice", DNSResolver::SRV_Protocol::TCP, "", &records);
252 ASSERT_TRUE(records.empty());