blob: 7a51bca421051f175d858cc8e9e0d58f0fb75613 [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
E. Scott Daniels84423e62020-12-04 13:04:29 -050090 fprintf( stderr, "<INFO> build key: %x %x --> %llx\n", (int) mtype, (int) sid, (long long) k );
E. Scott Daniels6511ac72019-08-27 10:17:21 -040091 return k;
92}
93
94/*
E. Scott Daniels84423e62020-12-04 13:04:29 -050095 Create a very large set of things to clone and ensure that the colleciton
96 buffers are properly resized without errors.
97*/
98static int lg_clone_test( ) {
99 int errors = 0;
100 uta_ctx_t* ctx;
101 char* old_env;
102 route_table_t* p;
103
104 old_env = getenv( "RMR_SEED_RT" );
105 setenv( "RMR_SEED_RT", "./large_meid.rt", 1 );
106
107 ctx = mk_dummy_ctx();
108
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" );
112 if( p != NULL ) {
113 errors += fail_not_equal( p->error, 0, "clone of large table had error" );
114 }
115
116 setenv( "RMR_SEED_RT", old_env, 1 );
117
118 return errors;
119}
120
121/*
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000122 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
124 situations).
125*/
126static int rt_test( ) {
127 uta_ctx_t* ctx; // context needed to test load static rt
E. Scott Danielsfc2112d2020-04-21 12:51:05 -0400128 uta_ctx_t* pctx; // "private" context for route manager communication tests
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000129 route_table_t* rt; // route table
130 route_table_t* crt; // cloned route table
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400131 rtable_ent_t* rte; // route table entries from table
132 rtable_ent_t* rte2;
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000133 endpoint_t* ep; // endpoint added
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500134 endpoint_t* ep2;
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000135 int more = 0; // more flag from round robin
136 int errors = 0; // number errors found
137 int i;
138 int k;
E. Scott Daniels3376a212019-05-14 14:14:20 +0000139 int c1; // general counters
140 int c2;
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000141 int mtype;
142 int value;
143 int alt_value;
144 ei_t entries[50]; // end point information
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400145 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
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000148 char* tok;
149 char* nxt_tok;
150 int enu = 0;
151 int state;
152 char *buf;
E. Scott Danielsfcea3952020-10-30 15:04:16 -0400153 char *buf2;
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000154 char* seed_fname; // seed file
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500155 SOCKET_TYPE nn_sock; // differnt in each transport (nng == struct, SI/Nano == int)
E. Scott Daniels0b79fc22019-12-04 15:20:16 -0500156 rmr_mbuf_t* mbuf; // message for meid route testing
E. Scott Daniels353bafb2020-11-12 16:44:34 -0500157 void* p; // generic pointer
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000158
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500159 #ifndef NNG_UNDER_TEST
160 si_ctx_t* si_ctx = NULL;
161 #endif
162
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000163 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 +0000164 i = open( ".ut_rmr_verbose", O_RDWR | O_CREAT, 0644 );
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000165 if( i >= 0 ) {
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400166 write( i, "2\n", 2 );
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000167 close( i );
168 }
169
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500170
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400171 /*
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.)
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500175
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400176 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
182 */
183 gcounts[0] = 1; // first entry has 1 group with 2 endpoints; message type 0, sid 0
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000184 ecounts[0] = 2;
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400185 mtypes[0] = build_key( 0, 0 ); // mtype is now a key of mtype/sid
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000186 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 -0400187 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 +0000188
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400189 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++;
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000193 entries[enu].group = 0; entries[enu].ep_name = "localhost:4568"; enu++;
194 entries[enu].group = 0; entries[enu].ep_name = "localhost:4569"; enu++;
195
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400196 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
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000199 entries[enu].group = 1; entries[enu].ep_name = "localhost:4561"; enu++;
200 entries[enu].group = 1; entries[enu].ep_name = "localhost:4562"; enu++;
201
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400202 gcounts[3] = 1; // next entry has 1 group
203 ecounts[3] = 2; // with 2 enpoints
204 mtypes[3] = build_key( 2, 0 );
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000205 entries[enu].group = 0; entries[enu].ep_name = "localhost:4563"; enu++;
206 entries[enu].group = 0; entries[enu].ep_name = "localhost:4564"; enu++;
207
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400208 gcounts[4] = 1; // three entries for mt==3 with different sids
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000209 ecounts[4] = 1;
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400210 mtypes[4] = build_key( 3, 0 );
211 entries[enu].group = 0; entries[enu].ep_name = "localhost:5500"; enu++;
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000212
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400213 gcounts[5] = 1;
214 ecounts[5] = 1;
215 mtypes[5] = build_key( 3, 11 );
216 entries[enu].group = 0; entries[enu].ep_name = "localhost:5511"; enu++;
217
218 gcounts[6] = 1;
219 ecounts[6] = 1;
220 mtypes[6] = build_key( 3, -1 );
221 entries[enu].group = 0; entries[enu].ep_name = "localhost:5512"; enu++;
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000222
223
E. Scott Daniels5ec64c52020-11-05 09:11:04 -0500224 rt = uta_rt_init( NULL );
225 errors += fail_if_false( rt == NULL, "rt_init given a nil context didn't return nil" );
226
227 ctx = mk_dummy_ctx(); // make a dummy with rtgate mutex
228 rt = uta_rt_init( ctx ); // get us a route table
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000229 if( (errors += fail_if_nil( rt, "pointer to route table" )) ) {
230 fprintf( stderr, "<FAIL> abort: cannot continue without a route table\n" );
231 exit( 1 );
232 }
233
234 enu = 0;
235 rte = NULL;
236 for( i = 0; i < sizeof( gcounts )/sizeof( int ); i++ ) { // add entries defined above
237 if( gcounts[i] ) {
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" );
241 exit( 1 );
242 }
243 } else {
244 if( rte == NULL ) {
245 fprintf( stderr, "<SNAFU> internal testing error -- rte was nil for gcount == 0\n" );
246 exit( 1 );
247 }
248 }
249
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" );
253 enu++;
254 }
255 }
256
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400257 // ----- end hacking together a route table ---------------------------------------------------
258
259
E. Scott Daniels5ec64c52020-11-05 09:11:04 -0500260 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 +0000261 errors += fail_if_nil( crt, "cloned route table" );
E. Scott Daniels3376a212019-05-14 14:14:20 +0000262 if( crt ) {
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)" );
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500266
E. Scott Daniels3376a212019-05-14 14:14:20 +0000267 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" );
E. Scott Daniels5ec64c52020-11-05 09:11:04 -0500269
270 errors += fail_if_false( crt->ephash == rt->ephash, "ephash pointer in cloned table is not right" );
E. Scott Daniels3376a212019-05-14 14:14:20 +0000271 uta_rt_drop( crt );
272 }
273
274
E. Scott Daniels5ec64c52020-11-05 09:11:04 -0500275 crt = uta_rt_clone( ctx, rt, NULL, 1 ); // clone all entries (MT and ME)
276 errors += fail_if_nil( crt, "cloned (all) route table" );
E. Scott Daniels3376a212019-05-14 14:14:20 +0000277
278 if( crt ) {
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)" );
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500282
E. Scott Daniels3376a212019-05-14 14:14:20 +0000283 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)" );
E. Scott Daniels5ec64c52020-11-05 09:11:04 -0500286
287 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 +0000288 uta_rt_drop( crt );
289 }
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500290
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 ) );
294 ctx->rtable = rt;
295 } else {
296 fprintf( stderr, "<FAIL> cannot acllocate a context, cannot continue rtable tests\n" );
297 return errors;
298 }
299 #else
300 ctx = mk_dummy_ctx();
301 #endif
302
303 ctx->rtable = rt;
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000304
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)" );
309
E. Scott Daniels58ccd682019-10-02 10:21:24 -0400310 ep = NULL;
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500311 #ifdef NNG_UNDER_TEST
312 state = uta_epsock_byname( rt, "localhost:4561", &nn_sock, &ep ); // this should be found
313 #else
E. Scott Daniels5ec64c52020-11-05 09:11:04 -0500314 state = uta_epsock_byname( ctx, "localhost:4561", &nn_sock, &ep ); // this should be found
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500315 #endif
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000316 errors += fail_if_equal( state, 0, "socket (by name)" );
E. Scott Daniels58ccd682019-10-02 10:21:24 -0400317 errors += fail_if_nil( ep, "epsock_byname did not populate endpoint pointer when expected to" );
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000318 //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" );
320
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500321 #if NNG_UNDER_TEST
322 state = uta_epsock_byname( NULL, "localhost:4561", &nn_sock, &ep ); // test coverage on nil checks
323 #else
324 state = uta_epsock_byname( NULL, "localhost:4561", &nn_sock, &ep );
E. Scott Daniels353bafb2020-11-12 16:44:34 -0500325 errors += fail_not_equal( state, 0, "socket (by name) nil context check returned true" );
326
327 p = ctx->si_ctx;
328 ctx->si_ctx = NULL; // set to drive second test
329 state = uta_epsock_byname( ctx, "localhost:4561", &nn_sock, &ep );
330 ctx->si_ctx = p;
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500331 #endif
332 errors += fail_not_equal( state, 0, "socket (by name) nil check returned true" );
333
E. Scott Daniels5ec64c52020-11-05 09:11:04 -0500334 if( ep ) { // if previous test fails, cant run this
335 ep->open = 1;
336 #if NNG_UNDER_TEST
337 state = uta_epsock_byname( rt, "localhost:4561", &nn_sock, NULL ); // test coverage on nil checks
338 #else
339 state = uta_epsock_byname( ctx, "localhost:4561", &nn_sock, NULL );
340 #endif
341 errors += fail_if_equal( state, 0, "socket (by name) open ep check returned false" );
342 }
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500343
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400344
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" );
348
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" );
351
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" );
354
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" );
357
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" );
360
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" );
364
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" );
368
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" );
371
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500372 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 -0400373 errors += fail_if_nil( rte, "get_rte did not return a pointer for s=12, m=3, true" );
374
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500375
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000376 alt_value = -1;
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400377 rte = uta_get_rte( rt, 0, 1, FALSE ); // get an rte for the next loop
378 if( rte ) {
379 for( i = 0; i < 10; i++ ) { // round robin return value should be different each time
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500380 #ifdef NNG_UNDER_TEST
381 value = uta_epsock_rr( rte, 0, &more, &nn_sock, &ep ); // msg type 1, group 1
382 #else
383 value = uta_epsock_rr( ctx, rte, 0, &more, &nn_sock, &ep );
384 #endif
385
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400386 errors += fail_if_equal( value, alt_value, "round robiin sockets with multiple end points" );
387 errors += fail_if_false( more, "more for mtype==1" );
388 alt_value = value;
389 }
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000390 }
391
392 more = -1;
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400393 rte = uta_get_rte( rt, 0, 3, FALSE ); // get an rte for the next loop
394 if( rte ) {
395 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 -0500396 #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
398 #else
399 value = uta_epsock_rr( ctx, rte, 0, NULL, &nn_sock, &ep );
400 #endif
401
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400402 if( i ) {
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" );
405 }
406 alt_value = value;
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000407 }
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000408 }
409
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400410 rte = uta_get_rte( rt, 11, 3, TRUE );
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500411 #ifdef NNG_UNDER_TEST
412 state = uta_epsock_rr( rte, 22, NULL, NULL, &ep );
413 #else
414 state = uta_epsock_rr( ctx, rte, 22, NULL, NULL, &ep );
415 #endif
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400416 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 +0000417
E. Scott Daniels0b79fc22019-12-04 15:20:16 -0500418
E. Scott Daniels5ec64c52020-11-05 09:11:04 -0500419 uta_rt_clone( ctx, NULL, NULL, 0 ); // verify null parms don't crash things
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000420 uta_rt_drop( NULL );
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500421 #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 );
424 #else
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" );
427
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" );
430
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" );
433 #endif
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000434 uta_add_rte( NULL, 99, 1 );
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400435 uta_get_rte( NULL, 0, 1000, TRUE );
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000436
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 );
440
441 buf = uta_fib( ".gitignore" );
442 errors += fail_if_nil( buf, "buffer from read file into buffer" );
443 if( buf ) {
444 free( buf );
445 }
446 buf = uta_fib( "no-file" );
447 errors += fail_if_nil( buf, "buffer from read file into buffer (no file)" );
448 if( buf ) {
449 free( buf );
450 }
451
E. Scott Daniels05850e02020-11-11 15:57:22 -0500452 fprintf( stderr, "<INFO> test is overtly dropping rt table at %p\n", rt );
453 ctx->rtable = NULL;
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000454 uta_rt_drop( rt );
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400455 rt = NULL;
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000456
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000457
E. Scott Daniels05850e02020-11-11 15:57:22 -0500458 // --- force the load of a RT which has some edge case forcing issues
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500459 if( ctx ) {
E. Scott Daniels05850e02020-11-11 15:57:22 -0500460 char* rt_stuff =
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"
466 "newrt | end | 10\n"
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400467
E. Scott Daniels05850e02020-11-11 15:57:22 -0500468 "# 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"
E. Scott Daniels05850e02020-11-11 15:57:22 -0500473
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"
479 "newrt | end | 3\n"
480
481 "# for an update to the existing table\n"
E. Scott Daniels05850e02020-11-11 15:57:22 -0500482 "# not in progress; drive that exception check\n"
483 "update | end | 23\n"
484
485 "update | start | dummy-seed\n"
E. Scott Daniels353bafb2020-11-12 16:44:34 -0500486 "mse | 3 | 2 | localhost:2222\n"
487 "# short record to drive test\n"
488 "del\n"
E. Scott Daniels05850e02020-11-11 15:57:22 -0500489 "# no table end for exception handling\n"
490
491 "update | start | dummy-seed\n"
492 "mse | 2 | 2 | localhost:2222\n"
E. Scott Daniels353bafb2020-11-12 16:44:34 -0500493 "del | 10 | 1\n"
494 "update | end | 2\n";
E. Scott Daniels05850e02020-11-11 15:57:22 -0500495
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 );
E. Scott Daniels353bafb2020-11-12 16:44:34 -0500499 fprintf( stderr, "<INFO> edge case load completed\n" );
E. Scott Daniels05850e02020-11-11 15:57:22 -0500500 errors += fail_if_nil( ctx->rtable, "edge case route table didn't generate a pointer into the context" );
501
502 unsetenv( "RMR_SEED_RT" ); // remove for next read try
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400503 read_static_rt( ctx, 0 ); // drive for not there coverage
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000504 }
505
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400506
507 buf = uta_fib( "no-suhch-file" ); // drive some error checking for coverage
508 if( buf ) {
509 free( buf );
510 }
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000511
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000512
E. Scott Daniels412d53d2019-05-20 20:00:52 +0000513 ep = (endpoint_t *) malloc( sizeof( *ep ) );
E. Scott Daniels9c923bc2020-08-03 09:22:20 -0400514 memset( ep, 0, sizeof( ep ) );
E. Scott Daniels412d53d2019-05-20 20:00:52 +0000515 pthread_mutex_init( &ep->gate, NULL );
516 ep->name = strdup( "worm" );
517 ep->addr = NULL;
E. Scott Daniels9c923bc2020-08-03 09:22:20 -0400518 ep->notify = 1;
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500519 #ifdef NNG_UNDER_TEST
520 state = uta_link2( ep );
521 #else
522 state = uta_link2( ctx, ep );
523 #endif
524 errors += fail_if_true( state, "link2 did not return false when given a bad target name" );
525
526 #ifdef NNG_UNDER_TEST
527 state = uta_link2( NULL );
528 #else
529 state = uta_link2( ctx, NULL );
530 errors += fail_if_true( state, "link2 did not return false when given nil ep pointer" );
531
532 state = uta_link2( NULL, ep );
533 #endif
534 errors += fail_if_true( state, "link2 did not return false when given nil pointer" );
535
536 ep->name = strdup( "localhost:5512" );
537 ep->open = 1;
538 #ifdef NNG_UNDER_TEST
539 state = uta_link2( ep ); // drive for coverage
540 #else
541 state = uta_link2( ctx, ep );
542 #endif
543 errors += fail_if_false( state, "link2 did returned false when given open ep" );
544
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
E. Scott Daniels9c923bc2020-08-03 09:22:20 -0400547 ep->notify = 1;
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500548 state = rt_link2_ep( NULL, ep );
549 errors += fail_if_true( state, "rt_link2_ep returned true when given bad context" );
550
551 state = rt_link2_ep( ctx, NULL );
552 errors += fail_if_true( state, "rt_link2_ep returned true when given bad ep" );
553
554 ep->open = 1;
555 state = rt_link2_ep( ctx, ep );
556 errors += fail_if_false( state, "rt_link2_ep returned false when given an open ep" );
557
558 ep->open = 0;
559 state = rt_link2_ep( ctx, ep );
560 errors += fail_if_false( state, "rt_link2_ep returned false when given a closed ep" );
561
562 ep->open = 1;
563 uta_ep_failed( ep );
564 errors += fail_if_true( ep->open, "uta_ep_failed didn't set open flag to false" );
565
566 #endif
567
E. Scott Daniels5efb1e62019-05-02 17:09:35 +0000568
E. Scott Daniels0b79fc22019-12-04 15:20:16 -0500569 // ----------------- test the meid support for looking up an endpoint based on the meid in the message -----
570
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500571 ctx->rtable = NULL;
E. Scott Daniels0b79fc22019-12-04 15:20:16 -0500572 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
575
576 mbuf = rmr_alloc_msg( ctx, 2048 ); // buffer to play with
577 mbuf->len = 100;
578 rmr_str2meid( mbuf, "meid1" ); // id that we know is in the map
579
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500580 #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" );
E. Scott Daniels0b79fc22019-12-04 15:20:16 -0500585
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500586 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" );
590 #else
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" );
595
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" );
599
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" );
604
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" );
607
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" );
610 #endif
611
E. Scott Danielsfc2112d2020-04-21 12:51:05 -0400612 // ------------ 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" );
616
E. Scott Danielsfcea3952020-10-30 15:04:16 -0400617 buf = ensure_nlterm( NULL );
618 errors += fail_if_nil( buf, "ensure nlterm returned null pointer when given nil ptr" );
619 if( buf ) {
620 errors += fail_not_equal( strlen( buf ), 1, "ensure nlterm returned incorrect length string when given nil pointer" );
621 free( buf );
622 }
623
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" );
626 if( buf ) {
627 errors += fail_not_equal( strlen( buf ), 2, "ensure nlterm returned incorrect length string when given single char string" );
628 free( buf );
629 }
630
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" ) ) {
634 errors++;
635 free( buf2 );
636 }
637 free( buf );
638
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" ) ) {
642 errors++;
643 free( buf2 );
644 }
645 free( buf );
646
E. Scott Danielsfc2112d2020-04-21 12:51:05 -0400647 buf = ensure_nlterm( strdup( "Stand up and cheer!" ) ); // force addition of newline
648 if( buf ) {
649 errors += fail_not_equal( strcmp( buf, "Stand up and cheer!\n" ), 0, "ensure nlterm didn't add newline" );
650 free( buf );
651 buf = NULL;
652 }
653
654
655 // ------------- route manager request/response funcitons -------------------------------------------------------
656 {
657 rmr_mbuf_t* smsg;
658
659 smsg = rmr_alloc_msg( ctx, 1024 );
660 send_rt_ack( ctx, smsg, "123456", 0, "no reason" );
661
662 pctx = mk_dummy_ctx();
663 ctx->rtg_whid = -1;
664 state = send_update_req( pctx, ctx );
665 errors += fail_not_equal( state, 0, "send_update_req did not return 0" );
666
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" );
670 }
671
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500672
673 // ------------- si only; fd to ep conversion functions ---------------------------------------------------------
674 #ifndef NNG_UNDER_TEST
675 ep2 = (endpoint_t *) malloc( sizeof( *ep ) );
676
677 fd2ep_init( ctx );
678 fd2ep_add( ctx, 10, ep2 );
679
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" );
683
684 ep = fd2ep_get( ctx, 20 );
685 errors += fail_not_nil( ep, "fd2ep did returned a pointer for unknown mapping" );
686
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" );
690
691 ep = fd2ep_del( ctx, 20 );
692 errors += fail_not_nil( ep, "fd2ep delete returned a pointer for unknown mapping" );
693 #endif
E. Scott Danielsa41c6f52019-04-23 18:24:25 +0000694
E. Scott Daniels05850e02020-11-11 15:57:22 -0500695 // ---------------- misc coverage tests --------------------------------------------------------------------------
E. Scott Daniels84423e62020-12-04 13:04:29 -0500696 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 );
699
700 ctx = mk_dummy_ctx();
701 roll_tables( ctx ); // drive nil rt check
702
703
704
705 // ------ specific edge case tests -------------------------------------------------------------------------------
706 errors += lg_clone_test( );
E. Scott Daniels05850e02020-11-11 15:57:22 -0500707
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000708 return !!errors; // 1 or 0 regardless of count
709}