1 // : vi ts=4 sw=4 noet :
3 ==================================================================================
4 Copyright (c) 2019 Nokia
5 Copyright (c) 2018-2019 AT&T Intellectual Property.
7 Licensed under the Apache License, Version 2.0 (the "License");
8 you may not use this file except in compliance with the License.
9 You may obtain a copy of the License at
11 http://www.apache.org/licenses/LICENSE-2.0
13 Unless required by applicable law or agreed to in writing, software
14 distributed under the License is distributed on an "AS IS" BASIS,
15 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 See the License for the specific language governing permissions and
17 limitations under the License.
18 ==================================================================================
22 Mmemonic: rt_static_test.c
23 Abstract: Test the route table funcitons. These are meant to be included at compile
24 time by the test driver.
26 Author: E. Scott Daniels
38 #include <semaphore.h>
41 #include "rmr_agnostic.h"
43 typedef struct entry_info {
50 Driven by symtab foreach element of one space.
51 We count using the data as a counter.
53 static void count_things( void* st, void* entry, char const* name, void* thing, void* vdata ) {
57 if( (counter = (int *) vdata) != NULL ) {
64 Returns the number of entries in the table for the given class.
66 static int count_entries( route_table_t* rt, int class ) {
76 rmr_sym_foreach_class( rt->hash, class, count_things, &counter ); // run each and update counter
82 This is the main route table test. It sets up a very specific table
83 for testing (not via the generic setup function for other test
86 static int rt_test( ) {
87 uta_ctx_t* ctx; // context needed to test load static rt
88 route_table_t* rt; // route table
89 route_table_t* crt; // cloned route table
90 rtable_ent_t* rte; // entry in the table
91 endpoint_t* ep; // endpoint added
92 int more = 0; // more flag from round robin
93 int errors = 0; // number errors found
96 int c1; // general counters
101 ei_t entries[50]; // end point information
102 int gcounts[5]; // number of groups in this set
103 int ecounts[5]; // number of elements per group
104 int mtypes[5]; // msg type for each group set
110 char* seed_fname; // seed file
111 nng_socket nn_sock; // this is a struct in nng, so difficult to validate
113 setenv( "ENV_VERBOSE_FILE", ".ut_rmr_verbose", 1 ); // allow for verbose code in rtc to be driven
114 i = open( ".ut_rmr_verbose", O_RDWR | O_CREAT, 0644 );
116 write( 1, "2\n", 2 );
120 gcounts[0] = 1; // build entry info -- this is hackish, but saves writing another parser
123 entries[enu].group = 0; entries[enu].ep_name = "yahoo.com:4561"; enu++; // use a dns resolvable name to test that
124 entries[enu].group = 0; entries[enu].ep_name = "localhost:4562"; enu++; // rest can default to some dummy ip
129 entries[enu].group = 0; entries[enu].ep_name = "localhost:4561"; enu++;
130 entries[enu].group = 0; entries[enu].ep_name = "localhost:4568"; enu++;
131 entries[enu].group = 0; entries[enu].ep_name = "localhost:4569"; enu++;
133 gcounts[2] = 0; // 0 groups means use same rte, this is the next gropup
136 entries[enu].group = 1; entries[enu].ep_name = "localhost:4561"; enu++;
137 entries[enu].group = 1; entries[enu].ep_name = "localhost:4562"; enu++;
139 gcounts[3] = 1; // 0 groups means use same rte, this is the next gropup
142 entries[enu].group = 0; entries[enu].ep_name = "localhost:4563"; enu++;
143 entries[enu].group = 0; entries[enu].ep_name = "localhost:4564"; enu++;
145 gcounts[4] = 1; // 0 groups means use same rte, this is the next gropup
148 entries[enu].group = 0; entries[enu].ep_name = "localhost:4565"; enu++;
152 rt = uta_rt_init( ); // get us a route table
153 if( (errors += fail_if_nil( rt, "pointer to route table" )) ) {
154 fprintf( stderr, "<FAIL> abort: cannot continue without a route table\n" );
160 for( i = 0; i < sizeof( gcounts )/sizeof( int ); i++ ) { // add entries defined above
162 rte = uta_add_rte( rt, mtypes[i], gcounts[i] ); // get/create entry for message type
163 if( (errors += fail_if_nil( rte, "route table entry" )) ) {
164 fprintf( stderr, "<FAIL> abort: cannot continue without a route table entry\n" );
169 fprintf( stderr, "<SNAFU> internal testing error -- rte was nil for gcount == 0\n" );
174 for( k = 0; k < ecounts[i]; k++ ) {
175 ep = uta_add_ep( rt, rte, entries[enu].ep_name, entries[enu].group );
176 errors += fail_if_nil( ep, "endpoint" );
181 crt = uta_rt_clone( rt ); // clone only the endpoint entries
182 errors += fail_if_nil( crt, "cloned route table" );
184 c1 = count_entries( rt, 1 );
185 c2 = count_entries( crt, 1 );
186 errors += fail_not_equal( c1, c2, "cloned (endpoints) table entries space 1 count (b) did not match original table count (a)" );
188 c2 = count_entries( crt, 0 );
189 errors += fail_not_equal( c2, 0, "cloned (endpoints) table entries space 0 count (a) was not zero as expected" );
194 crt = uta_rt_clone_all( rt ); // clone all entries
195 errors += fail_if_nil( crt, "cloned all route table" );
198 c1 = count_entries( rt, 0 );
199 c2 = count_entries( crt, 0 );
200 errors += fail_not_equal( c1, c2, "cloned (all) table entries space 0 count (b) did not match original table count (a)" );
202 c1 = count_entries( rt, 1 );
203 c2 = count_entries( crt, 1 );
204 errors += fail_not_equal( c1, c2, "cloned (all) table entries space 1 count (b) did not match original table count (a)" );
209 ep = uta_get_ep( rt, "localhost:4561" );
210 errors += fail_if_nil( ep, "end point (fetch by name)" );
211 ep = uta_get_ep( rt, "bad_name:4560" );
212 errors += fail_not_nil( ep, "end point (fetch by name with bad name)" );
214 state = uta_epsock_byname( rt, "localhost:4561", &nn_sock ); // this should be found
215 errors += fail_if_equal( state, 0, "socket (by name)" );
216 //alt_value = uta_epsock_byname( rt, "localhost:4562" ); // we might do a memcmp on the two structs, but for now nothing
217 //errors += fail_if_equal( value, alt_value, "app1/app2 sockets" );
220 for( i = 0; i < 10; i++ ) { // round robin return value should be different each time
221 value = uta_epsock_rr( rt, 1, 0, &more, &nn_sock ); // msg type 1, group 1
222 errors += fail_if_equal( value, alt_value, "round robiin sockets with multiple end points" );
223 errors += fail_if_false( more, "more for mtype==1" );
228 for( i = 0; i < 10; i++ ) { // this mtype has only one endpoint, so rr should be same each time
229 value = uta_epsock_rr( rt, 3, 0, NULL, &nn_sock ); // also test ability to deal properly with nil more pointer
231 errors += fail_not_equal( value, alt_value, "round robin sockets with one endpoint" );
232 errors += fail_not_equal( more, -1, "more value changed in single group instance" );
237 value = uta_epsock_rr( rt, 9, 0, &more, &nn_sock ); // non-existant message type; should return false (0)
238 errors += fail_not_equal( value, 0, "socket for bad mtype was valid" );
240 uta_rt_clone( NULL ); // verify null parms don't crash things
242 uta_epsock_rr( NULL, 1, 0, &more, &nn_sock ); // drive null case for coverage
243 uta_add_rte( NULL, 99, 1 );
245 fprintf( stderr, "[INFO] test: adding end points with nil data; warnings expected\n" );
246 uta_add_ep( NULL, NULL, "foo", 1 );
247 uta_add_ep( rt, NULL, "foo", 1 );
249 buf = uta_fib( ".gitignore" );
250 errors += fail_if_nil( buf, "buffer from read file into buffer" );
254 buf = uta_fib( "no-file" );
255 errors += fail_if_nil( buf, "buffer from read file into buffer (no file)" );
262 if( (ctx = (uta_ctx_t *) malloc( sizeof( uta_ctx_t ) )) != NULL ) {
263 memset( ctx, 0, sizeof( *ctx ) );
265 if( (seed_fname = getenv( "RMR_SEED_RT" )) != NULL ) {
266 if( ! (fail_if_nil( rt, "pointer to rt for load test" )) ) {
268 read_static_rt( ctx, 0 );
269 unsetenv( "RMR_SEED_RT" ); // unset to test the does not exist condition
270 read_static_rt( ctx, 0 );
272 fprintf( stderr, "<FAIL> cannot gen rt for load test\n" );
275 read_static_rt( ctx, 0 ); // not defined, just drive for that one case
279 uta_fib( "no-suhch-file" ); // drive some error checking for coverage
282 ep = (endpoint_t *) malloc( sizeof( *ep ) );
283 pthread_mutex_init( &ep->gate, NULL );
284 ep->name = strdup( "worm" );
286 state = uta_link2( ep );
287 errors += fail_if_true( state, "link2 did not return false when given nil pointers" );
289 state = uta_epsock_rr( rt, 122, 0, NULL, NULL );
290 errors += fail_if_true( state, "uta_epsock_rr returned bad state when given nil socket pointer" );
292 rt = uta_rt_init( ); // get us a route table
293 state = uta_epsock_rr( rt, 0, -1, NULL, &nn_sock );
294 errors += fail_if_true( state, "uta_epsock_rr returned bad state (true) when given negative group number" );
296 return !!errors; // 1 or 0 regardless of count