Motr  M0
link_ut.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 2012-2020 Seagate Technology LLC and/or its Affiliates
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  * For any questions about this software or licensing,
18  * please email opensource@seagate.com or cortx-questions@seagate.com.
19  *
20  */
21 
22 
23 #include "ut/ut.h"
24 #include "lib/finject.h"
25 #include "lib/memory.h"
26 #include "lib/trace.h"
27 #include "reqh/reqh.h"
28 #include "rpc/session.h"
29 #include "rpc/rpc_opcodes.h"
30 #include "net/lnet/lnet.h"
31 #include "rpc/link.h"
32 #include "rpc/rpc.h"
33 #include "fop/fop.h"
34 #include "sss/ss_fops.h"
35 #include "ha/ut/helper.h"
36 
37 #include "rpc/ut/clnt_srv_ctx.c" /* sctx, cctx. NOTE: This is .c file */
38 
39 enum {
41  RLUT_CONN_TIMEOUT = 40, /* seconds */
42  RLUT_SESS_TIMEOUT = 20, /* seconds */
43 };
44 
45 struct m0_clink clink;
46 
47 static void rlut_init(struct m0_net_domain *net_dom,
49  struct m0_reqh *reqh,
50  struct m0_rpc_machine *rmachine)
51 {
52  const char *client_ep = "0@lo:12345:34:1";
53  /* unreacheable remote EP */
54  int rc;
55 
56  enum {
57  NR_TMS = 1,
58  };
59 
60  M0_SET0(net_dom);
62  M0_SET0(reqh);
64 
66  M0_UT_ASSERT(rc == 0);
67 
69  buf_pool,
72  NR_TMS),
73  NR_TMS);
74  M0_UT_ASSERT(rc == 0);
75 
77  .rhia_dtm = (void *)1,
78  .rhia_mdstore = (void *)1,
79  .rhia_fid = &g_process_fid);
80  M0_UT_ASSERT(rc == 0);
82 
83  rc = m0_rpc_machine_init(rmachine, net_dom, client_ep, reqh, buf_pool,
87  M0_UT_ASSERT(rc == 0);
88 }
89 
90 static void rlut_fini(struct m0_net_domain *net_dom,
92  struct m0_reqh *reqh,
93  struct m0_rpc_machine *rmachine)
94 {
99  m0_net_domain_fini(net_dom);
100 }
101 
102 static void rlut_remote_unreachable(void)
103 {
104  struct m0_net_domain net_dom;
106  struct m0_reqh reqh;
107  struct m0_rpc_machine rmachine;
108  struct m0_rpc_link *rlink;
109  /* unreacheable remote EP */
110  const char *remote_ep = "0@lo:12345:35:1";
111  int rc;
112 
113  rlut_init(&net_dom, &buf_pool, &reqh, &rmachine);
114 
115  /* RPC link structure is too big to be allocated on stack */
116  M0_ALLOC_PTR(rlink);
117  M0_UT_ASSERT(rlink != NULL);
118 
119  rc = m0_rpc_link_init(rlink, &rmachine, NULL, remote_ep,
121  M0_UT_ASSERT(rc == 0);
122 
125  M0_UT_ASSERT(rc != 0 && !m0_rpc_link_is_connected(rlink));
126  m0_rpc_link_fini(rlink);
127  m0_free(rlink);
128 
129  rlut_fini(&net_dom, &buf_pool, &reqh, &rmachine);
130 }
131 
132 static void rlut_reconnect(void)
133 {
134  struct m0_ha_ut_rpc_ctx *rpc_ctx;
135  struct m0_rpc_machine *mach;
136  struct m0_rpc_link *rlink;
137  const char *remote_ep;
138  int rc;
139  int i;
140 
144  mach = &rpc_ctx->hurc_rpc_machine;
145  remote_ep = m0_rpc_machine_ep(mach);
146 
147  M0_ALLOC_PTR(rlink);
148  M0_UT_ASSERT(rlink != NULL);
149  rc = m0_rpc_link_init(rlink, mach, NULL, remote_ep,
151  M0_UT_ASSERT(rc == 0);
152 
153  /* Reconnect after disconnect */
154  for (i = 0; i < 2; ++i) {
157  M0_UT_ASSERT(rc == 0 && m0_rpc_link_is_connected(rlink));
160  M0_UT_ASSERT(rc == 0 && !m0_rpc_link_is_connected(rlink));
161  m0_rpc_link_reset(rlink);
162  }
163 
164  /* Reconnect after fail */
165  m0_fi_enable_once("m0_rpc_conn_establish", "fake_error");
168  M0_UT_ASSERT(rc != 0 && !m0_rpc_link_is_connected(rlink));
169  m0_rpc_link_reset(rlink);
170  m0_fi_disable("m0_rpc_conn_establish", "fake_error");
173  M0_UT_ASSERT(rc == 0 && m0_rpc_link_is_connected(rlink));
176  M0_UT_ASSERT(rc == 0 && !m0_rpc_link_is_connected(rlink));
177 
178  m0_rpc_link_fini(rlink);
179  m0_free(rlink);
181  m0_free(rpc_ctx);
182 }
183 
184 extern uint32_t m0_rpc__filter_opcode[4];
185 
186 static void rlut_remote_delay(void)
187 {
188  struct m0_ha_ut_rpc_ctx *rpc_ctx;
189  struct m0_rpc_machine *mach;
190  struct m0_rpc_link *rlink;
191  const char *remote_ep;
192  int rc;
193 
197  mach = &rpc_ctx->hurc_rpc_machine;
198  remote_ep = m0_rpc_machine_ep(mach);
199 
200  M0_ALLOC_PTR(rlink);
201  M0_UT_ASSERT(rlink != NULL);
202  /* delay on session establishing */
203  rc = m0_rpc_link_init(rlink, mach, NULL, remote_ep,
205  M0_UT_ASSERT(rc == 0);
206  m0_fi_enable("item_received_fi", "drop_opcode");
210  M0_UT_ASSERT(rc != 0 && !m0_rpc_link_is_connected(rlink));
211  m0_rpc__filter_opcode[0] = 0;
212  m0_fi_disable("item_received_fi", "drop_opcode");
213  m0_rpc_link_fini(rlink);
214  /* delay on session establishing and connection termination */
215  M0_SET0(rlink);
216  m0_fi_enable("item_received_fi", "drop_opcode");
219  rc = m0_rpc_link_init(rlink, mach, NULL, remote_ep,
221  M0_UT_ASSERT(rc == 0);
224  M0_UT_ASSERT(rc != 0 && !m0_rpc_link_is_connected(rlink));
225  m0_rpc__filter_opcode[0] = 0;
226  m0_rpc__filter_opcode[1] = 0;
227  m0_fi_disable("item_received_fi", "drop_opcode");
228  m0_rpc_link_fini(rlink);
229  /* delay on session termination */
230  M0_SET0(rlink);
231  m0_fi_enable("item_received_fi", "drop_opcode");
233  rc = m0_rpc_link_init(rlink, mach, NULL, remote_ep,
235  M0_UT_ASSERT(rc == 0);
238  M0_UT_ASSERT(rc == 0 && m0_rpc_link_is_connected(rlink));
241  M0_UT_ASSERT(rc == -ETIMEDOUT && !m0_rpc_link_is_connected(rlink));
242  m0_rpc__filter_opcode[0] = 0;
243  m0_fi_disable("item_received_fi", "drop_opcode");
244  m0_rpc_link_fini(rlink);
245  /* delay on connection termination */
246  M0_SET0(rlink);
247  rc = m0_rpc_link_init(rlink, mach, NULL, remote_ep,
249  M0_UT_ASSERT(rc == 0);
252  M0_UT_ASSERT(rc == 0 && m0_rpc_link_is_connected(rlink));
253  m0_fi_enable("item_received_fi", "drop_opcode");
257  M0_UT_ASSERT(rc == -ETIMEDOUT && !m0_rpc_link_is_connected(rlink));
258  m0_rpc__filter_opcode[0] = 0;
259  m0_fi_disable("item_received_fi", "drop_opcode");
260  m0_rpc_link_fini(rlink);
261 
262  m0_free(rlink);
264  m0_free(rpc_ctx);
265 }
266 
267 static void rlut_reset(void)
268 {
269  struct m0_ha_ut_rpc_ctx *rpc_ctx;
270  struct m0_rpc_machine *mach;
271  struct m0_rpc_link *rlink;
272  const char *remote_ep;
273  int rc;
274 
278  mach = &rpc_ctx->hurc_rpc_machine;
279  remote_ep = m0_rpc_machine_ep(mach);
280 
281  M0_ALLOC_PTR(rlink);
282  M0_UT_ASSERT(rlink != NULL);
283  rc = m0_rpc_link_init(rlink, mach, NULL, remote_ep,
285  M0_UT_ASSERT(rc == 0);
286 
287  /* delay on session establishing */
288  m0_fi_enable("item_received_fi", "drop_opcode");
292  M0_UT_ASSERT(rc != 0 && !m0_rpc_link_is_connected(rlink));
293  m0_rpc__filter_opcode[0] = 0;
294  m0_fi_disable("item_received_fi", "drop_opcode");
295 
296  /* normal connect */
297  m0_rpc_link_reset(rlink);
300  M0_UT_ASSERT(rc == 0 && m0_rpc_link_is_connected(rlink));
301 
302  /* delay on session termination */
303  m0_fi_enable("item_received_fi", "drop_opcode");
307  M0_UT_ASSERT(rc != 0 && !m0_rpc_link_is_connected(rlink));
308  m0_rpc__filter_opcode[0] = 0;
309  m0_fi_disable("item_received_fi", "drop_opcode");
310 
311  /* normal connect/disconnect */
312  m0_rpc_link_reset(rlink);
315  M0_UT_ASSERT(rc == 0 && m0_rpc_link_is_connected(rlink));
318  M0_UT_ASSERT(rc == 0 && !m0_rpc_link_is_connected(rlink));
319 
320  m0_rpc_link_fini(rlink);
321  m0_free(rlink);
323  m0_free(rpc_ctx);
324 }
325 
326 static struct m0_fop *ut_fop_alloc(const char *name, uint32_t cmd)
327 {
328  struct m0_fop *fop;
329  struct m0_sss_req *rfop;
330 
331  M0_ALLOC_PTR(fop);
332  M0_UT_ASSERT(fop != NULL);
333 
334  M0_ALLOC_PTR(rfop);
335  M0_UT_ASSERT(rfop != NULL);
336 
337  m0_buf_init(&rfop->ss_name, (void *)name, strlen(name));
338  rfop->ss_cmd = cmd;
339 
341 
342  return fop;
343 
344 }
345 
346 static void ut_req(struct m0_rpc_session *sess, const char *name, uint32_t cmd)
347 {
348  int rc;
349  struct m0_fop *fop;
350 
351  fop = ut_fop_alloc(name, cmd);
352 
353  rc = m0_rpc_post_sync(fop, sess, NULL, 0);
354  M0_UT_ASSERT(rc == 0);
356 }
357 
359 {
360  struct m0_rpc_machine *mach;
361  struct m0_rpc_link *rlink;
362  const char *remote_ep;
363  int rc;
364 
367  remote_ep = cctx.rcx_remote_addr;
368 
369  M0_ALLOC_PTR(rlink);
370  M0_UT_ASSERT(rlink != NULL);
371  rc = m0_rpc_link_init(rlink, mach, NULL, remote_ep,
373  M0_UT_ASSERT(rc == 0);
374 
376  clink.cl_is_oneshot = true;
377 
380  &clink);
382  M0_TIME_NEVER);
383  M0_UT_ASSERT(rc == 0);
384  ut_req(&rlink->rlk_sess, "M0_CST_IOS", M0_SERVICE_STATUS);
385 
387  M0_UT_ASSERT(rc == 0 && m0_rpc_link_is_connected(rlink));
388 
390 
392  clink.cl_is_oneshot = true;
395  &clink);
397  M0_UT_ASSERT(rc == 0 && !m0_rpc_link_is_connected(rlink));
399 
400  m0_rpc_link_fini(rlink);
401  m0_free(rlink);
403 }
404 
406  .ts_name = "rpc-link-ut",
407  .ts_tests = {
408  { "remote-unreacheable", rlut_remote_unreachable },
409  { "reconnect", rlut_reconnect },
410  { "remote-delay", rlut_remote_delay },
411  { "reset", rlut_reset },
412  { "connect-async", rlut_connect_async },
413  { NULL, NULL }
414  }
415 };
416 
417 /*
418  * Local variables:
419  * c-indentation-style: "K&R"
420  * c-basic-offset: 8
421  * tab-width: 8
422  * fill-column: 80
423  * scroll-step: 1
424  * End:
425  */
M0_INTERNAL void m0_chan_wait(struct m0_clink *link)
Definition: chan.c:336
void m0_rpc_machine_fini(struct m0_rpc_machine *machine)
Definition: rpc_machine.c:233
M0_INTERNAL void m0_reqh_services_terminate(struct m0_reqh *reqh)
Definition: reqh.c:675
void m0_net_domain_fini(struct m0_net_domain *dom)
Definition: domain.c:71
#define NULL
Definition: misc.h:38
M0_INTERNAL void m0_clink_init(struct m0_clink *link, m0_chan_cb_t cb)
Definition: chan.c:201
#define M0_REQH_INIT(reqh,...)
Definition: reqh.h:262
const m0_time_t M0_TIME_NEVER
Definition: time.c:108
M0_INTERNAL void m0_fop_init(struct m0_fop *fop, struct m0_fop_type *fopt, void *data, void(*fop_release)(struct m0_ref *))
Definition: fop.c:79
M0_INTERNAL void m0_buf_init(struct m0_buf *buf, void *data, uint32_t nob)
Definition: buf.c:37
static struct m0_rpc_client_ctx cctx
Definition: rconfc.c:69
M0_INTERNAL void m0_ha_ut_rpc_ctx_init(struct m0_ha_ut_rpc_ctx *ctx)
Definition: helper.c:41
static struct m0_addb2_mach * mach
Definition: storage.c:42
#define M0_BITS(...)
Definition: misc.h:236
struct m0_fop_type m0_fop_ss_fopt
Definition: ss_fops.c:39
uint32_t ss_cmd
Definition: ss_fops.h:61
#define M0_SET0(obj)
Definition: misc.h:64
Definition: ut.h:77
M0_INTERNAL void m0_reqh_fini(struct m0_reqh *reqh)
Definition: reqh.c:320
M0_INTERNAL const char * m0_rpc_machine_ep(const struct m0_rpc_machine *rmach)
Definition: rpc_machine.c:603
int i
Definition: dir.c:1033
const char * name
Definition: trace.c:110
struct m0_buf ss_name
Definition: ss_fops.h:66
M0_INTERNAL void m0_fi_disable(const char *fp_func, const char *fp_tag)
Definition: finject.c:485
static void m0_fi_enable(const char *func, const char *tag)
Definition: finject.h:276
static struct m0_rpc_machine rmachine
Definition: formation2.c:36
M0_INTERNAL int m0_rpc_net_buffer_pool_setup(struct m0_net_domain *ndom, struct m0_net_buffer_pool *app_pool, uint32_t bufs_nr, uint32_t tm_nr)
Definition: rpc.c:229
M0_INTERNAL uint32_t m0_rpc_bufs_nr(uint32_t len, uint32_t tms_nr)
Definition: rpc.c:271
static void stop_rpc_client_and_server(void)
Definition: note.c:126
M0_INTERNAL int m0_rpc_machine_init(struct m0_rpc_machine *machine, struct m0_net_domain *net_dom, const char *ep_addr, struct m0_reqh *reqh, struct m0_net_buffer_pool *receive_pool, uint32_t colour, m0_bcount_t msg_size, uint32_t queue_len)
Definition: rpc_machine.c:123
struct m0_net_xprt * m0_net_xprt_default_get(void)
Definition: net.c:151
int m0_rpc_post_sync(struct m0_fop *fop, struct m0_rpc_session *session, const struct m0_rpc_item_ops *ri_ops, m0_time_t deadline)
Definition: rpclib.c:284
M0_INTERNAL int m0_rpc_session_timedwait(struct m0_rpc_session *session, uint64_t states, const m0_time_t abs_timeout)
Definition: session.c:332
Definition: reqh.h:94
M0_INTERNAL void m0_ha_ut_rpc_ctx_fini(struct m0_ha_ut_rpc_ctx *ctx)
Definition: helper.c:73
M0_INTERNAL void m0_ss_fop_release(struct m0_ref *ref)
Definition: ss_fops.c:96
const char * ts_name
Definition: ut.h:99
M0_INTERNAL void m0_reqh_start(struct m0_reqh *reqh)
Definition: reqh.c:711
uint32_t m0_rpc__filter_opcode[4]
Definition: rpc_machine.c:910
struct m0_reqh reqh
Definition: rm_foms.c:48
int m0_net_domain_init(struct m0_net_domain *dom, const struct m0_net_xprt *xprt)
Definition: domain.c:36
#define M0_ALLOC_PTR(ptr)
Definition: memory.h:86
m0_time_t m0_time_from_now(uint64_t secs, long ns)
Definition: time.c:96
const char * rcx_remote_addr
Definition: rpclib.h:134
M0_INTERNAL void m0_clink_fini(struct m0_clink *link)
Definition: chan.c:208
void m0_fop_put_lock(struct m0_fop *fop)
Definition: fop.c:199
static struct m0_fop * fop
Definition: item.c:57
static void m0_fi_enable_once(const char *func, const char *tag)
Definition: finject.h:301
struct m0_rpc_machine rcx_rpc_machine
Definition: rpclib.h:145
static struct m0_net_buffer_pool * buf_pool
Definition: bulkio_ut.c:261
void m0_rpc_net_buffer_pool_cleanup(struct m0_net_buffer_pool *app_pool)
Definition: rpc.c:264
void m0_free(void *data)
Definition: memory.c:146
int32_t rc
Definition: trigger_fop.h:47
struct m0_fid g_process_fid
Definition: ut.c:689
static void start_rpc_client_and_server(void)
Definition: note.c:111
#define M0_UT_ASSERT(a)
Definition: ut.h:46
Definition: fop.h:79