More changes for scan corrections and unit test coverage
[ric-plt/lib/rmr.git] / test / rmr_si_rcv_static_test.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         Mmemonic:       rmr_si_api_static_test.c
23         Abstract:       Specific tests related to the API functions in rmr_si.c.
24                                 This should be included by a driver which invokes the 'main'
25                                 test function here: rmr_api_test.
26
27                                 This test set applies only to the outward facting API functions
28                                 in the rmr_si.c module (mostly because the context for SI is
29                                 different).
30
31                                 The message buffer specific API tests are in a different static
32                                 module.  API functions tested here are:
33                                          rmr_close
34                                          rmr_get_rcvfd
35                                          rmr_ready
36                                          rmr_init
37                                          rmr_set_rtimeout
38                                          rmr_set_stimeout
39                                          rmr_rcv_specific
40                                          rmr_torcv_msg
41                                          rmr_rcv_msg
42                                          rmr_call
43                                          rmr_rts_msg
44                                          rmr_send_msg
45                                          rmr_mtosend_msg
46                                          rmr_free_msg
47
48         Author:         E. Scott Daniels
49         Date:           14 April 2020   (AKD)
50 */
51
52 #define DEBUG 2
53
54 #include <unistd.h>
55 #include <stdio.h>
56 #include <stdlib.h>
57 #include <strings.h>
58 #include <errno.h>
59 #include <string.h>
60 #include <stdint.h>
61 #include <pthread.h>
62 #include <semaphore.h>
63
64 #include "rmr.h"
65 #include "rmr_agnostic.h"
66
67 static int rmr_rcv_test( ) {
68         int             errors = 0;
69         void*   rmc;                            // route manager context
70         void*   rmc2;                           // second context for non-listener init
71         rmr_mbuf_t*     msg;                    // message buffers
72         rmr_mbuf_t*     msg2;
73         int             v = 0;                                  // some value
74         char    wbuf[128];
75         int             i;
76         int             state;
77         int             max_tries;                      // prevent a sticking in any loop
78
79         v = rmr_ready( NULL );
80         errors += fail_if( v != 0, "rmr_ready returned true before initialisation "  );
81
82         em_set_long_hostname( 1 );
83         if( (rmc = rmr_init( "4560", 1024, FL_NOTHREAD )) == NULL ) {
84                 fail_if_nil( rmc, "rmr_init returned a nil pointer "  );
85                 return 1;
86         }
87
88         msg = rmr_alloc_msg( NULL,  1024 );                                                                     // should return nil pointer
89         errors += fail_not_nil( msg, "rmr_alloc_msg didn't return nil when given nil context "  );
90         gen_rt( rmc );                          // gen dummy route table
91
92         if( ! rmr_ready( rmc ) ) {
93                 fprintf( stderr, "\nPANIC!  rmr isn't showing ready after loading a rt table\n\n" );
94                 return errors+1;
95         }
96
97         msg = rmr_alloc_msg( rmc, 2048 );                               // get a buffer with a transport header
98         msg->len = 500;
99         msg->mtype = 1;
100         msg->state = 999;
101         msg->tp_state = 999;
102         errno = 999;
103         snprintf( msg->payload, 500, "Stand up and cheer from OU to Oh yea! (5)" );
104
105         msg = rmr_send_msg( rmc, msg );
106         errors += fail_if_nil( msg, "send_msg_ did not return a message on send "  );
107         if( msg ) {
108                 errors += fail_not_equal( msg->state, RMR_OK, "send_msg returned bad status for send that should work "  );
109                 errors += fail_if( errno != 0, "send_msg set errno for send that should work "  );
110                 v = rmr_payload_size( msg );
111                 errors += fail_if( v != 2048, "send_msg did not allocate new buffer with correct size "  );
112                 errors += fail_if( msg->tp_state == 999, "send_msg did not set tp_state (2)" );
113         }
114
115         rmr_set_stimeout( NULL, 0 );            // not supported, but funciton exists, so drive away
116         rmr_set_stimeout( rmc, 20 );
117         rmr_set_stimeout( rmc, -1 );
118         rmr_set_rtimeout( NULL, 0 );
119         rmr_set_rtimeout( rmc, 20 );
120         rmr_set_rtimeout( rmc, -1 );
121
122         max_tries = 10;                                         // there shouldn't be more than 10 queued at this point
123         while( (msg2 = rmr_torcv_msg( rmc, msg2, 200 )) != NULL ) {
124                 if( msg2->state != RMR_OK || max_tries <= 0 ) {
125                         break;
126                 }
127
128                 max_tries--;
129         }
130
131         msg2 = rmr_rcv_msg( NULL, NULL );
132         errors += fail_if( msg2 != NULL, "rmr_rcv_msg returned msg when given nil context and msg "  );
133
134         send_n_msgs( rmc, 1 );                  // ensure there is a message to read
135         msg2 = rmr_rcv_msg( rmc, NULL );
136         errors += fail_if( msg2 == NULL, "rmr_rcv_msg returned nil msg when given nil msg "  );
137         if( msg2 ) {
138                 if( msg2->state != RMR_ERR_EMPTY ) {
139                         errors += fail_not_equal( msg2->state, RMR_OK, "receive given nil message did not return msg with good state (not empty) "  );
140                 }
141         }
142
143         send_n_msgs( rmc, 1 );                  // ensure there is a message to read (len is set to 100)
144         msg = rmr_rcv_msg( rmc, msg );
145         if( msg ) {
146                 errors += fail_not_equal( msg->state, RMR_OK, "rmr_rcv_msg did not return an ok state "  );
147                 errors += fail_not_equal( msg->len, 100, "rmr_rcv_msg returned message with invalid len "  );
148         } else {
149                 errors += fail_if_nil( msg, "rmr_rcv_msg returned a nil pointer "  );
150         }
151
152         rmr_rts_msg( NULL, NULL );                      // drive for coverage
153         errors += fail_if( errno == 0, "rmr_rts_msg did not set errno when given a nil context "  );
154         rmr_rts_msg( rmc, NULL );
155         errors += fail_if( errno == 0, "rmr_rts_msg did not set errno when given a nil message "  );
156
157         msg->state = 0;
158         msg = rmr_rts_msg( NULL, msg );                 // should set state in msg
159         if( msg ) {
160                 errors += fail_if_equal( msg->state, 0, "rmr_rts_msg did not set state when given valid message but no context "  );
161         } else {
162                 errors += fail_if_nil( msg,  "rmr_rts_msg returned a nil msg when given a good one" );
163         }
164
165         msg = rmr_rts_msg( rmc, msg );                  // return the buffer to the sender
166         errors += fail_if_nil( msg, "rmr_rts_msg did not return a message pointer "  );
167         errors += fail_not_equal( msg->state, 0, "rts_msg did not return a good state (a) when expected" );
168         errors += fail_not_equal( errno, 0, "rmr_rts_msg did not reset errno (a) expected (b)"  );
169
170         msg->state = 0;
171         msg = rmr_call( NULL, msg );
172         errors += fail_if( msg->state == 0, "rmr_call did not set message state when given message with nil context "  );
173
174         em_set_rcvcount( 0 );                                                   // reset message counter
175         em_set_rcvdelay( 1 );                                                   // force slow msg rate during mt testing
176         em_disable_call_flg();                                                  // cause reflected message to appear to be a response
177
178         snprintf( msg->xaction, 17, "%015d", 16 );
179         msg->mtype = 0;
180         msg->sub_id = -1;
181         msg->len = 234;
182         msg = rmr_call( rmc, msg );
183         errors += fail_if_nil( msg, "rmr_call returned a nil message on call expected to succeed "  );
184         if( msg ) {
185                 errors += fail_not_equal( msg->state, RMR_OK, "rmr_call did not properly set state on successful return "  );
186                 errors += fail_not_equal( errno, 0, "rmr_call did not properly set errno (a) on successful return "  );
187         }
188
189         if( ! msg ) {
190                 msg = rmr_alloc_msg( rmc, 2048 );                               // something buggered above; get a new one
191         }
192
193         em_allow_call_flg();                                                            // cause reflected message to appear to be a call
194         snprintf( msg->xaction, 17, "%015d", 16 );                      // ensure there is an xaction id
195         msg->mtype = 0;
196         msg->sub_id = -1;
197         msg->len = 345;
198         msg = rmr_call( rmc, msg );                                                     // make a call that we never expect a response on (nil pointer back)
199         errors += fail_not_nil( msg, "rmr_call returned message on call expected not to receive a response "  );
200         errors += fail_if( errno == 0, "rmr_call did not set errno on failure "  );
201
202         rmr_free_msg( NULL );                   // drive for coverage; nothing to check
203         rmr_free_msg( msg2 );
204
205         msg2 = rmr_torcv_msg( NULL, NULL, 10 );
206         errors += fail_not_nil( msg2, "rmr_torcv_msg returned a pointer when given nil information "  );
207         msg2 = rmr_torcv_msg( rmc, NULL, 10 );
208         errors += fail_if_nil( msg2, "rmr_torcv_msg did not return a message pointer when given a nil old msg "  );
209
210         // ---  test timeout receive; our dummy epoll function will return 1 ready on first call and 0 ready (timeout emulation) on second
211         //              however we must drain the swamp (queue) first, so run until we get a timeout error, or 20 and report error if we get to 20.
212         msg = NULL;
213         for( i = 0; i < 40; i++ ) {
214                 msg = rmr_torcv_msg( rmc, msg, 10 );
215                 errors += fail_if_nil( msg, "torcv_msg returned nil msg when message expected "  );
216                 if( msg ) {
217                         if( msg->state == RMR_ERR_TIMEOUT || msg->state == RMR_ERR_EMPTY ) {            // queue drained and we've seen both states from poll if we get a timeout
218                                 break;
219                         }
220                 }
221         }
222         errors += fail_if( i >= 40, "torcv_msg never returned a timeout "  );
223
224         ((uta_ctx_t *)rmc)->shutdown = 1;
225         rmr_close( NULL );                      // drive for coverage
226         rmr_close( rmc );                       // no return to check; drive for coverage
227
228
229         // ------- receive specific is deprecated, but we still test to keep sonar happy ---------------
230
231         rmr_rcv_specific( NULL, NULL, "12345", 0 );             // drive for error handling coverage
232         rmr_rcv_specific( NULL, msg, "12345", 2 );
233
234         strncpy( wbuf, "dummy message", sizeof( wbuf ) );
235         msg = mk_populated_msg( 1024, 0, 0, -1, strlen( wbuf ) + 1 );
236         strncpy( msg->payload, wbuf, msg->len );
237         msg = rmr_send_msg( rmc, msg );                                         // give specific something to chew on
238
239         strncpy( msg->payload, wbuf, msg->len );
240         msg->mtype = 0;
241         rmr_str2xact( msg, "12345" );                                           // should allow rcv to find it
242         msg = rmr_send_msg( rmc, msg );
243
244         msg = rmr_rcv_specific( rmc, NULL, "12345", 2 );
245         if( msg ) {
246                 errors += fail_if( msg->state != 0, "rmr_rcv_specific failed to find the expected message" );
247         } else {
248                 errors++;
249                 fprintf( stderr, "<FAIL> rcv specific expected to return a message and did not\n" );
250         }
251
252         strncpy( wbuf, "dummy message", sizeof( wbuf ) );
253         msg = mk_populated_msg( 1024, 0, 0, -1, strlen( wbuf ) + 1 );
254         strncpy( msg->payload, wbuf, msg->len );
255         msg = rmr_send_msg( rmc, msg );                                         // give specific something to chew on
256
257         fprintf( stderr, "<INFO> starting rmr_rcv_specific test for no expected message\n" );
258         strncpy( msg->payload, wbuf, msg->len );
259         msg->mtype = 0;
260         rmr_str2xact( msg, "72345" );                                           // rcv should not find it
261         msg = rmr_send_msg( rmc, msg );
262         msg = rmr_rcv_specific( rmc, msg, "12345", 2 );
263         fail_if_nil( msg, "rmr_rcv_specific expected to retun nil message did  not" );
264
265         // --------------- phew, done ------------------------------------------------------------------------------
266
267         if( ! errors ) {
268                 fprintf( stderr, "<INFO> all RMR receive tests pass\n" );
269         } else {
270                 fprintf( stderr, "<INFO> receive tests failures noticed \n" );
271         }
272
273         return !!errors;
274 }