3 ==================================================================================
4 Copyright (c) 2020 Nokia
5 Copyright (c) 2020 AT&T Intellectual Property.
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
11 http://www.apache.org/licenses/LICENSE-2.0
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 ==================================================================================
23 Abstract: This is the main driver to test the si95 core functions
24 (within rmr/src/si/src/si95).
26 Author: E. Scott Daniels
39 #include <netdb.h> // these four needed for si address tests
42 #include <netinet/in.h>
54 #include <sys/epoll.h>
56 #include <semaphore.h>
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
66 #include "test_support.c" // things like fail_if()
67 #include "test_transport_em.c" // system/transport emulation (open, close, connect, etc)
70 #include "rmr.h" // things the users see
71 #include "rmr_symtab.h"
72 #include "rmr_agnostic.h" // transport agnostic header
74 #include <rmr_logging.h>
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>
100 // ---------------------------------------------------------------------
102 void* si_ctx = NULL; // a global context might be useful
104 // ---------------------------------------------------------------------
107 Fake callback to register.
109 static int test_cb( void* data ) {
114 Returns error for coverage testing of CB calls
116 static int test_cb_err( void* data ) {
121 Memory allocation/free related tests
123 static int memory( ) {
128 // ---- SInew ----------------
129 ptr = SInew( 100 ); // invalid block type should return nil
130 errors += fail_not_nil( ptr, "memory: sinew did not return nil when given a valid struct type" );
131 SItrash( 100, NULL ); // drive trash for coverage
133 iptr = SInew( IOQ_BLK );
134 errors += fail_if_nil( iptr, "memory: sinew returned nil when given ioq request" );
135 SItrash( IOQ_BLK, iptr );
137 ptr = SInew( TP_BLK );
138 errors += fail_if_nil( ptr, "memory: sinew returned nil when given tpblk request" );
140 iptr = SInew( IOQ_BLK );
141 ((struct tp_blk *)ptr)->squeue = iptr;
142 SItrash( TP_BLK, ptr );
145 ptr = SInew( GI_BLK );
146 errors += fail_if_nil( ptr, "memory: sinew returned nil when given giblk request" );
147 SItrash( GI_BLK, ptr ); // GI block cannot be trashed, ensure this (valgind will complain about a leak)
149 fprintf( stderr, "<INFO> memory module finished with %d errors\n", errors );
154 Test initialisation related things
159 si_ctx = SIinitialise( 0 );
160 errors += fail_if_nil( si_ctx, "init: siinit returned a nil pointer" );
162 SIclr_tflags( si_ctx, 0x00 ); // drive for coverage; no return value from these
163 SIset_tflags( si_ctx, 0x03 );
165 fprintf( stderr, "<INFO> init module finished with %d errors\n", errors );
169 static int cleanup() {
173 fprintf( stderr, "<INFO> cleanup has no context to use\n" );
177 fprintf( stderr, "<INFO> cleanup running\n" );
178 SIcbstat( si_ctx, SI_RET_UNREG, SI_CB_SECURITY );
179 SIcbstat( si_ctx, SI_RET_QUIT, SI_CB_SECURITY );
181 SItp_stats( si_ctx ); // drive for coverage only
184 SIconnect( si_ctx, "localhost:43086" ); // ensure context has a tp block to free on shutdown
189 fprintf( stderr, "<INFO> cleanup module finished with %d errors\n", errors );
194 Address related tests.
199 struct sockaddr* addr;
204 addr = (struct sockaddr *) malloc( sizeof( struct sockaddr ) );
206 l = SIgenaddr( " [ff02::4]:4567", PF_INET6, IPPROTO_TCP, SOCK_STREAM, &addr );
208 SIgenaddr( " [ff02::4]:4567", PF_INET6, IPPROTO_TCP, SOCK_STREAM, &addr );
212 snprintf( buf1, sizeof( buf1 ), " [ff02::5:4001" ); // invalid address, drive leading space eater too
213 l = SIaddress( buf1, (void **) &dest, AC_TOADDR6 );
214 errors += fail_if_true( l > 0, "to addr6 with bad addr convdersion returned valid len" );
216 snprintf( buf1, sizeof( buf1 ), "[ff02::5]:4002" ); // v6 might not be supported so failure is OK here; driving for coverage
217 l=SIaddress( buf1, (void **) &dest, AC_TOADDR6 );
219 snprintf( buf1, sizeof( buf1 ), "localhost:43086" );
220 l = SIaddress( buf1, (void **) &dest, AC_TOADDR );
221 errors += fail_if_true( l < 1, "to addr convdersion failed" );
223 snprintf( buf1, sizeof( buf1 ), "localhost:4004" );
224 l = SIaddress( buf1, (void **) &dest, AC_TODOT );
225 errors += fail_if_true( l < 1, "to dot convdersion failed" );
227 fprintf( stderr, "<INFO> addr module finished with %d errors\n", errors );
233 Connection oriented tests.
238 int cfd = 3; // fd for close
241 state = SIconnect( si_ctx, "localhost:4567" ); // driver regular connect
242 errors += fail_if_true( state < 0, "connect to low port failed" );
244 state = SIconnect( si_ctx, "localhost:43086" ); // drive save connect with good return code
245 errors += fail_if_true( state < 0, "connect to high port failed" );
247 tpem_set_addr_dup_state( 1 ); // force get sockket name emulation to return a duplicate address
248 state = SIconnect( si_ctx, "localhost:43086" ); // drive save connect with good return code
249 errors += fail_if_true( state >= 0, "forced dup connect did not return error" );
251 tpem_set_addr_dup_state( 0 ); // back to normal
252 tpem_set_conn_state( -1 );
253 state = SIconnect( si_ctx, "localhost:4567" ); // driver regular connect
254 errors += fail_if_true( state >= 0, "connect to low port successful when failure expected" );
255 tpem_set_conn_state( 3 );
257 tpem_set_sock_state( 1 ); // make scoket calls fail
258 state = SIconnect( si_ctx, "localhost:4567" ); // driver regular connect
259 errors += fail_if_true( state >= 0, "connect to low port successful when socket based failure expected" );
261 tpem_set_sock_state( 0 );
263 state = SIlistener( si_ctx, TCP_DEVICE, "0.0.0.0:4567" );
264 errors += fail_if_true( state < 0, "listen failed" );
266 tpem_set_bind_state( 1 );
267 state = SIlistener( si_ctx, TCP_DEVICE, "0.0.0.0:4567" );
268 errors += fail_if_true( state >= 0, "listen successful when bind error set" );
269 tpem_set_bind_state( 0 );
271 SIbldpoll( si_ctx ); // for coverage. no return value and nothing we can check
273 state = SIclose( NULL, 0 ); //coverage
274 errors += fail_if_true( state != SI_ERROR, "close given nil context returned success" );
276 state = SIclose( si_ctx, cfd );
277 errors += fail_if_true( state == SI_ERROR, "close given good context and good fd returned error" );
279 state = SIclose( si_ctx, 5000 ); // out of range fd
280 errors += fail_if_true( state != SI_ERROR, "close given good context and bad fd returned success" );
282 state = SIclose( si_ctx, TCP_LISTEN_PORT ); // close listener
283 errors += fail_if_true( state == SI_ERROR, "close given good context and listener fd returned error" );
285 state = SIclose( si_ctx, UDP_PORT ); // close first open udp port (should not be there)
286 errors += fail_if_true( state != SI_ERROR, "close given good context and udp generic fd returned error" );
288 buf = SIgetname( 3 );
289 if( fail_if_true( buf == NULL, "get name failed to return a buffer" ) ) {
292 errors += fail_if_true( buf[0] == 0, "get name returned buf with emtpy string" );
295 fprintf( stderr, "<INFO> conn module finished with %d errors\n", errors );
300 Misc tests that just don't fit in another bucket.
306 SIcbreg( NULL, SI_CB_SECURITY, test_cb, NULL ); // coverage only, no return value no verification
307 SIcbreg( si_ctx, SI_CB_SECURITY, test_cb, NULL );
310 SIgetaddr( si_ctx, buf );
311 errors += fail_if_true( buf[0] == 0, "get address failed" );
312 fprintf( stderr, "<INFO> get address returns (%s)\n", buf );
314 fprintf( stderr, "<INFO> misc module finished with %d errors\n", errors );
320 New session (accept) testing.
322 static int new_sess( ) {
325 struct tp_blk *tpptr;
328 tpptr = SInew( TP_BLK );
330 tpptr->flags |= TPF_LISTENFD;
332 tpem_set_accept_fd( -1 ); // accept will "fail" for coverage
333 status = SInewsession( si_ctx, tpptr );
334 errors += fail_if_true( status != SI_ERROR, "newsession did not fail when accept fails" );
336 tpem_set_accept_fd( 5 ); // accept will return a good fd
337 SIcbreg( si_ctx, SI_CB_SECURITY, test_cb_err, NULL ); // register error and drive new session for error coverage
338 status = SInewsession( si_ctx, tpptr );
339 errors += fail_if_true( status >= 0, "newsession did failed when accept was good" );
341 tpem_set_accept_fd( 6 ); // accept will return a good fd
342 SIset_tflags( si_ctx, SI_TF_NODELAY | SI_TF_FASTACK ); // flip options for coverage in new sess
343 SIcbreg( si_ctx, SI_CB_CONN, test_cb, NULL ); // drive connection for coverage
344 SIcbreg( si_ctx, SI_CB_SECURITY, test_cb, NULL );
345 status = SInewsession( si_ctx, tpptr );
346 errors += fail_if_true( status < 0, "newsession did failed when accept was good" );
348 fprintf( stderr, "<INFO> new_sess module finished with %d errors\n", errors );
355 static int send_tests( ) {
361 len = snprintf( buf, 100, "Heaven knows I'm miserable now!" );
363 state = SIsendt( si_ctx, 9999, buf, len );
364 errors += fail_if_true( state >= 0, "send given fd out of range did not fail" );
366 state = SIsendt( si_ctx, -1, buf, len );
367 errors += fail_if_true( state >= 0, "send given neg fd did not fail" );
369 SIsendt( si_ctx, 6, buf, len );
371 tpem_set_send_err( 99 );
372 SIsendt( si_ctx, 6, buf, len );
374 tpem_set_send_err( 0 );
375 tpem_set_sel_blk( 1 );
376 SIsendt( si_ctx, 6, buf, len );
378 tpem_set_sel_blk( 0 );
379 tpem_set_selef_fd( 6 ); // will cause send to fail and fd6 to close
380 SIsendt( si_ctx, 6, buf, len );
386 // ----------------------------------------------------------------------------------------
394 rmr_set_vlevel( 5 ); // enable all debugging
396 fprintf( stderr, "\n<INFO> starting SI95 tests\n" );
404 errors += new_sess(); // should leave a "connected" session at fd == 6
405 errors += send_tests();
409 test_summary( errors, "SI95 tests" );
411 fprintf( stderr, "<PASS> all tests were OK\n\n" );
413 fprintf( stderr, "<FAIL> %d errors in SI95 core code\n\n", errors );