X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=sidecars%2Flistener%2Funit_test.c;h=a946c8cbca19ceb03c30b801d9c26fdc4e26565e;hb=refs%2Fchanges%2F60%2F4560%2F1;hp=79bc43fd409c3990f1ce2db5bb8f3903d4171758;hpb=fe2bd3618e4748333078f91c26a8a3f5dcf184c4;p=ric-app%2Fmc.git diff --git a/sidecars/listener/unit_test.c b/sidecars/listener/unit_test.c index 79bc43f..a946c8c 100644 --- a/sidecars/listener/unit_test.c +++ b/sidecars/listener/unit_test.c @@ -24,39 +24,94 @@ Author: E. Scott Daniels */ -// this/these are what we are testing; include them directly +#define FOREVER 0 // allows forever loops in mcl code to escape after one loop + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define TEST_MTYPE 1000 // message type for testing +#include "test_rmr_em.c" // emulated rmr functions (for receives) + +// this/these are what we are testing; include them directly (must be after forever def) #include "mcl.c" +#include "rdc.c" + +/* + Set up env things for the rdc setup call. +*/ +static void set_env() { + setenv( "MCL_RDC_ENABLE", "1", 1 ); // cause 'raw' capture to be setup + setenv( "MCL_RDC_STAGE", "/tmp/mc_listener_test/stage", 1 ); // unit test script should create and will purge after + setenv( "MCL_RDC_FINAL", "/tmp/mc_listener_test/final", 1 ); + setenv( "MCL_RDC_SUFFIX", ".xxx", 1 ); + setenv( "MCL_RDC_DONE", ".done", 1 ); + setenv( "MCL_RDC_FREQ", "10", 1 ); +} /* Parms: [fifo-dir-name] */ int main( int argc, char** argv ) { void* ctx; - int errors; + void* bad_ctx; // context with a bad directory path for coverage/error testing + int errors = 0; char* dname = "/tmp/fifos"; char* port = "4560"; int fd; int fd2; + int rfd; // a reader file des so we can read what we write + fifo_t* fref = NULL; // fifo type reference; we just verify that suss sets it + char wbuf[2048]; + char payload[1024]; + char* bp; + void* buf; + int state; + char timestamp[1024]; // read will put a timestamp here if( argc > 1 ) { dname = argv[1]; } - ctx = mcl_mk_context( dname ); + set_env(); // set env that setup_rdc() looks for + + ctx = mcl_mk_context( dname ); // allocate the context if( ctx == NULL ) { - fprintf( stderr, "[FAIL] couldn't make context" ); + fprintf( stderr, "[FAIL] couldn't make context\n" ); exit( 1 ); } - mcl_set_sigh(); // prevent colobber from broken pipe + mcl_set_sigh(); // prevent colobber from broken pipe - fd = suss_fifo( ctx, 101, 1 ); // should open the file for writing and return the fdes + open_fifo( ctx, TEST_MTYPE, WRITER ); // open dummy to prevent blocking reader + rfd = open_fifo( ctx, TEST_MTYPE, READER ); // open a reader to check fanout output + if( rfd < 0 ) { + fprintf( stderr, "[FAIL] unable to open a pipe reader for type == 100\n" ); + errors++; + } + + fd = suss_fifo( ctx, TEST_MTYPE, WRITER, &fref ); // should open the file for writing and return the fdes if( fd < 0 ) { fprintf( stderr, "[FAIL] suss_fifo did not return a valid fd\n" ); errors++; } - fd2= suss_fifo( ctx, 101, 0 ); // should open the file file for reading and return a different fd + if( fref == NULL ) { + fprintf( stderr, "[FAIL] suss_fifo did not set the fifo reference pointer\n" ); + errors++; + } else { + chalk_ok( fref ); + chalk_error( fref ); + } + + fd2= suss_fifo( ctx, TEST_MTYPE, 0, NULL ); // should open the file file for reading and return a different fd if( fd < 0 ) { fprintf( stderr, "[FAIL] suss_fifo did not return a valid fd\n" ); errors++; @@ -66,10 +121,165 @@ int main( int argc, char** argv ) { errors++; } - mcl_start_listening( ctx, port, 0 ); // start the listener, no waiting for rt since we don't send + mcl_start_listening( ctx, port, 0 ); // start the listener + + // under test, the FOREVER = 0 keeps fanout from blocking; drive several times to cover all cases + mcl_fifo_fanout( ctx, 5, 1 ); // first rmr receive call will simulate a timeout + mcl_fifo_fanout( ctx, 5, 1 ); // second receive simulates a health check + mcl_fifo_fanout( ctx, 5, 1 ); // 3-n return alternating timeout messages; drive so that + mcl_fifo_fanout( ctx, 5, 1 ); // we will have several land in the FIFO + mcl_fifo_fanout( ctx, 5, 1 ); + mcl_fifo_fanout( ctx, 5, 1 ); + mcl_fifo_fanout( ctx, 5, 1 ); + + *timestamp = 0; + state = mcl_fifo_read1( ctx, TEST_MTYPE, payload, sizeof( payload ), TRUE ); + if( state < 1 ) { + fprintf( stderr, "[FAIL] fifo_read return positive value when expected to\n" ); + errors++; + } + state = mcl_fifo_tsread1( ctx, TEST_MTYPE, payload, sizeof( payload ), TRUE, timestamp ); + if( state < 1 ) { + fprintf( stderr, "[FAIL] fifo_read with timestamp return positive value when expected to\n" ); + errors++; + } + + state = fifo_read1( NULL, TEST_MTYPE, payload, sizeof( payload ), 1, timestamp ); // coverage error check + if( state != 0 ) { + fprintf( stderr, "[FAIL] fifo_read didn't return 0 when given a nil context to\n" ); + errors++; + } + + mcl_fifo_fanout( ctx, 5, 0 ); // test with writing short header + mcl_fifo_fanout( ctx, 5, 0 ); + + // ------ some error/coverage testing --------------------------- + logit( LOG_CRIT, "critical message" ); + logit( LOG_ERR, "error message" ); + logit( LOG_WARN, "warning message" ); + logit( LOG_STAT, "stats message" ); + + fprintf( stderr, "[INFO] expected create fail message should follow\n" ); + bad_ctx = mcl_mk_context( "/nosuchdirectoryinthesystem" ); // create a context where fifo opens should fail + if( bad_ctx == NULL ) { + fprintf( stderr, "[FAIL] couldn't make 'bad' context" ); + exit( 1 ); + } + + fref = NULL; + fd = suss_fifo( bad_ctx, TEST_MTYPE, 1, &fref ); // should fail to open the file for writing beacuse directory is bad + if( fd >= 0 ) { + fprintf( stderr, "[FAIL] suss_fifo returned a valid fd when given a context with a bad directory path\n" ); + errors++; + } + if( fref != NULL ) { + fprintf( stderr, "[FAIL] suss_fifo returned an fref pointer when given a bad context\n" ); + errors++; + } + + fd = suss_fifo( NULL, TEST_MTYPE, 1, &fref ); // coverage nil pointer check + if( fd >= 0 ) { + fprintf( stderr, "[FAIL] suss_fifo returned a valid fd when given a nil context a bad directory path\n" ); + errors++; + } + + fd = suss_fifo( ctx, -1, 1, &fref ); // mad message type check + if( fd >= 0 ) { + fprintf( stderr, "[FAIL] suss_fifo returned a valid fd when given a bad message type\n" ); + errors++; + } + + // -- buffer testing ------------------------------------------------------ + bp = build_hdr( 1024, wbuf, 0 ); + bp = build_hdr( 1024, NULL, 0 ); + if( bp == NULL ) { + fprintf( stderr, "[FAIL] build_hdr didn't return a buffer pointer when given a nil buffer\n" ); + errors++; + } + free( bp ); + + bp = build_hdr( 1024, wbuf, sizeof( wbuf ) ); + if( bp == NULL ) { + fprintf( stderr, "[FAIL] build_hdr didn't return a buffer pointer\n" ); + errors++; + } + + + // ----- msg receive testing ---------------------------------------------------- + buf = mcl_get_msg( NULL, NULL, 1 ); // drive nil pointer checks + if( buf != NULL ) { + errors++; + fprintf( stderr, "[FAIL], get_msg call with nil context returned a buffer pointer\n" ); + } + + buf = mcl_get_msg( ctx, NULL, 1 ); // drive to force coverage; nothing is sent, so we can't validate buffer + + + mcl_fifo_one( NULL, NULL, 1, 1 ); + mcl_fifo_one( ctx, NULL, 1, 1 ); + mcl_fifo_one( ctx, wbuf, 0, 1 ); + mcl_fifo_one( ctx, wbuf, 10, 100 ); + + + // --- some rdc testing as best as we can without message generators -------- + rdc_init( NULL, NULL, ".foo", ".bar" ); // coverage testing + + ctx = setup_rdc(); // coverage test to ensure that it generates a context + if( ctx == NULL ) { + fprintf( stderr, "[FAIL] setup_rdc did not return a context pointer\n" ); + errors++; + } + + rdc_set_freq( NULL, 0 ); // error/nil test + rdc_set_freq( ctx, 0 ); // error/nil test + rdc_set_freq( ctx, 10 ); // roll after 10seconds to test that + + build_hdr( 1024, wbuf, sizeof( wbuf ) ); + bp = NULL; + bp = rdc_init_buf( TEST_MTYPE, wbuf, 10, bp ); // set up for write + rdc_write( ctx, bp, payload, sizeof( payload ) ); // write the raw data + + fprintf( stderr, "[INFO] pausing to test rdc file rolling\n" ); + sleep( 15 ); + build_hdr( 1024, wbuf, sizeof( wbuf ) ); + bp = NULL; + bp = rdc_init_buf( TEST_MTYPE, wbuf, 10, bp ); + rdc_write( ctx, bp, payload, sizeof( payload ) ); + + + // CAUTION: filenames need to match those expected in the run script as it creates src, and will validate, destination files + state = copy_unlink( "/tmp/mc_listener_test/no-such-copy_src", "/tmp/mc_listener_test/copy_dest", 0664 ); // first couple drive for error and coverage + if( state >= 0 ) { + fprintf( stderr, "[FAIL] copy-unlink of bad file didn't return bad state\n" ); + errors++; + } + state = copy_unlink( "/tmp/mc_listener_test/copy_src", "/tmp/mc_listener_test-nodir/copy_dest", 0664 ); + if( state >= 0 ) { + fprintf( stderr, "[FAIL] copy-unlink of bad target didn't return bad state\n" ); + errors++; + } + state = copy_unlink( "/tmp/mc_listener_test/copy_src", "/tmp/mc_listener_test/copy_dest", 0664 ); // drive for coverage; setup script can check contents + if( state < 0 ) { + fprintf( stderr, "[FAIL] copy-unlink expected success but failed\n" ); + errors++; + } + state = mvocp( "/tmp/mc_listener_test/bad-src-mv_src", "/tmp/mc_listener_test/mv_dest" ); + if( state >= 0 ) { + fprintf( stderr, "[FAIL] mv or copy expected failure didn't set bad state\n" ); + errors++; + } + state = mvocp( "/tmp/mc_listener_test/mv_src", "/tmp/mc_listener_test/mv_dest" ); + if( state < 0 ) { + fprintf( stderr, "[FAIL] mv or copy expected to succeed didn't set good state\n" ); + errors++; + } + + // ---- finally, check error count, write nice cheerful message and exit ---- if( ! errors ) { - fprintf( stderr, "[PASS] all tests look peachy\n" ); + fprintf( stderr, "[PASS] unit_test: everything looks peachy\n" ); + } else { + fprintf( stderr, "[FAIL] unit_test: there were %d errors\n", errors ); } return errors != 0;