blob: 1e5e6572d62257084239d8434fd17c3f4b93dbf2 [file] [log] [blame]
E. Scott Danielse15b1382020-04-14 15:55:13 -04001// vi: ts=4 sw=4 noet :
Ashwin Sridharanfd9cc7a2019-04-03 16:47:02 -04002/*
3==================================================================================
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -05004 Copyright (c) 2019-2020 Nokia
5 Copyright (c) 2018-2020 AT&T Intellectual Property.
Ashwin Sridharanfd9cc7a2019-04-03 16:47:02 -04006
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
E. Scott Daniels8790bf02019-04-23 12:59:28 +000011 http://www.apache.org/licenses/LICENSE-2.0
Ashwin Sridharanfd9cc7a2019-04-03 16:47:02 -040012
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
E. Scott Daniels8dd46412019-04-16 20:47:54 +000030#ifndef _test_support_c
31#define _test_support_c
32
Ashwin Sridharanfd9cc7a2019-04-03 16:47:02 -040033#include <signal.h>
34#include <string.h>
35#include <stdio.h>
36#include <stdlib.h>
E. Scott Daniels8dd46412019-04-16 20:47:54 +000037#include <fcntl.h>
38#include <unistd.h>
Ashwin Sridharanfd9cc7a2019-04-03 16:47:02 -040039
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -050040/*
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
Ashwin Sridharanfd9cc7a2019-04-03 16:47:02 -040067#ifndef BAD
68#define BAD 1 // these are exit codes unless user overrides
69#define GOOD 0
70#endif
71
E. Scott Daniels77526eb2020-09-17 16:39:31 -040072// ----------- a couple of globals make it easier ---------------------------------------
73static int ts_tests_driven = 0; // number of fail_if calls made == numer of tests driven
74
75// ---------------------------------------------------------------------------------------
76
77/*
78 Support test counting, reset and summary.
79*/
80static int test_get_attempted() {
81 return ts_tests_driven;
82}
83
84static void test_reset_attempted() {
85 ts_tests_driven = 0;
86}
87
88static void test_summary( int ecount, char* tag ) {
89 fprintf( stderr, "<SUMMARY> %s completed; %d total tests, %d passed, %d failed\n",
90 tag, ts_tests_driven, ts_tests_driven - ecount, ecount );
91}
92
Ashwin Sridharanfd9cc7a2019-04-03 16:47:02 -040093/*
94 Snag the optional positional parameter at pp, return defval if not there.
95*/
96static char* snag_pp( int pp, int argc, char** argv, char* defval ) {
97
98 if( pp < argc ) {
99 return argv[pp];
100 }
101
102 return defval;
103}
104
105/*
106 Signal handler -- inside of the tests we will exit cleanly for hup/temp/intr
107 signals so that the coverage stuff will generate the needed data files. If
108 we inter/term the process they don't drive.
109*/
110
111void sig_clean_exit( int sign ) {
112 fprintf( stderr, "signal trapped for clean exit: %d\n", sign );
113 exit( 0 );
114}
115
E. Scott Daniels8790bf02019-04-23 12:59:28 +0000116/*
Ashwin Sridharanfd9cc7a2019-04-03 16:47:02 -0400117 Setup all of the signal handling for signals that we want to force a clean exit:
118 term, intr, hup, quit, usr1/2 alarm, etc. All others we'll let default.
119*/
120static void set_signals( void ) {
121 struct sigaction sa;
122 int sig_list[] = { SIGINT, SIGQUIT, SIGILL, SIGALRM, SIGTERM, SIGUSR1 , SIGUSR2 };
123 int i;
124 int nele; // number of elements in the list
E. Scott Daniels8790bf02019-04-23 12:59:28 +0000125
Ashwin Sridharanfd9cc7a2019-04-03 16:47:02 -0400126 nele = (int) ( sizeof( sig_list )/sizeof( int ) ); // convert raw size to the number of elements
127 for( i = 0; i < nele; i ++ ) {
128 memset( &sa, 0, sizeof( sa ) );
129 sa.sa_handler = sig_clean_exit;
130 sigaction( sig_list[i], &sa, NULL );
131 }
132}
133
134
E. Scott Daniels77526eb2020-09-17 16:39:31 -0400135/*
136 Assert like logic except these just record the test and return state so that we
137 can attempt all tests and not abort on the first failure as an assert would do.
138*/
Ashwin Sridharanfd9cc7a2019-04-03 16:47:02 -0400139static int fail_if_nil( void* p, char* what ) {
E. Scott Daniels77526eb2020-09-17 16:39:31 -0400140 ts_tests_driven++;
141
Ashwin Sridharanfd9cc7a2019-04-03 16:47:02 -0400142 if( !p ) {
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000143 fprintf( stderr, "<FAIL> %s: pointer was nil\n", what );
Ashwin Sridharanfd9cc7a2019-04-03 16:47:02 -0400144 }
145 return p ? GOOD : BAD;
146}
147
148static int fail_not_nil( void* p, char* what ) {
E. Scott Daniels77526eb2020-09-17 16:39:31 -0400149 ts_tests_driven++;
150
Ashwin Sridharanfd9cc7a2019-04-03 16:47:02 -0400151 if( p ) {
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000152 fprintf( stderr, "<FAIL> %s: pointer was not nil\n", what );
Ashwin Sridharanfd9cc7a2019-04-03 16:47:02 -0400153 }
154 return !p ? GOOD : BAD;
155}
156
157static int fail_if_false( int bv, char* what ) {
E. Scott Daniels77526eb2020-09-17 16:39:31 -0400158 ts_tests_driven++;
159
Ashwin Sridharanfd9cc7a2019-04-03 16:47:02 -0400160 if( !bv ) {
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000161 fprintf( stderr, "<FAIL> %s: expected true, boolean test was false (%d)\n", what, bv );
Ashwin Sridharanfd9cc7a2019-04-03 16:47:02 -0400162 }
163
164 return bv ? GOOD : BAD;
165}
166
167static int fail_if_true( int bv, char* what ) {
E. Scott Daniels77526eb2020-09-17 16:39:31 -0400168 ts_tests_driven++;
169
Ashwin Sridharanfd9cc7a2019-04-03 16:47:02 -0400170 if( bv ) {
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000171 fprintf( stderr, "<FAIL> %s: expected false, boolean test was true (%d)\n", what, bv );
Ashwin Sridharanfd9cc7a2019-04-03 16:47:02 -0400172 }
173 return bv ? BAD : GOOD;
174}
175
176/*
177 Same as fail_if_true(), but reads easier in the test code.
178*/
179static int fail_if( int bv, char* what ) {
E. Scott Daniels77526eb2020-09-17 16:39:31 -0400180 ts_tests_driven++;
181
Ashwin Sridharanfd9cc7a2019-04-03 16:47:02 -0400182
183 if( bv ) {
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000184 fprintf( stderr, "<FAIL> %s: expected false, boolean test was true (%d)\n", what, bv );
Ashwin Sridharanfd9cc7a2019-04-03 16:47:02 -0400185 }
186 return bv ? BAD : GOOD;
187}
188
E. Scott Danielsfcea3952020-10-30 15:04:16 -0400189static int fail_pequal( void* a, void* b, char* what ) {
190 ts_tests_driven++;
191
192 if( a == b ) {
193 fprintf( stderr, "<FAIL> %s: pointers were not equal a=%p b=%p\n", what, a, b );
194 }
195 return a == b ? GOOD : BAD; // user may override good/bad so do NOT return a==b directly!
196}
197
198static int fail_not_pequal( void* a, void* b, char* what ) {
199 ts_tests_driven++;
200
201 if( a != b ) {
202 fprintf( stderr, "<FAIL> %s: pointers were not equal a=%p b=%p\n", what, a, b );
203 }
204 return a == b ? GOOD : BAD; // user may override good/bad so do NOT return a==b directly!
205}
206
Ashwin Sridharanfd9cc7a2019-04-03 16:47:02 -0400207static int fail_not_equal( int a, int b, char* what ) {
E. Scott Daniels77526eb2020-09-17 16:39:31 -0400208 ts_tests_driven++;
209
Ashwin Sridharanfd9cc7a2019-04-03 16:47:02 -0400210 if( a != b ) {
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000211 fprintf( stderr, "<FAIL> %s: values were not equal a=%d b=%d\n", what, a, b );
Ashwin Sridharanfd9cc7a2019-04-03 16:47:02 -0400212 }
213 return a == b ? GOOD : BAD; // user may override good/bad so do NOT return a==b directly!
214}
215
216static int fail_if_equal( int a, int b, char* what ) {
E. Scott Daniels77526eb2020-09-17 16:39:31 -0400217 ts_tests_driven++;
218
Ashwin Sridharanfd9cc7a2019-04-03 16:47:02 -0400219 if( a == b ) {
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000220 fprintf( stderr, "<FAIL> %s values were equal a=%d b=%d\n", what, a, b );
Ashwin Sridharanfd9cc7a2019-04-03 16:47:02 -0400221 }
222 return a != b ? GOOD : BAD; // user may override good/bad so do NOT return a==b directly!
223}
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000224
E. Scott Daniels68d09fa2019-06-03 19:45:12 +0000225static int fail_not_equalp( void* a, void* b, char* what ) {
E. Scott Daniels77526eb2020-09-17 16:39:31 -0400226 ts_tests_driven++;
227
E. Scott Daniels68d09fa2019-06-03 19:45:12 +0000228 if( a != b ) {
229 fprintf( stderr, "<FAIL> %s: pointers were not equal a=%p b=%p\n", what, a, b );
230 }
231 return a == b ? GOOD : BAD; // user may override good/bad so do NOT return a==b directly!
232}
233
234static int fail_if_equalp( void* a, void* b, char* what ) {
E. Scott Daniels77526eb2020-09-17 16:39:31 -0400235 ts_tests_driven++;
236
E. Scott Daniels68d09fa2019-06-03 19:45:12 +0000237 if( a == b ) {
238 fprintf( stderr, "<FAIL> %s pointers were equal a=%p b=%p\n", what, a, b );
239 }
240 return a != b ? GOOD : BAD; // user may override good/bad so do NOT return a==b directly!
241}
242
E. Scott Danielsd7109572019-04-18 14:01:16 +0000243
E. Scott Danielsd9de79a2019-10-31 09:20:33 -0400244// for symtab and other non-message things this allows them to exclude by setting
E. Scott Danielsd7109572019-04-18 14:01:16 +0000245#ifndef NO_DUMMY_RMR
246/*
247 Dummy message allocator for testing without sr_static functions
248*/
E. Scott Daniels68d09fa2019-06-03 19:45:12 +0000249#ifndef MSG_VER
250#define MSG_VER 3
251#endif
252
E. Scott Danielsd7109572019-04-18 14:01:16 +0000253static rmr_mbuf_t* test_mk_msg( int len, int tr_len ) {
254 rmr_mbuf_t* new_msg;
255 uta_mhdr_t* hdr;
256 size_t alen;
257
E. Scott Danielsfc5c77b2020-02-21 13:24:29 -0500258 alen = sizeof( *hdr ) + tr_len + len + TP_HDR_LEN; // this does no support allocating len2 and len3 data fields
E. Scott Danielsd7109572019-04-18 14:01:16 +0000259
260 new_msg = (rmr_mbuf_t *) malloc( sizeof *new_msg );
E. Scott Daniels9c923bc2020-08-03 09:22:20 -0400261 memset( new_msg, 0, sizeof( *new_msg ) );
E. Scott Danielsd7109572019-04-18 14:01:16 +0000262 new_msg->tp_buf = (void *) malloc( alen );
263 memset( new_msg->tp_buf, 0, alen );
264
265 hdr = (uta_mhdr_t*) new_msg->tp_buf;
266 SET_HDR_LEN( hdr );
267 SET_HDR_TR_LEN( hdr, tr_len );
E. Scott Daniels68d09fa2019-06-03 19:45:12 +0000268 hdr->rmr_ver = htonl( MSG_VER );
269 strcpy( hdr->src, "dummyhost:1111" );
270 strcpy( hdr->srcip, "30.4.19.86:1111" );
E. Scott Danielsd7109572019-04-18 14:01:16 +0000271
272 new_msg->header = new_msg->tp_buf;
273 new_msg->payload = new_msg->header + PAYLOAD_OFFSET( hdr );
274 new_msg->alloc_len = alen;
275 new_msg->len = 0;
E. Scott Daniels8790bf02019-04-23 12:59:28 +0000276
E. Scott Danielsd7109572019-04-18 14:01:16 +0000277 return new_msg;
278}
E. Scott Daniels68d09fa2019-06-03 19:45:12 +0000279
280static void test_set_ver( rmr_mbuf_t* msg, int ver ) {
281 uta_mhdr_t* hdr;
282
283 hdr = (uta_mhdr_t*) msg->tp_buf;
284 hdr->rmr_ver = htonl( ver );
285 strcpy( hdr->src, "dummyhost-v2:1111" );
286 strcpy( hdr->srcip, "30.4.19.86:2222" );
287
288 return;
289}
E. Scott Danielsd7109572019-04-18 14:01:16 +0000290
E. Scott Danielsd9de79a2019-10-31 09:20:33 -0400291/*
292 These allow values to be pushed deep into the real RMR header allocated
293 at the front of the transport buffer. These are needed to simulate
294 the actions of rmr_send() which pushes the values from the message buffer
295 just before putting them on the wire.
296*/
297static void test_set_mtype( rmr_mbuf_t* msg, int mtype ) {
298 uta_mhdr_t* hdr;
299
300 msg->mtype = mtype;
301 hdr = (uta_mhdr_t*) msg->tp_buf;
302 hdr->mtype = htonl( mtype );
303}
304
305static void test_set_sid( rmr_mbuf_t* msg, int sid ) {
306 uta_mhdr_t* hdr;
307
308 msg->sub_id = sid;
309 hdr = (uta_mhdr_t*) msg->tp_buf;
310 hdr->sub_id = htonl( sid );
311}
312
313static void test_set_plen( rmr_mbuf_t* msg, int plen ) {
314 uta_mhdr_t* hdr;
315
316 msg->len = plen;
317 hdr = (uta_mhdr_t*) msg->tp_buf;
318 hdr->plen = htonl( plen );
319}
320
321/*
322 Build a message and populate both the msg buffer and the tranport header
E. Scott Daniels77526eb2020-09-17 16:39:31 -0400323 with mid, sid, and payload len. Tr_len causes that much space in the
E. Scott Danielsd9de79a2019-10-31 09:20:33 -0400324 header for trace info to be reserved.
325*/
326static rmr_mbuf_t* mk_populated_msg( int alloc_len, int tr_len, int mtype, int sid, int plen ) {
327 uta_mhdr_t* hdr;
328 rmr_mbuf_t* mbuf;
329
330 mbuf = test_mk_msg( alloc_len, tr_len );
331 test_set_mtype( mbuf, mtype );
332 test_set_sid( mbuf, sid );
333 test_set_plen( mbuf, plen );
334
335 return mbuf;
336}
337
338
E. Scott Daniels77526eb2020-09-17 16:39:31 -0400339// end no dummy rmr
E. Scott Danielsd9de79a2019-10-31 09:20:33 -0400340#endif
E. Scott Daniels68d09fa2019-06-03 19:45:12 +0000341
E. Scott Daniels8dd46412019-04-16 20:47:54 +0000342#endif