blob: dbe8d7807739b031eedb9795cc7162a486071666 [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;
126 char* seed_fname; // seed file
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500127 SOCKET_TYPE nn_sock; // differnt in each transport (nng == struct, SI/Nano == int)
E. Scott Daniels0b79fc22019-12-04 15:20:16 -0500128 rmr_mbuf_t* mbuf; // message for meid route testing
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000129
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500130 #ifndef NNG_UNDER_TEST
131 si_ctx_t* si_ctx = NULL;
132 #endif
133
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000134 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 +0000135 i = open( ".ut_rmr_verbose", O_RDWR | O_CREAT, 0644 );
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000136 if( i >= 0 ) {
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400137 write( i, "2\n", 2 );
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000138 close( i );
139 }
140
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500141
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400142 /*
143 The hacky code below calls the necessary rmr functions to create a route table
144 as though the following were read and parsed by the rmr functions. (This tests
145 the individual funcitons and avoids writing another parser, so it's not pretty.)
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500146
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400147 mse | 0 | 0 | yahoo.com:4561,localhost:4562
148 mse | 1 | 0 | localhost:4560,localhost:4568,localhost:4569; localhost:4561,localhost:4562
149 mse | 2 | 0 | localhost:4563,localhost:4564
150 mse | 3 | 0 | localhost:4565
151 mse | 3 | 11 | locahost:5511
152 mse | 3 | -1 | localhost:5500
153 */
154 gcounts[0] = 1; // first entry has 1 group with 2 endpoints; message type 0, sid 0
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000155 ecounts[0] = 2;
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400156 mtypes[0] = build_key( 0, 0 ); // mtype is now a key of mtype/sid
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000157 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 -0400158 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 +0000159
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400160 gcounts[1] = 2; // 2 groups
161 ecounts[1] = 3; // first has 3 endpoints
162 mtypes[1] = build_key( 1, 0 );
163 entries[enu].group = 0; entries[enu].ep_name = "localhost:4560"; enu++;
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000164 entries[enu].group = 0; entries[enu].ep_name = "localhost:4568"; enu++;
165 entries[enu].group = 0; entries[enu].ep_name = "localhost:4569"; enu++;
166
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400167 gcounts[2] = 0; // 0 means use same rte, this is the next group for the entry
168 ecounts[2] = 2; // 2 endpoints
169 mtypes[2] = 999; // ignored when appending to previous entry
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000170 entries[enu].group = 1; entries[enu].ep_name = "localhost:4561"; enu++;
171 entries[enu].group = 1; entries[enu].ep_name = "localhost:4562"; enu++;
172
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400173 gcounts[3] = 1; // next entry has 1 group
174 ecounts[3] = 2; // with 2 enpoints
175 mtypes[3] = build_key( 2, 0 );
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000176 entries[enu].group = 0; entries[enu].ep_name = "localhost:4563"; enu++;
177 entries[enu].group = 0; entries[enu].ep_name = "localhost:4564"; enu++;
178
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400179 gcounts[4] = 1; // three entries for mt==3 with different sids
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000180 ecounts[4] = 1;
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400181 mtypes[4] = build_key( 3, 0 );
182 entries[enu].group = 0; entries[enu].ep_name = "localhost:5500"; enu++;
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000183
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400184 gcounts[5] = 1;
185 ecounts[5] = 1;
186 mtypes[5] = build_key( 3, 11 );
187 entries[enu].group = 0; entries[enu].ep_name = "localhost:5511"; enu++;
188
189 gcounts[6] = 1;
190 ecounts[6] = 1;
191 mtypes[6] = build_key( 3, -1 );
192 entries[enu].group = 0; entries[enu].ep_name = "localhost:5512"; enu++;
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000193
194
195 rt = uta_rt_init( ); // get us a route table
196 if( (errors += fail_if_nil( rt, "pointer to route table" )) ) {
197 fprintf( stderr, "<FAIL> abort: cannot continue without a route table\n" );
198 exit( 1 );
199 }
200
201 enu = 0;
202 rte = NULL;
203 for( i = 0; i < sizeof( gcounts )/sizeof( int ); i++ ) { // add entries defined above
204 if( gcounts[i] ) {
205 rte = uta_add_rte( rt, mtypes[i], gcounts[i] ); // get/create entry for message type
206 if( (errors += fail_if_nil( rte, "route table entry" )) ) {
207 fprintf( stderr, "<FAIL> abort: cannot continue without a route table entry\n" );
208 exit( 1 );
209 }
210 } else {
211 if( rte == NULL ) {
212 fprintf( stderr, "<SNAFU> internal testing error -- rte was nil for gcount == 0\n" );
213 exit( 1 );
214 }
215 }
216
217 for( k = 0; k < ecounts[i]; k++ ) {
218 ep = uta_add_ep( rt, rte, entries[enu].ep_name, entries[enu].group );
219 errors += fail_if_nil( ep, "endpoint" );
220 enu++;
221 }
222 }
223
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400224 // ----- end hacking together a route table ---------------------------------------------------
225
226
E. Scott Daniels3376a212019-05-14 14:14:20 +0000227 crt = uta_rt_clone( rt ); // clone only the endpoint entries
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000228 errors += fail_if_nil( crt, "cloned route table" );
E. Scott Daniels3376a212019-05-14 14:14:20 +0000229 if( crt ) {
230 c1 = count_entries( rt, 1 );
231 c2 = count_entries( crt, 1 );
232 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 -0500233
E. Scott Daniels3376a212019-05-14 14:14:20 +0000234 c2 = count_entries( crt, 0 );
235 errors += fail_not_equal( c2, 0, "cloned (endpoints) table entries space 0 count (a) was not zero as expected" );
236 uta_rt_drop( crt );
237 }
238
239
240 crt = uta_rt_clone_all( rt ); // clone all entries
241 errors += fail_if_nil( crt, "cloned all route table" );
242
243 if( crt ) {
244 c1 = count_entries( rt, 0 );
245 c2 = count_entries( crt, 0 );
246 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 -0500247
E. Scott Daniels3376a212019-05-14 14:14:20 +0000248 c1 = count_entries( rt, 1 );
249 c2 = count_entries( crt, 1 );
250 errors += fail_not_equal( c1, c2, "cloned (all) table entries space 1 count (b) did not match original table count (a)" );
251 uta_rt_drop( crt );
252 }
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500253
254 #ifdef NNG_UNDER_TEST
255 if( (ctx = (uta_ctx_t *) malloc( sizeof( uta_ctx_t ) )) != NULL ) { // get a "context" needed for si testing
256 memset( ctx, 0, sizeof( *ctx ) );
257 ctx->rtable = rt;
258 } else {
259 fprintf( stderr, "<FAIL> cannot acllocate a context, cannot continue rtable tests\n" );
260 return errors;
261 }
262 #else
263 ctx = mk_dummy_ctx();
264 #endif
265
266 ctx->rtable = rt;
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000267
268 ep = uta_get_ep( rt, "localhost:4561" );
269 errors += fail_if_nil( ep, "end point (fetch by name)" );
270 ep = uta_get_ep( rt, "bad_name:4560" );
271 errors += fail_not_nil( ep, "end point (fetch by name with bad name)" );
272
E. Scott Daniels58ccd682019-10-02 10:21:24 -0400273 ep = NULL;
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500274 #ifdef NNG_UNDER_TEST
275 state = uta_epsock_byname( rt, "localhost:4561", &nn_sock, &ep ); // this should be found
276 #else
277 state = uta_epsock_byname( ctx, "localhost:4561", &nn_sock, &ep ); // this should be found
278 #endif
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000279 errors += fail_if_equal( state, 0, "socket (by name)" );
E. Scott Daniels58ccd682019-10-02 10:21:24 -0400280 errors += fail_if_nil( ep, "epsock_byname did not populate endpoint pointer when expected to" );
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000281 //alt_value = uta_epsock_byname( rt, "localhost:4562" ); // we might do a memcmp on the two structs, but for now nothing
282 //errors += fail_if_equal( value, alt_value, "app1/app2 sockets" );
283
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500284 #if NNG_UNDER_TEST
285 state = uta_epsock_byname( NULL, "localhost:4561", &nn_sock, &ep ); // test coverage on nil checks
286 #else
287 state = uta_epsock_byname( NULL, "localhost:4561", &nn_sock, &ep );
288 #endif
289 errors += fail_not_equal( state, 0, "socket (by name) nil check returned true" );
290
291 ep->open = 1;
292 #if NNG_UNDER_TEST
293 state = uta_epsock_byname( rt, "localhost:4561", &nn_sock, NULL ); // test coverage on nil checks
294 #else
295 state = uta_epsock_byname( ctx, "localhost:4561", &nn_sock, NULL );
296 #endif
297 errors += fail_if_equal( state, 0, "socket (by name) open ep check returned false" );
298
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400299
300 // --- test that the get_rte function finds expected keys, and retries to find 'bad' sid attempts for valid mtypes with no sid
301 rte = uta_get_rte( rt, 0, 1, TRUE ); // s=0 m=1 is defined, so this should return a pointer
302 errors += fail_if_nil( rte, "get_rte did not return a pointer when s=0 m=1 true given" );
303
304 rte = uta_get_rte( rt, 0, 1, FALSE ); // the retry shouldn't apply, but ensure it does the righ thing
305 errors += fail_if_nil( rte, "get_rte did not return a pointer when s=0 m=1 false given" );
306
307 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
308 errors += fail_not_nil( rte, "get_rte returned a pointer when s=1000 m=1 false given" );
309
310 rte = uta_get_rte( rt, 1000, 1, TRUE ); // this should also fail as there is no mt==1 sid==-1 defined
311 errors += fail_not_nil( rte, "get_rte returned a pointer when s=1000 m=1 true given" );
312
313 rte = uta_get_rte( rt, 0, 3, TRUE ); // mtype sid combo does exist; true/false should not matter
314 errors += fail_if_nil( rte, "get_rte did not return a pointer when s=0 m=3 true given" );
315
316 rte2 = uta_get_rte( rt, 11, 3, TRUE ); // same mtype as before, different (valid) group, rte should be different than before
317 errors += fail_if_nil( rte2, "get_rte did not return a pointer when s=11 m=3 true given" );
318 errors += fail_if_true( rte == rte2, "get_rte for mtype==3 and different sids (0 and 11) returned the same rte pointer" );
319
320 rte2 = uta_get_rte( rt, 0, 3, FALSE ); // since the mtype/sid combo exists, setting false should return the same as before
321 errors += fail_if_nil( rte2, "get_rte did not return a pointer when s=0 m=3 false given" );
322 errors += fail_if_false( rte == rte2, "get_rte did not return same pointer when mtype/sid combo given with different true/false" );
323
324 rte = uta_get_rte( rt, 12, 3, FALSE ); // this combo does not exist and should fail when alt-key is not allowed (false)
325 errors += fail_not_nil( rte, "get_rte returned a pointer for s=12, m=3, false" );
326
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500327 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 -0400328 errors += fail_if_nil( rte, "get_rte did not return a pointer for s=12, m=3, true" );
329
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500330
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000331 alt_value = -1;
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400332 rte = uta_get_rte( rt, 0, 1, FALSE ); // get an rte for the next loop
333 if( rte ) {
334 for( i = 0; i < 10; i++ ) { // round robin return value should be different each time
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500335 #ifdef NNG_UNDER_TEST
336 value = uta_epsock_rr( rte, 0, &more, &nn_sock, &ep ); // msg type 1, group 1
337 #else
338 value = uta_epsock_rr( ctx, rte, 0, &more, &nn_sock, &ep );
339 #endif
340
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400341 errors += fail_if_equal( value, alt_value, "round robiin sockets with multiple end points" );
342 errors += fail_if_false( more, "more for mtype==1" );
343 alt_value = value;
344 }
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000345 }
346
347 more = -1;
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400348 rte = uta_get_rte( rt, 0, 3, FALSE ); // get an rte for the next loop
349 if( rte ) {
350 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 -0500351 #ifdef NNG_UNDER_TEST
352 value = uta_epsock_rr( rte, 0, NULL, &nn_sock, &ep ); // also test ability to deal properly with nil more pointer
353 #else
354 value = uta_epsock_rr( ctx, rte, 0, NULL, &nn_sock, &ep );
355 #endif
356
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400357 if( i ) {
358 errors += fail_not_equal( value, alt_value, "round robin sockets with one endpoint" );
359 errors += fail_not_equal( more, -1, "more value changed in single group instance" );
360 }
361 alt_value = value;
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000362 }
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000363 }
364
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400365 rte = uta_get_rte( rt, 11, 3, TRUE );
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500366 #ifdef NNG_UNDER_TEST
367 state = uta_epsock_rr( rte, 22, NULL, NULL, &ep );
368 #else
369 state = uta_epsock_rr( ctx, rte, 22, NULL, NULL, &ep );
370 #endif
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400371 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 +0000372
E. Scott Daniels0b79fc22019-12-04 15:20:16 -0500373
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000374 uta_rt_clone( NULL ); // verify null parms don't crash things
375 uta_rt_drop( NULL );
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500376 #ifdef NNG_UNDER_TEST
377 uta_epsock_rr( NULL, 0, &more, &nn_sock, &ep ); // drive null case for coverage
378 state = uta_epsock_rr( rte, 22, NULL, NULL, &ep );
379 #else
380 state = uta_epsock_rr( NULL, NULL, 0, &more, &nn_sock, &ep ); // drive null case for coverage
381 errors += fail_not_equal( state, 0, "uta_epsock_rr did not return false when given nil ctx" );
382
383 state = uta_epsock_rr( ctx, NULL, 0, &more, &nn_sock, &ep );
384 errors += fail_not_equal( state, 0, "uta_epsock_rr did not return false when given nil rte" );
385
386 state = uta_epsock_rr( ctx, rte, 10000, &more, &nn_sock, &ep );
387 errors += fail_not_equal( state, 0, "uta_epsock_rr did not return false when given invalid group number" );
388 #endif
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000389 uta_add_rte( NULL, 99, 1 );
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400390 uta_get_rte( NULL, 0, 1000, TRUE );
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000391
392 fprintf( stderr, "[INFO] test: adding end points with nil data; warnings expected\n" );
393 uta_add_ep( NULL, NULL, "foo", 1 );
394 uta_add_ep( rt, NULL, "foo", 1 );
395
396 buf = uta_fib( ".gitignore" );
397 errors += fail_if_nil( buf, "buffer from read file into buffer" );
398 if( buf ) {
399 free( buf );
400 }
401 buf = uta_fib( "no-file" );
402 errors += fail_if_nil( buf, "buffer from read file into buffer (no file)" );
403 if( buf ) {
404 free( buf );
405 }
406
407 uta_rt_drop( rt );
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400408 rt = NULL;
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000409
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000410
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500411 if( ctx ) {
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000412 if( (seed_fname = getenv( "RMR_SEED_RT" )) != NULL ) {
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400413 read_static_rt( ctx, 0 );
414 rt = ctx->rtable;
415 errors += fail_if_nil( rt, "read seed table didn't generate a rtable pointer in context" );
416 unsetenv( "RMR_SEED_RT" ); // remove for next test
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000417 }
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400418
419 read_static_rt( ctx, 0 ); // drive for not there coverage
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000420 }
421
E. Scott Daniels6511ac72019-08-27 10:17:21 -0400422
423 buf = uta_fib( "no-suhch-file" ); // drive some error checking for coverage
424 if( buf ) {
425 free( buf );
426 }
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000427
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000428
E. Scott Daniels412d53d2019-05-20 20:00:52 +0000429 ep = (endpoint_t *) malloc( sizeof( *ep ) );
430 pthread_mutex_init( &ep->gate, NULL );
431 ep->name = strdup( "worm" );
432 ep->addr = NULL;
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500433 #ifdef NNG_UNDER_TEST
434 state = uta_link2( ep );
435 #else
436 state = uta_link2( ctx, ep );
437 #endif
438 errors += fail_if_true( state, "link2 did not return false when given a bad target name" );
439
440 #ifdef NNG_UNDER_TEST
441 state = uta_link2( NULL );
442 #else
443 state = uta_link2( ctx, NULL );
444 errors += fail_if_true( state, "link2 did not return false when given nil ep pointer" );
445
446 state = uta_link2( NULL, ep );
447 #endif
448 errors += fail_if_true( state, "link2 did not return false when given nil pointer" );
449
450 ep->name = strdup( "localhost:5512" );
451 ep->open = 1;
452 #ifdef NNG_UNDER_TEST
453 state = uta_link2( ep ); // drive for coverage
454 #else
455 state = uta_link2( ctx, ep );
456 #endif
457 errors += fail_if_false( state, "link2 did returned false when given open ep" );
458
459 #ifndef NNG_UNDER_TEST
460 ep->open = 0; // context is used only if ep not open, so to check this test close the ep
461 state = rt_link2_ep( NULL, ep );
462 errors += fail_if_true( state, "rt_link2_ep returned true when given bad context" );
463
464 state = rt_link2_ep( ctx, NULL );
465 errors += fail_if_true( state, "rt_link2_ep returned true when given bad ep" );
466
467 ep->open = 1;
468 state = rt_link2_ep( ctx, ep );
469 errors += fail_if_false( state, "rt_link2_ep returned false when given an open ep" );
470
471 ep->open = 0;
472 state = rt_link2_ep( ctx, ep );
473 errors += fail_if_false( state, "rt_link2_ep returned false when given a closed ep" );
474
475 ep->open = 1;
476 uta_ep_failed( ep );
477 errors += fail_if_true( ep->open, "uta_ep_failed didn't set open flag to false" );
478
479 #endif
480
E. Scott Daniels5efb1e62019-05-02 17:09:35 +0000481
E. Scott Daniels0b79fc22019-12-04 15:20:16 -0500482 // ----------------- test the meid support for looking up an endpoint based on the meid in the message -----
483
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500484 ctx->rtable = NULL;
E. Scott Daniels0b79fc22019-12-04 15:20:16 -0500485 ctx->my_name = strdup( "my_host_name" ); // set up to load a rtable
486 ctx->my_ip = strdup( "192.168.1.30" );
487 gen_rt( ctx ); // generate a route table with meid entries and hang off ctx
488
489 mbuf = rmr_alloc_msg( ctx, 2048 ); // buffer to play with
490 mbuf->len = 100;
491 rmr_str2meid( mbuf, "meid1" ); // id that we know is in the map
492
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500493 #ifdef NNG_UNDER_TEST
494 ep = NULL; // force to nil so we see it go non-nil
495 state = epsock_meid( ctx->rtable, mbuf, &nn_sock, &ep );
496 errors += fail_if_nil( ep, "ep was nil when looking up ep with known meid in message" );
497 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 -0500498
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500499 rmr_str2meid( mbuf, "XXXmeid1" ); // id that we know is NOT in the map
500 state = epsock_meid( ctx->rtable, mbuf, &nn_sock, &ep );
501 // it is NOT a valid check to test ep for nil -- epsock_mied doesn't guarentee ep is set/cleared when state is false
502 errors += fail_not_equal( state, 0, "state was not false when looking up ep with unknown meid in message" );
503 #else
504 ep = NULL; // force to nil so we see it go non-nil
505 state = epsock_meid( ctx, ctx->rtable, mbuf, &nn_sock, &ep );
506 errors += fail_if_nil( ep, "ep was nil when looking up ep with known meid in message" );
507 errors += fail_not_equal( state, 1, "state was not true when looking up ep with known meid in message" );
508
509 state = epsock_meid( ctx, ctx->rtable, mbuf, &nn_sock, &ep ); // a second call to drive open == true check for coverage
510 errors += fail_if_nil( ep, "ep was nil when looking up ep with known meid in message; on open ep" );
511 errors += fail_not_equal( state, 1, "state was not true when looking up ep with known meid in message; on open ep" );
512
513 rmr_str2meid( mbuf, "XXXmeid1" ); // id that we know is NOT in the map
514 state = epsock_meid( ctx, ctx->rtable, mbuf, &nn_sock, &ep );
515 // it is NOT a valid check to test ep for nil -- epsock_mied doesn't guarentee ep is set/cleared when state is false
516 errors += fail_not_equal( state, 0, "state was not false when looking up ep with unknown meid in message" );
517
518 state = epsock_meid( NULL, ctx->rtable, mbuf, &nn_sock, &ep );
519 errors += fail_not_equal( state, 0, "epsock_meid returned true when given nil context" );
520
521 state = epsock_meid( ctx, ctx->rtable, mbuf, NULL, &ep );
522 errors += fail_not_equal( state, 0, "epsock_meid returned true when given nil socket pointer" );
523 #endif
524
E. Scott Danielsfc2112d2020-04-21 12:51:05 -0400525 // ------------ debugging and such; coverage only calls ----------------------------------------------------------
526 ep_stats( ctx->rtable, NULL, "name", NULL, NULL ); // ensure no crash when given nil pointer
527 rt_epcounts( ctx->rtable, "testing" );
528 rt_epcounts( NULL, "testing" );
529
530 buf = ensure_nlterm( strdup( "Stand up and cheer!" ) ); // force addition of newline
531 if( buf ) {
532 errors += fail_not_equal( strcmp( buf, "Stand up and cheer!\n" ), 0, "ensure nlterm didn't add newline" );
533 free( buf );
534 buf = NULL;
535 }
536
537
538 // ------------- route manager request/response funcitons -------------------------------------------------------
539 {
540 rmr_mbuf_t* smsg;
541
542 smsg = rmr_alloc_msg( ctx, 1024 );
543 send_rt_ack( ctx, smsg, "123456", 0, "no reason" );
544
545 pctx = mk_dummy_ctx();
546 ctx->rtg_whid = -1;
547 state = send_update_req( pctx, ctx );
548 errors += fail_not_equal( state, 0, "send_update_req did not return 0" );
549
550 ctx->rtg_whid = rmr_wh_open( ctx, "localhost:19289" );
551 state = send_update_req( pctx, ctx );
552 errors += fail_if_equal( state, 0, "send_update_req to an open whid did not return 0" );
553 }
554
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500555
556 // ------------- si only; fd to ep conversion functions ---------------------------------------------------------
557 #ifndef NNG_UNDER_TEST
558 ep2 = (endpoint_t *) malloc( sizeof( *ep ) );
559
560 fd2ep_init( ctx );
561 fd2ep_add( ctx, 10, ep2 );
562
563 ep = fd2ep_get( ctx, 10 );
564 errors += fail_if_nil( ep, "fd2ep did not return pointer for known mapping" );
565 errors += fail_if_false( ep == ep2, "fd2ep did not return same pointer that was added" );
566
567 ep = fd2ep_get( ctx, 20 );
568 errors += fail_not_nil( ep, "fd2ep did returned a pointer for unknown mapping" );
569
570 ep = fd2ep_del( ctx, 10 );
571 errors += fail_if_nil( ep, "fd2ep delete did not return pointer for known mapping" );
572 errors += fail_if_false( ep == ep2, "fd2ep delete did not return same pointer that was added" );
573
574 ep = fd2ep_del( ctx, 20 );
575 errors += fail_not_nil( ep, "fd2ep delete returned a pointer for unknown mapping" );
576 #endif
E. Scott Danielsa41c6f52019-04-23 18:24:25 +0000577
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000578 return !!errors; // 1 or 0 regardless of count
579}