1 // : vi ts=4 sw=4 noet :
3 ==================================================================================
4 Copyright (c) 2019 Nokia
5 Copyright (c) 2018-2019 AT&T Intellectual Property.
7 Licensed under the Apache License, Version 2.0 (the "License");
8 you may not use this file except in compliance with the License.
9 You may obtain a copy of the License at
11 http://www.apache.org/licenses/LICENSE-2.0
13 Unless required by applicable law or agreed to in writing, software
14 distributed under the License is distributed on an "AS IS" BASIS,
15 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 See the License for the specific language governing permissions and
17 limitations under the License.
18 ==================================================================================
22 Mmemonic: rt_static_test.c
23 Abstract: Test the route table funcitons. These are meant to be included at compile
24 time by the test driver.
26 Author: E. Scott Daniels
38 #include <semaphore.h>
41 #include "rmr_agnostic.h"
43 typedef struct entry_info {
50 Driven by symtab foreach element of one space.
51 We count using the data as a counter.
53 static void count_things( void* st, void* entry, char const* name, void* thing, void* vdata ) {
57 if( (counter = (int *) vdata) != NULL ) {
64 Returns the number of entries in the table for the given class.
66 static int count_entries( route_table_t* rt, int class ) {
76 rmr_sym_foreach_class( rt->hash, class, count_things, &counter ); // run each and update counter
82 Builds a route table key.
84 static uint64_t build_key( uint32_t mtype, uint32_t sid ) {
87 k = (uint64_t) sid << 32;
90 fprintf( stderr, "<INFO> build key: %x %x --> %llx\n", (int) mtype, (int) sid, (long long) k );
95 Create a very large set of things to clone and ensure that the colleciton
96 buffers are properly resized without errors.
98 static int lg_clone_test( ) {
104 old_env = getenv( "RMR_SEED_RT" );
105 setenv( "RMR_SEED_RT", "./large_meid.rt", 1 );
107 ctx = mk_dummy_ctx();
109 read_static_rt( ctx, 0 );
110 p = uta_rt_clone( ctx, ctx->rtable, NULL, 1 ); // clone to force the copy from the existing table
111 errors += fail_if_nil( p, "clone of large table returned nil" );
113 errors += fail_not_equal( p->error, 0, "clone of large table had error" );
116 setenv( "RMR_SEED_RT", old_env, 1 );
122 This is the main route table test. It sets up a very specific table
123 for testing (not via the generic setup function for other test
126 static int rt_test( ) {
127 uta_ctx_t* ctx; // context needed to test load static rt
128 uta_ctx_t* pctx; // "private" context for route manager communication tests
129 route_table_t* rt; // route table
130 route_table_t* crt; // cloned route table
131 rtable_ent_t* rte; // route table entries from table
133 endpoint_t* ep; // endpoint added
135 int more = 0; // more flag from round robin
136 int errors = 0; // number errors found
139 int c1; // general counters
144 ei_t entries[50]; // end point information
145 int gcounts[7]; // number of groups in this set
146 int ecounts[7]; // number of elements per group
147 uint64_t mtypes[7]; // mtype/sid 'key' in the modern RMR world
154 char* seed_fname; // seed file
155 SOCKET_TYPE nn_sock; // differnt in each transport (nng == struct, SI/Nano == int)
156 rmr_mbuf_t* mbuf; // message for meid route testing
157 void* p; // generic pointer
159 #ifndef NNG_UNDER_TEST
160 si_ctx_t* si_ctx = NULL;
163 setenv( "ENV_VERBOSE_FILE", ".ut_rmr_verbose", 1 ); // allow for verbose code in rtc to be driven
164 i = open( ".ut_rmr_verbose", O_RDWR | O_CREAT, 0644 );
166 write( i, "2\n", 2 );
172 The hacky code below calls the necessary rmr functions to create a route table
173 as though the following were read and parsed by the rmr functions. (This tests
174 the individual funcitons and avoids writing another parser, so it's not pretty.)
176 mse | 0 | 0 | yahoo.com:4561,localhost:4562
177 mse | 1 | 0 | localhost:4560,localhost:4568,localhost:4569; localhost:4561,localhost:4562
178 mse | 2 | 0 | localhost:4563,localhost:4564
179 mse | 3 | 0 | localhost:4565
180 mse | 3 | 11 | locahost:5511
181 mse | 3 | -1 | localhost:5500
183 gcounts[0] = 1; // first entry has 1 group with 2 endpoints; message type 0, sid 0
185 mtypes[0] = build_key( 0, 0 ); // mtype is now a key of mtype/sid
186 entries[enu].group = 0; entries[enu].ep_name = "yahoo.com:4561"; enu++; // use a dns resolvable name to test that
187 entries[enu].group = 0; entries[enu].ep_name = "localhost:4562"; enu++; // rest can default to some dummy ip
189 gcounts[1] = 2; // 2 groups
190 ecounts[1] = 3; // first has 3 endpoints
191 mtypes[1] = build_key( 1, 0 );
192 entries[enu].group = 0; entries[enu].ep_name = "localhost:4560"; enu++;
193 entries[enu].group = 0; entries[enu].ep_name = "localhost:4568"; enu++;
194 entries[enu].group = 0; entries[enu].ep_name = "localhost:4569"; enu++;
196 gcounts[2] = 0; // 0 means use same rte, this is the next group for the entry
197 ecounts[2] = 2; // 2 endpoints
198 mtypes[2] = 999; // ignored when appending to previous entry
199 entries[enu].group = 1; entries[enu].ep_name = "localhost:4561"; enu++;
200 entries[enu].group = 1; entries[enu].ep_name = "localhost:4562"; enu++;
202 gcounts[3] = 1; // next entry has 1 group
203 ecounts[3] = 2; // with 2 enpoints
204 mtypes[3] = build_key( 2, 0 );
205 entries[enu].group = 0; entries[enu].ep_name = "localhost:4563"; enu++;
206 entries[enu].group = 0; entries[enu].ep_name = "localhost:4564"; enu++;
208 gcounts[4] = 1; // three entries for mt==3 with different sids
210 mtypes[4] = build_key( 3, 0 );
211 entries[enu].group = 0; entries[enu].ep_name = "localhost:5500"; enu++;
215 mtypes[5] = build_key( 3, 11 );
216 entries[enu].group = 0; entries[enu].ep_name = "localhost:5511"; enu++;
220 mtypes[6] = build_key( 3, -1 );
221 entries[enu].group = 0; entries[enu].ep_name = "localhost:5512"; enu++;
224 rt = uta_rt_init( NULL );
225 errors += fail_if_false( rt == NULL, "rt_init given a nil context didn't return nil" );
227 ctx = mk_dummy_ctx(); // make a dummy with rtgate mutex
228 rt = uta_rt_init( ctx ); // get us a route table
229 if( (errors += fail_if_nil( rt, "pointer to route table" )) ) {
230 fprintf( stderr, "<FAIL> abort: cannot continue without a route table\n" );
236 for( i = 0; i < sizeof( gcounts )/sizeof( int ); i++ ) { // add entries defined above
238 rte = uta_add_rte( rt, mtypes[i], gcounts[i] ); // get/create entry for message type
239 if( (errors += fail_if_nil( rte, "route table entry" )) ) {
240 fprintf( stderr, "<FAIL> abort: cannot continue without a route table entry\n" );
245 fprintf( stderr, "<SNAFU> internal testing error -- rte was nil for gcount == 0\n" );
250 for( k = 0; k < ecounts[i]; k++ ) {
251 ep = uta_add_ep( rt, rte, entries[enu].ep_name, entries[enu].group );
252 errors += fail_if_nil( ep, "endpoint" );
257 // ----- end hacking together a route table ---------------------------------------------------
260 crt = uta_rt_clone( ctx, rt, NULL, 0 ); // create a new rt and clone only the me entries
261 errors += fail_if_nil( crt, "cloned route table" );
263 c1 = count_entries( rt, 1 );
264 c2 = count_entries( crt, 1 );
265 errors += fail_not_equal( c1, c2, "cloned (endpoints) table entries space 1 count (b) did not match original table count (a)" );
267 c2 = count_entries( crt, 0 );
268 errors += fail_not_equal( c2, 0, "cloned (endpoints) table entries space 0 count (a) was not zero as expected" );
270 errors += fail_if_false( crt->ephash == rt->ephash, "ephash pointer in cloned table is not right" );
275 crt = uta_rt_clone( ctx, rt, NULL, 1 ); // clone all entries (MT and ME)
276 errors += fail_if_nil( crt, "cloned (all) route table" );
279 c1 = count_entries( rt, 0 );
280 c2 = count_entries( crt, 0 );
281 errors += fail_not_equal( c1, c2, "cloned (all) table entries space 0 count (b) did not match original table count (a)" );
283 c1 = count_entries( rt, 1 );
284 c2 = count_entries( crt, 1 );
285 errors += fail_not_equal( c1, c2, "cloned (all) table entries space 1 count (b) did not match original table count (a)" );
287 errors += fail_if_false( crt->ephash == rt->ephash, "ephash pointer in cloned table (all) is not right" );
291 #ifdef NNG_UNDER_TEST
292 if( (ctx = (uta_ctx_t *) malloc( sizeof( uta_ctx_t ) )) != NULL ) { // get a "context" needed for si testing
293 memset( ctx, 0, sizeof( *ctx ) );
296 fprintf( stderr, "<FAIL> cannot acllocate a context, cannot continue rtable tests\n" );
300 ctx = mk_dummy_ctx();
305 ep = uta_get_ep( rt, "localhost:4561" );
306 errors += fail_if_nil( ep, "end point (fetch by name)" );
307 ep = uta_get_ep( rt, "bad_name:4560" );
308 errors += fail_not_nil( ep, "end point (fetch by name with bad name)" );
311 #ifdef NNG_UNDER_TEST
312 state = uta_epsock_byname( rt, "localhost:4561", &nn_sock, &ep ); // this should be found
314 state = uta_epsock_byname( ctx, "localhost:4561", &nn_sock, &ep ); // this should be found
316 errors += fail_if_equal( state, 0, "socket (by name)" );
317 errors += fail_if_nil( ep, "epsock_byname did not populate endpoint pointer when expected to" );
318 //alt_value = uta_epsock_byname( rt, "localhost:4562" ); // we might do a memcmp on the two structs, but for now nothing
319 //errors += fail_if_equal( value, alt_value, "app1/app2 sockets" );
322 state = uta_epsock_byname( NULL, "localhost:4561", &nn_sock, &ep ); // test coverage on nil checks
324 state = uta_epsock_byname( NULL, "localhost:4561", &nn_sock, &ep );
325 errors += fail_not_equal( state, 0, "socket (by name) nil context check returned true" );
328 ctx->si_ctx = NULL; // set to drive second test
329 state = uta_epsock_byname( ctx, "localhost:4561", &nn_sock, &ep );
332 errors += fail_not_equal( state, 0, "socket (by name) nil check returned true" );
334 if( ep ) { // if previous test fails, cant run this
337 state = uta_epsock_byname( rt, "localhost:4561", &nn_sock, NULL ); // test coverage on nil checks
339 state = uta_epsock_byname( ctx, "localhost:4561", &nn_sock, NULL );
341 errors += fail_if_equal( state, 0, "socket (by name) open ep check returned false" );
345 // --- test that the get_rte function finds expected keys, and retries to find 'bad' sid attempts for valid mtypes with no sid
346 rte = uta_get_rte( rt, 0, 1, TRUE ); // s=0 m=1 is defined, so this should return a pointer
347 errors += fail_if_nil( rte, "get_rte did not return a pointer when s=0 m=1 true given" );
349 rte = uta_get_rte( rt, 0, 1, FALSE ); // the retry shouldn't apply, but ensure it does the righ thing
350 errors += fail_if_nil( rte, "get_rte did not return a pointer when s=0 m=1 false given" );
352 rte = uta_get_rte( rt, 1000, 1, FALSE ); // s=1000 does not exist for any msg type; should return nil as not allowed to drop sid
353 errors += fail_not_nil( rte, "get_rte returned a pointer when s=1000 m=1 false given" );
355 rte = uta_get_rte( rt, 1000, 1, TRUE ); // this should also fail as there is no mt==1 sid==-1 defined
356 errors += fail_not_nil( rte, "get_rte returned a pointer when s=1000 m=1 true given" );
358 rte = uta_get_rte( rt, 0, 3, TRUE ); // mtype sid combo does exist; true/false should not matter
359 errors += fail_if_nil( rte, "get_rte did not return a pointer when s=0 m=3 true given" );
361 rte2 = uta_get_rte( rt, 11, 3, TRUE ); // same mtype as before, different (valid) group, rte should be different than before
362 errors += fail_if_nil( rte2, "get_rte did not return a pointer when s=11 m=3 true given" );
363 errors += fail_if_true( rte == rte2, "get_rte for mtype==3 and different sids (0 and 11) returned the same rte pointer" );
365 rte2 = uta_get_rte( rt, 0, 3, FALSE ); // since the mtype/sid combo exists, setting false should return the same as before
366 errors += fail_if_nil( rte2, "get_rte did not return a pointer when s=0 m=3 false given" );
367 errors += fail_if_false( rte == rte2, "get_rte did not return same pointer when mtype/sid combo given with different true/false" );
369 rte = uta_get_rte( rt, 12, 3, FALSE ); // this combo does not exist and should fail when alt-key is not allowed (false)
370 errors += fail_not_nil( rte, "get_rte returned a pointer for s=12, m=3, false" );
372 rte = uta_get_rte( rt, 12, 3, TRUE ); // this should return the entry for the 3/-1 combination
373 errors += fail_if_nil( rte, "get_rte did not return a pointer for s=12, m=3, true" );
377 rte = uta_get_rte( rt, 0, 1, FALSE ); // get an rte for the next loop
379 for( i = 0; i < 10; i++ ) { // round robin return value should be different each time
380 #ifdef NNG_UNDER_TEST
381 value = uta_epsock_rr( rte, 0, &more, &nn_sock, &ep ); // msg type 1, group 1
383 value = uta_epsock_rr( ctx, rte, 0, &more, &nn_sock, &ep );
386 errors += fail_if_equal( value, alt_value, "round robiin sockets with multiple end points" );
387 errors += fail_if_false( more, "more for mtype==1" );
393 rte = uta_get_rte( rt, 0, 3, FALSE ); // get an rte for the next loop
395 for( i = 0; i < 10; i++ ) { // this mtype has only one endpoint, so rr should be same each time
396 #ifdef NNG_UNDER_TEST
397 value = uta_epsock_rr( rte, 0, NULL, &nn_sock, &ep ); // also test ability to deal properly with nil more pointer
399 value = uta_epsock_rr( ctx, rte, 0, NULL, &nn_sock, &ep );
403 errors += fail_not_equal( value, alt_value, "round robin sockets with one endpoint" );
404 errors += fail_not_equal( more, -1, "more value changed in single group instance" );
410 rte = uta_get_rte( rt, 11, 3, TRUE );
411 #ifdef NNG_UNDER_TEST
412 state = uta_epsock_rr( rte, 22, NULL, NULL, &ep );
414 state = uta_epsock_rr( ctx, rte, 22, NULL, NULL, &ep );
416 errors += fail_if_true( state, "uta_epsock_rr returned bad (non-zero) state when given nil socket pointer" );
419 uta_rt_clone( ctx, NULL, NULL, 0 ); // verify null parms don't crash things
421 #ifdef NNG_UNDER_TEST
422 uta_epsock_rr( NULL, 0, &more, &nn_sock, &ep ); // drive null case for coverage
423 state = uta_epsock_rr( rte, 22, NULL, NULL, &ep );
425 state = uta_epsock_rr( NULL, NULL, 0, &more, &nn_sock, &ep ); // drive null case for coverage
426 errors += fail_not_equal( state, 0, "uta_epsock_rr did not return false when given nil ctx" );
428 state = uta_epsock_rr( ctx, NULL, 0, &more, &nn_sock, &ep );
429 errors += fail_not_equal( state, 0, "uta_epsock_rr did not return false when given nil rte" );
431 state = uta_epsock_rr( ctx, rte, 10000, &more, &nn_sock, &ep );
432 errors += fail_not_equal( state, 0, "uta_epsock_rr did not return false when given invalid group number" );
434 uta_add_rte( NULL, 99, 1 );
435 uta_get_rte( NULL, 0, 1000, TRUE );
437 fprintf( stderr, "[INFO] test: adding end points with nil data; warnings expected\n" );
438 uta_add_ep( NULL, NULL, "foo", 1 );
439 uta_add_ep( rt, NULL, "foo", 1 );
441 buf = uta_fib( ".gitignore" );
442 errors += fail_if_nil( buf, "buffer from read file into buffer" );
446 buf = uta_fib( "no-file" );
447 errors += fail_if_nil( buf, "buffer from read file into buffer (no file)" );
452 fprintf( stderr, "<INFO> test is overtly dropping rt table at %p\n", rt );
458 // --- force the load of a RT which has some edge case forcing issues
461 "newrt | start | dummy-seed\n"
462 "mse | 1 | -1 | localhost:84306\n"
463 "mse | 10 | -1 | localhost:84306\n"
464 "mse | 10 | 1 | localhost:84306\n"
465 "# should cause failure because there aren't 10 entries above\n"
468 "# this table has no end\n"
469 "newrt | start | dummy-seed\n"
470 "mse | 1 | -1 | localhost:84306\n"
471 "mse | 10 | -1 | localhost:84306\n"
472 "mse | 10 | 1 | localhost:84306\n"
474 "# this table should be ok\n"
475 "newrt | start | dummy-seed\n"
476 "mse | 1 | -1 | localhost:84306\n"
477 "mse | 10 | -1 | localhost:84306\n"
478 "mse | 10 | 1 | localhost:84306\n"
481 "# for an update to the existing table\n"
482 "# not in progress; drive that exception check\n"
483 "update | end | 23\n"
485 "update | start | dummy-seed\n"
486 "mse | 3 | 2 | localhost:2222\n"
487 "# short record to drive test\n"
489 "# no table end for exception handling\n"
491 "update | start | dummy-seed\n"
492 "mse | 2 | 2 | localhost:2222\n"
494 "update | end | 2\n";
496 fprintf( stderr, "<INFO> loading RT from edge case static table\n" );
497 fprintf( stderr, "<INFO> %s\n", rt_stuff );
498 gen_custom_rt( ctx, rt_stuff );
499 fprintf( stderr, "<INFO> edge case load completed\n" );
500 errors += fail_if_nil( ctx->rtable, "edge case route table didn't generate a pointer into the context" );
502 unsetenv( "RMR_SEED_RT" ); // remove for next read try
503 read_static_rt( ctx, 0 ); // drive for not there coverage
507 buf = uta_fib( "no-suhch-file" ); // drive some error checking for coverage
513 ep = (endpoint_t *) malloc( sizeof( *ep ) );
514 memset( ep, 0, sizeof( ep ) );
515 pthread_mutex_init( &ep->gate, NULL );
516 ep->name = strdup( "worm" );
519 #ifdef NNG_UNDER_TEST
520 state = uta_link2( ep );
522 state = uta_link2( ctx, ep );
524 errors += fail_if_true( state, "link2 did not return false when given a bad target name" );
526 #ifdef NNG_UNDER_TEST
527 state = uta_link2( NULL );
529 state = uta_link2( ctx, NULL );
530 errors += fail_if_true( state, "link2 did not return false when given nil ep pointer" );
532 state = uta_link2( NULL, ep );
534 errors += fail_if_true( state, "link2 did not return false when given nil pointer" );
536 ep->name = strdup( "localhost:5512" );
538 #ifdef NNG_UNDER_TEST
539 state = uta_link2( ep ); // drive for coverage
541 state = uta_link2( ctx, ep );
543 errors += fail_if_false( state, "link2 did returned false when given open ep" );
545 #ifndef NNG_UNDER_TEST
546 ep->open = 0; // context is used only if ep not open, so to check this test close the ep
548 state = rt_link2_ep( NULL, ep );
549 errors += fail_if_true( state, "rt_link2_ep returned true when given bad context" );
551 state = rt_link2_ep( ctx, NULL );
552 errors += fail_if_true( state, "rt_link2_ep returned true when given bad ep" );
555 state = rt_link2_ep( ctx, ep );
556 errors += fail_if_false( state, "rt_link2_ep returned false when given an open ep" );
559 state = rt_link2_ep( ctx, ep );
560 errors += fail_if_false( state, "rt_link2_ep returned false when given a closed ep" );
564 errors += fail_if_true( ep->open, "uta_ep_failed didn't set open flag to false" );
569 // ----------------- test the meid support for looking up an endpoint based on the meid in the message -----
572 ctx->my_name = strdup( "my_host_name" ); // set up to load a rtable
573 ctx->my_ip = strdup( "192.168.1.30" );
574 gen_rt( ctx ); // generate a route table with meid entries and hang off ctx
576 mbuf = rmr_alloc_msg( ctx, 2048 ); // buffer to play with
578 rmr_str2meid( mbuf, "meid1" ); // id that we know is in the map
580 #ifdef NNG_UNDER_TEST
581 ep = NULL; // force to nil so we see it go non-nil
582 state = epsock_meid( ctx->rtable, mbuf, &nn_sock, &ep );
583 errors += fail_if_nil( ep, "ep was nil when looking up ep with known meid in message" );
584 errors += fail_not_equal( state, 1, "state was not true when looking up ep with known meid in message" );
586 rmr_str2meid( mbuf, "XXXmeid1" ); // id that we know is NOT in the map
587 state = epsock_meid( ctx->rtable, mbuf, &nn_sock, &ep );
588 // it is NOT a valid check to test ep for nil -- epsock_mied doesn't guarentee ep is set/cleared when state is false
589 errors += fail_not_equal( state, 0, "state was not false when looking up ep with unknown meid in message" );
591 ep = NULL; // force to nil so we see it go non-nil
592 state = epsock_meid( ctx, ctx->rtable, mbuf, &nn_sock, &ep );
593 errors += fail_if_nil( ep, "ep was nil when looking up ep with known meid in message" );
594 errors += fail_not_equal( state, 1, "state was not true when looking up ep with known meid in message" );
596 state = epsock_meid( ctx, ctx->rtable, mbuf, &nn_sock, &ep ); // a second call to drive open == true check for coverage
597 errors += fail_if_nil( ep, "ep was nil when looking up ep with known meid in message; on open ep" );
598 errors += fail_not_equal( state, 1, "state was not true when looking up ep with known meid in message; on open ep" );
600 rmr_str2meid( mbuf, "XXXmeid1" ); // id that we know is NOT in the map
601 state = epsock_meid( ctx, ctx->rtable, mbuf, &nn_sock, &ep );
602 // it is NOT a valid check to test ep for nil -- epsock_mied doesn't guarentee ep is set/cleared when state is false
603 errors += fail_not_equal( state, 0, "state was not false when looking up ep with unknown meid in message" );
605 state = epsock_meid( NULL, ctx->rtable, mbuf, &nn_sock, &ep );
606 errors += fail_not_equal( state, 0, "epsock_meid returned true when given nil context" );
608 state = epsock_meid( ctx, ctx->rtable, mbuf, NULL, &ep );
609 errors += fail_not_equal( state, 0, "epsock_meid returned true when given nil socket pointer" );
612 // ------------ debugging and such; coverage only calls ----------------------------------------------------------
613 ep_stats( ctx->rtable, NULL, "name", NULL, NULL ); // ensure no crash when given nil pointer
614 rt_epcounts( ctx->rtable, "testing" );
615 rt_epcounts( NULL, "testing" );
617 buf = ensure_nlterm( NULL );
618 errors += fail_if_nil( buf, "ensure nlterm returned null pointer when given nil ptr" );
620 errors += fail_not_equal( strlen( buf ), 1, "ensure nlterm returned incorrect length string when given nil pointer" );
624 buf = ensure_nlterm( strdup( "x" ) ); // should return "x\n"
625 errors += fail_if_nil( buf, "ensure nlterm returned null pointer when given single char string" );
627 errors += fail_not_equal( strlen( buf ), 2, "ensure nlterm returned incorrect length string when given single char string" );
631 buf = strdup( "x\n" );
632 buf2 = ensure_nlterm( buf ); // buffer returned should be the same
633 if( fail_not_pequal( buf, buf2, "ensure nlterm returned new buffer for one char string with newline" ) ) {
639 buf = strdup( "Missing our trips to Gloria's for papossas.\n" );
640 buf2 = ensure_nlterm( buf ); // buffer returned should be the same
641 if( fail_not_pequal( buf, buf2, "ensure nlterm returned new buffer for string with newline" ) ) {
647 buf = ensure_nlterm( strdup( "Stand up and cheer!" ) ); // force addition of newline
649 errors += fail_not_equal( strcmp( buf, "Stand up and cheer!\n" ), 0, "ensure nlterm didn't add newline" );
655 // ------------- route manager request/response funcitons -------------------------------------------------------
659 smsg = rmr_alloc_msg( ctx, 1024 );
660 send_rt_ack( ctx, smsg, "123456", 0, "no reason" );
662 pctx = mk_dummy_ctx();
664 state = send_update_req( pctx, ctx );
665 errors += fail_not_equal( state, 0, "send_update_req did not return 0" );
667 ctx->rtg_whid = rmr_wh_open( ctx, "localhost:19289" );
668 state = send_update_req( pctx, ctx );
669 errors += fail_if_equal( state, 0, "send_update_req to an open whid did not return 0" );
673 // ------------- si only; fd to ep conversion functions ---------------------------------------------------------
674 #ifndef NNG_UNDER_TEST
675 ep2 = (endpoint_t *) malloc( sizeof( *ep ) );
678 fd2ep_add( ctx, 10, ep2 );
680 ep = fd2ep_get( ctx, 10 );
681 errors += fail_if_nil( ep, "fd2ep did not return pointer for known mapping" );
682 errors += fail_if_false( ep == ep2, "fd2ep did not return same pointer that was added" );
684 ep = fd2ep_get( ctx, 20 );
685 errors += fail_not_nil( ep, "fd2ep did returned a pointer for unknown mapping" );
687 ep = fd2ep_del( ctx, 10 );
688 errors += fail_if_nil( ep, "fd2ep delete did not return pointer for known mapping" );
689 errors += fail_if_false( ep == ep2, "fd2ep delete did not return same pointer that was added" );
691 ep = fd2ep_del( ctx, 20 );
692 errors += fail_not_nil( ep, "fd2ep delete returned a pointer for unknown mapping" );
695 // ---------------- misc coverage tests --------------------------------------------------------------------------
696 collect_things( NULL, NULL, NULL, NULL, NULL ); // these both return null, these test NP checks
697 collect_things( NULL, NULL, NULL, NULL, (void *) 1234 ); // the last is an invalid pointer, but check needed to force check on previous param
698 del_rte( NULL, NULL, NULL, NULL, NULL );
700 ctx = mk_dummy_ctx();
701 roll_tables( ctx ); // drive nil rt check
705 // ------ specific edge case tests -------------------------------------------------------------------------------
706 errors += lg_clone_test( );
708 return !!errors; // 1 or 0 regardless of count