Correct bug identified in static analysis
[ric-plt/lib/rmr.git] / test / test_support.c
index 4ed976c..1e5e657 100644 (file)
@@ -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,
 #include <fcntl.h>
 #include <unistd.h>
 
+/*
+       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 <rmr_nng_private.h>            // context things are type sensitive
+       #else
+               #include "si95/socket_if.h"                     // need to have the si context more than anything else
+               #include <rmr_si_private.h>
+       #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, "<SUMMARY> %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.
 */
@@ -65,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.
 */
@@ -74,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 ) );
@@ -84,7 +132,13 @@ 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> %s: pointer was nil\n", what );
        }
@@ -92,6 +146,8 @@ static int fail_if_nil( void* p, char* what ) {
 }
 
 static int fail_not_nil( void* p, char* what ) {
+       ts_tests_driven++;
+
        if( p ) {
                fprintf( stderr, "<FAIL> %s: pointer was not nil\n", what );
        }
@@ -99,6 +155,8 @@ static int fail_not_nil( void* p, char* what ) {
 }
 
 static int fail_if_false( int bv, char* what ) {
+       ts_tests_driven++;
+
        if( !bv ) {
                fprintf( stderr, "<FAIL> %s: expected true, boolean test was false (%d)\n", what, bv );
        }
@@ -107,6 +165,8 @@ static int fail_if_false( int bv, char* what ) {
 }
 
 static int fail_if_true( int bv, char* what ) {
+       ts_tests_driven++;
+
        if( bv ) {
                fprintf( stderr, "<FAIL> %s: expected false, boolean test was true (%d)\n", what, bv );
        }
@@ -117,6 +177,8 @@ 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> %s: expected false, boolean test was true (%d)\n", what, bv );
@@ -124,7 +186,27 @@ static int fail_if( int bv, char* what ) {
        return bv ? BAD : GOOD;
 }
 
+static int fail_pequal( void* a, void* b, char* what ) {
+       ts_tests_driven++;
+
+       if( a == b ) {
+               fprintf( stderr, "<FAIL> %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, "<FAIL> %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 );
        }
@@ -132,10 +214,129 @@ static int fail_not_equal( int a, int b, char* what ) {
 }
 
 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 );
        }
        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, "<FAIL> %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, "<FAIL> %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