enhance(API): Add multi-threaded call
[ric-plt/lib/rmr.git] / test / tools_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_testh.c
24         Abstract:       Unit tests for the RMr tools module.
25         Author:         E. Scott Daniels
26         Date:           21 January 2019
27 */
28
29
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <netdb.h>
33 #include <errno.h>
34 #include <string.h>
35 #include <errno.h>
36 #include <pthread.h>
37 #include <ctype.h>
38 #include <pthread.h>
39 #include <semaphore.h>
40
41 #include "rmr.h"
42 #include "rmr_agnostic.h"
43 #include "test_support.c"               // our private library of test tools
44
45 // ===== dummy context for tools testing so we don't have to pull in all of the nano/nng specific stuff =====
46 struct uta_ctx {
47         char*   my_name;                        // dns name of this host to set in sender field of a message
48         int     shutdown;                               // thread notification if we need to tell them to stop
49         int max_mlen;                           // max message length payload+header
50         int     max_plen;                               // max payload length
51         int     flags;                                  // CTXFL_ constants
52         int nrtele;                                     // number of elements in the routing table
53         int send_retries;                       // number of retries send_msg() should attempt if eagain/timeout indicated by nng
54         //nng_socket    nn_sock;                // our general listen socket
55         route_table_t* rtable;          // the active route table
56         route_table_t* old_rtable;      // the previously used rt, sits here to allow for draining
57         route_table_t* new_rtable;      // route table under construction
58         if_addrs_t*     ip_list;                // list manager of the IP addresses that are on our known interfaces
59         void*   mring;                          // ring where msgs are queued while waiting for a call response msg
60
61         char*   rtg_addr;                       // addr/port of the route table generation publisher
62         int             rtg_port;                       // the port that the rtg listens on
63
64         wh_mgt_t*       wormholes;              // management of user opened wormholes
65         //epoll_stuff_t*        eps;            // epoll information needed for the rcv with timeout call
66
67         //pthread_t     rtc_th;                 // thread info for the rtc listener
68 };
69
70
71 #include "tools_static.c"
72
73
74 int main( ) {
75         int i;
76         int j;
77         int errors = 0;
78         char* tokens[127];
79         char* buf = "2,Fred,Wilma,Barney,Betty,Dino,Pebbles,Bambam,Mr. Slate,Gazoo";
80         char*   dbuf;                           // duplicated buf since C marks a const string is unumtable
81         char*   hname;
82         uta_ctx_t ctx;                          // context for uta_lookup test
83         void*   if_list;
84
85
86         // ------------------ tokenise tests -----------------------------------------------------------
87         dbuf = strdup( buf );
88         i = uta_tokenise( dbuf, tokens, 127, ',' );
89         errors += fail_not_equal( i, 10, "unexpected number of tokens returned (comma sep)" );
90         for( j = 0; j < i; j++ ) {
91                 //fprintf( stderr, ">>>> [%d] (%s)\n", j, tokens[j] );
92                 errors += fail_if_nil( tokens[j], "token from buffer" );
93         }
94         errors += fail_not_equal( strcmp( tokens[4], "Betty" ), 0, "4th token wasn't 'Betty'" );
95
96         free( dbuf );
97         dbuf = strdup( buf );
98         i = uta_tokenise( dbuf, tokens, 127, '|' );
99         errors += fail_not_equal( i, 1, "unexpected number of tokens returned (bar sep)" );
100         free( dbuf );
101
102         // ------------ has str tests -----------------------------------------------------------------
103         j = uta_has_str( buf, "Mr. Slate", ',', 1 );                    // should fail (-1) because user should use strcmp in this situation
104         errors += fail_if_true( j >= 0, "test to ensure has str rejects small max" );
105
106         j = uta_has_str( buf, "Mr. Slate", ',', 27 );
107         errors += fail_if_true( j < 0, "has string did not find Mr. Slate" );
108
109         j = uta_has_str( buf, "Mrs. Slate", ',', 27 );
110         errors += fail_if_true( j >= 0, "has string not found Mrs. Slate" );
111
112         // ------------ host name 2 ip tests ---------------------------------------------------------
113         hname = uta_h2ip( "192.168.1.2" );
114         errors += fail_not_equal( strcmp( hname, "192.168.1.2" ), 0, "h2ip did not return IP address when given address" );
115         errors += fail_if_nil( hname, "h2ip did not return a pointer" );
116
117         hname = uta_h2ip( "yahoo.com" );
118         errors += fail_if_nil( hname, "h2ip did not return a pointer" );
119
120         hname = uta_h2ip( "yahoo.com:1234" );                                                   // should ignore the port
121         errors += fail_if_nil( hname, "h2ip did not return a pointer" );
122
123         // ------------ rtg lookup test -------------------------------------------------------------
124         ctx.rtg_port = 0;
125         ctx.rtg_addr = NULL;
126
127         i = uta_lookup_rtg( NULL );                                             // ensure it handles a nil context
128         errors += fail_if_true( i, "rtg lookup returned that it found something when not expected to (nil context)" );
129
130         setenv( "RMR_RTG_SVC", "localhost:1234", 1);
131         i = uta_lookup_rtg( &ctx );
132         errors += fail_if_false( i, "rtg lookup returned that it did not find something when expected to" );
133         errors += fail_if_nil( ctx.rtg_addr, "rtg lookup did not return a pointer (with port)" );
134         errors += fail_not_equal( ctx.rtg_port, 1234, "rtg lookup did not capture the port" );
135
136         setenv( "RMR_RTG_SVC", "localhost", 1);                 // test ability to generate default port
137         uta_lookup_rtg( &ctx );
138         errors += fail_if_nil( ctx.rtg_addr, "rtg lookup did not return a pointer (no port)" );
139         errors += fail_not_equal( ctx.rtg_port, 5656, "rtg lookup did not return default port" );
140
141         unsetenv( "RMR_RTG_SVC" );                                              // this should fail as the default name (rtg) will be unknown during testing
142         i = uta_lookup_rtg( &ctx );
143         errors += fail_if_true( i, "rtg lookup returned that it found something when not expected to" );
144
145
146         // ------------ my ip stuff -----------------------------------------------------------------
147
148         if_list = mk_ip_list( "1235" );
149         errors += fail_if_nil( if_list, "mk_ip_list returned nil pointer" );
150
151         i = has_myip( NULL, NULL, ',', 128 );           // should be false if pointers are nil
152         errors += fail_if_true( i, "has_myip returned true when given nil buffer" );
153
154         i = has_myip( "buffer contents not valid", NULL, ',', 128 );            // should be false if pointers are nil
155         errors += fail_if_true( i, "has_myip returned true when given nil list" );
156
157         i = has_myip( "buffer contents not valid", NULL, ',', 1 );                      // should be false if max < 2
158         errors += fail_if_true( i, "has_myip returned true when given small max value" );
159
160         i = has_myip( "buffer.contents.not.valid", if_list, ',', 128 );         // should be false as there is nothing valid in the list
161         errors += fail_if_true( i, "has_myip returned true when given a buffer with no valid info" );
162
163
164         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
165         if_list = mk_ip_list( "1235" );
166         errors += fail_if_nil( if_list, "mk_ip_list with env set returned nil pointer" );
167
168         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
169         errors += fail_if_false( i, "has_myip did not find IP in middle of list" );
170
171         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
172         errors += fail_if_false( i, "has_myip did not find IP at head of list" );
173
174         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
175         errors += fail_if_false( i, "has_myip did not find IP at tail of list" );
176
177         i = has_myip( "192.168.4.30:1235", if_list, ',', 128 );                                                                                 // should find our ip when only in list
178         errors += fail_if_false( i, "has_myip did not find IP when only one in list" );
179
180         return errors > 0;                      // overall exit code bad if errors
181 }