]>
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_
)
67 lock("mon-msg-test::lock")
72 dout(1) << __func__
<< dendl
;
75 msg
->add_dispatcher_tail(this);
79 int init_messenger() {
80 dout(1) << __func__
<< dendl
;
82 std::string public_msgr_type
= cct
->_conf
->ms_public_type
.empty() ? cct
->_conf
->get_val
<std::string
>("ms_type") : cct
->_conf
->ms_public_type
;
83 msg
= Messenger::create(cct
, public_msgr_type
, entity_name_t::CLIENT(-1),
84 "test-mon-msg", 0, 0);
86 msg
->set_default_policy(Messenger::Policy::lossy_client(0));
87 dout(0) << __func__
<< " starting messenger at "
88 << msg
->get_myaddr() << dendl
;
94 dout(1) << __func__
<< dendl
;
96 int err
= monc
.build_initial_monmap();
98 derr
<< __func__
<< " error building monmap: "
99 << cpp_strerror(err
) << dendl
;
103 monc
.set_messenger(msg
);
104 msg
->add_dispatcher_head(&monc
);
106 monc
.set_want_keys(CEPH_ENTITY_TYPE_MON
);
109 derr
<< __func__
<< " monc init failed: "
110 << cpp_strerror(err
) << dendl
;
114 err
= monc
.authenticate();
116 derr
<< __func__
<< " monc auth failed: "
117 << cpp_strerror(err
) << dendl
;
120 monc
.wait_auth_rotating(30.0);
122 dout(0) << __func__
<< " finished" << dendl
;
126 derr
<< __func__
<< " failing monc" << dendl
;
132 void shutdown_messenger() {
133 dout(0) << __func__
<< dendl
;
138 void shutdown_monc() {
139 dout(0) << __func__
<< dendl
;
144 dout(0) << __func__
<< dendl
;
146 shutdown_messenger();
149 MonMap
*get_monmap() {
154 int err
= init_messenger();
167 shutdown_messenger();
172 virtual void handle_wanted(Message
*m
) { }
174 bool handle_message(Message
*m
) {
175 dout(1) << __func__
<< " " << *m
<< dendl
;
177 dout(10) << __func__
<< " not wanted" << dendl
;
186 bool ms_dispatch(Message
*m
) override
{
187 return handle_message(m
);
189 void ms_handle_connect(Connection
*con
) override
{ }
190 void ms_handle_remote_reset(Connection
*con
) override
{ }
191 bool ms_handle_reset(Connection
*con
) override
{ return false; }
192 bool ms_handle_refused(Connection
*con
) override
{ return false; }
194 bool is_wanted(Message
*m
) {
195 dout(20) << __func__
<< " " << *m
<< " type " << m
->get_type() << dendl
;
196 return (wanted
.find(m
->get_type()) != wanted
.end());
199 void add_wanted(int t
) {
200 dout(20) << __func__
<< " type " << t
<< dendl
;
204 void rm_wanted(int t
) {
205 dout(20) << __func__
<< " type " << t
<< dendl
;
209 void send_message(Message
*m
) {
210 dout(15) << __func__
<< " " << *m
<< dendl
;
211 monc
.send_mon_message(m
);
214 void wait() { msg
->wait(); }
217 class MonMsgTest
: public MonClientHelper
,
218 public ::testing::Test
222 Message
*reply_msg
= nullptr;
227 MonClientHelper(g_ceph_context
),
231 void SetUp() override
{
237 ASSERT_EQ(init(), 0);
240 void TearDown() override
{
248 void handle_wanted(Message
*m
) override
{
250 // caller will put() after they call us, so hold on to a ref
257 Message
*send_wait_reply(Message
*m
, int t
, double timeout
=30.0) {
265 utime_t cond_timeout
;
266 cond_timeout
.set_from_double(timeout
);
267 utime_t s
= ceph_clock_now();
268 err
= cond
.WaitInterval(lock
, cond_timeout
);
269 utime_t e
= ceph_clock_now();
270 dout(20) << __func__
<< " took " << (e
-s
) << " seconds" << dendl
;
272 err
= cond
.Wait(lock
);
277 dout(20) << __func__
<< " error: " << cpp_strerror(err
) << dendl
;
278 return (Message
*)((long)-err
);
282 dout(20) << __func__
<< " reply_msg is nullptr" << dendl
;
284 dout(20) << __func__
<< " reply_msg " << *reply_msg
<< dendl
;
289 TEST_F(MonMsgTest
, MMonProbeTest
)
291 Message
*m
= new MMonProbe(get_monmap()->fsid
,
292 MMonProbe::OP_PROBE
, "b", false);
293 Message
*r
= send_wait_reply(m
, MSG_MON_PROBE
);
294 ASSERT_NE(IS_ERR(r
), 0);
295 ASSERT_EQ(PTR_ERR(r
), -ETIMEDOUT
);
298 TEST_F(MonMsgTest
, MRouteTest
)
300 Message
*payload
= new MGenericMessage(CEPH_MSG_SHUTDOWN
);
301 MRoute
*m
= new MRoute
;
303 m
->dest
= msg
->get_myinst();
304 Message
*r
= send_wait_reply(m
, CEPH_MSG_SHUTDOWN
);
306 ASSERT_NE(IS_ERR(r
), 0);
307 ASSERT_EQ(PTR_ERR(r
), -ETIMEDOUT
);
310 /* MMonScrub and MMonSync have other safeguards in place that prevent
311 * us from actually receiving a reply even if the message is handled
312 * by the monitor due to lack of cap checking.
314 TEST_F(MonMsgTest
, MMonJoin
)
316 Message
*m
= new MMonJoin(get_monmap()->fsid
, string("client"),
318 send_wait_reply(m
, MSG_MON_PAXOS
, 10.0);
320 int r
= monc
.get_monmap();
322 ASSERT_FALSE(monc
.monmap
.contains("client"));
325 int main(int argc
, char *argv
[])
327 vector
<const char*> args
;
328 argv_to_vec(argc
, (const char **)argv
, args
);
330 auto cct
= global_init(nullptr, args
,
331 CEPH_ENTITY_TYPE_CLIENT
, CODE_ENVIRONMENT_UTILITY
,
333 common_init_finish(g_ceph_context
);
334 g_ceph_context
->_conf
->apply_changes(NULL
);
335 ::testing::InitGoogleTest(&argc
, argv
);
337 return RUN_ALL_TESTS();