blob: 129eec1da669b436f5b7793fb318dc415f4d348c [file] [log] [blame]
E. Scott Daniels8dd46412019-04-16 20:47:54 +00001// : vi ts=4 sw=4 noet :
2/*
3==================================================================================
E. Scott Daniels8790bf02019-04-23 12:59:28 +00004 Copyright (c) 2019 Nokia
5 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
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
41typedef struct entry_info {
42 int group;
43 char* ep_name;
44} ei_t;
45
46
47/*
48 This is the main route table test. It sets up a very specific table
49 for testing (not via the generic setup function for other test
50 situations).
51*/
52static int rt_test( ) {
53 uta_ctx_t* ctx; // context needed to test load static rt
54 route_table_t* rt; // route table
55 route_table_t* crt; // cloned route table
56 rtable_ent_t* rte; // entry in the table
57 endpoint_t* ep; // endpoint added
58 int more = 0; // more flag from round robin
59 int errors = 0; // number errors found
60 int i;
61 int k;
62 int mtype;
63 int value;
64 int alt_value;
65 ei_t entries[50]; // end point information
66 int gcounts[5]; // number of groups in this set
67 int ecounts[5]; // number of elements per group
68 int mtypes[5]; // msg type for each group set
69 char* tok;
70 char* nxt_tok;
71 int enu = 0;
72 int state;
73 char *buf;
74 char* seed_fname; // seed file
75 nng_socket nn_sock; // this is a struct in nng, so difficult to validate
76
77 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 +000078 i = open( ".ut_rmr_verbose", O_RDWR | O_CREAT, 0644 );
E. Scott Daniels8dd46412019-04-16 20:47:54 +000079 if( i >= 0 ) {
E. Scott Danielsd7109572019-04-18 14:01:16 +000080 write( 1, "2\n", 2 );
E. Scott Daniels8dd46412019-04-16 20:47:54 +000081 close( i );
82 }
83
84 gcounts[0] = 1; // build entry info -- this is hackish, but saves writing another parser
85 ecounts[0] = 2;
86 mtypes[0] = 0;
87 entries[enu].group = 0; entries[enu].ep_name = "yahoo.com:4561"; enu++; // use a dns resolvable name to test that
88 entries[enu].group = 0; entries[enu].ep_name = "localhost:4562"; enu++; // rest can default to some dummy ip
89
90 gcounts[1] = 2;
91 ecounts[1] = 3;
92 mtypes[1] = 1;
93 entries[enu].group = 0; entries[enu].ep_name = "localhost:4561"; enu++;
94 entries[enu].group = 0; entries[enu].ep_name = "localhost:4568"; enu++;
95 entries[enu].group = 0; entries[enu].ep_name = "localhost:4569"; enu++;
96
97 gcounts[2] = 0; // 0 groups means use same rte, this is the next gropup
98 ecounts[2] = 2;
99 mtypes[2] = 1;
100 entries[enu].group = 1; entries[enu].ep_name = "localhost:4561"; enu++;
101 entries[enu].group = 1; entries[enu].ep_name = "localhost:4562"; enu++;
102
103 gcounts[3] = 1; // 0 groups means use same rte, this is the next gropup
104 ecounts[3] = 2;
105 mtypes[3] = 2;
106 entries[enu].group = 0; entries[enu].ep_name = "localhost:4563"; enu++;
107 entries[enu].group = 0; entries[enu].ep_name = "localhost:4564"; enu++;
108
109 gcounts[4] = 1; // 0 groups means use same rte, this is the next gropup
110 ecounts[4] = 1;
111 mtypes[4] = 3;
112 entries[enu].group = 0; entries[enu].ep_name = "localhost:4565"; enu++;
113
114
115
116 rt = uta_rt_init( ); // get us a route table
117 if( (errors += fail_if_nil( rt, "pointer to route table" )) ) {
118 fprintf( stderr, "<FAIL> abort: cannot continue without a route table\n" );
119 exit( 1 );
120 }
121
122 enu = 0;
123 rte = NULL;
124 for( i = 0; i < sizeof( gcounts )/sizeof( int ); i++ ) { // add entries defined above
125 if( gcounts[i] ) {
126 rte = uta_add_rte( rt, mtypes[i], gcounts[i] ); // get/create entry for message type
127 if( (errors += fail_if_nil( rte, "route table entry" )) ) {
128 fprintf( stderr, "<FAIL> abort: cannot continue without a route table entry\n" );
129 exit( 1 );
130 }
131 } else {
132 if( rte == NULL ) {
133 fprintf( stderr, "<SNAFU> internal testing error -- rte was nil for gcount == 0\n" );
134 exit( 1 );
135 }
136 }
137
138 for( k = 0; k < ecounts[i]; k++ ) {
139 ep = uta_add_ep( rt, rte, entries[enu].ep_name, entries[enu].group );
140 errors += fail_if_nil( ep, "endpoint" );
141 enu++;
142 }
143 }
144
145 crt = uta_rt_clone( rt );
146 errors += fail_if_nil( crt, "cloned route table" );
147
148 ep = uta_get_ep( rt, "localhost:4561" );
149 errors += fail_if_nil( ep, "end point (fetch by name)" );
150 ep = uta_get_ep( rt, "bad_name:4560" );
151 errors += fail_not_nil( ep, "end point (fetch by name with bad name)" );
152
153 state = uta_epsock_byname( rt, "localhost:4561", &nn_sock ); // this should be found
154 errors += fail_if_equal( state, 0, "socket (by name)" );
155 //alt_value = uta_epsock_byname( rt, "localhost:4562" ); // we might do a memcmp on the two structs, but for now nothing
156 //errors += fail_if_equal( value, alt_value, "app1/app2 sockets" );
157
158 alt_value = -1;
159 for( i = 0; i < 10; i++ ) { // round robin return value should be different each time
160 value = uta_epsock_rr( rt, 1, 0, &more, &nn_sock ); // msg type 1, group 1
161 errors += fail_if_equal( value, alt_value, "round robiin sockets with multiple end points" );
162 errors += fail_if_false( more, "more for mtype==1" );
163 alt_value = value;
164 }
165
166 more = -1;
167 for( i = 0; i < 10; i++ ) { // this mtype has only one endpoint, so rr should be same each time
168 value = uta_epsock_rr( rt, 3, 0, NULL, &nn_sock ); // also test ability to deal properly with nil more pointer
169 if( i ) {
170 errors += fail_not_equal( value, alt_value, "round robin sockets with one endpoint" );
171 errors += fail_not_equal( more, -1, "more value changed in single group instance" );
172 }
173 alt_value = value;
174 }
175
176 value = uta_epsock_rr( rt, 9, 0, &more, &nn_sock ); // non-existant message type; should return false (0)
177 errors += fail_not_equal( value, 0, "socket for bad mtype was valid" );
178
179 uta_rt_clone( NULL ); // verify null parms don't crash things
180 uta_rt_drop( NULL );
181 uta_epsock_rr( NULL, 1, 0, &more, &nn_sock ); // drive null case for coverage
182 uta_add_rte( NULL, 99, 1 );
183
184 fprintf( stderr, "[INFO] test: adding end points with nil data; warnings expected\n" );
185 uta_add_ep( NULL, NULL, "foo", 1 );
186 uta_add_ep( rt, NULL, "foo", 1 );
187
188 buf = uta_fib( ".gitignore" );
189 errors += fail_if_nil( buf, "buffer from read file into buffer" );
190 if( buf ) {
191 free( buf );
192 }
193 buf = uta_fib( "no-file" );
194 errors += fail_if_nil( buf, "buffer from read file into buffer (no file)" );
195 if( buf ) {
196 free( buf );
197 }
198
199 uta_rt_drop( rt );
200
201 uta_rt_drop( crt );
202
203 if( (ctx = (uta_ctx_t *) malloc( sizeof( uta_ctx_t ) )) != NULL ) {
204 memset( ctx, 0, sizeof( *ctx ) );
205
206 if( (seed_fname = getenv( "RMR_SEED_RT" )) != NULL ) {
207 if( ! (fail_if_nil( rt, "pointer to rt for load test" )) ) {
208 errors++;
209 read_static_rt( ctx, 0 );
210 unsetenv( "RMR_SEED_RT" ); // unset to test the does not exist condition
211 read_static_rt( ctx, 0 );
212 } else {
213 fprintf( stderr, "<FAIL> cannot gen rt for load test\n" );
214 }
215 } else {
216 read_static_rt( ctx, 0 ); // not defined, just drive for that one case
217 }
218 }
219
220 uta_fib( "no-suhch-file" ); // drive some error checking for coverage
221
222/*
223 if( ctx ) {
224 if( ctx->rtg_addr ) {
225 free( ctx->rtg_addr );
226 }
227 free( ctx );
228 }
229*/
230
231 return !!errors; // 1 or 0 regardless of count
232}