enhance(API): Add source IP support to msg header
[ric-plt/lib/rmr.git] / test / sr_nng_static_test.c
1 // : vi ts=4 sw=4 noet :
2 /*
3 ==================================================================================
4             Copyright (c) 2019 Nokia
5             Copyright (c) 2018-2019 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_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.
25
26         Author:         E. Scott Daniels
27         Date:           3 April 2019
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 /*
44         Generate a simple route table (for all but direct route table testing).
45         This gets tricky inasmuch as we generate two in one; first a whole table 
46         and then two update tables. The first is a table with a bad counter in the
47         last record to test that we don't load that table and error. The second
48         is a good update.
49 */
50 static void gen_rt( uta_ctx_t* ctx ) {
51         int             fd;
52         char*   rt_stuff;               // strings for the route table
53
54         rt_stuff =
55                 "newrt|end\n"                                                           // end of table check before start of table found
56                 "# comment to drive full comment test\n"
57                 "\n"                                                                            // handle blank lines
58                 "   \n"                                                                         // handle blank lines
59             "mse|4|10|localhost:4561\n"                                 // entry before start message
60             "rte|4|localhost:4561\n"                                    // entry before start message
61                 "newrt|start\n"                                                         // false start to drive detection
62                 "xxx|badentry to drive default case"
63                 "newrt|start\n"
64             "rte|0|localhost:4560,localhost:4562\n"                                     // these are legitimate entries for our testing
65             "rte|1|localhost:4562;localhost:4561,localhost:4569\n"
66             "rte|2|localhost:4562| 10\n"                                                                // new subid at end
67             "mse|4|10|localhost:4561\n"                                                                 // new msg/subid specifier rec
68             "mse|4|localhost:4561\n"                                                                    // new mse entry with less than needed fields
69                 "   rte|   5   |localhost:4563    #garbage comment\n"           // tests white space cleanup
70             "rte|6|localhost:4562\n"
71                 "newrt|end\n";
72
73         fd = open( "utesting.rt", O_WRONLY | O_CREAT, 0600 );
74         if( fd < 0 ) {
75                 fprintf( stderr, "<BUGGERED> unable to open file for testing route table gen\n" );
76                 return;
77         }
78
79         setenv( "RMR_SEED_RT", "utesting.rt", 1 );
80         write( fd, rt_stuff, strlen( rt_stuff ) );              // write in the whole table
81
82         rt_stuff =
83                 "updatert|start\n"                                                                      // this is an update to the table
84             "mse|4|99|fooapp:9999,barapp:9999;logger:9999\n"    // update just one entry
85                 "updatert|end | 3\n";                                                           // bad count; this update should be rejected
86         write( fd, rt_stuff, strlen( rt_stuff ) );
87
88         rt_stuff =
89                 "updatert|start\n"                                                                      // this is an update to the table
90             "mse|4|10|fooapp:4561,barapp:4561;logger:9999\n"    // update just one entry
91                 "del|2|-1\n"                                                                            // delete an entry; not there so no action
92                 "del|2|10\n"                                                                            // delete an entry
93                 "updatert|end | 3\n";                                                           // end table; updates have a count as last field
94         write( fd, rt_stuff, strlen( rt_stuff ) );
95         
96         close( fd );
97         read_static_rt( ctx, 1 );                                                               // force in verbose mode to see stats on tty if failure
98         unlink( "utesting.rt" );
99 }
100
101
102 /*
103         Drive the send and receive functions.  We also drive as much of the route
104         table collector as is possible without a real rtg process running somewhere.
105
106         Send and receive functions are indirectly exercised from the rmr_nng_static_test
107         module as it tests the user facing send/receive/call/rts functions. These tests
108         should exercise specific cases for the internal functions as they will not
109         specifically be driven elsewhere.
110 */
111 static int sr_nng_test() {
112         uta_ctx_t* ctx;                         // context needed to test load static rt
113         uta_ctx_t*      real_ctx;       // real one to force odd situations for error testing
114         int errors = 0;                 // number errors found
115         rmr_mbuf_t*     mbuf;           // mbuf to send/receive
116         rmr_mbuf_t*     mb2;            // error capturing msg buf
117         int             whid = -1;
118         int             last_whid;
119         int     state;
120         nng_socket nn_dummy_sock;                                       // dummy needed to drive send
121         int             size;
122         int             i;
123         void*   p;
124
125         //ctx = rmr_init( "tcp:4360", 2048, 0 );                                // do NOT call init -- that starts the rtc thread which isn't good here
126         ctx = (uta_ctx_t *) malloc( sizeof( uta_ctx_t ) );              // alloc the context manually
127         memset( ctx, 0, sizeof( uta_ctx_t ) );
128
129         ctx->mring = NULL;              //uta_mk_ring( 128 );
130         ctx->max_plen = RMR_MAX_RCV_BYTES + sizeof( uta_mhdr_t );
131         ctx->max_mlen = ctx->max_plen + sizeof( uta_mhdr_t );
132         ctx->my_name = strdup( "dummy-test" );
133         ctx->my_ip = strdup( "30.4.19.86:1111" );
134         uta_lookup_rtg( ctx );
135
136         gen_rt( ctx );                                                          // forces a static load with some known info since we don't start the rtc()
137         gen_rt( ctx );                                                          // force a second load to test cloning
138
139         p = rt_ensure_ep( NULL, "foo" );                                // drive for coverage
140         errors += fail_not_nil( p,  "rt_ensure_ep did not return nil when given nil route table" );
141
142         state = rmr_ready( NULL );
143         errors += fail_if_true( state, "reported ready when given a nil context" );
144         state = rmr_ready( ctx );
145         errors += fail_if_false( state, "reported not ready when it should be" );
146
147         mbuf = rcv_msg( ctx, NULL );
148         errors += fail_if_nil( mbuf, "no mbuf returned on receive test" );
149
150         mbuf->len = 10;
151         mbuf->mtype = 1;
152
153         mb2 = clone_msg( mbuf );
154         errors += fail_if_nil( mb2, "clone message returned nil pointer" );
155         errors += fail_not_equal( mbuf->flags, mb2->flags, "clone did not duplicate flags" );
156         errors += fail_not_equal( mbuf->alloc_len, mb2->alloc_len, "clone did not dup alloc-len" );
157         errors += fail_not_equal( mbuf->state, mb2->state, "clone did not dup state" );
158         rmr_free_msg( mb2 );
159
160         mbuf = rmr_send_msg( NULL, mbuf );
161         errors += fail_if_nil( mbuf, "send with nil context but buffere didn't return buffer" );
162         if( mbuf ) {
163                 errors += fail_not_equal( mbuf->state, RMR_ERR_BADARG, "send with buffer but nil context didn't return right state" );
164         } else {
165                 mbuf = rmr_rcv_msg( ctx, NULL );
166         }
167
168         size = 2048 - em_hdr_size();            // emulated nng receive allocates 2K buffers -- subtract off header size
169         state = rmr_payload_size( mbuf );
170         errors += fail_not_equal( state, size, "payload size didn't return expected value" );   // receive should always give 4k buffer
171
172         rmr_free_msg( mbuf );
173
174
175         state = xlate_nng_state( NNG_EAGAIN, 99 );
176         errors += fail_if( state == 99, "xlate_nng_state returned default for nng_eagain" );
177         errors += fail_if( errno != EAGAIN, "xlate_nng_state did not set errno to eagain for nng_eagain" );
178
179         state = xlate_nng_state( NNG_ETIMEDOUT, 99 );
180         errors += fail_if( state == 99, "xlate_nng_state returned default for nng_timeout" );
181         errors += fail_if( errno != EAGAIN, "xlate_nng_state did not set errno to eagain for nng_timeout" );
182
183         state = xlate_nng_state( NNG_ENOTSUP, 99 );
184         errors += fail_if( state != 99, "xlate_nng_state did not return  default for nng_notsup" );
185
186         state = xlate_nng_state( NNG_ENOTSUP, 99 );
187         errors += fail_if( state != 99, "xlate_nng_state did not return  default for nng_notsup" );
188         errors += fail_if( errno == 0, "xlate_nng_state did not set errno (1)" );
189
190         state = xlate_nng_state( NNG_EINVAL, 99 );
191         errors += fail_if( state != 99, "xlate_nng_state did not return  default for nng_inval" );
192         errors += fail_if( errno == 0, "xlate_nng_state did not set errno (2)" );
193
194         state = xlate_nng_state( NNG_ENOMEM, 99 );
195         errors += fail_if( state != 99, "xlate_nng_state did not return  default for nng_nomem" );
196         errors += fail_if( errno == 0, "xlate_nng_state did not set errno (3)" );
197
198         state = xlate_nng_state( NNG_ESTATE, 99 );
199         errors += fail_if( state != 99, "xlate_nng_state did not return  default for nng_state" );
200         errors += fail_if( errno == 0, "xlate_nng_state did not set errno (4)" );
201
202         state = xlate_nng_state( NNG_ECLOSED, 99 );
203         errors += fail_if( state != 99, "xlate_nng_state did not return  default for nng_closed" );
204         errors += fail_if( errno == 0, "xlate_nng_state did not set errno (5)" );
205
206         state = xlate_nng_state( 999, 99 );
207         errors += fail_if( state != 99, "xlate_nng_state did not return  default for unknown error" );
208         errors += fail_if( errno == 0, "xlate_nng_state did not set errno (6)" );
209
210         // ---- drive rtc in a 'static' (not pthreaded) mode to get some coverage; no 'results' to be verified -----
211         setenv( ENV_RTG_RAW, "1", 1 );                                                          // rtc should expect raw messages (mostly coverage here)
212         setenv( ENV_VERBOSE_FILE, ".ut_rmr_verbose", 1 );                       // allow for verbose code in rtc to be driven
213         i = open( ".ut_rmr_verbose", O_RDWR | O_CREAT, 0654 );
214         if( i >= 0 ) {
215                 write( i, "2\n", 2 );
216                 close( i );
217         }
218         ctx->shutdown = 1;                      // should force rtc to quit on first pass
219         rtc( NULL );                            // coverage test with nil pointer
220         rtc( ctx );
221
222
223         return !!errors;
224 }