e3b5a7763e70f8e280d209953fcefaac52c8d578
[ric-plt/lib/rmr.git] / test / sr_si_static_test.c
1 // : vi ts=4 sw=4 noet :
2 /*
3 ==================================================================================
4             Copyright (c) 2020 Nokia
5             Copyright (c) 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:       sr_si_static_test.c
23         Abstract:       Test the send/receive funcitons. These are meant to be included at compile
24                                 time by the test driver.
25
26         Author:         E. Scott Daniels
27         Date:           21 February 2020
28 */
29
30 #include <unistd.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <strings.h>
34 #include <errno.h>
35 #include <string.h>
36 #include <stdint.h>
37 #include <pthread.h>
38 #include <semaphore.h>
39
40 #include "rmr.h"
41 #include "rmr_agnostic.h"
42
43 // ----------- local test support ----------------------------------------------------------
44 #define CLONE   1                       // convenience constants for payload realloc tests
45 #define NO_CLONE 0
46 #define COPY 1
47 #define NO_COPY 0
48
49 /*
50         Drive the send and receive functions.  We also drive as much of the route
51         table collector as is possible without a real rtg process running somewhere.
52
53         Send and receive functions are indirectly exercised from the rmr_si_static_test
54         module as it tests the user facing send/receive/call/rts functions. These tests
55         should exercise specific cases for the internal functions as they will not
56         specifically be driven elsewhere.
57
58         This requires the gen_rt funcition that is in the test_gen_rt module and should
59         have been included by the test module(s) which include this.
60 */
61 static int sr_si_test() {
62         uta_ctx_t* ctx;                 // two context structs needed to test route table collector
63         uta_ctx_t* pctx;
64         uta_ctx_t*      real_ctx;       // real one to force odd situations for error testing
65         int errors = 0;                 // number errors found
66         rmr_mbuf_t*     mbuf;           // mbuf to send/receive
67         rmr_mbuf_t*     mb2;            // second mbuf when needed
68         int             whid = -1;
69         int             last_whid;
70         int             state;
71         int             nn_dummy_sock;                                  // dummy needed to drive send
72         int             size;
73         int             i;
74         int             flags = 0;                                              // flags needed to pass to rtc funcitons
75         void*   p;
76         char*   payload_str;
77
78         ctx = mk_dummy_ctx();                                                                   // in the si world we need some rings in the context
79         pctx = mk_dummy_ctx();
80
81         ctx->max_plen = RMR_MAX_RCV_BYTES + sizeof( uta_mhdr_t );
82         ctx->max_mlen = ctx->max_plen + sizeof( uta_mhdr_t );
83         ctx->my_name = strdup( "dummy-test" );
84         ctx->my_ip = strdup( "30.4.19.86:1111" );
85         uta_lookup_rtg( ctx );
86
87         gen_rt( ctx );                                                          // forces a static load with some known info since we don't start the rtc()
88         gen_rt( ctx );                                                          // force a second load to test cloning
89
90         p = rt_ensure_ep( NULL, "foo" );                                // drive for coverage
91         errors += fail_not_nil( p,  "rt_ensure_ep did not return nil when given nil route table" );
92
93         state = rmr_ready( NULL );
94         errors += fail_if_true( state, "reported ready when given a nil context" );
95         state = rmr_ready( ctx );
96         errors += fail_if_false( state, "reported not ready when it should be" );
97
98         /*
99                 rcv_msg under SI is deprecated -- do not attempt to call
100         mbuf = rcv_msg( ctx, NULL );
101         errors += fail_if_nil( mbuf, "no mbuf returned on receive test" );
102         */
103
104         mbuf = rmr_alloc_msg( ctx, 2048 );
105         mbuf->len = 10;
106         mbuf->mtype = 1;
107
108         mb2 = clone_msg( mbuf );
109         errors += fail_if_nil( mb2, "clone message returned nil pointer" );
110         errors += fail_not_equal( mbuf->flags, mb2->flags, "clone did not duplicate flags" );
111         errors += fail_not_equal( mbuf->alloc_len, mb2->alloc_len, "clone did not dup alloc-len" );
112         errors += fail_not_equal( mbuf->state, mb2->state, "clone did not dup state" );
113         rmr_free_msg( mb2 );
114
115         mbuf = rmr_send_msg( NULL, mbuf );
116         errors += fail_if_nil( mbuf, "send with nil context but buffere didn't return buffer" );
117         if( mbuf ) {
118                 errors += fail_not_equal( mbuf->state, RMR_ERR_BADARG, "send with buffer but nil context didn't return right state" );
119         } else {
120                 mbuf = rmr_alloc_msg( ctx, 2048 );
121         }
122
123         //size = 2048 - em_hdr_size();          // emulated receive allocates 2K buffers -- subtract off header size
124         size = 2048;
125         state = rmr_payload_size( mbuf );
126         errors += fail_not_equal( state, size, "payload size didn't return expected value" );   // receive should always give 4k buffer
127
128         rmr_free_msg( mbuf );
129
130
131         // -------- drive rtc in a 'static' (not pthreaded) mode to get some coverage; no 'results' to be verified -----
132         /*
133                 It is impossible to drive the message loop of the rtc from a unit test because
134                 we cannot generate a message that will arrive on its private RMR context.
135         */
136
137         setenv( ENV_RTG_RAW, "0", 1 );                                                          // rtc is never raw under SI
138         setenv( ENV_VERBOSE_FILE, ".ut_rmr_verbose", 1 );                       // allow for verbose code in rtc to be driven
139         i = open( ".ut_rmr_verbose", O_RDWR | O_CREAT, 0654 );
140         if( i >= 0 ) {
141                 write( i, "2\n", 2 );
142                 close( i );
143         }
144         ctx->shutdown = 1;                      // should force rtc to quit on first pass
145         rtc( NULL );                            // coverage test with nil pointer
146
147         rtc_file( NULL );                       // the static file only collector
148         rtc_file( ctx );
149
150         setenv( "RMR_RTREQ_FREQ", "400", 1 );   // force error checking code in rtc to resort to default
151         rtc( ctx );
152
153         setenv( "RMR_CTL_PORT", "43086", 1 );   // force defined branch in rtc
154         rtc( ctx );
155
156         setenv( "RMR_RTG_SVC", "4567", 1 );             // drive for edge case coverage to ensure no nil pointer etc
157         rtc( ctx );
158         setenv( "RMR_RTG_SVC", "tcp:4567", 1 );
159         rtc( ctx );
160         setenv( "RMR_RTG_SVC", "tcp:4567:error", 1 );
161         rtc( ctx );
162         setenv( "RMR_RTG_SVC", "localhost:4589", 1 );           // should force a request to be sent though no reponse back.
163         rtc( ctx );
164
165         payload_str = "newrt|start|abc-def\nmse|10|-1|host1:43086\nmse|20|-1|host1:43086\nnewrt|end|2\n";
166         mbuf = mk_populated_msg( 1024, 0, 20, -2, strlen( payload_str ) );
167         memcpy( mbuf->payload, payload_str, mbuf->len );
168         rtc_parse_msg( ctx, pctx, mbuf, 5, &flags );
169
170         mbuf = mk_populated_msg( 1024, 0, 90, -2, strlen( payload_str ) );              // drive with invalid message type for coverage
171         rtc_parse_msg( ctx, pctx, mbuf, 5, &flags );
172
173
174         // ------------- reallocation tests ------------------------------------------------------------
175         // we use mk_populated_msg() to create a message with mid/sid/plen pushed into the transport
176         // header to simulate a message having been sent and received which is what causes this data
177         // to push into the wire packet.
178
179         payload_str = "Stand Up and Cheer; OU78-82";
180
181
182         mbuf = mk_populated_msg( 1024, 0, 99, 100, strlen( payload_str ) );
183         memcpy( mbuf->payload, payload_str, mbuf->len );
184         mb2 = realloc_payload( mbuf, 512, NO_COPY, NO_CLONE );
185         errors += fail_if_nil( mb2, "realloc_payload (no copy) returned a nil pointer when reallocating with smaller size" );
186         errors += fail_if_false( mbuf == mb2, "non-clone realloc payload (no copy) of smaller size did not return the same buffer" );
187
188         mb2 = realloc_payload( NULL, 512, NO_COPY, NO_CLONE );
189         errors += fail_not_nil( mb2, "realloc payload did not return nil pointer when passed nil mbuf" );
190
191         mb2 = realloc_payload( mbuf, 0, NO_COPY, NO_CLONE );
192         errors += fail_not_nil( mb2, "realloc payload did not return nil pointer when passed bad len" );
193
194         fprintf( stderr, "<TEST> no copy/no clone test starts\n" );
195         mb2 = realloc_payload( mbuf, 2048, NO_COPY, NO_CLONE );
196         errors += fail_if_false( mbuf == mb2, "realloc payload (no copy) of larger size did not return the same msg buffer(1)" );
197         errors += fail_not_equal( mb2->mtype, -1, "realloc payload (no copy) did not reset mtype(a) to expected(b) value" );
198         errors += fail_not_equal( mb2->sub_id, -1, "realloc payload (no copy) did not reset sub-id(a) to expected(b) value" );
199         errors += fail_if_nil( mb2, "realloc payload returned (no copy) a nil pointer when increasing payload len" );
200         errors += fail_not_equal( mb2->len, 0, "realloc payload payload len(a) not expected(b):" );
201         errors += fail_not_equal( rmr_payload_size( mb2), 2048, "realloc payload alloc len(a) not expected(b)" );
202
203         fprintf( stderr, "<TEST> copy/no clone test starts\n" );
204         mbuf = mk_populated_msg( 1024, 0, 99, 100, strlen( payload_str ) );
205         memcpy( mbuf->payload, payload_str, mbuf->len );
206         mb2 = realloc_payload( mbuf, 2048, COPY, NO_CLONE );
207         errors += fail_if_false( mbuf == mb2, "non-clone realloc payload (copy) of larger size did not return the same msg buffer(2)" );
208         errors += fail_if_nil( mb2, "realloc payload (copy) returned a nil pointer when increasing payload len)" );
209         errors += fail_not_equal( mb2->mtype, 99, "realloc payload (copy) did not reset mtype(a) to expected(b) value" );
210         errors += fail_not_equal( mb2->sub_id, 100, "realloc payload (copy) did not reset sub-id(a) to expected(b) value" );
211         errors += fail_if_equal( mb2->len, 0, "realloc payload (copy) msg len(a) not expected(b)" );
212         errors += fail_not_equal( rmr_payload_size( mb2), 2048, "realloc payload (copy) alloc len(a) not expected(b)" );
213         errors += fail_not_equal( strncmp( payload_str, mb2->payload, strlen( payload_str )), 0, "realloc payload(copy) didn't copy payload" );
214
215         fprintf( stderr, "<TEST> copy/clone test starts requested buffer smaller than original\n" );
216         mbuf = mk_populated_msg( 1024, 0, 99, 100, strlen( payload_str ) );
217         memcpy( mbuf->payload, payload_str, mbuf->len );
218         mb2 = realloc_payload( mbuf, 512, COPY, CLONE );
219         errors += fail_if_true( mbuf == mb2, "realloc payload (clone+copy) of larger size did not return different message buffers" );
220         errors += fail_if_nil( mb2, "realloc payload (clone+copy) returned a nil pointer when increasing payload len)" );
221         errors += fail_not_equal( mb2->mtype, 99, "realloc payload (clone+copy) did not reset mtype(a) to expected(b) value" );
222         errors += fail_not_equal( mb2->sub_id, 100, "realloc payload (clone+copy) did not reset sub-id(a) to expected(b) value" );
223         errors += fail_not_equal( mb2->len, strlen( payload_str ), "realloc payload (clone+copy) msg len(a) not expected(b)" );
224         errors += fail_not_equal( rmr_payload_size( mb2), 1024, "realloc payload (clone+copy) alloc len(a) not expected(b)" );
225         errors += fail_not_equal( strncmp( payload_str, mb2->payload, strlen( payload_str )), 0, "realloc payload(clone+copy) didn't copy payload" );
226
227         // with a clone, we must verify that original message looks sane too
228         errors += fail_not_equal( mbuf->mtype, 99, "realloc payload (clone+copy) validation of unchanged mbuf->mtype fails" );
229         errors += fail_not_equal( mbuf->sub_id, 100, "realloc payload (clone+copy) validation of unchanged mbuf->subid fails" );
230         errors += fail_not_equal( mbuf->len, strlen( payload_str ), "realloc payload (clone+copy) validation of unchanged payload len fails" );
231         errors += fail_not_equal( rmr_payload_size( mbuf ), 1024, "realloc payload (clone+copy) validation of unchanged alloc length fails" );
232         errors += fail_not_equal( strncmp( payload_str, mbuf->payload, strlen( payload_str )), 0, "realloc payload(clone+copy) validation of unchanged payload fails" );
233
234
235         fprintf( stderr, "<TEST> copy/clone test starts requested buf is larger than original\n" );
236         mbuf = mk_populated_msg( 1024, 0, 99, 100, strlen( payload_str ) );
237         memcpy( mbuf->payload, payload_str, mbuf->len );
238         mb2 = realloc_payload( mbuf, 2048, COPY, CLONE );
239         errors += fail_if_true( mbuf == mb2, "realloc payload(clone+copy/lg) of larger size did not return different message buffers" );
240         errors += fail_if_nil( mb2, "realloc payload (clone+copy/lg) returned a nil pointer when increasing payload len)" );
241         errors += fail_not_equal( mb2->mtype, 99, "realloc payload (clone+copy/lg) did not reset mtype(a) to expected(b) value" );
242         errors += fail_not_equal( mb2->sub_id, 100, "realloc payload (clone+copy/lg) did not reset sub-id(a) to expected(b) value" );
243         errors += fail_not_equal( mb2->len, strlen( payload_str ), "realloc payload (clone+copy/lg) msg len(a) not expected(b)" );
244         errors += fail_not_equal( rmr_payload_size( mb2), 2048, "realloc payload (clone+copy/lg) alloc len(a) not expected(b)" );
245         errors += fail_not_equal( strncmp( payload_str, mb2->payload, strlen( payload_str )), 0, "realloc payload(clone+copy/lg) didn't copy payload" );
246
247         // with a clone, we must verify that original message looks sane too
248         errors += fail_not_equal( mbuf->mtype, 99, "realloc payload (clone+copy/lg) validation of unchanged mbuf->mtype fails" );
249         errors += fail_not_equal( mbuf->sub_id, 100, "realloc payload (clone+copy/lg) validation of unchanged mbuf->subid fails" );
250         errors += fail_not_equal( mbuf->len, strlen( payload_str ), "realloc payload (clone+copy/lg) validation of unchanged payload len fails" );
251         errors += fail_not_equal( rmr_payload_size( mbuf ), 1024, "realloc payload (clone+copy/lg) validation of unchanged alloc length fails" );
252         errors += fail_not_equal( strncmp( payload_str, mbuf->payload, strlen( payload_str )), 0, "realloc payload(clone+copy/lg) validation of unchanged payload fails" );
253
254         // original message should be unharmed, and new message should have no type/sid or payload len; total alloc len should be requested enlargement
255         fprintf( stderr, "<TEST> no copy/clone test starts requested buf is larger than original\n" );
256         mbuf = mk_populated_msg( 1024, 0, 99, 100, strlen( payload_str ) );
257         memcpy( mbuf->payload, payload_str, mbuf->len );
258         mb2 = realloc_payload( mbuf, 2048, NO_COPY, CLONE );
259         errors += fail_if_true( mbuf == mb2, "realloc payload (clone+nocopy) of larger size did not return different message buffers" );
260         errors += fail_if_nil( mb2, "realloc payload (clone+nocopy) returned a nil pointer when increasing payload len)" );
261         errors += fail_not_equal( mb2->mtype, -1, "realloc payload (clone+nocopy) did not reset mtype(a) to expected(b) value" );
262         errors += fail_not_equal( mb2->sub_id, -1, "realloc payload (clone+nocopy) did not reset sub-id(a) to expected(b) value" );
263         errors += fail_not_equal( mb2->len, 0, "realloc payload (clone+nocopy) msg len(a) not expected(b)" );
264         errors += fail_not_equal( rmr_payload_size( mb2 ), 2048, "realloc payload (clone+nocopy) alloc len(a) not expected(b)" );
265         //errors += fail_if_equal( strncmp( payload_str, mb2->payload, strlen( payload_str )), 0, "realloc payload(clone+nocopy) copied payload when not supposed to" );
266
267         // with a clone, we must verify that original message looks sane too
268         errors += fail_not_equal( mbuf->mtype, 99, "realloc payload (clone+nocopy) validation of unchanged mbuf->mtype fails" );
269         errors += fail_not_equal( mbuf->sub_id, 100, "realloc payload (clone+nocopy) validation of unchanged mbuf->subid fails" );
270         errors += fail_not_equal( mbuf->len, strlen( payload_str ), "realloc payload (clone+nocopy) validation of unchanged payload len fails" );
271         errors += fail_not_equal( rmr_payload_size( mbuf ), 1024, "realloc payload (clone+nocopy) validation of unchanged alloc length fails" );
272         errors += fail_not_equal( strncmp( payload_str, mbuf->payload, strlen( payload_str )), 0, "realloc payload (clone+nocopy) validation of unchanged payload fails" );
273
274
275         return !!errors;
276 }