blob: f1e69817767a52f52cb5f34c37da059e2065604e [file] [log] [blame]
E. Scott Daniels8dd46412019-04-16 20:47:54 +00001// : 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
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
78 i = open( ".rmr_verbose", O_CREAT, 0664 );
79 if( i >= 0 ) {
80 close( i );
81 }
82
83 gcounts[0] = 1; // build entry info -- this is hackish, but saves writing another parser
84 ecounts[0] = 2;
85 mtypes[0] = 0;
86 entries[enu].group = 0; entries[enu].ep_name = "yahoo.com:4561"; enu++; // use a dns resolvable name to test that
87 entries[enu].group = 0; entries[enu].ep_name = "localhost:4562"; enu++; // rest can default to some dummy ip
88
89 gcounts[1] = 2;
90 ecounts[1] = 3;
91 mtypes[1] = 1;
92 entries[enu].group = 0; entries[enu].ep_name = "localhost:4561"; enu++;
93 entries[enu].group = 0; entries[enu].ep_name = "localhost:4568"; enu++;
94 entries[enu].group = 0; entries[enu].ep_name = "localhost:4569"; enu++;
95
96 gcounts[2] = 0; // 0 groups means use same rte, this is the next gropup
97 ecounts[2] = 2;
98 mtypes[2] = 1;
99 entries[enu].group = 1; entries[enu].ep_name = "localhost:4561"; enu++;
100 entries[enu].group = 1; entries[enu].ep_name = "localhost:4562"; enu++;
101
102 gcounts[3] = 1; // 0 groups means use same rte, this is the next gropup
103 ecounts[3] = 2;
104 mtypes[3] = 2;
105 entries[enu].group = 0; entries[enu].ep_name = "localhost:4563"; enu++;
106 entries[enu].group = 0; entries[enu].ep_name = "localhost:4564"; enu++;
107
108 gcounts[4] = 1; // 0 groups means use same rte, this is the next gropup
109 ecounts[4] = 1;
110 mtypes[4] = 3;
111 entries[enu].group = 0; entries[enu].ep_name = "localhost:4565"; enu++;
112
113
114
115 rt = uta_rt_init( ); // get us a route table
116 if( (errors += fail_if_nil( rt, "pointer to route table" )) ) {
117 fprintf( stderr, "<FAIL> abort: cannot continue without a route table\n" );
118 exit( 1 );
119 }
120
121 enu = 0;
122 rte = NULL;
123 for( i = 0; i < sizeof( gcounts )/sizeof( int ); i++ ) { // add entries defined above
124 if( gcounts[i] ) {
125 rte = uta_add_rte( rt, mtypes[i], gcounts[i] ); // get/create entry for message type
126 if( (errors += fail_if_nil( rte, "route table entry" )) ) {
127 fprintf( stderr, "<FAIL> abort: cannot continue without a route table entry\n" );
128 exit( 1 );
129 }
130 } else {
131 if( rte == NULL ) {
132 fprintf( stderr, "<SNAFU> internal testing error -- rte was nil for gcount == 0\n" );
133 exit( 1 );
134 }
135 }
136
137 for( k = 0; k < ecounts[i]; k++ ) {
138 ep = uta_add_ep( rt, rte, entries[enu].ep_name, entries[enu].group );
139 errors += fail_if_nil( ep, "endpoint" );
140 enu++;
141 }
142 }
143
144 crt = uta_rt_clone( rt );
145 errors += fail_if_nil( crt, "cloned route table" );
146
147 ep = uta_get_ep( rt, "localhost:4561" );
148 errors += fail_if_nil( ep, "end point (fetch by name)" );
149 ep = uta_get_ep( rt, "bad_name:4560" );
150 errors += fail_not_nil( ep, "end point (fetch by name with bad name)" );
151
152 state = uta_epsock_byname( rt, "localhost:4561", &nn_sock ); // this should be found
153 errors += fail_if_equal( state, 0, "socket (by name)" );
154 //alt_value = uta_epsock_byname( rt, "localhost:4562" ); // we might do a memcmp on the two structs, but for now nothing
155 //errors += fail_if_equal( value, alt_value, "app1/app2 sockets" );
156
157 alt_value = -1;
158 for( i = 0; i < 10; i++ ) { // round robin return value should be different each time
159 value = uta_epsock_rr( rt, 1, 0, &more, &nn_sock ); // msg type 1, group 1
160 errors += fail_if_equal( value, alt_value, "round robiin sockets with multiple end points" );
161 errors += fail_if_false( more, "more for mtype==1" );
162 alt_value = value;
163 }
164
165 more = -1;
166 for( i = 0; i < 10; i++ ) { // this mtype has only one endpoint, so rr should be same each time
167 value = uta_epsock_rr( rt, 3, 0, NULL, &nn_sock ); // also test ability to deal properly with nil more pointer
168 if( i ) {
169 errors += fail_not_equal( value, alt_value, "round robin sockets with one endpoint" );
170 errors += fail_not_equal( more, -1, "more value changed in single group instance" );
171 }
172 alt_value = value;
173 }
174
175 value = uta_epsock_rr( rt, 9, 0, &more, &nn_sock ); // non-existant message type; should return false (0)
176 errors += fail_not_equal( value, 0, "socket for bad mtype was valid" );
177
178 uta_rt_clone( NULL ); // verify null parms don't crash things
179 uta_rt_drop( NULL );
180 uta_epsock_rr( NULL, 1, 0, &more, &nn_sock ); // drive null case for coverage
181 uta_add_rte( NULL, 99, 1 );
182
183 fprintf( stderr, "[INFO] test: adding end points with nil data; warnings expected\n" );
184 uta_add_ep( NULL, NULL, "foo", 1 );
185 uta_add_ep( rt, NULL, "foo", 1 );
186
187 buf = uta_fib( ".gitignore" );
188 errors += fail_if_nil( buf, "buffer from read file into buffer" );
189 if( buf ) {
190 free( buf );
191 }
192 buf = uta_fib( "no-file" );
193 errors += fail_if_nil( buf, "buffer from read file into buffer (no file)" );
194 if( buf ) {
195 free( buf );
196 }
197
198 uta_rt_drop( rt );
199
200 uta_rt_drop( crt );
201
202 if( (ctx = (uta_ctx_t *) malloc( sizeof( uta_ctx_t ) )) != NULL ) {
203 memset( ctx, 0, sizeof( *ctx ) );
204
205 if( (seed_fname = getenv( "RMR_SEED_RT" )) != NULL ) {
206 if( ! (fail_if_nil( rt, "pointer to rt for load test" )) ) {
207 errors++;
208 read_static_rt( ctx, 0 );
209 unsetenv( "RMR_SEED_RT" ); // unset to test the does not exist condition
210 read_static_rt( ctx, 0 );
211 } else {
212 fprintf( stderr, "<FAIL> cannot gen rt for load test\n" );
213 }
214 } else {
215 read_static_rt( ctx, 0 ); // not defined, just drive for that one case
216 }
217 }
218
219 uta_fib( "no-suhch-file" ); // drive some error checking for coverage
220
221/*
222 if( ctx ) {
223 if( ctx->rtg_addr ) {
224 free( ctx->rtg_addr );
225 }
226 free( ctx );
227 }
228*/
229
230 return !!errors; // 1 or 0 regardless of count
231}