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");