Motr  M0
client_server.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 2013-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" /* M0_UT_ASSERT */
24 #include "lib/memory.h" /* m0_free */
25 #include "lib/thread.h" /* M0_THREAD_INIT */
26 #include "lib/semaphore.h" /* m0_semaphore_down */
27 #include "lib/misc.h" /* M0_SET0 */
28 #include "lib/trace.h" /* M0_LOG */
29 
30 #include "net/lnet/lnet.h" /* M0_NET_LNET_PID */
31 
32 #include "net/test/node.h" /* m0_net_test_node_ctx */
33 #include "net/test/console.h" /* m0_net_test_console_ctx */
35 
36 #define NET_TEST_MODULE_NAME ut_client_server
37 #include "net/test/debug.h"
38 
39 enum {
54 };
55 
59 
60 static char *addr_console4clients;
61 static char *addr_console4servers;
66 
67 /* s/NTCS_TIMEOUT/NTCS_TIMEOUT_GDB/ while using gdb */
69 
70 static char *addr_get(const char *nid, int tmid)
71 {
73  char *result;
74  int rc;
75 
76  rc = snprintf(addr, NTCS_NODE_ADDR_MAX,
77  "%s:%d:%d:%d", nid, NTCS_PID, NTCS_PORTAL, tmid);
79 
80  result = m0_alloc(NTCS_NODE_ADDR_MAX);
81  M0_UT_ASSERT(result != NULL);
82  return strncpy(result, addr, NTCS_NODE_ADDR_MAX);
83 }
84 
85 static void addr_free(char *addr)
86 {
87  m0_free(addr);
88 }
89 
91 {
92  struct m0_net_test_node_ctx *ctx;
93  int rc;
94 
95  M0_PRE(node_cfg != NULL);
96 
98  M0_ASSERT(ctx != NULL);
100  M0_UT_ASSERT(rc == 0);
102  M0_UT_ASSERT(rc == 0);
104  /* wait for the test node thread */
105  m0_semaphore_down(&ctx->ntnc_thread_finished_sem);
108  m0_free(ctx);
109 }
110 
111 static void node_cfg_fill(struct m0_net_test_node_cfg *ncfg,
112  char *addr_cmd,
113  char *addr_cmd_list,
114  char *addr_data,
115  char *addr_data_list,
116  char *addr_console,
117  bool last_node)
118 {
119  *ncfg = (struct m0_net_test_node_cfg) {
120  .ntnc_addr = addr_cmd,
121  .ntnc_addr_console = addr_console,
122  .ntnc_send_timeout = timeout,
123  };
124 
125  strncat(addr_cmd_list, ncfg->ntnc_addr, NTCS_NODE_ADDR_MAX - 1);
126  strncat(addr_cmd_list, last_node ? "" : ",", 2);
127  strncat(addr_data_list, addr_data, NTCS_NODE_ADDR_MAX - 1);
128  strncat(addr_data_list, last_node ? "" : ",", 2);
129 
130  addr_free(addr_data);
131 }
132 
133 static void msg_nr_print(const char *prefix,
134  const struct m0_net_test_msg_nr *msg_nr)
135 {
136  LOGD("%-21s total/failed/bad = %lu/%lu/%lu", prefix,
137  msg_nr->ntmn_total, msg_nr->ntmn_failed, msg_nr->ntmn_bad);
138 }
139 
140 static bool msg_nr_in_range(size_t nr1, size_t nr2)
141 {
142  size_t nr1_x100 = nr1 * 100;
143  return nr1_x100 >= nr2 * (100 - NTCS_ACCEPTABLE_MSG_LOSS) &&
144  nr1_x100 <= nr2 * (100 + NTCS_ACCEPTABLE_MSG_LOSS);
145 }
146 
147 #define nrchk(nr1, nr2) \
148 { \
149  size_t total1 = (nr1)->ntmn_total; \
150  size_t total2 = (nr2)->ntmn_total; \
151  M0_UT_ASSERT(msg_nr_in_range(total1, total2)); \
152  M0_UT_ASSERT(msg_nr_in_range(total2, total1)); \
153 }
154 
155 /*
156  * Real situation - no explicit synchronization
157  * between test console and test nodes.
158  */
159 static void net_test_client_server(const char *nid,
160  enum m0_net_test_type type,
161  size_t clients_nr,
162  size_t servers_nr,
163  size_t concurrency_client,
164  size_t concurrency_server,
165  size_t msg_nr,
166  m0_bcount_t msg_size,
167  size_t bd_buf_nr_client,
168  size_t bd_buf_nr_server,
169  m0_bcount_t bd_buf_size,
170  size_t bd_nr_max)
171 {
172  struct m0_net_test_cmd_status_data *sd_servers;
173  struct m0_net_test_cmd_status_data *sd_clients;
174  struct m0_net_test_console_cfg *console_cfg;
176  int rc;
177  int i;
178 
179  M0_PRE(clients_nr <= NTCS_NODES_MAX);
180  M0_PRE(servers_nr <= NTCS_NODES_MAX);
181 
182  M0_ALLOC_PTR(console_cfg);
184  if (console_cfg == NULL || console == NULL)
185  goto done;
186  /* prepare config for test clients and test servers */
189  clients[0] = '\0';
190  clients_data[0] = '\0';
191  for (i = 0; i < clients_nr; ++i) {
196  i == clients_nr - 1);
197  }
198  servers[0] = '\0';
199  servers_data[0] = '\0';
200  for (i = 0; i < servers_nr; ++i) {
201  node_cfg_fill(&node_cfg[clients_nr + i],
205  i == servers_nr - 1);
206  }
207  /* spawn test clients and test servers */
209  for (i = 0; i < clients_nr + servers_nr; ++i) {
211  struct m0_net_test_node_cfg *,
213  "net_test node%d", i);
214  M0_UT_ASSERT(rc == 0);
215  }
216  /* wait until test node started */
217  for (i = 0; i < clients_nr + servers_nr; ++i)
220  /* prepare console config */
221  *console_cfg = (struct m0_net_test_console_cfg) {
223  .ntcc_addr_console4clients = addr_console4clients,
224  .ntcc_cmd_send_timeout = timeout,
225  .ntcc_cmd_recv_timeout = timeout,
226  .ntcc_buf_send_timeout = timeout,
227  .ntcc_buf_recv_timeout = timeout,
228  .ntcc_buf_bulk_timeout = timeout,
229  .ntcc_test_type = type,
230  .ntcc_msg_nr = msg_nr,
231  .ntcc_test_time_limit = M0_TIME_NEVER,
232  .ntcc_msg_size = msg_size,
233  .ntcc_bd_buf_nr_server = bd_buf_nr_server,
234  .ntcc_bd_buf_nr_client = bd_buf_nr_client,
235  .ntcc_bd_buf_size = bd_buf_size,
236  .ntcc_bd_nr_max = bd_nr_max,
237  .ntcc_concurrency_server = concurrency_server,
238  .ntcc_concurrency_client = concurrency_client,
239  };
240  LOGD("addr_console4servers = %s", addr_console4servers);
241  LOGD("addr_console4clients = %s", addr_console4clients);
242  LOGD("clients = %s", (char *) clients);
243  LOGD("servers = %s", (char *) servers);
244  LOGD("clients_data = %s", (char *) clients_data);
245  LOGD("servers_data = %s", (char *) servers_data);
246  rc = m0_net_test_slist_init(&console_cfg->ntcc_clients, clients, ',');
247  M0_UT_ASSERT(rc == 0);
248  rc = m0_net_test_slist_init(&console_cfg->ntcc_servers, servers, ',');
249  M0_UT_ASSERT(rc == 0);
251  clients_data, ',');
252  M0_UT_ASSERT(rc == 0);
254  servers_data, ',');
255  M0_UT_ASSERT(rc == 0);
256  /* initialize console */
257  rc = m0_net_test_console_init(console, console_cfg);
258  M0_UT_ASSERT(rc == 0);
259  /* send INIT to the test servers */
262  M0_UT_ASSERT(rc == servers_nr);
263  /* send INIT to the test clients */
266  M0_UT_ASSERT(rc == clients_nr);
267  /* send START command to the test servers */
270  M0_UT_ASSERT(rc == servers_nr);
271  /* send START command to the test clients */
274  M0_UT_ASSERT(rc == clients_nr);
275  /* send STATUS command to the test clients until it finishes. */
276  do {
279  M0_UT_ASSERT(rc == clients_nr);
280  } while (!console->ntcc_clients.ntcrc_sd->ntcsd_finished);
281  /*
282  * Sleep a second to wait test update its status.
283  * TODO: Making a quiesce command (or is_quiesced query) for servers
284  * which will tell if all buffer callbacks are executed. After this is
285  * done and it’s called from the test, 1s delay will no longer be
286  * needed. So the bug is actually in UT which compares the values that
287  * can’t be compared. From @max.
288  */
289  m0_nanosleep(m0_time(1,0), NULL);
290  /* send STATUS command to the test clients */
293  M0_UT_ASSERT(rc == clients_nr);
294  /* send STATUS command to the test servers */
297  M0_UT_ASSERT(rc == servers_nr);
298  msg_nr_print("client msg sent",
299  &console->ntcc_clients.ntcrc_sd->ntcsd_msg_nr_send);
300  msg_nr_print("client msg received",
301  &console->ntcc_clients.ntcrc_sd->ntcsd_msg_nr_recv);
302  msg_nr_print("client bulk sent",
303  &console->ntcc_clients.ntcrc_sd->ntcsd_bulk_nr_send);
304  msg_nr_print("client bulk received",
305  &console->ntcc_clients.ntcrc_sd->ntcsd_bulk_nr_recv);
306  msg_nr_print("client transfers",
307  &console->ntcc_clients.ntcrc_sd->ntcsd_transfers);
308  msg_nr_print("server msg sent",
309  &console->ntcc_servers.ntcrc_sd->ntcsd_msg_nr_send);
310  msg_nr_print("server msg received",
311  &console->ntcc_servers.ntcrc_sd->ntcsd_msg_nr_recv);
312  msg_nr_print("server bulk sent",
313  &console->ntcc_servers.ntcrc_sd->ntcsd_bulk_nr_send);
314  msg_nr_print("server bulk received",
315  &console->ntcc_servers.ntcrc_sd->ntcsd_bulk_nr_recv);
316  msg_nr_print("server transfers",
317  &console->ntcc_servers.ntcrc_sd->ntcsd_transfers);
318  /* send STOP command to the test clients */
321  M0_UT_ASSERT(rc == clients_nr);
322  /* send STOP command to the test servers */
325  M0_UT_ASSERT(rc == servers_nr);
326  sd_servers = console->ntcc_servers.ntcrc_sd;
327  sd_clients = console->ntcc_clients.ntcrc_sd;
328  /* check stats */
329  nrchk(&sd_servers->ntcsd_msg_nr_send, &sd_clients->ntcsd_msg_nr_recv);
330  nrchk(&sd_servers->ntcsd_msg_nr_recv, &sd_clients->ntcsd_msg_nr_send);
331  nrchk(&sd_servers->ntcsd_bulk_nr_send, &sd_clients->ntcsd_bulk_nr_recv);
332  nrchk(&sd_servers->ntcsd_bulk_nr_recv, &sd_clients->ntcsd_bulk_nr_send);
333  if (type == M0_NET_TEST_TYPE_BULK) {
334  /*
335  * number of transfers are not measured on the test server
336  * for ping test.
337  */
338  nrchk(&sd_servers->ntcsd_transfers,
339  &sd_clients->ntcsd_transfers);
340  }
341  /* finalize console */
342  m0_net_test_slist_fini(&console_cfg->ntcc_servers);
343  m0_net_test_slist_fini(&console_cfg->ntcc_clients);
347  /* finalize test clients and test servers */
348  for (i = 0; i < clients_nr + servers_nr; ++i) {
350  M0_UT_ASSERT(rc == 0);
352  addr_free(node_cfg[i].ntnc_addr);
353  }
356 done:
357  m0_free(console);
358  m0_free(console_cfg);
359 }
360 
362 {
363  /* test console-node interaction with dummy node */
365  1, 1, 1, 1, 1, 1,
366  0, 0, 0, 0);
367 }
368 
370 {
371  /*
372  * - 0@lo interface
373  * - 8 test clients, 8 test servers
374  * - 8 pairs of concurrent buffers on each test client
375  * - 128 concurrent buffers on each test server
376  * - 4k test messages x 4KiB per message
377  */
379  8, 8, 8, 128, 0x1000, 0x1000,
380  /* 1, 1, 8, 128, 0x1000, 0x1000, */
381  0, 0, 0, 0);
382 }
383 
385 {
390  /*
391  * - 0@lo interface
392  * - 2 test clients, 2 test servers
393  * - 2 pairs of concurrent buffers on each test client
394  * - 8 concurrent buffers on each test server
395  * - 64 test messages x 1MiB per message
396  * - 8(16) network buffers for network buffer descriptors
397  * on the test client(server) with 16KiB per buffer and
398  * 64k maximum buffer descriptors in buffer
399  */
401  2, 2, 2, 8,
402  64, 0x100000,
403  8, 16, 0x4000, 0x10000);
404 }
406 {
407  M0_LOG(M0_DEBUG, "Before mem fini\n");
412  M0_LOG(M0_DEBUG, "After mem fini\n");
416  M0_LOG(M0_DEBUG, "After mem init\n");
418 
422  M0_LOG(M0_DEBUG, "After Lnet fini\n");
426  M0_LOG(M0_DEBUG, "After Lnet init\n");
428 
429 }
430 
431 #undef NET_TEST_MODULE_NAME
432 
433 /*
434  * Local variables:
435  * c-indentation-style: "K&R"
436  * c-basic-offset: 8
437  * tab-width: 8
438  * fill-column: 79
439  * scroll-step: 1
440  * End:
441  */
m0_net_test_type
Definition: commands.h:68
#define nrchk(nr1, nr2)
static void addr_free(char *addr)
Definition: client_server.c:85
#define M0_PRE(cond)
void m0_net_test_node_stop(struct m0_net_test_node_ctx *ctx)
Definition: node.c:932
#define NULL
Definition: misc.h:38
void m0_net_test_xprt_dynamic_reg_dereg_ut(void)
static char * addr_console4clients
Definition: client_server.c:60
int m0_thread_join(struct m0_thread *q)
Definition: kthread.c:169
static char clients_data[NTCS_NODES_MAX *NTCS_NODE_ADDR_MAX]
Definition: client_server.c:64
const struct m0_net_xprt m0_net_lnet_xprt
Definition: lnet_xo.c:679
const m0_time_t M0_TIME_NEVER
Definition: time.c:108
static void msg_nr_print(const char *prefix, const struct m0_net_test_msg_nr *msg_nr)
uint64_t m0_time_t
Definition: time.h:37
#define M0_LOG(level,...)
Definition: trace.h:167
static struct m0_uint128 prefix
Definition: extmap.c:45
M0_INTERNAL int m0_mem_xprt_init(void)
Definition: mem_xprt_xo.c:47
uint64_t m0_bcount_t
Definition: types.h:77
#define M0_THREAD_INIT(thread, TYPE, init, func, arg, namefmt,...)
Definition: thread.h:139
int m0_net_test_slist_init(struct m0_net_test_slist *slist, const char *str, char delim)
Definition: slist.c:57
struct m0_net_test_msg_nr ntcsd_bulk_nr_send
Definition: commands.h:170
m0_time_t m0_time(uint64_t secs, long ns)
Definition: time.c:41
static m0_time_t timeout
Definition: client_server.c:68
struct m0_net_test_msg_nr ntcsd_transfers
Definition: commands.h:174
char * ntnc_addr
Definition: node.h:193
void m0_net_test_client_server_bulk_ut(void)
static struct m0_net_test_cmd_ctx console
Definition: commands.c:73
void m0_net_test_console_fini(struct m0_net_test_console_ctx *ctx)
Definition: console.c:122
int i
Definition: dir.c:1033
void m0_net_test_client_server_ping_ut(void)
static char * addr_get(const char *nid, int tmid)
Definition: client_server.c:70
#define LOGD(...)
Definition: tx_regmap.c:37
static struct m0_net_test_node_cfg node_cfg[NTCS_NODES_MAX *2]
Definition: client_server.c:56
int m0_net_test_node_start(struct m0_net_test_node_ctx *ctx)
Definition: node.c:921
size_t ntmn_bad
Definition: stats.h:322
size_t m0_net_test_console_cmd(struct m0_net_test_console_ctx *ctx, enum m0_net_test_role role, enum m0_net_test_cmd_type cmd_type)
Definition: console.c:228
#define M0_ASSERT(cond)
char * ntcc_addr_console4servers
Definition: console.h:52
void m0_net_test_slist_fini(struct m0_net_test_slist *slist)
Definition: slist.c:120
static char servers[NTCS_NODES_MAX *NTCS_NODE_ADDR_MAX]
Definition: client_server.c:63
struct m0_net_test_msg_nr ntcsd_msg_nr_recv
Definition: commands.h:168
void m0_thread_fini(struct m0_thread *q)
Definition: thread.c:92
static struct m0_thread node_thread[NTCS_NODES_MAX *2]
Definition: client_server.c:57
M0_INTERNAL void m0_net_print_xprt(void)
Definition: net.c:215
M0_INTERNAL int m0_semaphore_init(struct m0_semaphore *semaphore, unsigned value)
Definition: semaphore.c:38
void * m0_alloc(size_t size)
Definition: memory.c:126
Definition: xcode.h:73
size_t ntmn_total
Definition: stats.h:308
static struct fdmi_ctx ctx
Definition: main.c:80
struct m0_net_test_slist ntcc_data_clients
Definition: console.h:77
static char * addr_console4servers
Definition: client_server.c:61
struct m0_net_test_msg_nr ntcsd_msg_nr_send
Definition: commands.h:166
static char * addr_console
Definition: node_k.c:38
M0_INTERNAL void m0_mem_xprt_fini(void)
Definition: mem_xprt_xo.c:59
M0_INTERNAL int m0_net_lnet_init(void)
Definition: lnet_main.c:923
void m0_net_test_client_server_stub_ut(void)
void m0_net_test_node_fini(struct m0_net_test_node_ctx *ctx)
Definition: node.c:915
int m0_net_test_node_init(struct m0_net_test_node_ctx *ctx, struct m0_net_test_node_cfg *cfg)
Definition: node.c:909
#define M0_ALLOC_PTR(ptr)
Definition: memory.h:86
M0_INTERNAL void m0_semaphore_fini(struct m0_semaphore *semaphore)
Definition: semaphore.c:45
M0_INTERNAL bool m0_net_check_xprt(const struct m0_net_xprt *xprt)
Definition: net.c:225
int m0_net_test_console_init(struct m0_net_test_console_ctx *ctx, struct m0_net_test_console_cfg *cfg)
Definition: console.c:116
struct m0_net_test_msg_nr ntcsd_bulk_nr_recv
Definition: commands.h:172
struct m0_net_test_slist ntcc_servers
Definition: console.h:60
size_t ntmn_failed
Definition: stats.h:316
static char clients[NTCS_NODES_MAX *NTCS_NODE_ADDR_MAX]
Definition: client_server.c:62
static char servers_data[NTCS_NODES_MAX *NTCS_NODE_ADDR_MAX]
Definition: client_server.c:65
static void node_cfg_fill(struct m0_net_test_node_cfg *ncfg, char *addr_cmd, char *addr_cmd_list, char *addr_data, char *addr_data_list, char *addr_console, bool last_node)
#define M0_MKTIME(secs, ns)
Definition: time.h:86
static unsigned done
Definition: storage.c:91
M0_INTERNAL void m0_semaphore_down(struct m0_semaphore *semaphore)
Definition: semaphore.c:49
Definition: nucleus.c:42
struct m0_net_test_slist ntcc_clients
Definition: console.h:65
int type
Definition: dir.c:1031
struct m0_net_test_slist ntcc_data_servers
Definition: console.h:72
M0_INTERNAL void m0_semaphore_up(struct m0_semaphore *semaphore)
Definition: semaphore.c:65
static void net_test_node(struct m0_net_test_node_cfg *node_cfg)
Definition: client_server.c:90
static void net_test_client_server(const char *nid, enum m0_net_test_type type, size_t clients_nr, size_t servers_nr, size_t concurrency_client, size_t concurrency_server, size_t msg_nr, m0_bcount_t msg_size, size_t bd_buf_nr_client, size_t bd_buf_nr_server, m0_bcount_t bd_buf_size, size_t bd_nr_max)
void m0_free(void *data)
Definition: memory.c:146
M0_INTERNAL void m0_net_lnet_fini(void)
Definition: lnet_main.c:933
int32_t rc
Definition: trigger_fop.h:47
#define M0_UT_ASSERT(a)
Definition: ut.h:46
static struct m0_semaphore node_init_sem
Definition: client_server.c:58
static bool msg_nr_in_range(size_t nr1, size_t nr2)
const struct m0_net_xprt m0_net_bulk_mem_xprt
Definition: mem_xprt_xo.c:761
int m0_nanosleep(const m0_time_t req, m0_time_t *rem)
Definition: ktime.c:73