# API and build change and fix summaries. Doc correctsions
# and/or changes are not mentioned here; see the commit messages.
+2020 April 14; version 3.7.3
+ Fix bug in rmr_call() when using SI95 (RIC-333)
+
2020 April 10; version 3.7.2
Fix bug related to static route table only mode (RIC-331)
set( major_version "3" ) # should be automatically populated from git tag later, but until CI process sets a tag we use this
set( minor_version "7" )
-set( patch_level "2" )
+set( patch_level "3" )
set( install_root "${CMAKE_INSTALL_PREFIX}" )
set( install_inc "include/rmr" )
return msg;
}
- return rmr_mt_call( vctx, msg, 1, 1000 ); // use the reserved call-id of 1 and wait up to 1 sec
+ return mt_call( vctx, msg, 1, 1000, NULL ); // use the reserved call-id of 1 and wait up to 1 sec
}
/*
if( mbuf != NULL ) {
mbuf->flags |= MFL_ADDSRC; // turn on so if user app tries to send this buffer we reset src
}
+
return mbuf;
}
return mbuf;
}
- if( call_id > MAX_CALL_ID || call_id < 2 ) { // 0 and 1 are reserved; user app cannot supply them
- mbuf->state = RMR_ERR_BADARG;
- mbuf->tp_state = errno;
- return mbuf;
- }
-
ombuf = mbuf; // save to return timeout status with
chute = &ctx->chutes[call_id];
This is now just an outward facing wrapper so we can support wormhole calls.
*/
extern rmr_mbuf_t* rmr_mt_call( void* vctx, rmr_mbuf_t* mbuf, int call_id, int max_wait ) {
+
+ // must vet call_id here, all others vetted by workhorse mt_call() function
+ if( call_id > MAX_CALL_ID || call_id < 2 ) { // 0 and 1 are reserved; user app cannot supply them
+ mbuf->state = RMR_ERR_BADARG;
+ mbuf->tp_state = EINVAL;
+ return mbuf;
+ }
+
return mt_call( vctx, mbuf, call_id, max_wait, NULL );
}
} else {
ok_sends++;
msg = clone_m; // clone will be the next to send
+ msg->state = RMR_OK;
}
} else {
msg = send_msg( ctx, msg, nn_sock, max_to ); // send the last, and allocate a new buffer; drops the clone if it was
snprintf( msg->payload, msg->len, "Rambling Wreck from Georgia Tech!\n\n" );
msg = rmr_send_msg( rmc, msg );
if( msg && msg->state != RMR_OK ) {
- printf( stderr, "[ERR] lg buf test: send failed? %d\n", msg->state );
+ fprintf( stderr, "<FAIL> lg buf test: send failed? %d\n", msg->state );
}
rmr_free_msg( msg );
rmr_mtosend_msg
rmr_free_msg
+ Not all message/call functions can be tested here because of the
+ callback nature of SI. There is a specific rcv test static module
+ for those tests.
+
Author: E. Scott Daniels
Date: 5 April 2019
*/
#include "rmr.h"
#include "rmr_agnostic.h"
-/*
- Send a 'burst' of messages to drive some send retry failures to increase RMr coverage
- by handling the retry caee.
-*/
-static void send_n_msgs( void* ctx, int n ) {
- rmr_mbuf_t* msg; // message buffers
- int i;
-
- msg = rmr_alloc_msg( ctx, 1024 );
- if( ! msg ) {
- return;
- }
-
- for( i = 0; i < n; i++ ) {
- //fprintf( stderr, "mass send\n" );
- msg->len = 100;
- msg->mtype = 1;
- msg->state = 999;
- errno = 999;
- msg = rmr_send_msg( ctx, msg );
- }
-}
-
-/*
- Refresh or allocate a message with some default values
-*/
-static rmr_mbuf_t* fresh_msg( void* ctx, rmr_mbuf_t* msg ) {
- if( ! msg ) {
- msg = rmr_alloc_msg( ctx, 2048 );
- }
-
- msg->mtype = 0;
- msg->sub_id = -1;
- msg->state = 0;
- msg->len = 100;
-
- return msg;
-}
-
static int rmr_api_test( ) {
int errors = 0;
void* rmc; // route manager context
mt_disc_cb( rmc, 0 ); // disconnect callback for coverage
mt_disc_cb( rmc, 100 ); // with a fd that doesn't exist
-return errors;
-
- msg2 = rmr_rcv_msg( NULL, NULL );
- errors += fail_if( msg2 != NULL, "rmr_rcv_msg returned msg when given nil context and msg " );
-
- msg2 = rmr_rcv_msg( rmc, NULL );
- errors += fail_if( msg2 == NULL, "rmr_rcv_msg returned nil msg when given nil msg " );
- if( msg2 ) {
- if( msg2->state != RMR_ERR_EMPTY ) {
- errors += fail_not_equal( msg2->state, RMR_OK, "receive given nil message did not return msg with good state (not empty) " );
- }
- }
-
-
- msg = rmr_rcv_msg( rmc, msg );
- if( msg ) {
- errors += fail_not_equal( msg->state, RMR_OK, "rmr_rcv_msg did not return an ok state " );
- errors += fail_not_equal( msg->len, 220, "rmr_rcv_msg returned message with invalid len " );
- } else {
- errors += fail_if_nil( msg, "rmr_rcv_msg returned a nil pointer " );
- }
-
- rmr_rts_msg( NULL, NULL ); // drive for coverage
- rmr_rts_msg( rmc, NULL );
- errors += fail_if( errno == 0, "rmr_rts_msg did not set errno when given a nil message " );
-
- msg->state = 0;
- msg = rmr_rts_msg( NULL, msg ); // should set state in msg
- if( msg ) {
- errors += fail_if_equal( msg->state, 0, "rmr_rts_msg did not set state when given valid message but no context " );
- } else {
- errors += fail_if_nil( msg, "rmr_rts_msg returned a nil msg when given a good one" );
- }
-
-
- msg = rmr_rts_msg( rmc, msg ); // return the buffer to the sender
- errors += fail_if_nil( msg, "rmr_rts_msg did not return a message pointer " );
- errors += fail_not_equal( msg->state, 0, "rts_msg did not return a good state (a) when expected" );
- errors += fail_not_equal( errno, 0, "rmr_rts_msg did not reset errno (a) expected (b)" );
-
- msg->state = 0;
- msg = rmr_call( NULL, msg );
- errors += fail_if( msg->state == 0, "rmr_call did not set message state when given message with nil context " );
-
- snprintf( msg->xaction, 17, "%015d", 16 ); // dummy transaction id (emulation generates, this should arrive after a few calls to recv)
- msg->mtype = 0;
- msg->sub_id = -1;
- em_set_rcvcount( 0 ); // reset message counter
- em_set_rcvdelay( 1 ); // force slow msg rate during mt testing
- msg = rmr_call( rmc, msg ); // dummy nng/nano function will sequentually add xactions and should match or '16'
- errors += fail_if_nil( msg, "rmr_call returned a nil message on call expected to succeed " );
- if( msg ) {
- errors += fail_not_equal( msg->state, RMR_OK, "rmr_call did not properly set state on successful return " );
- errors += fail_not_equal( errno, 0, "rmr_call did not properly set errno (a) on successful return " );
- }
-
- snprintf( wbuf, 17, "%015d", 14 ); // while waiting, the queued messages should have #14, so issue a few receives looking for it
- for( i = 0; i < 16; i++ ) { // it should be in the first 15
- msg = rmr_rcv_msg( rmc, msg );
- if( msg ) {
- if( strcmp( wbuf, msg->xaction ) == 0 ) { // found the queued message
- break;
- }
- fprintf( stderr, "<INFO> msg: %s\n", msg->xaction );
- } else {
- errors += fail_if_nil( msg, "receive returnd nil msg while looking for queued message " );
- }
- }
-
- errors += fail_if( i >= 16, "did not find expected message on queue " );
-
- if( ! msg ) {
- msg = rmr_alloc_msg( rmc, 2048 ); // something buggered above; get a new one
- }
- msg->mtype = 0;
- msg->sub_id = -1;
- msg = rmr_call( rmc, msg ); // make a call that we never expect a response on (nil pointer back)
- errors += fail_not_nil( msg, "rmr_call returned a nil message on call expected not to receive a response " );
- errors += fail_if( errno == 0, "rmr_call did not set errno on failure " );
-
- rmr_free_msg( NULL ); // drive for coverage; nothing to check
- rmr_free_msg( msg2 );
-
-
- msg2 = rmr_torcv_msg( NULL, NULL, 10 );
- errors += fail_not_nil( msg2, "rmr_torcv_msg returned a pointer when given nil information " );
- msg2 = rmr_torcv_msg( rmc, NULL, 10 );
- errors += fail_if_nil( msg2, "rmr_torcv_msg did not return a message pointer when given a nil old msg " );
-
- // --- test timeout receive; our dummy epoll function will return 1 ready on first call and 0 ready (timeout emulation) on second
- // however we must drain the swamp (queue) first, so run until we get a timeout error, or 20 and report error if we get to 20.
- msg = NULL;
- for( i = 0; i < 40; i++ ) {
- msg = rmr_torcv_msg( rmc, msg, 10 );
- errors += fail_if_nil( msg, "torcv_msg returned nil msg when message expected " );
- if( msg ) {
- if( msg->state == RMR_ERR_TIMEOUT || msg->state == RMR_ERR_EMPTY ) { // queue drained and we've seen both states from poll if we get a timeout
- break;
- }
- }
- }
- errors += fail_if( i >= 40, "torcv_msg never returned a timeout " );
-
// ---- trace things that are not a part of the mbuf_api functions and thus must be tested here -------
state = rmr_init_trace( NULL, 37 ); // coverage test nil context
--- /dev/null
+// : vi ts=4 sw=4 noet :
+/*
+==================================================================================
+ Copyright (c) 2019-2020 Nokia
+ Copyright (c) 2018-2020 AT&T Intellectual Property.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================================
+*/
+
+/*
+ Mmemonic: rmr_si_api_static_test.c
+ Abstract: Specific tests related to the API functions in rmr_si.c.
+ This should be included by a driver which invokes the 'main'
+ test function here: rmr_api_test.
+
+ This test set applies only to the outward facting API functions
+ in the rmr_si.c module (mostly because the context for SI is
+ different).
+
+ The message buffer specific API tests are in a different static
+ module. API functions tested here are:
+ rmr_close
+ rmr_get_rcvfd
+ rmr_ready
+ rmr_init
+ rmr_set_rtimeout
+ rmr_set_stimeout
+ rmr_rcv_specific
+ rmr_torcv_msg
+ rmr_rcv_msg
+ rmr_call
+ rmr_rts_msg
+ rmr_send_msg
+ rmr_mtosend_msg
+ rmr_free_msg
+
+ Author: E. Scott Daniels
+ Date: 14 April 2020 (AKD)
+*/
+
+#define DEBUG 2
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+#include <errno.h>
+#include <string.h>
+#include <stdint.h>
+#include <pthread.h>
+#include <semaphore.h>
+
+#include "rmr.h"
+#include "rmr_agnostic.h"
+
+static int rmr_rcv_test( ) {
+ int errors = 0;
+ void* rmc; // route manager context
+ void* rmc2; // second context for non-listener init
+ rmr_mbuf_t* msg; // message buffers
+ rmr_mbuf_t* msg2;
+ int v = 0; // some value
+ char wbuf[128];
+ int i;
+ int state;
+ int max_tries; // prevent a sticking in any loop
+
+ v = rmr_ready( NULL );
+ errors += fail_if( v != 0, "rmr_ready returned true before initialisation " );
+
+ em_set_long_hostname( 1 );
+ if( (rmc = rmr_init( "4560", 1024, FL_NOTHREAD )) == NULL ) {
+ fail_if_nil( rmc, "rmr_init returned a nil pointer " );
+ return 1;
+ }
+
+ msg = rmr_alloc_msg( NULL, 1024 ); // should return nil pointer
+ errors += fail_not_nil( msg, "rmr_alloc_msg didn't return nil when given nil context " );
+ gen_rt( rmc ); // gen dummy route table
+
+ if( ! rmr_ready( rmc ) ) {
+ fprintf( stderr, "\nPANIC! rmr isn't showing ready after loading a rt table\n\n" );
+ return errors+1;
+ }
+
+ msg = rmr_alloc_msg( rmc, 2048 ); // get a buffer with a transport header
+ msg->len = 500;
+ msg->mtype = 1;
+ msg->state = 999;
+ msg->tp_state = 999;
+ errno = 999;
+ snprintf( msg->payload, 500, "Stand up and cheer from OU to Oh yea! (5)" );
+
+ msg = rmr_send_msg( rmc, msg );
+ errors += fail_if_nil( msg, "send_msg_ did not return a message on send " );
+ if( msg ) {
+ errors += fail_not_equal( msg->state, RMR_OK, "send_msg returned bad status for send that should work " );
+ errors += fail_if( errno != 0, "send_msg set errno for send that should work " );
+ v = rmr_payload_size( msg );
+ errors += fail_if( v != 2048, "send_msg did not allocate new buffer with correct size " );
+ errors += fail_if( msg->tp_state == 999, "send_msg did not set tp_state (2)" );
+ }
+
+ rmr_set_stimeout( NULL, 0 ); // not supported, but funciton exists, so drive away
+ rmr_set_stimeout( rmc, 20 );
+ rmr_set_stimeout( rmc, -1 );
+ rmr_set_rtimeout( NULL, 0 );
+ rmr_set_rtimeout( rmc, 20 );
+ rmr_set_rtimeout( rmc, -1 );
+
+ max_tries = 10; // there shouldn't be more than 10 queued at this point
+ while( (msg2 = rmr_torcv_msg( rmc, msg2, 200 )) != NULL ) {
+ if( msg2->state != RMR_OK || max_tries <= 0 ) {
+ break;
+ }
+
+ max_tries--;
+ }
+
+ msg2 = rmr_rcv_msg( NULL, NULL );
+ errors += fail_if( msg2 != NULL, "rmr_rcv_msg returned msg when given nil context and msg " );
+
+ send_n_msgs( rmc, 1 ); // ensure there is a message to read
+ msg2 = rmr_rcv_msg( rmc, NULL );
+ errors += fail_if( msg2 == NULL, "rmr_rcv_msg returned nil msg when given nil msg " );
+ if( msg2 ) {
+ if( msg2->state != RMR_ERR_EMPTY ) {
+ errors += fail_not_equal( msg2->state, RMR_OK, "receive given nil message did not return msg with good state (not empty) " );
+ }
+ }
+
+ send_n_msgs( rmc, 1 ); // ensure there is a message to read (len is set to 100)
+ msg = rmr_rcv_msg( rmc, msg );
+ if( msg ) {
+ errors += fail_not_equal( msg->state, RMR_OK, "rmr_rcv_msg did not return an ok state " );
+ errors += fail_not_equal( msg->len, 100, "rmr_rcv_msg returned message with invalid len " );
+ } else {
+ errors += fail_if_nil( msg, "rmr_rcv_msg returned a nil pointer " );
+ }
+
+ rmr_rts_msg( NULL, NULL ); // drive for coverage
+ rmr_rts_msg( rmc, NULL );
+ errors += fail_if( errno == 0, "rmr_rts_msg did not set errno when given a nil message " );
+
+ msg->state = 0;
+ msg = rmr_rts_msg( NULL, msg ); // should set state in msg
+ if( msg ) {
+ errors += fail_if_equal( msg->state, 0, "rmr_rts_msg did not set state when given valid message but no context " );
+ } else {
+ errors += fail_if_nil( msg, "rmr_rts_msg returned a nil msg when given a good one" );
+ }
+
+ msg = rmr_rts_msg( rmc, msg ); // return the buffer to the sender
+ errors += fail_if_nil( msg, "rmr_rts_msg did not return a message pointer " );
+ errors += fail_not_equal( msg->state, 0, "rts_msg did not return a good state (a) when expected" );
+ errors += fail_not_equal( errno, 0, "rmr_rts_msg did not reset errno (a) expected (b)" );
+
+ msg->state = 0;
+ msg = rmr_call( NULL, msg );
+ errors += fail_if( msg->state == 0, "rmr_call did not set message state when given message with nil context " );
+
+ em_set_rcvcount( 0 ); // reset message counter
+ em_set_rcvdelay( 1 ); // force slow msg rate during mt testing
+ em_disable_call_flg(); // cause reflected message to appear to be a response
+
+ snprintf( msg->xaction, 17, "%015d", 16 );
+ msg->mtype = 0;
+ msg->sub_id = -1;
+ msg->len = 234;
+ msg = rmr_call( rmc, msg );
+ errors += fail_if_nil( msg, "rmr_call returned a nil message on call expected to succeed " );
+ if( msg ) {
+ errors += fail_not_equal( msg->state, RMR_OK, "rmr_call did not properly set state on successful return " );
+ errors += fail_not_equal( errno, 0, "rmr_call did not properly set errno (a) on successful return " );
+ }
+
+ if( ! msg ) {
+ msg = rmr_alloc_msg( rmc, 2048 ); // something buggered above; get a new one
+ }
+
+ em_allow_call_flg(); // cause reflected message to appear to be a call
+ snprintf( msg->xaction, 17, "%015d", 16 ); // ensure there is an xaction id
+ msg->mtype = 0;
+ msg->sub_id = -1;
+ msg->len = 345;
+ msg = rmr_call( rmc, msg ); // make a call that we never expect a response on (nil pointer back)
+ errors += fail_not_nil( msg, "rmr_call returned message on call expected not to receive a response " );
+ errors += fail_if( errno == 0, "rmr_call did not set errno on failure " );
+
+ rmr_free_msg( NULL ); // drive for coverage; nothing to check
+ rmr_free_msg( msg2 );
+
+ msg2 = rmr_torcv_msg( NULL, NULL, 10 );
+ errors += fail_not_nil( msg2, "rmr_torcv_msg returned a pointer when given nil information " );
+ msg2 = rmr_torcv_msg( rmc, NULL, 10 );
+ errors += fail_if_nil( msg2, "rmr_torcv_msg did not return a message pointer when given a nil old msg " );
+
+ // --- test timeout receive; our dummy epoll function will return 1 ready on first call and 0 ready (timeout emulation) on second
+ // however we must drain the swamp (queue) first, so run until we get a timeout error, or 20 and report error if we get to 20.
+ msg = NULL;
+ for( i = 0; i < 40; i++ ) {
+ msg = rmr_torcv_msg( rmc, msg, 10 );
+ errors += fail_if_nil( msg, "torcv_msg returned nil msg when message expected " );
+ if( msg ) {
+ if( msg->state == RMR_ERR_TIMEOUT || msg->state == RMR_ERR_EMPTY ) { // queue drained and we've seen both states from poll if we get a timeout
+ break;
+ }
+ }
+ }
+ errors += fail_if( i >= 40, "torcv_msg never returned a timeout " );
+
+ ((uta_ctx_t *)rmc)->shutdown = 1;
+ rmr_close( NULL ); // drive for coverage
+ rmr_close( rmc ); // no return to check; drive for coverage
+
+
+ // --------------- phew, done ------------------------------------------------------------------------------
+
+ if( ! errors ) {
+ fprintf( stderr, "<INFO> all RMR receive tests pass\n" );
+ } else {
+ fprintf( stderr, "<INFO> receive tests failures noticed \n" );
+ }
+
+ return !!errors;
+}
--- /dev/null
+// :vi sw=4 ts=4 noet:
+/*
+==================================================================================
+ Copyright (c) 2020 Nokia
+ Copyright (c) 2020 AT&T Intellectual Property.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================================
+*/
+
+/*
+ Mmemonic: rmr_si_rcv_test.c
+ Abstract: This drives only the receive tests for the SI API. Because
+ of the threaded nature of SI receives it is not possible to
+ mix these tests with the other coverage tests which allocate
+ various contexes.
+
+ Author: E. Scott Daniels
+ Date: 14 April 2020 (AKD)
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <netdb.h>
+#include <errno.h>
+#include <string.h>
+#include <errno.h>
+#include <pthread.h>
+#include <ctype.h>
+
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+#include <errno.h>
+#include <string.h>
+#include <stdint.h>
+#include <ctype.h>
+#include <sys/epoll.h>
+#include <pthread.h>
+#include <semaphore.h>
+
+#define DEBUG 1
+#define PARANOID_CHECKS 1 // must have parinoid testing on to not fail on nil pointer tests
+
+ // specific test tools in this directory
+#undef NNG_UNDER_TEST
+#include "test_support.c" // things like fail_if()
+#include "test_ctx_support.c" // dummy context support
+#include "test_msg_support.c"
+#include "test_gen_rt.c"
+
+
+#include "rmr.h" // things the users see
+#include "rmr_symtab.h"
+#include "rmr_logging.h"
+#include "rmr_agnostic.h" // transport agnostic header
+
+#include "symtab.c"
+#include "logging.c"
+#include "rmr_si.c"
+#include "mbuf_api.c"
+
+
+static void gen_rt( uta_ctx_t* ctx ); // defined in sr_si_static_test, but used by a few others (eliminate order requirement below)
+
+ // and finally....
+#include "rmr_si_rcv_static_test.c" // the only test driver
+
+
+/*
+ Drive each of the separate tests and report.
+*/
+int main() {
+ int errors = 0;
+
+ rmr_set_vlevel( 5 ); // enable all debugging
+
+ fprintf( stderr, "\n<INFO> starting receive tests (%d)\n", errors );
+ errors += rmr_rcv_test();
+ fprintf( stderr, "<INFO> error count: %d\n", errors );
+
+ if( errors == 0 ) {
+ fprintf( stderr, "<PASS> all tests were OK\n\n" );
+ } else {
+ fprintf( stderr, "<FAIL> %d modules reported errors\n\n", errors );
+ }
+
+ return !!errors;
+}
#undef NNG_UNDER_TEST
#include "test_support.c" // things like fail_if()
#include "test_ctx_support.c" // dummy context support
+#include "test_msg_support.c"
#include "test_gen_rt.c"
#include "mbuf_api_static_test.c"
#include "sr_si_static_test.c"
#include "lg_buf_static_test.c"
+// do NOT include the receive test static must be stand alone
#include "rmr_si_api_static_test.c"
--- /dev/null
+// vi: ts=4 sw=4 noet :
+/*
+==================================================================================
+ Copyright (c) 2019-2020 Nokia
+ Copyright (c) 2018-2020 AT&T Intellectual Property.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================================
+*/
+
+/*
+ Mnemonic: test_msg_support.c
+ Abstract: Support for testing with messages; requires RMR defs, so not
+ to be included for things like ring tests etc.
+ Author: E. Scott Daniels
+ Date: 14 April 2020 (AKD)
+*/
+
+#ifndef _test_msg_support_c
+#define _test_msg_support_c
+
+#include <signal.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+int test_support_xact_count = 0;
+/*
+ Send a 'burst' of messages to drive some send retry failures to increase RMr coverage
+ by handling the retry caee.
+*/
+static void send_n_msgs( void* ctx, int n ) {
+ rmr_mbuf_t* msg; // message buffers
+ int i;
+
+ msg = rmr_alloc_msg( ctx, 1024 );
+ if( ! msg ) {
+ fprintf( stderr, "<FAIL> mass send of %d messages couldn't allocate message!\n", n );
+ return;
+ }
+
+ fprintf( stderr, "<INFO> mass send of %d messages\n", n );
+ for( i = 0; i < n; i++ ) {
+ msg->len = 100;
+ msg->mtype = 1;
+ msg->state = 999;
+
+ snprintf( msg->xaction, 32, "%015d", test_support_xact_count++ ); // simple transaction id so we can test receive specific and ring stuff
+
+ errno = 999;
+ msg = rmr_send_msg( ctx, msg );
+ if( msg && msg->state != 0 ) {
+ fprintf( stderr, "<WARN> mass send failed: state=%d type=%d\n", msg->state, msg->mtype );
+ }
+ }
+}
+
+
+/*
+ Allow test to reset the transaction id counter.
+*/
+static void reset_xact_count() {
+ test_support_xact_count = 0;
+}
+
+/*
+ Refresh or allocate a message with some default values
+*/
+static rmr_mbuf_t* fresh_msg( void* ctx, rmr_mbuf_t* msg ) {
+ if( ! msg ) {
+ msg = rmr_alloc_msg( ctx, 2048 );
+ }
+
+ msg->mtype = 0;
+ msg->sub_id = -1;
+ msg->state = 0;
+ msg->len = 100;
+
+ return msg;
+}
+
+#endif
#include "rmr.h" // we use some of rmr defs in building dummy messages, so we need these
#include "rmr_agnostic.h"
-// ---------------------- emulated nng functions ---------------------------
+// ---------------------- emulated SI95 functions ---------------------------
#ifndef _em_si // this is the same define as the nng emulation code uses to give warning if both included
#include "test_common_em.c" // common emulation needed for all (epoll, gethostname...)
+// --- some globals --------------------------------------------------------
+int em_reset_call_flag = 0; // allows a send to turn off the call flag (see em_disable_call_flg())
+
+// ------------- emulated message header -----------------------------------
+
+/*
+ This is a copy from agnostic.h. we need to reset flags in some situations
+ so we have to have this, under a different name to avoid disaster.
+*/
+typedef struct {
+ int32_t mtype; // message type ("long" network integer)
+ int32_t plen; // payload length (sender data length in payload)
+ int32_t rmr_ver; // our internal message version number
+ unsigned char xid[RMR_MAX_XID]; // space for user transaction id or somesuch
+ unsigned char sid[RMR_MAX_SID]; // sender ID for return to sender needs
+ unsigned char src[RMR_MAX_SRC]; // name:port of the sender (source)
+ unsigned char meid[RMR_MAX_MEID]; // managed element id.
+ struct timespec ts; // timestamp ???
+
+ // V2 extension
+ int32_t flags; // HFL_* constants
+ int32_t len0; // length of the RMr header data
+ int32_t len1; // length of the tracing data
+ int32_t len2; // length of data 1 (d1)
+ int32_t len3; // length of data 2 (d2)
+ int32_t sub_id; // subscription id (-1 invalid)
+
+ // v3 extension
+ unsigned char srcip[RMR_MAX_SRC]; // ip address and port of the source
+} em_mhdr_t;
+
//--------------------------------------------------------------------------
/*
These are the current references in the RMR code; all others are internal
return -1;
}
- fprintf( stderr, "<SIEM> siem is emulating connect attempt return fd=%d\n", em_next_fd );
- em_next_fd++;
+ fprintf( stderr, "<SIEM> siem is emulating connect to (%s) attempt return fd=%d\n", abuf, em_next_fd );
+ if( em_next_fd < 50 ) {
+ em_next_fd++;
+ }
return em_next_fd-1;
}
return;
}
+/*
+ Calling this function causes the send emulation to turn off the call
+ flag in the RMR header. Turning that flag off makes the arriving message
+ look as though it might be a response to a call rather than a call itself.
+ This is needed since we loop back messages.
+*/
+static void em_disable_call_flg() {
+ em_reset_call_flag = 1;
+ fprintf( stderr, "<SIEM> reset call flag setting is: %d\n", em_reset_call_flag );
+}
+
+/*
+ Opposite of disable_call_flg; the flag is not touched.
+*/
+static void em_allow_call_flg() {
+ em_reset_call_flag = 0;
+ fprintf( stderr, "<SIEM> reset call flag setting is: %d\n", em_reset_call_flag );
+}
+
// callback prototype to drive to simulate 'receive'
static int mt_data_cb( void* datap, int fd, char* buf, int buflen );
+
/*
Emulate sending a message. If the global em_send_failures is set,
then every so often we fail with an EAGAIN to drive that part
return SIEM_BLOCKED;
}
+ if( em_reset_call_flag ) { // for call testing we need to flip the flag off to see it "return"
+ em_mhdr_t* hdr;
+
+ hdr = (em_mhdr_t *) (ubuf+50); // past the transport header bytes
+ hdr->flags &= ~HFL_CALL_MSG; // flip off the call flag
+ }
+
uss++;
if( em_cb_data != NULL ) {
-// : vi ts=4 sw=4 noet :
+// vi: ts=4 sw=4 noet :
/*
==================================================================================
Copyright (c) 2019-2020 Nokia