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