Motr  M0
sss_ut.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 2015-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 #define M0_TRACE_SUBSYSTEM M0_TRACE_SUBSYS_UT
24 #include "lib/trace.h"
25 
26 #include "sss/ss_fops.h" /* m0_sss_req */
27 #include "sss/process_fops.h" /* m0_ss_process_req */
28 #include "sss/device_fops.h" /* m0_sss_device_fop */
29 #include "rpc/rpclib.h" /* m0_rpc_server_ctx */
30 #include "lib/finject.h"
31 #include "ut/misc.h" /* M0_UT_PATH */
32 #include "ut/ut.h"
33 #include "motr/version.h" /* m0_build_info_get */
34 
35 #define SERVER_DB_NAME "sss_ut_server.db"
36 #define SERVER_STOB_NAME "sss_ut_server.stob"
37 #define SERVER_ADDB_STOB_NAME "linuxstob:sss_ut_server.addb_stob"
38 #define SERVER_LOG_NAME "sss_ut_server.log"
39 #define SERVER_ENDPOINT_ADDR "0@lo:12345:34:1"
40 #define SERVER_ENDPOINT M0_NET_XPRT_PREFIX_DEFAULT":"SERVER_ENDPOINT_ADDR
41 
42 #define CLIENT_DB_NAME "sss_ut_client.db"
43 #define CLIENT_ENDPOINT_ADDR "0@lo:12345:34:*"
44 
45 enum {
47 };
48 
49 static const struct m0_fid ut_fid = {
50  .f_container = 0x7300000000000001,
51  .f_key = 10
52 };
53 
55 
56 static char *server_argv[] = {
57  "sss_ut", "-T", "AD", "-D", SERVER_DB_NAME,
59  "-e", SERVER_ENDPOINT, "-H", SERVER_ENDPOINT_ADDR, "-w", "10",
60  "-f", M0_UT_CONF_PROCESS,
61  "-c", M0_UT_PATH("conf.xc")
62 };
63 
64 static struct m0_rpc_server_ctx sctx = {
65  .rsx_xprts = NULL,
66  .rsx_xprts_nr = 1,
67  .rsx_argv = server_argv,
68  .rsx_argc = ARRAY_SIZE(server_argv),
69  .rsx_log_file_name = SERVER_LOG_NAME,
70 };
71 
72 static struct m0_rpc_client_ctx cctx = {
74  .rcx_local_addr = CLIENT_ENDPOINT_ADDR,
75  .rcx_remote_addr = SERVER_ENDPOINT_ADDR,
76  .rcx_max_rpcs_in_flight = MAX_RPCS_IN_FLIGHT,
77  .rcx_fid = &g_process_fid,
78 };
79 
80 extern const struct m0_fom_type_ops ss_process_fom_type_ops;
81 extern struct m0_fop_type m0_fop_process_fopt;
82 
83 static void rpc_client_and_server_start(void)
84 {
85  int rc;
86 
88 
92  M0_ASSERT(rc == 0);
93 #if 0
94  /* Test case: memory error on service allocate */
95  m0_fi_enable("ss_svc_rsto_service_allocate", "fail_allocation");
97  M0_UT_ASSERT(rc != 0);
98  m0_fi_disable("ss_svc_rsto_service_allocate", "fail_allocation");
100 #endif
101  /* Normal start */
103  M0_ASSERT(rc == 0);
105  M0_ASSERT(rc == 0);
106 }
107 
108 static void rpc_client_and_server_stop(void)
109 {
110  int rc;
111  M0_LOG(M0_DEBUG, "stop");
113  M0_ASSERT(rc == 0);
118 }
119 
120 static struct m0_fop *sss_ut_fop_alloc(const char *name, uint32_t cmd)
121 {
122  struct m0_fop *fop;
123  struct m0_sss_req *ss_fop;
124 
125  M0_ALLOC_PTR(fop);
126  M0_ASSERT(fop != NULL);
127 
128  M0_ALLOC_PTR(ss_fop);
129  M0_ASSERT(ss_fop != NULL);
130 
131  m0_buf_init(&ss_fop->ss_name, (void *)name, strlen(name));
132  ss_fop->ss_cmd = cmd;
133  ss_fop->ss_id = ut_fid;
134 
135  m0_fop_init(fop, &m0_fop_ss_fopt, (void *)ss_fop, m0_ss_fop_release);
136 
137  return fop;
138 }
139 
140 static void sss_ut_req(uint32_t cmd,
141  int32_t expected_rc,
142  uint32_t expected_state)
143 {
144  int rc;
145  struct m0_fop *fop;
146  struct m0_fop *rfop;
147  struct m0_rpc_item *item;
148  struct m0_sss_rep *ss_rfop;
149 
150  fop = sss_ut_fop_alloc("M0_CST_MDS", cmd);
151  item = &fop->f_item;
153  M0_UT_ASSERT(rc == 0);
154 
156  M0_UT_ASSERT(rfop != NULL);
157 
158  ss_rfop = m0_fop_data(rfop);
159  M0_UT_ASSERT(ss_rfop->ssr_rc == expected_rc);
160 
161  if (expected_state != 0)
163 
165 }
166 
167 static int sss_ut_init(void)
168 {
169  M0_ENTRY();
171  M0_LEAVE();
172  return M0_RC(0);
173 }
174 
175 static int sss_ut_fini(void)
176 {
177  M0_ENTRY();
179  M0_LEAVE();
180  return M0_RC(0);
181 }
182 
183 static void sss_commands_test(void)
184 {
185  /* quiesce and stop */
189 
190  /* init */
191  sss_ut_req(M0_SERVICE_STATUS, -ENOENT, 0);
194 
195  /* start */
198 
199  /* health */
200  /* health is not implemented for mdservice now */
202 
203  /* quiesce */
206 
207  /* stop */
209  sss_ut_req(M0_SERVICE_STATUS, -ENOENT, 0);
210 }
211 
212 static struct m0_fop *ut_sss_process_create_req(uint32_t cmd)
213 {
214  struct m0_fop *fop;
215  struct m0_ss_process_req *process_fop_req;
216 
217  M0_ALLOC_PTR(fop);
218  M0_UT_ASSERT(fop != NULL);
219  M0_ALLOC_PTR(process_fop_req);
220  M0_UT_ASSERT(process_fop_req != NULL);
221 
222  process_fop_req->ssp_cmd = cmd;
223  process_fop_req->ssp_id = M0_FID_TINIT('r', 1, 5);
226  (void *)process_fop_req,
228 
229  return fop;
230 }
231 
232 static void ut_sss_process_param_set(struct m0_fop *fop, const char *name)
233 {
235 
236  if (name != NULL)
237  req->ssp_param = M0_BUF_INIT_CONST(strlen(name) + 1, name);
238  else
239  req->ssp_param = M0_BUF_INIT0;
240 }
241 
245 static void ut_sss_process_req(struct m0_fop *fop, int ssr_rc_exptd)
246 {
247  int rc;
248  struct m0_fop *rfop;
249  struct m0_ss_process_rep *process_fop_resp;
250  struct m0_rpc_item *item;
251 
252  item = &fop->f_item;
254  M0_UT_ASSERT(rc == 0);
255 
257  M0_UT_ASSERT(rfop != NULL);
258 
259  process_fop_resp = m0_fop_data(rfop);
260  M0_UT_ASSERT(process_fop_resp->sspr_rc == ssr_rc_exptd);
263 }
264 
265 static void sss_process_quiesce_test(void)
266 {
267  struct m0_fop *fop;
268 
271 }
272 
273 static void sss_process_reconfig_test(void)
274 {
275  struct m0_fop *fop;
276 
277  m0_fi_enable_once("ss_process_reconfig", "unit_test");
280 }
281 
282 static void sss_process_health_test(void)
283 {
284  struct m0_fop *fop;
285 
288 }
289 
290 static void sss_process_stop_test(void)
291 {
292  struct m0_fop *fop;
293 
294  m0_fi_enable_once("m0_ss_process_stop_fop_release", "no_kill");
297 }
298 
299 static void sss_process_commands_test(void)
300 {
305 }
306 
307 static void sss_process_svc_list_test(void)
308 {
309  int rc;
310  struct m0_fop *fop;
311  struct m0_fop *rfop;
312  struct m0_ss_process_svc_list_rep *process_fop_resp;
313  struct m0_rpc_item *item;
314 
316  item = &fop->f_item;
318  M0_UT_ASSERT(rc == 0);
319 
321  M0_UT_ASSERT(rfop != NULL);
322 
323  process_fop_resp = m0_fop_data(rfop);
324  M0_UT_ASSERT(process_fop_resp->sspr_rc == 0);
325  rc = process_fop_resp->sspr_rc;
326  M0_UT_ASSERT(rc == 0);
327 
328  M0_UT_ASSERT(process_fop_resp->sspr_services.ab_count > 0);
329 
331 }
332 
334 {
335  struct m0_fop *fop;
336 
338  ut_sss_process_param_set(fop, "no-such-library");
339  ut_sss_process_req(fop, -EINVAL);
340 }
341 
343 {
344  struct m0_fop *fop;
345 
347  ut_sss_process_param_set(fop, "libc.so.6"); /* OK, fragile. */
349 }
350 
359 {
360  struct m0_fop *fop;
361  char *sopath;
362  int rc;
363  int i;
364 
365  /*
366  * This failure injection can be enabled, because libtestlib.so is also
367  * loaded by other tests.
368  */
369  m0_fi_enable(__func__, "loaded");
370  m0_fi_disable(__func__, "loaded");
371  /*
372  * Convoluted code below because, M0_FI_ENABLED() introduces a static
373  * structure. That is, multiple M0_FI_ENABLED(LABEL) with the same
374  * label are *different* fi points.
375  */
376  for (i = 0; i < 2; ++i) {
377  M0_UT_ASSERT(!!M0_FI_ENABLED("loaded") == !!i);
378  if (i == 0) {
379  rc = asprintf(&sopath, "%s/%s",
380  m0_build_info_get()->bi_build_dir,
381  "ut/.libs/libtestlib.so.0.0.0");
382  M0_UT_ASSERT(rc >= 0);
383  M0_UT_ASSERT(sopath != NULL);
385  ut_sss_process_param_set(fop, sopath);
387  } else
388  free(sopath);
389  }
390 }
391 
392 static void sss_fop_ut_release(struct m0_ref *ref)
393 {
394  struct m0_fop *fop;
395  fop = M0_AMB(fop, ref, f_ref);
396  m0_free(fop);
397 }
398 
400 {
401  int rc;
402  struct m0_fop *fop;
403  struct m0_fom *fom;
404  struct m0_reqh *reqh;
405  struct m0_ss_process_req *req;
406 
407  M0_ALLOC_PTR(fop);
408  M0_ALLOC_PTR(req);
409  M0_ALLOC_PTR(fom);
411 
414  req->ssp_cmd = 1;
415 
416  m0_fi_enable_once("ss_process_fom_create", "fom_alloc_fail");
418  M0_UT_ASSERT(rc == -ENOMEM);
419 
420  m0_fi_enable_once("ss_process_fom_create", "fop_alloc_fail");
423  M0_UT_ASSERT(rc == -ENOMEM);
424 
425  m0_fi_enable_once("ss_process_fom_create", "fop_data_alloc_fail");
428  M0_UT_ASSERT(rc == -ENOMEM);
429 
430  m0_fop_fini(fop);
431  m0_free(fop);
432  m0_free(fom);
433  m0_free(reqh);
434 }
435 
441 static void sss_device_fom_create_fail(void)
442 {
443  int rc;
444  struct m0_fop *fop;
445  struct m0_fom *fom;
446  struct m0_sss_device_fop *req;
447  struct m0_reqh *reqh;
448 
449  M0_ALLOC_PTR(fop);
450  M0_ALLOC_PTR(req);
451  M0_ALLOC_PTR(fom);
453 
455  req->ssd_cmd = M0_DEVICE_ATTACH;
456 
457  m0_fi_enable_once("sss_device_fom_create", "fom_alloc_fail");
460  M0_UT_ASSERT(rc == -ENOMEM);
461 
462  m0_fi_enable_once("sss_device_fom_create", "fop_alloc_fail");
465  M0_UT_ASSERT(rc == -ENOMEM);
466 
467  m0_fop_fini(fop);
468  m0_free(fop);
469  m0_free(fom);
470  m0_free(reqh);
471 }
472 
473 struct m0_ut_suite sss_ut = {
474  .ts_name = "sss-ut",
475  .ts_init = sss_ut_init,
476  .ts_fini = sss_ut_fini,
477  .ts_tests = {
478  { "commands", sss_commands_test },
479  { "process-commands", sss_process_commands_test },
480  { "process-services-list", sss_process_svc_list_test },
481  { "process-fom-create-fail", sss_process_fom_create_fail },
482  { "device-fom-fail", sss_device_fom_create_fail },
483  { "lib-load-noent", sss_process_lib_load_noent_test },
484  { "lib-load-libc", sss_process_lib_load_libc_test },
485  { "lib-testlib", sss_process_lib_load_testlib_test },
486  { NULL, NULL },
487  },
488 };
489 M0_EXPORTED(sss_ut);
490 
491 #undef M0_TRACE_SUBSYSTEM
492 
493 /*
494  * Local variables:
495  * c-indentation-style: "K&R"
496  * c-basic-offset: 8
497  * tab-width: 8
498  * fill-column: 80
499  * scroll-step: 1
500  * End:
501  */
#define SERVER_ENDPOINT
Definition: sss_ut.c:40
static void sss_process_quiesce_test(void)
Definition: sss_ut.c:265
static void rpc_client_and_server_stop(void)
Definition: sss_ut.c:108
void m0_net_domain_fini(struct m0_net_domain *dom)
Definition: domain.c:71
static int sss_ut_fini(void)
Definition: sss_ut.c:175
#define NULL
Definition: misc.h:38
uint32_t ssr_state
Definition: ss_fops.h:86
static struct io_request req
Definition: file.c:100
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
#define M0_LOG(level,...)
Definition: trace.h:167
M0_LEAVE()
struct m0_fop_type m0_sss_fop_device_fopt
Definition: device_fops.c:39
int m0_rpc_server_start(struct m0_rpc_server_ctx *sctx)
Definition: rpclib.c:50
int(* fto_create)(struct m0_fop *fop, struct m0_fom **out, struct m0_reqh *reqh)
Definition: fom.h:650
uint32_t ab_count
Definition: buf.h:44
M0_INTERNAL void m0_buf_init(struct m0_buf *buf, void *data, uint32_t nob)
Definition: buf.c:37
static void sss_process_svc_list_test(void)
Definition: sss_ut.c:307
void * m0_fop_data(const struct m0_fop *fop)
Definition: fop.c:220
static const struct m0_fid ut_fid
Definition: sss_ut.c:49
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
static struct m0_rpc_item * item
Definition: item.c:56
struct m0_fom_type ft_fom_type
Definition: fop.h:232
struct m0_fop_type m0_fop_process_fopt
Definition: process_fops.c:42
return M0_RC(rc)
static char * server_argv[]
Definition: sss_ut.c:56
#define M0_ENTRY(...)
Definition: trace.h:170
static void sss_device_fom_create_fail(void)
Definition: sss_ut.c:441
struct m0_ut_suite sss_ut
Definition: sss_ut.c:473
static void sss_process_lib_load_noent_test(void)
Definition: sss_ut.c:333
int i
Definition: dir.c:1033
struct m0_fop_type * f_type
Definition: fop.h:81
static void ut_sss_process_param_set(struct m0_fop *fop, const char *name)
Definition: sss_ut.c:232
static void ut_sss_process_req(struct m0_fop *fop, int ssr_rc_exptd)
Definition: sss_ut.c:245
static void rpc_client_and_server_start(void)
Definition: sss_ut.c:83
struct m0_fid ss_id
Definition: ss_fops.h:71
const struct m0_build_info * m0_build_info_get(void)
Definition: version.c:61
#define SERVER_LOG_NAME
Definition: sss_ut.c:38
#define CLIENT_ENDPOINT_ADDR
Definition: sss_ut.c:43
const char * name
Definition: trace.c:110
#define M0_FID_TINIT(type, container, key)
Definition: fid.h:90
#define M0_AMB(obj, ptr, field)
Definition: misc.h:320
static void sss_commands_test(void)
Definition: sss_ut.c:183
Definition: refs.h:34
struct m0_buf ss_name
Definition: ss_fops.h:66
static void sss_process_lib_load_libc_test(void)
Definition: sss_ut.c:342
static struct m0_rpc_server_ctx sctx
Definition: sss_ut.c:64
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
#define M0_ASSERT(cond)
static void sss_process_reconfig_test(void)
Definition: sss_ut.c:273
static struct m0_fop * sss_ut_fop_alloc(const char *name, uint32_t cmd)
Definition: sss_ut.c:120
struct m0_bufs sspr_services
Definition: process_fops.h:148
static void sss_process_fom_create_fail(void)
Definition: sss_ut.c:399
#define M0_BUF_INIT0
Definition: buf.h:71
int m0_net_xprt_nr(void)
Definition: net.c:168
#define SERVER_ADDB_STOB_NAME
Definition: sss_ut.c:37
int m0_rpc_client_stop(struct m0_rpc_client_ctx *cctx)
Definition: rpclib.c:217
static int sss_ut_init(void)
Definition: sss_ut.c:167
static struct m0_fop * ut_sss_process_create_req(uint32_t cmd)
Definition: sss_ut.c:212
#define SERVER_DB_NAME
Definition: sss_ut.c:35
struct m0_net_xprt * m0_net_xprt_default_get(void)
Definition: net.c:151
int m0_rpc_client_start(struct m0_rpc_client_ctx *cctx)
Definition: rpclib.c:160
struct m0_net_xprt ** rsx_xprts
Definition: rpclib.h:69
struct m0_rpc_item * ri_reply
Definition: item.h:163
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
struct m0_fid ssp_id
Definition: process_fops.h:70
uint64_t f_container
Definition: fid.h:39
static void sss_ut_req(uint32_t cmd, int32_t expected_rc, uint32_t expected_state)
Definition: sss_ut.c:140
Definition: reqh.h:94
Definition: dump.c:103
static struct m0_net_domain client_net_dom
Definition: sss_ut.c:54
M0_INTERNAL void m0_fop_fini(struct m0_fop *fop)
Definition: fop.c:136
struct m0_net_domain * rcx_net_dom
Definition: rpclib.h:128
#define SERVER_STOB_NAME
Definition: sss_ut.c:36
const struct m0_fom_type_ops * ft_ops
Definition: fom.h:614
M0_INTERNAL void m0_ss_fop_release(struct m0_ref *ref)
Definition: ss_fops.c:96
static struct m0_rpc_client_ctx cctx
Definition: sss_ut.c:72
static void sss_process_stop_test(void)
Definition: sss_ut.c:290
#define SERVER_ENDPOINT_ADDR
Definition: sss_ut.c:39
Definition: fom.h:481
const char * ts_name
Definition: ut.h:99
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
int rsx_xprts_nr
Definition: rpclib.h:71
struct m0_rpc_session rcx_session
Definition: rpclib.h:147
#define M0_FI_ENABLED(tag)
Definition: finject.h:231
struct m0_ref f_ref
Definition: fop.h:80
Definition: fid.h:38
M0_INTERNAL void m0_fop_release(struct m0_ref *ref)
Definition: fop.c:148
#define M0_ALLOC_PTR(ptr)
Definition: memory.h:86
#define M0_UT_CONF_PROCESS
Definition: misc.h:45
struct m0_net_xprt ** m0_net_all_xprt_get(void)
Definition: net.c:161
static void sss_process_commands_test(void)
Definition: sss_ut.c:299
static void sss_fop_ut_release(struct m0_ref *ref)
Definition: sss_ut.c:392
void m0_fop_put_lock(struct m0_fop *fop)
Definition: fop.c:199
static struct m0_fop * fop
Definition: item.c:57
struct m0_fop * m0_rpc_item_to_fop(const struct m0_rpc_item *item)
Definition: fop.c:346
static void m0_fi_enable_once(const char *func, const char *tag)
Definition: finject.h:301
static void sss_process_lib_load_testlib_test(void)
Definition: sss_ut.c:358
void m0_rpc_server_stop(struct m0_rpc_server_ctx *sctx)
Definition: rpclib.c:85
struct m0_rpc_machine rcx_rpc_machine
Definition: rpclib.h:145
int32_t ssr_rc
Definition: ss_fops.h:81
#define M0_UT_PATH(name)
Definition: misc.h:41
static enum m0_ha_obj_state expected_state
Definition: item.c:50
struct m0_rpc_machine * ri_rmachine
Definition: item.h:160
void m0_free(void *data)
Definition: memory.c:146
static void sss_process_health_test(void)
Definition: sss_ut.c:282
struct m0_rpc_item f_item
Definition: fop.h:83
#define M0_BUF_INIT_CONST(size, data)
Definition: buf.h:66
int32_t rc
Definition: trigger_fop.h:47
#define ARRAY_SIZE(a)
Definition: misc.h:45
struct m0_fid g_process_fid
Definition: ut.c:689
#define M0_UT_ASSERT(a)
Definition: ut.h:46
struct m0_motr rsx_motr_ctx
Definition: rpclib.h:84
const struct m0_fom_type_ops ss_process_fom_type_ops
Definition: process_foms.c:87
Definition: fop.h:79