From 19ab994d8ea15bf16ed2f20c651f1a1d5abd12e3 Mon Sep 17 00:00:00 2001 From: Chris Koeritz Date: Sun, 25 Sep 2016 14:03:31 -0400 Subject: [PATCH] more updates, with a fix for windows finally in. it turned out to be a strange failure in cygwin due to some of the apps being built with a WinMain, leading them to seemingly exit immediately, which messed with the status being returned pretty badly. perhaps cygwin was also killing the process prematurely because it had no console? in any case, adding a pipe to cat has forced cygwin to track the process across its entire lifetime and now we are correctly trapping the results of all the test aps. whew. this was a really ugly mess and popped up in some really strangely unrelated ways. --- nucleus/library/tests_basis/test_mutex.cpp | 10 ++-- octopi/library/sockets/raw_socket.cpp | 15 ------ octopi/library/sockets/spocket.cpp | 49 +------------------ .../library/tests_sockets/bcast_spocketer.cpp | 2 +- .../library/tests_sockets/bcast_spocketer.h | 1 - .../library/tests_sockets/spocket_tester.cpp | 29 +---------- octopi/library/tests_sockets/test_spocket.cpp | 24 --------- scripts/clam/cpp/variables.def | 3 ++ scripts/clam/target_runner.sh | 15 +++++- 9 files changed, 25 insertions(+), 123 deletions(-) diff --git a/nucleus/library/tests_basis/test_mutex.cpp b/nucleus/library/tests_basis/test_mutex.cpp index 743e0004..83ba313b 100644 --- a/nucleus/library/tests_basis/test_mutex.cpp +++ b/nucleus/library/tests_basis/test_mutex.cpp @@ -214,6 +214,10 @@ int test_mutex::execute() { FUNCDEF("execute"); + // make sure the guard is initialized before the threads run. + guard().lock(); + guard().unlock(); + { // we check how long a lock and unlock of a non-locked mutex will take. // this is important to know so that we aren't spending much of our time @@ -234,10 +238,6 @@ int test_mutex::execute() ASSERT_TRUE(time_per_lock < 1.0, "mutex lock timing should be super fast"); } - // make sure the guard is initialized before the threads run. - guard().lock(); - guard().unlock(); - amorph thread_list; for (int i = 0; i < DEFAULT_FISH; i++) { @@ -248,7 +248,7 @@ int test_mutex::execute() ethread *q = thread_list[thread_list.elements() - 1]; ASSERT_EQUAL(q, t, "amorph pointer equivalence is required"); // start the thread we added. - thread_list[thread_list.elements() - 1]->start(NIL); + q->start(NIL); } time_stamp when_to_leave(DEFAULT_RUN_TIME); diff --git a/octopi/library/sockets/raw_socket.cpp b/octopi/library/sockets/raw_socket.cpp index 6b50fbe5..97ad00ab 100644 --- a/octopi/library/sockets/raw_socket.cpp +++ b/octopi/library/sockets/raw_socket.cpp @@ -213,36 +213,23 @@ int raw_socket::inner_select(basis::un_int socket, int mode, int timeout, FUNCDEF("inner_select"); // setup the file descriptor sets for the select. we check readability, // writability and exception status. -LOG("select A"); FD_ZERO(&read_list); FD_SET(socket, &read_list); -LOG("select B"); FD_ZERO(&write_list); FD_SET(socket, &write_list); -LOG("select C"); FD_ZERO(&exceptions); FD_SET(socket, &exceptions); -LOG("select D"); -timeval *farkle = new timeval; -LOG("select D.1"); -time_stamp *t = new time_stamp(); -LOG("select D.2"); timeval time_out; time_stamp::fill_timeval_ms(time_out, timeout); // timeval has tv_sec=seconds, tv_usec=microseconds. -LOG("select E"); // select will tell us about the socket. int ret = ::select(socket + 1, (mode & SELECTING_JUST_WRITE)? NIL : &read_list, (mode & SELECTING_JUST_READ)? NIL : &write_list, &exceptions, &time_out); -LOG("select F"); int error = critical_events::system_error(); -LOG("select G"); - if (!ret) return 0; // nothing to report. if (ret == SOCKET_ERROR) { -LOG("select H"); switch (error) { // all real errors fall out to the error handling stuff. case SOCK_EFAULT: // intentional fall-through. @@ -264,7 +251,6 @@ LOG("select H"); #endif return 0; // not really an error. } -LOG("select I"); #ifdef DEBUG_RAW_SOCKET LOG(a_sprintf("socket %u had error %d in select: %s.", socket, error, _stack->tcpip_error_name(error).s())); @@ -272,7 +258,6 @@ LOG("select I"); return SI_ERRONEOUS; } -LOG("select J"); // if we got to here, then there are some things to report... return SI_BASELINE; } diff --git a/octopi/library/sockets/spocket.cpp b/octopi/library/sockets/spocket.cpp index 0c32b132..3f469bae 100644 --- a/octopi/library/sockets/spocket.cpp +++ b/octopi/library/sockets/spocket.cpp @@ -47,7 +47,7 @@ using namespace timely; namespace sockets { -#define DEBUG_SPOCKET +//#define DEBUG_SPOCKET // uncomment for noisy version. #undef LOG @@ -149,32 +149,20 @@ tcpip_stack &spocket::stack() const { return *_stack; } astring spocket::text_form() { FUNCDEF("text_form"); -LOG("INTO TEXT_FORM A"); astring to_return = is_client()? "client" : (is_root_server()? "root-server" : "server"); -LOG("INTO TEXT_FORM B"); to_return += " spocket: "; -LOG("INTO TEXT_FORM C"); if (connected()) { -LOG("INTO TEXT_FORM C.1"); to_return += "connected, "; } else { -LOG("INTO TEXT_FORM C.2"); if (was_connected()) to_return += "unconnected (was once), "; else to_return += "never-connected, "; -LOG("INTO TEXT_FORM C.3"); } -LOG("INTO TEXT_FORM D"); to_return += a_sprintf("socket=%u, ", _socket); -LOG("INTO TEXT_FORM E"); if (is_root_server()) { -LOG("INTO TEXT_FORM F"); to_return += a_sprintf("root-socket=%u, ", _server_socket); -LOG("INTO TEXT_FORM G"); } -LOG("INTO TEXT_FORM H"); to_return += _where->text_form().s(); -LOG("INTO TEXT_FORM X"); return to_return; } @@ -222,18 +210,12 @@ bool spocket::connected() if (!_socket) return false; -LOG("conn check, _sock not null"); - // do examination on spocket. int sel_mode = 0; GRAB_LOCK; -LOG(a_sprintf("lock was grabbed, socks is %x", _socks)); try { int ret = _socks->select(_socket, sel_mode); - -LOG("after select"); - if (ret == 0) { return true; // we are happy. } @@ -243,7 +225,7 @@ LOG("after select"); } return true; } catch (...) { -LOG("caught exception thrown from select, returning false."); + LOG("caught exception thrown from select, returning false."); return false; } } @@ -320,14 +302,11 @@ outcome spocket::connect(int communication_wait) LOG("Failed to open the client's connecting spocket."); return ACCESS_DENIED; } -LOG(a_sprintf("hola, socket value received is: %d", _socket)); // mark the spocket for _blocking_ I/O. we want connect to sit there // until it's connected or returns with an error. _socks->set_non_blocking(_socket, false); -LOG(a_sprintf("set nonblock false on : %d", _socket)); - if (_type == BROADCAST) { if (!_socks->set_broadcast(_socket)) return ACCESS_DENIED; // mark the socket for broadcast capability. @@ -335,7 +314,6 @@ LOG(a_sprintf("set nonblock false on : %d", _socket)); if (!_socks->set_reuse_address(_socket)) return ACCESS_DENIED; // mark the socket so we don't get bind errors on in-use conditions. -LOG(a_sprintf("set reuse addr : %d", _socket)); } if (_type == CONNECTED) { @@ -553,13 +531,9 @@ outcome spocket::accept(spocket * &sock, bool wait) return ACCESS_DENIED; } -LOG(a_sprintf("accepted socket number is %d", accepted)); - // mark the new spocket for non-blocking I/O. _socks->set_non_blocking(accepted, true); -LOG("after set nonblockheading"); - //move to socks object! int sock_hop = 1; if (setsockopt(accepted, SOL_SOCKET, SO_KEEPALIVE, (char *)&sock_hop, @@ -579,16 +553,10 @@ LOG("after set nonblockheading"); // create the spocket address that we will connect to. sock = new spocket(*_where); -LOG("preview new spock A:"); LOG(sock->text_form()); *sock->_remote = _stack->convert(new_sock); -LOG("preview new spock B:"); LOG(sock->text_form()); sock->_socket = accepted; -LOG("preview new spock C:"); LOG(sock->text_form()); sock->_server_socket = 0; // reset to avoid whacking. -LOG("preview new spock D:"); LOG(sock->text_form()); sock->_was_connected = true; -LOG("about to return this spocket as new spock:"); -LOG(sock->text_form()); return OKAY; } @@ -691,45 +659,32 @@ outcome spocket::receive(byte_array &buffer, int &size) outcome spocket::receive(abyte *buffer, int &size) { FUNCDEF("receive"); -LOG("RECV A"); CHECK_BOGUS(NONE_READY); -LOG("RECV B"); if (_type != CONNECTED) return BAD_INPUT; ENSURE_HEALTH(NO_CONNECTION); -LOG("RECV C"); int expected = size; size = 0; if (expected <= 0) return BAD_INPUT; -LOG("RECV D"); GRAB_LOCK; -LOG("RECV E"); int len = recv(_socket, (char *)buffer, expected, 0); -LOG("RECV F"); if (!len) { -LOG("RECV F.1"); // check to make sure we're not disconnected. int ret = _socks->select(_socket, raw_socket::SELECTING_JUST_READ); -LOG("RECV F.2"); if (ret & SI_DISCONNECTED) { RECOGNIZE_DISCO; return NO_CONNECTION; } -LOG("RECV F.3"); // seems like more normal absence of data. return NONE_READY; } else if (len < 0) { -LOG("RECV F.4"); if (critical_events::system_error() == SOCK_EWOULDBLOCK) return NONE_READY; #ifdef DEBUG_SPOCKET LOG(astring("The receive failed with an error ") + critical_events::system_error_text(critical_events::system_error())); #endif -LOG("RECV F.5"); if (!connected()) return NO_CONNECTION; -LOG("RECV F.6"); return ACCESS_DENIED; } -LOG("RECV G"); size = len; return OKAY; } diff --git a/octopi/library/tests_sockets/bcast_spocketer.cpp b/octopi/library/tests_sockets/bcast_spocketer.cpp index dbd19805..9541255d 100644 --- a/octopi/library/tests_sockets/bcast_spocketer.cpp +++ b/octopi/library/tests_sockets/bcast_spocketer.cpp @@ -50,7 +50,7 @@ const int MAXIMUM_TRANSFER_WAIT = 40 * SECOND_ms; static abyte receive_buffer[MAXIMUM_WINSOCK_MTU + 1]; // used for dumping received data into. -#define DEBUG_SPOCKET_TESTER +//#define DEBUG_SPOCKET_TESTER // uncomment for noisy version. broadcast_spocket_tester::broadcast_spocket_tester diff --git a/octopi/library/tests_sockets/bcast_spocketer.h b/octopi/library/tests_sockets/bcast_spocketer.h index bf171c15..d63efedf 100644 --- a/octopi/library/tests_sockets/bcast_spocketer.h +++ b/octopi/library/tests_sockets/bcast_spocketer.h @@ -19,7 +19,6 @@ * Please send any updates to: fred@gruntose.com * \*****************************************************************************/ -////#include #include #include #include diff --git a/octopi/library/tests_sockets/spocket_tester.cpp b/octopi/library/tests_sockets/spocket_tester.cpp index 025f976f..3fac9bb8 100644 --- a/octopi/library/tests_sockets/spocket_tester.cpp +++ b/octopi/library/tests_sockets/spocket_tester.cpp @@ -52,7 +52,7 @@ static abyte receive_buffer[MAXIMUM_WINSOCK_MTU + 1]; const int PAUSE_TIME = 200; // the snooze interval when we encounter socket underflow or overflow. -#define DEBUG_SPOCKET_TESTER +//#define DEBUG_SPOCKET_TESTER // uncomment for noisy version. spocket_tester::spocket_tester(const internet_address &where) @@ -76,10 +76,8 @@ spocket_tester::~spocket_tester() bool spocket_tester::connect() { if (!_socket) { -LOG("creating new client socket"); _socket = new spocket(*_where); } -LOG(astring("connect socket info: ") + _socket->text_form()); outcome ret = spocket::NO_CONNECTION; while (true) { ret = _socket->connect(); @@ -93,17 +91,13 @@ LOG(astring("connect socket info: ") + _socket->text_form()); bool spocket_tester::accept(bool wait) { if (!_root_server) { -LOG("hey creating new root server socket"); _root_server = new spocket(*_where); -LOG("got past creating the root server socket"); -LOG(astring("accept root server socket info: ") + _root_server->text_form()); } if (_socket) { LOG("already have a socket for accept!"); return true; } outcome ret = spocket::NO_CONNECTION; -LOG("int accepting loop on root server"); while (true) { ret = _root_server->accept(_socket, false); if (ret == spocket::OKAY) break; @@ -112,9 +106,6 @@ LOG("int accepting loop on root server"); time_control::sleep_ms(100); // snooze to avoid slamming with accepts. } -if (_socket != NIL) { -LOG(astring("accepted! socket info: ") + _socket->text_form()); -} return ret == spocket::OKAY; } @@ -179,26 +170,14 @@ bool spocket_tester::do_a_receive(int size_expected, testing_statistics &stats) #endif time_stamp when_to_leave(MAXIMUM_TRANSFER_WAIT); -LOG("FARP 1"); int full_length = 0; while ( (full_length < size_expected) && (time_stamp() < when_to_leave) ) { -LOG("FARP 2"); time_stamp start_of_receive; int len = MAXIMUM_WINSOCK_MTU; -LOG("FARP 3"); -if (!_socket) { - LOG("WHAT? SOCKET IS NULL!!!"); -} -////time_control::sleep_ms(PAUSE_TIME); -LOG("FARP 3.1"); -LOG(astring("socket info: ") + _socket->text_form()); -LOG("FARP 3.2"); outcome ret = _socket->receive(receive_buffer, len); -LOG("FARP 4"); if (ret != spocket::OKAY) { if (ret == spocket::NONE_READY) { if (len != 0) LOG(a_sprintf("supposedly nothing was received (%d bytes)", len)); -/// time_control::sleep_ms(PAUSE_TIME); _socket->await_readable(PAUSE_TIME); continue; } else break; @@ -238,10 +217,6 @@ if (len != 0) LOG(a_sprintf("supposedly nothing was received (%d bytes)", len)); bool spocket_tester::perform_test(int size, int count, testing_statistics &stats) { -#ifdef DEBUG_SPOCKET_TESTER - LOG("into perf test"); -#endif - // the statics are used to generate our random buffer for sending. static abyte garbage_buffer[MAXIMUM_WINSOCK_MTU + 1]; static bool garbage_initialized = false; @@ -250,12 +225,10 @@ bool spocket_tester::perform_test(int size, int count, // if our static buffer full of random stuff was never initialized, we do // so now. this supports efficiently re-using the tester if desired. if (!garbage_initialized) { - LOG("initializing random send buffer."); // note the less than or equal; we know we have one more byte to fill. for (int i = 0; i <= MAXIMUM_WINSOCK_MTU; i++) garbage_buffer[i] = randomizer.inclusive(0, 255); garbage_initialized = true; - LOG("random send buffer initialized."); } // reset the statistical package. diff --git a/octopi/library/tests_sockets/test_spocket.cpp b/octopi/library/tests_sockets/test_spocket.cpp index 506566bb..5c761203 100644 --- a/octopi/library/tests_sockets/test_spocket.cpp +++ b/octopi/library/tests_sockets/test_spocket.cpp @@ -100,7 +100,6 @@ bool test_spocket::parse_address(const astring &input, ip_address_holder &ip_add int test_spocket::execute() { FUNCDEF("execute"); -LOG("OY POINT A"); ip_address_holder ip_address; // accumulates the source address. int rcv_port = 0; bool is_client = false; @@ -112,8 +111,6 @@ LOG("OY POINT A"); const int DEFAULT_SEND_SIZE = 1008; const int DEFAULT_SEND_COUNT = 10; -LOG("OY POINT B"); - if (_global_argc < 6) { if (_global_argc > 1) { LOG("\ @@ -137,19 +134,15 @@ expected during a cycle."); } } -LOG("OY POINT C"); - // only parse the parameters if we got enough from the user; otherwise we accept our // defaults to do a simple test run. if (_global_argc >= 6) { -LOG("OY POINT D"); if (!parse_address(_global_argv[1], ip_address)) { LOG("failed to parse source address."); return 9283; } -LOG("OY POINT E"); LOG(a_sprintf("\tParsed a source of: \"%d.%d.%d.%d\".", (int)ip_address[0], (int)ip_address[1], (int)ip_address[2], (int)ip_address[3])); @@ -188,8 +181,6 @@ LOG("OY POINT E"); LOG(a_sprintf("\tGot a send count of %d.", send_count)); } -LOG("OY POINT Q"); - // package our parameters in a form the tester likes. internet_address to_pass(byte_array(4, ip_address), "", rcv_port); @@ -199,10 +190,8 @@ LOG("OY POINT Q"); // choose the appropriate action based on our role. bool outcome; if (is_client) { -LOG("client side is connecting"); outcome = tester->connect(); } else { -LOG("server side is accepting"); outcome = tester->accept(_global_argc != 1); } if (!outcome) { @@ -210,9 +199,6 @@ LOG("server side is accepting"); LOG(astring("Failed to ") + action + " on the tester."); return 10; } -LOG("success after conn/accept"); - -LOG("OY POINT T"); if (_global_argc == 1) { // launch a paired duplicate of our test so we can chat. @@ -223,40 +209,30 @@ LOG("OY POINT T"); + a_sprintf("%d", DEFAULT_SEND_SIZE) + " " + a_sprintf("%d", DEFAULT_SEND_COUNT), launch_process::RETURN_IMMEDIATELY, kidnum); ASSERT_EQUAL(result, 0, "launching paired process should start successfully"); -LOG("OY POINT U.1"); // now we try again accepting from our client side. outcome = tester->accept(); //hmmm: redundant below. -LOG("OY POINT U.2"); if (!outcome) { const char *action = is_client? "connect" : "accept"; -LOG("OY POINT U.3"); LOG(astring("Failed to ") + action + " on the tester."); return 10; } } -LOG("OY POINT V"); // so, we're connected. try sending the test packages out. testing_statistics stats; // to be filled by the tester. -LOG("OY POINT V.1"); outcome = tester->perform_test(send_size, send_count * 2, stats); // multiply send_count since we count each side as one. -LOG("OY POINT V.2"); if (!outcome) { LOG("Failed out of send_data; maybe other side terminated."); } -LOG("OY POINT V.3"); stats.total_runs /= 2; // cut down to the real number of tests. -LOG("OY POINT V.4"); if (!stats.total_runs) stats.total_runs = 1; -LOG("OY POINT W"); - // now report on the stats that we get from the data sending. LOG(a_sprintf("Report for %d completed test cycles.", stats.total_runs)); LOG(""); diff --git a/scripts/clam/cpp/variables.def b/scripts/clam/cpp/variables.def index cf57dcfa..1581e075 100644 --- a/scripts/clam/cpp/variables.def +++ b/scripts/clam/cpp/variables.def @@ -868,6 +868,9 @@ ifeq "$(COMPILER)" "VISUAL_CPP" # now, vary the flag configuration based on the flags that have been set. +####override for windows since things are broken with WinMain +###export CONSOLE_MODE = true + ifneq "$(CONSOLE_MODE)" "" # console type of applications are built using the static flag so that # they are more redistributable. diff --git a/scripts/clam/target_runner.sh b/scripts/clam/target_runner.sh index 2678630d..d7b1ed33 100755 --- a/scripts/clam/target_runner.sh +++ b/scripts/clam/target_runner.sh @@ -23,8 +23,19 @@ if [ ! -z "${RUN_TARGETS}" -a ! -z "${RUN_ALL_TESTS}" ]; then total_exitval=0; for program_name in ${RUN_TARGETS}; do base=$(basename $program_name); - "$program_name"; - exitval=$?; + if [ "$OP_SYSTEM" == "WIN32" ]; then + # extra step to force win32 apps to stay held in our grip, + # since they will float off and appear to have stopped when + # run by cygwin. but by grabbing the i/o stream, we know it's + # running until it's done. + "$program_name" 2>&1 | cat + # we care about the exit status of the first process in the pipe, + # which is the app being run. + exitval=${PIPESTATUS[0]} + else + "$program_name" + exitval=$?; + fi if [ $exitval -ne 0 ]; then echo "ERROR: $program_name exits with $exitval at $(date)"; total_exitval=$(($total_exitval + 1)); -- 2.34.1