CI: Add silent cmake SonarCloud scan
[ric-plt/lib/rmr.git] / test / sr_si_static_test.c
1 // : vi ts=4 sw=4 noet :
2 /*
3 ==================================================================================
4             Copyright (c) 2020-2021 Nokia
5             Copyright (c) 2020-2021 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
86         gen_rt( ctx );                                                          // forces a static load with some known info since we don't start the rtc()
87         gen_rt( ctx );                                                          // force a second load to test cloning
88
89         p = rt_ensure_ep( NULL, "foo" );                                // drive for coverage
90         errors += fail_not_nil( p,  "rt_ensure_ep did not return nil when given nil route table" );
91
92         state = rmr_ready( NULL );
93         errors += fail_if_true( state, "reported ready when given a nil context" );
94         state = rmr_ready( ctx );
95         errors += fail_if_false( state, "reported not ready when it should be" );
96
97         /*
98                 rcv_msg under SI is deprecated -- do not attempt to call
99         mbuf = rcv_msg( ctx, NULL );
100         errors += fail_if_nil( mbuf, "no mbuf returned on receive test" );
101         */
102
103         mbuf = rmr_alloc_msg( ctx, 2048 );
104         mbuf->len = 10;
105         mbuf->mtype = 1;
106
107         mb2 = clone_msg( mbuf );
108         errors += fail_if_nil( mb2, "clone message returned nil pointer" );
109         errors += fail_not_equal( mbuf->flags, mb2->flags, "clone did not duplicate flags" );
110         errors += fail_not_equal( mbuf->alloc_len, mb2->alloc_len, "clone did not dup alloc-len" );
111         errors += fail_not_equal( mbuf->state, mb2->state, "clone did not dup state" );
112         rmr_free_msg( mb2 );
113
114         mbuf = rmr_send_msg( NULL, mbuf );
115         errors += fail_if_nil( mbuf, "send with nil context but buffere didn't return buffer" );
116         if( mbuf ) {
117                 errors += fail_not_equal( mbuf->state, RMR_ERR_BADARG, "send with buffer but nil context didn't return right state" );
118         } else {
119                 mbuf = rmr_alloc_msg( ctx, 2048 );
120         }
121
122         //size = 2048 - em_hdr_size();          // emulated receive allocates 2K buffers -- subtract off header size
123         size = 2048;
124         state = rmr_payload_size( mbuf );
125         errors += fail_not_equal( state, size, "payload size didn't return expected value" );   // receive should always give 4k buffer
126
127         rmr_free_msg( mbuf );
128
129
130         // -------- drive rtc in a 'static' (not pthreaded) mode to get some coverage; no 'results' to be verified -----
131         /*
132                 It is impossible to drive the message loop of the rtc from a unit test because
133                 we cannot generate a message that will arrive on its private RMR context.
134         */
135
136         setenv( ENV_RTG_RAW, "0", 1 );                                                          // rtc is never raw under SI
137         setenv( ENV_VERBOSE_FILE, ".ut_rmr_verbose", 1 );                       // allow for verbose code in rtc to be driven
138         i = open( ".ut_rmr_verbose", O_RDWR | O_CREAT, 0654 );
139         if( i >= 0 ) {
140                 write( i, "2\n", 2 );
141                 close( i );
142         }
143         ctx->shutdown = 1;                      // should force rtc to quit on first pass
144         rtc( NULL );                            // coverage test with nil pointer
145
146         rtc_file( NULL );                       // the static file only collector
147         rtc_file( ctx );
148
149         setenv( "RMR_RTREQ_FREQ", "400", 1 );   // force error checking code in rtc to resort to default
150         rtc( ctx );
151
152         setenv( "RMR_CTL_PORT", "43086", 1 );   // force defined branch in rtc
153         rtc( ctx );
154
155         setenv( "RMR_RTG_SVC", "4567", 1 );             // drive for edge case coverage to ensure no nil pointer etc
156         rtc( ctx );
157         setenv( "RMR_RTG_SVC", "tcp:4567", 1 );
158         rtc( ctx );
159         setenv( "RMR_RTG_SVC", "tcp:4567:error", 1 );
160         rtc( ctx );
161         setenv( "RMR_RTG_SVC", "localhost:4589", 1 );           // should force a request to be sent though no reponse back.
162         rtc( ctx );
163
164         payload_str = "newrt|start|abc-def\nmse|10|-1|host1:43086\nmse|20|-1|host1:43086\nnewrt|end|2\n";
165         mbuf = mk_populated_msg( 1024, 0, 20, -2, strlen( payload_str ) );
166         memcpy( mbuf->payload, payload_str, mbuf->len );
167         rtc_parse_msg( ctx, pctx, mbuf, 5, &flags );
168
169         mbuf = mk_populated_msg( 1024, 0, 90, -2, strlen( payload_str ) );              // drive with invalid message type for coverage
170         rtc_parse_msg( ctx, pctx, mbuf, 5, &flags );
171
172
173         // ------------- reallocation tests ------------------------------------------------------------
174         // we use mk_populated_msg() to create a message with mid/sid/plen pushed into the transport
175         // header to simulate a message having been sent and received which is what causes this data
176         // to push into the wire packet.
177
178         payload_str = "Stand Up and Cheer; OU78-82";
179
180
181         mbuf = mk_populated_msg( 1024, 0, 99, 100, strlen( payload_str ) );
182         memcpy( mbuf->payload, payload_str, mbuf->len );
183         mb2 = realloc_payload( mbuf, 512, NO_COPY, NO_CLONE );
184         errors += fail_if_nil( mb2, "realloc_payload (no copy) returned a nil pointer when reallocating with smaller size" );
185         errors += fail_if_false( mbuf == mb2, "non-clone realloc payload (no copy) of smaller size did not return the same buffer" );
186
187         mb2 = realloc_payload( NULL, 512, NO_COPY, NO_CLONE );
188         errors += fail_not_nil( mb2, "realloc payload did not return nil pointer when passed nil mbuf" );
189
190         mb2 = realloc_payload( mbuf, 0, NO_COPY, NO_CLONE );
191         errors += fail_not_nil( mb2, "realloc payload did not return nil pointer when passed bad len" );
192
193         fprintf( stderr, "<TEST> no copy/no clone test starts\n" );
194         mb2 = realloc_payload( mbuf, 2048, NO_COPY, NO_CLONE );
195         errors += fail_if_false( mbuf == mb2, "realloc payload (no copy) of larger size did not return the same msg buffer(1)" );
196         errors += fail_not_equal( mb2->mtype, -1, "realloc payload (no copy) did not reset mtype(a) to expected(b) value" );
197         errors += fail_not_equal( mb2->sub_id, -1, "realloc payload (no copy) did not reset sub-id(a) to expected(b) value" );
198         errors += fail_if_nil( mb2, "realloc payload returned (no copy) a nil pointer when increasing payload len" );
199         errors += fail_not_equal( mb2->len, 0, "realloc payload payload len(a) not expected(b):" );
200         errors += fail_not_equal( rmr_payload_size( mb2), 2048, "realloc payload alloc len(a) not expected(b)" );
201
202         fprintf( stderr, "<TEST> copy/no clone test starts\n" );
203         mbuf = mk_populated_msg( 1024, 0, 99, 100, strlen( payload_str ) );
204         memcpy( mbuf->payload, payload_str, mbuf->len );
205         mb2 = realloc_payload( mbuf, 2048, COPY, NO_CLONE );
206         errors += fail_if_false( mbuf == mb2, "non-clone realloc payload (copy) of larger size did not return the same msg buffer(2)" );
207         errors += fail_if_nil( mb2, "realloc payload (copy) returned a nil pointer when increasing payload len)" );
208         errors += fail_not_equal( mb2->mtype, 99, "realloc payload (copy) did not reset mtype(a) to expected(b) value" );
209         errors += fail_not_equal( mb2->sub_id, 100, "realloc payload (copy) did not reset sub-id(a) to expected(b) value" );
210         errors += fail_if_equal( mb2->len, 0, "realloc payload (copy) msg len(a) not expected(b)" );
211         errors += fail_not_equal( rmr_payload_size( mb2), 2048, "realloc payload (copy) alloc len(a) not expected(b)" );
212         errors += fail_not_equal( strncmp( payload_str, mb2->payload, strlen( payload_str )), 0, "realloc payload(copy) didn't copy payload" );
213
214         fprintf( stderr, "<TEST> copy/clone test starts requested buffer smaller than original\n" );
215         mbuf = mk_populated_msg( 1024, 0, 99, 100, strlen( payload_str ) );
216         memcpy( mbuf->payload, payload_str, mbuf->len );
217         mb2 = realloc_payload( mbuf, 512, COPY, CLONE );
218         errors += fail_if_true( mbuf == mb2, "realloc payload (clone+copy) of larger size did not return different message buffers" );
219         errors += fail_if_nil( mb2, "realloc payload (clone+copy) returned a nil pointer when increasing payload len)" );
220         errors += fail_not_equal( mb2->mtype, 99, "realloc payload (clone+copy) did not reset mtype(a) to expected(b) value" );
221         errors += fail_not_equal( mb2->sub_id, 100, "realloc payload (clone+copy) did not reset sub-id(a) to expected(b) value" );
222         errors += fail_not_equal( mb2->len, strlen( payload_str ), "realloc payload (clone+copy) msg len(a) not expected(b)" );
223         errors += fail_not_equal( rmr_payload_size( mb2), 1024, "realloc payload (clone+copy) alloc len(a) not expected(b)" );
224         errors += fail_not_equal( strncmp( payload_str, mb2->payload, strlen( payload_str )), 0, "realloc payload(clone+copy) didn't copy payload" );
225
226         // with a clone, we must verify that original message looks sane too
227         errors += fail_not_equal( mbuf->mtype, 99, "realloc payload (clone+copy) validation of unchanged mbuf->mtype fails" );
228         errors += fail_not_equal( mbuf->sub_id, 100, "realloc payload (clone+copy) validation of unchanged mbuf->subid fails" );
229         errors += fail_not_equal( mbuf->len, strlen( payload_str ), "realloc payload (clone+copy) validation of unchanged payload len fails" );
230         errors += fail_not_equal( rmr_payload_size( mbuf ), 1024, "realloc payload (clone+copy) validation of unchanged alloc length fails" );
231         errors += fail_not_equal( strncmp( payload_str, mbuf->payload, strlen( payload_str )), 0, "realloc payload(clone+copy) validation of unchanged payload fails" );
232
233
234         fprintf( stderr, "<TEST> copy/clone test starts requested buf is larger than original\n" );
235         mbuf = mk_populated_msg( 1024, 0, 99, 100, strlen( payload_str ) );
236         memcpy( mbuf->payload, payload_str, mbuf->len );
237         mb2 = realloc_payload( mbuf, 2048, COPY, CLONE );
238         errors += fail_if_true( mbuf == mb2, "realloc payload(clone+copy/lg) of larger size did not return different message buffers" );
239         errors += fail_if_nil( mb2, "realloc payload (clone+copy/lg) returned a nil pointer when increasing payload len)" );
240         errors += fail_not_equal( mb2->mtype, 99, "realloc payload (clone+copy/lg) did not reset mtype(a) to expected(b) value" );
241         errors += fail_not_equal( mb2->sub_id, 100, "realloc payload (clone+copy/lg) did not reset sub-id(a) to expected(b) value" );
242         errors += fail_not_equal( mb2->len, strlen( payload_str ), "realloc payload (clone+copy/lg) msg len(a) not expected(b)" );
243         errors += fail_not_equal( rmr_payload_size( mb2), 2048, "realloc payload (clone+copy/lg) alloc len(a) not expected(b)" );
244         errors += fail_not_equal( strncmp( payload_str, mb2->payload, strlen( payload_str )), 0, "realloc payload(clone+copy/lg) didn't copy payload" );
245
246         // with a clone, we must verify that original message looks sane too
247         errors += fail_not_equal( mbuf->mtype, 99, "realloc payload (clone+copy/lg) validation of unchanged mbuf->mtype fails" );
248         errors += fail_not_equal( mbuf->sub_id, 100, "realloc payload (clone+copy/lg) validation of unchanged mbuf->subid fails" );
249         errors += fail_not_equal( mbuf->len, strlen( payload_str ), "realloc payload (clone+copy/lg) validation of unchanged payload len fails" );
250         errors += fail_not_equal( rmr_payload_size( mbuf ), 1024, "realloc payload (clone+copy/lg) validation of unchanged alloc length fails" );
251         errors += fail_not_equal( strncmp( payload_str, mbuf->payload, strlen( payload_str )), 0, "realloc payload(clone+copy/lg) validation of unchanged payload fails" );
252
253         // original message should be unharmed, and new message should have no type/sid or payload len; total alloc len should be requested enlargement
254         fprintf( stderr, "<TEST> no copy/clone test starts requested buf is larger than original\n" );
255         mbuf = mk_populated_msg( 1024, 0, 99, 100, strlen( payload_str ) );
256         memcpy( mbuf->payload, payload_str, mbuf->len );
257         mb2 = realloc_payload( mbuf, 2048, NO_COPY, CLONE );
258         errors += fail_if_true( mbuf == mb2, "realloc payload (clone+nocopy) of larger size did not return different message buffers" );
259         errors += fail_if_nil( mb2, "realloc payload (clone+nocopy) returned a nil pointer when increasing payload len)" );
260         errors += fail_not_equal( mb2->mtype, -1, "realloc payload (clone+nocopy) did not reset mtype(a) to expected(b) value" );
261         errors += fail_not_equal( mb2->sub_id, -1, "realloc payload (clone+nocopy) did not reset sub-id(a) to expected(b) value" );
262         errors += fail_not_equal( mb2->len, 0, "realloc payload (clone+nocopy) msg len(a) not expected(b)" );
263         errors += fail_not_equal( rmr_payload_size( mb2 ), 2048, "realloc payload (clone+nocopy) alloc len(a) not expected(b)" );
264         //errors += fail_if_equal( strncmp( payload_str, mb2->payload, strlen( payload_str )), 0, "realloc payload(clone+nocopy) copied payload when not supposed to" );
265
266         // with a clone, we must verify that original message looks sane too
267         errors += fail_not_equal( mbuf->mtype, 99, "realloc payload (clone+nocopy) validation of unchanged mbuf->mtype fails" );
268         errors += fail_not_equal( mbuf->sub_id, 100, "realloc payload (clone+nocopy) validation of unchanged mbuf->subid fails" );
269         errors += fail_not_equal( mbuf->len, strlen( payload_str ), "realloc payload (clone+nocopy) validation of unchanged payload len fails" );
270         errors += fail_not_equal( rmr_payload_size( mbuf ), 1024, "realloc payload (clone+nocopy) validation of unchanged alloc length fails" );
271         errors += fail_not_equal( strncmp( payload_str, mbuf->payload, strlen( payload_str )), 0, "realloc payload (clone+nocopy) validation of unchanged payload fails" );
272
273
274         // ---------------------- misc coverage tests; nothing to verify other than they don't crash -----------------------
275         payload_str = strdup( "The Marching 110 will play the OU fightsong after every touchdown or field goal; it is a common sound echoing from Peden Stadium in the fall." );
276
277         dump_n( payload_str, "A dump", strlen( payload_str ) );
278         dump_40( payload_str, "another dump" );
279
280         unlink( ".ut_rmr_verbose" );
281
282         return errors;
283
284 }