16 #ifndef __vcl_test_h__ 17 #define __vcl_test_h__ 24 #include <vcl/vppcom.h> 26 #define vtfail(_fn, _rv) \ 29 perror ("ERROR when calling " _fn); \ 30 fprintf (stderr, "\nERROR: " _fn " failed (errno = %d)!\n", -_rv); \ 34 #define vterr(_fn, _rv) \ 37 fprintf (stderr, "\nERROR: " _fn " failed (errno = %d)!\n", -_rv); \ 40 #define vtwrn(_fmt, _args...) \ 41 fprintf (stderr, "\nERROR: " _fmt "\n", ##_args) \ 43 #define vtinf(_fmt, _args...) \ 44 fprintf (stdout, "vt<w%u>: " _fmt "\n", __wrk_index, ##_args) 46 #define vt_atomic_add(_ptr, _val) \ 47 __atomic_fetch_add (_ptr, _val, __ATOMIC_RELEASE) 49 #define VCL_TEST_TOKEN_HELP "#H" 50 #define VCL_TEST_TOKEN_EXIT "#X" 51 #define VCL_TEST_TOKEN_VERBOSE "#V" 52 #define VCL_TEST_TOKEN_TXBUF_SIZE "#T:" 53 #define VCL_TEST_TOKEN_NUM_TEST_SESS "#I:" 54 #define VCL_TEST_TOKEN_NUM_WRITES "#N:" 55 #define VCL_TEST_TOKEN_RXBUF_SIZE "#R:" 56 #define VCL_TEST_TOKEN_SHOW_CFG "#C" 57 #define VCL_TEST_TOKEN_RUN_UNI "#U" 58 #define VCL_TEST_TOKEN_RUN_BI "#B" 60 #define VCL_TEST_SERVER_PORT 22000 61 #define VCL_TEST_LOCALHOST_IPADDR "127.0.0.1" 63 #define VCL_TEST_CFG_CTRL_MAGIC 0xfeedface 64 #define VCL_TEST_CFG_NUM_WRITES_DEF 1000000 65 #define VCL_TEST_CFG_TXBUF_SIZE_DEF 8192 66 #define VCL_TEST_CFG_RXBUF_SIZE_DEF (64*VCL_TEST_CFG_TXBUF_SIZE_DEF) 67 #define VCL_TEST_CFG_BUF_SIZE_MIN 128 68 #define VCL_TEST_CFG_MAX_TEST_SESS 512 69 #define VCL_TEST_CFG_MAX_EPOLL_EVENTS 16 71 #define VCL_TEST_CTRL_LISTENER (~0 - 1) 72 #define VCL_TEST_DATA_LISTENER (~0) 73 #define VCL_TEST_DELAY_DISCONNECT 1 74 #define VCL_TEST_SEPARATOR_STRING \ 75 " -----------------------------\n" 92 typedef struct __attribute__ ((packed))
121 struct timespec start;
122 struct timespec stop;
143 vppcom_data_segment_t
ds[2];
147 static __thread
int __wrk_index = 0;
181 #define VCL_TEST_REGISTER_PROTO(proto, vft) \ 182 static void __attribute__ ((constructor)) vcl_test_init_##proto (void) \ 184 vcl_test_main.protos[proto] = &vft; \ 234 uint8_t *lb =
realloc (*buf, (
size_t) alloc_size);
247 vtwrn (
"realloc failed. using buffer size %d instead of %u",
248 *bufsize, alloc_size);
302 printf (
" test config (%p):\n" 306 "%-5s test: %s (%d)\n" 307 " ctrl handle: %d (0x%x)\n" 308 "%-5s num test sockets: %u (0x%08x)\n" 309 "%-5s verbose: %s (%d)\n" 310 "%-5s rxbuf size: %lu (0x%08lx)\n" 311 "%-5s txbuf size: %lu (0x%08lx)\n" 312 "%-5s num writes: %lu (0x%08lx)\n" 313 " client tx bytes: %lu (0x%08lx)\n" 315 (
void *) cfg, cfg->
magic, cfg->seq_num,
321 cfg->ctrl_handle, cfg->ctrl_handle,
323 cfg->num_test_sessions, cfg->num_test_sessions,
325 cfg->verbose ?
"on" :
"off", cfg->verbose,
327 cfg->rxbuf_size, cfg->rxbuf_size,
329 cfg->txbuf_size, cfg->txbuf_size,
331 cfg->num_writes, cfg->num_writes,
332 cfg->total_bytes, cfg->total_bytes);
337 uint8_t show_rx, uint8_t show_tx, uint8_t verbose)
339 struct timespec diff;
340 double duration, rate;
341 uint64_t total_bytes;
343 if ((stats->
stop.tv_nsec - stats->
start.tv_nsec) < 0)
345 diff.tv_sec = stats->
stop.tv_sec - stats->
start.tv_sec - 1;
346 diff.tv_nsec = stats->
stop.tv_nsec - stats->
start.tv_nsec + 1e9;
350 diff.tv_sec = stats->
stop.tv_sec - stats->
start.tv_sec;
351 diff.tv_nsec = stats->
stop.tv_nsec - stats->
start.tv_nsec;
353 duration = (double) diff.tv_sec + (1e-9 * diff.tv_nsec);
356 rate = (double) total_bytes *8 / duration / 1e9;
357 printf (
"\n%s: Streamed %lu bytes\n" 358 " in %lf seconds (%lf Gbps %s-duplex)!\n",
359 header, total_bytes, duration, rate,
360 (show_rx && show_tx) ?
"full" :
"half");
365 " tx stats (0x%p):\n" 367 " writes: %lu (0x%08lx)\n" 368 " tx bytes: %lu (0x%08lx)\n" 369 " tx eagain: %u (0x%08x)\n" 370 " tx incomplete: %u (0x%08x)\n",
371 (
void *) stats, stats->
tx_xacts, stats->tx_xacts,
372 stats->tx_bytes, stats->tx_bytes,
373 stats->tx_eagain, stats->tx_eagain,
374 stats->tx_incomp, stats->tx_incomp);
379 " rx stats (0x%p):\n" 381 " reads: %lu (0x%08lx)\n" 382 " rx bytes: %lu (0x%08lx)\n" 383 " rx eagain: %u (0x%08x)\n" 384 " rx incomplete: %u (0x%08x)\n",
385 (
void *) stats, stats->
rx_xacts, stats->rx_xacts,
386 stats->rx_bytes, stats->rx_bytes,
387 stats->rx_eagain, stats->rx_eagain,
388 stats->rx_incomp, stats->rx_incomp);
391 printf (
" start.tv_sec: %ld\n" 392 " start.tv_nsec: %ld\n" 393 " stop.tv_sec: %ld\n" 394 " stop.tv_nsec: %ld\n",
396 stats->
stop.tv_sec, stats->
stop.tv_nsec);
405 if ((
new->tv_nsec - old->tv_nsec) < 0)
407 sec =
new->tv_sec - old->tv_sec - 1;
408 nsec =
new->tv_nsec - old->tv_nsec + 1e9;
412 sec =
new->tv_sec - old->tv_sec;
413 nsec =
new->tv_nsec - old->tv_nsec;
415 return (
double) sec + (1e-9 * nsec);
422 double duration, rate;
423 uint64_t total_bytes;
432 total_bytes =
new->rx_bytes - old->
rx_bytes;
433 dir_str =
"Received";
437 total_bytes =
new->tx_bytes - old->
tx_bytes;
441 rate = (double) total_bytes * 8 / duration / 1e9;
442 printf (
"%d: %s %lu Mbytes in %.2lf seconds %.2lf Gbps\n", ts->
fd, dir_str,
443 (uint64_t) (total_bytes / 1e6), duration, rate);
449 if (a->tv_sec < b->tv_sec)
451 else if (a->tv_sec > b->tv_sec)
453 else if (a->tv_nsec < b->tv_nsec)
455 else if (a->tv_nsec > b->tv_nsec)
465 int rv, rx_bytes = 0;
470 rv = vppcom_session_read (ts->
fd, buf, nbytes);
474 if (errno == EAGAIN || errno == EWOULDBLOCK)
480 vterr (
"vppcom_session_read()", -errno);
504 rx_bytes = vppcom_session_read_segments (ts->
fd, ts->
ds, 2, ~0);
511 if ((rx_bytes == 0) ||
513 && ((errno == EAGAIN) || (errno == EWOULDBLOCK))))
516 while ((rx_bytes == 0) ||
517 ((rx_bytes < 0) && ((errno == EAGAIN) || (errno == EWOULDBLOCK))));
521 vterr (
"vppcom_session_read()", -errno);
532 int tx_bytes = 0, nbytes_left = nbytes,
rv;
538 rv = vppcom_session_write (ts->
fd, buf, nbytes_left);
542 if ((errno == EAGAIN || errno == EWOULDBLOCK))
548 nbytes_left = nbytes_left -
rv;
550 if (rv < nbytes_left)
553 while (tx_bytes != nbytes);
557 vterr (
"vpcom_session_write", -errno);
570 printf (
"CLIENT: Test configuration commands:" 572 "\t\t\tDisplay help." 574 "\t\t\tExit test client & server." 576 "\t\t\tShow the current test cfg." 578 "\t\t\tRun the Uni-directional test." 580 "\t\t\tRun the Bi-directional test." 582 "\t\t\tToggle verbose setting." 584 "<rxbuf size>\tRx buffer size (bytes)." 586 "<txbuf size>\tTx buffer size (bytes)." 588 "<# of writes>\tNumber of txbuf writes to server." "\n");
vppcom_data_segment_t ds[2]
#define VCL_TEST_TOKEN_RXBUF_SIZE
static int vcl_test_worker_index(void)
static double vcl_test_time_diff(struct timespec *old, struct timespec *new)
Optimized string handling code, including c11-compliant "safe C library" variants.
static int vcl_test_write(vcl_test_session_t *ts, void *buf, uint32_t nbytes)
vcl_test_main_t vcl_test_main
uint32_t num_test_qsessions
static void dump_help(void)
uint32_t num_test_sessions
vcl_test_session_t * qsessions
#define VCL_TEST_TOKEN_NUM_WRITES
vl_api_cnat_endpoint_t new
#define VCL_TEST_TOKEN_SHOW_CFG
static void vcl_test_stats_dump(char *header, vcl_test_stats_t *stats, uint8_t show_rx, uint8_t show_tx, uint8_t verbose)
static void vcl_test_session_buf_alloc(vcl_test_session_t *ts)
static char * vcl_test_type_str(vcl_test_t t)
vl_api_ikev2_sa_stats_t stats
vcl_test_stats_t old_stats
int(* write)(struct vcl_test_session *ts, void *buf, uint32_t buflen)
#define VCL_TEST_SEPARATOR_STRING
static void vcl_test_cfg_dump(vcl_test_cfg_t *cfg, uint8_t is_client)
#define VCL_TEST_CFG_CTRL_MAGIC
#define VCL_TEST_TOKEN_RUN_BI
struct vcl_test_session vcl_test_session_t
static void vcl_test_cfg_init(vcl_test_cfg_t *cfg)
#define VCL_TEST_TOKEN_TXBUF_SIZE
#define VCL_TEST_TOKEN_VERBOSE
static void vcl_test_session_buf_free(vcl_test_session_t *ts)
uint32_t num_test_sessions_perq
#define VCL_TEST_TOKEN_HELP
static void vcl_test_buf_alloc(vcl_test_cfg_t *cfg, uint8_t is_rxbuf, uint8_t **buf, uint32_t *bufsize)
static int vcl_test_read(vcl_test_session_t *ts, void *buf, uint32_t nbytes)
void * realloc(void *p, size_t size)
#define VCL_TEST_CFG_NUM_WRITES_DEF
#define VCL_TEST_TOKEN_RUN_UNI
static int vcl_comp_tspec(struct timespec *a, struct timespec *b)
static void vcl_test_stats_accumulate(vcl_test_stats_t *accum, vcl_test_stats_t *incr)
#define VCL_TEST_CFG_RXBUF_SIZE_DEF
static int vcl_test_read_ds(vcl_test_session_t *ts)
#define VCL_TEST_CFG_TXBUF_SIZE_DEF
static void vcl_test_stats_dump_inc(vcl_test_session_t *ts, int is_rx)
#define VCL_TEST_TOKEN_NUM_TEST_SESS
#define VCL_TEST_TOKEN_EXIT
static int vcl_test_cfg_verify(vcl_test_cfg_t *cfg, vcl_test_cfg_t *valid_cfg)
#define vtwrn(_fmt, _args...)