test(app): Support lib64 based Linix flavours
[ric-plt/lib/rmr.git] / test / rt_nano_static_test.c
1 // : vi ts=4 sw=4 noet :
2 /*
3 ==================================================================================
4             Copyright (c) 2019 Nokia
5             Copyright (c) 2018-2019 AT&T Intellectual Property.
6
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
11            http://www.apache.org/licenses/LICENSE-2.0
12
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
24                                 time by the test driver.
25
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>
37
38 #include "../src/common/include/rmr.h"
39 #include "../src/common/include/rmr_agnostic.h"
40
41 typedef struct entry_info {
42         int group;
43         char* ep_name;
44 } ei_t;
45
46 /*
47         Create a dummy endpoint for some direct function calls.
48 */
49 static endpoint_t* mk_ep( char* name ) {
50         endpoint_t* ep;
51
52         ep = (endpoint_t *) malloc( sizeof( struct endpoint ) );
53         ep->name = strdup( name );
54         ep->proto = strdup( "tcp" );
55         ep->addr = strdup( "address" );
56         ep->nn_sock = -1;
57         ep->open = 0;
58
59         return ep;
60 }
61
62
63 /*
64         This is the main route table test. It sets up a very specific table
65         for testing (not via the generic setup function for other test
66         situations).
67 */
68 static int rt_test( ) {
69         uta_ctx_t* ctx;                 // context needed to test load static rt
70         route_table_t* rt;              // route table
71         route_table_t*  crt;            // cloned route table
72         rtable_ent_t*   rte;    // entry in the table
73         endpoint_t*             ep;                     // endpoint added
74         int                             more = 0;                       // more flag from round robin
75         int                             errors = 0;                     // number errors found
76         int                             i;
77         int                             k;
78         int                             mtype;
79         int                             value;
80         int                             alt_value;
81         ei_t                    entries[50];    // end point information
82         int                             gcounts[5];             // number of groups in this set
83         int                             ecounts[5];             // number of elements per group
84         int                             mtypes[5];              // msg type for each group set
85         char*                   tok;
86         char*                   nxt_tok;
87         int                             enu = 0;
88         int                             state;
89         char                    *buf;
90         char*                   seed_fname;             // seed file
91         int                     nn_sock;
92
93         setenv( "ENV_VERBOSE_FILE", ".ut_rmr_verbose", 1 );                     // allow for verbose code in rtc to be driven
94         i = open( ".ut_rmr_verbose", O_RDWR | O_CREAT, 0644 );
95         if( i >= 0 ) {
96                 write( i, "2\n", 2 );
97                 close( i );
98         }
99
100         gcounts[0] = 1;                 // build entry info -- this is hackish, but saves writing another parser
101         ecounts[0] = 2;
102         mtypes[0] = 0;
103         entries[enu].group = 0; entries[enu].ep_name = "yahoo.com:4561"; enu++;         // use a dns resolvable name to test that
104         entries[enu].group = 0; entries[enu].ep_name = "localhost:4562"; enu++; // rest can default to some dummy ip
105
106         gcounts[1] = 2;
107         ecounts[1] = 3;
108         mtypes[1] = 1;
109         entries[enu].group = 0; entries[enu].ep_name = "localhost:4561"; enu++;
110         entries[enu].group = 0; entries[enu].ep_name = "localhost:4568"; enu++;
111         entries[enu].group = 0; entries[enu].ep_name = "localhost:4569"; enu++;
112
113         gcounts[2] = 0;         // 0 groups means use same rte, this is the next gropup
114         ecounts[2] = 2;
115         mtypes[2] = 1;
116         entries[enu].group = 1; entries[enu].ep_name = "localhost:4561"; enu++;
117         entries[enu].group = 1; entries[enu].ep_name = "localhost:4562"; enu++;
118
119         gcounts[3] = 1;         // 0 groups means use same rte, this is the next gropup
120         ecounts[3] = 2;
121         mtypes[3] = 2;
122         entries[enu].group = 0; entries[enu].ep_name = "localhost:4563"; enu++;
123         entries[enu].group = 0; entries[enu].ep_name = "localhost:4564"; enu++;
124
125         gcounts[4] = 1;         // 0 groups means use same rte, this is the next gropup
126         ecounts[4] = 1;
127         mtypes[4] = 3;
128         entries[enu].group = 0; entries[enu].ep_name = "localhost:4565"; enu++;
129
130
131         rt = uta_rt_init( );                                                                            // get us a route table
132         if( (errors += fail_if_nil( rt, "pointer to route table" )) ) {
133                 fprintf( stderr, "<FAIL> abort: cannot continue without a route table\n" );
134                 exit( 1 );
135         }
136
137         enu = 0;
138         rte = NULL;
139         for( i = 0; i < sizeof( gcounts )/sizeof( int ); i++ ) {                                // add entries defined above
140                 if( gcounts[i] ) {
141                         rte = uta_add_rte( rt, mtypes[i], gcounts[i] );                                 // get/create entry for message type
142                         if( (errors += fail_if_nil( rte, "route table entry" )) ) {
143                                 fprintf( stderr, "<FAIL> abort: cannot continue without a route table entry\n" );
144                                 exit( 1 );
145                         }
146                 } else {
147                         if( rte == NULL ) {
148                                 fprintf( stderr, "<SNAFU> internal testing error -- rte was nil for gcount == 0\n" );
149                                 exit( 1 );
150                         }
151                 }
152
153                 for( k = 0; k < ecounts[i]; k++ ) {
154                         ep = uta_add_ep( rt, rte, entries[enu].ep_name, entries[enu].group );
155                         errors += fail_if_nil( ep, "endpoint" );
156                         enu++;
157                 }
158         }
159
160         crt = uta_rt_clone( rt );
161         errors += fail_if_nil( crt, "cloned route table" );
162
163         ep = uta_get_ep( rt, "localhost:4561" );
164         errors += fail_if_nil( ep, "end point (fetch by name)" );
165         ep = uta_get_ep( rt, "bad_name:4560" );
166         errors += fail_not_nil( ep, "end point (fetch by name with bad name)" );
167
168         state = uta_epsock_byname( rt, "localhost:4561" );              // this should be found
169         errors += fail_if_true( state < 0, "socket (by name) returned socket less than 0 when expected >= 0 socket" );
170
171         alt_value = -1;
172         for( i = 0; i < 10; i++ ) {                                                                             // round robin return value should be different each time
173                 value = uta_epsock_rr( rt, 1, 0, &more );                                       // nano returns the socket which should be different than the last call
174                 errors += fail_if_equal( value, alt_value, "round robiin sockets with multiple end points" );
175                 errors += fail_if_false( more, "more for mtype==1" );
176                 alt_value = value;
177         }
178
179         more = -1;
180         for( i = 0; i < 10; i++ ) {                                                     // this mtype has only one endpoint, so rr should be same each time
181                 value = uta_epsock_rr( rt, 3, 0, NULL );                // also test ability to deal properly with nil more pointer
182                 if( i ) {
183                         errors += fail_not_equal( value, alt_value, "round robin sockets with one endpoint" );
184                         errors += fail_not_equal( more, -1, "more value changed in single group instance" );
185                 }
186                 alt_value = value;
187         }
188
189         value = uta_epsock_rr( rt, 289486, 0, &more  );                 // non-existant message type; should return false (0)
190         errors += fail_if_true( value >= 0, "socket for bad hash key was valid" );
191
192         uta_rt_clone( NULL );                                                           // verify null parms don't crash things
193         uta_rt_drop( NULL );
194         uta_epsock_rr( NULL, 1, 0, &more );                                     // drive null case for coverage
195         uta_add_rte( NULL, 99, 1 );
196
197         fprintf( stderr, "<INFO> adding end points with nil data; warnings from RMr code are expected\n" );
198         uta_add_ep( NULL, NULL, "foo", 1 );
199         uta_add_ep( rt, NULL, "foo", 1 );
200
201         buf = uta_fib( ".gitignore" );
202         errors += fail_if_nil( buf, "buffer from read file into buffer" );
203         if( buf ) {
204                 free( buf );
205         }
206         buf = uta_fib( "no-file" );
207         errors += fail_if_nil( buf, "buffer from read file into buffer (no file)" );
208         if( buf ) {
209                 free( buf );
210         }
211
212         uta_rt_drop( rt );
213
214         uta_rt_drop( crt );
215
216         if( (ctx = (uta_ctx_t *) malloc( sizeof( uta_ctx_t ) )) != NULL ) {
217                 memset( ctx, 0, sizeof( *ctx ) );
218
219                 if( (seed_fname = getenv( "RMR_SEED_RT" )) != NULL ) {
220                         if( ! (fail_if_nil( rt, "pointer to rt for load test" )) ) {
221                                 read_static_rt( ctx, 0 );
222                                 unsetenv( "RMR_SEED_RT" );                      // unset to test the does not exist condition
223                                 read_static_rt( ctx, 0 );
224                         } else {
225                                 fprintf( stderr, "<FAIL> cannot gen rt for load test\n" );
226                         }
227                 } else {
228                         read_static_rt( ctx, 0 );               // not defined, just drive for that one case
229                 }
230         }
231
232         uta_fib( "no-suhch-file" );                     // drive some error checking for coverage
233
234         rt = uta_rt_init( );                                                                            // get us a route table
235         state = uta_link2( NULL );
236         errors += fail_not_equal( state, -1, "link2 did not return (a==) -1 when given nil pointers" );
237
238         ep = mk_ep( "foo" );
239         state = rt_link2_ep( NULL );
240         errors += fail_not_equal( state, 0, "link2_ep did not return (a) bad  when given nil pointers" );
241
242         state = rt_link2_ep( ep );
243         errors += fail_not_equal( state, 1, "link2_ep did not return (a) bad  when given an ep to use to open" );
244
245         ep->open = 1;
246         state = rt_link2_ep( ep );
247         errors += fail_not_equal( state, 1, "link2_ep did not return (a) bad when given an ep which was set open" );
248
249         state = uta_epsock_rr( rt, 122, 0, NULL );
250         errors += fail_not_equal( state, -1, "uta_epsock_rr returned bad state when given nil socket pointer" );
251
252         state = uta_epsock_rr( rt, 0, -1, NULL );
253         errors += fail_not_equal( state, -1, "uta_epsock_rr returned bad state (a) when given negative group number" );
254
255         state = rt_link2_ep( NULL );
256         errors += fail_if_equal( state, -1, "call to link2_ep with nil ep returned true when false expected" );
257
258
259         return !!errors;                        // 1 or 0 regardless of count
260 }