diff --git a/tests/api_tst.test/runit b/tests/api_tst.test/runit index 267a1ca480..433a0fd0bc 100755 --- a/tests/api_tst.test/runit +++ b/tests/api_tst.test/runit @@ -99,6 +99,10 @@ ${TESTSBUILDDIR}/cdb2api_localcache_systable ${DBNAME} [[ $? -ne 0 ]] && echo "cdb2api_localcache_systable - fail" && exit 1 echo 'cdb2api_localcache_systable - pass' +${TESTSBUILDDIR}/cdb2api_sockpooltimeout ${DBNAME} +[[ $? -ne 0 ]] && echo "cdb2api_sockpooltimeout - fail" && exit 1 +echo 'cdb2api_sockpooltimeout - pass' + echo 'comdb2_feature:discard_unread_socket_data=on' >> ${cfg} ${TESTSBUILDDIR}/cdb2api_unread_data ${DBNAME} [[ $? -ne 0 ]] && echo "cdb2api_unread_data - fail" && exit 1 diff --git a/tests/tools/CMakeLists.txt b/tests/tools/CMakeLists.txt index 8428ea3367..1eac99029d 100644 --- a/tests/tools/CMakeLists.txt +++ b/tests/tools/CMakeLists.txt @@ -44,6 +44,7 @@ add_exe(cdb2api_localcache_systable cdb2api_localcache_systable.cpp) add_exe(cdb2api_read_intrans_results cdb2api_read_intrans_results.c) add_exe(cdb2api_rte cdb2api_rte.cpp) add_exe(cdb2api_setoptions cdb2api_setoptions.cpp) +add_exe(cdb2api_sockpooltimeout cdb2api_sockpooltimeout.cpp) add_exe(cdb2api_sptrace cdb2api_sptrace.cpp) add_exe(cdb2api_stmt_return_types cdb2api_stmt_return_types.cpp) add_exe(cdb2api_string_escape cdb2api_string_escape.cpp) diff --git a/tests/tools/cdb2api_sockpooltimeout.cpp b/tests/tools/cdb2api_sockpooltimeout.cpp new file mode 100644 index 0000000000..a7ed2000dc --- /dev/null +++ b/tests/tools/cdb2api_sockpooltimeout.cpp @@ -0,0 +1,114 @@ +#undef NDEBUG +#include +#include +#include +#include +#include + +#include +#include + +static void sockpool_prod_timeout_test(const char *db) +{ + int rc; + cdb2_effects_tp effects; + cdb2_hndl_tp *hndl = NULL; + + // Should fail "quickly" + time_t start_time = time(NULL); + rc = cdb2_open(&hndl, db, "prod", 0); + time_t end_time = time(NULL); + printf("Total open time=%ld\n", end_time - start_time); + assert(rc != 0 && (end_time - start_time) < 10); +} + +// Just a simple select 1 +static void sockpool_test(const char *db, int line) +{ + int rc; + cdb2_effects_tp effects; + cdb2_hndl_tp *hndl = NULL; + + rc = cdb2_open(&hndl, db, "default", 0); + if (rc) + fprintf(stderr, "Line %d: open rc=%d errstr=%s\n", line, rc, + cdb2_errstr(hndl)); + assert(rc == 0); + + rc = cdb2_run_statement(hndl, "select 1"); + if (rc) + fprintf(stderr, "Line %d: run_statement rc=%d errstr=%s\n", line, rc, + cdb2_errstr(hndl)); + assert(rc == 0); + + while ((rc = cdb2_next_record(hndl)) == CDB2_OK) + ; + assert(rc == CDB2_OK_DONE); + + rc = cdb2_close(hndl); + assert(rc == 0); +} + +int main(int argc, char **argv) +{ + const char *dbname; + signal(SIGPIPE, SIG_IGN); + + /* bypass local cache code for this test needs to talk to sockpool */ + setenv("COMDB2_CONFIG_MAX_LOCAL_CONNECTION_CACHE_ENTRIES", "0", 1); + test_process_env_vars(); + + if (argc != 2) { + fprintf(stderr, "Usage: %s dbname\n", argv[0]); + exit(1); + } + dbname = argv[1]; + char *conf = getenv("CDB2_CONFIG"); + if (conf) + cdb2_set_comdb2db_config(conf); + + cdb2_enable_sockpool(); + + setenv("COMDB2_CONFIG_SOCKPOOL_SEND_TIMEOUTMS", "1", 1); + setenv("COMDB2_CONFIG_SOCKPOOL_RECV_TIMEOUTMS", "1", 1); + setenv("COMDB2_CONFIG_SOCKET_TIMEOUT", "1", 1); + setenv("COMDB2_CONFIG_CONNECT_TIMEOUT", "1", 1); + + assert(0 == get_num_sockpool_send_timeouts()); + assert(0 == get_num_sockpool_recv_timeouts()); + + // sockpool_prod_timeout_test("comdb2db"); + + // prod test causes lots of actual sockpool recv timeouts + int recv_timeouts = get_num_sockpool_recv_timeouts(); + + setenv("COMDB2_CONFIG_SOCKPOOL_SEND_TIMEOUTMS", "1000", 1); + setenv("COMDB2_CONFIG_SOCKPOOL_RECV_TIMEOUTMS", "1000", 1); + setenv("COMDB2_CONFIG_SOCKET_TIMEOUT", "100", 1); + setenv("COMDB2_CONFIG_CONNECT_TIMEOUT", "100", 1); + + sockpool_test(dbname, __LINE__); + + set_fail_timeout_sockpool_send(1); + sockpool_test(dbname, __LINE__); + + assert(1 == get_num_sockpool_send_timeouts()); + assert(recv_timeouts == get_num_sockpool_recv_timeouts()); + + set_fail_timeout_sockpool_recv(1); + sockpool_test(dbname, __LINE__); + assert(1 == get_num_sockpool_send_timeouts()); + assert((recv_timeouts + 1) == get_num_sockpool_recv_timeouts()); + + set_fail_timeout_sockpool_send(2); + set_fail_timeout_sockpool_recv(2); + sockpool_test(dbname, __LINE__); + assert(3 == get_num_sockpool_send_timeouts()); + int expected_recv_timeouts = getenv("CLUSTER") ? recv_timeouts + 2 : recv_timeouts + 1; + // int expected_recv_timeouts = recv_timeouts + 3; + fprintf(stderr, "Expected recv timeouts=%d actual=%d\n", expected_recv_timeouts, + get_num_sockpool_recv_timeouts()); + assert((expected_recv_timeouts)== get_num_sockpool_recv_timeouts()); + + printf("%s - pass\n", basename(argv[0])); +}