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"
27 #define dout_subsys ceph_subsys_mon
30 using ::testing::Return
;
32 using ::testing::SetArrayArgument
;
33 using ::testing::DoAll
;
34 using ::testing::StrEq
;
37 class MonMapTest
: public ::testing::Test
{
39 virtual void SetUp() {
40 g_ceph_context
->_conf
->subsys
.set_log_level(dout_subsys
, TEST_DEBUG
);
43 virtual void TearDown() {
44 DNSResolver::get_instance(nullptr);
48 TEST_F(MonMapTest
, build_initial_config_from_dns
) {
50 MockResolvHWrapper
*resolvH
= new MockResolvHWrapper();
51 DNSResolver::get_instance(resolvH
);
53 int len
= sizeof(ns_search_msg_ok_payload
);
54 int lena
= sizeof(ns_query_msg_mon_a_payload
);
55 int lenb
= sizeof(ns_query_msg_mon_b_payload
);
56 int lenc
= sizeof(ns_query_msg_mon_c_payload
);
58 using ::testing::InSequence
;
62 #ifdef HAVE_RES_NQUERY
63 EXPECT_CALL(*resolvH
, res_nsearch(_
, StrEq("_cephmon._tcp"), C_IN
, T_SRV
, _
, _
))
64 .WillOnce(DoAll(SetArrayArgument
<4>(ns_search_msg_ok_payload
,
65 ns_search_msg_ok_payload
+len
), Return(len
)));
67 EXPECT_CALL(*resolvH
, res_nquery(_
,StrEq("mon.a.ceph.com"), C_IN
, T_A
,_
,_
))
68 .WillOnce(DoAll(SetArrayArgument
<4>(ns_query_msg_mon_a_payload
,
69 ns_query_msg_mon_a_payload
+lena
), Return(lena
)));
71 EXPECT_CALL(*resolvH
, res_nquery(_
, StrEq("mon.c.ceph.com"), C_IN
, T_A
,_
,_
))
72 .WillOnce(DoAll(SetArrayArgument
<4>(ns_query_msg_mon_c_payload
,
73 ns_query_msg_mon_c_payload
+lenc
), Return(lenc
)));
75 EXPECT_CALL(*resolvH
, res_nquery(_
,StrEq("mon.b.ceph.com"), C_IN
, T_A
, _
,_
))
76 .WillOnce(DoAll(SetArrayArgument
<4>(ns_query_msg_mon_b_payload
,
77 ns_query_msg_mon_b_payload
+lenb
), Return(lenb
)));
79 EXPECT_CALL(*resolvH
, res_search(StrEq("_cephmon._tcp"), C_IN
, T_SRV
, _
, _
))
80 .WillOnce(DoAll(SetArrayArgument
<3>(ns_search_msg_ok_payload
,
81 ns_search_msg_ok_payload
+len
), Return(len
)));
83 EXPECT_CALL(*resolvH
, res_query(StrEq("mon.a.ceph.com"), C_IN
, T_A
,_
,_
))
84 .WillOnce(DoAll(SetArrayArgument
<3>(ns_query_msg_mon_a_payload
,
85 ns_query_msg_mon_a_payload
+lena
), Return(lena
)));
87 EXPECT_CALL(*resolvH
, res_query(StrEq("mon.c.ceph.com"), C_IN
, T_A
,_
,_
))
88 .WillOnce(DoAll(SetArrayArgument
<3>(ns_query_msg_mon_c_payload
,
89 ns_query_msg_mon_c_payload
+lenc
), Return(lenc
)));
91 EXPECT_CALL(*resolvH
, res_query(StrEq("mon.b.ceph.com"), C_IN
, T_A
, _
,_
))
92 .WillOnce(DoAll(SetArrayArgument
<3>(ns_query_msg_mon_b_payload
,
93 ns_query_msg_mon_b_payload
+lenb
), Return(lenb
)));
99 CephContext
*cct
= (new CephContext(CEPH_ENTITY_TYPE_MON
))->get();
100 cct
->_conf
->set_val("mon_dns_srv_name", "cephmon", false);
102 int r
= monmap
.build_initial(cct
, std::cerr
);
105 ASSERT_EQ(monmap
.mon_addr
.size(), (unsigned int)3);
106 map
<string
,entity_addr_t
>::iterator it
= monmap
.mon_addr
.find("mon.a");
107 ASSERT_NE(it
, monmap
.mon_addr
.end());
108 std::ostringstream os
;
110 ASSERT_EQ(os
.str(), "192.168.1.11:6789/0");
112 it
= monmap
.mon_addr
.find("mon.b");
113 ASSERT_NE(it
, monmap
.mon_addr
.end());
115 ASSERT_EQ(os
.str(), "192.168.1.12:6789/0");
117 it
= monmap
.mon_addr
.find("mon.c");
118 ASSERT_NE(it
, monmap
.mon_addr
.end());
120 ASSERT_EQ(os
.str(), "192.168.1.13:6789/0");
123 TEST_F(MonMapTest
, build_initial_config_from_dns_fail
) {
124 MockResolvHWrapper
*resolvH
= new MockResolvHWrapper();
125 DNSResolver::get_instance(resolvH
);
128 #ifdef HAVE_RES_NQUERY
129 EXPECT_CALL(*resolvH
, res_nsearch(_
, StrEq("_ceph-mon._tcp"), C_IN
, T_SRV
, _
, _
))
130 .WillOnce(Return(0));
132 EXPECT_CALL(*resolvH
, res_search(StrEq("_ceph-mon._tcp"), C_IN
, T_SRV
, _
, _
))
133 .WillOnce(Return(0));
136 CephContext
*cct
= (new CephContext(CEPH_ENTITY_TYPE_MON
))->get();
137 // using default value of mon_dns_srv_name option
139 int r
= monmap
.build_initial(cct
, std::cerr
);
141 ASSERT_EQ(r
, -ENOENT
);
142 ASSERT_EQ(monmap
.mon_addr
.size(), (unsigned int)0);
146 TEST_F(MonMapTest
, build_initial_config_from_dns_with_domain
) {
148 MockResolvHWrapper
*resolvH
= new MockResolvHWrapper();
149 DNSResolver::get_instance(resolvH
);
151 int len
= sizeof(ns_search_msg_ok_payload
);
152 int lena
= sizeof(ns_query_msg_mon_a_payload
);
153 int lenb
= sizeof(ns_query_msg_mon_b_payload
);
154 int lenc
= sizeof(ns_query_msg_mon_c_payload
);
156 using ::testing::InSequence
;
160 #ifdef HAVE_RES_NQUERY
161 EXPECT_CALL(*resolvH
, res_nsearch(_
, StrEq("_cephmon._tcp.ceph.com"), C_IN
, T_SRV
, _
, _
))
162 .WillOnce(DoAll(SetArrayArgument
<4>(ns_search_msg_ok_payload
,
163 ns_search_msg_ok_payload
+len
), Return(len
)));
165 EXPECT_CALL(*resolvH
, res_nquery(_
,StrEq("mon.a.ceph.com"), C_IN
, T_A
,_
,_
))
166 .WillOnce(DoAll(SetArrayArgument
<4>(ns_query_msg_mon_a_payload
,
167 ns_query_msg_mon_a_payload
+lena
), Return(lena
)));
169 EXPECT_CALL(*resolvH
, res_nquery(_
, StrEq("mon.c.ceph.com"), C_IN
, T_A
,_
,_
))
170 .WillOnce(DoAll(SetArrayArgument
<4>(ns_query_msg_mon_c_payload
,
171 ns_query_msg_mon_c_payload
+lenc
), Return(lenc
)));
173 EXPECT_CALL(*resolvH
, res_nquery(_
,StrEq("mon.b.ceph.com"), C_IN
, T_A
, _
,_
))
174 .WillOnce(DoAll(SetArrayArgument
<4>(ns_query_msg_mon_b_payload
,
175 ns_query_msg_mon_b_payload
+lenb
), Return(lenb
)));
177 EXPECT_CALL(*resolvH
, res_search(StrEq("_cephmon._tcp.ceph.com"), C_IN
, T_SRV
, _
, _
))
178 .WillOnce(DoAll(SetArrayArgument
<3>(ns_search_msg_ok_payload
,
179 ns_search_msg_ok_payload
+len
), Return(len
)));
181 EXPECT_CALL(*resolvH
, res_query(StrEq("mon.a.ceph.com"), C_IN
, T_A
,_
,_
))
182 .WillOnce(DoAll(SetArrayArgument
<3>(ns_query_msg_mon_a_payload
,
183 ns_query_msg_mon_a_payload
+lena
), Return(lena
)));
185 EXPECT_CALL(*resolvH
, res_query(StrEq("mon.c.ceph.com"), C_IN
, T_A
,_
,_
))
186 .WillOnce(DoAll(SetArrayArgument
<3>(ns_query_msg_mon_c_payload
,
187 ns_query_msg_mon_c_payload
+lenc
), Return(lenc
)));
189 EXPECT_CALL(*resolvH
, res_query(StrEq("mon.b.ceph.com"), C_IN
, T_A
, _
,_
))
190 .WillOnce(DoAll(SetArrayArgument
<3>(ns_query_msg_mon_b_payload
,
191 ns_query_msg_mon_b_payload
+lenb
), Return(lenb
)));
197 CephContext
*cct
= (new CephContext(CEPH_ENTITY_TYPE_MON
))->get();
198 cct
->_conf
->set_val("mon_dns_srv_name", "cephmon_ceph.com", false);
200 int r
= monmap
.build_initial(cct
, std::cerr
);
203 ASSERT_EQ(monmap
.mon_addr
.size(), (unsigned int)3);
204 map
<string
,entity_addr_t
>::iterator it
= monmap
.mon_addr
.find("mon.a");
205 ASSERT_NE(it
, monmap
.mon_addr
.end());
206 std::ostringstream os
;
208 ASSERT_EQ(os
.str(), "192.168.1.11:6789/0");
210 it
= monmap
.mon_addr
.find("mon.b");
211 ASSERT_NE(it
, monmap
.mon_addr
.end());
213 ASSERT_EQ(os
.str(), "192.168.1.12:6789/0");
215 it
= monmap
.mon_addr
.find("mon.c");
216 ASSERT_NE(it
, monmap
.mon_addr
.end());
218 ASSERT_EQ(os
.str(), "192.168.1.13:6789/0");