E. Scott Daniels | 4d1f9bf | 2020-03-06 12:29:28 -0500 | [diff] [blame] | 1 | // :vi sw=4 ts=4 noet: |
| 2 | /* |
| 3 | ================================================================================== |
E. Scott Daniels | 11838bc | 2021-04-22 16:34:08 -0400 | [diff] [blame] | 4 | Copyright (c) 2020-2021 Nokia |
| 5 | Copyright (c) 2020-2021 AT&T Intellectual Property. |
E. Scott Daniels | 4d1f9bf | 2020-03-06 12:29:28 -0500 | [diff] [blame] | 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 |
E. Scott Daniels | fc2112d | 2020-04-21 12:51:05 -0400 | [diff] [blame] | 24 | (within rmr/src/si/src/si95). |
E. Scott Daniels | 4d1f9bf | 2020-03-06 12:29:28 -0500 | [diff] [blame] | 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> |
E. Scott Daniels | 4d1f9bf | 2020-03-06 12:29:28 -0500 | [diff] [blame] | 35 | #include <pthread.h> |
| 36 | #include <ctype.h> |
E. Scott Daniels | 11838bc | 2021-04-22 16:34:08 -0400 | [diff] [blame] | 37 | #include <unistd.h> |
| 38 | #include <strings.h> |
| 39 | #include <stdint.h> |
| 40 | #include <sys/epoll.h> |
| 41 | #include <semaphore.h> |
| 42 | |
E. Scott Daniels | 4d1f9bf | 2020-03-06 12:29:28 -0500 | [diff] [blame] | 43 | |
E. Scott Daniels | 0a58458 | 2020-04-06 16:42:32 -0400 | [diff] [blame] | 44 | #include <netdb.h> // these four needed for si address tests |
| 45 | #include <stdio.h> |
| 46 | #include <ctype.h> |
| 47 | #include <netinet/in.h> |
| 48 | |
E. Scott Daniels | 4d1f9bf | 2020-03-06 12:29:28 -0500 | [diff] [blame] | 49 | #define DEBUG 1 |
| 50 | |
| 51 | // specific test tools in this directory |
E. Scott Daniels | fc2112d | 2020-04-21 12:51:05 -0400 | [diff] [blame] | 52 | #undef NNG_UNDER_TEST // NNG is NOT under test so undefine if set |
E. Scott Daniels | 4d1f9bf | 2020-03-06 12:29:28 -0500 | [diff] [blame] | 53 | #define NO_EMULATION 1 // no emulation of transport functions |
| 54 | #define NO_PRIVATE_HEADERS 1 // no rmr_si or rmr_nng headers |
| 55 | #define NO_DUMMY_RMR 1 // no msg things |
E. Scott Daniels | 4d1f9bf | 2020-03-06 12:29:28 -0500 | [diff] [blame] | 56 | |
E. Scott Daniels | 43b7981 | 2020-04-17 13:00:28 -0400 | [diff] [blame] | 57 | #include "test_support.c" // things like fail_if() |
| 58 | #include "test_transport_em.c" // system/transport emulation (open, close, connect, etc) |
E. Scott Daniels | 4d1f9bf | 2020-03-06 12:29:28 -0500 | [diff] [blame] | 59 | |
E. Scott Daniels | 4d1f9bf | 2020-03-06 12:29:28 -0500 | [diff] [blame] | 60 | #include <rmr_logging.h> |
| 61 | #include <logging.c> |
| 62 | |
E. Scott Daniels | 11838bc | 2021-04-22 16:34:08 -0400 | [diff] [blame] | 63 | |
| 64 | // ------------- dummy functions to force edge cases when we can --------------------------------------- |
| 65 | |
| 66 | #define SYSTEM_UNDER_TEST 1 // for conditional code |
| 67 | |
| 68 | /* |
| 69 | These are global so they can be reset for individual tests. |
| 70 | */ |
| 71 | static int good_mallocs = 0; // number of initial good malocs before failurs |
| 72 | static int bad_mallocs = 1; // number of failed mallocs (consecutive) |
| 73 | |
| 74 | static void* test_malloc( size_t n ) { |
| 75 | |
Alexandre Huff | fa45400 | 2022-01-07 14:20:28 -0300 | [diff] [blame] | 76 | fprintf( stderr, ">>>> test malloc: %d %d\n", good_mallocs, bad_mallocs ); |
E. Scott Daniels | 11838bc | 2021-04-22 16:34:08 -0400 | [diff] [blame] | 77 | if( good_mallocs ) { |
| 78 | good_mallocs--; |
| 79 | return malloc( n ); |
| 80 | } |
| 81 | |
| 82 | if( bad_mallocs ) { |
| 83 | bad_mallocs--; |
| 84 | errno = ENOMEM; |
| 85 | return NULL; |
| 86 | } |
| 87 | |
| 88 | return malloc( n ); |
| 89 | } |
| 90 | |
| 91 | // ----------------------------------------------------------------------------------------------------- |
| 92 | |
E. Scott Daniels | 0a58458 | 2020-04-06 16:42:32 -0400 | [diff] [blame] | 93 | #include <si95/siaddress.c> |
E. Scott Daniels | 4d1f9bf | 2020-03-06 12:29:28 -0500 | [diff] [blame] | 94 | //#include <si95/sialloc.c> |
E. Scott Daniels | cc314e0 | 2020-09-15 10:27:34 -0400 | [diff] [blame] | 95 | #include <si95/sibldpoll.c> |
| 96 | #include <si95/sicbreg.c> |
| 97 | #include <si95/sicbstat.c> |
| 98 | #include <si95/siclose.c> |
E. Scott Daniels | 0a58458 | 2020-04-06 16:42:32 -0400 | [diff] [blame] | 99 | #include <si95/siconnect.c> |
| 100 | #include <si95/siestablish.c> |
E. Scott Daniels | cc314e0 | 2020-09-15 10:27:34 -0400 | [diff] [blame] | 101 | #include <si95/sigetadd.c> |
| 102 | #include <si95/sigetname.c> |
E. Scott Daniels | 4d1f9bf | 2020-03-06 12:29:28 -0500 | [diff] [blame] | 103 | #include <si95/siinit.c> |
E. Scott Daniels | 43b7981 | 2020-04-17 13:00:28 -0400 | [diff] [blame] | 104 | #include <si95/silisten.c> |
E. Scott Daniels | 4d1f9bf | 2020-03-06 12:29:28 -0500 | [diff] [blame] | 105 | #include <si95/sinew.c> |
E. Scott Daniels | cc314e0 | 2020-09-15 10:27:34 -0400 | [diff] [blame] | 106 | #include <si95/sinewses.c> |
E. Scott Daniels | 05850e0 | 2020-11-11 15:57:22 -0500 | [diff] [blame] | 107 | #include <si95/sipoll.c> |
E. Scott Daniels | 4d1f9bf | 2020-03-06 12:29:28 -0500 | [diff] [blame] | 108 | //#include <si95/sircv.c> |
E. Scott Daniels | 05850e0 | 2020-11-11 15:57:22 -0500 | [diff] [blame] | 109 | #include <si95/sisend.c> |
E. Scott Daniels | cc314e0 | 2020-09-15 10:27:34 -0400 | [diff] [blame] | 110 | #include <si95/sisendt.c> |
E. Scott Daniels | 4d1f9bf | 2020-03-06 12:29:28 -0500 | [diff] [blame] | 111 | #include <si95/sishutdown.c> |
| 112 | #include <si95/siterm.c> |
| 113 | #include <si95/sitrash.c> |
E. Scott Daniels | 11838bc | 2021-04-22 16:34:08 -0400 | [diff] [blame] | 114 | #define malloc test_malloc |
| 115 | #include <si95/siwait.c> |
| 116 | #undef malloc |
E. Scott Daniels | 4d1f9bf | 2020-03-06 12:29:28 -0500 | [diff] [blame] | 117 | |
E. Scott Daniels | 0a58458 | 2020-04-06 16:42:32 -0400 | [diff] [blame] | 118 | // --------------------------------------------------------------------- |
| 119 | |
| 120 | void* si_ctx = NULL; // a global context might be useful |
| 121 | |
| 122 | // --------------------------------------------------------------------- |
E. Scott Daniels | 4d1f9bf | 2020-03-06 12:29:28 -0500 | [diff] [blame] | 123 | |
| 124 | /* |
E. Scott Daniels | cc314e0 | 2020-09-15 10:27:34 -0400 | [diff] [blame] | 125 | Fake callback to register. |
| 126 | */ |
| 127 | static int test_cb( void* data ) { |
| 128 | return 0; |
| 129 | } |
| 130 | |
| 131 | /* |
| 132 | Returns error for coverage testing of CB calls |
| 133 | */ |
| 134 | static int test_cb_err( void* data ) { |
| 135 | return -1; |
| 136 | } |
| 137 | |
| 138 | /* |
E. Scott Daniels | 4d1f9bf | 2020-03-06 12:29:28 -0500 | [diff] [blame] | 139 | Memory allocation/free related tests |
| 140 | */ |
| 141 | static int memory( ) { |
| 142 | int errors = 0; |
| 143 | void* ptr; |
| 144 | void* iptr; |
| 145 | |
| 146 | // ---- SInew ---------------- |
| 147 | ptr = SInew( 100 ); // invalid block type should return nil |
| 148 | errors += fail_not_nil( ptr, "memory: sinew did not return nil when given a valid struct type" ); |
| 149 | SItrash( 100, NULL ); // drive trash for coverage |
| 150 | |
| 151 | iptr = SInew( IOQ_BLK ); |
| 152 | errors += fail_if_nil( iptr, "memory: sinew returned nil when given ioq request" ); |
E. Scott Daniels | 4d1f9bf | 2020-03-06 12:29:28 -0500 | [diff] [blame] | 153 | SItrash( IOQ_BLK, iptr ); |
| 154 | |
| 155 | ptr = SInew( TP_BLK ); |
| 156 | errors += fail_if_nil( ptr, "memory: sinew returned nil when given tpblk request" ); |
| 157 | if( ptr ) { |
E. Scott Daniels | d961525 | 2020-04-01 14:01:02 -0400 | [diff] [blame] | 158 | iptr = SInew( IOQ_BLK ); |
E. Scott Daniels | 4d1f9bf | 2020-03-06 12:29:28 -0500 | [diff] [blame] | 159 | ((struct tp_blk *)ptr)->squeue = iptr; |
| 160 | SItrash( TP_BLK, ptr ); |
| 161 | } |
E. Scott Daniels | fc2112d | 2020-04-21 12:51:05 -0400 | [diff] [blame] | 162 | |
E. Scott Daniels | 4d1f9bf | 2020-03-06 12:29:28 -0500 | [diff] [blame] | 163 | ptr = SInew( GI_BLK ); |
| 164 | errors += fail_if_nil( ptr, "memory: sinew returned nil when given giblk request" ); |
E. Scott Daniels | d961525 | 2020-04-01 14:01:02 -0400 | [diff] [blame] | 165 | SItrash( GI_BLK, ptr ); // GI block cannot be trashed, ensure this (valgind will complain about a leak) |
Alexandre Huff | fa45400 | 2022-01-07 14:20:28 -0300 | [diff] [blame] | 166 | free( ptr ); // we can free GI block only in tests |
E. Scott Daniels | 4d1f9bf | 2020-03-06 12:29:28 -0500 | [diff] [blame] | 167 | |
E. Scott Daniels | cc314e0 | 2020-09-15 10:27:34 -0400 | [diff] [blame] | 168 | fprintf( stderr, "<INFO> memory module finished with %d errors\n", errors ); |
E. Scott Daniels | 4d1f9bf | 2020-03-06 12:29:28 -0500 | [diff] [blame] | 169 | return errors; |
| 170 | } |
| 171 | |
E. Scott Daniels | 4d1f9bf | 2020-03-06 12:29:28 -0500 | [diff] [blame] | 172 | /* |
| 173 | Test initialisation related things |
| 174 | */ |
| 175 | static int init() { |
| 176 | int errors = 0; |
| 177 | |
| 178 | si_ctx = SIinitialise( 0 ); |
| 179 | errors += fail_if_nil( si_ctx, "init: siinit returned a nil pointer" ); |
| 180 | |
| 181 | SIclr_tflags( si_ctx, 0x00 ); // drive for coverage; no return value from these |
| 182 | SIset_tflags( si_ctx, 0x03 ); |
| 183 | |
E. Scott Daniels | 43b7981 | 2020-04-17 13:00:28 -0400 | [diff] [blame] | 184 | fprintf( stderr, "<INFO> init module finished with %d errors\n", errors ); |
E. Scott Daniels | 4d1f9bf | 2020-03-06 12:29:28 -0500 | [diff] [blame] | 185 | return errors; |
| 186 | } |
| 187 | |
E. Scott Daniels | 0a58458 | 2020-04-06 16:42:32 -0400 | [diff] [blame] | 188 | static int cleanup() { |
| 189 | int errors = 0; |
E. Scott Daniels | fc2112d | 2020-04-21 12:51:05 -0400 | [diff] [blame] | 190 | |
E. Scott Daniels | 0a58458 | 2020-04-06 16:42:32 -0400 | [diff] [blame] | 191 | if( ! si_ctx ) { |
E. Scott Daniels | cc314e0 | 2020-09-15 10:27:34 -0400 | [diff] [blame] | 192 | fprintf( stderr, "<INFO> cleanup has no context to use\n" ); |
E. Scott Daniels | 0a58458 | 2020-04-06 16:42:32 -0400 | [diff] [blame] | 193 | return 0; |
| 194 | } |
| 195 | |
E. Scott Daniels | cc314e0 | 2020-09-15 10:27:34 -0400 | [diff] [blame] | 196 | fprintf( stderr, "<INFO> cleanup running\n" ); |
| 197 | SIcbstat( si_ctx, SI_RET_UNREG, SI_CB_SECURITY ); |
| 198 | SIcbstat( si_ctx, SI_RET_QUIT, SI_CB_SECURITY ); |
| 199 | |
E. Scott Daniels | 43b7981 | 2020-04-17 13:00:28 -0400 | [diff] [blame] | 200 | SItp_stats( si_ctx ); // drive for coverage only |
| 201 | SItp_stats( NULL ); |
| 202 | |
E. Scott Daniels | 8c6756d | 2021-04-19 15:13:51 -0400 | [diff] [blame] | 203 | SIconnect( si_ctx, "127.0.0.1:43086" ); // ensure context has a tp block to free on shutdown |
E. Scott Daniels | fc2112d | 2020-04-21 12:51:05 -0400 | [diff] [blame] | 204 | SIshutdown( NULL ); |
| 205 | SIabort( si_ctx ); |
E. Scott Daniels | 0a58458 | 2020-04-06 16:42:32 -0400 | [diff] [blame] | 206 | |
Alexandre Huff | fa45400 | 2022-01-07 14:20:28 -0300 | [diff] [blame] | 207 | // cleaning up the remaining global resources |
| 208 | struct ginfo_blk *gptr = (struct ginfo_blk*)si_ctx; |
| 209 | SItrash( TP_BLK, gptr->tplist ); |
| 210 | free( gptr->tp_map ); |
| 211 | free( gptr->rbuf ); |
| 212 | free( gptr->cbtab ); |
| 213 | free( si_ctx ); |
E. Scott Daniels | 43b7981 | 2020-04-17 13:00:28 -0400 | [diff] [blame] | 214 | |
| 215 | fprintf( stderr, "<INFO> cleanup module finished with %d errors\n", errors ); |
E. Scott Daniels | 0a58458 | 2020-04-06 16:42:32 -0400 | [diff] [blame] | 216 | return errors; |
| 217 | } |
| 218 | |
| 219 | /* |
| 220 | Address related tests. |
| 221 | */ |
| 222 | static int addr() { |
| 223 | int errors = 0; |
| 224 | int l; |
E. Scott Daniels | 05850e0 | 2020-11-11 15:57:22 -0500 | [diff] [blame] | 225 | char buf1[4096]; // space to build buffers for xlation |
| 226 | char* hr_addr; // human readable address returned |
| 227 | void* net_addr; // a network address block of some type |
E. Scott Daniels | 0a58458 | 2020-04-06 16:42:32 -0400 | [diff] [blame] | 228 | |
E. Scott Daniels | 0a58458 | 2020-04-06 16:42:32 -0400 | [diff] [blame] | 229 | /* |
Alexandre Huff | fa45400 | 2022-01-07 14:20:28 -0300 | [diff] [blame] | 230 | struct sockaddr* addr; |
| 231 | addr = (struct sockaddr *) malloc( sizeof( struct sockaddr ) ); |
| 232 | |
E. Scott Daniels | 0a58458 | 2020-04-06 16:42:32 -0400 | [diff] [blame] | 233 | l = SIgenaddr( " [ff02::4]:4567", PF_INET6, IPPROTO_TCP, SOCK_STREAM, &addr ); |
| 234 | |
| 235 | SIgenaddr( " [ff02::4]:4567", PF_INET6, IPPROTO_TCP, SOCK_STREAM, &addr ); |
| 236 | */ |
| 237 | |
E. Scott Daniels | 05850e0 | 2020-11-11 15:57:22 -0500 | [diff] [blame] | 238 | l = SIaddress( NULL, NULL, 0 ); |
| 239 | errors += fail_if_true( l != 0, "SIaddress given two null pointers didn't return 0 len" ); |
| 240 | l = SIaddress( buf1, NULL, 0 ); |
| 241 | errors += fail_if_true( l != 0, "SIaddress given null dest pointer didn't return 0 len" ); |
E. Scott Daniels | 8c6756d | 2021-04-19 15:13:51 -0400 | [diff] [blame] | 242 | l = SIaddress( NULL, (void *) &buf1, 0 ); |
E. Scott Daniels | 05850e0 | 2020-11-11 15:57:22 -0500 | [diff] [blame] | 243 | errors += fail_if_true( l != 0, "SIaddress given null src pointer didn't return 0 len" ); |
| 244 | |
| 245 | net_addr = NULL; |
E. Scott Daniels | 0a58458 | 2020-04-06 16:42:32 -0400 | [diff] [blame] | 246 | snprintf( buf1, sizeof( buf1 ), " [ff02::5:4001" ); // invalid address, drive leading space eater too |
E. Scott Daniels | 05850e0 | 2020-11-11 15:57:22 -0500 | [diff] [blame] | 247 | l = SIaddress( buf1, (void **) &net_addr, AC_TOADDR6 ); |
E. Scott Daniels | 0a58458 | 2020-04-06 16:42:32 -0400 | [diff] [blame] | 248 | errors += fail_if_true( l > 0, "to addr6 with bad addr convdersion returned valid len" ); |
E. Scott Daniels | 05850e0 | 2020-11-11 15:57:22 -0500 | [diff] [blame] | 249 | free( net_addr ); |
E. Scott Daniels | 0a58458 | 2020-04-06 16:42:32 -0400 | [diff] [blame] | 250 | |
E. Scott Daniels | fc2112d | 2020-04-21 12:51:05 -0400 | [diff] [blame] | 251 | snprintf( buf1, sizeof( buf1 ), "[ff02::5]:4002" ); // v6 might not be supported so failure is OK here; driving for coverage |
E. Scott Daniels | 05850e0 | 2020-11-11 15:57:22 -0500 | [diff] [blame] | 252 | l = SIaddress( buf1, &net_addr, AC_TOADDR6 ); |
| 253 | if( l > 0 ) { |
E. Scott Daniels | 8c6756d | 2021-04-19 15:13:51 -0400 | [diff] [blame] | 254 | l = SIaddress( net_addr, (void *) &hr_addr, AC_TODOT ); // convert the address back to hr string |
E. Scott Daniels | 05850e0 | 2020-11-11 15:57:22 -0500 | [diff] [blame] | 255 | errors += fail_if_true( l < 1, "v6 to dot conversion failed" ); |
| 256 | errors += fail_if_nil( hr_addr, "v6 to dot conversion yields a nil pointer" ); |
| 257 | free( net_addr ); |
Alexandre Huff | fa45400 | 2022-01-07 14:20:28 -0300 | [diff] [blame] | 258 | free( hr_addr ); |
E. Scott Daniels | 05850e0 | 2020-11-11 15:57:22 -0500 | [diff] [blame] | 259 | } |
E. Scott Daniels | 0a58458 | 2020-04-06 16:42:32 -0400 | [diff] [blame] | 260 | |
| 261 | snprintf( buf1, sizeof( buf1 ), "localhost:43086" ); |
E. Scott Daniels | 05850e0 | 2020-11-11 15:57:22 -0500 | [diff] [blame] | 262 | l = SIaddress( buf1, (void **) &net_addr, AC_TOADDR ); |
| 263 | errors += fail_if_true( l < 1, "v4 to addr conversion failed" ); |
E. Scott Daniels | 0a58458 | 2020-04-06 16:42:32 -0400 | [diff] [blame] | 264 | |
E. Scott Daniels | 8c6756d | 2021-04-19 15:13:51 -0400 | [diff] [blame] | 265 | l = SIaddress( net_addr, (void *) &hr_addr, AC_TODOT ); // convert the address back to hr string |
E. Scott Daniels | 0a58458 | 2020-04-06 16:42:32 -0400 | [diff] [blame] | 266 | errors += fail_if_true( l < 1, "to dot convdersion failed" ); |
E. Scott Daniels | 05850e0 | 2020-11-11 15:57:22 -0500 | [diff] [blame] | 267 | errors += fail_if_nil( hr_addr, "v4 to dot conversion yields a nil pointer" ); |
| 268 | free( net_addr ); |
Alexandre Huff | fa45400 | 2022-01-07 14:20:28 -0300 | [diff] [blame] | 269 | free( hr_addr ); |
E. Scott Daniels | 0a58458 | 2020-04-06 16:42:32 -0400 | [diff] [blame] | 270 | |
E. Scott Daniels | 43b7981 | 2020-04-17 13:00:28 -0400 | [diff] [blame] | 271 | fprintf( stderr, "<INFO> addr module finished with %d errors\n", errors ); |
E. Scott Daniels | 0a58458 | 2020-04-06 16:42:32 -0400 | [diff] [blame] | 272 | return errors; |
E. Scott Daniels | 0a58458 | 2020-04-06 16:42:32 -0400 | [diff] [blame] | 273 | } |
| 274 | |
E. Scott Daniels | 05850e0 | 2020-11-11 15:57:22 -0500 | [diff] [blame] | 275 | /* |
| 276 | Prep related tests. These mostly drive cases that aren't driven by "normal" |
| 277 | connect, send, receive tests (e.g. UDP branches). |
| 278 | */ |
| 279 | static int prep() { |
| 280 | int errors = 0; |
| 281 | void* thing; // the thing that should be returned |
| 282 | |
| 283 | thing = SIlisten_prep( UDP_DEVICE, "localhost:1234", AF_INET ); |
| 284 | errors += fail_if_nil( thing, "listen prep udp returned nil block" ); |
Alexandre Huff | fa45400 | 2022-01-07 14:20:28 -0300 | [diff] [blame] | 285 | SItrash( TP_BLK, thing ); |
E. Scott Daniels | 05850e0 | 2020-11-11 15:57:22 -0500 | [diff] [blame] | 286 | |
| 287 | thing = SIlisten_prep( UDP_DEVICE, "localhost:1234", 84306 ); // this should fail |
| 288 | errors += fail_not_nil( thing, "listen prep udp returned valid block ptr for bogus family" ); |
| 289 | |
| 290 | thing = SIconn_prep( si_ctx, UDP_DEVICE, "localhost:1234", 84306 ); // again, expect to fail; bogus family |
| 291 | errors += fail_not_nil( thing, "conn prep udp returned valid block ptr for bogus family" ); |
| 292 | |
| 293 | return errors; |
| 294 | } |
| 295 | |
| 296 | /* |
| 297 | Polling/waiting tests. These are difficult at best because of the blocking |
| 298 | nature of things, not to mention needing to have real ports open etc. |
| 299 | */ |
| 300 | static int poll() { |
| 301 | int errors = 0; |
| 302 | int status; |
E. Scott Daniels | 11838bc | 2021-04-22 16:34:08 -0400 | [diff] [blame] | 303 | struct ginfo_blk* dummy; |
| 304 | |
| 305 | |
| 306 | dummy = SIinitialise( 0 ); // get one to fiddle to drive edge cases |
| 307 | dummy->flags |= GIF_SHUTDOWN; // shutdown edge condition |
| 308 | SIpoll( dummy, 1 ); |
| 309 | |
Alexandre Huff | fa45400 | 2022-01-07 14:20:28 -0300 | [diff] [blame] | 310 | free( dummy->tp_map ); |
| 311 | free( dummy->rbuf ); |
| 312 | free( dummy->cbtab ); |
| 313 | |
E. Scott Daniels | 11838bc | 2021-04-22 16:34:08 -0400 | [diff] [blame] | 314 | memset( dummy, 0, sizeof( *dummy ) ); // force bad cookie check code to drive |
| 315 | SIpoll( dummy, 1 ); |
E. Scott Daniels | 05850e0 | 2020-11-11 15:57:22 -0500 | [diff] [blame] | 316 | |
Alexandre Huff | fa45400 | 2022-01-07 14:20:28 -0300 | [diff] [blame] | 317 | free (dummy ); |
| 318 | |
E. Scott Daniels | 05850e0 | 2020-11-11 15:57:22 -0500 | [diff] [blame] | 319 | status = SIpoll( si_ctx, 1 ); |
| 320 | errors += fail_if_true( status != 0, "poll failed" ); |
| 321 | |
| 322 | return errors; |
| 323 | } |
| 324 | |
E. Scott Daniels | 43b7981 | 2020-04-17 13:00:28 -0400 | [diff] [blame] | 325 | |
| 326 | /* |
| 327 | Connection oriented tests. |
| 328 | */ |
| 329 | static int conn( ) { |
| 330 | int errors = 0; |
| 331 | int state; |
E. Scott Daniels | cc314e0 | 2020-09-15 10:27:34 -0400 | [diff] [blame] | 332 | int cfd = 3; // fd for close |
| 333 | char* buf; |
E. Scott Daniels | 43b7981 | 2020-04-17 13:00:28 -0400 | [diff] [blame] | 334 | |
| 335 | state = SIconnect( si_ctx, "localhost:4567" ); // driver regular connect |
| 336 | errors += fail_if_true( state < 0, "connect to low port failed" ); |
| 337 | |
E. Scott Daniels | fc2112d | 2020-04-21 12:51:05 -0400 | [diff] [blame] | 338 | state = SIconnect( si_ctx, "localhost:43086" ); // drive save connect with good return code |
E. Scott Daniels | 43b7981 | 2020-04-17 13:00:28 -0400 | [diff] [blame] | 339 | errors += fail_if_true( state < 0, "connect to high port failed" ); |
| 340 | |
E. Scott Daniels | cc314e0 | 2020-09-15 10:27:34 -0400 | [diff] [blame] | 341 | tpem_set_addr_dup_state( 1 ); // force get sockket name emulation to return a duplicate address |
E. Scott Daniels | fc2112d | 2020-04-21 12:51:05 -0400 | [diff] [blame] | 342 | state = SIconnect( si_ctx, "localhost:43086" ); // drive save connect with good return code |
E. Scott Daniels | 43b7981 | 2020-04-17 13:00:28 -0400 | [diff] [blame] | 343 | errors += fail_if_true( state >= 0, "forced dup connect did not return error" ); |
| 344 | |
E. Scott Daniels | cc314e0 | 2020-09-15 10:27:34 -0400 | [diff] [blame] | 345 | tpem_set_addr_dup_state( 0 ); // back to normal |
E. Scott Daniels | 77526eb | 2020-09-17 16:39:31 -0400 | [diff] [blame] | 346 | tpem_set_conn_state( -1 ); |
E. Scott Daniels | 43b7981 | 2020-04-17 13:00:28 -0400 | [diff] [blame] | 347 | state = SIconnect( si_ctx, "localhost:4567" ); // driver regular connect |
| 348 | errors += fail_if_true( state >= 0, "connect to low port successful when failure expected" ); |
E. Scott Daniels | 77526eb | 2020-09-17 16:39:31 -0400 | [diff] [blame] | 349 | tpem_set_conn_state( 3 ); |
E. Scott Daniels | 43b7981 | 2020-04-17 13:00:28 -0400 | [diff] [blame] | 350 | |
E. Scott Daniels | cc314e0 | 2020-09-15 10:27:34 -0400 | [diff] [blame] | 351 | tpem_set_sock_state( 1 ); // make scoket calls fail |
E. Scott Daniels | 43b7981 | 2020-04-17 13:00:28 -0400 | [diff] [blame] | 352 | state = SIconnect( si_ctx, "localhost:4567" ); // driver regular connect |
| 353 | errors += fail_if_true( state >= 0, "connect to low port successful when socket based failure expected" ); |
| 354 | |
| 355 | tpem_set_sock_state( 0 ); |
| 356 | |
| 357 | state = SIlistener( si_ctx, TCP_DEVICE, "0.0.0.0:4567" ); |
| 358 | errors += fail_if_true( state < 0, "listen failed" ); |
| 359 | |
| 360 | tpem_set_bind_state( 1 ); |
| 361 | state = SIlistener( si_ctx, TCP_DEVICE, "0.0.0.0:4567" ); |
| 362 | errors += fail_if_true( state >= 0, "listen successful when bind error set" ); |
| 363 | tpem_set_bind_state( 0 ); |
| 364 | |
E. Scott Daniels | cc314e0 | 2020-09-15 10:27:34 -0400 | [diff] [blame] | 365 | SIbldpoll( si_ctx ); // for coverage. no return value and nothing we can check |
| 366 | |
| 367 | state = SIclose( NULL, 0 ); //coverage |
| 368 | errors += fail_if_true( state != SI_ERROR, "close given nil context returned success" ); |
| 369 | |
| 370 | state = SIclose( si_ctx, cfd ); |
| 371 | errors += fail_if_true( state == SI_ERROR, "close given good context and good fd returned error" ); |
| 372 | |
| 373 | state = SIclose( si_ctx, 5000 ); // out of range fd |
| 374 | errors += fail_if_true( state != SI_ERROR, "close given good context and bad fd returned success" ); |
| 375 | |
| 376 | state = SIclose( si_ctx, TCP_LISTEN_PORT ); // close listener |
| 377 | errors += fail_if_true( state == SI_ERROR, "close given good context and listener fd returned error" ); |
| 378 | |
| 379 | state = SIclose( si_ctx, UDP_PORT ); // close first open udp port (should not be there) |
| 380 | errors += fail_if_true( state != SI_ERROR, "close given good context and udp generic fd returned error" ); |
| 381 | |
| 382 | buf = SIgetname( 3 ); |
| 383 | if( fail_if_true( buf == NULL, "get name failed to return a buffer" ) ) { |
| 384 | errors++; |
| 385 | } else { |
| 386 | errors += fail_if_true( buf[0] == 0, "get name returned buf with emtpy string" ); |
E. Scott Daniels | 05850e0 | 2020-11-11 15:57:22 -0500 | [diff] [blame] | 387 | free( buf ); |
E. Scott Daniels | cc314e0 | 2020-09-15 10:27:34 -0400 | [diff] [blame] | 388 | } |
E. Scott Daniels | 43b7981 | 2020-04-17 13:00:28 -0400 | [diff] [blame] | 389 | |
E. Scott Daniels | 05850e0 | 2020-11-11 15:57:22 -0500 | [diff] [blame] | 390 | buf = SIgetname( -1 ); // invalid fd |
| 391 | errors += fail_not_nil( buf, "get name returned buf with non-emtpy string when given bad fd" ); |
| 392 | |
E. Scott Daniels | 43b7981 | 2020-04-17 13:00:28 -0400 | [diff] [blame] | 393 | fprintf( stderr, "<INFO> conn module finished with %d errors\n", errors ); |
| 394 | return errors; |
| 395 | } |
| 396 | |
E. Scott Daniels | 4d1f9bf | 2020-03-06 12:29:28 -0500 | [diff] [blame] | 397 | /* |
E. Scott Daniels | cc314e0 | 2020-09-15 10:27:34 -0400 | [diff] [blame] | 398 | Misc tests that just don't fit in another bucket. |
| 399 | */ |
| 400 | static int misc( ) { |
| 401 | int errors = 0; |
| 402 | char buf[1024]; |
| 403 | |
| 404 | SIcbreg( NULL, SI_CB_SECURITY, test_cb, NULL ); // coverage only, no return value no verification |
| 405 | SIcbreg( si_ctx, SI_CB_SECURITY, test_cb, NULL ); |
| 406 | |
| 407 | buf[0] = 0; |
| 408 | SIgetaddr( si_ctx, buf ); |
| 409 | errors += fail_if_true( buf[0] == 0, "get address failed" ); |
| 410 | fprintf( stderr, "<INFO> get address returns (%s)\n", buf ); |
| 411 | |
| 412 | fprintf( stderr, "<INFO> misc module finished with %d errors\n", errors ); |
| 413 | return errors; |
| 414 | } |
| 415 | |
| 416 | |
| 417 | /* |
| 418 | New session (accept) testing. |
| 419 | */ |
| 420 | static int new_sess( ) { |
| 421 | int errors = 0; |
| 422 | char buf[1024]; |
| 423 | struct tp_blk *tpptr; |
| 424 | int status; |
| 425 | |
| 426 | tpptr = SInew( TP_BLK ); |
| 427 | tpptr->fd = 3; |
| 428 | tpptr->flags |= TPF_LISTENFD; |
| 429 | |
| 430 | tpem_set_accept_fd( -1 ); // accept will "fail" for coverage |
| 431 | status = SInewsession( si_ctx, tpptr ); |
| 432 | errors += fail_if_true( status != SI_ERROR, "newsession did not fail when accept fails" ); |
| 433 | |
| 434 | tpem_set_accept_fd( 5 ); // accept will return a good fd |
| 435 | SIcbreg( si_ctx, SI_CB_SECURITY, test_cb_err, NULL ); // register error and drive new session for error coverage |
| 436 | status = SInewsession( si_ctx, tpptr ); |
| 437 | errors += fail_if_true( status >= 0, "newsession did failed when accept was good" ); |
| 438 | |
| 439 | tpem_set_accept_fd( 6 ); // accept will return a good fd |
| 440 | SIset_tflags( si_ctx, SI_TF_NODELAY | SI_TF_FASTACK ); // flip options for coverage in new sess |
| 441 | SIcbreg( si_ctx, SI_CB_CONN, test_cb, NULL ); // drive connection for coverage |
| 442 | SIcbreg( si_ctx, SI_CB_SECURITY, test_cb, NULL ); |
| 443 | status = SInewsession( si_ctx, tpptr ); |
| 444 | errors += fail_if_true( status < 0, "newsession did failed when accept was good" ); |
| 445 | |
Alexandre Huff | fa45400 | 2022-01-07 14:20:28 -0300 | [diff] [blame] | 446 | free( tpptr ); |
| 447 | |
E. Scott Daniels | cc314e0 | 2020-09-15 10:27:34 -0400 | [diff] [blame] | 448 | fprintf( stderr, "<INFO> new_sess module finished with %d errors\n", errors ); |
| 449 | return errors; |
| 450 | } |
| 451 | |
| 452 | /* |
| 453 | Send tests |
| 454 | */ |
| 455 | static int send_tests( ) { |
| 456 | int errors = 0; |
| 457 | char buf[1024]; |
| 458 | int len; |
| 459 | int state; |
| 460 | |
| 461 | len = snprintf( buf, 100, "Heaven knows I'm miserable now!" ); |
| 462 | |
| 463 | state = SIsendt( si_ctx, 9999, buf, len ); |
| 464 | errors += fail_if_true( state >= 0, "send given fd out of range did not fail" ); |
| 465 | |
| 466 | state = SIsendt( si_ctx, -1, buf, len ); |
| 467 | errors += fail_if_true( state >= 0, "send given neg fd did not fail" ); |
| 468 | |
| 469 | SIsendt( si_ctx, 6, buf, len ); |
| 470 | |
| 471 | tpem_set_send_err( 99 ); |
| 472 | SIsendt( si_ctx, 6, buf, len ); |
| 473 | |
| 474 | tpem_set_send_err( 0 ); |
| 475 | tpem_set_sel_blk( 1 ); |
| 476 | SIsendt( si_ctx, 6, buf, len ); |
| 477 | |
| 478 | tpem_set_sel_blk( 0 ); |
| 479 | tpem_set_selef_fd( 6 ); // will cause send to fail and fd6 to close |
| 480 | SIsendt( si_ctx, 6, buf, len ); |
| 481 | |
| 482 | return errors; |
| 483 | } |
| 484 | |
| 485 | |
E. Scott Daniels | 11838bc | 2021-04-22 16:34:08 -0400 | [diff] [blame] | 486 | /* |
| 487 | Wait testing. This is tricky because we don't have any sessions and thus it's difficult |
| 488 | to drive much of SIwait(). |
| 489 | */ |
| 490 | static int wait_tests() { |
| 491 | int errors = 0; |
| 492 | struct ginfo_blk* dummy; |
| 493 | |
| 494 | |
| 495 | dummy = SIinitialise( 0 ); // get one to fiddle to drive edge cases |
| 496 | SIwait( dummy ); // malloc should "fail" |
| 497 | |
| 498 | dummy->flags |= GIF_SHUTDOWN; |
| 499 | SIwait( dummy ); |
| 500 | |
Alexandre Huff | fa45400 | 2022-01-07 14:20:28 -0300 | [diff] [blame] | 501 | free( dummy->tp_map ); |
| 502 | free( dummy->rbuf ); |
| 503 | free( dummy->cbtab ); |
| 504 | |
E. Scott Daniels | 11838bc | 2021-04-22 16:34:08 -0400 | [diff] [blame] | 505 | memset( dummy, 0, sizeof( *dummy ) ); // force bad cookie check code to drive |
| 506 | SIwait( dummy ); |
| 507 | |
Alexandre Huff | fa45400 | 2022-01-07 14:20:28 -0300 | [diff] [blame] | 508 | free( dummy ); |
| 509 | |
| 510 | |
E. Scott Daniels | 11838bc | 2021-04-22 16:34:08 -0400 | [diff] [blame] | 511 | SIwait( si_ctx ); // should drive once through the loop |
| 512 | |
| 513 | return errors; |
| 514 | } |
| 515 | |
E. Scott Daniels | cc314e0 | 2020-09-15 10:27:34 -0400 | [diff] [blame] | 516 | // ---------------------------------------------------------------------------------------- |
| 517 | |
| 518 | /* |
E. Scott Daniels | 4d1f9bf | 2020-03-06 12:29:28 -0500 | [diff] [blame] | 519 | Drive tests... |
| 520 | */ |
| 521 | int main() { |
| 522 | int errors = 0; |
| 523 | |
| 524 | rmr_set_vlevel( 5 ); // enable all debugging |
| 525 | |
| 526 | fprintf( stderr, "\n<INFO> starting SI95 tests\n" ); |
| 527 | |
| 528 | errors += init(); |
| 529 | errors += memory(); |
E. Scott Daniels | 0a58458 | 2020-04-06 16:42:32 -0400 | [diff] [blame] | 530 | errors += addr(); |
E. Scott Daniels | 05850e0 | 2020-11-11 15:57:22 -0500 | [diff] [blame] | 531 | errors += prep(); |
E. Scott Daniels | 43b7981 | 2020-04-17 13:00:28 -0400 | [diff] [blame] | 532 | errors += conn(); |
E. Scott Daniels | cc314e0 | 2020-09-15 10:27:34 -0400 | [diff] [blame] | 533 | errors += misc(); |
| 534 | |
| 535 | errors += new_sess(); // should leave a "connected" session at fd == 6 |
| 536 | errors += send_tests(); |
| 537 | |
E. Scott Daniels | 05850e0 | 2020-11-11 15:57:22 -0500 | [diff] [blame] | 538 | errors += poll(); |
E. Scott Daniels | 11838bc | 2021-04-22 16:34:08 -0400 | [diff] [blame] | 539 | errors += wait_tests(); |
E. Scott Daniels | 05850e0 | 2020-11-11 15:57:22 -0500 | [diff] [blame] | 540 | |
E. Scott Daniels | 0a58458 | 2020-04-06 16:42:32 -0400 | [diff] [blame] | 541 | errors += cleanup(); |
E. Scott Daniels | 4d1f9bf | 2020-03-06 12:29:28 -0500 | [diff] [blame] | 542 | |
E. Scott Daniels | 77526eb | 2020-09-17 16:39:31 -0400 | [diff] [blame] | 543 | test_summary( errors, "SI95 tests" ); |
E. Scott Daniels | 4d1f9bf | 2020-03-06 12:29:28 -0500 | [diff] [blame] | 544 | if( errors == 0 ) { |
| 545 | fprintf( stderr, "<PASS> all tests were OK\n\n" ); |
| 546 | } else { |
| 547 | fprintf( stderr, "<FAIL> %d errors in SI95 core code\n\n", errors ); |
| 548 | } |
| 549 | |
| 550 | return !!errors; |
| 551 | } |