1 // : vi ts=4 sw=4 noet :
3 ==================================================================================
4 Copyright (c) 2019 Nokia
5 Copyright (c) 2018-2019 AT&T Intellectual Property.
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
11 http://www.apache.org/licenses/LICENSE-2.0
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 ==================================================================================
22 Mmemonic: rmr_api_static_test.c
23 Abstract: Specific tests related to the API functions in rmr_nng.c/rmr.c.
24 This should be included by a driver, but only the main RMr
25 driver and there likely not be a specific stand alone driver
26 for just this small set of tests because of the depth of the
27 library needed to test at this level.
29 The message buffer specific API tests are in a different static
30 module. API functions tested here are:
46 Author: E. Scott Daniels
58 #include "../src/common/include/rmr.h"
59 #include "../src/common/include/rmr_agnostic.h"
60 //#include "../src/common/src/ring_static.c"
63 Send a 'burst' of messages to drive some send retry failures to increase RMr coverage
64 by handling the retry caee.
66 static void send_n_msgs( void* ctx, int n ) {
67 rmr_mbuf_t* msg; // message buffers
70 msg = rmr_alloc_msg( ctx, 1024 );
75 for( i = 0; i < n; i++ ) {
76 //fprintf( stderr, "mass send\n" );
81 msg = rmr_send_msg( ctx, msg );
85 static int rmr_api_test( ) {
87 void* rmc; // route manager context
88 void* rmc2; // second context for non-listener init
89 rmr_mbuf_t* msg; // message buffers
91 int v = 0; // some value
96 v = rmr_ready( NULL );
97 errors += fail_if( v != 0, "rmr_ready returned true before initialisation" );
99 if( (rmc = rmr_init( "4560", 1024, FL_NOTHREAD )) == NULL ) {
100 fail_if_nil( rmc, "rmr_init returned a nil pointer" );
104 if( (rmc2 = rmr_init( ":6789", 1024, FL_NOTHREAD )) == NULL ) { // init without starting a thread
105 errors += fail_if_nil( rmc, "rmr_init returned a nil pointer for non-threaded init" );
108 free_ctx( rmc2 ); // coverage
110 if( (rmc2 = rmr_init( NULL, 1024, FL_NOTHREAD )) == NULL ) { // drive default port selector code
111 errors += fail_if_nil( rmc, "rmr_init returned a nil pointer when driving for default port" );
114 v = rmr_ready( rmc ); // unknown return; not checking at the moment
116 msg = rmr_alloc_msg( NULL, 1024 ); // should return nil pointer
117 errors += fail_not_nil( msg, "rmr_alloc_msg didn't return nil when given nil context" );
119 msg = rmr_alloc_msg( rmc, 2048 ); // allocate larger than default size given on init
120 errors += fail_if_nil( msg, "rmr_alloc_msg returned nil msg pointer" );
122 v = rmr_payload_size( NULL );
123 errors += fail_if( v >= 0, "rmr_payload_size returned valid size for nil message" );
124 errors += fail_if( errno == 0, "rmr_payload_size did not set errno on failure" );
126 v = rmr_payload_size( msg );
128 errors += fail_not_equal( v, 2048, "rmr_payload_size returned invalid size (a) instead of expected size (b)" );
129 errors += fail_if( errno != 0, "rmr_payload_size did not clear errno on success" );
131 errors += fail_if( v < 0, "rmr_payload_size returned invalid size for good message" );
134 v = rmr_get_rcvfd( NULL );
135 errors += fail_if( v >= 0, "rmr_get_rcvfd returned a valid file descriptor when given nil context" );
136 v = rmr_get_rcvfd( rmc );
137 errors += fail_if( v < 0, "rmr_get_rcvfd did not return a valid file descriptor" );
139 msg2 = rmr_send_msg( NULL, NULL ); // drive for coverage
140 errors += fail_not_nil( msg2, "send_msg returned msg pointer when given a nil message and context" );
143 msg = rmr_send_msg( NULL, msg );
144 errors += fail_if( msg->state == 0, "rmr_send_msg did not set msg state when msg given with nil context" );
146 // --- sends will fail with a no endpoint error until a dummy route table is set, so we test fail case first.
151 msg = rmr_send_msg( rmc, msg );
152 errors += fail_if_nil( msg, "send_msg_ did not return a message on send" );
154 errors += fail_not_equal( msg->state, RMR_ERR_NOENDPT, "send_msg did not return no endpoints before rtable added" );
155 errors += fail_if( errno == 0, "send_msg did not set errno" );
158 gen_rt( rmc ); // --- after this point there is a dummy route table so send and rts calls should be ok
164 msg = rmr_send_msg( rmc, msg );
165 errors += fail_if_nil( msg, "send_msg_ did not return a message on send" );
167 errors += fail_not_equal( msg->state, RMR_OK, "send_msg returned bad status for send that should work" );
168 errors += fail_if( errno != 0, "send_msg set errno for send that should work" );
169 v = rmr_payload_size( msg );
170 errors += fail_if( v != 2048, "send_msg did not allocate new buffer with correct size" );
173 rmr_set_stimeout( NULL, 0 );
174 rmr_set_stimeout( rmc, 20 );
175 rmr_set_stimeout( rmc, -1 );
176 rmr_set_rtimeout( NULL, 0 );
177 rmr_set_rtimeout( rmc, 20 );
178 rmr_set_rtimeout( rmc, -1 );
180 msg2 = rmr_rcv_msg( NULL, NULL );
181 errors += fail_if( msg2 != NULL, "rmr_rcv_msg returned msg when given nil context and msg" );
183 msg2 = rmr_rcv_msg( rmc, NULL );
184 errors += fail_if( msg2 == NULL, "rmr_rcv_msg returned nil msg when given nil msg" );
186 errors += fail_not_equal( msg2->state, RMR_OK, "receive given nil message did not return msg with good state" );
189 msg = rmr_rcv_msg( rmc, msg );
191 errors += fail_if( msg->state != RMR_OK, "rmr_rcv_msg did not return an ok state" );
192 errors += fail_not_equal( msg->len, 129, "rmr_rcv_msg returned message with invalid len" );
194 errors += fail_if_nil( msg, "rmr_rcv_msg returned a nil pointer" );
197 rmr_rts_msg( NULL, NULL ); // drive for coverage
198 rmr_rts_msg( rmc, NULL );
199 errors += fail_if( errno == 0, "rmr_rts_msg did not set errno when given a nil message" );
202 msg = rmr_rts_msg( NULL, msg ); // should set state in msg
203 errors += fail_if_equal( msg->state, 0, "rmr_rts_msg did not set state when given valid message but no context" );
206 msg = rmr_rts_msg( rmc, msg ); // return the buffer to the sender
207 errors += fail_if_nil( msg, "rmr_rts_msg did not return a message pointer" );
208 errors += fail_if( errno != 0, "rmr_rts_msg did not reset errno" );
211 snprintf( msg->xaction, 17, "%015d", 16 ); // dummy transaction id (emulation generates, this should arrive after a few calls to recv)
214 msg = rmr_call( NULL, msg );
215 errors += fail_if( msg->state == 0, "rmr_call did not set message state when given message with nil context" );
218 msg = rmr_call( rmc, msg ); // this call should return a message as we can anticipate a dummy message in
219 errors += fail_if_nil( msg, "rmr_call returned a nil message on call expected to succeed" );
221 errors += fail_not_equal( msg->state, RMR_OK, "rmr_call did not properly set state on successful return" );
222 errors += fail_not_equal( errno, 0, "rmr_call did not properly set errno (a) on successful return" );
225 snprintf( wbuf, 17, "%015d", 14 ); // if we call receive we should find this in the first 15 tries
226 for( i = 0; i < 16; i++ ) {
227 msg = rmr_rcv_msg( rmc, msg );
229 if( strcmp( wbuf, msg->xaction ) == 0 ) { // found the queued message
232 fprintf( stderr, "<INFO> msg: %s\n", msg->xaction );
234 errors += fail_if_nil( msg, "receive returnd nil msg while looking for queued message" );
238 errors += fail_if( i >= 16, "did not find expected message on queue" );
241 msg = rmr_alloc_msg( rmc, 2048 ); // something buggered above; get a new one
243 msg = rmr_call( rmc, msg ); // make a call that we never expect a response on
244 errors += fail_if_nil( msg, "rmr_call returned a non-nil message on call expected not to receive a response" );
246 errors += fail_if_equal( msg->state, RMR_OK, "rmr_call did not properly set state on queued message receive" );
247 errors += fail_if( errno == 0, "rmr_call did not properly set errno on queued message receivesuccessful" );
250 msg = rmr_call( rmc, msg ); // this should "timeout" because the message xaction id won't ever appear again
251 errors += fail_if_nil( msg, "rmr_call returned a nil message on call expected to fail (but return a pointer)" );
252 errors += fail_if( errno == 0, "rmr_call did not set errno on failure" );
254 rmr_free_msg( NULL ); // drive for coverage; nothing to check
255 rmr_free_msg( msg2 );
258 msg2 = rmr_torcv_msg( NULL, NULL, 10 );
259 errors += fail_not_nil( msg2, "rmr_torcv_msg returned a pointer when given nil information" );
260 msg2 = rmr_torcv_msg( rmc, NULL, 10 );
261 errors += fail_if_nil( msg2, "rmr_torcv_msg did not return a message pointer when given a nil old msg" );
263 // --- test timeout receive; our dummy epoll function will return 1 ready on first call and 0 ready (timeout emulation) on second
264 // 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.
266 for( i = 0; i < 40; i++ ) {
267 msg = rmr_torcv_msg( rmc, msg, 10 );
268 errors += fail_if_nil( msg, "torcv_msg returned nil msg when message expected" );
270 if( msg->state == RMR_ERR_TIMEOUT ) { // queue drained and we've seen both states from poll if we get a timeout
275 errors += fail_if( i >= 40, "torcv_msg never returned a timeout" );
278 // ---- trace things that are not a part of the mbuf_api functions and thus must be tested here
279 state = rmr_init_trace( NULL, 37 ); // coverage test nil context
280 errors += fail_not_equal( state, 0, "attempt to initialise trace with nil context returned non-zero state (a)" );
281 errors += fail_if_equal( errno, 0, "attempt to initialise trace with nil context did not set errno as expected" );
283 state = rmr_init_trace( rmc, 37 );
284 errors += fail_if_equal( state, 0, "attempt to set trace len in context was not successful" );
285 errors += fail_not_equal( errno, 0, "attempt to set trace len in context did not clear errno" );
287 msg = rmr_tralloc_msg( rmc, 1024, 17, "1904308620110417" );
288 errors += fail_if_nil( msg, "attempt to allocate message with trace data returned nil message" );
289 state = rmr_get_trace( msg, wbuf, 17 );
290 errors += fail_not_equal( state, 17, "len of trace data (a) returned after msg allocation was not expected size (b)" );
291 state = strcmp( wbuf, "1904308620110417" );
292 errors += fail_not_equal( state, 0, "trace data returned after tralloc was not correct" );
294 em_send_failures = 1;
295 send_n_msgs( rmc, 30 ); // send 30 messages with emulation failures
296 em_send_failures = 0;
299 rmr_close( NULL ); // drive for coverage
300 rmr_close( rmc ); // no return to check; drive for coverage
304 fprintf( stderr, "<INFO> all RMr API tests pass\n" );