809deba071a3dc610f31390cac2a0440d53e52b2
[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         uta_lookup_rtg( ctx );
134
135         gen_rt( ctx );                                                          // forces a static load with some known info since we don't start the rtc()
136         gen_rt( ctx );                                                          // force a second load to test cloning
137
138         p = rt_ensure_ep( NULL, "foo" );                                // drive for coverage
139         errors += fail_not_nil( p,  "rt_ensure_ep did not return nil when given nil route table" );
140
141         state = rmr_ready( NULL );
142         errors += fail_if_true( state, "reported ready when given a nil context" );
143         state = rmr_ready( ctx );
144         errors += fail_if_false( state, "reported not ready when it should be" );
145
146         mbuf = rcv_msg( ctx, NULL );
147         errors += fail_if_nil( mbuf, "no mbuf returned on receive test" );
148
149         mbuf->len = 10;
150         mbuf->mtype = 1;
151
152         mb2 = clone_msg( mbuf );
153         errors += fail_if_nil( mb2, "clone message returned nil pointer" );
154         errors += fail_not_equal( mbuf->flags, mb2->flags, "clone did not duplicate flags" );
155         errors += fail_not_equal( mbuf->alloc_len, mb2->alloc_len, "clone did not dup alloc-len" );
156         errors += fail_not_equal( mbuf->state, mb2->state, "clone did not dup state" );
157         rmr_free_msg( mb2 );
158
159         mbuf = rmr_send_msg( NULL, mbuf );
160         errors += fail_if_nil( mbuf, "send with nil context but buffere didn't return buffer" );
161         if( mbuf ) {
162                 errors += fail_not_equal( mbuf->state, RMR_ERR_BADARG, "send with buffer but nil context didn't return right state" );
163         } else {
164                 mbuf = rmr_rcv_msg( ctx, NULL );
165         }
166
167         size = 2048 - em_hdr_size();            // emulated nng receive allocates 2K buffers -- subtract off header size
168         state = rmr_payload_size( mbuf );
169         errors += fail_not_equal( state, size, "payload size didn't return expected value" );   // receive should always give 4k buffer
170
171         rmr_free_msg( mbuf );
172
173
174         state = xlate_nng_state( NNG_EAGAIN, 99 );
175         errors += fail_if( state == 99, "xlate_nng_state returned default for nng_eagain" );
176         errors += fail_if( errno != EAGAIN, "xlate_nng_state did not set errno to eagain for nng_eagain" );
177
178         state = xlate_nng_state( NNG_ETIMEDOUT, 99 );
179         errors += fail_if( state == 99, "xlate_nng_state returned default for nng_timeout" );
180         errors += fail_if( errno != EAGAIN, "xlate_nng_state did not set errno to eagain for nng_timeout" );
181
182         state = xlate_nng_state( NNG_ENOTSUP, 99 );
183         errors += fail_if( state != 99, "xlate_nng_state did not return  default for nng_notsup" );
184
185         state = xlate_nng_state( NNG_ENOTSUP, 99 );
186         errors += fail_if( state != 99, "xlate_nng_state did not return  default for nng_notsup" );
187         errors += fail_if( errno == 0, "xlate_nng_state did not set errno (1)" );
188
189         state = xlate_nng_state( NNG_EINVAL, 99 );
190         errors += fail_if( state != 99, "xlate_nng_state did not return  default for nng_inval" );
191         errors += fail_if( errno == 0, "xlate_nng_state did not set errno (2)" );
192
193         state = xlate_nng_state( NNG_ENOMEM, 99 );
194         errors += fail_if( state != 99, "xlate_nng_state did not return  default for nng_nomem" );
195         errors += fail_if( errno == 0, "xlate_nng_state did not set errno (3)" );
196
197         state = xlate_nng_state( NNG_ESTATE, 99 );
198         errors += fail_if( state != 99, "xlate_nng_state did not return  default for nng_state" );
199         errors += fail_if( errno == 0, "xlate_nng_state did not set errno (4)" );
200
201         state = xlate_nng_state( NNG_ECLOSED, 99 );
202         errors += fail_if( state != 99, "xlate_nng_state did not return  default for nng_closed" );
203         errors += fail_if( errno == 0, "xlate_nng_state did not set errno (5)" );
204
205         state = xlate_nng_state( 999, 99 );
206         errors += fail_if( state != 99, "xlate_nng_state did not return  default for unknown error" );
207         errors += fail_if( errno == 0, "xlate_nng_state did not set errno (6)" );
208
209         // ---- drive rtc in a 'static' (not pthreaded) mode to get some coverage; no 'results' to be verified -----
210         setenv( ENV_RTG_RAW, "1", 1 );                                                          // rtc should expect raw messages (mostly coverage here)
211         setenv( ENV_VERBOSE_FILE, ".ut_rmr_verbose", 1 );                       // allow for verbose code in rtc to be driven
212         i = open( ".ut_rmr_verbose", O_RDWR | O_CREAT, 0654 );
213         if( i >= 0 ) {
214                 write( i, "2\n", 2 );
215                 close( i );
216         }
217         ctx->shutdown = 1;                      // should force rtc to quit on first pass
218         rtc( NULL );                            // coverage test with nil pointer
219         rtc( ctx );
220
221
222         return !!errors;
223 }