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: sr_nng_static_test.c
23 Abstract: Test the send/receive funcitons. These are meant to be included at compile
24 time by the test driver.
26 Author: E. Scott Daniels
38 #include <semaphore.h>
41 #include "rmr_agnostic.h"
43 // ----------- local test support ----------------------------------------------------------
44 #define CLONE 1 // convenience constants for payload realloc tests
50 Generate a simple route table (for all but direct route table testing).
51 This gets tricky inasmuch as we generate two in one; first a whole table
52 and then two update tables. The first is a table with a bad counter in the
53 last record to test that we don't load that table and error. The second
56 static void gen_rt( uta_ctx_t* ctx ) {
58 char* rt_stuff; // strings for the route table
61 "newrt|end\n" // end of table check before start of table found
62 "# comment to drive full comment test\n"
63 "\n" // handle blank lines
64 " \n" // handle blank lines
65 "mse|4|10|localhost:4561\n" // entry before start message
66 "rte|4|localhost:4561\n" // entry before start message
67 "newrt|start\n" // false start to drive detection
68 "xxx|badentry to drive default case"
70 "rte|0|localhost:4560,localhost:4562\n" // these are legitimate entries for our testing
71 "rte|1|localhost:4562;localhost:4561,localhost:4569\n"
72 "rte|2|localhost:4562| 10\n" // new subid at end
73 "mse|4|10|localhost:4561\n" // new msg/subid specifier rec
74 "mse|4|localhost:4561\n" // new mse entry with less than needed fields
75 " rte| 5 |localhost:4563 #garbage comment\n" // tests white space cleanup
76 "rte|6|localhost:4562\n"
79 fd = open( "utesting.rt", O_WRONLY | O_CREAT, 0600 );
81 fprintf( stderr, "<BUGGERED> unable to open file for testing route table gen\n" );
85 setenv( "RMR_SEED_RT", "utesting.rt", 1 );
86 write( fd, rt_stuff, strlen( rt_stuff ) ); // write in the whole table
89 "updatert|start\n" // this is an update to the table
90 "mse|4|99|fooapp:9999,barapp:9999;logger:9999\n" // update just one entry
91 "updatert|end | 3\n"; // bad count; this update should be rejected
92 write( fd, rt_stuff, strlen( rt_stuff ) );
95 "updatert|start\n" // this is an update to the table
96 "mse|4|10|fooapp:4561,barapp:4561;logger:9999\n" // update just one entry
97 "del|2|-1\n" // delete an entry; not there so no action
98 "del|2|10\n" // delete an entry
99 "updatert|end | 3\n"; // end table; updates have a count as last field
100 write( fd, rt_stuff, strlen( rt_stuff ) );
103 read_static_rt( ctx, 1 ); // force in verbose mode to see stats on tty if failure
104 unlink( "utesting.rt" );
109 Drive the send and receive functions. We also drive as much of the route
110 table collector as is possible without a real rtg process running somewhere.
112 Send and receive functions are indirectly exercised from the rmr_nng_static_test
113 module as it tests the user facing send/receive/call/rts functions. These tests
114 should exercise specific cases for the internal functions as they will not
115 specifically be driven elsewhere.
117 static int sr_nng_test() {
118 uta_ctx_t* ctx; // context needed to test load static rt
119 uta_ctx_t* real_ctx; // real one to force odd situations for error testing
120 int errors = 0; // number errors found
121 rmr_mbuf_t* mbuf; // mbuf to send/receive
122 rmr_mbuf_t* mb2; // second mbuf when needed
126 nng_socket nn_dummy_sock; // dummy needed to drive send
132 //ctx = rmr_init( "tcp:4360", 2048, 0 ); // do NOT call init -- that starts the rtc thread which isn't good here
133 ctx = (uta_ctx_t *) malloc( sizeof( uta_ctx_t ) ); // alloc the context manually
134 memset( ctx, 0, sizeof( uta_ctx_t ) );
136 ctx->mring = NULL; //uta_mk_ring( 128 );
137 ctx->max_plen = RMR_MAX_RCV_BYTES + sizeof( uta_mhdr_t );
138 ctx->max_mlen = ctx->max_plen + sizeof( uta_mhdr_t );
139 ctx->my_name = strdup( "dummy-test" );
140 ctx->my_ip = strdup( "30.4.19.86:1111" );
141 uta_lookup_rtg( ctx );
143 gen_rt( ctx ); // forces a static load with some known info since we don't start the rtc()
144 gen_rt( ctx ); // force a second load to test cloning
146 p = rt_ensure_ep( NULL, "foo" ); // drive for coverage
147 errors += fail_not_nil( p, "rt_ensure_ep did not return nil when given nil route table" );
149 state = rmr_ready( NULL );
150 errors += fail_if_true( state, "reported ready when given a nil context" );
151 state = rmr_ready( ctx );
152 errors += fail_if_false( state, "reported not ready when it should be" );
154 mbuf = rcv_msg( ctx, NULL );
155 errors += fail_if_nil( mbuf, "no mbuf returned on receive test" );
160 mb2 = clone_msg( mbuf );
161 errors += fail_if_nil( mb2, "clone message returned nil pointer" );
162 errors += fail_not_equal( mbuf->flags, mb2->flags, "clone did not duplicate flags" );
163 errors += fail_not_equal( mbuf->alloc_len, mb2->alloc_len, "clone did not dup alloc-len" );
164 errors += fail_not_equal( mbuf->state, mb2->state, "clone did not dup state" );
167 mbuf = rmr_send_msg( NULL, mbuf );
168 errors += fail_if_nil( mbuf, "send with nil context but buffere didn't return buffer" );
170 errors += fail_not_equal( mbuf->state, RMR_ERR_BADARG, "send with buffer but nil context didn't return right state" );
172 mbuf = rmr_rcv_msg( ctx, NULL );
175 size = 2048 - em_hdr_size(); // emulated nng receive allocates 2K buffers -- subtract off header size
176 state = rmr_payload_size( mbuf );
177 errors += fail_not_equal( state, size, "payload size didn't return expected value" ); // receive should always give 4k buffer
179 rmr_free_msg( mbuf );
182 state = xlate_nng_state( NNG_EAGAIN, 99 );
183 errors += fail_if( state == 99, "xlate_nng_state returned default for nng_eagain" );
184 errors += fail_if( errno != EAGAIN, "xlate_nng_state did not set errno to eagain for nng_eagain" );
186 state = xlate_nng_state( NNG_ETIMEDOUT, 99 );
187 errors += fail_if( state == 99, "xlate_nng_state returned default for nng_timeout" );
188 errors += fail_if( errno != EAGAIN, "xlate_nng_state did not set errno to eagain for nng_timeout" );
190 state = xlate_nng_state( NNG_ENOTSUP, 99 );
191 errors += fail_if( state != 99, "xlate_nng_state did not return default for nng_notsup" );
193 state = xlate_nng_state( NNG_ENOTSUP, 99 );
194 errors += fail_if( state != 99, "xlate_nng_state did not return default for nng_notsup" );
195 errors += fail_if( errno == 0, "xlate_nng_state did not set errno (1)" );
197 state = xlate_nng_state( NNG_EINVAL, 99 );
198 errors += fail_if( state != 99, "xlate_nng_state did not return default for nng_inval" );
199 errors += fail_if( errno == 0, "xlate_nng_state did not set errno (2)" );
201 state = xlate_nng_state( NNG_ENOMEM, 99 );
202 errors += fail_if( state != 99, "xlate_nng_state did not return default for nng_nomem" );
203 errors += fail_if( errno == 0, "xlate_nng_state did not set errno (3)" );
205 state = xlate_nng_state( NNG_ESTATE, 99 );
206 errors += fail_if( state != 99, "xlate_nng_state did not return default for nng_state" );
207 errors += fail_if( errno == 0, "xlate_nng_state did not set errno (4)" );
209 state = xlate_nng_state( NNG_ECLOSED, 99 );
210 errors += fail_if( state != 99, "xlate_nng_state did not return default for nng_closed" );
211 errors += fail_if( errno == 0, "xlate_nng_state did not set errno (5)" );
213 state = xlate_nng_state( 999, 99 );
214 errors += fail_if( state != 99, "xlate_nng_state did not return default for unknown error" );
215 errors += fail_if( errno == 0, "xlate_nng_state did not set errno (6)" );
217 // ---- drive rtc in a 'static' (not pthreaded) mode to get some coverage; no 'results' to be verified -----
218 setenv( ENV_RTG_RAW, "1", 1 ); // rtc should expect raw messages (mostly coverage here)
219 setenv( ENV_VERBOSE_FILE, ".ut_rmr_verbose", 1 ); // allow for verbose code in rtc to be driven
220 i = open( ".ut_rmr_verbose", O_RDWR | O_CREAT, 0654 );
222 write( i, "2\n", 2 );
225 ctx->shutdown = 1; // should force rtc to quit on first pass
226 rtc( NULL ); // coverage test with nil pointer
229 setenv( "RMR_RTG_SVC", "4567", 1 ); // drive for edge case coverage to ensure no nil pointer etc
231 setenv( "RMR_RTG_SVC", "tcp:4567", 1 );
233 setenv( "RMR_RTG_SVC", "tcp:4567:error", 1 );
236 // ------------- reallocation tests ------------------------------------------------------------
237 // we use mk_populated_msg() to create a message with mid/sid/plen pushed into the transport
238 // header to simulate a message having been sent and received which is what causes this data
239 // to push into the wire packet.
241 payload_str = "Stand Up and Cheer; OU78-82";
244 mbuf = mk_populated_msg( 1024, 0, 99, 100, strlen( payload_str ) );
245 memcpy( mbuf->payload, payload_str, mbuf->len );
246 mb2 = realloc_payload( mbuf, 512, NO_COPY, NO_CLONE );
247 errors += fail_if_nil( mb2, "realloc_payload (no copy) returned a nil pointer when reallocating with smaller size" );
248 errors += fail_if_false( mbuf == mb2, "non-clone realloc payload (no copy) of smaller size did not return the same buffer" );
250 mb2 = realloc_payload( NULL, 512, NO_COPY, NO_CLONE );
251 errors += fail_not_nil( mb2, "realloc payload did not return nil pointer when passed nil mbuf" );
253 mb2 = realloc_payload( mbuf, 0, NO_COPY, NO_CLONE );
254 errors += fail_not_nil( mb2, "realloc payload did not return nil pointer when passed bad len" );
256 fprintf( stderr, "<TEST> no copy/no clone test starts\n" );
257 mb2 = realloc_payload( mbuf, 2048, NO_COPY, NO_CLONE );
258 errors += fail_if_false( mbuf == mb2, "realloc payload (no copy) of larger size did not return the same msg buffer(1)" );
259 errors += fail_not_equal( mb2->mtype, -1, "realloc payload (no copy) did not reset mtype(a) to expected(b) value" );
260 errors += fail_not_equal( mb2->sub_id, -1, "realloc payload (no copy) did not reset sub-id(a) to expected(b) value" );
261 errors += fail_if_nil( mb2, "realloc payload returned (no copy) a nil pointer when increasing payload len" );
262 errors += fail_not_equal( mb2->len, 0, "realloc payload payload len(a) not expected(b):" );
263 errors += fail_not_equal( rmr_payload_size( mb2), 2048, "realloc payload alloc len(a) not expected(b)" );
265 fprintf( stderr, "<TEST> copy/no clone test starts\n" );
266 mbuf = mk_populated_msg( 1024, 0, 99, 100, strlen( payload_str ) );
267 memcpy( mbuf->payload, payload_str, mbuf->len );
268 mb2 = realloc_payload( mbuf, 2048, COPY, NO_CLONE );
269 errors += fail_if_false( mbuf == mb2, "non-clone realloc payload (copy) of larger size did not return the same msg buffer(2)" );
270 errors += fail_if_nil( mb2, "realloc payload (copy) returned a nil pointer when increasing payload len)" );
271 errors += fail_not_equal( mb2->mtype, 99, "realloc payload (copy) did not reset mtype(a) to expected(b) value" );
272 errors += fail_not_equal( mb2->sub_id, 100, "realloc payload (copy) did not reset sub-id(a) to expected(b) value" );
273 errors += fail_if_equal( mb2->len, 0, "realloc payload (copy) msg len(a) not expected(b)" );
274 errors += fail_not_equal( rmr_payload_size( mb2), 2048, "realloc payload (copy) alloc len(a) not expected(b)" );
275 errors += fail_not_equal( strncmp( payload_str, mb2->payload, strlen( payload_str )), 0, "realloc payload(copy) didn't copy payload" );
277 fprintf( stderr, "<TEST> copy/clone test starts requested buffer smaller than original\n" );
278 mbuf = mk_populated_msg( 1024, 0, 99, 100, strlen( payload_str ) );
279 memcpy( mbuf->payload, payload_str, mbuf->len );
280 mb2 = realloc_payload( mbuf, 512, COPY, CLONE );
281 errors += fail_if_true( mbuf == mb2, "realloc payload (clone+copy) of larger size did not return different message buffers" );
282 errors += fail_if_nil( mb2, "realloc payload (clone+copy) returned a nil pointer when increasing payload len)" );
283 errors += fail_not_equal( mb2->mtype, 99, "realloc payload (clone+copy) did not reset mtype(a) to expected(b) value" );
284 errors += fail_not_equal( mb2->sub_id, 100, "realloc payload (clone+copy) did not reset sub-id(a) to expected(b) value" );
285 errors += fail_not_equal( mb2->len, strlen( payload_str ), "realloc payload (clone+copy) msg len(a) not expected(b)" );
286 errors += fail_not_equal( rmr_payload_size( mb2), 1024, "realloc payload (clone+copy) alloc len(a) not expected(b)" );
287 errors += fail_not_equal( strncmp( payload_str, mb2->payload, strlen( payload_str )), 0, "realloc payload(clone+copy) didn't copy payload" );
289 // with a clone, we must verify that original message looks sane too
290 errors += fail_not_equal( mbuf->mtype, 99, "realloc payload (clone+copy) validation of unchanged mbuf->mtype fails" );
291 errors += fail_not_equal( mbuf->sub_id, 100, "realloc payload (clone+copy) validation of unchanged mbuf->subid fails" );
292 errors += fail_not_equal( mbuf->len, strlen( payload_str ), "realloc payload (clone+copy) validation of unchanged payload len fails" );
293 errors += fail_not_equal( rmr_payload_size( mbuf ), 1024, "realloc payload (clone+copy) validation of unchanged alloc length fails" );
294 errors += fail_not_equal( strncmp( payload_str, mbuf->payload, strlen( payload_str )), 0, "realloc payload(clone+copy) validation of unchanged payload fails" );
297 fprintf( stderr, "<TEST> copy/clone test starts requested buf is larger than original\n" );
298 mbuf = mk_populated_msg( 1024, 0, 99, 100, strlen( payload_str ) );
299 memcpy( mbuf->payload, payload_str, mbuf->len );
300 mb2 = realloc_payload( mbuf, 2048, COPY, CLONE );
301 errors += fail_if_true( mbuf == mb2, "realloc payload(clone+copy/lg) of larger size did not return different message buffers" );
302 errors += fail_if_nil( mb2, "realloc payload (clone+copy/lg) returned a nil pointer when increasing payload len)" );
303 errors += fail_not_equal( mb2->mtype, 99, "realloc payload (clone+copy/lg) did not reset mtype(a) to expected(b) value" );
304 errors += fail_not_equal( mb2->sub_id, 100, "realloc payload (clone+copy/lg) did not reset sub-id(a) to expected(b) value" );
305 errors += fail_not_equal( mb2->len, strlen( payload_str ), "realloc payload (clone+copy/lg) msg len(a) not expected(b)" );
306 errors += fail_not_equal( rmr_payload_size( mb2), 2048, "realloc payload (clone+copy/lg) alloc len(a) not expected(b)" );
307 errors += fail_not_equal( strncmp( payload_str, mb2->payload, strlen( payload_str )), 0, "realloc payload(clone+copy/lg) didn't copy payload" );
309 // with a clone, we must verify that original message looks sane too
310 errors += fail_not_equal( mbuf->mtype, 99, "realloc payload (clone+copy/lg) validation of unchanged mbuf->mtype fails" );
311 errors += fail_not_equal( mbuf->sub_id, 100, "realloc payload (clone+copy/lg) validation of unchanged mbuf->subid fails" );
312 errors += fail_not_equal( mbuf->len, strlen( payload_str ), "realloc payload (clone+copy/lg) validation of unchanged payload len fails" );
313 errors += fail_not_equal( rmr_payload_size( mbuf ), 1024, "realloc payload (clone+copy/lg) validation of unchanged alloc length fails" );
314 errors += fail_not_equal( strncmp( payload_str, mbuf->payload, strlen( payload_str )), 0, "realloc payload(clone+copy/lg) validation of unchanged payload fails" );
316 // original message should be unharmed, and new message should have no type/sid or payload len; total alloc len should be requested enlargement
317 fprintf( stderr, "<TEST> no copy/clone test starts requested buf is larger than original\n" );
318 mbuf = mk_populated_msg( 1024, 0, 99, 100, strlen( payload_str ) );
319 memcpy( mbuf->payload, payload_str, mbuf->len );
320 mb2 = realloc_payload( mbuf, 2048, NO_COPY, CLONE );
321 errors += fail_if_true( mbuf == mb2, "realloc payload (clone+nocopy) of larger size did not return different message buffers" );
322 errors += fail_if_nil( mb2, "realloc payload (clone+nocopy) returned a nil pointer when increasing payload len)" );
323 errors += fail_not_equal( mb2->mtype, -1, "realloc payload (clone+nocopy) did not reset mtype(a) to expected(b) value" );
324 errors += fail_not_equal( mb2->sub_id, -1, "realloc payload (clone+nocopy) did not reset sub-id(a) to expected(b) value" );
325 errors += fail_not_equal( mb2->len, 0, "realloc payload (clone+nocopy) msg len(a) not expected(b)" );
326 errors += fail_not_equal( rmr_payload_size( mb2 ), 2048, "realloc payload (clone+nocopy) alloc len(a) not expected(b)" );
327 errors += fail_if_equal( strncmp( payload_str, mb2->payload, strlen( payload_str )), 0, "realloc payload(clone+nocopy) copied payload when not supposed to" );
329 // with a clone, we must verify that original message looks sane too
330 errors += fail_not_equal( mbuf->mtype, 99, "realloc payload (clone+nocopy) validation of unchanged mbuf->mtype fails" );
331 errors += fail_not_equal( mbuf->sub_id, 100, "realloc payload (clone+nocopy) validation of unchanged mbuf->subid fails" );
332 errors += fail_not_equal( mbuf->len, strlen( payload_str ), "realloc payload (clone+nocopy) validation of unchanged payload len fails" );
333 errors += fail_not_equal( rmr_payload_size( mbuf ), 1024, "realloc payload (clone+nocopy) validation of unchanged alloc length fails" );
334 errors += fail_not_equal( strncmp( payload_str, mbuf->payload, strlen( payload_str )), 0, "realloc payload (clone+nocopy) validation of unchanged payload fails" );