]>
git.proxmox.com Git - ceph.git/blob - ceph/src/test/mon/test-mon-msg.cc
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) 2014 Red Hat
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.
21 #include "global/global_init.h"
22 #include "global/global_context.h"
23 #include "common/ceph_argparse.h"
24 #include "common/dout.h"
25 #include "common/debug.h"
26 #include "common/Cond.h"
27 #include "common/Mutex.h"
28 #include "common/Timer.h"
29 #include "common/errno.h"
30 #include "mon/MonClient.h"
31 #include "msg/Dispatcher.h"
32 #include "include/err.h"
33 #include <boost/scoped_ptr.hpp>
35 #include "gtest/gtest.h"
37 #include "common/config.h"
38 #include "include/assert.h"
40 #include "messages/MMonProbe.h"
41 #include "messages/MRoute.h"
42 #include "messages/MGenericMessage.h"
43 #include "messages/MMonJoin.h"
45 #define dout_context g_ceph_context
46 #define dout_subsys ceph_subsys_
48 #define dout_prefix *_dout << "test-mon-msg "
50 class MonClientHelper
: public Dispatcher
63 explicit MonClientHelper(CephContext
*cct_
)
68 lock("mon-msg-test::lock")
73 dout(1) << __func__
<< dendl
;
76 msg
->add_dispatcher_tail(this);
80 int init_messenger() {
81 dout(1) << __func__
<< dendl
;
83 std::string public_msgr_type
= cct
->_conf
->ms_public_type
.empty() ? cct
->_conf
->get_val
<std::string
>("ms_type") : cct
->_conf
->ms_public_type
;
84 msg
= Messenger::create(cct
, public_msgr_type
, entity_name_t::CLIENT(-1),
85 "test-mon-msg", 0, 0);
87 msg
->set_default_policy(Messenger::Policy::lossy_client(0));
88 dout(0) << __func__
<< " starting messenger at "
89 << msg
->get_myaddr() << dendl
;
95 dout(1) << __func__
<< dendl
;
97 int err
= monc
.build_initial_monmap();
99 derr
<< __func__
<< " error building monmap: "
100 << cpp_strerror(err
) << dendl
;
104 monc
.set_messenger(msg
);
105 msg
->add_dispatcher_head(&monc
);
107 monc
.set_want_keys(CEPH_ENTITY_TYPE_MON
);
110 derr
<< __func__
<< " monc init failed: "
111 << cpp_strerror(err
) << dendl
;
115 err
= monc
.authenticate();
117 derr
<< __func__
<< " monc auth failed: "
118 << cpp_strerror(err
) << dendl
;
121 monc
.wait_auth_rotating(30.0);
123 dout(0) << __func__
<< " finished" << dendl
;
127 derr
<< __func__
<< " failing monc" << dendl
;
133 void shutdown_messenger() {
134 dout(0) << __func__
<< dendl
;
139 void shutdown_monc() {
140 dout(0) << __func__
<< dendl
;
145 dout(0) << __func__
<< dendl
;
147 shutdown_messenger();
150 MonMap
*get_monmap() {
155 int err
= init_messenger();
168 shutdown_messenger();
173 virtual void handle_wanted(Message
*m
) { }
175 bool handle_message(Message
*m
) {
176 dout(1) << __func__
<< " " << *m
<< dendl
;
178 dout(10) << __func__
<< " not wanted" << dendl
;
187 bool ms_dispatch(Message
*m
) override
{
188 return handle_message(m
);
190 void ms_handle_connect(Connection
*con
) override
{ }
191 void ms_handle_remote_reset(Connection
*con
) override
{ }
192 bool ms_handle_reset(Connection
*con
) override
{ return false; }
193 bool ms_handle_refused(Connection
*con
) override
{ return false; }
195 bool is_wanted(Message
*m
) {
196 dout(20) << __func__
<< " " << *m
<< " type " << m
->get_type() << dendl
;
197 return (wanted
.find(m
->get_type()) != wanted
.end());
200 void add_wanted(int t
) {
201 dout(20) << __func__
<< " type " << t
<< dendl
;
205 void rm_wanted(int t
) {
206 dout(20) << __func__
<< " type " << t
<< dendl
;
210 void send_message(Message
*m
) {
211 dout(15) << __func__
<< " " << *m
<< dendl
;
212 monc
.send_mon_message(m
);
215 void wait() { msg
->wait(); }
218 class MonMsgTest
: public MonClientHelper
,
219 public ::testing::Test
223 Message
*reply_msg
= nullptr;
228 MonClientHelper(g_ceph_context
),
232 void SetUp() override
{
238 ASSERT_EQ(init(), 0);
241 void TearDown() override
{
249 void handle_wanted(Message
*m
) override
{
251 // caller will put() after they call us, so hold on to a ref
258 Message
*send_wait_reply(Message
*m
, int t
, double timeout
=30.0) {
266 utime_t cond_timeout
;
267 cond_timeout
.set_from_double(timeout
);
268 utime_t s
= ceph_clock_now();
269 err
= cond
.WaitInterval(lock
, cond_timeout
);
270 utime_t e
= ceph_clock_now();
271 dout(20) << __func__
<< " took " << (e
-s
) << " seconds" << dendl
;
273 err
= cond
.Wait(lock
);
278 dout(20) << __func__
<< " error: " << cpp_strerror(err
) << dendl
;
279 return (Message
*)((long)-err
);
283 dout(20) << __func__
<< " reply_msg is nullptr" << dendl
;
285 dout(20) << __func__
<< " reply_msg " << *reply_msg
<< dendl
;
290 TEST_F(MonMsgTest
, MMonProbeTest
)
292 Message
*m
= new MMonProbe(get_monmap()->fsid
,
293 MMonProbe::OP_PROBE
, "b", false);
294 Message
*r
= send_wait_reply(m
, MSG_MON_PROBE
);
295 ASSERT_NE(IS_ERR(r
), 0);
296 ASSERT_EQ(PTR_ERR(r
), -ETIMEDOUT
);
299 TEST_F(MonMsgTest
, MRouteTest
)
301 Message
*payload
= new MGenericMessage(CEPH_MSG_SHUTDOWN
);
302 MRoute
*m
= new MRoute
;
304 m
->dest
= msg
->get_myinst();
305 Message
*r
= send_wait_reply(m
, CEPH_MSG_SHUTDOWN
);
307 ASSERT_NE(IS_ERR(r
), 0);
308 ASSERT_EQ(PTR_ERR(r
), -ETIMEDOUT
);
311 /* MMonScrub and MMonSync have other safeguards in place that prevent
312 * us from actually receiving a reply even if the message is handled
313 * by the monitor due to lack of cap checking.
315 TEST_F(MonMsgTest
, MMonJoin
)
317 Message
*m
= new MMonJoin(get_monmap()->fsid
, string("client"),
319 send_wait_reply(m
, MSG_MON_PAXOS
, 10.0);
321 int r
= monc
.get_monmap();
323 ASSERT_FALSE(monc
.monmap
.contains("client"));
326 int main(int argc
, char *argv
[])
328 vector
<const char*> args
;
329 argv_to_vec(argc
, (const char **)argv
, args
);
331 auto cct
= global_init(nullptr, args
,
332 CEPH_ENTITY_TYPE_CLIENT
, CODE_ENVIRONMENT_UTILITY
,
334 common_init_finish(g_ceph_context
);
335 g_ceph_context
->_conf
->apply_changes(NULL
);
336 ::testing::InitGoogleTest(&argc
, argv
);
338 return RUN_ALL_TESTS();