59 #include "rnr/rnrconfig.h" 86 #define APP_EC_USAGE 2
89 #define LT_MAX_CLIENTS 256 90 #define LT_MAX_VCONN 4
91 #define LT_N_CLIENT_DFT 1
93 #define LT_DEVICES_DFT "server,null" 95 #define LT_DEV_SERVER 0x0001 96 #define LT_DEV_I2C 0x0002
97 #define LT_DEV_NULL 0x0004
98 #define LT_DEV_SERIAL 0x0008
100 #define LT_T_MIN 1000 101 #define LT_T_MAX 2000000
118 char *optarg,
void *pOptVal);
120 char *optarg,
void *pOptVal);
122 char *optarg,
void *pOptVal);
130 "BotSense bsProxy server load tester client.",
133 "The %P application creates a multi-client, multi-thread application to " 134 "load test both the bsProxy server and the libbotsense client library." 146 .has_arg = required_argument,
150 .fn_fmt = OptsFmtStr,
151 .arg_name =
"<addr[:port]>",
152 .opt_desc =
"Proxy Server's network address. The format of the address " 153 "can be either a network hostname or a dotted IP address " 154 "number. If port is not specfied, then the default port " 162 .has_arg = required_argument,
166 .fn_fmt = OptsFmtInt,
167 .arg_name =
"<count>",
168 .opt_desc =
"Number of client's to create and run." 173 .long_opt =
"devices",
174 .short_opt = OPTS_NO_SHORT,
175 .has_arg = required_argument,
179 .fn_fmt = OptsFmtStr,
180 .arg_name =
"<list>",
181 .opt_desc =
"List of proxied devices where each client will create " 182 "a thread and load test. Format:\n" 183 " list: dev[,dev...]\n" 184 " dev: server i2c null serial" 190 .long_opt =
"fixeddiag",
191 .short_opt = OPTS_NO_SHORT,
192 .has_arg = no_argument,
195 .fn_cvt = OptsCvtArgBool,
196 .fn_fmt = OptsFmtBool,
198 .opt_desc =
"Fix message tracing and logging diagnostics to the values " 199 "set when %P was invoked." 204 .long_opt =
"serdev",
205 .short_opt = OPTS_NO_SHORT,
206 .has_arg = required_argument,
209 .fn_cvt = OptsCvtArgStr,
210 .fn_fmt = OptsFmtStr,
212 .opt_desc =
"Proxied serial device. The interface module is fixed at " 218 .long_opt =
"i2cdev",
219 .short_opt = OPTS_NO_SHORT,
220 .has_arg = required_argument,
223 .fn_cvt = OptsCvtArgStr,
224 .fn_fmt = OptsFmtStr,
226 .opt_desc =
"Proxied I2C device. The interface module is fixed at " 275 return (uint_t)(n * r);
286 usleep( tmin +
RandN(tmax-tmin) );
323 static uint_t actions[] =
325 ActionOpenClose, ActionScan
328 static uint_t uNumActions = (uint_t)arraysize(actions);
331 const char *sClientName = bsClientAttrGetName(pClient);
332 uint_t uCloseFreq = 50;
335 i2c_addr_t addrs[256];
340 hndVConn = bsI2CReqOpen(pClient,
OptsDevI2C,
false);
348 printf(
"<%s>: i2copen: %s\n", sClientName,
OptsDevI2C);
352 printf(
"<%s>: i2c load test thread started.\n", sClientName);
360 switch( actions[
RandN(uNumActions)] )
362 case ActionOpenClose:
365 if(
RandN(uCloseFreq) == 0 )
367 rc = bsI2CReqClose(pClient, hndVConn);
370 printf(
"<%s>: i2cclose: %s\n", sClientName,
OptsDevI2C);
375 printf(
"<%s>: i2cclose: failed: rc=%d\n", sClientName, rc);
382 hndVConn = bsI2CReqOpen(pClient,
OptsDevI2C,
false);
386 printf(
"<%s>: i2copen: %s\n", sClientName,
OptsDevI2C);
391 printf(
"<%s>: i2copen: failed: rc=%d\n", sClientName, hndVConn);
398 rc = bsI2CReqScan(pClient, hndVConn, addrs, arraysize(addrs));
401 printf(
"<%s>: i2cscan: %d addresses:", sClientName, rc);
404 printf(
" 0x%02x", addrs[i]);
410 printf(
"<%s>: i2cscan: failed: rc=%d\n", sClientName, rc);
419 printf(
"<%s>: i2c load test thread terminated.\n", sClientName);
433 if( pthread_create(&thread, NULL,
LtThreadI2C, (
void *)pClient) )
436 "pthread_create(\"/dev/null\")");
456 static uint_t actions[] =
458 ActionOpenClose, ActionWrite
461 static uint_t uNumActions = (uint_t)arraysize(actions);
463 static char *wrPhrase[] =
465 "It just so happens that your friend here is only MOSTLY dead.",
466 "Rest well and dream of large women.",
467 "Hello. My name is Inigo Montoya. You killed my father. Prepare to die." 469 static uint_t uNumWrPhrases = (uint_t)arraysize(wrPhrase);
472 const char *sClientName = bsClientAttrGetName(pClient);
473 uint_t uCloseFreq = 50;
481 hndVConn = bsNullReqOpen(pClient,
false);
493 printf(
"<%s>: devnull load test thread started.\n", sClientName);
501 switch( actions[
RandN(uNumActions)] )
503 case ActionOpenClose:
506 if(
RandN(uCloseFreq) == 0 )
508 rc = bsNullReqClose(pClient, hndVConn);
516 printf(
"<%s>: nullclose: failed: rc=%d\n", sClientName, rc);
523 hndVConn = bsNullReqOpen(pClient,
false);
532 printf(
"<%s>: nullopen: failed: rc=%d\n", sClientName, hndVConn);
539 i =
RandN(uNumWrPhrases);
540 memcpy(buf, wrPhrase[i], strlen(wrPhrase[i]));
541 rc = bsNullReqWrite(pClient, hndVConn, buf, strlen(wrPhrase[i]));
544 printf(
"<%s>: nullwrite: %d bytes: \"%*s\"\n",
545 sClientName, rc, rc, wrPhrase[i]);
549 printf(
"<%s>: nullwrite: failed: rc=%d\n", sClientName, rc);
558 printf(
"<%s>: devnull load test thread terminated.\n", sClientName);
572 if( pthread_create(&thread, NULL,
LtThreadNull, (
void *)pClient) )
575 "pthread_create(\"/dev/null\")");
597 static uint_t actions[] =
599 ActionOpenClose, ActionWrite
602 static uint_t uNumActions = (uint_t)arraysize(actions);
604 static char *wrPhrase[] =
608 "This is the end / Beautiful friend / This is the end / " 609 "My only friend, the end" 611 static uint_t uNumWrPhrases = (uint_t)arraysize(wrPhrase);
614 const char *sClientName = bsClientAttrGetName(pClient);
615 uint_t uCloseFreq = 50;
624 115200, 8,
'N', 1,
false,
false,
false);
632 printf(
"<%s>: serialopen: %s\n", sClientName,
OptsDevSerial);
636 printf(
"<%s>: serial load test thread started.\n", sClientName);
644 switch( actions[
RandN(uNumActions)] )
646 case ActionOpenClose:
649 if(
RandN(uCloseFreq) == 0 )
651 rc = bsSerialReqClose(pClient, hndVConn);
654 printf(
"<%s>: serialclose: %s\n", sClientName,
OptsDevSerial);
659 printf(
"<%s>: serialclose: failed: rc=%d\n", sClientName, rc);
667 115200, 8,
'N', 1,
false,
false,
false);
671 printf(
"<%s>: serialopen: %s\n", sClientName,
OptsDevSerial);
676 printf(
"<%s>: serialopen: failed: rc=%d\n", sClientName, hndVConn);
683 i =
RandN(uNumWrPhrases);
684 memcpy(buf, wrPhrase[i], strlen(wrPhrase[i]));
685 rc = bsSerialReqWrite(pClient, hndVConn, buf, strlen(wrPhrase[i]));
688 printf(
"<%s>: serialwrite: %d bytes: \"%*s\"\n",
689 sClientName, rc, rc, wrPhrase[i]);
693 printf(
"<%s>: serialwrite: failed: rc=%d\n", sClientName, rc);
704 printf(
"<%s>: serial load test thread terminated.\n", sClientName);
718 if( pthread_create(&thread, NULL,
LtThreadSerial, (
void *)pClient) )
721 "pthread_create(\"serial\")");
745 static uint_t actions[] =
747 ActionLoopback, ActionSetLogging, ActionGetVersion,
748 ActionMsgTrace, ActionGetVConnList, ActionGetVConnInfo
751 static uint_t uNumActions = (uint_t)arraysize(actions);
754 const char *sClientName = bsClientAttrGetName(pClient);
762 printf(
"<%s>: server load test thread started.\n", sClientName);
772 switch( actions[
RandN(uNumActions)] )
775 sprintf(buf,
"%s wants loopback.", sClientName);
776 rc = bsServerReqLoopback(pClient, buf);
779 printf(
"<%s>: loopback: \"%s\"\n", sClientName, buf);
783 printf(
"<%s>: loopback: failed: rc=%d\n", sClientName, rc);
786 case ActionSetLogging:
790 rc = bsServerReqSetLogging(pClient, (
int)i);
793 printf(
"<%s>: setlogging: %d\n", sClientName, (
int)i);
797 printf(
"<%s>: setlogging: failed: rc=%d\n", sClientName, rc);
801 case ActionGetVersion:
802 rc = bsServerReqGetVersion(pClient, buf,
sizeof(buf));
805 printf(
"<%s>: getversion: \"%s\"\n", sClientName, buf);
809 printf(
"<%s>: getversion: failed: rc=%d\n", sClientName, rc);
827 rc = bsServerReqMsgTrace(pClient, hndVConn, (bool_t)j);
830 printf(
"<%s>: msgtrace: vconn=%d, trace=%d\n",
831 sClientName, hndVConn, (
int)j);
836 printf(
"<%s>: msgtrace: failed: rc=%d\n", sClientName, rc);
841 case ActionGetVConnList:
842 rc = bsServerReqGetVConnList(pClient, &vconnlist);
845 printf(
"<%s>: getvconnlist: (%zu)", sClientName, vconnlist.
m_uCount);
848 printf(
" %d", vconnlist.
m_vecHnd[i]);
855 printf(
"<%s>: getvconnlist: failed: rc=%d\n", sClientName, rc);
858 case ActionGetVConnInfo:
862 rc = bsServerReqGetVConnInfo(pClient, hndVConn, &vconninfo);
865 printf(
"<%s>: getvconninfo:\n", sClientName);
866 printf(
" vconn = %d\n", vconninfo.
m_vconn);
867 printf(
" rd = %d\n", vconninfo.
m_rd);
868 printf(
" client = %s\n", vconninfo.
m_client);
869 printf(
" devuri = %s\n", vconninfo.
m_devuri);
870 printf(
" moduri = %s\n", vconninfo.
m_moduri);
871 printf(
" modver = %s\n", vconninfo.
m_modver);
872 printf(
" moddate = %s\n", vconninfo.
m_moddate);
877 printf(
"<%s>: getvconninfo: failed: rc=%d\n", sClientName, rc);
886 printf(
"<%s>: server load test thread terminated.\n", sClientName);
900 if( pthread_create(&thread, NULL,
LtThreadServer, (
void *)pClient) )
903 "pthread_create(\"server\")");
921 sprintf_s(buf,
sizeof(buf),
"TestClient%d", i);
923 pClient = bsClientNew(buf);
934 LOGDIAG1(
"Created client %s.", bsClientAttrGetName(pClient));
958 bsClientDelete(pClient);
987 char *optarg,
void *pOptVal)
1002 sPort = sSepField+1;
1006 OptsInvalid(
Argv0,
"'%s': Invalid '%s' argument port value.",
1017 OptsInvalid(
Argv0,
"'%s': Invalid '%s' argument address value.",
1037 char *optarg,
void *pOptVal)
1043 OptsInvalid(
Argv0,
"'%s': Client '%s' argument out-of-range.",
1065 char *optarg,
void *pOptVal)
1072 sList = new_strdup(optarg);
1074 for(sDev=strtok(sList,
",");
1076 sDev=strtok(NULL,
","))
1078 if( !strcmp(sDev,
"server") )
1082 else if( !strcmp(sDev,
"i2c") )
1086 else if( !strcmp(sDev,
"null") )
1090 else if( !strcmp(sDev,
"serial") )
1096 OptsInvalid(
Argv0,
"'%s': Option '%s': Unknown device '%s'.",
1097 optarg, sOptName, sDev);
1120 Argv0 = basename(argv[0]);
1171 bsServerDisconnect(Client[i]);
1172 bsClientDelete(Client[i]);
static uint_t RandN(uint_t n)
Generate random integer between [0,n).
#define BS_NULL_DEV_NAME
DevNull device.
#define LT_MAX_CLIENTS
maximum number of load testing clients
#define BSPROXY_LISTEN_PORT_DFT
default bsProxy passive socket
BotSense client application - bsProxy server-terminated core messages.
#define LT_N_CLIENT_DFT
default option load testing client count
static int OptsCvtArgDevices(const char *argv0, const char *sOptName, char *optarg, void *pOptVal)
Convert command-line devices option string to bitmap.
ulong_t seed
the initial seed
static char * OptsProxyServer
proxy server addr/port
static char * OptsDevSerial
serial device
#define LT_DEV_I2C
load test proxied I2C device requests
static BsClient_P Client[256]
array of clients
byte_t m_vconn
virtual connection handle
static BsVConnHnd_T RandVConn(BsVecHandles_T *pVConnList)
Randomly pick a virtual connection in list.
#define BSPROXY_VCONN_SERVER
handle for server-terminated msgs
static int MainInit(int argc, char *argv[])
Initialize application.
<b><i>BotSense</i></b> bsProxy client library I2C bus interface.
static char * OptsDevices
number of clients
#define BSCLIENT_LOG_SYSERROR(pClient, ecode, efmt,...)
Log System Error.
static BsClient_P CreateTestClient(int i)
Get and pretty print all the versions from all proxied entities.
static int OptsCvtArgServerAddr(const char *argv0, const char *sOptName, char *optarg, void *pOptVal)
Convert command-line server option IP address string to network name/number and port number...
#define BSCLIENT_LOG_ERROR(pClient, ecode, efmt,...)
Log Error.
The Client Structure Type.
<b><i>BotSense</i></b> bsProxy client library /dev/null interface.
static OptsInfo_T OptsInfo[]
Command-line options information.
#define BS_OK
not an error, success
BsVConnHnd_T m_vecHnd[BSPROXY_VCONN_CLIENT_MAX]
vector of handles
static void * LtThreadI2C(void *pArg)
Load test proxied I2C device thread.
static void ClientStartTestThreadI2C(BsClient_P pClient)
Start proxied I2C device load test thread.
static void ClientStartTestThreadNull(BsClient_P pClient)
Start proxied /dev/null device load test thread.
static char * Argv0
this command basename
static int ProxyIPPort
default bsProxy port
#define BSPROXY_VCONN_UNDEF
undefined virtual connection handle
static int OptsCvtArgClientCnt(const char *argv0, const char *sOptName, char *optarg, void *pOptVal)
Convert command-line client count option.
#define BS_ECODE_NO_EXEC
cannot execute
<b><i>BotSense</i></b> bsProxy client library RS-232 serial interface.
static void * LtThreadNull(void *pArg)
Load test proxied /dev/null device thread.
char m_moddate[256]
i/f module date
BotSense bsProxy server - client raw I2C NetMsgs XML Definition.
char m_modver[256]
i/f module version
<b><i>BotSense</i></b> client library declarations.
#define LT_MAX_VCONN
maximum number of virtual conn. / client
static union @20 RandomSeq
Random seed.
static void ClientStartTestThreadSerial(BsClient_P pClient)
Start proxied serial device load test thread.
static const PkgInfo_T PkgInfo
BotSense bsProxy server - client raw serial NetMsgs XML Definition.
char m_client[256]
client name
#define LT_DEV_SERIAL
load test proxied serial device requests
size_t m_uCount
vector length
static void ClientStartTestThreadServer(BsClient_P pClient)
Start server-terminated requests load test thread.
static char * ProxyIPAddr
default bsProxy IP addr
char m_moduri[256]
i/f module URI
Package version information.
int main(int argc, char *argv[])
Application main.
static void * LtThreadServer(void *pArg)
Load test server-terminated messages thread.
struct _bsClientStruct * BsClient_P
Pointer to client structure forward declaration.
static void RandSeed()
Seed random number generator.
static void RandSleep(uint_t tmin, uint_t tmax)
Sleep for a random μs duration between [tmin, tmax].
#define LT_DEV_NULL
load test proxied /dev/null requests
static uint_t ProxiedDevices
proxied devices
static char * OptsDevI2C
i2c device
#define LT_DEV_SERVER
load test server-terminated requests
static bool_t OptsFixedDiag
fixed diagnostics
static OptsPgmInfo_T PgmInfo
Program information.
int m_rd
resource descriptor
#define LT_T_MIN
minimum thread sleep time
static int OptsClientCnt
number of clients
#define LT_DEVICES_DFT
default option list of proxied devices
ushort_t xsubi[3]
successive x_i'th 48-bit value
#define LT_T_MAX
minimum thread sleep time
<b><i>BotSense</i></b> package top-level, unifying header declarations.
static void * LtThreadSerial(void *pArg)
Load test proxied serial device thread.
BotSense bsProxy server - client /dev/null NetMsgs XML Definition.
#define APP_EC_OK
success exit code
int BsVConnHnd_T
virtual connection handle type
char m_devuri[256]
device URI