Fix rmr_call() parameter checking bug
[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         new_msg->tp_buf = (void *) malloc( alen );
201         memset( new_msg->tp_buf, 0, alen );
202
203         hdr = (uta_mhdr_t*) new_msg->tp_buf;
204         SET_HDR_LEN( hdr );
205         SET_HDR_TR_LEN( hdr, tr_len );
206         hdr->rmr_ver = htonl( MSG_VER );
207         strcpy( hdr->src, "dummyhost:1111" );
208         strcpy( hdr->srcip, "30.4.19.86:1111" );
209
210         new_msg->header = new_msg->tp_buf;
211         new_msg->payload =  new_msg->header + PAYLOAD_OFFSET( hdr );
212         new_msg->alloc_len = alen;
213         new_msg->len = 0;
214
215         return new_msg;
216 }
217
218 static void test_set_ver( rmr_mbuf_t* msg, int ver ) {
219         uta_mhdr_t* hdr;
220
221         hdr = (uta_mhdr_t*) msg->tp_buf;
222         hdr->rmr_ver = htonl( ver );
223         strcpy( hdr->src, "dummyhost-v2:1111" );
224         strcpy( hdr->srcip, "30.4.19.86:2222" );
225
226         return;
227 }
228
229 /*
230         These allow values to be pushed deep into the real RMR header allocated
231         at the front of the transport buffer. These are needed to simulate
232         the actions of rmr_send() which pushes the values from the message buffer
233         just before putting them on the wire.
234 */
235 static void test_set_mtype( rmr_mbuf_t* msg, int mtype ) {
236         uta_mhdr_t* hdr;
237
238         msg->mtype = mtype;
239         hdr = (uta_mhdr_t*) msg->tp_buf;
240         hdr->mtype = htonl( mtype );
241 }
242
243 static void test_set_sid( rmr_mbuf_t* msg, int sid ) {
244         uta_mhdr_t* hdr;
245
246         msg->sub_id = sid;
247         hdr = (uta_mhdr_t*) msg->tp_buf;
248         hdr->sub_id = htonl( sid );
249 }
250
251 static void test_set_plen( rmr_mbuf_t* msg, int plen ) {
252         uta_mhdr_t* hdr;
253
254         msg->len = plen;
255         hdr = (uta_mhdr_t*) msg->tp_buf;
256         hdr->plen = htonl( plen );
257 }
258
259 /*
260         Build a message and populate both the msg buffer and the tranport header
261         with mid, sid, and payload len. Tr_len causes that much space in the 
262         header for trace info to be reserved.
263 */
264 static rmr_mbuf_t* mk_populated_msg( int alloc_len, int tr_len, int mtype, int sid, int plen ) {
265         uta_mhdr_t* hdr;
266         rmr_mbuf_t* mbuf;
267
268         mbuf = test_mk_msg( alloc_len, tr_len );
269         test_set_mtype( mbuf, mtype );
270         test_set_sid( mbuf, sid );
271         test_set_plen( mbuf, plen );
272
273         return mbuf;
274 }
275
276
277 #endif
278
279 #endif