X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=test%2Ftest_support.c;h=1e5e6572d62257084239d8434fd17c3f4b93dbf2;hb=8c6756d9d6f94beca0bc382f97383ca5e79d16c7;hp=d9a5f477582d44c3e34478632fe9a363f5f726a3;hpb=fd9cc7a5b3355146388ebdf4d558cb284c66c5f1;p=ric-plt%2Flib%2Frmr.git diff --git a/test/test_support.c b/test/test_support.c index d9a5f47..1e5e657 100644 --- a/test/test_support.c +++ b/test/test_support.c @@ -1,14 +1,14 @@ -// : vi ts=4 sw=4 noet : +// vi: ts=4 sw=4 noet : /* ================================================================================== - Copyright (c) 2019 Nokia - Copyright (c) 2018-2019 AT&T Intellectual Property. + Copyright (c) 2019-2020 Nokia + Copyright (c) 2018-2020 AT&T Intellectual Property. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 + http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -27,16 +27,69 @@ Date: 6 January 2019 */ +#ifndef _test_support_c +#define _test_support_c + #include #include #include #include +#include +#include + +/* + This is ugly, but needed to allow for component testing. + + The test code (e.g. foo_test.c and not foo_static_test.c) can include these + constants to turn off the import of test support files: + NO_EMULATION -- the transport emulation will not be included + NO_PRIVATE_HEADERS -- the private headers for the transport component of RMR + (e.g. si) will not be included. +*/ +#ifndef NO_EMULATION // assume emulation unless specifically put off (love double negatives) + #ifdef NNG_UNDER_TEST + #define TP_HDR_LEN 0 // needed for support functions but nonexistant in nng world + #include "test_nng_em.c" // nano/ngg emulation functions + #else + #include "test_si95_em.c" // si emulation functions + #endif +#endif + +#ifndef NO_PRIVATE_HEADERS // include transport headers unless specifically turned off + #ifdef NNG_UNDER_TEST + #include // context things are type sensitive + #else + #include "si95/socket_if.h" // need to have the si context more than anything else + #include + #endif +#endif #ifndef BAD #define BAD 1 // these are exit codes unless user overrides #define GOOD 0 #endif +// ----------- a couple of globals make it easier --------------------------------------- +static int ts_tests_driven = 0; // number of fail_if calls made == numer of tests driven + +// --------------------------------------------------------------------------------------- + +/* + Support test counting, reset and summary. +*/ +static int test_get_attempted() { + return ts_tests_driven; +} + +static void test_reset_attempted() { + ts_tests_driven = 0; +} + +static void test_summary( int ecount, char* tag ) { + fprintf( stderr, " %s completed; %d total tests, %d passed, %d failed\n", + tag, ts_tests_driven, ts_tests_driven - ecount, ecount ); +} + /* Snag the optional positional parameter at pp, return defval if not there. */ @@ -60,7 +113,7 @@ void sig_clean_exit( int sign ) { exit( 0 ); } -/* +/* Setup all of the signal handling for signals that we want to force a clean exit: term, intr, hup, quit, usr1/2 alarm, etc. All others we'll let default. */ @@ -69,7 +122,7 @@ static void set_signals( void ) { int sig_list[] = { SIGINT, SIGQUIT, SIGILL, SIGALRM, SIGTERM, SIGUSR1 , SIGUSR2 }; int i; int nele; // number of elements in the list - + nele = (int) ( sizeof( sig_list )/sizeof( int ) ); // convert raw size to the number of elements for( i = 0; i < nele; i ++ ) { memset( &sa, 0, sizeof( sa ) ); @@ -79,31 +132,43 @@ static void set_signals( void ) { } +/* + Assert like logic except these just record the test and return state so that we + can attempt all tests and not abort on the first failure as an assert would do. +*/ static int fail_if_nil( void* p, char* what ) { + ts_tests_driven++; + if( !p ) { - fprintf( stderr, "[FAIL] pointer to '%s' was nil\n", what ); + fprintf( stderr, " %s: pointer was nil\n", what ); } return p ? GOOD : BAD; } static int fail_not_nil( void* p, char* what ) { + ts_tests_driven++; + if( p ) { - fprintf( stderr, "[FAIL] pointer to '%s' was not nil\n", what ); + fprintf( stderr, " %s: pointer was not nil\n", what ); } return !p ? GOOD : BAD; } static int fail_if_false( int bv, char* what ) { + ts_tests_driven++; + if( !bv ) { - fprintf( stderr, "[FAIL] boolean was false (%d) %s\n", bv, what ); + fprintf( stderr, " %s: expected true, boolean test was false (%d)\n", what, bv ); } return bv ? GOOD : BAD; } static int fail_if_true( int bv, char* what ) { + ts_tests_driven++; + if( bv ) { - fprintf( stderr, "[FAIL] boolean was true (%d) %s\n", bv, what ); + fprintf( stderr, " %s: expected false, boolean test was true (%d)\n", what, bv ); } return bv ? BAD : GOOD; } @@ -112,23 +177,166 @@ static int fail_if_true( int bv, char* what ) { Same as fail_if_true(), but reads easier in the test code. */ static int fail_if( int bv, char* what ) { + ts_tests_driven++; + if( bv ) { - fprintf( stderr, "[FAIL] boolean was true (%d) %s\n", bv, what ); + fprintf( stderr, " %s: expected false, boolean test was true (%d)\n", what, bv ); } return bv ? BAD : GOOD; } +static int fail_pequal( void* a, void* b, char* what ) { + ts_tests_driven++; + + if( a == b ) { + fprintf( stderr, " %s: pointers were not equal a=%p b=%p\n", what, a, b ); + } + return a == b ? GOOD : BAD; // user may override good/bad so do NOT return a==b directly! +} + +static int fail_not_pequal( void* a, void* b, char* what ) { + ts_tests_driven++; + + if( a != b ) { + fprintf( stderr, " %s: pointers were not equal a=%p b=%p\n", what, a, b ); + } + return a == b ? GOOD : BAD; // user may override good/bad so do NOT return a==b directly! +} + static int fail_not_equal( int a, int b, char* what ) { + ts_tests_driven++; + if( a != b ) { - fprintf( stderr, "[FAIL] %s values were not equal a=%d b=%d\n", what, a, b ); + fprintf( stderr, " %s: values were not equal a=%d b=%d\n", what, a, b ); } return a == b ? GOOD : BAD; // user may override good/bad so do NOT return a==b directly! } static int fail_if_equal( int a, int b, char* what ) { + ts_tests_driven++; + if( a == b ) { - fprintf( stderr, "[FAIL] %s values were equal a=%d b=%d\n", what, a, b ); + fprintf( stderr, " %s values were equal a=%d b=%d\n", what, a, b ); } return a != b ? GOOD : BAD; // user may override good/bad so do NOT return a==b directly! } + +static int fail_not_equalp( void* a, void* b, char* what ) { + ts_tests_driven++; + + if( a != b ) { + fprintf( stderr, " %s: pointers were not equal a=%p b=%p\n", what, a, b ); + } + return a == b ? GOOD : BAD; // user may override good/bad so do NOT return a==b directly! +} + +static int fail_if_equalp( void* a, void* b, char* what ) { + ts_tests_driven++; + + if( a == b ) { + fprintf( stderr, " %s pointers were equal a=%p b=%p\n", what, a, b ); + } + return a != b ? GOOD : BAD; // user may override good/bad so do NOT return a==b directly! +} + + +// for symtab and other non-message things this allows them to exclude by setting +#ifndef NO_DUMMY_RMR +/* + Dummy message allocator for testing without sr_static functions +*/ +#ifndef MSG_VER +#define MSG_VER 3 +#endif + +static rmr_mbuf_t* test_mk_msg( int len, int tr_len ) { + rmr_mbuf_t* new_msg; + uta_mhdr_t* hdr; + size_t alen; + + alen = sizeof( *hdr ) + tr_len + len + TP_HDR_LEN; // this does no support allocating len2 and len3 data fields + + new_msg = (rmr_mbuf_t *) malloc( sizeof *new_msg ); + memset( new_msg, 0, sizeof( *new_msg ) ); + new_msg->tp_buf = (void *) malloc( alen ); + memset( new_msg->tp_buf, 0, alen ); + + hdr = (uta_mhdr_t*) new_msg->tp_buf; + SET_HDR_LEN( hdr ); + SET_HDR_TR_LEN( hdr, tr_len ); + hdr->rmr_ver = htonl( MSG_VER ); + strcpy( hdr->src, "dummyhost:1111" ); + strcpy( hdr->srcip, "30.4.19.86:1111" ); + + new_msg->header = new_msg->tp_buf; + new_msg->payload = new_msg->header + PAYLOAD_OFFSET( hdr ); + new_msg->alloc_len = alen; + new_msg->len = 0; + + return new_msg; +} + +static void test_set_ver( rmr_mbuf_t* msg, int ver ) { + uta_mhdr_t* hdr; + + hdr = (uta_mhdr_t*) msg->tp_buf; + hdr->rmr_ver = htonl( ver ); + strcpy( hdr->src, "dummyhost-v2:1111" ); + strcpy( hdr->srcip, "30.4.19.86:2222" ); + + return; +} + +/* + These allow values to be pushed deep into the real RMR header allocated + at the front of the transport buffer. These are needed to simulate + the actions of rmr_send() which pushes the values from the message buffer + just before putting them on the wire. +*/ +static void test_set_mtype( rmr_mbuf_t* msg, int mtype ) { + uta_mhdr_t* hdr; + + msg->mtype = mtype; + hdr = (uta_mhdr_t*) msg->tp_buf; + hdr->mtype = htonl( mtype ); +} + +static void test_set_sid( rmr_mbuf_t* msg, int sid ) { + uta_mhdr_t* hdr; + + msg->sub_id = sid; + hdr = (uta_mhdr_t*) msg->tp_buf; + hdr->sub_id = htonl( sid ); +} + +static void test_set_plen( rmr_mbuf_t* msg, int plen ) { + uta_mhdr_t* hdr; + + msg->len = plen; + hdr = (uta_mhdr_t*) msg->tp_buf; + hdr->plen = htonl( plen ); +} + +/* + Build a message and populate both the msg buffer and the tranport header + with mid, sid, and payload len. Tr_len causes that much space in the + header for trace info to be reserved. +*/ +static rmr_mbuf_t* mk_populated_msg( int alloc_len, int tr_len, int mtype, int sid, int plen ) { + uta_mhdr_t* hdr; + rmr_mbuf_t* mbuf; + + mbuf = test_mk_msg( alloc_len, tr_len ); + test_set_mtype( mbuf, mtype ); + test_set_sid( mbuf, sid ); + test_set_plen( mbuf, plen ); + + return mbuf; +} + + +// end no dummy rmr +#endif + +#endif