d14678b7bd724a934ff5586d6820231253182d96
[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         if( a == b ) {
163                 fprintf( stderr, "<FAIL> %s values were equal a=%d b=%d\n", what, a, b );
164         }
165         return a != b ? GOOD : BAD;                     // user may override good/bad so do NOT return a==b directly!
166 }
167
168 static int fail_not_equalp( void* a, void* b, char* what ) {
169         if( a != b ) {
170                 fprintf( stderr, "<FAIL> %s: pointers were not equal a=%p b=%p\n", what, a, b );
171         }
172         return a == b ? GOOD : BAD;                     // user may override good/bad so do NOT return a==b directly!
173 }
174
175 static int fail_if_equalp( void* a, void* b, char* what ) {
176         if( a == b ) {
177                 fprintf( stderr, "<FAIL> %s pointers were equal a=%p b=%p\n", what, a, b );
178         }
179         return a != b ? GOOD : BAD;                     // user may override good/bad so do NOT return a==b directly!
180 }
181
182
183 // for symtab and other non-message things this allows them to exclude by setting
184 #ifndef NO_DUMMY_RMR
185 /*
186         Dummy message allocator for testing without sr_static functions
187 */
188 #ifndef MSG_VER
189 #define MSG_VER 3
190 #endif
191
192 static rmr_mbuf_t* test_mk_msg( int len, int tr_len ) {
193         rmr_mbuf_t*     new_msg;
194         uta_mhdr_t* hdr;
195         size_t  alen;
196
197         alen = sizeof( *hdr ) + tr_len + len + TP_HDR_LEN;      // this does no support allocating len2 and len3 data fields
198
199         new_msg = (rmr_mbuf_t *) malloc( sizeof *new_msg );
200         memset( new_msg, 0, sizeof( *new_msg ) );
201         new_msg->tp_buf = (void *) malloc( alen );
202         memset( new_msg->tp_buf, 0, alen );
203
204         hdr = (uta_mhdr_t*) new_msg->tp_buf;
205         SET_HDR_LEN( hdr );
206         SET_HDR_TR_LEN( hdr, tr_len );
207         hdr->rmr_ver = htonl( MSG_VER );
208         strcpy( hdr->src, "dummyhost:1111" );
209         strcpy( hdr->srcip, "30.4.19.86:1111" );
210
211         new_msg->header = new_msg->tp_buf;
212         new_msg->payload =  new_msg->header + PAYLOAD_OFFSET( hdr );
213         new_msg->alloc_len = alen;
214         new_msg->len = 0;
215
216         return new_msg;
217 }
218
219 static void test_set_ver( rmr_mbuf_t* msg, int ver ) {
220         uta_mhdr_t* hdr;
221
222         hdr = (uta_mhdr_t*) msg->tp_buf;
223         hdr->rmr_ver = htonl( ver );
224         strcpy( hdr->src, "dummyhost-v2:1111" );
225         strcpy( hdr->srcip, "30.4.19.86:2222" );
226
227         return;
228 }
229
230 /*
231         These allow values to be pushed deep into the real RMR header allocated
232         at the front of the transport buffer. These are needed to simulate
233         the actions of rmr_send() which pushes the values from the message buffer
234         just before putting them on the wire.
235 */
236 static void test_set_mtype( rmr_mbuf_t* msg, int mtype ) {
237         uta_mhdr_t* hdr;
238
239         msg->mtype = mtype;
240         hdr = (uta_mhdr_t*) msg->tp_buf;
241         hdr->mtype = htonl( mtype );
242 }
243
244 static void test_set_sid( rmr_mbuf_t* msg, int sid ) {
245         uta_mhdr_t* hdr;
246
247         msg->sub_id = sid;
248         hdr = (uta_mhdr_t*) msg->tp_buf;
249         hdr->sub_id = htonl( sid );
250 }
251
252 static void test_set_plen( rmr_mbuf_t* msg, int plen ) {
253         uta_mhdr_t* hdr;
254
255         msg->len = plen;
256         hdr = (uta_mhdr_t*) msg->tp_buf;
257         hdr->plen = htonl( plen );
258 }
259
260 /*
261         Build a message and populate both the msg buffer and the tranport header
262         with mid, sid, and payload len. Tr_len causes that much space in the 
263         header for trace info to be reserved.
264 */
265 static rmr_mbuf_t* mk_populated_msg( int alloc_len, int tr_len, int mtype, int sid, int plen ) {
266         uta_mhdr_t* hdr;
267         rmr_mbuf_t* mbuf;
268
269         mbuf = test_mk_msg( alloc_len, tr_len );
270         test_set_mtype( mbuf, mtype );
271         test_set_sid( mbuf, sid );
272         test_set_plen( mbuf, plen );
273
274         return mbuf;
275 }
276
277
278 #endif
279
280 #endif