Release 221
[ric-plt/lib/rmr.git] / test / sr_nng_static_test.c
index 69090a1..b11934d 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 Nokia
+           Copyright (c) 2018-2019 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
 
 
    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,
 
    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
@@ -21,7 +21,7 @@
 /*
        Mmemonic:       sr_nng_static_test.c
        Abstract:       Test the send/receive funcitons. These are meant to be included at compile
 /*
        Mmemonic:       sr_nng_static_test.c
        Abstract:       Test the send/receive funcitons. These are meant to be included at compile
-                               time by the test driver.  
+                               time by the test driver.
 
        Author:         E. Scott Daniels
        Date:           3 April 2019
 
        Author:         E. Scott Daniels
        Date:           3 April 2019
 #include <errno.h>
 #include <string.h>
 #include <stdint.h>
 #include <errno.h>
 #include <string.h>
 #include <stdint.h>
+#include <pthread.h>
+#include <semaphore.h>
 
 
-#include "../src/common/include/rmr.h"
-#include "../src/common/include/rmr_agnostic.h"
-
-/*
-       Generate a simple route table (for all but direct route table testing).
-*/
-static void gen_rt( uta_ctx_t* ctx ) {
-       int             fd;
-       char*   rt_stuff;               // strings for the route table
-
-       rt_stuff = 
-               "newrt|start\n"                                                         // false start to drive detection 
-               "xxx|badentry to drive default case"
-               "newrt|start\n"
-        "rte|0|localhost:4560,localhost:4562\n"
-        "rte|1|localhost:4562;localhost:4561,localhost:4569\n"
-        "rte|2|localhost:4562\n"
-           "rte|4|localhost:4561\n"
-               "rte|5|localhost:4563\n"
-        "rte|6|localhost:4562\n"
-               "newrt|end\n";
-
-       fd = open( "utesting.rt", O_WRONLY | O_CREAT, 0600 );
-       if( fd < 0 ) {
-               fprintf( stderr, "<BUGGERED> unable to open file for testing route table gen\n" );
-               return;
-       }
-
-       setenv( "RMR_SEED_RT", "utesting.rt", 1 );
-       write( fd, rt_stuff, strlen( rt_stuff ) );
-       close( fd );
-       read_static_rt( ctx, 0 );
-       unlink( "utesting.rt" );
-}
+#include "rmr.h"
+#include "rmr_agnostic.h"
 
 
+// ----------- local test support ----------------------------------------------------------
+#define CLONE  1                       // convenience constants for payload realloc tests
+#define NO_CLONE 0
+#define COPY 1
+#define NO_COPY 0
 
 /*
        Drive the send and receive functions.  We also drive as much of the route
 
 /*
        Drive the send and receive functions.  We also drive as much of the route
@@ -77,21 +52,26 @@ static void gen_rt( uta_ctx_t* ctx ) {
 
        Send and receive functions are indirectly exercised from the rmr_nng_static_test
        module as it tests the user facing send/receive/call/rts functions. These tests
 
        Send and receive functions are indirectly exercised from the rmr_nng_static_test
        module as it tests the user facing send/receive/call/rts functions. These tests
-       should exercise specific cases for the internal functions as they will not 
+       should exercise specific cases for the internal functions as they will not
        specifically be driven elsewhere.
        specifically be driven elsewhere.
+
+       This requires the gen_rt funcition that is in the test_gen_rt module and should
+       have been included by the test module(s) which include this.
 */
 static int sr_nng_test() {
        uta_ctx_t* ctx;                         // context needed to test load static rt
        uta_ctx_t*      real_ctx;       // real one to force odd situations for error testing
        int errors = 0;                 // number errors found
        rmr_mbuf_t*     mbuf;           // mbuf to send/receive
 */
 static int sr_nng_test() {
        uta_ctx_t* ctx;                         // context needed to test load static rt
        uta_ctx_t*      real_ctx;       // real one to force odd situations for error testing
        int errors = 0;                 // number errors found
        rmr_mbuf_t*     mbuf;           // mbuf to send/receive
-       rmr_mbuf_t*     mb2;            // error capturing msg buf
+       rmr_mbuf_t*     mb2;            // second mbuf when needed
        int             whid = -1;
        int             last_whid;
        int     state;
        nng_socket nn_dummy_sock;                                       // dummy needed to drive send
        int             size;
        int             i;
        int             whid = -1;
        int             last_whid;
        int     state;
        nng_socket nn_dummy_sock;                                       // dummy needed to drive send
        int             size;
        int             i;
+       void*   p;
+       char*   payload_str;
 
        //ctx = rmr_init( "tcp:4360", 2048, 0 );                                // do NOT call init -- that starts the rtc thread which isn't good here
        ctx = (uta_ctx_t *) malloc( sizeof( uta_ctx_t ) );              // alloc the context manually
 
        //ctx = rmr_init( "tcp:4360", 2048, 0 );                                // do NOT call init -- that starts the rtc thread which isn't good here
        ctx = (uta_ctx_t *) malloc( sizeof( uta_ctx_t ) );              // alloc the context manually
@@ -101,9 +81,14 @@ static int sr_nng_test() {
        ctx->max_plen = RMR_MAX_RCV_BYTES + sizeof( uta_mhdr_t );
        ctx->max_mlen = ctx->max_plen + sizeof( uta_mhdr_t );
        ctx->my_name = strdup( "dummy-test" );
        ctx->max_plen = RMR_MAX_RCV_BYTES + sizeof( uta_mhdr_t );
        ctx->max_mlen = ctx->max_plen + sizeof( uta_mhdr_t );
        ctx->my_name = strdup( "dummy-test" );
+       ctx->my_ip = strdup( "30.4.19.86:1111" );
        uta_lookup_rtg( ctx );
 
        gen_rt( ctx );                                                          // forces a static load with some known info since we don't start the rtc()
        uta_lookup_rtg( ctx );
 
        gen_rt( ctx );                                                          // forces a static load with some known info since we don't start the rtc()
+       gen_rt( ctx );                                                          // force a second load to test cloning
+
+       p = rt_ensure_ep( NULL, "foo" );                                // drive for coverage
+       errors += fail_not_nil( p,  "rt_ensure_ep did not return nil when given nil route table" );
 
        state = rmr_ready( NULL );
        errors += fail_if_true( state, "reported ready when given a nil context" );
 
        state = rmr_ready( NULL );
        errors += fail_if_true( state, "reported ready when given a nil context" );
@@ -121,7 +106,7 @@ static int sr_nng_test() {
        errors += fail_not_equal( mbuf->flags, mb2->flags, "clone did not duplicate flags" );
        errors += fail_not_equal( mbuf->alloc_len, mb2->alloc_len, "clone did not dup alloc-len" );
        errors += fail_not_equal( mbuf->state, mb2->state, "clone did not dup state" );
        errors += fail_not_equal( mbuf->flags, mb2->flags, "clone did not duplicate flags" );
        errors += fail_not_equal( mbuf->alloc_len, mb2->alloc_len, "clone did not dup alloc-len" );
        errors += fail_not_equal( mbuf->state, mb2->state, "clone did not dup state" );
-       rmr_free_msg( mb2 );    
+       rmr_free_msg( mb2 );
 
        mbuf = rmr_send_msg( NULL, mbuf );
        errors += fail_if_nil( mbuf, "send with nil context but buffere didn't return buffer" );
 
        mbuf = rmr_send_msg( NULL, mbuf );
        errors += fail_if_nil( mbuf, "send with nil context but buffere didn't return buffer" );
@@ -131,7 +116,7 @@ static int sr_nng_test() {
                mbuf = rmr_rcv_msg( ctx, NULL );
        }
 
                mbuf = rmr_rcv_msg( ctx, NULL );
        }
 
-       size = 2048 - sizeof( uta_mhdr_t );             // emulated nng receive allocates 2K payloads
+       size = 2048 - em_hdr_size();            // emulated nng receive allocates 2K buffers -- subtract off header size
        state = rmr_payload_size( mbuf );
        errors += fail_not_equal( state, size, "payload size didn't return expected value" );   // receive should always give 4k buffer
 
        state = rmr_payload_size( mbuf );
        errors += fail_not_equal( state, size, "payload size didn't return expected value" );   // receive should always give 4k buffer
 
@@ -173,16 +158,125 @@ static int sr_nng_test() {
        errors += fail_if( state != 99, "xlate_nng_state did not return  default for unknown error" );
        errors += fail_if( errno == 0, "xlate_nng_state did not set errno (6)" );
 
        errors += fail_if( state != 99, "xlate_nng_state did not return  default for unknown error" );
        errors += fail_if( errno == 0, "xlate_nng_state did not set errno (6)" );
 
-       // ---- drive rtc in a 'static' (not pthreaded) mode -----
-       setenv( "ENV_VERBOSE_FILE", ".ut_rmr_verbose", 1 );                     // allow for verbose code in rtc to be driven
-       i = open( ".rmr_verbose", O_CREAT, 0664 );
+       // ---- drive rtc in a 'static' (not pthreaded) mode to get some coverage; no 'results' to be verified -----
+       setenv( ENV_RTG_RAW, "1", 1 );                                                          // rtc should expect raw messages (mostly coverage here)
+       setenv( ENV_VERBOSE_FILE, ".ut_rmr_verbose", 1 );                       // allow for verbose code in rtc to be driven
+       i = open( ".ut_rmr_verbose", O_RDWR | O_CREAT, 0654 );
        if( i >= 0 ) {
        if( i >= 0 ) {
-               write( i, "0\n", 2 );
+               write( i, "2\n", 2 );
                close( i );
        }
        ctx->shutdown = 1;                      // should force rtc to quit on first pass
                close( i );
        }
        ctx->shutdown = 1;                      // should force rtc to quit on first pass
+       rtc( NULL );                            // coverage test with nil pointer
+       rtc( ctx );
+
+       setenv( "RMR_RTG_SVC", "4567", 1 );             // drive for edge case coverage to ensure no nil pointer etc
+       rtc( ctx );
+       setenv( "RMR_RTG_SVC", "tcp:4567", 1 );
        rtc( ctx );
        rtc( ctx );
-       
+       setenv( "RMR_RTG_SVC", "tcp:4567:error", 1 );
+       rtc( ctx );
+
+       // ------------- reallocation tests ------------------------------------------------------------
+       // we use mk_populated_msg() to create a message with mid/sid/plen pushed into the transport
+       // header to simulate a message having been sent and received which is what causes this data
+       // to push into the wire packet.
+
+       payload_str = "Stand Up and Cheer; OU78-82";
+
+
+       mbuf = mk_populated_msg( 1024, 0, 99, 100, strlen( payload_str ) );
+       memcpy( mbuf->payload, payload_str, mbuf->len );
+       mb2 = realloc_payload( mbuf, 512, NO_COPY, NO_CLONE );
+       errors += fail_if_nil( mb2, "realloc_payload (no copy) returned a nil pointer when reallocating with smaller size" );
+       errors += fail_if_false( mbuf == mb2, "non-clone realloc payload (no copy) of smaller size did not return the same buffer" );
+
+       mb2 = realloc_payload( NULL, 512, NO_COPY, NO_CLONE );
+       errors += fail_not_nil( mb2, "realloc payload did not return nil pointer when passed nil mbuf" );
+
+       mb2 = realloc_payload( mbuf, 0, NO_COPY, NO_CLONE );
+       errors += fail_not_nil( mb2, "realloc payload did not return nil pointer when passed bad len" );
+
+       fprintf( stderr, "<TEST> no copy/no clone test starts\n" );
+       mb2 = realloc_payload( mbuf, 2048, NO_COPY, NO_CLONE );
+       errors += fail_if_false( mbuf == mb2, "realloc payload (no copy) of larger size did not return the same msg buffer(1)" );
+       errors += fail_not_equal( mb2->mtype, -1, "realloc payload (no copy) did not reset mtype(a) to expected(b) value" );
+       errors += fail_not_equal( mb2->sub_id, -1, "realloc payload (no copy) did not reset sub-id(a) to expected(b) value" );
+       errors += fail_if_nil( mb2, "realloc payload returned (no copy) a nil pointer when increasing payload len" );
+       errors += fail_not_equal( mb2->len, 0, "realloc payload payload len(a) not expected(b):" );
+       errors += fail_not_equal( rmr_payload_size( mb2), 2048, "realloc payload alloc len(a) not expected(b)" );
+
+       fprintf( stderr, "<TEST> copy/no clone test starts\n" );
+       mbuf = mk_populated_msg( 1024, 0, 99, 100, strlen( payload_str ) );
+       memcpy( mbuf->payload, payload_str, mbuf->len );
+       mb2 = realloc_payload( mbuf, 2048, COPY, NO_CLONE );
+       errors += fail_if_false( mbuf == mb2, "non-clone realloc payload (copy) of larger size did not return the same msg buffer(2)" );
+       errors += fail_if_nil( mb2, "realloc payload (copy) returned a nil pointer when increasing payload len)" );
+       errors += fail_not_equal( mb2->mtype, 99, "realloc payload (copy) did not reset mtype(a) to expected(b) value" );
+       errors += fail_not_equal( mb2->sub_id, 100, "realloc payload (copy) did not reset sub-id(a) to expected(b) value" );
+       errors += fail_if_equal( mb2->len, 0, "realloc payload (copy) msg len(a) not expected(b)" );
+       errors += fail_not_equal( rmr_payload_size( mb2), 2048, "realloc payload (copy) alloc len(a) not expected(b)" );
+       errors += fail_not_equal( strncmp( payload_str, mb2->payload, strlen( payload_str )), 0, "realloc payload(copy) didn't copy payload" );
+
+       fprintf( stderr, "<TEST> copy/clone test starts requested buffer smaller than original\n" );
+       mbuf = mk_populated_msg( 1024, 0, 99, 100, strlen( payload_str ) );
+       memcpy( mbuf->payload, payload_str, mbuf->len );
+       mb2 = realloc_payload( mbuf, 512, COPY, CLONE );
+       errors += fail_if_true( mbuf == mb2, "realloc payload (clone+copy) of larger size did not return different message buffers" );
+       errors += fail_if_nil( mb2, "realloc payload (clone+copy) returned a nil pointer when increasing payload len)" );
+       errors += fail_not_equal( mb2->mtype, 99, "realloc payload (clone+copy) did not reset mtype(a) to expected(b) value" );
+       errors += fail_not_equal( mb2->sub_id, 100, "realloc payload (clone+copy) did not reset sub-id(a) to expected(b) value" );
+       errors += fail_not_equal( mb2->len, strlen( payload_str ), "realloc payload (clone+copy) msg len(a) not expected(b)" );
+       errors += fail_not_equal( rmr_payload_size( mb2), 1024, "realloc payload (clone+copy) alloc len(a) not expected(b)" );
+       errors += fail_not_equal( strncmp( payload_str, mb2->payload, strlen( payload_str )), 0, "realloc payload(clone+copy) didn't copy payload" );
+
+       // with a clone, we must verify that original message looks sane too
+       errors += fail_not_equal( mbuf->mtype, 99, "realloc payload (clone+copy) validation of unchanged mbuf->mtype fails" );
+       errors += fail_not_equal( mbuf->sub_id, 100, "realloc payload (clone+copy) validation of unchanged mbuf->subid fails" );
+       errors += fail_not_equal( mbuf->len, strlen( payload_str ), "realloc payload (clone+copy) validation of unchanged payload len fails" );
+       errors += fail_not_equal( rmr_payload_size( mbuf ), 1024, "realloc payload (clone+copy) validation of unchanged alloc length fails" );
+       errors += fail_not_equal( strncmp( payload_str, mbuf->payload, strlen( payload_str )), 0, "realloc payload(clone+copy) validation of unchanged payload fails" );
+
+
+       fprintf( stderr, "<TEST> copy/clone test starts requested buf is larger than original\n" );
+       mbuf = mk_populated_msg( 1024, 0, 99, 100, strlen( payload_str ) );
+       memcpy( mbuf->payload, payload_str, mbuf->len );
+       mb2 = realloc_payload( mbuf, 2048, COPY, CLONE );
+       errors += fail_if_true( mbuf == mb2, "realloc payload(clone+copy/lg) of larger size did not return different message buffers" );
+       errors += fail_if_nil( mb2, "realloc payload (clone+copy/lg) returned a nil pointer when increasing payload len)" );
+       errors += fail_not_equal( mb2->mtype, 99, "realloc payload (clone+copy/lg) did not reset mtype(a) to expected(b) value" );
+       errors += fail_not_equal( mb2->sub_id, 100, "realloc payload (clone+copy/lg) did not reset sub-id(a) to expected(b) value" );
+       errors += fail_not_equal( mb2->len, strlen( payload_str ), "realloc payload (clone+copy/lg) msg len(a) not expected(b)" );
+       errors += fail_not_equal( rmr_payload_size( mb2), 2048, "realloc payload (clone+copy/lg) alloc len(a) not expected(b)" );
+       errors += fail_not_equal( strncmp( payload_str, mb2->payload, strlen( payload_str )), 0, "realloc payload(clone+copy/lg) didn't copy payload" );
+
+       // with a clone, we must verify that original message looks sane too
+       errors += fail_not_equal( mbuf->mtype, 99, "realloc payload (clone+copy/lg) validation of unchanged mbuf->mtype fails" );
+       errors += fail_not_equal( mbuf->sub_id, 100, "realloc payload (clone+copy/lg) validation of unchanged mbuf->subid fails" );
+       errors += fail_not_equal( mbuf->len, strlen( payload_str ), "realloc payload (clone+copy/lg) validation of unchanged payload len fails" );
+       errors += fail_not_equal( rmr_payload_size( mbuf ), 1024, "realloc payload (clone+copy/lg) validation of unchanged alloc length fails" );
+       errors += fail_not_equal( strncmp( payload_str, mbuf->payload, strlen( payload_str )), 0, "realloc payload(clone+copy/lg) validation of unchanged payload fails" );
+
+       // original message should be unharmed, and new message should have no type/sid or payload len; total alloc len should be requested enlargement
+       fprintf( stderr, "<TEST> no copy/clone test starts requested buf is larger than original\n" );
+       mbuf = mk_populated_msg( 1024, 0, 99, 100, strlen( payload_str ) );
+       memcpy( mbuf->payload, payload_str, mbuf->len );
+       mb2 = realloc_payload( mbuf, 2048, NO_COPY, CLONE );
+       errors += fail_if_true( mbuf == mb2, "realloc payload (clone+nocopy) of larger size did not return different message buffers" );
+       errors += fail_if_nil( mb2, "realloc payload (clone+nocopy) returned a nil pointer when increasing payload len)" );
+       errors += fail_not_equal( mb2->mtype, -1, "realloc payload (clone+nocopy) did not reset mtype(a) to expected(b) value" );
+       errors += fail_not_equal( mb2->sub_id, -1, "realloc payload (clone+nocopy) did not reset sub-id(a) to expected(b) value" );
+       errors += fail_not_equal( mb2->len, 0, "realloc payload (clone+nocopy) msg len(a) not expected(b)" );
+       errors += fail_not_equal( rmr_payload_size( mb2 ), 2048, "realloc payload (clone+nocopy) alloc len(a) not expected(b)" );
+       errors += fail_if_equal( strncmp( payload_str, mb2->payload, strlen( payload_str )), 0, "realloc payload(clone+nocopy) copied payload when not supposed to" );
+
+       // with a clone, we must verify that original message looks sane too
+       errors += fail_not_equal( mbuf->mtype, 99, "realloc payload (clone+nocopy) validation of unchanged mbuf->mtype fails" );
+       errors += fail_not_equal( mbuf->sub_id, 100, "realloc payload (clone+nocopy) validation of unchanged mbuf->subid fails" );
+       errors += fail_not_equal( mbuf->len, strlen( payload_str ), "realloc payload (clone+nocopy) validation of unchanged payload len fails" );
+       errors += fail_not_equal( rmr_payload_size( mbuf ), 1024, "realloc payload (clone+nocopy) validation of unchanged alloc length fails" );
+       errors += fail_not_equal( strncmp( payload_str, mbuf->payload, strlen( payload_str )), 0, "realloc payload (clone+nocopy) validation of unchanged payload fails" );
+
 
        return !!errors;
 }
 
        return !!errors;
 }