From: E. Scott Daniels Date: Wed, 2 Sep 2020 20:02:30 +0000 (-0400) Subject: Tweak unit tests to save coverage in common dir X-Git-Tag: 1.7.0~3 X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=commitdiff_plain;h=974431c8dfa40769b6fb46a1b62cd8b5bc91f6ff;p=ric-app%2Fmc.git Tweak unit tests to save coverage in common dir The CI changes now define a common directory for coverage files. This change causes the listener unit tests to move the gcov files to this directory. Some minor sonar prompted cleanup to listener code also done. Issue-ID: RIC-632 Signed-off-by: E. Scott Daniels Change-Id: I6e53b3dea9244038275c76c5f6fdbc2ff3f0f164 --- diff --git a/sidecars/listener/src/mc_listener.c b/sidecars/listener/src/mc_listener.c index 1eefab4..f1b6507 100644 --- a/sidecars/listener/src/mc_listener.c +++ b/sidecars/listener/src/mc_listener.c @@ -53,31 +53,35 @@ #include "mcl.h" //---- support ----------------------------------------------------------------------------- +char* usage_str = + "[-d fifo-dir] [-e] [-p listen-port] [-q | -r report-freq]\n" + " -e disable extended header in buffers written to FIFOs\n" + "\n" + "The following environment variables may be set to affect operation:\n" + " MCL_RDC_STAGE: the directory where raw data capture files are staged. (/tmp/rdc/stage)\n" + " MCL_RDC_FINAL: the directory where raw data capture files are placed for export. (/tmp/rdc/final)\n" + " MCL_RDC_SUFFIX: the suffix written on each raw data capture file; must include '.'. (.rdc)\n" + " MCL_RDC_SOURCE: a short string used as source identification in rdc file names.\n" + " MCL_RDC_FREQ: the amount of time (seconds) that raw capture files are rolled. (300)\n" + "\nIf either final or staging directories are defined by environment vars, they MUST exist.\n"; -static void bad_arg( char* what ) { +/* + Bad argument error. +*/ +static void ba_err( char* what ) { fprintf( stderr, "[ERR] option is unrecognised or isn't followed by meaningful data: %s\n", what ); } static void usage( char* argv0 ) { - fprintf( stderr, "usage: %s [-d fifo-dir] [-e] [-p listen-port] [-q | -r report-freq]\n", argv0 ); - fprintf( stderr, " -e disable extended header in buffers written to FIFOs\n" ); - fprintf( stderr, "\n" ); - fprintf( stderr, "The following environment variables may be set to affect operation:\n" ); - fprintf( stderr, " MCL_RDC_STAGE: the directory where raw data capture files are staged. (/tmp/rdc/stage)\n" ); - fprintf( stderr, " MCL_RDC_FINAL: the directory where raw data capture files are placed for export. (/tmp/rdc/final)\n" ); - fprintf( stderr, " MCL_RDC_SUFFIX: the suffix written on each raw data capture file; must include '.'. (.rdc)\n" ); - fprintf( stderr, " MCL_RDC_SOURCE: a short string used as source identification in rdc file names.\n" ); - fprintf( stderr, " MCL_RDC_FREQ: the amount of time (seconds) that raw capture files are rolled. (300)\n" ); - fprintf( stderr, "\nIf either final or staging directories are defined by environment vars, they MUST exist.\n" ); - fprintf( stderr, "\n" ); + fprintf( stderr, "usage: %s %s\n", argv0, usage_str ); } /* - We exit on any trapped signal so that we can kill -15 the proecss - and still get gcoverage information to keep sonar happy. + Exit on trapped signal allowing ctl-C or SIGTERM to stop us gracefully and capture + the gcda data for coverage. */ -static void sigh( int sig ) { - fprintf( stderr, "\n[INFO] exiting on signal %d\n", sig ); +static void sigh( int sign ) { + fprintf( stderr, "\n[INFO] exiting on signal %d\n", sign ); exit( 0 ); } @@ -85,9 +89,7 @@ static void sigh( int sig ) { int main( int argc, char** argv ) { void* ctx; // the mc listener library context char* dname = NULL; // default directory where we open fifos - char* port = "4560"; // default rmr port - char* siphon_dir = "/tmp/mci/siphon"; // where siphon files are placed - int siphon = 0; // percentage of messages to siphone off + char* port = NULL; int report_freq = 60; // report stats every n seconds int pidx = 1; // parameter index int error = 0; @@ -97,15 +99,17 @@ int main( int argc, char** argv ) { signal( SIGTERM, sigh ); dname = strdup( "/tmp/mcl/fifos" ); // so we can always free + port = strdup( "4560" ); // default port while( pidx < argc && argv[pidx][0] == '-' ) { // simple argument parsing (-x or -x value) switch( argv[pidx][1] ) { case 'd': if( pidx+1 < argc ) { + free( dname ); dname = strdup( argv[pidx+1] ); pidx++; } else { - bad_arg( argv[pidx] ); + ba_err( argv[pidx] ); error = 1; } break; @@ -116,10 +120,11 @@ int main( int argc, char** argv ) { case 'p': if( pidx+1 < argc ) { + free( port ); port = strdup( argv[pidx+1] ); pidx++; } else { - bad_arg( argv[pidx] ); + ba_err( argv[pidx] ); error = 1; } break; @@ -133,7 +138,7 @@ int main( int argc, char** argv ) { report_freq = atoi( argv[pidx+1] ); pidx++; } else { - bad_arg( argv[pidx] ); + ba_err( argv[pidx] ); error = 1; } break; @@ -144,7 +149,7 @@ int main( int argc, char** argv ) { exit( 0 ); default: - bad_arg( argv[pidx] ); + ba_err( argv[pidx] ); error = 1; break; } diff --git a/sidecars/listener/src/mcl.c b/sidecars/listener/src/mcl.c index a50924b..0077e96 100644 --- a/sidecars/listener/src/mcl.c +++ b/sidecars/listener/src/mcl.c @@ -321,6 +321,16 @@ static void wr_stats( void* st, void* entry, char const* name, void* thing, void fifo->wcount_rp = 0; // reset the report counts fifo->drops_rp = 0; + return; // return here to avoid sonar required hack below + } + + /* + Sonar doesn't grok the fact that for callback functions some parms are naturally + ignored. So, to eliminate the 5 code smells because we only care about thing, we + have this hack.... + */ + if( st == NULL && entry == NULL && name == NULL && data == NULL ) { + fprintf( stderr, "mdcl: all parms to callback stats were nil\n" ); } } @@ -421,10 +431,10 @@ extern void* mcl_mk_context( const char* dir ) { delimeter. We assume best case most likely and handle it as such. */ static void read_header( int fd, char* buf ) { - int len; - int need = MCL_EXHDR_SIZE; // total needed - int dneed; // delimieter needed - char* rp; // read position in buf + size_t len; + size_t need = MCL_EXHDR_SIZE; // total needed + size_t dneed; // delimieter needed + char* rp; // read position in buf len = read( fd, buf, need ); if( len == need && strncmp( buf, MCL_DELIM, strlen( MCL_DELIM )) == 0 ) { // best case, most likely diff --git a/sidecars/listener/src/mcl.h b/sidecars/listener/src/mcl.h index 5d5af4a..ebe66eb 100644 --- a/sidecars/listener/src/mcl.h +++ b/sidecars/listener/src/mcl.h @@ -65,11 +65,11 @@ extern int mcl_start_listening( void* vctx, char* port, int wait4ready ); // ---- these can be used by external programmes, but it liekely doesn't make sense to do so ---- extern void logit( int level, char* fmt, ... ); -extern void* rdc_init( char* sdir, char* fdir, char* suffix, char* dsuffix ); -extern void* rdc_init_buf( int mtype, char* uheader, int uhlen, void* capture_buf ); +extern void* rdc_init( const char* sdir, const char* fdir, const char* suffix, const char* dsuffix ); +extern void* rdc_init_buf( int mtype, const char* uheader, int uhlen, void* capture_buf ); extern void rdc_close( void* rdl_ctx ); extern void rdc_set_freq( void* rdl_ctx, int freq ); -extern int rdc_write( void* rdl_ctx, void* rdc_buffer, char* payload, int len ); +extern int rdc_write( void* rdl_ctx, void* rdc_buffer, const char* payload, int len ); #endif diff --git a/sidecars/listener/src/rdc.c b/sidecars/listener/src/rdc.c index 049508c..6b0c50f 100644 --- a/sidecars/listener/src/rdc.c +++ b/sidecars/listener/src/rdc.c @@ -30,7 +30,7 @@ Where is the message type of the message received and is the length of the data that was written to the FIFO. - + Date: 06 Oct 2019 Author: E. Scott Daniels */ @@ -94,7 +94,7 @@ static int copy_unlink( char* old, char* new, int mode ) { char* tfname = NULL; // temp file name while we have it open char* wbuf; // work buffer for disecting the new filename char* tok; // token pointer into a buffer - int len; + size_t len; int rfd; // read/write file descriptors int wfd; int start; @@ -108,7 +108,7 @@ static int copy_unlink( char* old, char* new, int mode ) { return -1; } - len = sizeof( char ) * (strlen( new ) + 2 ); // space needed for temp file name with added . + len = (int) sizeof( char ) * (strlen( new ) + 2 ); // space needed for temp file name with added . tfname = (char *) malloc( len ); wbuf = strdup( new ); // we need to trash the string, so copy tok = strrchr( wbuf, '/' ); // find end of path @@ -120,7 +120,6 @@ static int copy_unlink( char* old, char* new, int mode ) { snprintf( tfname, len, ".%s", wbuf ); // no path, just add leading . } free( wbuf ); - //logit( LOG_INFO, "copy: creating file in tmp filename: %s", tfname ); if( (wfd = open( tfname, O_WRONLY | O_CREAT | O_TRUNC, 0200 )) < 0 ) { logit( LOG_ERR, "copy: open tmp file for copy failed: %s: %s", tfname, strerror( errno ) ); @@ -132,14 +131,15 @@ static int copy_unlink( char* old, char* new, int mode ) { start = 0; while( remain > 0 ) { errno = 0; - if( (len = write( wfd, &buf[start], len )) != remain ) { // short write - if( errno != EINTR && errno != EAGAIN ) { - logit( LOG_ERR, "copy: write failed: %s", strerror( errno ) ); - free( tfname ); - close( wfd ); - close( rfd ); - return -1; - } + if( (len = write( wfd, &buf[start], len )) != remain // short write + && errno != EINTR // and not interrrupted or try later + && errno != EAGAIN ) { + + logit( LOG_ERR, "copy: write failed: %s", strerror( errno ) ); + free( tfname ); + close( wfd ); + close( rfd ); + return -1; } remain -= len; // recompute what we need to write, and try again @@ -156,7 +156,6 @@ static int copy_unlink( char* old, char* new, int mode ) { if( mode != 0 ) { chmod( tfname, mode ); } - //logit( LOG_INFO, "copy: moving tmp file to: %s", new ); if( (state = rename( tfname, new )) < 0 ) { logit( LOG_WARN, "copy: rename of tmp to final name failed for %s -> %s: %s", tfname, new, strerror( errno ) ); } else { @@ -215,8 +214,8 @@ static int rdc_open( void* vctx ) { ts = ts - (ts % ctx->frequency); // round to previous frequency ctx->next_roll = ts + ctx->frequency; // set next time to roll the file - snprintf( basename, sizeof( fname ), "MCLT%s_%ld", ctx->source, (long) ts ); // basename needed to build final file name at close - snprintf( fname, sizeof( fname ), "%s/MCLT_%ld", ctx->sdir, (long) ts ); + snprintf( basename, sizeof( fname ), "MCLT%s_%ld", ctx->source, ts ); // basename needed to build final file name at close + snprintf( fname, sizeof( fname ), "%s/MCLT_%ld", ctx->sdir, ts ); fd = open( fname, O_WRONLY | O_CREAT, 0200 ); // open in w-- mode so that it should not be readable if( fd < 0 ) { logit( LOG_CRIT, "(rdf) cannot open data capture file: %s: %s", fname, strerror( errno ) ); @@ -290,9 +289,9 @@ extern void logit( int priority, char *fmt, ... ) { A pointer to the context is returned; nil on error with errno set to some useful (we hope) value. */ -extern void* rdc_init( char* sdir, char* fdir, char* suffix, char* dsuffix ) { +extern void* rdc_init( const char* sdir, const char* fdir, const char* suffix, const char* dsuffix ) { rdc_ctx_t* ctx; - char* ep; // pointer at environment var value + const char* ep; // pointer at environment var value ctx = (rdc_ctx_t *) malloc( sizeof( *ctx ) ); if( ctx == NULL ) { @@ -405,8 +404,8 @@ extern void rdc_close( void* vctx ) { If it's time to roll the file, or the file isn't opened, the needed housekeeping is done first. */ -extern int rdc_write( void* vctx, void* vcb, char* payload, int len ) { - cap_buf_t* cb; +extern int rdc_write( void* vctx, void* vcb, const char* payload, int len ) { + const cap_buf_t* cb; char header[100]; // our header rdc_ctx_t* ctx; @@ -438,7 +437,7 @@ extern int rdc_write( void* vctx, void* vcb, char* payload, int len ) { We save the message type, and will use that and the user header length and payload length on write to create the complete RDC header. */ -extern void* rdc_init_buf( int mtype, char* uheader, int uhlen, void* vcb ) { +extern void* rdc_init_buf( int mtype, const char* uheader, int uhlen, void* vcb ) { cap_buf_t* cb; cb = (cap_buf_t *) vcb; diff --git a/sidecars/listener/test/run_app_tests.ksh b/sidecars/listener/test/run_app_tests.ksh index 6866041..27b6812 100755 --- a/sidecars/listener/test/run_app_tests.ksh +++ b/sidecars/listener/test/run_app_tests.ksh @@ -102,6 +102,15 @@ export LIBRARY_PATH=/usr/local/lib:$LIBRARY_PATH force_rmr_load=0 no_rmr_load=0 +# defined in the CI configuration where jenkins jobs are looking for gcov files +gcov_dir=/tmp/gcov_rpts +if [[ ! -d $cov_dir ]] +then + echo " making $gcov_dir" + mkdir $gcov_dir +fi + + while [[ $1 == -* ]] do case $1 in @@ -130,8 +139,10 @@ make -B # ensure coverage data is nuked mc_listener -p 4567 -q -r 10 -e -d foo -x >/dev/null 2>&1 # -x (invalid) prevents execution loop for x in d p r \? h # drive with missing values for d, p, r and singletons -h and -? do + gcov mc_listener.c # debugging because jenkins gcov doesn't seem to be accumulating data mc_listener -$x >/dev/null 2>&1 done +gcov mc_listener.c # debugging because jenkins gcov doesn't seem to be accumulating data pipe_reader -d foo -e -f -m 0 -s -x >/dev/null 2>&1 # drive for all "good" conditions for x in d m \? h @@ -154,7 +165,7 @@ $script_dir/verify_replay.sh for x in mc_listener sender rdc_replay pipe_reader do gcov $x.c - cp $x.c.gcov ../ # copy only interesting things (not the lib modules if they exist) + cp $x.c.gcov $gcov_dir/ done exit diff --git a/sidecars/listener/test/run_unit_test.ksh b/sidecars/listener/test/run_unit_test.ksh index 93fe2fb..44e1c90 100755 --- a/sidecars/listener/test/run_unit_test.ksh +++ b/sidecars/listener/test/run_unit_test.ksh @@ -131,6 +131,14 @@ function ensure_pkgs { export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH export LIBRARY_PATH=/usr/local/lib:$LIBRARY_PATH +# defined in the CI configuration where jenkins jobs are looking for gcov files +gcov_dir=/tmp/gcov_rpts +if [[ ! -d $cov_dir ]] +then + echo "[INFO] making $gcov_dir" + mkdir $gcov_dir +fi + running=/tmp/PID$$.running force_rmr_load=0 ci_mode=1 # -c turns off; see the flower box above @@ -158,6 +166,10 @@ fi ensure_pkgs # ensure that we have RMR; some CI environments are lacking +echo "[INFO] ----------------------------------------------" +gcov --version # gcov files don't seem to aggregate on the LF guest +echo "[INFO] ----------------------------------------------" + if (( ci_mode )) # in CI mode we must force a build in the src so build wrapper captures trigger data then echo "building in src for sonar build wrapper capture" @@ -187,10 +199,9 @@ fi pid=$! abort_after 60 $pid & wait $pid -#if ! unit_test >/tmp/PID$$.utlog 2>&1 if (( $? != 0 )) then - echo ">>>> wait popped" + echo " run_unit_test: wait popped" rm -f $running cat /tmp/PID$$.utlog rm -f /tmp/PID$$.* @@ -243,7 +254,7 @@ else rm -f *test*.gcov fi -cp *.gcov ../ # jjb description points to top listener dir for sonar to find gcov files +cp *.gcov $gcov_dir/ # make avilable to jenkins job(s) rm -f /tmp/PID$$.* exit $rc