1 // vim: ts=4 sw=4 noet:
3 --------------------------------------------------------------------------------
4 Copyright (c) 2018-2019 AT&T Intellectual Property.
6 Licensed under the Apache License, Version 2.0 (the "License");
7 you may not use this file except in compliance with the License.
8 You may obtain a copy of the License at
10 http://www.apache.org/licenses/LICENSE-2.0
12 Unless required by applicable law or agreed to in writing, software
13 distributed under the License is distributed on an "AS IS" BASIS,
14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 See the License for the specific language governing permissions and
16 limitations under the License.
17 --------------------------------------------------------------------------------
22 Abstract: Basic unit tests for the mc listener.
24 Author: E. Scott Daniels
27 #define FOREVER 0 // allows forever loops in mcl code to escape after one loop
38 #include <sys/types.h>
40 #include "test_rmr_em.c" // emulated rmr functions (for receives)
42 // this/these are what we are testing; include them directly (must be after forever def)
47 Set up env things for the rdc setup call.
49 static void set_env() {
50 setenv( "MCL_RDC_ENABLE", "1", 1 ); // cause 'raw' capture to be setup
51 setenv( "MCL_RDC_STAGE", "/tmp/mc_listener_test/stage", 1 ); // unit test script should create and will purge after
52 setenv( "MCL_RDC_FINAL", "/tmp/mc_listener_test/final", 1 );
53 setenv( "MCL_RDC_SUFFIX", ".xxx", 1 );
54 setenv( "MCL_RDC_DONE", ".done", 1 );
55 setenv( "MCL_RDC_FREQ", "10", 1 );
59 Parms: [fifo-dir-name]
61 int main( int argc, char** argv ) {
63 void* bad_ctx; // context with a bad directory path for coverage/error testing
65 char* dname = "/tmp/fifos";
69 int rfd; // a reader file des so we can read what we write
70 fifo_t* fref = NULL; // fifo type reference; we just verify that suss sets it
76 char timestamp[1024]; // read will put a timestamp here
82 set_env(); // set env that setup_rdc() looks for
84 ctx = mcl_mk_context( dname ); // allocate the context
86 fprintf( stderr, "[FAIL] couldn't make context\n" );
90 mcl_set_sigh(); // prevent colobber from broken pipe
92 open_fifo( ctx, 100, WRITER ); // open dummy to prevent blocking reader
93 rfd = open_fifo( ctx, 100, READER ); // open a reader to check fanout output
95 fprintf( stderr, "[FAIL] unable to open a pipe reader for type == 100\n" );
99 fd = suss_fifo( ctx, 100, 1, &fref ); // should open the file for writing and return the fdes
101 fprintf( stderr, "[FAIL] suss_fifo did not return a valid fd\n" );
106 fprintf( stderr, "[FAIL] suss_fifo did not set the fifo reference pointer\n" );
113 fd2= suss_fifo( ctx, 100, 0, NULL ); // should open the file file for reading and return a different fd
115 fprintf( stderr, "[FAIL] suss_fifo did not return a valid fd\n" );
119 fprintf( stderr, "[FAIL] reading and writing fifo file descriptors expected to differ; both were %d\n", fd );
123 mcl_start_listening( ctx, port, 0 ); // start the listener
125 // under test, the forever keeps fanout from blocking; drive for each of two cases:
126 mcl_fifo_fanout( ctx, 5, 1 ); // first rmr receive call will simulate a timeout
127 mcl_fifo_fanout( ctx, 5, 1 ); // second receive call simualtes a message arriving
128 mcl_fifo_fanout( ctx, 5, 1 ); // another round so there are two to read
129 mcl_fifo_fanout( ctx, 5, 1 );
132 state = mcl_fifo_read1( ctx, 100, payload, sizeof( payload ), TRUE );
134 fprintf( stderr, "[FAIL] fifo_read return positive value when expected to\n" );
137 state = mcl_fifo_tsread1( ctx, 100, payload, sizeof( payload ), TRUE, timestamp );
139 fprintf( stderr, "[FAIL] fifo_read with timestamp return positive value when expected to\n" );
143 state = fifo_read1( NULL, 100, payload, sizeof( payload ), 1, timestamp ); // coverage error check
145 fprintf( stderr, "[FAIL] fifo_read didn't return 0 when given a nil context to\n" );
149 mcl_fifo_fanout( ctx, 5, 0 ); // test with writing short header
150 mcl_fifo_fanout( ctx, 5, 0 );
152 // ------ some error/coverage testing ---------------------------
153 logit( LOG_CRIT, "critical message" );
154 logit( LOG_ERR, "error message" );
155 logit( LOG_WARN, "warning message" );
156 logit( LOG_STAT, "stats message" );
158 bad_ctx = mcl_mk_context( "/nosuchdirectoryinthesystem" ); // create a context where fifo opens should fail
159 if( bad_ctx == NULL ) {
160 fprintf( stderr, "[FAIL] couldn't make 'bad' context" );
165 fd = suss_fifo( bad_ctx, 100, 1, &fref ); // should fail to open the file for writing beacuse directory is bad
167 fprintf( stderr, "[FAIL] suss_fifo returned a valid fd when given a context with a bad directory path\n" );
171 fprintf( stderr, "[FAIL] suss_fifo returned an fref pointer when given a bad context\n" );
175 fd = suss_fifo( NULL, 100, 1, &fref ); // coverage nil pointer check
177 fprintf( stderr, "[FAIL] suss_fifo returned a valid fd when given a nil context a bad directory path\n" );
181 fd = suss_fifo( ctx, -1, 1, &fref ); // mad message type check
183 fprintf( stderr, "[FAIL] suss_fifo returned a valid fd when given a bad message type\n" );
187 // -- buffer testing ------------------------------------------------------
188 bp = build_hdr( 1024, wbuf, 0 );
189 bp = build_hdr( 1024, NULL, 0 );
191 fprintf( stderr, "[FAIL] build_hdr didn't return a buffer pointer when given a nil buffer\n" );
196 bp = build_hdr( 1024, wbuf, sizeof( wbuf ) );
198 fprintf( stderr, "[FAIL] build_hdr didn't return a buffer pointer\n" );
203 // ----- msg receive testing ----------------------------------------------------
204 buf = mcl_get_msg( NULL, NULL, 1 ); // drive nil pointer checks
207 fprintf( stderr, "[FAIL], get_msg call with nil context returned a buffer pointer\n" );
210 buf = mcl_get_msg( ctx, NULL, 1 ); // drive to force coverage; nothing is sent, so we can't validate buffer
213 mcl_fifo_one( NULL, NULL, 1, 1 );
214 mcl_fifo_one( ctx, NULL, 1, 1 );
215 mcl_fifo_one( ctx, wbuf, 0, 1 );
216 mcl_fifo_one( ctx, wbuf, 10, 100 );
219 // --- some rdc testing as best as we can without message generators --------
220 rdc_init( NULL, NULL, ".foo", ".bar" ); // coverage testing
222 ctx = setup_rdc(); // coverage test to ensure that it generates a context
224 fprintf( stderr, "[FAIL] setup_rdc did not return a context pointer\n" );
228 rdc_set_freq( NULL, 0 ); // error/nil test
229 rdc_set_freq( ctx, 0 ); // error/nil test
230 rdc_set_freq( ctx, 10 ); // roll after 10seconds to test that
232 build_hdr( 1024, wbuf, sizeof( wbuf ) );
234 bp = rdc_init_buf( 100, wbuf, 10, bp ); // set up for write
235 rdc_write( ctx, bp, payload, sizeof( payload ) ); // write the raw data
237 fprintf( stderr, "[INFO] pausing to test rdc file rolling\n" );
239 build_hdr( 1024, wbuf, sizeof( wbuf ) );
241 bp = rdc_init_buf( 100, wbuf, 10, bp );
242 rdc_write( ctx, bp, payload, sizeof( payload ) );
245 // CAUTION: filenames need to match those expected in the run script as it creates src, and will validate, destination files
246 state = copy_unlink( "/tmp/mc_listener_test/no-such-copy_src", "/tmp/mc_listener_test/copy_dest", 0664 ); // first couple drive for error and coverage
248 fprintf( stderr, "[FAIL] copy-unlink of bad file didn't return bad state\n" );
251 state = copy_unlink( "/tmp/mc_listener_test/copy_src", "/tmp/mc_listener_test-nodir/copy_dest", 0664 );
253 fprintf( stderr, "[FAIL] copy-unlink of bad target didn't return bad state\n" );
256 state = copy_unlink( "/tmp/mc_listener_test/copy_src", "/tmp/mc_listener_test/copy_dest", 0664 ); // drive for coverage; setup script can check contents
258 fprintf( stderr, "[FAIL] copy-unlink expected success but failed\n" );
261 state = mvocp( "/tmp/mc_listener_test/bad-src-mv_src", "/tmp/mc_listener_test/mv_dest" );
263 fprintf( stderr, "[FAIL] mv or copy expected failure didn't set bad state\n" );
266 state = mvocp( "/tmp/mc_listener_test/mv_src", "/tmp/mc_listener_test/mv_dest" );
268 fprintf( stderr, "[FAIL] mv or copy expected to succeed didn't set good state\n" );
273 // ---- finally, check error count, write nice cheerful message and exit ----
275 fprintf( stderr, "[PASS] unit_test: everything looks peachy\n" );
277 fprintf( stderr, "[FAIL] unit_test: there were %d errors\n", errors );