Add safe connect, fix possible seg fault in RTC
[ric-plt/lib/rmr.git] / test / si95_test.c
1 // :vi sw=4 ts=4 noet:
2 /*
3 ==================================================================================
4         Copyright (c) 2020 Nokia
5         Copyright (c) 2020 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:       si95_test.c
23         Abstract:       This is the main driver to test the si95 core functions
24                                 (within rmr/src/si/src/si95). 
25
26         Author:         E. Scott Daniels
27         Date:           6 March 2018
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
39 #include <netdb.h>              // these four needed for si address tests
40 #include <stdio.h>
41 #include <ctype.h>
42 #include <netinet/in.h>
43
44
45
46 #include <unistd.h>
47 #include <stdio.h>
48 #include <stdlib.h>
49 #include <strings.h>
50 #include <errno.h>
51 #include <string.h>
52 #include <stdint.h>
53 #include <ctype.h>
54 #include <sys/epoll.h>
55 #include <pthread.h>
56 #include <semaphore.h>
57
58 #define DEBUG 1
59
60                                                                                         // specific test tools in this directory
61 #undef NNG_UNDER_TEST                                           // NNG is NOT under test so undefine if set
62 #define NO_EMULATION 1                                          // no emulation of transport functions
63 #define NO_PRIVATE_HEADERS 1                            // no rmr_si or rmr_nng headers
64 #define NO_DUMMY_RMR 1                                          // no msg things
65
66 #include "test_support.c"                                       // things like fail_if()
67 #include "test_transport_em.c"                          // system/transport emulation (open, close, connect, etc)
68
69 /*
70 #include "rmr.h"                                        // things the users see
71 #include "rmr_symtab.h"
72 #include "rmr_agnostic.h"                       // transport agnostic header
73 */
74 #include <rmr_logging.h>
75 #include <logging.c>
76
77 #include <si95/siaddress.c>
78 //#include <si95/sialloc.c>
79 //#include <si95/sibldpoll.c>
80 //#include <si95/sicbreg.c>
81 //#include <si95/sicbstat.c>
82 //#include <si95/siclose.c>
83 #include <si95/siconnect.c>
84 #include <si95/siestablish.c>
85 //#include <si95/sigetadd.c>
86 //#include <si95/sigetname.c>
87 #include <si95/siinit.c>
88 #include <si95/silisten.c>
89 #include <si95/sinew.c>
90 //#include <si95/sinewses.c>
91 //#include <si95/sipoll.c>
92 //#include <si95/sircv.c>
93 //#include <si95/sisend.c>
94 //#include <si95/sisendt.c>
95 #include <si95/sishutdown.c>
96 #include <si95/siterm.c>
97 #include <si95/sitrash.c>
98 //#include <si95/siwait.c>
99
100 // ---------------------------------------------------------------------
101
102 void*   si_ctx = NULL;                  // a global context might be useful
103
104 // ---------------------------------------------------------------------
105
106 /*
107         Memory allocation/free related tests
108 */
109 static int memory( ) {
110         int             errors = 0;
111         void*   ptr;
112         void*   iptr;
113
114         // ---- SInew ----------------
115         ptr = SInew( 100 );                             // invalid block type should return nil
116         errors += fail_not_nil( ptr, "memory: sinew did not return nil when given a valid struct type" );
117         SItrash( 100, NULL );                           // drive trash for coverage
118
119         iptr = SInew( IOQ_BLK );
120         errors += fail_if_nil( iptr, "memory: sinew returned nil when given ioq request" );
121         SItrash(  IOQ_BLK, iptr );
122
123         ptr = SInew( TP_BLK );
124         errors += fail_if_nil( ptr, "memory: sinew returned nil when given tpblk request" );
125         if( ptr ) {
126                 iptr = SInew( IOQ_BLK );
127                 ((struct tp_blk *)ptr)->squeue = iptr;
128                 SItrash(  TP_BLK, ptr );
129         }
130         
131         ptr = SInew( GI_BLK );
132         errors += fail_if_nil( ptr, "memory: sinew returned nil when given giblk request" );
133         SItrash(  GI_BLK, ptr );                // GI block cannot be trashed, ensure this (valgind will complain about a leak)
134
135
136         return errors;
137 }
138
139
140 /*
141         Test initialisation related things
142 */
143 static int init() {
144         int             errors = 0;
145
146         si_ctx = SIinitialise( 0 );
147         errors += fail_if_nil( si_ctx, "init: siinit returned a nil pointer" );
148
149         SIclr_tflags( si_ctx, 0x00 );           // drive for coverage; no return value from these
150         SIset_tflags( si_ctx, 0x03 );
151
152         fprintf( stderr, "<INFO> init  module finished with %d errors\n", errors );
153         return errors;
154 }
155
156 static int cleanup() {
157         int errors = 0;
158         
159         if( ! si_ctx ) {
160                 return 0;
161         }
162
163         SItp_stats( si_ctx );           // drive for coverage only
164         SItp_stats( NULL );
165
166         SIconnect( si_ctx, "localhost:43086" );         // ensure context has a tp block to free on shutdown
167         SIshutdown( si_ctx );
168
169
170         fprintf( stderr, "<INFO> cleanup  module finished with %d errors\n", errors );
171         return errors;
172 }
173
174 /*
175         Address related tests.
176 */
177 static int addr() {
178         int errors = 0;
179         int l;
180         struct sockaddr* addr;
181         char buf1[4096];
182         char buf2[4096];
183         char* dest;
184
185         addr = (struct sockaddr *) malloc( sizeof( struct sockaddr ) );
186 /*
187         l = SIgenaddr( "    [ff02::4]:4567", PF_INET6, IPPROTO_TCP, SOCK_STREAM, &addr );
188
189         SIgenaddr( "    [ff02::4]:4567", PF_INET6, IPPROTO_TCP, SOCK_STREAM, &addr );
190 */
191
192         dest = NULL;
193         snprintf( buf1, sizeof( buf1 ), "   [ff02::5:4001" );           // invalid address, drive leading space eater too
194         l = SIaddress( buf1, (void **)  &dest, AC_TOADDR6 );
195         errors += fail_if_true( l > 0, "to addr6 with bad addr convdersion returned valid len" );
196
197         snprintf( buf1, sizeof( buf1 ), "[ff02::5]:4002" );             // v6 might not be supported so failure is OK here
198         l=SIaddress( buf1, (void **) &dest, AC_TOADDR6 );
199         errors += fail_if_true( l < 1, "to addr convdersion failed" );
200
201         snprintf( buf1, sizeof( buf1 ), "localhost:43086" );
202         l = SIaddress( buf1, (void **) &dest, AC_TOADDR );
203         errors += fail_if_true( l < 1, "to addr convdersion failed" );
204
205         snprintf( buf1, sizeof( buf1 ), "localhost:4004" );
206         l = SIaddress( buf1, (void **) &dest, AC_TODOT );
207         errors += fail_if_true( l < 1, "to dot convdersion failed" );
208
209         fprintf( stderr, "<INFO> addr module finished with %d errors\n", errors );
210         return errors;
211
212 }
213
214
215 /*
216         Connection oriented tests.
217 */
218 static int conn( ) {
219         int errors = 0;
220         int state;
221
222         state = SIconnect( si_ctx, "localhost:4567" );          // driver regular connect
223         errors += fail_if_true( state < 0, "connect to low port failed" );
224
225         state = SIconnect( si_ctx, "localhost:43086" );         // drive save connect with good return code
226         errors += fail_if_true( state < 0, "connect to high port failed" );
227
228         tpem_set_addr_dup_state( 1 );                           // force get sockket name emulation to return a duplicate address
229         state = SIconnect( si_ctx, "localhost:43086" );         // drive save connect with good return code
230         errors += fail_if_true( state >= 0, "forced dup connect did not return error" );
231
232         tpem_set_addr_dup_state( 0 );                           // force get sockket name emulation to return a duplicate address
233         tpem_set_conn_state( 1 );
234         state = SIconnect( si_ctx, "localhost:4567" );          // driver regular connect
235         errors += fail_if_true( state >= 0, "connect to low port successful when failure expected" );
236
237         tpem_set_sock_state( 1 );               // make scoket calls fail
238         state = SIconnect( si_ctx, "localhost:4567" );          // driver regular connect
239         errors += fail_if_true( state >= 0, "connect to low port successful when socket based failure expected" );
240
241         tpem_set_sock_state( 0 );
242
243         state = SIlistener( si_ctx, TCP_DEVICE, "0.0.0.0:4567" );
244         errors += fail_if_true( state < 0, "listen failed" );
245
246         tpem_set_bind_state( 1 );
247         state = SIlistener( si_ctx, TCP_DEVICE, "0.0.0.0:4567" );
248         errors += fail_if_true( state >= 0, "listen successful when bind error set" );
249         tpem_set_bind_state( 0 );
250
251
252         fprintf( stderr, "<INFO> conn module finished with %d errors\n", errors );
253         return errors;
254 }
255
256 /*
257         Drive tests...
258 */
259 int main() {
260         int errors = 0;
261
262         rmr_set_vlevel( 5 );                    // enable all debugging
263
264         fprintf( stderr, "\n<INFO> starting SI95 tests\n" );
265
266         errors += init();
267         errors += memory();
268         errors += addr();
269         errors += conn();
270         errors += cleanup();
271
272         fprintf( stderr, "<INFO> testing finished\n" );
273         if( errors == 0 ) {
274                 fprintf( stderr, "<PASS> all tests were OK\n\n" );
275         } else {
276                 fprintf( stderr, "<FAIL> %d errors in SI95 core code\n\n", errors );
277         }
278
279         return !!errors;
280 }