blob: 3bdd3124ed4b3035dc36b1f4bfd4a9b211f652b6 [file] [log] [blame]
E. Scott Danielsc8e651e2021-04-09 08:40:20 -04001
E. Scott Daniels8dd46412019-04-16 20:47:54 +00002// : vi ts=4 sw=4 noet :
3/*
4==================================================================================
E. Scott Daniels5efb1e62019-05-02 17:09:35 +00005 Copyright (c) 2019 Nokia
E. Scott Daniels8790bf02019-04-23 12:59:28 +00006 Copyright (c) 2018-2019 AT&T Intellectual Property.
E. Scott Daniels8dd46412019-04-16 20:47:54 +00007
8 Licensed under the Apache License, Version 2.0 (the "License");
9 you may not use this file except in compliance with the License.
10 You may obtain a copy of the License at
11
E. Scott Daniels8790bf02019-04-23 12:59:28 +000012 http://www.apache.org/licenses/LICENSE-2.0
E. Scott Daniels8dd46412019-04-16 20:47:54 +000013
14 Unless required by applicable law or agreed to in writing, software
15 distributed under the License is distributed on an "AS IS" BASIS,
16 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 See the License for the specific language governing permissions and
18 limitations under the License.
19==================================================================================
20*/
21
22/*
23 Mmemonic: rt_static_test.c
24 Abstract: Test the route table funcitons. These are meant to be included at compile
E. Scott Daniels5efb1e62019-05-02 17:09:35 +000025 time by the test driver.
E. Scott Daniels8dd46412019-04-16 20:47:54 +000026
27 Author: E. Scott Daniels
28 Date: 3 April 2019
29*/
30
31#include <unistd.h>
32#include <stdio.h>
33#include <stdlib.h>
34#include <strings.h>
35#include <errno.h>
36#include <string.h>
37#include <stdint.h>
E. Scott Daniels412d53d2019-05-20 20:00:52 +000038#include <pthread.h>
39#include <semaphore.h>
E. Scott Daniels8dd46412019-04-16 20:47:54 +000040
E. Scott Daniels412d53d2019-05-20 20:00:52 +000041#include "rmr.h"
42#include "rmr_agnostic.h"
E. Scott Daniels8dd46412019-04-16 20:47:54 +000043
44typedef struct entry_info {
45 int group;
46 char* ep_name;
47} ei_t;
48
49
50/*
E. Scott Daniels3376a212019-05-14 14:14:20 +000051 Driven by symtab foreach element of one space.
52 We count using the data as a counter.
53*/
54static void count_things( void* st, void* entry, char const* name, void* thing, void* vdata ) {
55 int* counter;
56
57 if( thing ) {
58 if( (counter = (int *) vdata) != NULL ) {
59 *counter++;
60 }
61 }
62}
63
64/*
65 Returns the number of entries in the table for the given class.
66*/
67static int count_entries( route_table_t* rt, int class ) {
68 int counter = 0;
69
70 if( ! rt ) {
71 return 0;
72 }
73 if( !rt->hash ) {
74 return 0;
75 }
76
77 rmr_sym_foreach_class( rt->hash, class, count_things, &counter ); // run each and update counter
78
79 return counter;
80}
81
82/*
E. Scott Daniels6511ac72019-08-27 10:17:21 -040083 Builds a route table key.
84*/
85static uint64_t build_key( uint32_t mtype, uint32_t sid ) {
86 uint64_t k;
87
88 k = (uint64_t) sid << 32;
89 k += mtype;
90
E. Scott Daniels84423e62020-12-04 13:04:29 -050091 fprintf( stderr, "<INFO> build key: %x %x --> %llx\n", (int) mtype, (int) sid, (long long) k );
E. Scott Daniels6511ac72019-08-27 10:17:21 -040092 return k;
93}
94
95/*
E. Scott Daniels84423e62020-12-04 13:04:29 -050096 Create a very large set of things to clone and ensure that the colleciton
97 buffers are properly resized without errors.
98*/
99static int lg_clone_test( ) {
100 int errors = 0;
101 uta_ctx_t* ctx;
102 char* old_env;
103 route_table_t* p;
104
105 old_env = getenv( "RMR_SEED_RT" );
106 setenv( "RMR_SEED_RT", "./large_meid.rt", 1 );
107
108 ctx = mk_dummy_ctx();
109
110 read_static_rt( ctx, 0 );
111 p = uta_rt_clone( ctx, ctx->rtable, NULL, 1 ); // clone to force the copy from the existing table
112 errors += fail_if_nil( p, "clone of large table returned nil" );
113 if( p != NULL ) {
114 errors += fail_not_equal( p->error, 0, "clone of large table had error" );
115 }
116
117 setenv( "RMR_SEED_RT", old_env, 1 );
118
119 return errors;
120}
121
122/*
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000123 This is the main route table test. It sets up a very specific table
124 for testing (not via the generic setup function for other test
125 situations).
126*/
127static int rt_test( ) {
128 uta_ctx_t* ctx; // context needed to test load static rt
E. Scott Danielsfc2112d2020-04-21 12:51:05 -0400129 uta_ctx_t* pctx; // "private" context for route manager communication tests
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000130 route_table_t* rt; // route table
131 route_table_t* crt; // cloned route table
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400132 rtable_ent_t* rte; // route table entries from table
133 rtable_ent_t* rte2;
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000134 endpoint_t* ep; // endpoint added
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500135 endpoint_t* ep2;
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000136 int more = 0; // more flag from round robin
137 int errors = 0; // number errors found
138 int i;
139 int k;
E. Scott Daniels3376a212019-05-14 14:14:20 +0000140 int c1; // general counters
141 int c2;
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000142 int mtype;
143 int value;
144 int alt_value;
145 ei_t entries[50]; // end point information
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400146 int gcounts[7]; // number of groups in this set
147 int ecounts[7]; // number of elements per group
148 uint64_t mtypes[7]; // mtype/sid 'key' in the modern RMR world
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000149 char* tok;
150 char* nxt_tok;
151 int enu = 0;
152 int state;
153 char *buf;
E. Scott Danielsfcea3952020-10-30 15:04:16 -0400154 char *buf2;
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000155 char* seed_fname; // seed file
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500156 SOCKET_TYPE nn_sock; // differnt in each transport (nng == struct, SI/Nano == int)
E. Scott Daniels0b79fc22019-12-04 15:20:16 -0500157 rmr_mbuf_t* mbuf; // message for meid route testing
E. Scott Daniels353bafb2020-11-12 16:44:34 -0500158 void* p; // generic pointer
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000159
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500160 #ifndef NNG_UNDER_TEST
161 si_ctx_t* si_ctx = NULL;
162 #endif
163
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000164 setenv( "ENV_VERBOSE_FILE", ".ut_rmr_verbose", 1 ); // allow for verbose code in rtc to be driven
E. Scott Danielsd7109572019-04-18 14:01:16 +0000165 i = open( ".ut_rmr_verbose", O_RDWR | O_CREAT, 0644 );
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000166 if( i >= 0 ) {
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400167 write( i, "2\n", 2 );
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000168 close( i );
169 }
170
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500171
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400172 /*
173 The hacky code below calls the necessary rmr functions to create a route table
174 as though the following were read and parsed by the rmr functions. (This tests
175 the individual funcitons and avoids writing another parser, so it's not pretty.)
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500176
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400177 mse | 0 | 0 | yahoo.com:4561,localhost:4562
178 mse | 1 | 0 | localhost:4560,localhost:4568,localhost:4569; localhost:4561,localhost:4562
179 mse | 2 | 0 | localhost:4563,localhost:4564
180 mse | 3 | 0 | localhost:4565
181 mse | 3 | 11 | locahost:5511
182 mse | 3 | -1 | localhost:5500
183 */
184 gcounts[0] = 1; // first entry has 1 group with 2 endpoints; message type 0, sid 0
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000185 ecounts[0] = 2;
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400186 mtypes[0] = build_key( 0, 0 ); // mtype is now a key of mtype/sid
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000187 entries[enu].group = 0; entries[enu].ep_name = "yahoo.com:4561"; enu++; // use a dns resolvable name to test that
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400188 entries[enu].group = 0; entries[enu].ep_name = "localhost:4562"; enu++; // rest can default to some dummy ip
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000189
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400190 gcounts[1] = 2; // 2 groups
191 ecounts[1] = 3; // first has 3 endpoints
192 mtypes[1] = build_key( 1, 0 );
193 entries[enu].group = 0; entries[enu].ep_name = "localhost:4560"; enu++;
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000194 entries[enu].group = 0; entries[enu].ep_name = "localhost:4568"; enu++;
195 entries[enu].group = 0; entries[enu].ep_name = "localhost:4569"; enu++;
196
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400197 gcounts[2] = 0; // 0 means use same rte, this is the next group for the entry
198 ecounts[2] = 2; // 2 endpoints
199 mtypes[2] = 999; // ignored when appending to previous entry
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000200 entries[enu].group = 1; entries[enu].ep_name = "localhost:4561"; enu++;
201 entries[enu].group = 1; entries[enu].ep_name = "localhost:4562"; enu++;
202
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400203 gcounts[3] = 1; // next entry has 1 group
204 ecounts[3] = 2; // with 2 enpoints
205 mtypes[3] = build_key( 2, 0 );
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000206 entries[enu].group = 0; entries[enu].ep_name = "localhost:4563"; enu++;
207 entries[enu].group = 0; entries[enu].ep_name = "localhost:4564"; enu++;
208
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400209 gcounts[4] = 1; // three entries for mt==3 with different sids
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000210 ecounts[4] = 1;
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400211 mtypes[4] = build_key( 3, 0 );
212 entries[enu].group = 0; entries[enu].ep_name = "localhost:5500"; enu++;
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000213
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400214 gcounts[5] = 1;
215 ecounts[5] = 1;
216 mtypes[5] = build_key( 3, 11 );
217 entries[enu].group = 0; entries[enu].ep_name = "localhost:5511"; enu++;
218
219 gcounts[6] = 1;
220 ecounts[6] = 1;
221 mtypes[6] = build_key( 3, -1 );
222 entries[enu].group = 0; entries[enu].ep_name = "localhost:5512"; enu++;
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000223
224
E. Scott Daniels5ec64c52020-11-05 09:11:04 -0500225 rt = uta_rt_init( NULL );
226 errors += fail_if_false( rt == NULL, "rt_init given a nil context didn't return nil" );
227
228 ctx = mk_dummy_ctx(); // make a dummy with rtgate mutex
229 rt = uta_rt_init( ctx ); // get us a route table
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000230 if( (errors += fail_if_nil( rt, "pointer to route table" )) ) {
231 fprintf( stderr, "<FAIL> abort: cannot continue without a route table\n" );
232 exit( 1 );
233 }
234
235 enu = 0;
236 rte = NULL;
237 for( i = 0; i < sizeof( gcounts )/sizeof( int ); i++ ) { // add entries defined above
238 if( gcounts[i] ) {
239 rte = uta_add_rte( rt, mtypes[i], gcounts[i] ); // get/create entry for message type
240 if( (errors += fail_if_nil( rte, "route table entry" )) ) {
241 fprintf( stderr, "<FAIL> abort: cannot continue without a route table entry\n" );
242 exit( 1 );
243 }
244 } else {
245 if( rte == NULL ) {
246 fprintf( stderr, "<SNAFU> internal testing error -- rte was nil for gcount == 0\n" );
247 exit( 1 );
248 }
249 }
250
251 for( k = 0; k < ecounts[i]; k++ ) {
252 ep = uta_add_ep( rt, rte, entries[enu].ep_name, entries[enu].group );
253 errors += fail_if_nil( ep, "endpoint" );
254 enu++;
255 }
256 }
257
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400258 // ----- end hacking together a route table ---------------------------------------------------
259
260
E. Scott Daniels5ec64c52020-11-05 09:11:04 -0500261 crt = uta_rt_clone( ctx, rt, NULL, 0 ); // create a new rt and clone only the me entries
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000262 errors += fail_if_nil( crt, "cloned route table" );
E. Scott Daniels3376a212019-05-14 14:14:20 +0000263 if( crt ) {
264 c1 = count_entries( rt, 1 );
265 c2 = count_entries( crt, 1 );
266 errors += fail_not_equal( c1, c2, "cloned (endpoints) table entries space 1 count (b) did not match original table count (a)" );
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500267
E. Scott Daniels3376a212019-05-14 14:14:20 +0000268 c2 = count_entries( crt, 0 );
269 errors += fail_not_equal( c2, 0, "cloned (endpoints) table entries space 0 count (a) was not zero as expected" );
E. Scott Daniels5ec64c52020-11-05 09:11:04 -0500270
271 errors += fail_if_false( crt->ephash == rt->ephash, "ephash pointer in cloned table is not right" );
E. Scott Daniels3376a212019-05-14 14:14:20 +0000272 uta_rt_drop( crt );
273 }
274
275
E. Scott Daniels5ec64c52020-11-05 09:11:04 -0500276 crt = uta_rt_clone( ctx, rt, NULL, 1 ); // clone all entries (MT and ME)
277 errors += fail_if_nil( crt, "cloned (all) route table" );
E. Scott Daniels3376a212019-05-14 14:14:20 +0000278
279 if( crt ) {
280 c1 = count_entries( rt, 0 );
281 c2 = count_entries( crt, 0 );
282 errors += fail_not_equal( c1, c2, "cloned (all) table entries space 0 count (b) did not match original table count (a)" );
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500283
E. Scott Daniels3376a212019-05-14 14:14:20 +0000284 c1 = count_entries( rt, 1 );
285 c2 = count_entries( crt, 1 );
286 errors += fail_not_equal( c1, c2, "cloned (all) table entries space 1 count (b) did not match original table count (a)" );
E. Scott Daniels5ec64c52020-11-05 09:11:04 -0500287
288 errors += fail_if_false( crt->ephash == rt->ephash, "ephash pointer in cloned table (all) is not right" );
E. Scott Daniels3376a212019-05-14 14:14:20 +0000289 uta_rt_drop( crt );
290 }
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500291
292 #ifdef NNG_UNDER_TEST
293 if( (ctx = (uta_ctx_t *) malloc( sizeof( uta_ctx_t ) )) != NULL ) { // get a "context" needed for si testing
294 memset( ctx, 0, sizeof( *ctx ) );
295 ctx->rtable = rt;
296 } else {
297 fprintf( stderr, "<FAIL> cannot acllocate a context, cannot continue rtable tests\n" );
298 return errors;
299 }
300 #else
301 ctx = mk_dummy_ctx();
302 #endif
303
304 ctx->rtable = rt;
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000305
306 ep = uta_get_ep( rt, "localhost:4561" );
307 errors += fail_if_nil( ep, "end point (fetch by name)" );
308 ep = uta_get_ep( rt, "bad_name:4560" );
309 errors += fail_not_nil( ep, "end point (fetch by name with bad name)" );
310
E. Scott Daniels58ccd682019-10-02 10:21:24 -0400311 ep = NULL;
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500312 #ifdef NNG_UNDER_TEST
313 state = uta_epsock_byname( rt, "localhost:4561", &nn_sock, &ep ); // this should be found
314 #else
E. Scott Daniels5ec64c52020-11-05 09:11:04 -0500315 state = uta_epsock_byname( ctx, "localhost:4561", &nn_sock, &ep ); // this should be found
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500316 #endif
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000317 errors += fail_if_equal( state, 0, "socket (by name)" );
E. Scott Daniels58ccd682019-10-02 10:21:24 -0400318 errors += fail_if_nil( ep, "epsock_byname did not populate endpoint pointer when expected to" );
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000319 //alt_value = uta_epsock_byname( rt, "localhost:4562" ); // we might do a memcmp on the two structs, but for now nothing
320 //errors += fail_if_equal( value, alt_value, "app1/app2 sockets" );
321
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500322 #if NNG_UNDER_TEST
323 state = uta_epsock_byname( NULL, "localhost:4561", &nn_sock, &ep ); // test coverage on nil checks
324 #else
325 state = uta_epsock_byname( NULL, "localhost:4561", &nn_sock, &ep );
E. Scott Daniels353bafb2020-11-12 16:44:34 -0500326 errors += fail_not_equal( state, 0, "socket (by name) nil context check returned true" );
327
328 p = ctx->si_ctx;
329 ctx->si_ctx = NULL; // set to drive second test
330 state = uta_epsock_byname( ctx, "localhost:4561", &nn_sock, &ep );
331 ctx->si_ctx = p;
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500332 #endif
333 errors += fail_not_equal( state, 0, "socket (by name) nil check returned true" );
334
E. Scott Daniels5ec64c52020-11-05 09:11:04 -0500335 if( ep ) { // if previous test fails, cant run this
336 ep->open = 1;
337 #if NNG_UNDER_TEST
338 state = uta_epsock_byname( rt, "localhost:4561", &nn_sock, NULL ); // test coverage on nil checks
339 #else
340 state = uta_epsock_byname( ctx, "localhost:4561", &nn_sock, NULL );
341 #endif
342 errors += fail_if_equal( state, 0, "socket (by name) open ep check returned false" );
343 }
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500344
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400345
346 // --- test that the get_rte function finds expected keys, and retries to find 'bad' sid attempts for valid mtypes with no sid
347 rte = uta_get_rte( rt, 0, 1, TRUE ); // s=0 m=1 is defined, so this should return a pointer
348 errors += fail_if_nil( rte, "get_rte did not return a pointer when s=0 m=1 true given" );
349
350 rte = uta_get_rte( rt, 0, 1, FALSE ); // the retry shouldn't apply, but ensure it does the righ thing
351 errors += fail_if_nil( rte, "get_rte did not return a pointer when s=0 m=1 false given" );
352
353 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
354 errors += fail_not_nil( rte, "get_rte returned a pointer when s=1000 m=1 false given" );
355
356 rte = uta_get_rte( rt, 1000, 1, TRUE ); // this should also fail as there is no mt==1 sid==-1 defined
357 errors += fail_not_nil( rte, "get_rte returned a pointer when s=1000 m=1 true given" );
358
359 rte = uta_get_rte( rt, 0, 3, TRUE ); // mtype sid combo does exist; true/false should not matter
360 errors += fail_if_nil( rte, "get_rte did not return a pointer when s=0 m=3 true given" );
361
362 rte2 = uta_get_rte( rt, 11, 3, TRUE ); // same mtype as before, different (valid) group, rte should be different than before
363 errors += fail_if_nil( rte2, "get_rte did not return a pointer when s=11 m=3 true given" );
364 errors += fail_if_true( rte == rte2, "get_rte for mtype==3 and different sids (0 and 11) returned the same rte pointer" );
365
366 rte2 = uta_get_rte( rt, 0, 3, FALSE ); // since the mtype/sid combo exists, setting false should return the same as before
367 errors += fail_if_nil( rte2, "get_rte did not return a pointer when s=0 m=3 false given" );
368 errors += fail_if_false( rte == rte2, "get_rte did not return same pointer when mtype/sid combo given with different true/false" );
369
370 rte = uta_get_rte( rt, 12, 3, FALSE ); // this combo does not exist and should fail when alt-key is not allowed (false)
371 errors += fail_not_nil( rte, "get_rte returned a pointer for s=12, m=3, false" );
372
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500373 rte = uta_get_rte( rt, 12, 3, TRUE ); // this should return the entry for the 3/-1 combination
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400374 errors += fail_if_nil( rte, "get_rte did not return a pointer for s=12, m=3, true" );
375
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500376
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000377 alt_value = -1;
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400378 rte = uta_get_rte( rt, 0, 1, FALSE ); // get an rte for the next loop
379 if( rte ) {
380 for( i = 0; i < 10; i++ ) { // round robin return value should be different each time
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500381 #ifdef NNG_UNDER_TEST
382 value = uta_epsock_rr( rte, 0, &more, &nn_sock, &ep ); // msg type 1, group 1
383 #else
384 value = uta_epsock_rr( ctx, rte, 0, &more, &nn_sock, &ep );
385 #endif
386
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400387 errors += fail_if_equal( value, alt_value, "round robiin sockets with multiple end points" );
388 errors += fail_if_false( more, "more for mtype==1" );
389 alt_value = value;
390 }
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000391 }
392
393 more = -1;
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400394 rte = uta_get_rte( rt, 0, 3, FALSE ); // get an rte for the next loop
395 if( rte ) {
396 for( i = 0; i < 10; i++ ) { // this mtype has only one endpoint, so rr should be same each time
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500397 #ifdef NNG_UNDER_TEST
398 value = uta_epsock_rr( rte, 0, NULL, &nn_sock, &ep ); // also test ability to deal properly with nil more pointer
399 #else
400 value = uta_epsock_rr( ctx, rte, 0, NULL, &nn_sock, &ep );
401 #endif
402
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400403 if( i ) {
404 errors += fail_not_equal( value, alt_value, "round robin sockets with one endpoint" );
405 errors += fail_not_equal( more, -1, "more value changed in single group instance" );
406 }
407 alt_value = value;
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000408 }
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000409 }
410
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400411 rte = uta_get_rte( rt, 11, 3, TRUE );
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500412 #ifdef NNG_UNDER_TEST
413 state = uta_epsock_rr( rte, 22, NULL, NULL, &ep );
414 #else
415 state = uta_epsock_rr( ctx, rte, 22, NULL, NULL, &ep );
416 #endif
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400417 errors += fail_if_true( state, "uta_epsock_rr returned bad (non-zero) state when given nil socket pointer" );
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000418
E. Scott Daniels0b79fc22019-12-04 15:20:16 -0500419
E. Scott Daniels5ec64c52020-11-05 09:11:04 -0500420 uta_rt_clone( ctx, NULL, NULL, 0 ); // verify null parms don't crash things
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000421 uta_rt_drop( NULL );
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500422 #ifdef NNG_UNDER_TEST
423 uta_epsock_rr( NULL, 0, &more, &nn_sock, &ep ); // drive null case for coverage
424 state = uta_epsock_rr( rte, 22, NULL, NULL, &ep );
425 #else
426 state = uta_epsock_rr( NULL, NULL, 0, &more, &nn_sock, &ep ); // drive null case for coverage
427 errors += fail_not_equal( state, 0, "uta_epsock_rr did not return false when given nil ctx" );
428
429 state = uta_epsock_rr( ctx, NULL, 0, &more, &nn_sock, &ep );
430 errors += fail_not_equal( state, 0, "uta_epsock_rr did not return false when given nil rte" );
431
432 state = uta_epsock_rr( ctx, rte, 10000, &more, &nn_sock, &ep );
433 errors += fail_not_equal( state, 0, "uta_epsock_rr did not return false when given invalid group number" );
434 #endif
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000435 uta_add_rte( NULL, 99, 1 );
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400436 uta_get_rte( NULL, 0, 1000, TRUE );
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000437
438 fprintf( stderr, "[INFO] test: adding end points with nil data; warnings expected\n" );
439 uta_add_ep( NULL, NULL, "foo", 1 );
440 uta_add_ep( rt, NULL, "foo", 1 );
441
442 buf = uta_fib( ".gitignore" );
443 errors += fail_if_nil( buf, "buffer from read file into buffer" );
444 if( buf ) {
445 free( buf );
446 }
447 buf = uta_fib( "no-file" );
448 errors += fail_if_nil( buf, "buffer from read file into buffer (no file)" );
449 if( buf ) {
450 free( buf );
451 }
452
E. Scott Daniels05850e02020-11-11 15:57:22 -0500453 fprintf( stderr, "<INFO> test is overtly dropping rt table at %p\n", rt );
454 ctx->rtable = NULL;
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000455 uta_rt_drop( rt );
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400456 rt = NULL;
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000457
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000458
E. Scott Daniels05850e02020-11-11 15:57:22 -0500459 // --- force the load of a RT which has some edge case forcing issues
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500460 if( ctx ) {
E. Scott Daniels05850e02020-11-11 15:57:22 -0500461 char* rt_stuff =
462 "newrt | start | dummy-seed\n"
463 "mse | 1 | -1 | localhost:84306\n"
464 "mse | 10 | -1 | localhost:84306\n"
465 "mse | 10 | 1 | localhost:84306\n"
466 "# should cause failure because there aren't 10 entries above\n"
467 "newrt | end | 10\n"
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400468
E. Scott Daniels05850e02020-11-11 15:57:22 -0500469 "# this table has no end\n"
470 "newrt | start | dummy-seed\n"
471 "mse | 1 | -1 | localhost:84306\n"
472 "mse | 10 | -1 | localhost:84306\n"
473 "mse | 10 | 1 | localhost:84306\n"
E. Scott Daniels05850e02020-11-11 15:57:22 -0500474
475 "# this table should be ok\n"
476 "newrt | start | dummy-seed\n"
477 "mse | 1 | -1 | localhost:84306\n"
478 "mse | 10 | -1 | localhost:84306\n"
479 "mse | 10 | 1 | localhost:84306\n"
480 "newrt | end | 3\n"
481
482 "# for an update to the existing table\n"
E. Scott Daniels05850e02020-11-11 15:57:22 -0500483 "# not in progress; drive that exception check\n"
484 "update | end | 23\n"
485
486 "update | start | dummy-seed\n"
E. Scott Daniels353bafb2020-11-12 16:44:34 -0500487 "mse | 3 | 2 | localhost:2222\n"
488 "# short record to drive test\n"
489 "del\n"
E. Scott Daniels05850e02020-11-11 15:57:22 -0500490 "# no table end for exception handling\n"
491
492 "update | start | dummy-seed\n"
493 "mse | 2 | 2 | localhost:2222\n"
E. Scott Daniels353bafb2020-11-12 16:44:34 -0500494 "del | 10 | 1\n"
495 "update | end | 2\n";
E. Scott Daniels05850e02020-11-11 15:57:22 -0500496
497 fprintf( stderr, "<INFO> loading RT from edge case static table\n" );
498 fprintf( stderr, "<INFO> %s\n", rt_stuff );
499 gen_custom_rt( ctx, rt_stuff );
E. Scott Daniels353bafb2020-11-12 16:44:34 -0500500 fprintf( stderr, "<INFO> edge case load completed\n" );
E. Scott Daniels05850e02020-11-11 15:57:22 -0500501 errors += fail_if_nil( ctx->rtable, "edge case route table didn't generate a pointer into the context" );
502
503 unsetenv( "RMR_SEED_RT" ); // remove for next read try
E. Scott Danielsc8e651e2021-04-09 08:40:20 -0400504 if( ctx && ctx->seed_rt_fname != NULL ) {
505 free( ctx->seed_rt_fname );
506 ctx->seed_rt_fname = NULL;
507 }
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400508 read_static_rt( ctx, 0 ); // drive for not there coverage
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000509 }
510
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400511
512 buf = uta_fib( "no-suhch-file" ); // drive some error checking for coverage
513 if( buf ) {
514 free( buf );
515 }
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000516
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000517
E. Scott Daniels412d53d2019-05-20 20:00:52 +0000518 ep = (endpoint_t *) malloc( sizeof( *ep ) );
E. Scott Daniels9c923bc2020-08-03 09:22:20 -0400519 memset( ep, 0, sizeof( ep ) );
E. Scott Daniels412d53d2019-05-20 20:00:52 +0000520 pthread_mutex_init( &ep->gate, NULL );
521 ep->name = strdup( "worm" );
522 ep->addr = NULL;
E. Scott Daniels9c923bc2020-08-03 09:22:20 -0400523 ep->notify = 1;
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500524 #ifdef NNG_UNDER_TEST
525 state = uta_link2( ep );
526 #else
527 state = uta_link2( ctx, ep );
528 #endif
529 errors += fail_if_true( state, "link2 did not return false when given a bad target name" );
530
531 #ifdef NNG_UNDER_TEST
532 state = uta_link2( NULL );
533 #else
534 state = uta_link2( ctx, NULL );
535 errors += fail_if_true( state, "link2 did not return false when given nil ep pointer" );
536
537 state = uta_link2( NULL, ep );
538 #endif
539 errors += fail_if_true( state, "link2 did not return false when given nil pointer" );
540
541 ep->name = strdup( "localhost:5512" );
542 ep->open = 1;
543 #ifdef NNG_UNDER_TEST
544 state = uta_link2( ep ); // drive for coverage
545 #else
546 state = uta_link2( ctx, ep );
547 #endif
548 errors += fail_if_false( state, "link2 did returned false when given open ep" );
549
550 #ifndef NNG_UNDER_TEST
551 ep->open = 0; // context is used only if ep not open, so to check this test close the ep
E. Scott Daniels9c923bc2020-08-03 09:22:20 -0400552 ep->notify = 1;
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500553 state = rt_link2_ep( NULL, ep );
554 errors += fail_if_true( state, "rt_link2_ep returned true when given bad context" );
555
556 state = rt_link2_ep( ctx, NULL );
557 errors += fail_if_true( state, "rt_link2_ep returned true when given bad ep" );
558
559 ep->open = 1;
560 state = rt_link2_ep( ctx, ep );
561 errors += fail_if_false( state, "rt_link2_ep returned false when given an open ep" );
562
563 ep->open = 0;
564 state = rt_link2_ep( ctx, ep );
565 errors += fail_if_false( state, "rt_link2_ep returned false when given a closed ep" );
566
567 ep->open = 1;
568 uta_ep_failed( ep );
569 errors += fail_if_true( ep->open, "uta_ep_failed didn't set open flag to false" );
570
571 #endif
572
E. Scott Daniels5efb1e62019-05-02 17:09:35 +0000573
E. Scott Daniels0b79fc22019-12-04 15:20:16 -0500574 // ----------------- test the meid support for looking up an endpoint based on the meid in the message -----
575
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500576 ctx->rtable = NULL;
E. Scott Daniels0b79fc22019-12-04 15:20:16 -0500577 ctx->my_name = strdup( "my_host_name" ); // set up to load a rtable
578 ctx->my_ip = strdup( "192.168.1.30" );
E. Scott Danielsc8e651e2021-04-09 08:40:20 -0400579 if( ctx && ctx->seed_rt_fname != NULL ) {
580 free( ctx->seed_rt_fname );
581 ctx->seed_rt_fname = NULL;
582 }
E. Scott Daniels0b79fc22019-12-04 15:20:16 -0500583 gen_rt( ctx ); // generate a route table with meid entries and hang off ctx
584
585 mbuf = rmr_alloc_msg( ctx, 2048 ); // buffer to play with
586 mbuf->len = 100;
587 rmr_str2meid( mbuf, "meid1" ); // id that we know is in the map
588
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500589 #ifdef NNG_UNDER_TEST
590 ep = NULL; // force to nil so we see it go non-nil
591 state = epsock_meid( ctx->rtable, mbuf, &nn_sock, &ep );
592 errors += fail_if_nil( ep, "ep was nil when looking up ep with known meid in message" );
593 errors += fail_not_equal( state, 1, "state was not true when looking up ep with known meid in message" );
E. Scott Daniels0b79fc22019-12-04 15:20:16 -0500594
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500595 rmr_str2meid( mbuf, "XXXmeid1" ); // id that we know is NOT in the map
596 state = epsock_meid( ctx->rtable, mbuf, &nn_sock, &ep );
597 // it is NOT a valid check to test ep for nil -- epsock_mied doesn't guarentee ep is set/cleared when state is false
598 errors += fail_not_equal( state, 0, "state was not false when looking up ep with unknown meid in message" );
599 #else
600 ep = NULL; // force to nil so we see it go non-nil
601 state = epsock_meid( ctx, ctx->rtable, mbuf, &nn_sock, &ep );
602 errors += fail_if_nil( ep, "ep was nil when looking up ep with known meid in message" );
603 errors += fail_not_equal( state, 1, "state was not true when looking up ep with known meid in message" );
604
605 state = epsock_meid( ctx, ctx->rtable, mbuf, &nn_sock, &ep ); // a second call to drive open == true check for coverage
606 errors += fail_if_nil( ep, "ep was nil when looking up ep with known meid in message; on open ep" );
607 errors += fail_not_equal( state, 1, "state was not true when looking up ep with known meid in message; on open ep" );
608
609 rmr_str2meid( mbuf, "XXXmeid1" ); // id that we know is NOT in the map
610 state = epsock_meid( ctx, ctx->rtable, mbuf, &nn_sock, &ep );
611 // it is NOT a valid check to test ep for nil -- epsock_mied doesn't guarentee ep is set/cleared when state is false
612 errors += fail_not_equal( state, 0, "state was not false when looking up ep with unknown meid in message" );
613
614 state = epsock_meid( NULL, ctx->rtable, mbuf, &nn_sock, &ep );
615 errors += fail_not_equal( state, 0, "epsock_meid returned true when given nil context" );
616
617 state = epsock_meid( ctx, ctx->rtable, mbuf, NULL, &ep );
618 errors += fail_not_equal( state, 0, "epsock_meid returned true when given nil socket pointer" );
619 #endif
620
E. Scott Danielsfc2112d2020-04-21 12:51:05 -0400621 // ------------ debugging and such; coverage only calls ----------------------------------------------------------
622 ep_stats( ctx->rtable, NULL, "name", NULL, NULL ); // ensure no crash when given nil pointer
623 rt_epcounts( ctx->rtable, "testing" );
624 rt_epcounts( NULL, "testing" );
625
E. Scott Danielsfcea3952020-10-30 15:04:16 -0400626 buf = ensure_nlterm( NULL );
627 errors += fail_if_nil( buf, "ensure nlterm returned null pointer when given nil ptr" );
628 if( buf ) {
629 errors += fail_not_equal( strlen( buf ), 1, "ensure nlterm returned incorrect length string when given nil pointer" );
630 free( buf );
631 }
632
633 buf = ensure_nlterm( strdup( "x" ) ); // should return "x\n"
634 errors += fail_if_nil( buf, "ensure nlterm returned null pointer when given single char string" );
635 if( buf ) {
636 errors += fail_not_equal( strlen( buf ), 2, "ensure nlterm returned incorrect length string when given single char string" );
637 free( buf );
638 }
639
640 buf = strdup( "x\n" );
641 buf2 = ensure_nlterm( buf ); // buffer returned should be the same
642 if( fail_not_pequal( buf, buf2, "ensure nlterm returned new buffer for one char string with newline" ) ) {
643 errors++;
644 free( buf2 );
645 }
646 free( buf );
647
648 buf = strdup( "Missing our trips to Gloria's for papossas.\n" );
649 buf2 = ensure_nlterm( buf ); // buffer returned should be the same
650 if( fail_not_pequal( buf, buf2, "ensure nlterm returned new buffer for string with newline" ) ) {
651 errors++;
652 free( buf2 );
653 }
654 free( buf );
655
E. Scott Danielsfc2112d2020-04-21 12:51:05 -0400656 buf = ensure_nlterm( strdup( "Stand up and cheer!" ) ); // force addition of newline
657 if( buf ) {
658 errors += fail_not_equal( strcmp( buf, "Stand up and cheer!\n" ), 0, "ensure nlterm didn't add newline" );
659 free( buf );
660 buf = NULL;
661 }
662
663
664 // ------------- route manager request/response funcitons -------------------------------------------------------
665 {
666 rmr_mbuf_t* smsg;
667
668 smsg = rmr_alloc_msg( ctx, 1024 );
669 send_rt_ack( ctx, smsg, "123456", 0, "no reason" );
670
671 pctx = mk_dummy_ctx();
672 ctx->rtg_whid = -1;
673 state = send_update_req( pctx, ctx );
674 errors += fail_not_equal( state, 0, "send_update_req did not return 0" );
675
676 ctx->rtg_whid = rmr_wh_open( ctx, "localhost:19289" );
677 state = send_update_req( pctx, ctx );
678 errors += fail_if_equal( state, 0, "send_update_req to an open whid did not return 0" );
679 }
680
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500681
682 // ------------- si only; fd to ep conversion functions ---------------------------------------------------------
683 #ifndef NNG_UNDER_TEST
684 ep2 = (endpoint_t *) malloc( sizeof( *ep ) );
685
686 fd2ep_init( ctx );
687 fd2ep_add( ctx, 10, ep2 );
688
689 ep = fd2ep_get( ctx, 10 );
690 errors += fail_if_nil( ep, "fd2ep did not return pointer for known mapping" );
691 errors += fail_if_false( ep == ep2, "fd2ep did not return same pointer that was added" );
692
693 ep = fd2ep_get( ctx, 20 );
694 errors += fail_not_nil( ep, "fd2ep did returned a pointer for unknown mapping" );
695
696 ep = fd2ep_del( ctx, 10 );
697 errors += fail_if_nil( ep, "fd2ep delete did not return pointer for known mapping" );
698 errors += fail_if_false( ep == ep2, "fd2ep delete did not return same pointer that was added" );
699
700 ep = fd2ep_del( ctx, 20 );
701 errors += fail_not_nil( ep, "fd2ep delete returned a pointer for unknown mapping" );
702 #endif
E. Scott Danielsa41c6f52019-04-23 18:24:25 +0000703
E. Scott Daniels05850e02020-11-11 15:57:22 -0500704 // ---------------- misc coverage tests --------------------------------------------------------------------------
E. Scott Daniels84423e62020-12-04 13:04:29 -0500705 collect_things( NULL, NULL, NULL, NULL, NULL ); // these both return null, these test NP checks
706 collect_things( NULL, NULL, NULL, NULL, (void *) 1234 ); // the last is an invalid pointer, but check needed to force check on previous param
707 del_rte( NULL, NULL, NULL, NULL, NULL );
708
709 ctx = mk_dummy_ctx();
710 roll_tables( ctx ); // drive nil rt check
711
712
713
714 // ------ specific edge case tests -------------------------------------------------------------------------------
715 errors += lg_clone_test( );
E. Scott Daniels05850e02020-11-11 15:57:22 -0500716
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000717 return !!errors; // 1 or 0 regardless of count
718}