Correct table clear bug in route table ready
[ric-plt/lib/rmr.git] / test / tools_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 /*
23         Mnemonic:       tools_static_test.c
24         Abstract:       Unit tests for the RMr tools module. This file is a static include
25                                 that is pulle in at compile time by the test driver.  The driver is
26                                 expected to include necessary rmr*.h and test_support files before
27                                 including this file.  In addition, a context struct, or dummy, must
28                                 be provided based on the type of testing being done.
29
30         Author:         E. Scott Daniels
31         Date:           3 April 2019
32 */
33
34 // ------------ zero termianted buffer ---------------------------------------------------------
35 static int ztbf_test() {
36         int errors = 0;
37         char buf[128];
38         char*   sshort = "Stand up and cheer! Cheer long and loud for old Ohio.";
39         char*   slong = "Now is the time for the bobcat in the forest to make its way back to Court St for a round of pints at the Pub.";
40         int l1;
41
42         l1 = zt_buf_fill( buf, sshort, 64 );
43         errors += fail_not_equal( l1, strlen( sshort ), "zt_buf_fill of short buf returned unexpected len" );
44         errors += fail_not_equal( l1, strlen( buf ), "zt_buf_fill of short buf returned len did not match strlen" );
45
46         l1 = zt_buf_fill( buf, slong, 64 );
47         errors += fail_if_equal( l1, strlen( slong ), "zt_buf_fill of long buf returned unexpected len" );
48         errors += fail_not_equal( l1, strlen( buf ), "zt_buf_fill of long buf returned len did not match strlen" );
49
50         l1 = zt_buf_fill( buf, sshort, strlen( sshort ) );              // edge case of exact size
51         errors += fail_not_equal( l1, strlen( sshort )-1, "zt_buf_fill exact length edge case failed" );
52
53         l1 = zt_buf_fill( buf, sshort, 1 );                                             // unrealistic edge case
54         errors += fail_not_equal( l1, 0, "zt_buf_fill dest len == 1 test failed" );
55
56         return errors;
57 }
58
59 /*
60         Returns an interface name that is valid in this environment (keeps us from
61         having to know/guess a name to test with.
62 */
63 static char* get_ifname( ) {
64         if_addrs_t* l;
65         struct  ifaddrs *ifs;           // pointer to head
66         struct  ifaddrs *ele;           // pointer into the list
67         char*   rstr = NULL;            // return string
68
69
70         if( (l = (if_addrs_t *) malloc( sizeof( if_addrs_t ) )) == NULL ) {
71                 return NULL;
72         }
73         memset( l, 0, sizeof( if_addrs_t ) );
74         l->addrs = (char **) malloc( sizeof( char* ) * 128 );
75         if( l->addrs == NULL ) {
76                 free( l );
77                 return NULL;
78         }
79
80         getifaddrs( &ifs );
81         for( ele = ifs; ele; ele = ele->ifa_next ) {
82                 if( ele && strcmp( ele->ifa_name, "lo" ) ) {
83                         rstr = strdup( ele->ifa_name );
84                         break;
85                 }
86         }
87
88         free( l );
89         return rstr;
90 }
91
92 static int tools_test( ) {
93         int i;
94         int j;
95         int errors = 0;
96         char* tokens[127];
97         char* buf = "2,Fred,Wilma,Barney,Betty,Dino,Pebbles,Bambam,Mr. Slate,Gazoo";
98         char*   dbuf;                           // duplicated buf since C marks a const string is unumtable
99         char*   hname;
100         char*   ip;                                     // ip address string
101         uta_ctx_t ctx;                          // context for uta_lookup test
102         void*   if_list;
103
104
105         uta_dump_env();
106
107         // ------------------ tokenise tests -----------------------------------------------------------
108         dbuf = strdup( buf );
109         i = uta_tokenise( dbuf, tokens, 127, ',' );
110         errors += fail_not_equal( i, 10, "unexpected number of tokens returned (comma sep)" );
111         for( j = 0; j < i; j++ ) {
112                 //fprintf( stderr, ">>>> [%d] (%s)\n", j, tokens[j] );
113                 errors += fail_if_nil( tokens[j], "token from buffer" );
114         }
115         errors += fail_not_equal( strcmp( tokens[4], "Betty" ), 0, "4th token wasn't 'Betty'" );
116
117         free( dbuf );
118         dbuf = strdup( buf );
119         i = uta_tokenise( dbuf, tokens, 127, '|' );
120         errors += fail_not_equal( i, 1, "unexpected number of tokens returned (bar sep)" );
121         free( dbuf );
122
123         // ------------ has str tests -----------------------------------------------------------------
124         j = uta_has_str( buf, "Mr. Slate", ',', 1 );                    // should fail (-1) because user should use strcmp in this situation
125         errors += fail_if_true( j >= 0, "test to ensure has str rejects small max" );
126
127         j = uta_has_str( buf, "Mr. Slate", ',', 27 );
128         errors += fail_if_true( j < 0, "has string did not find Mr. Slate" );
129
130         j = uta_has_str( buf, "Mrs. Slate", ',', 27 );
131         errors += fail_if_true( j >= 0, "has string not found Mrs. Slate" );
132
133         // ------------ host name 2 ip tests ---------------------------------------------------------
134         hname = uta_h2ip( "192.168.1.2" );
135         errors += fail_not_equal( strcmp( hname, "192.168.1.2" ), 0, "h2ip did not return IP address when given address" );
136         errors += fail_if_nil( hname, "h2ip did not return a pointer" );
137         free( hname );
138
139         hname = uta_h2ip( "yahoo.com" );
140         errors += fail_if_nil( hname, "h2ip did not return a pointer" );
141         free( hname );
142
143         hname = uta_h2ip( "yahoo.com:1234" );                                                   // should ignore the port
144         errors += fail_if_nil( hname, "h2ip did not return a pointer" );
145         free( hname );
146
147         // ------------ rtg lookup test -------------------------------------------------------------
148 #ifdef KEEP
149         // pub/sub route table generator is deprecated and should be removed at this point
150         ctx.rtg_port = 0;
151         ctx.rtg_addr = NULL;
152
153         i = uta_lookup_rtg( NULL );                                             // ensure it handles a nil context
154         errors += fail_if_true( i, "rtg lookup returned that it found something when not expected to (nil context)" );
155
156         setenv( "RMR_RTG_SVC", "localhost:1234", 1);
157         i = uta_lookup_rtg( &ctx );
158         errors += fail_if_false( i, "rtg lookup returned that it did not find something when expected to" );
159         errors += fail_if_nil( ctx.rtg_addr, "rtg lookup did not return a pointer (with port)" );
160         errors += fail_not_equal( ctx.rtg_port, 1234, "rtg lookup did not capture the port" );
161
162         setenv( "RMR_RTG_SVC", "localhost", 1);                 // test ability to generate default port
163         uta_lookup_rtg( &ctx );
164         errors += fail_if_nil( ctx.rtg_addr, "rtg lookup did not return a pointer (no port)" );
165         errors += fail_not_equal( ctx.rtg_port, 5656, "rtg lookup did not return default port" );
166
167         unsetenv( "RMR_RTG_SVC" );                                              // this should fail as the default name (rtg) will be unknown during testing
168         i = uta_lookup_rtg( &ctx );
169         errors += fail_if_true( i, "rtg lookup returned that it found something when not expected to" );
170 #endif
171
172         // ------------ my_ip stuff -----------------------------------------------------------------
173
174         if_list = mk_ip_list( "1235" );
175         errors += fail_if_nil( if_list, "mk_ip_list returned nil pointer" );
176
177         i = has_myip( NULL, NULL, ',', 128 );           // should be false if pointers are nil
178         errors += fail_if_true( i, "has_myip returned true when given nil buffer" );
179
180         i = has_myip( "buffer contents not valid", NULL, ',', 128 );            // should be false if pointers are nil
181         errors += fail_if_true( i, "has_myip returned true when given nil list" );
182
183         i = has_myip( "buffer contents not valid", NULL, ',', 1 );                      // should be false if max < 2
184         errors += fail_if_true( i, "has_myip returned true when given small max value" );
185
186         i = has_myip( "buffer.contents.not.valid", if_list, ',', 128 );         // should be false as there is nothing valid in the list
187         errors += fail_if_true( i, "has_myip returned true when given a buffer with no valid info" );
188
189
190         setenv( "RMR_BIND_IF", "192.168.4.30", 1 );                     // drive the case where we have a hard set interface; and set known interface in list
191         if_list = mk_ip_list( "1235" );
192         errors += fail_if_nil( if_list, "mk_ip_list with env set returned nil pointer" );
193
194         i = has_myip( "192.168.1.2:1235,192.168.4.30:1235,192.168.2.19:4567", if_list, ',', 128 );              // should find our ip in middle
195         errors += fail_if_false( i, "has_myip did not find IP in middle of list" );
196
197         i = has_myip( "192.168.4.30:1235,192.168.2.19:4567,192.168.2.19:2222", if_list, ',', 128 );             // should find our ip at head
198         errors += fail_if_false( i, "has_myip did not find IP at head of list" );
199
200         i = has_myip( "192.168.23.45:4444,192.168.1.2:1235,192.168.4.30:1235", if_list, ',', 128 );             // should find our ip at end
201         errors += fail_if_false( i, "has_myip did not find IP at tail of list" );
202
203         i = has_myip( "192.168.4.30:1235", if_list, ',', 128 );                                                                                 // should find our ip when only in list
204         errors += fail_if_false( i, "has_myip did not find IP when only one in list" );
205
206         ip = get_default_ip( NULL );
207         errors += fail_not_nil( ip, "get_default_ip returned non-nil pointer when given nil information" );
208
209         ip = get_default_ip( if_list );
210         if( ip ) {
211                 free( ip );
212         } else {
213                 errors += fail_if_nil( ip, "get_defaul_ip returned nil pointer when valid pointer expected" );
214         }
215
216         ip = get_ifname();                                                      // suss out a valid interface name (not lo)
217         if( ip ) {
218                 setenv( "RMR_BIND_IF", ip, 1 );                 // drive the case where we have a hard set interface; and set known interface in list
219                 free( ip );
220                 if_list = mk_ip_list( "1235" );
221                 if( if_list ) {
222                         ip = get_default_ip( if_list );
223                         errors += fail_if_nil( ip, "get_default_ip did not return valid pointer when list created from interface name" );
224                 } else {
225                         errors += fail_if_nil( if_list, "mk_ip_list with a specific interface name returned a nil list" );
226                 }
227
228                 free( ip );
229         }
230
231         errors += ztbf_test();                                  // test the zero term buffer fill function
232
233 // -------------------------------------------------------------------------------------------------
234
235         return !!errors;                        // 1 or 0 regardless of count
236 }