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 "mon/MonMap.h"
15 #include "common/ceph_context.h"
16 #include "common/dns_resolve.h"
17 #include "test/common/dns_messages.h"
19 #include "common/debug.h"
20 #include "gmock/gmock.h"
21 #include "gtest/gtest.h"
23 #include <boost/smart_ptr/intrusive_ptr.hpp>
29 #define dout_subsys ceph_subsys_mon
32 using ::testing::Return
;
34 using ::testing::SetArrayArgument
;
35 using ::testing::DoAll
;
36 using ::testing::StrEq
;
39 class MonMapTest
: public ::testing::Test
{
41 virtual void SetUp() {
42 g_ceph_context
->_conf
->subsys
.set_log_level(dout_subsys
, TEST_DEBUG
);
45 virtual void TearDown() {
46 DNSResolver::get_instance(nullptr);
50 TEST_F(MonMapTest
, DISABLED_build_initial_config_from_dns
) {
52 MockResolvHWrapper
*resolvH
= new MockResolvHWrapper();
53 DNSResolver::get_instance(resolvH
);
55 int len
= sizeof(ns_search_msg_ok_payload
);
56 int lena
= sizeof(ns_query_msg_mon_a_payload
);
57 int lenb
= sizeof(ns_query_msg_mon_b_payload
);
58 int lenc
= sizeof(ns_query_msg_mon_c_payload
);
60 using ::testing::InSequence
;
64 #ifdef HAVE_RES_NQUERY
65 EXPECT_CALL(*resolvH
, res_nsearch(_
, StrEq("_cephmon._tcp"), C_IN
, T_SRV
, _
, _
))
66 .WillOnce(DoAll(SetArrayArgument
<4>(ns_search_msg_ok_payload
,
67 ns_search_msg_ok_payload
+len
), Return(len
)));
69 EXPECT_CALL(*resolvH
, res_nquery(_
,StrEq("mon.a.ceph.com"), C_IN
, T_A
,_
,_
))
70 .WillOnce(DoAll(SetArrayArgument
<4>(ns_query_msg_mon_a_payload
,
71 ns_query_msg_mon_a_payload
+lena
), Return(lena
)));
73 EXPECT_CALL(*resolvH
, res_nquery(_
, StrEq("mon.c.ceph.com"), C_IN
, T_A
,_
,_
))
74 .WillOnce(DoAll(SetArrayArgument
<4>(ns_query_msg_mon_c_payload
,
75 ns_query_msg_mon_c_payload
+lenc
), Return(lenc
)));
77 EXPECT_CALL(*resolvH
, res_nquery(_
,StrEq("mon.b.ceph.com"), C_IN
, T_A
, _
,_
))
78 .WillOnce(DoAll(SetArrayArgument
<4>(ns_query_msg_mon_b_payload
,
79 ns_query_msg_mon_b_payload
+lenb
), Return(lenb
)));
81 EXPECT_CALL(*resolvH
, res_search(StrEq("_cephmon._tcp"), C_IN
, T_SRV
, _
, _
))
82 .WillOnce(DoAll(SetArrayArgument
<3>(ns_search_msg_ok_payload
,
83 ns_search_msg_ok_payload
+len
), Return(len
)));
85 EXPECT_CALL(*resolvH
, res_query(StrEq("mon.a.ceph.com"), C_IN
, T_A
,_
,_
))
86 .WillOnce(DoAll(SetArrayArgument
<3>(ns_query_msg_mon_a_payload
,
87 ns_query_msg_mon_a_payload
+lena
), Return(lena
)));
89 EXPECT_CALL(*resolvH
, res_query(StrEq("mon.c.ceph.com"), C_IN
, T_A
,_
,_
))
90 .WillOnce(DoAll(SetArrayArgument
<3>(ns_query_msg_mon_c_payload
,
91 ns_query_msg_mon_c_payload
+lenc
), Return(lenc
)));
93 EXPECT_CALL(*resolvH
, res_query(StrEq("mon.b.ceph.com"), C_IN
, T_A
, _
,_
))
94 .WillOnce(DoAll(SetArrayArgument
<3>(ns_query_msg_mon_b_payload
,
95 ns_query_msg_mon_b_payload
+lenb
), Return(lenb
)));
101 boost::intrusive_ptr
<CephContext
> cct
= new CephContext(CEPH_ENTITY_TYPE_MON
);
102 cct
->_conf
.set_val("mon_dns_srv_name", "cephmon");
104 int r
= monmap
.build_initial(cct
.get(), false, std::cerr
);
107 ASSERT_EQ(monmap
.mon_info
.size(), (unsigned int)3);
108 auto it
= monmap
.mon_info
.find("mon.a");
109 ASSERT_NE(it
, monmap
.mon_info
.end());
110 std::ostringstream os
;
111 os
<< it
->second
.public_addrs
;
112 ASSERT_EQ(os
.str(), "192.168.1.11:6789/0");
114 it
= monmap
.mon_info
.find("mon.b");
115 ASSERT_NE(it
, monmap
.mon_info
.end());
116 os
<< it
->second
.public_addrs
;
117 ASSERT_EQ(os
.str(), "192.168.1.12:6789/0");
119 it
= monmap
.mon_info
.find("mon.c");
120 ASSERT_NE(it
, monmap
.mon_info
.end());
121 os
<< it
->second
.public_addrs
;
122 ASSERT_EQ(os
.str(), "192.168.1.13:6789/0");
125 TEST_F(MonMapTest
, DISABLED_build_initial_config_from_dns_fail
) {
126 MockResolvHWrapper
*resolvH
= new MockResolvHWrapper();
127 DNSResolver::get_instance(resolvH
);
130 #ifdef HAVE_RES_NQUERY
131 EXPECT_CALL(*resolvH
, res_nsearch(_
, StrEq("_ceph-mon._tcp"), C_IN
, T_SRV
, _
, _
))
132 .WillOnce(Return(0));
134 EXPECT_CALL(*resolvH
, res_search(StrEq("_ceph-mon._tcp"), C_IN
, T_SRV
, _
, _
))
135 .WillOnce(Return(0));
138 boost::intrusive_ptr
<CephContext
> cct
= new CephContext(CEPH_ENTITY_TYPE_MON
);
139 // using default value of mon_dns_srv_name option
141 int r
= monmap
.build_initial(cct
.get(), false, std::cerr
);
143 ASSERT_EQ(r
, -ENOENT
);
144 ASSERT_EQ(monmap
.mon_info
.size(), (unsigned int)0);
148 TEST_F(MonMapTest
, DISABLED_build_initial_config_from_dns_with_domain
) {
150 MockResolvHWrapper
*resolvH
= new MockResolvHWrapper();
151 DNSResolver::get_instance(resolvH
);
153 int len
= sizeof(ns_search_msg_ok_payload
);
154 int lena
= sizeof(ns_query_msg_mon_a_payload
);
155 int lenb
= sizeof(ns_query_msg_mon_b_payload
);
156 int lenc
= sizeof(ns_query_msg_mon_c_payload
);
158 using ::testing::InSequence
;
162 #ifdef HAVE_RES_NQUERY
163 EXPECT_CALL(*resolvH
, res_nsearch(_
, StrEq("_cephmon._tcp.ceph.com"), C_IN
, T_SRV
, _
, _
))
164 .WillOnce(DoAll(SetArrayArgument
<4>(ns_search_msg_ok_payload
,
165 ns_search_msg_ok_payload
+len
), Return(len
)));
167 EXPECT_CALL(*resolvH
, res_nquery(_
,StrEq("mon.a.ceph.com"), C_IN
, T_A
,_
,_
))
168 .WillOnce(DoAll(SetArrayArgument
<4>(ns_query_msg_mon_a_payload
,
169 ns_query_msg_mon_a_payload
+lena
), Return(lena
)));
171 EXPECT_CALL(*resolvH
, res_nquery(_
, StrEq("mon.c.ceph.com"), C_IN
, T_A
,_
,_
))
172 .WillOnce(DoAll(SetArrayArgument
<4>(ns_query_msg_mon_c_payload
,
173 ns_query_msg_mon_c_payload
+lenc
), Return(lenc
)));
175 EXPECT_CALL(*resolvH
, res_nquery(_
,StrEq("mon.b.ceph.com"), C_IN
, T_A
, _
,_
))
176 .WillOnce(DoAll(SetArrayArgument
<4>(ns_query_msg_mon_b_payload
,
177 ns_query_msg_mon_b_payload
+lenb
), Return(lenb
)));
179 EXPECT_CALL(*resolvH
, res_search(StrEq("_cephmon._tcp.ceph.com"), C_IN
, T_SRV
, _
, _
))
180 .WillOnce(DoAll(SetArrayArgument
<3>(ns_search_msg_ok_payload
,
181 ns_search_msg_ok_payload
+len
), Return(len
)));
183 EXPECT_CALL(*resolvH
, res_query(StrEq("mon.a.ceph.com"), C_IN
, T_A
,_
,_
))
184 .WillOnce(DoAll(SetArrayArgument
<3>(ns_query_msg_mon_a_payload
,
185 ns_query_msg_mon_a_payload
+lena
), Return(lena
)));
187 EXPECT_CALL(*resolvH
, res_query(StrEq("mon.c.ceph.com"), C_IN
, T_A
,_
,_
))
188 .WillOnce(DoAll(SetArrayArgument
<3>(ns_query_msg_mon_c_payload
,
189 ns_query_msg_mon_c_payload
+lenc
), Return(lenc
)));
191 EXPECT_CALL(*resolvH
, res_query(StrEq("mon.b.ceph.com"), C_IN
, T_A
, _
,_
))
192 .WillOnce(DoAll(SetArrayArgument
<3>(ns_query_msg_mon_b_payload
,
193 ns_query_msg_mon_b_payload
+lenb
), Return(lenb
)));
199 boost::intrusive_ptr
<CephContext
> cct
= new CephContext(CEPH_ENTITY_TYPE_MON
);
200 cct
->_conf
.set_val("mon_dns_srv_name", "cephmon_ceph.com");
202 int r
= monmap
.build_initial(cct
.get(), false, std::cerr
);
205 ASSERT_EQ(monmap
.mon_info
.size(), (unsigned int)3);
206 auto it
= monmap
.mon_info
.find("mon.a");
207 ASSERT_NE(it
, monmap
.mon_info
.end());
208 std::ostringstream os
;
209 os
<< it
->second
.public_addrs
;
210 ASSERT_EQ(os
.str(), "192.168.1.11:6789/0");
212 it
= monmap
.mon_info
.find("mon.b");
213 ASSERT_NE(it
, monmap
.mon_info
.end());
214 os
<< it
->second
.public_addrs
;
215 ASSERT_EQ(os
.str(), "192.168.1.12:6789/0");
217 it
= monmap
.mon_info
.find("mon.c");
218 ASSERT_NE(it
, monmap
.mon_info
.end());
219 os
<< it
->second
.public_addrs
;
220 ASSERT_EQ(os
.str(), "192.168.1.13:6789/0");
223 TEST(MonMapBuildInitial
, build_initial_mon_host_from_dns
) {
224 boost::intrusive_ptr
<CephContext
> cct
= new CephContext(CEPH_ENTITY_TYPE_MON
);
225 cct
->_conf
.set_val("mon_host", "ceph.io");
227 int r
= monmap
.build_initial(cct
.get(), false, std::cerr
);
229 ASSERT_GE(monmap
.mon_info
.size(), 1u);
230 for (const auto& [name
, info
] : monmap
.mon_info
) {
231 std::cerr
<< info
<< std::endl
;
235 TEST(MonMapBuildInitial
, build_initial_mon_host_from_dns_fail
) {
236 boost::intrusive_ptr
<CephContext
> cct
= new CephContext(CEPH_ENTITY_TYPE_MON
);
237 cct
->_conf
.set_val("mon_host", "ceph.noname");
239 int r
= monmap
.build_initial(cct
.get(), false, std::cerr
);
240 ASSERT_EQ(r
, -EINVAL
);