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 #define TEST_MTYPE 1000 // message type for testing
41 #include "test_rmr_em.c" // emulated rmr functions (for receives)
43 // this/these are what we are testing; include them directly (must be after forever def)
48 Set up env things for the rdc setup call.
50 static void set_env() {
51 setenv( "MCL_RDC_ENABLE", "1", 1 ); // cause 'raw' capture to be setup
52 setenv( "MCL_RDC_STAGE", "/tmp/mc_listener_test/stage", 1 ); // unit test script should create and will purge after
53 setenv( "MCL_RDC_FINAL", "/tmp/mc_listener_test/final", 1 );
54 setenv( "MCL_RDC_SUFFIX", ".xxx", 1 );
55 setenv( "MCL_RDC_DONE", ".done", 1 );
56 setenv( "MCL_RDC_FREQ", "10", 1 );
60 Parms: [fifo-dir-name]
62 int main( int argc, char** argv ) {
64 void* bad_ctx; // context with a bad directory path for coverage/error testing
66 char* dname = "/tmp/fifos";
70 int rfd; // a reader file des so we can read what we write
71 fifo_t* fref = NULL; // fifo type reference; we just verify that suss sets it
77 char timestamp[1024]; // read will put a timestamp here
83 setenv( "MCL_RDC_ENABLE", "0", 1 ); /// test disabled mode for coverage
86 set_env(); // set env that setup_rdc() looks for
88 ctx = mcl_mk_context( dname ); // allocate the context
90 fprintf( stderr, "[FAIL] couldn't make context\n" );
94 mcl_set_sigh(); // prevent colobber from broken pipe
96 open_fifo( ctx, TEST_MTYPE, WRITER ); // open dummy to prevent blocking reader
97 rfd = open_fifo( ctx, TEST_MTYPE, READER ); // open a reader to check fanout output
99 fprintf( stderr, "[FAIL] unable to open a pipe reader for type == 100\n" );
103 fd = suss_fifo( ctx, TEST_MTYPE, WRITER, &fref ); // should open the file for writing and return the fdes
105 fprintf( stderr, "[FAIL] suss_fifo did not return a valid fd\n" );
110 fprintf( stderr, "[FAIL] suss_fifo did not set the fifo reference pointer\n" );
117 fd2= suss_fifo( ctx, TEST_MTYPE, 0, NULL ); // should open the file file for reading and return a different fd
119 fprintf( stderr, "[FAIL] suss_fifo did not return a valid fd\n" );
123 fprintf( stderr, "[FAIL] reading and writing fifo file descriptors expected to differ; both were %d\n", fd );
127 mcl_start_listening( ctx, port, 0 ); // start the listener
129 // under test, the FOREVER = 0 keeps fanout from blocking; drive several times to cover all cases
130 mcl_fifo_fanout( ctx, 5, 1 ); // first rmr receive call will simulate a timeout
131 mcl_fifo_fanout( ctx, 5, 1 ); // second receive simulates a health check
132 mcl_fifo_fanout( ctx, 5, 1 ); // 3-n return alternating timeout messages; drive so that
133 mcl_fifo_fanout( ctx, 5, 1 ); // we will have several land in the FIFO
134 mcl_fifo_fanout( ctx, 5, 1 );
135 mcl_fifo_fanout( ctx, 5, 1 );
136 mcl_fifo_fanout( ctx, 5, 1 );
139 state = mcl_fifo_read1( ctx, TEST_MTYPE, payload, sizeof( payload ), TRUE );
141 fprintf( stderr, "[FAIL] fifo_read return positive value when expected to\n" );
144 state = mcl_fifo_tsread1( ctx, TEST_MTYPE, payload, sizeof( payload ), TRUE, timestamp );
146 fprintf( stderr, "[FAIL] fifo_read with timestamp return positive value when expected to\n" );
150 state = fifo_read1( NULL, TEST_MTYPE, payload, sizeof( payload ), 1, timestamp ); // coverage error check
152 fprintf( stderr, "[FAIL] fifo_read didn't return 0 when given a nil context to\n" );
156 mcl_fifo_fanout( ctx, 5, 0 ); // test with writing short header
157 mcl_fifo_fanout( ctx, 5, 0 );
159 // ------ some error/coverage testing ---------------------------
160 logit( LOG_CRIT, "critical message" );
161 logit( LOG_ERR, "error message" );
162 logit( LOG_WARN, "warning message" );
163 logit( LOG_STAT, "stats message" );
165 fprintf( stderr, "[INFO] expected create fail message should follow\n" );
166 bad_ctx = mcl_mk_context( "/nosuchdirectoryinthesystem" ); // create a context where fifo opens should fail
167 if( bad_ctx == NULL ) {
168 fprintf( stderr, "[FAIL] couldn't make 'bad' context" );
173 fd = suss_fifo( bad_ctx, TEST_MTYPE, 1, &fref ); // should fail to open the file for writing beacuse directory is bad
175 fprintf( stderr, "[FAIL] suss_fifo returned a valid fd when given a context with a bad directory path\n" );
179 fprintf( stderr, "[FAIL] suss_fifo returned an fref pointer when given a bad context\n" );
183 fd = suss_fifo( NULL, TEST_MTYPE, 1, &fref ); // coverage nil pointer check
185 fprintf( stderr, "[FAIL] suss_fifo returned a valid fd when given a nil context a bad directory path\n" );
189 fd = suss_fifo( ctx, -1, 1, &fref ); // mad message type check
191 fprintf( stderr, "[FAIL] suss_fifo returned a valid fd when given a bad message type\n" );
195 // -- buffer testing ------------------------------------------------------
196 bp = build_hdr( 1024, wbuf, 0 );
197 bp = build_hdr( 1024, NULL, 0 );
199 fprintf( stderr, "[FAIL] build_hdr didn't return a buffer pointer when given a nil buffer\n" );
204 bp = build_hdr( 1024, wbuf, sizeof( wbuf ) );
206 fprintf( stderr, "[FAIL] build_hdr didn't return a buffer pointer\n" );
211 // ----- msg receive testing ----------------------------------------------------
212 buf = mcl_get_msg( NULL, NULL, 1 ); // drive nil pointer checks
215 fprintf( stderr, "[FAIL], get_msg call with nil context returned a buffer pointer\n" );
218 buf = mcl_get_msg( ctx, NULL, 1 ); // drive to force coverage; nothing is sent, so we can't validate buffer
221 mcl_fifo_one( NULL, NULL, 1, 1 );
222 mcl_fifo_one( ctx, NULL, 1, 1 );
223 mcl_fifo_one( ctx, wbuf, 0, 1 );
224 mcl_fifo_one( ctx, wbuf, 10, 100 );
227 // --- some rdc testing as best as we can without message generators --------
228 rdc_init( NULL, NULL, ".foo", ".bar" ); // coverage testing
230 ctx = setup_rdc(); // coverage test to ensure that it generates a context
232 fprintf( stderr, "[FAIL] setup_rdc did not return a context pointer\n" );
236 rdc_set_freq( NULL, 0 ); // error/nil test
237 rdc_set_freq( ctx, 0 ); // error/nil test
238 rdc_set_freq( ctx, 10 ); // roll after 10seconds to test that
240 build_hdr( 1024, wbuf, sizeof( wbuf ) );
242 bp = rdc_init_buf( TEST_MTYPE, wbuf, 10, bp ); // set up for write
243 rdc_write( ctx, bp, payload, sizeof( payload ) ); // write the raw data
245 fprintf( stderr, "[INFO] pausing to test rdc file rolling\n" );
247 build_hdr( 1024, wbuf, sizeof( wbuf ) );
249 bp = rdc_init_buf( TEST_MTYPE, wbuf, 10, bp );
250 rdc_write( ctx, bp, payload, sizeof( payload ) );
253 // CAUTION: filenames need to match those expected in the run script as it creates src, and will validate, destination files
254 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
256 fprintf( stderr, "[FAIL] copy-unlink of bad file didn't return bad state\n" );
259 state = copy_unlink( "/tmp/mc_listener_test/copy_src", "/tmp/mc_listener_test-nodir/copy_dest", 0664 );
261 fprintf( stderr, "[FAIL] copy-unlink of bad target didn't return bad state\n" );
264 state = copy_unlink( "/tmp/mc_listener_test/copy_src", "/tmp/mc_listener_test/copy_dest", 0664 ); // drive for coverage; setup script can check contents
266 fprintf( stderr, "[FAIL] copy-unlink expected success but failed\n" );
269 state = mvocp( "/tmp/mc_listener_test/bad-src-mv_src", "/tmp/mc_listener_test/mv_dest" );
271 fprintf( stderr, "[FAIL] mv or copy expected failure didn't set bad state\n" );
274 state = mvocp( "/tmp/mc_listener_test/mv_src", "/tmp/mc_listener_test/mv_dest" );
276 fprintf( stderr, "[FAIL] mv or copy expected to succeed didn't set good state\n" );
281 // ---- finally, check error count, write nice cheerful message and exit ----
283 fprintf( stderr, "[PASS] unit_test: everything looks peachy\n" );
285 fprintf( stderr, "[FAIL] unit_test: there were %d errors\n", errors );