test(all): Add additional log messages
[ric-plt/lib/rmr.git] / test / test_nng_em.c
1 /*
2 ==================================================================================
3         Copyright (c) 2019 Nokia 
4         Copyright (c) 2018-2019 AT&T Intellectual Property.
5
6    Licensed under the Apache License, Version 2.0 (the "License");
7    you may not use this file except in compliance with the License.
8    You may obtain a copy of the License at
9
10        http://www.apache.org/licenses/LICENSE-2.0
11
12    Unless required by applicable law or agreed to in writing, software
13    distributed under the License is distributed on an "AS IS" BASIS,
14    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15    See the License for the specific language governing permissions and
16    limitations under the License.
17 ==================================================================================
18 */
19
20 /*
21         Mnemonic:       test_nng_em.c
22         Abstract:       A nano/NNG message emulator for testing without needing to 
23                                 actually have nanomsg, nng, or external processes.
24                                 We also emulate the epoll_wait() function for controlled
25                                 poll related testing.
26
27                                 This module must be directly included to be used.
28         Date:           11 February 2019
29         Author:         E. Scott Daniels
30 */
31
32 // ---------------------- emulated nng functions ---------------------------
33
34
35 #ifndef _em_nn
36 #define _em_nn
37
38 static int em_send_failures = 0;        // test programme can set this to emulate eagain send failures
39
40 // ----------- epoll emulation ---------------------------------------------
41
42 // CAUTION: sys/epoll.h must be included before this define and function will properly compile. 
43 #define epoll_wait em_wait
44 /*
45         Every other call returns 1 ready; alternate calls return 0 ready. 
46         Mostly for testing the timeout receive call. First call should return 
47         something ready and the second should return nothing ready so we can
48         drive both cases. 
49 */
50 static int em_wait( int fd, void* events, int n, int to ) {
51         static int ready = 0;
52
53         ready = !ready;
54         return ready;
55 }
56
57
58
59 //--------------------------------------------------------------------------
60 #ifdef EMULATE_NNG
61 struct nn_msghdr {
62         int boo;
63 };
64
65 static int return_value = 0;
66
67 /*
68         Test app can call this to have all emulated functions return failure instead
69         of success.
70 */
71 static void en_set_retur( int rv ) {
72         return_value = rv;
73 }
74
75
76
77 static int em_nng_foo() {
78         fprintf( stderr, "emulated functions in play" );
79 }                              
80
81
82 /*
83         Simulated v1 message for receive to return. This needs to match the RMr header
84         so that we can fill in length, type and xaction id things.
85 #define MSG_VER 1
86 struct em_msg {
87         int32_t mtype;                                          // message type  ("long" network integer)
88         int32_t plen;                                           // payload length
89         int32_t rmr_ver;                                        // our internal message version number
90         unsigned char xid[32];                          // space for user transaction id or somesuch
91         unsigned char sid[32];                          // sender ID for return to sender needs
92         unsigned char src[16];                          // name of the sender (source)
93         unsigned char meid[32];                         // managed element id.
94         struct timespec ts;                                     // timestamp ???
95 };
96 */
97
98 /*
99         v2 message; should be able to use it for everything that is set up here as 
100         we don't add a payload even if setting a v1 type.
101 */
102 #define ALT_MSG_VER 1   // alternate every so often
103 #define MSG_VER 2               // default version to insert
104 struct em_msg {
105         int32_t mtype;                                          // message type  ("long" network integer)
106         int32_t plen;                                           // payload length
107         int32_t rmr_ver;                                        // our internal message version number
108         unsigned char xid[32];                          // space for user transaction id or somesuch
109         unsigned char sid[32];                          // sender ID for return to sender needs
110         unsigned char src[64];                          // name of the sender (source)
111         unsigned char meid[32];                         // managed element id.
112         struct timespec ts;                                     // timestamp ???
113
114                                         // V2 extension
115     int32_t flags;                      // HFL_* constants
116     int32_t len0;                       // length of the RMr header data
117     int32_t len1;                       // length of the tracing data
118     int32_t len2;                       // length of data 1 (d1)
119     int32_t len3;                       // length of data 2 (d2)
120
121 };
122
123 /*
124         Receive message must allocate a new buffer and return the pointer into *m.
125         Every 9 messages or so we'll simulate an old version message
126 */
127 static int em_nng_recvmsg( nng_socket s, nng_msg ** m, int i ) {
128         void* b;
129         struct em_msg* msg;
130         static int count = 0;                   // we'll simulate a message going in by dropping an rmr-ish msg with transaction id only
131         int trace_size = 0;
132
133         //sleep( 1 );
134
135         b = (void *) malloc( 2048 );
136         if( m != NULL ) {
137                 memset( b, 0, 2048 );
138                 *m = (nng_msg *) b;
139                 msg = (struct em_msg *) b;
140                 if( count % 10  == 9 ) {
141                         //msg->rmr_ver = htonl( MSG_VER );
142                         msg->rmr_ver = ALT_MSG_VER;             // emulate the bug in RMr v1
143                 } else {
144                         msg->rmr_ver = htonl( MSG_VER );
145                 }
146                 msg->mtype = htonl( 1 );
147                 msg->plen = htonl( 129 );
148                 msg->len0 = htonl( sizeof( struct em_msg ) );
149                 msg->len1 = htonl( trace_size );
150                 snprintf( msg->xid, 32, "%015d", count++ );             // simple transaction id so we can test receive specific and ring stuff
151                 snprintf( msg->src, 16, "localhost:4562" );             // set src id (unrealistic) so that rts() can be tested
152         }
153
154         //fprintf( stderr, ">>> simulated received message: %s\n", msg->xid );
155         return return_value;
156 }
157
158 static void* em_msg_body( nng_msg* msg ) {
159         return (void *) msg;                                                            // we don't manage a real msg, so body is just the buffer we allocated
160 }
161
162 static size_t em_msg_len( const nng_msg* msg ) {
163         if( msg ) {
164                 return  2048;
165         }
166
167         return 0;
168 }
169
170
171 static int em_nng_pull_open(nng_socket * s ) {
172         return return_value;
173 }
174 static int em_nng_pull0_open(nng_socket * s ) {
175         return return_value;
176 }
177 static int em_nng_listen(nng_socket s, const char * c, nng_listener * l, int i ) {
178         return return_value;
179 }
180 static int em_nng_close(nng_socket s ) {
181         return return_value;
182 }
183 static int em_nng_push0_open(nng_socket * s ) {
184         return return_value;
185 }
186 static int em_nng_dial(nng_socket s, const char * c, nng_dialer * d, int i ) {
187         //fprintf( stderr, "<info> === simulated dialing: %s\n", c );
188         return return_value;
189 }
190 static int em_nng_setopt(nng_socket s, const char * c, const void * p, size_t t ) {
191         return return_value;
192 }
193 static int em_nng_sub_open(nng_socket * s ) {
194         return return_value;
195 }
196 static int em_nng_sub0_open(nng_socket * s ) {
197         return return_value;
198 }
199 static int em_nng_recv(nng_socket s, void * v, size_t * t, int i ) {
200         return return_value;
201 }
202 static int em_nng_send( nng_socket s, void* m, int l, int f ) {
203         return return_value;
204 }
205
206 /*
207         Emulate sending a message. If the global em_send_failures is set,
208         then every so often we fail with an EAGAIN to drive that part 
209         of the code in RMr.
210 */
211 static int em_sendmsg( nng_socket s, nng_msg* m, int i ) {
212         static int count = 0;
213
214         if( em_send_failures && (count++ % 15 == 14) ) {
215                 //fprintf( stderr, ">>>> failing send\n\n" );
216                 return NNG_EAGAIN;
217         }
218
219         return return_value;
220 }
221
222 static void* em_nng_alloc( size_t len ) {
223         return malloc( len );
224 }
225
226 static int em_nng_msg_alloc( nng_msg** mp, size_t l ) {
227         void*   p;
228
229         if( !mp || return_value != 0  ) {
230                 return -1;
231         }
232
233         p = (void *) malloc( sizeof( char ) * l );
234         *mp = (nng_msg *) p;
235
236         return return_value;
237 }
238
239 /*
240         We just free the buffer here as it was a simple malloc.
241 */
242 static void em_nng_free( void* p, size_t l ) {
243         if( p ) {
244                 //fprintf( stderr, ">>>>> not freed: %p\n", p );
245                 free( p );
246         }
247 }
248 static void em_nng_msg_free( void* p ) {
249         if( p ) {
250                 //fprintf( stderr, ">>>>> not freed: %p\n", p );
251                 free( p );
252         }
253 }
254
255 static int em_dialer_create( void* d, nng_socket s, char* stuff ) {
256         //fprintf( stderr, ">>>> emulated dialer create\n\n" );
257         return 0;
258 }
259
260 static int em_dialer_start( nng_dialer d, int i ) {
261         //fprintf( stderr, ">>>> emulated dialer start\n\n" );
262         return return_value;
263 }
264
265
266 static int em_dialer_setopt_ms( nng_dialer dialer, void* option, int ms ) {
267         return return_value;
268 }
269
270 static int em_nng_getopt_int( nng_socket s, void* con, int* target ) {
271         if( target ) {
272                 *target = 0;
273         }
274         return return_value;
275 }
276
277
278
279 // nng redefines some of these to point directly to various 'versions' of the function (ugg, function versions, really?)
280 #undef nng_recvmsg 
281 #undef nng_free 
282 #undef nng_pull_open 
283 #undef nng_pull0_open 
284 #undef nng_listen 
285 #undef nng_close 
286 #undef nng_getopt_int 
287 #undef nng_push0_open 
288 #undef nng_dial 
289 #undef nng_setopt 
290 #undef nng_sub_open 
291 #undef nng_sub0_open 
292 #undef nng_recv 
293 #undef nng_alloc 
294
295 #define nng_msg_alloc em_nng_msg_alloc
296 #define nng_recvmsg em_nng_recvmsg
297 #define nng_free em_nng_free
298 #define nng_free em_nng_free
299 #define nng_msg_free em_nng_msg_free
300 #define nng_pull_open em_nng_pull_open
301 #define nng_pull0_open em_nng_pull0_open
302 #define nng_listen em_nng_listen
303 #define nng_close em_nng_close
304 #define nng_getopt_int em_nng_getopt_int
305 #define nng_push0_open em_nng_push0_open
306 #define nng_dial em_nng_dial
307 #define nng_setopt em_nng_setopt
308 #define nng_sub_open em_nng_sub_open
309 #define nng_sub0_open em_nng_sub0_open
310 #define nng_recv em_nng_recv
311 #define nng_send em_nng_send
312 #define nng_sendmsg em_sendmsg
313 #define nng_alloc em_nng_alloc
314 #define nng_free em_nng_free
315 #define nng_dialer_setopt_ms em_dialer_setopt_ms
316 #define nng_dialer_start em_dialer_start
317 #define nng_dialer_create em_dialer_create
318 #define nng_msg_body em_msg_body
319 #define nng_msg_len em_msg_len
320
321
322 #else
323
324
325 // ----------------------- emulated nano functions --------------------------
326 struct em_nn_msghdr {
327         int dummy;
328 };
329
330 static int em_nn_socket (int domain, int protocol ) {
331         static int s = 1;
332
333         return ++s;
334 }
335
336 static int em_nn_close (int s ) {
337         return 1;
338 }
339
340 static int em_nn_setsockopt (int s, int level, int option, const void *optval, size_t optvallen ) {
341         return 1;
342 }
343
344 static int em_nn_getsockopt (int s, int level, int option, void *optval, size_t *optvallen ) {
345         return 1;
346 }
347
348 static int em_nn_bind (int s, const char *addr ) {
349 fprintf( stderr, ">>> ===== emulated bind called ====\n" );
350         return 1;
351 }
352
353 static int em_nn_connect (int s, const char *addr ) {
354         return 1;
355 }
356
357 static int em_nn_shutdown (int s, int how ) {
358         return 1;
359 }
360
361 static int em_nn_send (int s, const void *buf, size_t len, int flags ) {
362         return 1;
363 }
364
365 static int em_nn_recv (int s, void *buf, size_t len, int flags ) {
366         return 1;
367 }
368
369 static int em_sendmsg (int s, const struct em_nn_msghdr *msghdr, int flags ) {
370         return 1;
371 }
372
373 static int em_nn_recvmsg (int s, struct nn_msghdr *msghdr, int flags ) {
374         return 1;
375 }
376
377 // nanomsg 
378 #define nn_socket  em_nn_socket
379 #define nn_close  em_nn_close
380 #define nn_setsockopt  em_nn_setsockopt
381 #define nn_getsockopt  em_nn_getsockopt
382 #define nn_bind  em_nn_bind
383 #define nn_connect  em_nn_connect
384 #define nn_shutdown  em_nn_shutdown
385 #define nn_send  em_nn_send
386 #define nn_recv  em_nn_recv
387 #define nn_sendmsg  em_nn_sendmsg
388 #define nn_recvmsg  em_nn_recvmsg
389
390 #endif 
391
392
393 #endif