Fix meid related core dump
[ric-plt/lib/rmr.git] / test / test_support.c
1 // : vi ts=4 sw=4 noet :
2 /*
3 ==================================================================================
4             Copyright (c) 2019 Nokia
5             Copyright (c) 2018-2019 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 #ifndef BAD
41 #define BAD 1                   // these are exit codes unless user overrides
42 #define GOOD 0
43 #endif
44
45 /*
46         Snag the optional positional parameter at pp, return defval if not there.
47 */
48 static char* snag_pp( int pp, int argc, char** argv, char* defval ) {
49
50         if( pp < argc ) {
51                 return argv[pp];
52         }
53
54         return defval;
55 }
56
57 /*
58         Signal handler -- inside of the tests we will exit cleanly for hup/temp/intr
59         signals so that the coverage stuff will generate the needed data files. If
60         we inter/term the process they don't drive.
61 */
62
63 void sig_clean_exit( int sign ) {
64         fprintf( stderr, "signal trapped for clean exit: %d\n", sign );
65         exit( 0 );
66 }
67
68 /*
69         Setup all of the signal handling for signals that we want to force a clean exit:
70         term, intr, hup, quit, usr1/2 alarm, etc.  All others we'll let default.
71 */
72 static void set_signals( void ) {
73         struct sigaction sa;
74         int     sig_list[] = { SIGINT, SIGQUIT, SIGILL, SIGALRM, SIGTERM, SIGUSR1 , SIGUSR2 };
75         int i;
76         int nele;               // number of elements in the list
77
78         nele = (int) ( sizeof( sig_list )/sizeof( int ) );              // convert raw size to the number of elements
79         for( i = 0; i < nele; i ++ ) {
80                 memset( &sa, 0, sizeof( sa ) );
81                 sa.sa_handler = sig_clean_exit;
82                 sigaction( sig_list[i], &sa, NULL );
83         }
84 }
85
86
87 static int fail_if_nil( void* p, char* what ) {
88         if( !p ) {
89                 fprintf( stderr, "<FAIL> %s: pointer was nil\n", what );
90         }
91         return p ? GOOD : BAD;
92 }
93
94 static int fail_not_nil( void* p, char* what ) {
95         if( p ) {
96                 fprintf( stderr, "<FAIL> %s: pointer was not nil\n", what );
97         }
98         return !p ? GOOD : BAD;
99 }
100
101 static int fail_if_false( int bv, char* what ) {
102         if( !bv ) {
103                 fprintf( stderr, "<FAIL> %s: expected true, boolean test was false (%d)\n", what, bv );
104         }
105
106         return bv ? GOOD : BAD;
107 }
108
109 static int fail_if_true( int bv, char* what ) {
110         if( bv ) {
111                 fprintf( stderr, "<FAIL> %s: expected false, boolean test was true (%d)\n", what, bv );
112         }
113         return bv ? BAD : GOOD;
114 }
115
116 /*
117         Same as fail_if_true(), but reads easier in the test code.
118 */
119 static int fail_if( int bv, char* what ) {
120
121         if( bv ) {
122                 fprintf( stderr, "<FAIL> %s: expected false, boolean test was true (%d)\n", what, bv );
123         }
124         return bv ? BAD : GOOD;
125 }
126
127 static int fail_not_equal( int a, int b, char* what ) {
128         if( a != b ) {
129                 fprintf( stderr, "<FAIL> %s: values were not equal a=%d b=%d\n", what, a, b );
130         }
131         return a == b ? GOOD : BAD;                     // user may override good/bad so do NOT return a==b directly!
132 }
133
134 static int fail_if_equal( int a, int b, char* what ) {
135         if( a == b ) {
136                 fprintf( stderr, "<FAIL> %s values were equal a=%d b=%d\n", what, a, b );
137         }
138         return a != b ? GOOD : BAD;                     // user may override good/bad so do NOT return a==b directly!
139 }
140
141 static int fail_not_equalp( void* a, void* b, char* what ) {
142         if( a != b ) {
143                 fprintf( stderr, "<FAIL> %s: pointers were not equal a=%p b=%p\n", what, a, b );
144         }
145         return a == b ? GOOD : BAD;                     // user may override good/bad so do NOT return a==b directly!
146 }
147
148 static int fail_if_equalp( void* a, void* b, char* what ) {
149         if( a == b ) {
150                 fprintf( stderr, "<FAIL> %s pointers were equal a=%p b=%p\n", what, a, b );
151         }
152         return a != b ? GOOD : BAD;                     // user may override good/bad so do NOT return a==b directly!
153 }
154
155
156 // for symtab and other non-message things this allows them to exclude by setting
157 #ifndef NO_DUMMY_RMR
158 /*
159         Dummy message allocator for testing without sr_static functions
160 */
161 #ifndef MSG_VER
162 #define MSG_VER 3
163 #endif
164
165 static rmr_mbuf_t* test_mk_msg( int len, int tr_len ) {
166         rmr_mbuf_t*     new_msg;
167         uta_mhdr_t* hdr;
168         size_t  alen;
169
170         alen = sizeof( *hdr ) + tr_len + len;   // this does no support allocating len2 and len3 data fields
171
172         new_msg = (rmr_mbuf_t *) malloc( sizeof *new_msg );
173         new_msg->tp_buf = (void *) malloc( alen );
174         memset( new_msg->tp_buf, 0, alen );
175
176         hdr = (uta_mhdr_t*) new_msg->tp_buf;
177         SET_HDR_LEN( hdr );
178         SET_HDR_TR_LEN( hdr, tr_len );
179         hdr->rmr_ver = htonl( MSG_VER );
180         strcpy( hdr->src, "dummyhost:1111" );
181         strcpy( hdr->srcip, "30.4.19.86:1111" );
182
183         new_msg->header = new_msg->tp_buf;
184         new_msg->payload =  new_msg->header + PAYLOAD_OFFSET( hdr );
185         new_msg->alloc_len = alen;
186         new_msg->len = 0;
187
188         return new_msg;
189 }
190
191 static void test_set_ver( rmr_mbuf_t* msg, int ver ) {
192         uta_mhdr_t* hdr;
193
194         hdr = (uta_mhdr_t*) msg->tp_buf;
195         hdr->rmr_ver = htonl( ver );
196         strcpy( hdr->src, "dummyhost-v2:1111" );
197         strcpy( hdr->srcip, "30.4.19.86:2222" );
198
199         return;
200 }
201
202 /*
203         These allow values to be pushed deep into the real RMR header allocated
204         at the front of the transport buffer. These are needed to simulate
205         the actions of rmr_send() which pushes the values from the message buffer
206         just before putting them on the wire.
207 */
208 static void test_set_mtype( rmr_mbuf_t* msg, int mtype ) {
209         uta_mhdr_t* hdr;
210
211         msg->mtype = mtype;
212         hdr = (uta_mhdr_t*) msg->tp_buf;
213         hdr->mtype = htonl( mtype );
214 }
215
216 static void test_set_sid( rmr_mbuf_t* msg, int sid ) {
217         uta_mhdr_t* hdr;
218
219         msg->sub_id = sid;
220         hdr = (uta_mhdr_t*) msg->tp_buf;
221         hdr->sub_id = htonl( sid );
222 }
223
224 static void test_set_plen( rmr_mbuf_t* msg, int plen ) {
225         uta_mhdr_t* hdr;
226
227         msg->len = plen;
228         hdr = (uta_mhdr_t*) msg->tp_buf;
229         hdr->plen = htonl( plen );
230 }
231
232 /*
233         Build a message and populate both the msg buffer and the tranport header
234         with mid, sid, and payload len. Tr_len causes that much space in the 
235         header for trace info to be reserved.
236 */
237 static rmr_mbuf_t* mk_populated_msg( int alloc_len, int tr_len, int mtype, int sid, int plen ) {
238         uta_mhdr_t* hdr;
239         rmr_mbuf_t* mbuf;
240
241         mbuf = test_mk_msg( alloc_len, tr_len );
242         test_set_mtype( mbuf, mtype );
243         test_set_sid( mbuf, sid );
244         test_set_plen( mbuf, plen );
245
246         return mbuf;
247 }
248
249
250 #endif
251
252 #endif