a8309d9d174ab10547646f96141bee0692860003
[ric-plt/lib/rmr.git] / test / test_support.c
1 // vi: ts=4 sw=4 noet :
2 /*
3 ==================================================================================
4             Copyright (c) 2019-2020 Nokia
5             Copyright (c) 2018-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         Mnemonic:       test_tools.c
23         Abstract:       Functions for test applications to make their life a bit easier.
24                                 This file is probably compiled to a .o, and then included on
25                                 the cc command for the test.
26         Author:         E. Scott Daniels
27         Date:           6 January 2019
28 */
29
30 #ifndef _test_support_c
31 #define _test_support_c
32
33 #include <signal.h>
34 #include <string.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <fcntl.h>
38 #include <unistd.h>
39
40 /*
41         This is ugly, but needed to allow for component testing.
42
43         The test code (e.g. foo_test.c and not foo_static_test.c) can include these
44         constants to turn off the import of test support files:
45                 NO_EMULATION            -- the transport emulation will not be included
46                 NO_PRIVATE_HEADERS      -- the private headers for the transport component of RMR
47                                                                 (e.g. si) will not be included.
48 */
49 #ifndef NO_EMULATION                            // assume emulation unless specifically put off (love double negatives)
50         #ifdef NNG_UNDER_TEST
51                 #define TP_HDR_LEN 0                            // needed for support functions but nonexistant in nng world
52                 #include "test_nng_em.c"                        // nano/ngg emulation functions
53         #else
54                 #include "test_si95_em.c"                       // si emulation functions
55         #endif
56 #endif
57
58 #ifndef NO_PRIVATE_HEADERS                                      // include transport headers unless specifically turned off
59         #ifdef NNG_UNDER_TEST
60                 #include <rmr_nng_private.h>            // context things are type sensitive
61         #else
62                 #include "si95/socket_if.h"                     // need to have the si context more than anything else
63                 #include <rmr_si_private.h>
64         #endif
65 #endif
66
67 #ifndef BAD
68 #define BAD 1                   // these are exit codes unless user overrides
69 #define GOOD 0
70 #endif
71
72 /*
73         Snag the optional positional parameter at pp, return defval if not there.
74 */
75 static char* snag_pp( int pp, int argc, char** argv, char* defval ) {
76
77         if( pp < argc ) {
78                 return argv[pp];
79         }
80
81         return defval;
82 }
83
84 /*
85         Signal handler -- inside of the tests we will exit cleanly for hup/temp/intr
86         signals so that the coverage stuff will generate the needed data files. If
87         we inter/term the process they don't drive.
88 */
89
90 void sig_clean_exit( int sign ) {
91         fprintf( stderr, "signal trapped for clean exit: %d\n", sign );
92         exit( 0 );
93 }
94
95 /*
96         Setup all of the signal handling for signals that we want to force a clean exit:
97         term, intr, hup, quit, usr1/2 alarm, etc.  All others we'll let default.
98 */
99 static void set_signals( void ) {
100         struct sigaction sa;
101         int     sig_list[] = { SIGINT, SIGQUIT, SIGILL, SIGALRM, SIGTERM, SIGUSR1 , SIGUSR2 };
102         int i;
103         int nele;               // number of elements in the list
104
105         nele = (int) ( sizeof( sig_list )/sizeof( int ) );              // convert raw size to the number of elements
106         for( i = 0; i < nele; i ++ ) {
107                 memset( &sa, 0, sizeof( sa ) );
108                 sa.sa_handler = sig_clean_exit;
109                 sigaction( sig_list[i], &sa, NULL );
110         }
111 }
112
113
114 static int fail_if_nil( void* p, char* what ) {
115         if( !p ) {
116                 fprintf( stderr, "<FAIL> %s: pointer was nil\n", what );
117         }
118         return p ? GOOD : BAD;
119 }
120
121 static int fail_not_nil( void* p, char* what ) {
122         if( p ) {
123                 fprintf( stderr, "<FAIL> %s: pointer was not nil\n", what );
124         }
125         return !p ? GOOD : BAD;
126 }
127
128 static int fail_if_false( int bv, char* what ) {
129         if( !bv ) {
130                 fprintf( stderr, "<FAIL> %s: expected true, boolean test was false (%d)\n", what, bv );
131         }
132
133         return bv ? GOOD : BAD;
134 }
135
136 static int fail_if_true( int bv, char* what ) {
137         if( bv ) {
138                 fprintf( stderr, "<FAIL> %s: expected false, boolean test was true (%d)\n", what, bv );
139         }
140         return bv ? BAD : GOOD;
141 }
142
143 /*
144         Same as fail_if_true(), but reads easier in the test code.
145 */
146 static int fail_if( int bv, char* what ) {
147
148         if( bv ) {
149                 fprintf( stderr, "<FAIL> %s: expected false, boolean test was true (%d)\n", what, bv );
150         }
151         return bv ? BAD : GOOD;
152 }
153
154 static int fail_not_equal( int a, int b, char* what ) {
155         if( a != b ) {
156                 fprintf( stderr, "<FAIL> %s: values were not equal a=%d b=%d\n", what, a, b );
157         }
158         return a == b ? GOOD : BAD;                     // user may override good/bad so do NOT return a==b directly!
159 }
160
161 static int fail_if_equal( int a, int b, char* what ) {
162                 fprintf( stderr, "<TESTING> %s %d\n", what, a==b );
163         if( a == b ) {
164                 fprintf( stderr, "<FAIL> %s values were equal a=%d b=%d\n", what, a, b );
165         }
166         return a != b ? GOOD : BAD;                     // user may override good/bad so do NOT return a==b directly!
167 }
168
169 static int fail_not_equalp( void* a, void* b, char* what ) {
170         if( a != b ) {
171                 fprintf( stderr, "<FAIL> %s: pointers were not equal a=%p b=%p\n", what, a, b );
172         }
173         return a == b ? GOOD : BAD;                     // user may override good/bad so do NOT return a==b directly!
174 }
175
176 static int fail_if_equalp( void* a, void* b, char* what ) {
177         if( a == b ) {
178                 fprintf( stderr, "<FAIL> %s pointers were equal a=%p b=%p\n", what, a, b );
179         }
180         return a != b ? GOOD : BAD;                     // user may override good/bad so do NOT return a==b directly!
181 }
182
183
184 // for symtab and other non-message things this allows them to exclude by setting
185 #ifndef NO_DUMMY_RMR
186 /*
187         Dummy message allocator for testing without sr_static functions
188 */
189 #ifndef MSG_VER
190 #define MSG_VER 3
191 #endif
192
193 static rmr_mbuf_t* test_mk_msg( int len, int tr_len ) {
194         rmr_mbuf_t*     new_msg;
195         uta_mhdr_t* hdr;
196         size_t  alen;
197
198         alen = sizeof( *hdr ) + tr_len + len + TP_HDR_LEN;      // this does no support allocating len2 and len3 data fields
199
200         new_msg = (rmr_mbuf_t *) malloc( sizeof *new_msg );
201         memset( new_msg, 0, sizeof( *new_msg ) );
202         new_msg->tp_buf = (void *) malloc( alen );
203         memset( new_msg->tp_buf, 0, alen );
204
205         hdr = (uta_mhdr_t*) new_msg->tp_buf;
206         SET_HDR_LEN( hdr );
207         SET_HDR_TR_LEN( hdr, tr_len );
208         hdr->rmr_ver = htonl( MSG_VER );
209         strcpy( hdr->src, "dummyhost:1111" );
210         strcpy( hdr->srcip, "30.4.19.86:1111" );
211
212         new_msg->header = new_msg->tp_buf;
213         new_msg->payload =  new_msg->header + PAYLOAD_OFFSET( hdr );
214         new_msg->alloc_len = alen;
215         new_msg->len = 0;
216
217         return new_msg;
218 }
219
220 static void test_set_ver( rmr_mbuf_t* msg, int ver ) {
221         uta_mhdr_t* hdr;
222
223         hdr = (uta_mhdr_t*) msg->tp_buf;
224         hdr->rmr_ver = htonl( ver );
225         strcpy( hdr->src, "dummyhost-v2:1111" );
226         strcpy( hdr->srcip, "30.4.19.86:2222" );
227
228         return;
229 }
230
231 /*
232         These allow values to be pushed deep into the real RMR header allocated
233         at the front of the transport buffer. These are needed to simulate
234         the actions of rmr_send() which pushes the values from the message buffer
235         just before putting them on the wire.
236 */
237 static void test_set_mtype( rmr_mbuf_t* msg, int mtype ) {
238         uta_mhdr_t* hdr;
239
240         msg->mtype = mtype;
241         hdr = (uta_mhdr_t*) msg->tp_buf;
242         hdr->mtype = htonl( mtype );
243 }
244
245 static void test_set_sid( rmr_mbuf_t* msg, int sid ) {
246         uta_mhdr_t* hdr;
247
248         msg->sub_id = sid;
249         hdr = (uta_mhdr_t*) msg->tp_buf;
250         hdr->sub_id = htonl( sid );
251 }
252
253 static void test_set_plen( rmr_mbuf_t* msg, int plen ) {
254         uta_mhdr_t* hdr;
255
256         msg->len = plen;
257         hdr = (uta_mhdr_t*) msg->tp_buf;
258         hdr->plen = htonl( plen );
259 }
260
261 /*
262         Build a message and populate both the msg buffer and the tranport header
263         with mid, sid, and payload len. Tr_len causes that much space in the 
264         header for trace info to be reserved.
265 */
266 static rmr_mbuf_t* mk_populated_msg( int alloc_len, int tr_len, int mtype, int sid, int plen ) {
267         uta_mhdr_t* hdr;
268         rmr_mbuf_t* mbuf;
269
270         mbuf = test_mk_msg( alloc_len, tr_len );
271         test_set_mtype( mbuf, mtype );
272         test_set_sid( mbuf, sid );
273         test_set_plen( mbuf, plen );
274
275         return mbuf;
276 }
277
278
279 #endif
280
281 #endif