LCOV - code coverage report
Current view: top level - plugins/hs_apps/vcl - vcl_test.h (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 123 182 67.6 %
Date: 2023-07-05 22:20:52 Functions: 12 17 70.6 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2017-2021 Cisco and/or its affiliates.
       3             :  * Licensed under the Apache License, Version 2.0 (the "License");
       4             :  * you may not use this file except in compliance with the License.
       5             :  * You may obtain a copy of the License at:
       6             :  *
       7             :  *     http://www.apache.org/licenses/LICENSE-2.0
       8             :  *
       9             :  * Unless required by applicable law or agreed to in writing, software
      10             :  * distributed under the License is distributed on an "AS IS" BASIS,
      11             :  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      12             :  * See the License for the specific language governing permissions and
      13             :  * limitations under the License.
      14             :  */
      15             : 
      16             : #ifndef __vcl_test_h__
      17             : #define __vcl_test_h__
      18             : 
      19             : #include <netdb.h>
      20             : #include <errno.h>
      21             : #include <stdlib.h>
      22             : #include <stdio.h>
      23             : #include <string.h>
      24             : #include <vcl/vppcom.h>
      25             : 
      26             : #define vtfail(_fn, _rv)                                                \
      27             : {                                                                       \
      28             :   errno = -_rv;                                                         \
      29             :   perror ("ERROR when calling " _fn);                                 \
      30             :   fprintf (stderr, "\nERROR: " _fn " failed (errno = %d)!\n", -_rv);        \
      31             :   exit (1);                                                             \
      32             : }
      33             : 
      34             : #define vterr(_fn, _rv)                                                 \
      35             : {                                                                       \
      36             :   errno = -_rv;                                                         \
      37             :   fprintf (stderr, "\nERROR: " _fn " failed (errno = %d)!\n", -_rv);        \
      38             : }
      39             : 
      40             : #define vtwrn(_fmt, _args...)                                           \
      41             :   fprintf (stderr, "\nERROR: " _fmt "\n", ##_args)                  \
      42             : 
      43             : #define vtinf(_fmt, _args...)                                           \
      44             :   fprintf (stdout, "vt<w%u>: " _fmt "\n", __wrk_index, ##_args)
      45             : 
      46             : #define vt_atomic_add(_ptr, _val)                                       \
      47             :   __atomic_fetch_add (_ptr, _val, __ATOMIC_RELEASE)
      48             : 
      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"
      59             : 
      60             : #define VCL_TEST_SERVER_PORT            22000
      61             : #define VCL_TEST_LOCALHOST_IPADDR       "127.0.0.1"
      62             : 
      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      ((uint32_t) 1e6)
      69             : #define VCL_TEST_CFG_MAX_SELECT_SESS    512
      70             : #define VCL_TEST_CFG_INIT_TEST_SESS     512
      71             : #define VCL_TEST_CFG_MAX_EPOLL_EVENTS   16
      72             : 
      73             : #define VCL_TEST_CTRL_LISTENER          (~0 - 1)
      74             : #define VCL_TEST_DATA_LISTENER          (~0)
      75             : #define VCL_TEST_DELAY_DISCONNECT       1
      76             : #define VCL_TEST_SEPARATOR_STRING       \
      77             :   "  -----------------------------\n"
      78             : typedef enum
      79             : {
      80             :   VCL_TEST_TYPE_NONE,
      81             :   VCL_TEST_TYPE_ECHO,
      82             :   VCL_TEST_TYPE_UNI,
      83             :   VCL_TEST_TYPE_BI,
      84             :   VCL_TEST_TYPE_EXIT,
      85             :   VCL_TEST_TYPE_EXIT_CLIENT,
      86             : } vcl_test_t;
      87             : 
      88             : typedef enum
      89             : {
      90             :   VCL_TEST_CMD_SYNC,
      91             :   VCL_TEST_CMD_START,
      92             :   VCL_TEST_CMD_STOP,
      93             : } vcl_test_cmd_t;
      94             : 
      95             : typedef struct __attribute__ ((packed))
      96             : {
      97             :   uint32_t magic;
      98             :   uint32_t seq_num;
      99             :   uint32_t test;
     100             :   uint32_t cmd;
     101             :   uint32_t ctrl_handle;
     102             :   uint32_t num_test_sessions;
     103             :   uint32_t num_test_sessions_perq;
     104             :   uint32_t num_test_qsessions;
     105             :   uint32_t verbose;
     106             :   uint32_t address_ip6;
     107             :   uint32_t transport_udp;
     108             :   uint64_t rxbuf_size;
     109             :   uint64_t txbuf_size;
     110             :   uint64_t num_writes;
     111             :   uint64_t total_bytes;
     112             : } vcl_test_cfg_t;
     113             : 
     114             : typedef struct
     115             : {
     116             :   uint64_t rx_xacts;
     117             :   uint64_t rx_bytes;
     118             :   uint32_t rx_eagain;
     119             :   uint32_t rx_incomp;
     120             :   uint64_t tx_xacts;
     121             :   uint64_t tx_bytes;
     122             :   uint32_t tx_eagain;
     123             :   uint32_t tx_incomp;
     124             :   struct timespec start;
     125             :   struct timespec stop;
     126             : } vcl_test_stats_t;
     127             : 
     128             : typedef struct vcl_test_session
     129             : {
     130             :   uint8_t is_done;
     131             :   uint8_t is_alloc : 1;
     132             :   uint8_t is_open : 1;
     133             :   uint8_t noblk_connect : 1;
     134             :   int fd;
     135             :   int (*read) (struct vcl_test_session *ts, void *buf, uint32_t buflen);
     136             :   int (*write) (struct vcl_test_session *ts, void *buf, uint32_t buflen);
     137             :   uint32_t txbuf_size;
     138             :   uint32_t rxbuf_size;
     139             :   char *txbuf;
     140             :   char *rxbuf;
     141             :   vcl_test_cfg_t cfg;
     142             :   vcl_test_stats_t stats;
     143             :   vcl_test_stats_t old_stats;
     144             :   int session_index;
     145             :   struct vcl_test_session *next;
     146             :   vppcom_endpt_t endpt;
     147             :   uint8_t ip[16];
     148             :   vppcom_data_segment_t ds[2];
     149             :   void *opaque;
     150             : } vcl_test_session_t;
     151             : 
     152             : static __thread int __wrk_index = 0;
     153             : 
     154             : static inline int
     155           0 : vcl_test_worker_index (void)
     156             : {
     157           0 :   return __wrk_index;
     158             : }
     159             : 
     160             : typedef struct
     161             : {
     162             :   int (*init) (vcl_test_cfg_t *cfg);
     163             :   int (*open) (vcl_test_session_t *ts, vppcom_endpt_t *endpt);
     164             :   int (*listen) (vcl_test_session_t *ts, vppcom_endpt_t *endpt);
     165             :   int (*accept) (int listen_fd, vcl_test_session_t *ts);
     166             :   int (*close) (vcl_test_session_t *ts);
     167             : } vcl_test_proto_vft_t;
     168             : 
     169             : typedef struct
     170             : {
     171             :   vcl_test_session_t *qsessions;
     172             :   uint32_t n_qsessions;
     173             :   uint32_t n_sessions;
     174             : } vcl_test_wrk_t;
     175             : 
     176             : typedef struct
     177             : {
     178             :   const vcl_test_proto_vft_t *protos[VPPCOM_PROTO_SRTP + 1];
     179             :   uint32_t ckpair_index;
     180             :   vcl_test_cfg_t cfg;
     181             :   vcl_test_wrk_t *wrk;
     182             : } vcl_test_main_t;
     183             : 
     184             : extern vcl_test_main_t vcl_test_main;
     185             : 
     186             : #define VCL_TEST_REGISTER_PROTO(proto, vft)                                   \
     187             :   static void __attribute__ ((constructor)) vcl_test_init_##proto (void)      \
     188             :   {                                                                           \
     189             :     vcl_test_main.protos[proto] = &vft;                                       \
     190             :   }
     191             : 
     192             : static inline void
     193        3606 : vcl_test_stats_accumulate (vcl_test_stats_t * accum, vcl_test_stats_t * incr)
     194             : {
     195        3606 :   accum->rx_xacts += incr->rx_xacts;
     196        3606 :   accum->rx_bytes += incr->rx_bytes;
     197        3606 :   accum->rx_eagain += incr->rx_eagain;
     198        3606 :   accum->rx_incomp += incr->rx_incomp;
     199        3606 :   accum->tx_xacts += incr->tx_xacts;
     200        3606 :   accum->tx_bytes += incr->tx_bytes;
     201        3606 :   accum->tx_eagain += incr->tx_eagain;
     202        3606 :   accum->tx_incomp += incr->tx_incomp;
     203        3606 : }
     204             : 
     205             : static inline void
     206          51 : vcl_test_cfg_init (vcl_test_cfg_t * cfg)
     207             : {
     208          51 :   cfg->magic = VCL_TEST_CFG_CTRL_MAGIC;
     209          51 :   cfg->test = VCL_TEST_TYPE_UNI;
     210          51 :   cfg->ctrl_handle = ~0;
     211          51 :   cfg->num_test_sessions = 1;
     212          51 :   cfg->num_test_sessions_perq = 1;
     213          51 :   cfg->verbose = 0;
     214          51 :   cfg->rxbuf_size = VCL_TEST_CFG_RXBUF_SIZE_DEF;
     215          51 :   cfg->num_writes = VCL_TEST_CFG_NUM_WRITES_DEF;
     216          51 :   cfg->txbuf_size = VCL_TEST_CFG_TXBUF_SIZE_DEF;
     217          51 :   cfg->total_bytes = cfg->num_writes * cfg->txbuf_size;
     218          51 : }
     219             : 
     220             : static inline int
     221          53 : vcl_test_cfg_verify (vcl_test_cfg_t * cfg, vcl_test_cfg_t * valid_cfg)
     222             : {
     223             :   /* Note: txbuf & rxbuf on server are the same buffer,
     224             :    *       so txbuf_size is not included in this check.
     225             :    */
     226          53 :   return ((cfg->magic == valid_cfg->magic)
     227          53 :           && (cfg->test == valid_cfg->test)
     228          53 :           && (cfg->verbose == valid_cfg->verbose)
     229          53 :           && (cfg->rxbuf_size == valid_cfg->rxbuf_size)
     230          53 :           && (cfg->num_writes == valid_cfg->num_writes)
     231         106 :           && (cfg->total_bytes == valid_cfg->total_bytes));
     232             : }
     233             : 
     234             : static inline void
     235         183 : vcl_test_buf_alloc (vcl_test_cfg_t * cfg, uint8_t is_rxbuf, uint8_t ** buf,
     236             :                     uint32_t * bufsize)
     237             : {
     238         183 :   uint32_t alloc_size = is_rxbuf ? cfg->rxbuf_size : cfg->txbuf_size;
     239         183 :   uint8_t *lb = realloc (*buf, (size_t) alloc_size);
     240             : 
     241         183 :   if (lb)
     242             :     {
     243         183 :       if (is_rxbuf)
     244         116 :         cfg->rxbuf_size = *bufsize = alloc_size;
     245             :       else
     246          67 :         cfg->txbuf_size = *bufsize = alloc_size;
     247             : 
     248         183 :       *buf = lb;
     249             :     }
     250             :   else
     251             :     {
     252           0 :       vtwrn ("realloc failed. using buffer size %d instead of %u",
     253             :              *bufsize, alloc_size);
     254             :     }
     255         183 : }
     256             : 
     257             : static inline void
     258          66 : vcl_test_session_buf_alloc (vcl_test_session_t *ts)
     259             : {
     260          66 :   ts->rxbuf_size = ts->cfg.rxbuf_size;
     261          66 :   ts->txbuf_size = ts->cfg.txbuf_size;
     262          66 :   vcl_test_buf_alloc (&ts->cfg, 0 /* is_rxbuf */, (uint8_t **) &ts->txbuf,
     263             :                       &ts->txbuf_size);
     264          66 :   vcl_test_buf_alloc (&ts->cfg, 1 /* is_rxbuf */, (uint8_t **) &ts->rxbuf,
     265             :                       &ts->rxbuf_size);
     266          66 : }
     267             : 
     268             : static inline void
     269        2605 : vcl_test_session_buf_free (vcl_test_session_t *ts)
     270             : {
     271        2605 :   free (ts->rxbuf);
     272        2605 :   free (ts->txbuf);
     273        2605 :   ts->rxbuf = 0;
     274        2605 :   ts->txbuf = 0;
     275        2605 : }
     276             : 
     277             : static inline char *
     278          17 : vcl_test_type_str (vcl_test_t t)
     279             : {
     280          17 :   switch (t)
     281             :     {
     282           0 :     case VCL_TEST_TYPE_NONE:
     283           0 :       return "NONE";
     284             : 
     285           0 :     case VCL_TEST_TYPE_ECHO:
     286           0 :       return "ECHO";
     287             : 
     288          11 :     case VCL_TEST_TYPE_UNI:
     289          11 :       return "UNI";
     290             : 
     291           6 :     case VCL_TEST_TYPE_BI:
     292           6 :       return "BI";
     293             : 
     294           0 :     case VCL_TEST_TYPE_EXIT:
     295           0 :       return "EXIT";
     296             : 
     297           0 :     default:
     298           0 :       return "Unknown";
     299             :     }
     300             : }
     301             : 
     302             : static inline void
     303          17 : vcl_test_cfg_dump (vcl_test_cfg_t * cfg, uint8_t is_client)
     304             : {
     305          17 :   char *spc = "     ";
     306             : 
     307          68 :   printf ("  test config (%p):\n"
     308             :           VCL_TEST_SEPARATOR_STRING
     309             :           "                 magic:  0x%08x\n"
     310             :           "               seq_num:  0x%08x\n"
     311             :           "%-5s             test:  %s (%d)\n"
     312             :           "           ctrl handle:  %d (0x%x)\n"
     313             :           "%-5s num test sockets:  %u (0x%08x)\n"
     314             :           "%-5s          verbose:  %s (%d)\n"
     315             :           "%-5s       rxbuf size:  %lu (0x%08lx)\n"
     316             :           "%-5s       txbuf size:  %lu (0x%08lx)\n"
     317             :           "%-5s       num writes:  %lu (0x%08lx)\n"
     318             :           "       client tx bytes:  %lu (0x%08lx)\n"
     319             :           VCL_TEST_SEPARATOR_STRING,
     320             :           (void *) cfg, cfg->magic, cfg->seq_num,
     321           9 :           is_client && (cfg->test == VCL_TEST_TYPE_UNI) ?
     322             :           "'" VCL_TEST_TOKEN_RUN_UNI "'" :
     323           3 :           is_client && (cfg->test == VCL_TEST_TYPE_BI) ?
     324          14 :           "'" VCL_TEST_TOKEN_RUN_BI "'" : spc,
     325          17 :           vcl_test_type_str (cfg->test), cfg->test,
     326             :           cfg->ctrl_handle, cfg->ctrl_handle,
     327             :           is_client ? "'" VCL_TEST_TOKEN_NUM_TEST_SESS "'" : spc,
     328             :           cfg->num_test_sessions, cfg->num_test_sessions,
     329             :           is_client ? "'" VCL_TEST_TOKEN_VERBOSE "'" : spc,
     330          17 :           cfg->verbose ? "on" : "off", cfg->verbose,
     331             :           is_client ? "'" VCL_TEST_TOKEN_RXBUF_SIZE "'" : spc,
     332             :           cfg->rxbuf_size, cfg->rxbuf_size,
     333             :           is_client ? "'" VCL_TEST_TOKEN_TXBUF_SIZE "'" : spc,
     334             :           cfg->txbuf_size, cfg->txbuf_size,
     335             :           is_client ? "'" VCL_TEST_TOKEN_NUM_WRITES "'" : spc,
     336             :           cfg->num_writes, cfg->num_writes,
     337             :           cfg->total_bytes, cfg->total_bytes);
     338          17 : }
     339             : 
     340             : static inline void
     341          17 : vcl_test_stats_dump (char *header, vcl_test_stats_t * stats,
     342             :                      uint8_t show_rx, uint8_t show_tx, uint8_t verbose)
     343             : {
     344             :   struct timespec diff;
     345             :   double duration, rate;
     346             :   uint64_t total_bytes;
     347             : 
     348          17 :   if ((stats->stop.tv_nsec - stats->start.tv_nsec) < 0)
     349             :     {
     350           1 :       diff.tv_sec = stats->stop.tv_sec - stats->start.tv_sec - 1;
     351           1 :       diff.tv_nsec = stats->stop.tv_nsec - stats->start.tv_nsec + 1e9;
     352             :     }
     353             :   else
     354             :     {
     355          16 :       diff.tv_sec = stats->stop.tv_sec - stats->start.tv_sec;
     356          16 :       diff.tv_nsec = stats->stop.tv_nsec - stats->start.tv_nsec;
     357             :     }
     358          17 :   duration = (double) diff.tv_sec + (1e-9 * diff.tv_nsec);
     359             : 
     360          17 :   total_bytes = stats->tx_bytes + stats->rx_bytes;
     361          17 :   rate = (double) total_bytes *8 / duration / 1e9;
     362          28 :   printf ("\n%s: Streamed %lu bytes\n"
     363             :           "  in %lf seconds (%lf Gbps %s-duplex)!\n",
     364             :           header, total_bytes, duration, rate,
     365          11 :           (show_rx && show_tx) ? "full" : "half");
     366             : 
     367          17 :   if (show_tx)
     368             :     {
     369          12 :       printf (VCL_TEST_SEPARATOR_STRING
     370             :               "  tx stats (0x%p):\n"
     371             :               VCL_TEST_SEPARATOR_STRING
     372             :               "         writes:  %lu (0x%08lx)\n"
     373             :               "       tx bytes:  %lu (0x%08lx)\n"
     374             :               "      tx eagain:  %u (0x%08x)\n"
     375             :               "  tx incomplete:  %u (0x%08x)\n",
     376             :               (void *) stats, stats->tx_xacts, stats->tx_xacts,
     377             :               stats->tx_bytes, stats->tx_bytes,
     378             :               stats->tx_eagain, stats->tx_eagain,
     379             :               stats->tx_incomp, stats->tx_incomp);
     380             :     }
     381          17 :   if (show_rx)
     382             :     {
     383          11 :       printf (VCL_TEST_SEPARATOR_STRING
     384             :               "  rx stats (0x%p):\n"
     385             :               VCL_TEST_SEPARATOR_STRING
     386             :               "          reads:  %lu (0x%08lx)\n"
     387             :               "       rx bytes:  %lu (0x%08lx)\n"
     388             :               "      rx eagain:  %u (0x%08x)\n"
     389             :               "  rx incomplete:  %u (0x%08x)\n",
     390             :               (void *) stats, stats->rx_xacts, stats->rx_xacts,
     391             :               stats->rx_bytes, stats->rx_bytes,
     392             :               stats->rx_eagain, stats->rx_eagain,
     393             :               stats->rx_incomp, stats->rx_incomp);
     394             :     }
     395          17 :   if (verbose)
     396           0 :     printf ("   start.tv_sec:  %ld\n"
     397             :             "  start.tv_nsec:  %ld\n"
     398             :             "    stop.tv_sec:  %ld\n"
     399             :             "   stop.tv_nsec:  %ld\n",
     400             :             stats->start.tv_sec, stats->start.tv_nsec,
     401             :             stats->stop.tv_sec, stats->stop.tv_nsec);
     402             : 
     403          17 :   printf (VCL_TEST_SEPARATOR_STRING);
     404          17 : }
     405             : 
     406             : static inline double
     407           0 : vcl_test_time_diff (struct timespec *old, struct timespec *new)
     408             : {
     409             :   uint64_t sec, nsec;
     410           0 :   if ((new->tv_nsec - old->tv_nsec) < 0)
     411             :     {
     412           0 :       sec = new->tv_sec - old->tv_sec - 1;
     413           0 :       nsec = new->tv_nsec - old->tv_nsec + 1e9;
     414             :     }
     415             :   else
     416             :     {
     417           0 :       sec = new->tv_sec - old->tv_sec;
     418           0 :       nsec = new->tv_nsec - old->tv_nsec;
     419             :     }
     420           0 :   return (double) sec + (1e-9 * nsec);
     421             : }
     422             : 
     423             : static inline void
     424           0 : vcl_test_stats_dump_inc (vcl_test_session_t *ts, int is_rx)
     425             : {
     426             :   vcl_test_stats_t *old, *new;
     427             :   double duration, rate;
     428             :   uint64_t total_bytes;
     429             :   char *dir_str;
     430             : 
     431           0 :   old = &ts->old_stats;
     432           0 :   new = &ts->stats;
     433           0 :   duration = vcl_test_time_diff (&old->stop, &new->stop);
     434             : 
     435           0 :   if (is_rx)
     436             :     {
     437           0 :       total_bytes = new->rx_bytes - old->rx_bytes;
     438           0 :       dir_str = "Received";
     439             :     }
     440             :   else
     441             :     {
     442           0 :       total_bytes = new->tx_bytes - old->tx_bytes;
     443           0 :       dir_str = "Sent";
     444             :     }
     445             : 
     446           0 :   rate = (double) total_bytes * 8 / duration / 1e9;
     447           0 :   printf ("%d: %s %lu Mbytes in %.2lf seconds %.2lf Gbps\n", ts->fd, dir_str,
     448           0 :           (uint64_t) (total_bytes / 1e6), duration, rate);
     449           0 : }
     450             : 
     451             : static inline int
     452        3590 : vcl_comp_tspec (struct timespec *a, struct timespec *b)
     453             : {
     454        3590 :   if (a->tv_sec < b->tv_sec)
     455           9 :     return -1;
     456        3581 :   else if (a->tv_sec > b->tv_sec)
     457        3570 :     return 1;
     458          11 :   else if (a->tv_nsec < b->tv_nsec)
     459           5 :     return -1;
     460           6 :   else if (a->tv_nsec > b->tv_nsec)
     461           6 :     return 1;
     462             :   else
     463           0 :     return 0;
     464             : }
     465             : 
     466             : static inline int
     467       11419 : vcl_test_read (vcl_test_session_t *ts, void *buf, uint32_t nbytes)
     468             : {
     469       11419 :   vcl_test_stats_t *stats = &ts->stats;
     470       11419 :   int rv, rx_bytes = 0;
     471             : 
     472             :   do
     473             :     {
     474       11419 :       stats->rx_xacts++;
     475       11419 :       rv = vppcom_session_read (ts->fd, buf, nbytes);
     476       11419 :       if (rv <= 0)
     477             :         {
     478           0 :           errno = -rv;
     479           0 :           if (errno == EAGAIN || errno == EWOULDBLOCK)
     480             :             {
     481           0 :               stats->rx_eagain++;
     482           0 :               continue;
     483             :             }
     484             : 
     485           0 :           vterr ("vppcom_session_read()", -errno);
     486           0 :           break;
     487             :         }
     488             : 
     489       11419 :       rx_bytes = rv;
     490       11419 :       if (rv < nbytes)
     491       11375 :         stats->rx_incomp++;
     492             :     }
     493       11419 :   while (!rx_bytes);
     494             : 
     495       11419 :   stats->rx_bytes += rx_bytes;
     496             : 
     497       11419 :   return (rx_bytes);
     498             : }
     499             : 
     500             : static inline int
     501           0 : vcl_test_read_ds (vcl_test_session_t *ts)
     502             : {
     503           0 :   vcl_test_stats_t *stats = &ts->stats;
     504             :   int rx_bytes;
     505             : 
     506             :   do
     507             :     {
     508           0 :       stats->rx_xacts++;
     509           0 :       rx_bytes = vppcom_session_read_segments (ts->fd, ts->ds, 2, ~0);
     510             : 
     511           0 :       if (rx_bytes < 0)
     512             :         {
     513           0 :           errno = -rx_bytes;
     514           0 :           rx_bytes = -1;
     515             :         }
     516           0 :           if ((rx_bytes == 0) ||
     517             :               ((rx_bytes < 0)
     518           0 :                && ((errno == EAGAIN) || (errno == EWOULDBLOCK))))
     519           0 :             stats->rx_eagain++;
     520             :     }
     521           0 :   while ((rx_bytes == 0) ||
     522           0 :          ((rx_bytes < 0) && ((errno == EAGAIN) || (errno == EWOULDBLOCK))));
     523             : 
     524           0 :   if (rx_bytes < 0)
     525             :     {
     526           0 :       vterr ("vppcom_session_read()", -errno);
     527             :     }
     528             :   else
     529           0 :     stats->rx_bytes += rx_bytes;
     530             : 
     531           0 :   return (rx_bytes);
     532             : }
     533             : 
     534             : static inline int
     535       15982 : vcl_test_write (vcl_test_session_t *ts, void *buf, uint32_t nbytes)
     536             : {
     537       15982 :   int tx_bytes = 0, nbytes_left = nbytes, rv;
     538       15982 :   vcl_test_stats_t *stats = &ts->stats;
     539             : 
     540             :   do
     541             :     {
     542       17235 :       stats->tx_xacts++;
     543       17235 :       rv = vppcom_session_write (ts->fd, buf, nbytes_left);
     544       17235 :       if (rv < 0)
     545             :         {
     546        1329 :           errno = -rv;
     547        1329 :           if ((errno == EAGAIN || errno == EWOULDBLOCK))
     548        1329 :             stats->tx_eagain++;
     549        1329 :           break;
     550             :         }
     551       15906 :       tx_bytes += rv;
     552             : 
     553       15906 :       nbytes_left = nbytes_left - rv;
     554       15906 :       buf += rv;
     555       15906 :       if (rv < nbytes_left)
     556         308 :         stats->tx_incomp++;
     557             :     }
     558       15906 :   while (tx_bytes != nbytes);
     559             : 
     560       15982 :   if (tx_bytes < 0)
     561             :     {
     562           0 :       vterr ("vpcom_session_write", -errno);
     563             :     }
     564             :   else
     565       15982 :     stats->tx_bytes += tx_bytes;
     566             : 
     567       15982 :   return (tx_bytes);
     568             : }
     569             : 
     570             : static inline void
     571           0 : dump_help (void)
     572             : {
     573             : #define INDENT "\n  "
     574             : 
     575           0 :   printf ("CLIENT: Test configuration commands:"
     576             :           INDENT VCL_TEST_TOKEN_HELP
     577             :           "\t\t\tDisplay help."
     578             :           INDENT VCL_TEST_TOKEN_EXIT
     579             :           "\t\t\tExit test client & server."
     580             :           INDENT VCL_TEST_TOKEN_SHOW_CFG
     581             :           "\t\t\tShow the current test cfg."
     582             :           INDENT VCL_TEST_TOKEN_RUN_UNI
     583             :           "\t\t\tRun the Uni-directional test."
     584             :           INDENT VCL_TEST_TOKEN_RUN_BI
     585             :           "\t\t\tRun the Bi-directional test."
     586             :           INDENT VCL_TEST_TOKEN_VERBOSE
     587             :           "\t\t\tToggle verbose setting."
     588             :           INDENT VCL_TEST_TOKEN_RXBUF_SIZE
     589             :           "<rxbuf size>\tRx buffer size (bytes)."
     590             :           INDENT VCL_TEST_TOKEN_TXBUF_SIZE
     591             :           "<txbuf size>\tTx buffer size (bytes)."
     592             :           INDENT VCL_TEST_TOKEN_NUM_WRITES
     593             :           "<# of writes>\tNumber of txbuf writes to server." "\n");
     594           0 : }
     595             : 
     596             : #endif /* __vcl_test_h__ */
     597             : 
     598             : /*
     599             :  * fd.io coding-style-patch-verification: ON
     600             :  *
     601             :  * Local Variables:
     602             :  * eval: (c-set-style "gnu")
     603             :  * End:
     604             :  */

Generated by: LCOV version 1.14