blob: 8bd91df44492c97d1b7fe61f3bb6922909aee4c1 [file] [log] [blame]
E. Scott Daniels8dd46412019-04-16 20:47:54 +00001// : vi ts=4 sw=4 noet :
2/*
3==================================================================================
E. Scott Daniels5efb1e62019-05-02 17:09:35 +00004 Copyright (c) 2019 Nokia
E. Scott Daniels8790bf02019-04-23 12:59:28 +00005 Copyright (c) 2018-2019 AT&T Intellectual Property.
E. Scott Daniels8dd46412019-04-16 20:47:54 +00006
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
10
E. Scott Daniels8790bf02019-04-23 12:59:28 +000011 http://www.apache.org/licenses/LICENSE-2.0
E. Scott Daniels8dd46412019-04-16 20:47:54 +000012
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==================================================================================
19*/
20
21/*
22 Mmemonic: rt_static_test.c
23 Abstract: Test the route table funcitons. These are meant to be included at compile
E. Scott Daniels5efb1e62019-05-02 17:09:35 +000024 time by the test driver.
E. Scott Daniels8dd46412019-04-16 20:47:54 +000025
26 Author: E. Scott Daniels
27 Date: 3 April 2019
28*/
29
30#include <unistd.h>
31#include <stdio.h>
32#include <stdlib.h>
33#include <strings.h>
34#include <errno.h>
35#include <string.h>
36#include <stdint.h>
E. Scott Daniels412d53d2019-05-20 20:00:52 +000037#include <pthread.h>
38#include <semaphore.h>
E. Scott Daniels8dd46412019-04-16 20:47:54 +000039
E. Scott Daniels412d53d2019-05-20 20:00:52 +000040#include "rmr.h"
41#include "rmr_agnostic.h"
E. Scott Daniels8dd46412019-04-16 20:47:54 +000042
43typedef struct entry_info {
44 int group;
45 char* ep_name;
46} ei_t;
47
48
49/*
E. Scott Daniels3376a212019-05-14 14:14:20 +000050 Driven by symtab foreach element of one space.
51 We count using the data as a counter.
52*/
53static void count_things( void* st, void* entry, char const* name, void* thing, void* vdata ) {
54 int* counter;
55
56 if( thing ) {
57 if( (counter = (int *) vdata) != NULL ) {
58 *counter++;
59 }
60 }
61}
62
63/*
64 Returns the number of entries in the table for the given class.
65*/
66static int count_entries( route_table_t* rt, int class ) {
67 int counter = 0;
68
69 if( ! rt ) {
70 return 0;
71 }
72 if( !rt->hash ) {
73 return 0;
74 }
75
76 rmr_sym_foreach_class( rt->hash, class, count_things, &counter ); // run each and update counter
77
78 return counter;
79}
80
81/*
E. Scott Daniels6511ac72019-08-27 10:17:21 -040082 Builds a route table key.
83*/
84static uint64_t build_key( uint32_t mtype, uint32_t sid ) {
85 uint64_t k;
86
87 k = (uint64_t) sid << 32;
88 k += mtype;
89
90fprintf( stderr, "<INFO> build key: %x %x --> %llx\n", (int) mtype, (int) sid, (long long) k );
91 return k;
92}
93
94/*
E. Scott Daniels8dd46412019-04-16 20:47:54 +000095 This is the main route table test. It sets up a very specific table
96 for testing (not via the generic setup function for other test
97 situations).
98*/
99static int rt_test( ) {
100 uta_ctx_t* ctx; // context needed to test load static rt
E. Scott Danielsfc2112d2020-04-21 12:51:05 -0400101 uta_ctx_t* pctx; // "private" context for route manager communication tests
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000102 route_table_t* rt; // route table
103 route_table_t* crt; // cloned route table
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400104 rtable_ent_t* rte; // route table entries from table
105 rtable_ent_t* rte2;
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000106 endpoint_t* ep; // endpoint added
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500107 endpoint_t* ep2;
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000108 int more = 0; // more flag from round robin
109 int errors = 0; // number errors found
110 int i;
111 int k;
E. Scott Daniels3376a212019-05-14 14:14:20 +0000112 int c1; // general counters
113 int c2;
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000114 int mtype;
115 int value;
116 int alt_value;
117 ei_t entries[50]; // end point information
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400118 int gcounts[7]; // number of groups in this set
119 int ecounts[7]; // number of elements per group
120 uint64_t mtypes[7]; // mtype/sid 'key' in the modern RMR world
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000121 char* tok;
122 char* nxt_tok;
123 int enu = 0;
124 int state;
125 char *buf;
E. Scott Danielsfcea3952020-10-30 15:04:16 -0400126 char *buf2;
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000127 char* seed_fname; // seed file
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500128 SOCKET_TYPE nn_sock; // differnt in each transport (nng == struct, SI/Nano == int)
E. Scott Daniels0b79fc22019-12-04 15:20:16 -0500129 rmr_mbuf_t* mbuf; // message for meid route testing
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000130
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500131 #ifndef NNG_UNDER_TEST
132 si_ctx_t* si_ctx = NULL;
133 #endif
134
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000135 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 +0000136 i = open( ".ut_rmr_verbose", O_RDWR | O_CREAT, 0644 );
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000137 if( i >= 0 ) {
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400138 write( i, "2\n", 2 );
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000139 close( i );
140 }
141
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500142
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400143 /*
144 The hacky code below calls the necessary rmr functions to create a route table
145 as though the following were read and parsed by the rmr functions. (This tests
146 the individual funcitons and avoids writing another parser, so it's not pretty.)
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500147
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400148 mse | 0 | 0 | yahoo.com:4561,localhost:4562
149 mse | 1 | 0 | localhost:4560,localhost:4568,localhost:4569; localhost:4561,localhost:4562
150 mse | 2 | 0 | localhost:4563,localhost:4564
151 mse | 3 | 0 | localhost:4565
152 mse | 3 | 11 | locahost:5511
153 mse | 3 | -1 | localhost:5500
154 */
155 gcounts[0] = 1; // first entry has 1 group with 2 endpoints; message type 0, sid 0
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000156 ecounts[0] = 2;
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400157 mtypes[0] = build_key( 0, 0 ); // mtype is now a key of mtype/sid
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000158 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 -0400159 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 +0000160
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400161 gcounts[1] = 2; // 2 groups
162 ecounts[1] = 3; // first has 3 endpoints
163 mtypes[1] = build_key( 1, 0 );
164 entries[enu].group = 0; entries[enu].ep_name = "localhost:4560"; enu++;
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000165 entries[enu].group = 0; entries[enu].ep_name = "localhost:4568"; enu++;
166 entries[enu].group = 0; entries[enu].ep_name = "localhost:4569"; enu++;
167
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400168 gcounts[2] = 0; // 0 means use same rte, this is the next group for the entry
169 ecounts[2] = 2; // 2 endpoints
170 mtypes[2] = 999; // ignored when appending to previous entry
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000171 entries[enu].group = 1; entries[enu].ep_name = "localhost:4561"; enu++;
172 entries[enu].group = 1; entries[enu].ep_name = "localhost:4562"; enu++;
173
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400174 gcounts[3] = 1; // next entry has 1 group
175 ecounts[3] = 2; // with 2 enpoints
176 mtypes[3] = build_key( 2, 0 );
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000177 entries[enu].group = 0; entries[enu].ep_name = "localhost:4563"; enu++;
178 entries[enu].group = 0; entries[enu].ep_name = "localhost:4564"; enu++;
179
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400180 gcounts[4] = 1; // three entries for mt==3 with different sids
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000181 ecounts[4] = 1;
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400182 mtypes[4] = build_key( 3, 0 );
183 entries[enu].group = 0; entries[enu].ep_name = "localhost:5500"; enu++;
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000184
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400185 gcounts[5] = 1;
186 ecounts[5] = 1;
187 mtypes[5] = build_key( 3, 11 );
188 entries[enu].group = 0; entries[enu].ep_name = "localhost:5511"; enu++;
189
190 gcounts[6] = 1;
191 ecounts[6] = 1;
192 mtypes[6] = build_key( 3, -1 );
193 entries[enu].group = 0; entries[enu].ep_name = "localhost:5512"; enu++;
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000194
195
E. Scott Daniels5ec64c52020-11-05 09:11:04 -0500196 rt = uta_rt_init( NULL );
197 errors += fail_if_false( rt == NULL, "rt_init given a nil context didn't return nil" );
198
199 ctx = mk_dummy_ctx(); // make a dummy with rtgate mutex
200 rt = uta_rt_init( ctx ); // get us a route table
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000201 if( (errors += fail_if_nil( rt, "pointer to route table" )) ) {
202 fprintf( stderr, "<FAIL> abort: cannot continue without a route table\n" );
203 exit( 1 );
204 }
205
206 enu = 0;
207 rte = NULL;
208 for( i = 0; i < sizeof( gcounts )/sizeof( int ); i++ ) { // add entries defined above
209 if( gcounts[i] ) {
210 rte = uta_add_rte( rt, mtypes[i], gcounts[i] ); // get/create entry for message type
211 if( (errors += fail_if_nil( rte, "route table entry" )) ) {
212 fprintf( stderr, "<FAIL> abort: cannot continue without a route table entry\n" );
213 exit( 1 );
214 }
215 } else {
216 if( rte == NULL ) {
217 fprintf( stderr, "<SNAFU> internal testing error -- rte was nil for gcount == 0\n" );
218 exit( 1 );
219 }
220 }
221
222 for( k = 0; k < ecounts[i]; k++ ) {
223 ep = uta_add_ep( rt, rte, entries[enu].ep_name, entries[enu].group );
224 errors += fail_if_nil( ep, "endpoint" );
225 enu++;
226 }
227 }
228
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400229 // ----- end hacking together a route table ---------------------------------------------------
230
231
E. Scott Daniels5ec64c52020-11-05 09:11:04 -0500232 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 +0000233 errors += fail_if_nil( crt, "cloned route table" );
E. Scott Daniels3376a212019-05-14 14:14:20 +0000234 if( crt ) {
235 c1 = count_entries( rt, 1 );
236 c2 = count_entries( crt, 1 );
237 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 -0500238
E. Scott Daniels3376a212019-05-14 14:14:20 +0000239 c2 = count_entries( crt, 0 );
240 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 -0500241
242 errors += fail_if_false( crt->ephash == rt->ephash, "ephash pointer in cloned table is not right" );
E. Scott Daniels3376a212019-05-14 14:14:20 +0000243 uta_rt_drop( crt );
244 }
245
246
E. Scott Daniels5ec64c52020-11-05 09:11:04 -0500247 crt = uta_rt_clone( ctx, rt, NULL, 1 ); // clone all entries (MT and ME)
248 errors += fail_if_nil( crt, "cloned (all) route table" );
E. Scott Daniels3376a212019-05-14 14:14:20 +0000249
250 if( crt ) {
251 c1 = count_entries( rt, 0 );
252 c2 = count_entries( crt, 0 );
253 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 -0500254
E. Scott Daniels3376a212019-05-14 14:14:20 +0000255 c1 = count_entries( rt, 1 );
256 c2 = count_entries( crt, 1 );
257 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 -0500258
259 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 +0000260 uta_rt_drop( crt );
261 }
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500262
263 #ifdef NNG_UNDER_TEST
264 if( (ctx = (uta_ctx_t *) malloc( sizeof( uta_ctx_t ) )) != NULL ) { // get a "context" needed for si testing
265 memset( ctx, 0, sizeof( *ctx ) );
266 ctx->rtable = rt;
267 } else {
268 fprintf( stderr, "<FAIL> cannot acllocate a context, cannot continue rtable tests\n" );
269 return errors;
270 }
271 #else
272 ctx = mk_dummy_ctx();
273 #endif
274
275 ctx->rtable = rt;
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000276
277 ep = uta_get_ep( rt, "localhost:4561" );
278 errors += fail_if_nil( ep, "end point (fetch by name)" );
279 ep = uta_get_ep( rt, "bad_name:4560" );
280 errors += fail_not_nil( ep, "end point (fetch by name with bad name)" );
281
E. Scott Daniels58ccd682019-10-02 10:21:24 -0400282 ep = NULL;
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500283 #ifdef NNG_UNDER_TEST
284 state = uta_epsock_byname( rt, "localhost:4561", &nn_sock, &ep ); // this should be found
285 #else
E. Scott Daniels5ec64c52020-11-05 09:11:04 -0500286 state = uta_epsock_byname( ctx, "localhost:4561", &nn_sock, &ep ); // this should be found
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500287 #endif
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000288 errors += fail_if_equal( state, 0, "socket (by name)" );
E. Scott Daniels58ccd682019-10-02 10:21:24 -0400289 errors += fail_if_nil( ep, "epsock_byname did not populate endpoint pointer when expected to" );
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000290 //alt_value = uta_epsock_byname( rt, "localhost:4562" ); // we might do a memcmp on the two structs, but for now nothing
291 //errors += fail_if_equal( value, alt_value, "app1/app2 sockets" );
292
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500293 #if NNG_UNDER_TEST
294 state = uta_epsock_byname( NULL, "localhost:4561", &nn_sock, &ep ); // test coverage on nil checks
295 #else
296 state = uta_epsock_byname( NULL, "localhost:4561", &nn_sock, &ep );
297 #endif
298 errors += fail_not_equal( state, 0, "socket (by name) nil check returned true" );
299
E. Scott Daniels5ec64c52020-11-05 09:11:04 -0500300 if( ep ) { // if previous test fails, cant run this
301 ep->open = 1;
302 #if NNG_UNDER_TEST
303 state = uta_epsock_byname( rt, "localhost:4561", &nn_sock, NULL ); // test coverage on nil checks
304 #else
305 state = uta_epsock_byname( ctx, "localhost:4561", &nn_sock, NULL );
306 #endif
307 errors += fail_if_equal( state, 0, "socket (by name) open ep check returned false" );
308 }
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500309
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400310
311 // --- test that the get_rte function finds expected keys, and retries to find 'bad' sid attempts for valid mtypes with no sid
312 rte = uta_get_rte( rt, 0, 1, TRUE ); // s=0 m=1 is defined, so this should return a pointer
313 errors += fail_if_nil( rte, "get_rte did not return a pointer when s=0 m=1 true given" );
314
315 rte = uta_get_rte( rt, 0, 1, FALSE ); // the retry shouldn't apply, but ensure it does the righ thing
316 errors += fail_if_nil( rte, "get_rte did not return a pointer when s=0 m=1 false given" );
317
318 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
319 errors += fail_not_nil( rte, "get_rte returned a pointer when s=1000 m=1 false given" );
320
321 rte = uta_get_rte( rt, 1000, 1, TRUE ); // this should also fail as there is no mt==1 sid==-1 defined
322 errors += fail_not_nil( rte, "get_rte returned a pointer when s=1000 m=1 true given" );
323
324 rte = uta_get_rte( rt, 0, 3, TRUE ); // mtype sid combo does exist; true/false should not matter
325 errors += fail_if_nil( rte, "get_rte did not return a pointer when s=0 m=3 true given" );
326
327 rte2 = uta_get_rte( rt, 11, 3, TRUE ); // same mtype as before, different (valid) group, rte should be different than before
328 errors += fail_if_nil( rte2, "get_rte did not return a pointer when s=11 m=3 true given" );
329 errors += fail_if_true( rte == rte2, "get_rte for mtype==3 and different sids (0 and 11) returned the same rte pointer" );
330
331 rte2 = uta_get_rte( rt, 0, 3, FALSE ); // since the mtype/sid combo exists, setting false should return the same as before
332 errors += fail_if_nil( rte2, "get_rte did not return a pointer when s=0 m=3 false given" );
333 errors += fail_if_false( rte == rte2, "get_rte did not return same pointer when mtype/sid combo given with different true/false" );
334
335 rte = uta_get_rte( rt, 12, 3, FALSE ); // this combo does not exist and should fail when alt-key is not allowed (false)
336 errors += fail_not_nil( rte, "get_rte returned a pointer for s=12, m=3, false" );
337
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500338 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 -0400339 errors += fail_if_nil( rte, "get_rte did not return a pointer for s=12, m=3, true" );
340
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500341
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000342 alt_value = -1;
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400343 rte = uta_get_rte( rt, 0, 1, FALSE ); // get an rte for the next loop
344 if( rte ) {
345 for( i = 0; i < 10; i++ ) { // round robin return value should be different each time
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500346 #ifdef NNG_UNDER_TEST
347 value = uta_epsock_rr( rte, 0, &more, &nn_sock, &ep ); // msg type 1, group 1
348 #else
349 value = uta_epsock_rr( ctx, rte, 0, &more, &nn_sock, &ep );
350 #endif
351
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400352 errors += fail_if_equal( value, alt_value, "round robiin sockets with multiple end points" );
353 errors += fail_if_false( more, "more for mtype==1" );
354 alt_value = value;
355 }
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000356 }
357
358 more = -1;
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400359 rte = uta_get_rte( rt, 0, 3, FALSE ); // get an rte for the next loop
360 if( rte ) {
361 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 -0500362 #ifdef NNG_UNDER_TEST
363 value = uta_epsock_rr( rte, 0, NULL, &nn_sock, &ep ); // also test ability to deal properly with nil more pointer
364 #else
365 value = uta_epsock_rr( ctx, rte, 0, NULL, &nn_sock, &ep );
366 #endif
367
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400368 if( i ) {
369 errors += fail_not_equal( value, alt_value, "round robin sockets with one endpoint" );
370 errors += fail_not_equal( more, -1, "more value changed in single group instance" );
371 }
372 alt_value = value;
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000373 }
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000374 }
375
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400376 rte = uta_get_rte( rt, 11, 3, TRUE );
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500377 #ifdef NNG_UNDER_TEST
378 state = uta_epsock_rr( rte, 22, NULL, NULL, &ep );
379 #else
380 state = uta_epsock_rr( ctx, rte, 22, NULL, NULL, &ep );
381 #endif
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400382 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 +0000383
E. Scott Daniels0b79fc22019-12-04 15:20:16 -0500384
E. Scott Daniels5ec64c52020-11-05 09:11:04 -0500385 uta_rt_clone( ctx, NULL, NULL, 0 ); // verify null parms don't crash things
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000386 uta_rt_drop( NULL );
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500387 #ifdef NNG_UNDER_TEST
388 uta_epsock_rr( NULL, 0, &more, &nn_sock, &ep ); // drive null case for coverage
389 state = uta_epsock_rr( rte, 22, NULL, NULL, &ep );
390 #else
391 state = uta_epsock_rr( NULL, NULL, 0, &more, &nn_sock, &ep ); // drive null case for coverage
392 errors += fail_not_equal( state, 0, "uta_epsock_rr did not return false when given nil ctx" );
393
394 state = uta_epsock_rr( ctx, NULL, 0, &more, &nn_sock, &ep );
395 errors += fail_not_equal( state, 0, "uta_epsock_rr did not return false when given nil rte" );
396
397 state = uta_epsock_rr( ctx, rte, 10000, &more, &nn_sock, &ep );
398 errors += fail_not_equal( state, 0, "uta_epsock_rr did not return false when given invalid group number" );
399 #endif
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000400 uta_add_rte( NULL, 99, 1 );
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400401 uta_get_rte( NULL, 0, 1000, TRUE );
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000402
403 fprintf( stderr, "[INFO] test: adding end points with nil data; warnings expected\n" );
404 uta_add_ep( NULL, NULL, "foo", 1 );
405 uta_add_ep( rt, NULL, "foo", 1 );
406
407 buf = uta_fib( ".gitignore" );
408 errors += fail_if_nil( buf, "buffer from read file into buffer" );
409 if( buf ) {
410 free( buf );
411 }
412 buf = uta_fib( "no-file" );
413 errors += fail_if_nil( buf, "buffer from read file into buffer (no file)" );
414 if( buf ) {
415 free( buf );
416 }
417
E. Scott Daniels05850e02020-11-11 15:57:22 -0500418 fprintf( stderr, "<INFO> test is overtly dropping rt table at %p\n", rt );
419 ctx->rtable = NULL;
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000420 uta_rt_drop( rt );
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400421 rt = NULL;
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000422
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000423
E. Scott Daniels05850e02020-11-11 15:57:22 -0500424 // --- force the load of a RT which has some edge case forcing issues
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500425 if( ctx ) {
E. Scott Daniels05850e02020-11-11 15:57:22 -0500426 char* rt_stuff =
427 "newrt | start | dummy-seed\n"
428 "mse | 1 | -1 | localhost:84306\n"
429 "mse | 10 | -1 | localhost:84306\n"
430 "mse | 10 | 1 | localhost:84306\n"
431 "# should cause failure because there aren't 10 entries above\n"
432 "newrt | end | 10\n"
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400433
E. Scott Daniels05850e02020-11-11 15:57:22 -0500434 "# this table has no end\n"
435 "newrt | start | dummy-seed\n"
436 "mse | 1 | -1 | localhost:84306\n"
437 "mse | 10 | -1 | localhost:84306\n"
438 "mse | 10 | 1 | localhost:84306\n"
439 "# short record to drive test\n"
440 "del\n"
441 "del | 12 | 12\n"
442
443 "# this table should be ok\n"
444 "newrt | start | dummy-seed\n"
445 "mse | 1 | -1 | localhost:84306\n"
446 "mse | 10 | -1 | localhost:84306\n"
447 "mse | 10 | 1 | localhost:84306\n"
448 "newrt | end | 3\n"
449
450 "# for an update to the existing table\n"
451
452 "# not in progress; drive that exception check\n"
453 "update | end | 23\n"
454
455 "update | start | dummy-seed\n"
456 "mse | 2 | 2 | localhost:2222\n"
457 "# no table end for exception handling\n"
458
459 "update | start | dummy-seed\n"
460 "mse | 2 | 2 | localhost:2222\n"
461 "update | end | 1\n";
462
463 fprintf( stderr, "<INFO> loading RT from edge case static table\n" );
464 fprintf( stderr, "<INFO> %s\n", rt_stuff );
465 gen_custom_rt( ctx, rt_stuff );
466 errors += fail_if_nil( ctx->rtable, "edge case route table didn't generate a pointer into the context" );
467
468 unsetenv( "RMR_SEED_RT" ); // remove for next read try
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400469 read_static_rt( ctx, 0 ); // drive for not there coverage
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000470 }
471
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400472
473 buf = uta_fib( "no-suhch-file" ); // drive some error checking for coverage
474 if( buf ) {
475 free( buf );
476 }
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000477
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000478
E. Scott Daniels412d53d2019-05-20 20:00:52 +0000479 ep = (endpoint_t *) malloc( sizeof( *ep ) );
E. Scott Daniels9c923bc2020-08-03 09:22:20 -0400480 memset( ep, 0, sizeof( ep ) );
E. Scott Daniels412d53d2019-05-20 20:00:52 +0000481 pthread_mutex_init( &ep->gate, NULL );
482 ep->name = strdup( "worm" );
483 ep->addr = NULL;
E. Scott Daniels9c923bc2020-08-03 09:22:20 -0400484 ep->notify = 1;
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500485 #ifdef NNG_UNDER_TEST
486 state = uta_link2( ep );
487 #else
488 state = uta_link2( ctx, ep );
489 #endif
490 errors += fail_if_true( state, "link2 did not return false when given a bad target name" );
491
492 #ifdef NNG_UNDER_TEST
493 state = uta_link2( NULL );
494 #else
495 state = uta_link2( ctx, NULL );
496 errors += fail_if_true( state, "link2 did not return false when given nil ep pointer" );
497
498 state = uta_link2( NULL, ep );
499 #endif
500 errors += fail_if_true( state, "link2 did not return false when given nil pointer" );
501
502 ep->name = strdup( "localhost:5512" );
503 ep->open = 1;
504 #ifdef NNG_UNDER_TEST
505 state = uta_link2( ep ); // drive for coverage
506 #else
507 state = uta_link2( ctx, ep );
508 #endif
509 errors += fail_if_false( state, "link2 did returned false when given open ep" );
510
511 #ifndef NNG_UNDER_TEST
512 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 -0400513 ep->notify = 1;
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500514 state = rt_link2_ep( NULL, ep );
515 errors += fail_if_true( state, "rt_link2_ep returned true when given bad context" );
516
517 state = rt_link2_ep( ctx, NULL );
518 errors += fail_if_true( state, "rt_link2_ep returned true when given bad ep" );
519
520 ep->open = 1;
521 state = rt_link2_ep( ctx, ep );
522 errors += fail_if_false( state, "rt_link2_ep returned false when given an open ep" );
523
524 ep->open = 0;
525 state = rt_link2_ep( ctx, ep );
526 errors += fail_if_false( state, "rt_link2_ep returned false when given a closed ep" );
527
528 ep->open = 1;
529 uta_ep_failed( ep );
530 errors += fail_if_true( ep->open, "uta_ep_failed didn't set open flag to false" );
531
532 #endif
533
E. Scott Daniels5efb1e62019-05-02 17:09:35 +0000534
E. Scott Daniels0b79fc22019-12-04 15:20:16 -0500535 // ----------------- test the meid support for looking up an endpoint based on the meid in the message -----
536
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500537 ctx->rtable = NULL;
E. Scott Daniels0b79fc22019-12-04 15:20:16 -0500538 ctx->my_name = strdup( "my_host_name" ); // set up to load a rtable
539 ctx->my_ip = strdup( "192.168.1.30" );
540 gen_rt( ctx ); // generate a route table with meid entries and hang off ctx
541
542 mbuf = rmr_alloc_msg( ctx, 2048 ); // buffer to play with
543 mbuf->len = 100;
544 rmr_str2meid( mbuf, "meid1" ); // id that we know is in the map
545
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500546 #ifdef NNG_UNDER_TEST
547 ep = NULL; // force to nil so we see it go non-nil
548 state = epsock_meid( ctx->rtable, mbuf, &nn_sock, &ep );
549 errors += fail_if_nil( ep, "ep was nil when looking up ep with known meid in message" );
550 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 -0500551
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500552 rmr_str2meid( mbuf, "XXXmeid1" ); // id that we know is NOT in the map
553 state = epsock_meid( ctx->rtable, mbuf, &nn_sock, &ep );
554 // it is NOT a valid check to test ep for nil -- epsock_mied doesn't guarentee ep is set/cleared when state is false
555 errors += fail_not_equal( state, 0, "state was not false when looking up ep with unknown meid in message" );
556 #else
557 ep = NULL; // force to nil so we see it go non-nil
558 state = epsock_meid( ctx, ctx->rtable, mbuf, &nn_sock, &ep );
559 errors += fail_if_nil( ep, "ep was nil when looking up ep with known meid in message" );
560 errors += fail_not_equal( state, 1, "state was not true when looking up ep with known meid in message" );
561
562 state = epsock_meid( ctx, ctx->rtable, mbuf, &nn_sock, &ep ); // a second call to drive open == true check for coverage
563 errors += fail_if_nil( ep, "ep was nil when looking up ep with known meid in message; on open ep" );
564 errors += fail_not_equal( state, 1, "state was not true when looking up ep with known meid in message; on open ep" );
565
566 rmr_str2meid( mbuf, "XXXmeid1" ); // id that we know is NOT in the map
567 state = epsock_meid( ctx, ctx->rtable, mbuf, &nn_sock, &ep );
568 // it is NOT a valid check to test ep for nil -- epsock_mied doesn't guarentee ep is set/cleared when state is false
569 errors += fail_not_equal( state, 0, "state was not false when looking up ep with unknown meid in message" );
570
571 state = epsock_meid( NULL, ctx->rtable, mbuf, &nn_sock, &ep );
572 errors += fail_not_equal( state, 0, "epsock_meid returned true when given nil context" );
573
574 state = epsock_meid( ctx, ctx->rtable, mbuf, NULL, &ep );
575 errors += fail_not_equal( state, 0, "epsock_meid returned true when given nil socket pointer" );
576 #endif
577
E. Scott Danielsfc2112d2020-04-21 12:51:05 -0400578 // ------------ debugging and such; coverage only calls ----------------------------------------------------------
579 ep_stats( ctx->rtable, NULL, "name", NULL, NULL ); // ensure no crash when given nil pointer
580 rt_epcounts( ctx->rtable, "testing" );
581 rt_epcounts( NULL, "testing" );
582
E. Scott Danielsfcea3952020-10-30 15:04:16 -0400583 buf = ensure_nlterm( NULL );
584 errors += fail_if_nil( buf, "ensure nlterm returned null pointer when given nil ptr" );
585 if( buf ) {
586 errors += fail_not_equal( strlen( buf ), 1, "ensure nlterm returned incorrect length string when given nil pointer" );
587 free( buf );
588 }
589
590 buf = ensure_nlterm( strdup( "x" ) ); // should return "x\n"
591 errors += fail_if_nil( buf, "ensure nlterm returned null pointer when given single char string" );
592 if( buf ) {
593 errors += fail_not_equal( strlen( buf ), 2, "ensure nlterm returned incorrect length string when given single char string" );
594 free( buf );
595 }
596
597 buf = strdup( "x\n" );
598 buf2 = ensure_nlterm( buf ); // buffer returned should be the same
599 if( fail_not_pequal( buf, buf2, "ensure nlterm returned new buffer for one char string with newline" ) ) {
600 errors++;
601 free( buf2 );
602 }
603 free( buf );
604
605 buf = strdup( "Missing our trips to Gloria's for papossas.\n" );
606 buf2 = ensure_nlterm( buf ); // buffer returned should be the same
607 if( fail_not_pequal( buf, buf2, "ensure nlterm returned new buffer for string with newline" ) ) {
608 errors++;
609 free( buf2 );
610 }
611 free( buf );
612
E. Scott Danielsfc2112d2020-04-21 12:51:05 -0400613 buf = ensure_nlterm( strdup( "Stand up and cheer!" ) ); // force addition of newline
614 if( buf ) {
615 errors += fail_not_equal( strcmp( buf, "Stand up and cheer!\n" ), 0, "ensure nlterm didn't add newline" );
616 free( buf );
617 buf = NULL;
618 }
619
620
621 // ------------- route manager request/response funcitons -------------------------------------------------------
622 {
623 rmr_mbuf_t* smsg;
624
625 smsg = rmr_alloc_msg( ctx, 1024 );
626 send_rt_ack( ctx, smsg, "123456", 0, "no reason" );
627
628 pctx = mk_dummy_ctx();
629 ctx->rtg_whid = -1;
630 state = send_update_req( pctx, ctx );
631 errors += fail_not_equal( state, 0, "send_update_req did not return 0" );
632
633 ctx->rtg_whid = rmr_wh_open( ctx, "localhost:19289" );
634 state = send_update_req( pctx, ctx );
635 errors += fail_if_equal( state, 0, "send_update_req to an open whid did not return 0" );
636 }
637
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500638
639 // ------------- si only; fd to ep conversion functions ---------------------------------------------------------
640 #ifndef NNG_UNDER_TEST
641 ep2 = (endpoint_t *) malloc( sizeof( *ep ) );
642
643 fd2ep_init( ctx );
644 fd2ep_add( ctx, 10, ep2 );
645
646 ep = fd2ep_get( ctx, 10 );
647 errors += fail_if_nil( ep, "fd2ep did not return pointer for known mapping" );
648 errors += fail_if_false( ep == ep2, "fd2ep did not return same pointer that was added" );
649
650 ep = fd2ep_get( ctx, 20 );
651 errors += fail_not_nil( ep, "fd2ep did returned a pointer for unknown mapping" );
652
653 ep = fd2ep_del( ctx, 10 );
654 errors += fail_if_nil( ep, "fd2ep delete did not return pointer for known mapping" );
655 errors += fail_if_false( ep == ep2, "fd2ep delete did not return same pointer that was added" );
656
657 ep = fd2ep_del( ctx, 20 );
658 errors += fail_not_nil( ep, "fd2ep delete returned a pointer for unknown mapping" );
659 #endif
E. Scott Danielsa41c6f52019-04-23 18:24:25 +0000660
E. Scott Daniels05850e02020-11-11 15:57:22 -0500661 // ---------------- misc coverage tests --------------------------------------------------------------------------
662 collect_things( NULL, NULL, NULL, NULL, NULL ); // these both return null, these test NP checks
663 collect_things( NULL, NULL, NULL, NULL, (void *) 1234 ); // the last is an invalid pointer, but check needed to force check on previous param
664 del_rte( NULL, NULL, NULL, NULL, NULL );
665
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000666 return !!errors; // 1 or 0 regardless of count
667}