X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=test%2Frt_static_test.c;h=79d05614d80a54246da61c236b14964a379a6762;hb=353bafbe34c601eda6649ea7dcfdcf285d796d5a;hp=87f9931702060c035e8c777d5b0aa76ff6f3de98;hpb=b96e3d0a31cbe1451eec330f0615477b92258a33;p=ric-plt%2Flib%2Frmr.git diff --git a/test/rt_static_test.c b/test/rt_static_test.c index 87f9931..79d0561 100644 --- a/test/rt_static_test.c +++ b/test/rt_static_test.c @@ -98,11 +98,13 @@ fprintf( stderr, " build key: %x %x --> %llx\n", (int) mtype, (int) sid, ( */ static int rt_test( ) { uta_ctx_t* ctx; // context needed to test load static rt + uta_ctx_t* pctx; // "private" context for route manager communication tests route_table_t* rt; // route table route_table_t* crt; // cloned route table rtable_ent_t* rte; // route table entries from table rtable_ent_t* rte2; endpoint_t* ep; // endpoint added + endpoint_t* ep2; int more = 0; // more flag from round robin int errors = 0; // number errors found int i; @@ -121,8 +123,15 @@ static int rt_test( ) { int enu = 0; int state; char *buf; + char *buf2; char* seed_fname; // seed file - nng_socket nn_sock; // this is a struct in nng, so difficult to validate + SOCKET_TYPE nn_sock; // differnt in each transport (nng == struct, SI/Nano == int) + rmr_mbuf_t* mbuf; // message for meid route testing + void* p; // generic pointer + + #ifndef NNG_UNDER_TEST + si_ctx_t* si_ctx = NULL; + #endif 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, 0644 ); @@ -131,12 +140,12 @@ static int rt_test( ) { close( i ); } - + /* The hacky code below calls the necessary rmr functions to create a route table as though the following were read and parsed by the rmr functions. (This tests the individual funcitons and avoids writing another parser, so it's not pretty.) - + mse | 0 | 0 | yahoo.com:4561,localhost:4562 mse | 1 | 0 | localhost:4560,localhost:4568,localhost:4569; localhost:4561,localhost:4562 mse | 2 | 0 | localhost:4563,localhost:4564 @@ -185,7 +194,11 @@ static int rt_test( ) { entries[enu].group = 0; entries[enu].ep_name = "localhost:5512"; enu++; - rt = uta_rt_init( ); // get us a route table + rt = uta_rt_init( NULL ); + errors += fail_if_false( rt == NULL, "rt_init given a nil context didn't return nil" ); + + ctx = mk_dummy_ctx(); // make a dummy with rtgate mutex + rt = uta_rt_init( ctx ); // get us a route table if( (errors += fail_if_nil( rt, "pointer to route table" )) ) { fprintf( stderr, " abort: cannot continue without a route table\n" ); exit( 1 ); @@ -217,33 +230,50 @@ static int rt_test( ) { // ----- end hacking together a route table --------------------------------------------------- - crt = uta_rt_clone( rt ); // clone only the endpoint entries + crt = uta_rt_clone( ctx, rt, NULL, 0 ); // create a new rt and clone only the me entries errors += fail_if_nil( crt, "cloned route table" ); if( crt ) { c1 = count_entries( rt, 1 ); c2 = count_entries( crt, 1 ); errors += fail_not_equal( c1, c2, "cloned (endpoints) table entries space 1 count (b) did not match original table count (a)" ); - + c2 = count_entries( crt, 0 ); errors += fail_not_equal( c2, 0, "cloned (endpoints) table entries space 0 count (a) was not zero as expected" ); + + errors += fail_if_false( crt->ephash == rt->ephash, "ephash pointer in cloned table is not right" ); uta_rt_drop( crt ); } - crt = uta_rt_clone_all( rt ); // clone all entries - errors += fail_if_nil( crt, "cloned all route table" ); + crt = uta_rt_clone( ctx, rt, NULL, 1 ); // clone all entries (MT and ME) + errors += fail_if_nil( crt, "cloned (all) route table" ); if( crt ) { c1 = count_entries( rt, 0 ); c2 = count_entries( crt, 0 ); errors += fail_not_equal( c1, c2, "cloned (all) table entries space 0 count (b) did not match original table count (a)" ); - + c1 = count_entries( rt, 1 ); c2 = count_entries( crt, 1 ); errors += fail_not_equal( c1, c2, "cloned (all) table entries space 1 count (b) did not match original table count (a)" ); + + errors += fail_if_false( crt->ephash == rt->ephash, "ephash pointer in cloned table (all) is not right" ); uta_rt_drop( crt ); } - + + #ifdef NNG_UNDER_TEST + if( (ctx = (uta_ctx_t *) malloc( sizeof( uta_ctx_t ) )) != NULL ) { // get a "context" needed for si testing + memset( ctx, 0, sizeof( *ctx ) ); + ctx->rtable = rt; + } else { + fprintf( stderr, " cannot acllocate a context, cannot continue rtable tests\n" ); + return errors; + } + #else + ctx = mk_dummy_ctx(); + #endif + + ctx->rtable = rt; ep = uta_get_ep( rt, "localhost:4561" ); errors += fail_if_nil( ep, "end point (fetch by name)" ); @@ -251,12 +281,39 @@ static int rt_test( ) { errors += fail_not_nil( ep, "end point (fetch by name with bad name)" ); ep = NULL; - state = uta_epsock_byname( rt, "localhost:4561", &nn_sock, &ep ); // this should be found + #ifdef NNG_UNDER_TEST + state = uta_epsock_byname( rt, "localhost:4561", &nn_sock, &ep ); // this should be found + #else + state = uta_epsock_byname( ctx, "localhost:4561", &nn_sock, &ep ); // this should be found + #endif errors += fail_if_equal( state, 0, "socket (by name)" ); errors += fail_if_nil( ep, "epsock_byname did not populate endpoint pointer when expected to" ); //alt_value = uta_epsock_byname( rt, "localhost:4562" ); // we might do a memcmp on the two structs, but for now nothing //errors += fail_if_equal( value, alt_value, "app1/app2 sockets" ); + #if NNG_UNDER_TEST + state = uta_epsock_byname( NULL, "localhost:4561", &nn_sock, &ep ); // test coverage on nil checks + #else + state = uta_epsock_byname( NULL, "localhost:4561", &nn_sock, &ep ); + errors += fail_not_equal( state, 0, "socket (by name) nil context check returned true" ); + + p = ctx->si_ctx; + ctx->si_ctx = NULL; // set to drive second test + state = uta_epsock_byname( ctx, "localhost:4561", &nn_sock, &ep ); + ctx->si_ctx = p; + #endif + errors += fail_not_equal( state, 0, "socket (by name) nil check returned true" ); + + if( ep ) { // if previous test fails, cant run this + ep->open = 1; + #if NNG_UNDER_TEST + state = uta_epsock_byname( rt, "localhost:4561", &nn_sock, NULL ); // test coverage on nil checks + #else + state = uta_epsock_byname( ctx, "localhost:4561", &nn_sock, NULL ); + #endif + errors += fail_if_equal( state, 0, "socket (by name) open ep check returned false" ); + } + // --- test that the get_rte function finds expected keys, and retries to find 'bad' sid attempts for valid mtypes with no sid rte = uta_get_rte( rt, 0, 1, TRUE ); // s=0 m=1 is defined, so this should return a pointer @@ -285,14 +342,20 @@ static int rt_test( ) { rte = uta_get_rte( rt, 12, 3, FALSE ); // this combo does not exist and should fail when alt-key is not allowed (false) errors += fail_not_nil( rte, "get_rte returned a pointer for s=12, m=3, false" ); - rte = uta_get_rte( rt, 12, 3, TRUE ); // this should return the entry for the 3/-1 combination + rte = uta_get_rte( rt, 12, 3, TRUE ); // this should return the entry for the 3/-1 combination errors += fail_if_nil( rte, "get_rte did not return a pointer for s=12, m=3, true" ); + alt_value = -1; rte = uta_get_rte( rt, 0, 1, FALSE ); // get an rte for the next loop if( rte ) { for( i = 0; i < 10; i++ ) { // round robin return value should be different each time - value = uta_epsock_rr( rte, 0, &more, &nn_sock, &ep ); // msg type 1, group 1 + #ifdef NNG_UNDER_TEST + value = uta_epsock_rr( rte, 0, &more, &nn_sock, &ep ); // msg type 1, group 1 + #else + value = uta_epsock_rr( ctx, rte, 0, &more, &nn_sock, &ep ); + #endif + errors += fail_if_equal( value, alt_value, "round robiin sockets with multiple end points" ); errors += fail_if_false( more, "more for mtype==1" ); alt_value = value; @@ -303,7 +366,12 @@ static int rt_test( ) { rte = uta_get_rte( rt, 0, 3, FALSE ); // get an rte for the next loop if( rte ) { for( i = 0; i < 10; i++ ) { // this mtype has only one endpoint, so rr should be same each time - value = uta_epsock_rr( rte, 0, NULL, &nn_sock, &ep ); // also test ability to deal properly with nil more pointer + #ifdef NNG_UNDER_TEST + value = uta_epsock_rr( rte, 0, NULL, &nn_sock, &ep ); // also test ability to deal properly with nil more pointer + #else + value = uta_epsock_rr( ctx, rte, 0, NULL, &nn_sock, &ep ); + #endif + if( i ) { errors += fail_not_equal( value, alt_value, "round robin sockets with one endpoint" ); errors += fail_not_equal( more, -1, "more value changed in single group instance" ); @@ -313,12 +381,29 @@ static int rt_test( ) { } rte = uta_get_rte( rt, 11, 3, TRUE ); - state = uta_epsock_rr( rte, 22, NULL, NULL, &ep ); + #ifdef NNG_UNDER_TEST + state = uta_epsock_rr( rte, 22, NULL, NULL, &ep ); + #else + state = uta_epsock_rr( ctx, rte, 22, NULL, NULL, &ep ); + #endif errors += fail_if_true( state, "uta_epsock_rr returned bad (non-zero) state when given nil socket pointer" ); - uta_rt_clone( NULL ); // verify null parms don't crash things + + uta_rt_clone( ctx, NULL, NULL, 0 ); // verify null parms don't crash things uta_rt_drop( NULL ); - uta_epsock_rr( NULL, 0, &more, &nn_sock, &ep ); // drive null case for coverage + #ifdef NNG_UNDER_TEST + uta_epsock_rr( NULL, 0, &more, &nn_sock, &ep ); // drive null case for coverage + state = uta_epsock_rr( rte, 22, NULL, NULL, &ep ); + #else + state = uta_epsock_rr( NULL, NULL, 0, &more, &nn_sock, &ep ); // drive null case for coverage + errors += fail_not_equal( state, 0, "uta_epsock_rr did not return false when given nil ctx" ); + + state = uta_epsock_rr( ctx, NULL, 0, &more, &nn_sock, &ep ); + errors += fail_not_equal( state, 0, "uta_epsock_rr did not return false when given nil rte" ); + + state = uta_epsock_rr( ctx, rte, 10000, &more, &nn_sock, &ep ); + errors += fail_not_equal( state, 0, "uta_epsock_rr did not return false when given invalid group number" ); + #endif uta_add_rte( NULL, 99, 1 ); uta_get_rte( NULL, 0, 1000, TRUE ); @@ -337,19 +422,57 @@ static int rt_test( ) { free( buf ); } + fprintf( stderr, " test is overtly dropping rt table at %p\n", rt ); + ctx->rtable = NULL; uta_rt_drop( rt ); rt = NULL; - if( (ctx = (uta_ctx_t *) malloc( sizeof( uta_ctx_t ) )) != NULL ) { - memset( ctx, 0, sizeof( *ctx ) ); - - if( (seed_fname = getenv( "RMR_SEED_RT" )) != NULL ) { - read_static_rt( ctx, 0 ); - rt = ctx->rtable; - errors += fail_if_nil( rt, "read seed table didn't generate a rtable pointer in context" ); - unsetenv( "RMR_SEED_RT" ); // remove for next test - } + // --- force the load of a RT which has some edge case forcing issues + if( ctx ) { + char* rt_stuff = + "newrt | start | dummy-seed\n" + "mse | 1 | -1 | localhost:84306\n" + "mse | 10 | -1 | localhost:84306\n" + "mse | 10 | 1 | localhost:84306\n" + "# should cause failure because there aren't 10 entries above\n" + "newrt | end | 10\n" + + "# this table has no end\n" + "newrt | start | dummy-seed\n" + "mse | 1 | -1 | localhost:84306\n" + "mse | 10 | -1 | localhost:84306\n" + "mse | 10 | 1 | localhost:84306\n" + + "# this table should be ok\n" + "newrt | start | dummy-seed\n" + "mse | 1 | -1 | localhost:84306\n" + "mse | 10 | -1 | localhost:84306\n" + "mse | 10 | 1 | localhost:84306\n" + "newrt | end | 3\n" + + "# for an update to the existing table\n" + "# not in progress; drive that exception check\n" + "update | end | 23\n" + + "update | start | dummy-seed\n" + "mse | 3 | 2 | localhost:2222\n" + "# short record to drive test\n" + "del\n" + "# no table end for exception handling\n" + + "update | start | dummy-seed\n" + "mse | 2 | 2 | localhost:2222\n" + "del | 10 | 1\n" + "update | end | 2\n"; + + fprintf( stderr, " loading RT from edge case static table\n" ); + fprintf( stderr, " %s\n", rt_stuff ); + gen_custom_rt( ctx, rt_stuff ); + fprintf( stderr, " edge case load completed\n" ); + errors += fail_if_nil( ctx->rtable, "edge case route table didn't generate a pointer into the context" ); + + unsetenv( "RMR_SEED_RT" ); // remove for next read try read_static_rt( ctx, 0 ); // drive for not there coverage } @@ -361,12 +484,191 @@ static int rt_test( ) { ep = (endpoint_t *) malloc( sizeof( *ep ) ); + memset( ep, 0, sizeof( ep ) ); pthread_mutex_init( &ep->gate, NULL ); ep->name = strdup( "worm" ); ep->addr = NULL; - state = uta_link2( ep ); - errors += fail_if_true( state, "link2 did not return false when given nil pointers" ); + ep->notify = 1; + #ifdef NNG_UNDER_TEST + state = uta_link2( ep ); + #else + state = uta_link2( ctx, ep ); + #endif + errors += fail_if_true( state, "link2 did not return false when given a bad target name" ); + + #ifdef NNG_UNDER_TEST + state = uta_link2( NULL ); + #else + state = uta_link2( ctx, NULL ); + errors += fail_if_true( state, "link2 did not return false when given nil ep pointer" ); + + state = uta_link2( NULL, ep ); + #endif + errors += fail_if_true( state, "link2 did not return false when given nil pointer" ); + + ep->name = strdup( "localhost:5512" ); + ep->open = 1; + #ifdef NNG_UNDER_TEST + state = uta_link2( ep ); // drive for coverage + #else + state = uta_link2( ctx, ep ); + #endif + errors += fail_if_false( state, "link2 did returned false when given open ep" ); + + #ifndef NNG_UNDER_TEST + ep->open = 0; // context is used only if ep not open, so to check this test close the ep + ep->notify = 1; + state = rt_link2_ep( NULL, ep ); + errors += fail_if_true( state, "rt_link2_ep returned true when given bad context" ); + + state = rt_link2_ep( ctx, NULL ); + errors += fail_if_true( state, "rt_link2_ep returned true when given bad ep" ); + + ep->open = 1; + state = rt_link2_ep( ctx, ep ); + errors += fail_if_false( state, "rt_link2_ep returned false when given an open ep" ); + + ep->open = 0; + state = rt_link2_ep( ctx, ep ); + errors += fail_if_false( state, "rt_link2_ep returned false when given a closed ep" ); + + ep->open = 1; + uta_ep_failed( ep ); + errors += fail_if_true( ep->open, "uta_ep_failed didn't set open flag to false" ); + + #endif + + + // ----------------- test the meid support for looking up an endpoint based on the meid in the message ----- + + ctx->rtable = NULL; + ctx->my_name = strdup( "my_host_name" ); // set up to load a rtable + ctx->my_ip = strdup( "192.168.1.30" ); + gen_rt( ctx ); // generate a route table with meid entries and hang off ctx + + mbuf = rmr_alloc_msg( ctx, 2048 ); // buffer to play with + mbuf->len = 100; + rmr_str2meid( mbuf, "meid1" ); // id that we know is in the map + + #ifdef NNG_UNDER_TEST + ep = NULL; // force to nil so we see it go non-nil + state = epsock_meid( ctx->rtable, mbuf, &nn_sock, &ep ); + errors += fail_if_nil( ep, "ep was nil when looking up ep with known meid in message" ); + errors += fail_not_equal( state, 1, "state was not true when looking up ep with known meid in message" ); + + rmr_str2meid( mbuf, "XXXmeid1" ); // id that we know is NOT in the map + state = epsock_meid( ctx->rtable, mbuf, &nn_sock, &ep ); + // it is NOT a valid check to test ep for nil -- epsock_mied doesn't guarentee ep is set/cleared when state is false + errors += fail_not_equal( state, 0, "state was not false when looking up ep with unknown meid in message" ); + #else + ep = NULL; // force to nil so we see it go non-nil + state = epsock_meid( ctx, ctx->rtable, mbuf, &nn_sock, &ep ); + errors += fail_if_nil( ep, "ep was nil when looking up ep with known meid in message" ); + errors += fail_not_equal( state, 1, "state was not true when looking up ep with known meid in message" ); + + state = epsock_meid( ctx, ctx->rtable, mbuf, &nn_sock, &ep ); // a second call to drive open == true check for coverage + errors += fail_if_nil( ep, "ep was nil when looking up ep with known meid in message; on open ep" ); + errors += fail_not_equal( state, 1, "state was not true when looking up ep with known meid in message; on open ep" ); + + rmr_str2meid( mbuf, "XXXmeid1" ); // id that we know is NOT in the map + state = epsock_meid( ctx, ctx->rtable, mbuf, &nn_sock, &ep ); + // it is NOT a valid check to test ep for nil -- epsock_mied doesn't guarentee ep is set/cleared when state is false + errors += fail_not_equal( state, 0, "state was not false when looking up ep with unknown meid in message" ); + + state = epsock_meid( NULL, ctx->rtable, mbuf, &nn_sock, &ep ); + errors += fail_not_equal( state, 0, "epsock_meid returned true when given nil context" ); + + state = epsock_meid( ctx, ctx->rtable, mbuf, NULL, &ep ); + errors += fail_not_equal( state, 0, "epsock_meid returned true when given nil socket pointer" ); + #endif + + // ------------ debugging and such; coverage only calls ---------------------------------------------------------- + ep_stats( ctx->rtable, NULL, "name", NULL, NULL ); // ensure no crash when given nil pointer + rt_epcounts( ctx->rtable, "testing" ); + rt_epcounts( NULL, "testing" ); + + buf = ensure_nlterm( NULL ); + errors += fail_if_nil( buf, "ensure nlterm returned null pointer when given nil ptr" ); + if( buf ) { + errors += fail_not_equal( strlen( buf ), 1, "ensure nlterm returned incorrect length string when given nil pointer" ); + free( buf ); + } + + buf = ensure_nlterm( strdup( "x" ) ); // should return "x\n" + errors += fail_if_nil( buf, "ensure nlterm returned null pointer when given single char string" ); + if( buf ) { + errors += fail_not_equal( strlen( buf ), 2, "ensure nlterm returned incorrect length string when given single char string" ); + free( buf ); + } + + buf = strdup( "x\n" ); + buf2 = ensure_nlterm( buf ); // buffer returned should be the same + if( fail_not_pequal( buf, buf2, "ensure nlterm returned new buffer for one char string with newline" ) ) { + errors++; + free( buf2 ); + } + free( buf ); + + buf = strdup( "Missing our trips to Gloria's for papossas.\n" ); + buf2 = ensure_nlterm( buf ); // buffer returned should be the same + if( fail_not_pequal( buf, buf2, "ensure nlterm returned new buffer for string with newline" ) ) { + errors++; + free( buf2 ); + } + free( buf ); + + buf = ensure_nlterm( strdup( "Stand up and cheer!" ) ); // force addition of newline + if( buf ) { + errors += fail_not_equal( strcmp( buf, "Stand up and cheer!\n" ), 0, "ensure nlterm didn't add newline" ); + free( buf ); + buf = NULL; + } + + + // ------------- route manager request/response funcitons ------------------------------------------------------- + { + rmr_mbuf_t* smsg; + + smsg = rmr_alloc_msg( ctx, 1024 ); + send_rt_ack( ctx, smsg, "123456", 0, "no reason" ); + + pctx = mk_dummy_ctx(); + ctx->rtg_whid = -1; + state = send_update_req( pctx, ctx ); + errors += fail_not_equal( state, 0, "send_update_req did not return 0" ); + + ctx->rtg_whid = rmr_wh_open( ctx, "localhost:19289" ); + state = send_update_req( pctx, ctx ); + errors += fail_if_equal( state, 0, "send_update_req to an open whid did not return 0" ); + } + + + // ------------- si only; fd to ep conversion functions --------------------------------------------------------- + #ifndef NNG_UNDER_TEST + ep2 = (endpoint_t *) malloc( sizeof( *ep ) ); + + fd2ep_init( ctx ); + fd2ep_add( ctx, 10, ep2 ); + + ep = fd2ep_get( ctx, 10 ); + errors += fail_if_nil( ep, "fd2ep did not return pointer for known mapping" ); + errors += fail_if_false( ep == ep2, "fd2ep did not return same pointer that was added" ); + + ep = fd2ep_get( ctx, 20 ); + errors += fail_not_nil( ep, "fd2ep did returned a pointer for unknown mapping" ); + + ep = fd2ep_del( ctx, 10 ); + errors += fail_if_nil( ep, "fd2ep delete did not return pointer for known mapping" ); + errors += fail_if_false( ep == ep2, "fd2ep delete did not return same pointer that was added" ); + + ep = fd2ep_del( ctx, 20 ); + errors += fail_not_nil( ep, "fd2ep delete returned a pointer for unknown mapping" ); + #endif + // ---------------- misc coverage tests -------------------------------------------------------------------------- + collect_things( NULL, NULL, NULL, NULL, NULL ); // these both return null, these test NP checks + collect_things( NULL, NULL, NULL, NULL, (void *) 1234 ); // the last is an invalid pointer, but check needed to force check on previous param + del_rte( NULL, NULL, NULL, NULL, NULL ); return !!errors; // 1 or 0 regardless of count }