diff options
author | schmidt <douglascraigschmidt@users.noreply.github.com> | 1998-06-18 04:13:58 +0000 |
---|---|---|
committer | schmidt <douglascraigschmidt@users.noreply.github.com> | 1998-06-18 04:13:58 +0000 |
commit | 70e1738416a17108b087ec4b4b35dd2ddb7ca49f (patch) | |
tree | aa1234eb4c766900e6b0da717638b9d4a8e88af0 /tests/CLASSIX | |
parent | dfdc610629ae7e8fd4839082737dbaad95da9847 (diff) | |
download | ATCD-70e1738416a17108b087ec4b4b35dd2ddb7ca49f.tar.gz |
*** empty log message ***
Diffstat (limited to 'tests/CLASSIX')
-rw-r--r-- | tests/CLASSIX/Addr_Test.cpp | 115 | ||||
-rw-r--r-- | tests/CLASSIX/CLD_Connector_Test.cpp | 391 | ||||
-rw-r--r-- | tests/CLASSIX/Con_Acc_Test.cpp | 405 | ||||
-rw-r--r-- | tests/CLASSIX/Con_Acc_Test.h | 77 | ||||
-rw-r--r-- | tests/CLASSIX/Group_Test.cpp | 85 | ||||
-rw-r--r-- | tests/CLASSIX/Notify_Test.cpp | 266 | ||||
-rw-r--r-- | tests/CLASSIX/OS.cpp | 62 | ||||
-rw-r--r-- | tests/CLASSIX/OS_Test.cpp | 43 | ||||
-rw-r--r-- | tests/CLASSIX/README | 25 | ||||
-rw-r--r-- | tests/CLASSIX/Reactor_Test.cpp | 150 | ||||
-rw-r--r-- | tests/CLASSIX/Reactor_Test.h | 52 | ||||
-rw-r--r-- | tests/CLASSIX/SOCK_Test.cpp | 99 | ||||
-rw-r--r-- | tests/CLASSIX/Select_Reactor_Test.cpp | 166 | ||||
-rw-r--r-- | tests/CLASSIX/Select_Reactor_Test.h | 51 | ||||
-rw-r--r-- | tests/CLASSIX/Stream_Test.cpp | 110 | ||||
-rw-r--r-- | tests/CLASSIX/test_config.h | 272 |
16 files changed, 2369 insertions, 0 deletions
diff --git a/tests/CLASSIX/Addr_Test.cpp b/tests/CLASSIX/Addr_Test.cpp new file mode 100644 index 00000000000..03e35984363 --- /dev/null +++ b/tests/CLASSIX/Addr_Test.cpp @@ -0,0 +1,115 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// tests +// +// = FILENAME +// CLASSIX_Addr_Test.cpp +// +// = DESCRIPTION +// This is a test of the <IPP_CLASSIX_Addr> class. +// +// = AUTHOR +// Wei Chiang +// +// ============================================================================ + +#include "tests/test_config.h" +#include "CLASSIX/Addr.h" +#include "CLASSIX/SAP.h" +#include "CLASSIX/Port_Default.h" + +class testSap : public ACE_CLASSIX_SAP +{ +public: + testSap(): ACE_CLASSIX_SAP() {} + testSap(const ACE_Addr& theAddr) : ACE_CLASSIX_SAP(theAddr) {} + + ~testSap() {ACE_DEBUG((LM_DEBUG, "~testSap()\n"));} +}; + +int +main (int, char *[]) +{ + ACE_START_TEST ("Addr_Test"); + + /* ================================================================== */ + ACE_DEBUG((LM_INFO, "------test virtual destructor------\n")); + testSap *n1 = new testSap(); + ACE_CLASSIX_SAP *n2 = n1; + delete n2; + + /* ================================================================== */ + ACE_DEBUG((LM_INFO, "--------ACE_CLASSIX_Addr----------\n")); + ACE_DEBUG((LM_DEBUG, "\n--------------------------------\n")); + ACE_CLASSIX_Port_Core *k2 = new ACE_CLASSIX_Port_Core(); + int p2 = k2->get_handle(); + ACE_CLASSIX_Port a2(*k2); + ACE_DEBUG((LM_INFO, "Addr a2(ipc port id = %d)\n", p2)); + a2.dump(); + + ACE_CLASSIX_Port *a1 = ACE_CLASSIX_DEFAULT_PORT::instance(); + ACE_DEBUG((LM_INFO, "Default port:")); + a1->dump(); + a1->set_addr(a2.get_addr(), a2.get_size()); + if (*a1 != *ACE_CLASSIX_DEFAULT_PORT::instance()) + ACE_DEBUG((LM_ERROR, "???? Default port cannot be changed-2 !!!")); + + ACE_DEBUG((LM_DEBUG, "\n--------------------------------\n")); + ACE_CLASSIX_Port_Core k3; + ACE_CLASSIX_Port a3(k3); + ACE_DEBUG((LM_INFO, "Addr a3(ipc port id = %d)\n", k3.get_handle)); + a3.dump(); + + ACE_DEBUG((LM_DEBUG, "\n--------------------------------\n")); + ACE_CLASSIX_Port a4(a1->get_addr(), a1->get_size()); + a4.dump(); + if (a4 == *a1) + ACE_DEBUG((LM_INFO, "OK: Addr a4 == a1\n")); + else + ACE_ERROR((LM_ERROR, "Error: Addr a4 != a1\n")); + + if (a4 != a2) + ACE_DEBUG((LM_INFO, "OK: Addr a4 != a2\n")); + else + ACE_ERROR((LM_ERROR, "Error: Addr a4 == a2\n")); + + /* ================================================================== */ + + ACE_DEBUG((LM_INFO, "\n--------ACE_CLASSIX_Sap----------\n")); + testSap sap1; + sap1.set_addr(*a1); + ACE_CLASSIX_Port b1; + if (sap1.get_addr(b1) < 0) + ACE_ERROR((LM_ERROR, "failed to get sap1 address")); + if (b1 != *a1) + ACE_ERROR((LM_ERROR, "Error: sap1 address")); + sap1.dump(); + + + ACE_DEBUG((LM_DEBUG, "\n--------------------------------\n")); + testSap sap2(a2); + ACE_CLASSIX_Port b2; + if (sap2.get_addr(b2) < 0) + ACE_ERROR((LM_ERROR, "failed to get sap1 address")); + if (b2 != a2) + ACE_ERROR((LM_ERROR, "Error: sap2 address")); + b2.dump(); + sap2.dump(); + + + /* ================================================================== */ + int result = 0; + int p = k2->get_handle(); + delete k2; + if ((result = portDelete(K_MYACTOR, p)) == 0) + ACE_ERROR((LM_ERROR, + "????Error: delete already deleted port")); + + ACE_END_TEST; + return 0; +} + diff --git a/tests/CLASSIX/CLD_Connector_Test.cpp b/tests/CLASSIX/CLD_Connector_Test.cpp new file mode 100644 index 00000000000..50caf31c7e1 --- /dev/null +++ b/tests/CLASSIX/CLD_Connector_Test.cpp @@ -0,0 +1,391 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// tests +// +// = FILENAME +// CLD_Connector.cpp +// +// = DESCRIPTION +// Based on $ACE_ROOT/tests/MT_SOCK.cpp +// +// This is a multi-threaded torture test of the ACE_CLASSIX_CLD_Connector +// class. +// +// The test spawns a server and multiple clients allowing clients to +// exchange data with the server. +// +// This example demonstrates the following use cases +// - server is a subclass of ACE_Svc_Handler, +// but it does not involve an acceptor class. +// - server multicasts message to the clients +// - client uses ACE_CLASSIX_Connector to "connect" to the server +// +// ============================================================================ + +#include "test_config.h" +#include "ace/OS.h" +#include "ace/Thread.h" +#include "ace/Thread_Manager.h" +#include "ace/Handle_Set.h" +#include "ace/Svc_Handler.h" + +#include "CLASSIX/Reactor.h" +#include "CLASSIX/Stream.h" +#include "CLASSIX/Dgram_Mcast.h" +#include "CLASSIX/Group_Stamp.h" +#include "CLASSIX/CLD_Connector.h" + +#define MAX_TEST_CLIENTS 30 +#define TEST_STAMP 300 +#define ACE_CLASSIX_MCAST_DGRAM ACE_CLASSIX_Dgram_Mcast, ACE_CLASSIX_Group + +static ACE_Atomic_Op<ACE_Thread_Mutex, u_int> client_id = 0; + + +struct client_arg +{ + ACE_Barrier *wait; + ACE_CLASSIX_Port_Core *server; +}; + +struct client_data +{ + u_int me; + char c; +}; + +class server_handler : public ACE_Svc_Handler<ACE_CLASSIX_MCAST_DGRAM, + ACE_MT_SYNCH> +{ +public: + server_handler(int /* stamp */, const ACE_CLASSIX_Port_Core&); + // port that the server uses to receive data from all sorts of clients + virtual int open (void * = 0 /* args */); + virtual int handle_close (ACE_HANDLE, ACE_Reactor_Mask); + virtual int svc (void); + + // = Demultiplexing hooks for Reactor + virtual int handle_input (ACE_HANDLE); + // The first int of each message identifies the sender + +private: + ACE_Atomic_Op<ACE_Thread_Mutex, u_int> in_svc_; + // 1 if svc() is running +}; + +server_handler::server_handler(int theStamp, + const ACE_CLASSIX_Port_Core & thePort) + : ACE_Svc_Handler<ACE_CLASSIX_MCAST_DGRAM, ACE_MT_SYNCH> (), + in_svc_ (0) +{ + if (this->peer().set_saps(theStamp, thePort) != 0) + ACE_DEBUG((LM_DEBUG, "failed to set up IO stream \n")); +} + +int +server_handler::open (void *) +{ + ACE_DEBUG((LM_DEBUG, "server_handler::open()\n")); + if (reactor ()->register_handler (this, READ_MASK) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "(%t)server_handler:: cannot register handler\n"), + -1); + + if (this->peer().selectable() != 0) + ACE_DEBUG ((LM_DEBUG, + "(%t) failed to make Server's port %d selectable\n", + get_handle ())); + else + ACE_DEBUG ((LM_DEBUG, "(%t) created svc_handler for handle %d\n", + get_handle ())); + + if (this->peer().control(K_BROADMODE) != 0) + ACE_DEBUG((LM_DEBUG, "(%t) %p\n" + "server cannot send data to destination\n")); + + return this->activate (THR_BOUND); +} + +int +server_handler::handle_close (ACE_HANDLE, ACE_Reactor_Mask) +{ + while (this->in_svc_ == 1) + { + ACE_DEBUG ((LM_DEBUG, "(%t) server is closing down\n")); + + // Use a blank message to tell the thread to stop + ACE_Message_Block *mb = new ACE_Message_Block((size_t) 0); + ACE_Time_Value timeout(0, 10*1000); // wait for at most 10 usec + this->putq(mb, &timeout); + ACE_OS::thr_yield(); + } + + this->destroy(); +} + +int +server_handler::handle_input(ACE_HANDLE) +{ + // Get input as fast as it can to free the reactor to handle other work. + size_t n = 0; + if (ACE_Reactor::instance()-> + get_current_info(this->get_handle(),n) == -1) + ACE_ERROR_RETURN((LM_ERROR, "???(%t) failed to get input size\n"), -1); + + ACE_Message_Block *msg; + ACE_NEW_RETURN(msg, ACE_Message_Block(n == 0 ? 1 : n), -1); + if (this->peer().recv(msg->wr_ptr(), n) == -1) + ACE_ERROR_RETURN((LM_ERROR, "???(%t) %p\n", "get_data()"), -1); + msg->wr_ptr(n); + + + if (this->putq(msg) == -1) + ACE_ERROR_RETURN((LM_ERROR, "???(%t) failed to enqueue message\n"), + -1); + return 0; +} + +int +server_handler::svc(void) +{ + this->peer().open_writer(); + this->in_svc_ = 1; + + ACE_Message_Block *mb = 0; + int result = 0; + char *storage[MAX_TEST_CLIENTS]; + + // initialize the expected result per client + for (int i = 0; i < MAX_TEST_CLIENTS; i++) + storage[i] = ACE_ALPHABET; + + int len = sizeof (client_data); + int total_clients = MAX_TEST_CLIENTS; + + ACE_DEBUG((LM_DEBUG, "(%t)server is waiting for clients\n")); + // read input + for (;;) + { + // wait until a message has arrived + result = this->getq (mb); + + if (result == -1) + { + ACE_ERROR_RETURN((LM_ERROR, + "???(%t), error while waiting for a message " + "on the queue\n"), 0); + } + + int length = mb->length (); + + u_int client = 0; + if (length != 0 && length == len) + { + client = *((u_int*) mb->rd_ptr ()); + mb->rd_ptr(sizeof (u_int)); + char* data = storage[client]; + // Check if the client has done + if (*(mb->rd_ptr()) == '\0') + { + ACE_DEBUG((LM_DEBUG, "handshake with client %d\n", client)); + client_data response; + response.me = client; + int r = this->peer().send_n(&response, len); + if (r != len) + ACE_ERROR((LM_ERROR, + "(%t):%d %p\n",r, + "server faided to send handshake msg")); + total_clients--; + if (total_clients == 0) + { + mb->release(); + ACE_DEBUG((LM_DEBUG, "(%t) end event loop \n")); + ACE_Reactor::end_event_loop(); + this->in_svc_ = 0; + break; + } + } + if (*data != *(mb->rd_ptr())) + ACE_ERROR((LM_ERROR, "???(%t), invalid input\n")); + storage[client] = ++data; + } + else if (length > 0) + { + ACE_ERROR((LM_ERROR, "???(%t), invalid input length(%d)\n", + length)); + } + mb->release(); + + } + + return 0; +} + + +static void * +client (void *arg) +{ + client_data info; + info.me = client_id++; + int info_len = sizeof (client_data); + + client_arg *data = (client_arg*) arg; + ACE_CLASSIX_Port_Core *server_port = data->server; + ACE_CLASSIX_Port server_addr(*server_port); + ACE_Barrier *barrier = data->wait; + //=================================================================== + // Stream & Connector + // +// ACE_CLASSIX_Stream cli_stream(*server_port); + ACE_CLASSIX_Stream cli_stream; + // create a stream where the local SAP uses the actor's default port. + + ACE_CLASSIX_CLD_Connector con; + // create a connector for the stream + + ACE_DEBUG ((LM_DEBUG, "(%P|%t) Connecting local and peer SAPs\n")); + // Connect local and peer SAPs. + + barrier->wait(); + //=================================================================== + // Attempt a connect to the server... + // A local port will be created as a local SAP + if (con.connect (cli_stream, server_addr) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + "(%P|%t) %p\n", + "connection failed"), + 0); + } + ACE_CLASSIX_Port client_addr; + if (cli_stream.local_sap().get_addr (client_addr) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) %p\n", "get_local_addr"), 0); + else + ACE_DEBUG ((LM_DEBUG, "(%P|%t) connected client at %d\n", + client_addr.get_handle ())); + + + //=================================================================== + // Insert the local SAP to the test group + ACE_CLASSIX_Group_Stamp group(TEST_STAMP); + // group that the client's port is in + if (group.insert(&client_addr) == -1) + ACE_ERROR_RETURN((LM_ERROR, + "Failed to insert local SAP of client %d in to the" + "group \n"), -1); + + //=================================================================== + // Do not use Reactor, so disable local port from being monitored + int result = cli_stream.unselectable(); + if (result != 0) + ACE_ERROR_RETURN ((LM_ERROR, + "(%P|%t) failed to disable local port(%d)\n", + result), -1); + + //=================================================================== + // Send data to server (correctly handles "incomplete writes"). + char *c = ACE_ALPHABET; + + do + { + ACE_OS::thr_yield(); + info.c = *c; + if (cli_stream.send_n (&info, info_len) != info_len) + ACE_ERROR ((LM_ERROR, "(%P|%t) %p\n", "send_n")); + }while(*c++ != '\0'); + + //=================================================================== + // Close writer + // ACE_DEBUG ((LM_DEBUG, "(%P|%t) closing writer\n")); + // Explicitly close the writer-side of the connection. + //if (cli_stream.close_writer () == -1) + // ACE_ERROR ((LM_ERROR, "(%P|%t) %p\n", "close_writer")); + + // Wait for handshake with server. + client_data response; + do + { + if (cli_stream.ipcRecv_n (&response, info_len) != info_len) + ACE_ERROR ((LM_ERROR, "(%P|%t) %p\n", "recv_n")); + } + while (response.me != info.me); + + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) received handshake from server\n")); + + // Close the connection completely. + if (cli_stream.close () == -1) + ACE_ERROR ((LM_ERROR, "(%P|%t) %p\n", "close")); + + return 0; +} + + +static void +spawn (ACE_CLASSIX_Port_Core* theServer) +{ + // create a port for the server + ACE_DEBUG ((LM_DEBUG, "(%P|%t) starting server at port %d\n", + theServer->get_handle ())); + + // activate server + server_handler handler(TEST_STAMP, *theServer); + handler.open(); // make the server active + + // activate clients + // make sure + // - we don't let client send messages before the event loop is running + ACE_Barrier wait(MAX_TEST_CLIENTS); + client_arg data; + data.server = theServer; + data.wait = &wait; + + ACE_DEBUG ((LM_DEBUG, "(%t) starting clients\n")); + if (ACE_Thread_Manager::instance ()->spawn_n + (MAX_TEST_CLIENTS, + ACE_THR_FUNC (client), + (void *) &data, + THR_BOUND | THR_DETACHED) == -1) + ACE_ERROR ((LM_ERROR, "(%P|%t) %p\n%a", "spawn failed")); + + // handle event + ACE_DEBUG((LM_DEBUG, "(%t)run event loop\n")); + ACE_Reactor::run_event_loop(); + + // wait until all server has completed + ACE_Thread_Manager::instance()->wait_task(&handler); +} + +int +main (int, char *[]) +{ + ACE_START_TEST ("CLD_Connector_Test"); + + // initialize classix environment, such as reactor + ACE_CLASSIX_OS classix; + + // running server and clients + ACE_CLASSIX_Port_Core server_port; + spawn(&server_port); + + + // Wait all the threads to exit. + ACE_Thread_Manager::instance ()->wait (); + + ACE_END_TEST; + return 0; +} + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) +template class ACE_Atomic_Op<ACE_Thread_Mutex, u_int>; +template class ACE_Svc_Handler<ACE_CLASSIX_MCAST_DGRAM, ACE_MT_SYNCH>; +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +#pragma instantiate ACE_Atomic_Op<ACE_Thread_Mutex, u_int> +#pragma instantiate ACE_Svc_Handler<ACE_CLASSIX_MCAST_DGRAM, ACE_MT_SYNCH> +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ + + diff --git a/tests/CLASSIX/Con_Acc_Test.cpp b/tests/CLASSIX/Con_Acc_Test.cpp new file mode 100644 index 00000000000..7c0a896eb10 --- /dev/null +++ b/tests/CLASSIX/Con_Acc_Test.cpp @@ -0,0 +1,405 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// tests +// +// = FILENAME +// Con_Acc__Test.cpp +// +// = DESCRIPTION +// Based on $ACE_ROOT/tests/Priority_Reactor_Test.cpp +// +// This is a test of the <ACE_Priority_Reactor>. The test forks +// two processes (for a total of three processes) which connect to +// the main process and The clients send data to a connector, +// interestingly enough the acceptor will give more priority to +// the second connection, which should run always before the first +// one. +// +// The test itself is interesting, it shows how to write very +// simple <ACE_Svc_Handler>, <ACE_Connectors> and <ACE_Acceptors>. +// +// = AUTHOR +// Carlos O'Ryan +// +// ============================================================================ + +#include "test_config.h" +#include "ace/Get_Opt.h" +#include "ace/Acceptor.h" +#include "ace/Handle_Set.h" +#include "ace/Connector.h" +#include "ace/Strategies.h" +#include "ace/Auto_Ptr.h" +#include "ace/Priority_Reactor.h" + +#include "CLASSIX/Connector.h" +#include "CLASSIX/Acceptor.h" +#include "Con_Acc_Test.h" + + +// The number of children to run, it can be changed using the -c +// option. +static int opt_nchildren = 2 /* 10 */; + +// The number of loops per children, it can be changed using the -l +// option. +static int opt_nloops = 200 /* 200 */; + +// If not set use the normal reactor, it can be changed using the -d +// option. +static int opt_priority_reactor = 1; + +// Maximum time to wait for the test termination (-t) +static int opt_max_duration = 60; + +// Maximum number of retries to connect, it can be changed using the +// -m option. +static int max_retries = 5; + +typedef ACE_Connector<Write_Handler, ACE_CLASSIX_CONNECTOR> + CONNECTOR; +typedef ACE_Acceptor<Read_Handler, ACE_CLASSIX_ACCEPTOR> + ACCEPTOR; + +typedef ACE_CLASSIX_Port ADDR; + +ACE_Atomic_Op<ACE_Thread_Mutex, int> Read_Handler::waiting_ = 0; +ACE_Atomic_Op<ACE_Thread_Mutex, int> Read_Handler::started_ = 0; + +void +Read_Handler::set_countdown (int nchildren) +{ + Read_Handler::waiting_ = nchildren; +} + +int +Read_Handler::get_countdown (void) +{ + return Read_Handler::waiting_.value(); +} + +int +Read_Handler::open (void *) +{ + if (this->peer ().enable (ACE_NONBLOCK) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "(%P|%t) Read_Handler::open, " + "cannot set non blocking mode"), -1); + + if (reactor ()->register_handler (this, READ_MASK) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "(%P|%t) Read_Handler::open, " + "cannot register handler"), -1); + + // A number larger than the actual number of priorities, so some + // clients are misbehaved, hence pusnished. + const int max_priority = 15; + + this->priority (ACE_Event_Handler::LO_PRIORITY + started_.value() % max_priority); + started_++; + + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) created svc_handler for handle %d " + "with priority %d\n", + get_handle (), + priority ())); + return 0; +} + +int +Read_Handler::handle_input (ACE_HANDLE h) +{ + char buf[BUFSIZ]; + + ACE_DEBUG((LM_DEBUG, + "(%P|%t|%x) read from handle %d...", this, h)); + ssize_t result = this->peer ().recv (buf, sizeof (buf)); + + if (result <= 0) + { + if (result < 0 && errno == EWOULDBLOCK) + return 0; + + if (result != 0) + ACE_DEBUG ((LM_DEBUG, "(%P|%t) %p\n", + "Read_Handler::handle_input")); + waiting_--; + + if (waiting_ == 0) + { + ACE_DEBUG ((LM_DEBUG, + "Last svc_handler closed, shutting down\n")); + ACE_Reactor::instance()->end_event_loop(); + } + + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) Read_Handler(%d)::handle_input closing down\n", h)); + return -1; + } + + ACE_DEBUG((LM_DEBUG, + "...(%P|%t) read %d bytes from handle %d, priority %d\n", + result, h, priority ())); + return 0; +} + +int +Write_Handler::open (void *) +{ + return 0; +} + +int +Write_Handler::svc (void) +{ + ACE_DEBUG ((LM_DEBUG, "(%P|%t) in svc\n")); + // Send several short messages, doing pauses between each message. + // The number of messages can be controlled from the command line. + + ACE_Time_Value pause (0, 1000); + for (int i = 0; i < opt_nloops; ++i) + { + if (this->peer ().send_n (ACE_ALPHABET, + sizeof (ACE_ALPHABET) - 1) == -1) + { + ACE_DEBUG((LM_DEBUG, "%t %p\n", "send_n\n")); + ACE_OS::sleep (pause); + } + } + this->peer().close_writer(); + return 0; +} + +// Execute the client tests. +static void * +client (void *arg) +{ + ADDR *connection_addr = (ADDR *) arg; + ACE_DEBUG ((LM_DEBUG, "(%P|%t) running client\n")); + CONNECTOR connector; + + Write_Handler *writer = 0; + + // Do exponential backoff connections + ACE_Synch_Options options = ACE_Synch_Options::synch; + + // Start with one msec timeouts. + ACE_Time_Value msec (0, 1000); + options.timeout (msec); + + // Try up to <max_retries> to connect to the server. + for (int i = 0; i < max_retries; i++) + { + if (connector.connect (writer, + *connection_addr, + options) == -1) + { + // Double the timeout... + ACE_Time_Value tmp = options.timeout (); + tmp += options.timeout (); + options.timeout (tmp); + writer = 0; + ACE_DEBUG ((LM_DEBUG, "(%P|%t) still trying to connect\n")); + } + else + { + // Let the new Svc_Handler to its job... + ACE_DEBUG ((LM_DEBUG, "(%P|%t) running svc\n")); + writer->svc (); + + ACE_DEBUG ((LM_DEBUG, "(%P|%t) finishing client\n")); + + // then close the connection and release the Svc_Handler. + writer->destroy (); + + return 0; + } + } + + ACE_ERROR ((LM_ERROR, + "(%P|%t) failed to connect after %d retries\n", + max_retries)); + return 0; +} + +int +main (int argc, char *argv[]) +{ + ACE_START_TEST ("Con_Acc_Test"); + + // initialize environment, eg. reactor, etc. + ACE_CLASSIX_OS os; + + ACE_Get_Opt getopt (argc, argv, "dc:l:m:t:", 1); + + for (int c; (c = getopt ()) != -1; ) + switch (c) + { + case 'd': + opt_priority_reactor = 0; + break; + case 'c': + opt_nchildren = atoi (getopt.optarg); + break; + case 'l': + opt_nloops = atoi (getopt.optarg); + break; + case 'm': + max_retries = atoi (getopt.optarg); + break; + case 't': + opt_max_duration = atoi (getopt.optarg); + break; + case '?': + default: + ACE_ERROR_RETURN ((LM_ERROR, "Usage: Priority_Reactor_Test " + " [-d] (disable priority reactor)\n" + " [-c nchildren] (number of threads/processes)\n" + " [-l loops] (number of loops per child)\n" + " [-m maxretries] (attempts to connect)\n" + " [-t max_time] (limits test duration)\n"), -1); + ACE_NOTREACHED (break); + } +#if 0 + // Manage memory automagically. + // Note: This ordering is very subtle... + auto_ptr<ACE_Reactor> reactor; + auto_ptr<ACE_Select_Reactor> impl; + + if (opt_priority_reactor) + { + ACE_Select_Reactor *impl_ptr; + ACE_NEW_RETURN (impl_ptr, ACE_Priority_Reactor, -1); + impl = auto_ptr<ACE_Select_Reactor> (impl_ptr); + ACE_Reactor *reactor_ptr; + ACE_NEW_RETURN (reactor_ptr, ACE_Reactor (impl_ptr), -1); + reactor = auto_ptr<ACE_Reactor> (reactor_ptr); + ACE_Reactor::instance (reactor_ptr); + } +#endif + + Read_Handler::set_countdown (opt_nchildren); + + // Acceptor + ACE_DEBUG((LM_DEBUG, "Create an Acceptor\n")); + ACCEPTOR acceptor(ACE_Reactor::instance(), 0); + // The acceptor uses the global reactor and does not use select. + + acceptor.priority (ACE_Event_Handler::HI_PRIORITY); + ADDR server_addr; + + // Bind acceptor to any port and then find out what the port was. + ACE_DEBUG((LM_DEBUG, "Open the acceptor\n")); + if (acceptor.open ((const ADDR &) ACE_Addr::sap_any) == -1 + || acceptor.acceptor ().get_local_addr (server_addr) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) %p\n", "open"), -1); + + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) starting server at port %d\n", + server_addr.get_port_number ())); + + ADDR connection_addr (server_addr); + + int i; + +#if defined (ACE_HAS_THREADS) + for (i = 0; i < opt_nchildren; ++i) + { + if (ACE_Thread_Manager::instance ()->spawn + (ACE_THR_FUNC (client), + (void *) &connection_addr, + THR_NEW_LWP | THR_DETACHED) == -1) + ACE_ERROR ((LM_ERROR, "(%P|%t) %p\n%a", "thread create failed")); + } +#elif !defined (ACE_LACKS_FORK) + for (i = 0; i < opt_nchildren; ++i) + { + switch (ACE_OS::fork ("child")) + { + case -1: + ACE_ERROR ((LM_ERROR, "(%P|%t) %p\n%a", "fork failed")); + exit (-1); + /* NOTREACHED */ + case 0: + client (&connection_addr); + exit (0); + break; + /* NOTREACHED */ + default: + break; + /* NOTREACHED */ + } + } +#else + ACE_ERROR ((LM_ERROR, + "(%P|%t) only one thread may be run in a process on this platform\n%a", 1)); +#endif /* ACE_HAS_THREADS */ + + ACE_Time_Value tv (opt_max_duration); + + ACE_Reactor::instance()->register_handler + (&acceptor, ACE_Event_Handler::READ_MASK); + ACE_Reactor::instance()->run_event_loop (tv); + + if (Read_Handler::get_countdown () != 0) + { + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) running out of time, " + "probably due to failed connections.\n")); + } + + ACE_DEBUG ((LM_DEBUG, "(%P|%t) waiting for the children...\n")); + +#if defined (ACE_HAS_THREADS) + ACE_Thread_Manager::instance ()->wait (); +#elif !defined (ACE_WIN32) && !defined (VXWORKS) && !defined (ACE_PSOS) + for (i = 0; i < opt_nchildren; ++i) + { + pid_t pid = ACE_OS::wait(); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) child %d terminated\n", pid)); + } +#else + /* NOTREACHED */ + // We aborted on the previous #ifdef +#endif /* ACE_HAS_THREADS */ + + ACE_END_TEST; + return 0; +} + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) +template class ACE_Connector<Write_Handler, ACE_CLASSIX_CONNECTOR>; +template class ACE_Acceptor<Read_Handler, ACE_CLASSIX_ACCEPTOR>; +template class ACE_Svc_Handler<ACE_CLASSIX_STREAM, ACE_SYNCH>; +template class auto_ptr<ACE_Reactor>; +template class ACE_Auto_Basic_Ptr<ACE_Reactor>; +template class auto_ptr<ACE_Select_Reactor>; +template class ACE_Auto_Basic_Ptr<ACE_Select_Reactor>; +template class ACE_Map_Manager<ACE_HANDLE,ACE_Svc_Tuple<Write_Handler>*,ACE_SYNCH_RW_MUTEX>; +template class ACE_Map_Iterator_Base<ACE_HANDLE,ACE_Svc_Tuple<Write_Handler>*,ACE_SYNCH_RW_MUTEX>; +template class ACE_Map_Iterator<ACE_HANDLE,ACE_Svc_Tuple<Write_Handler>*,ACE_SYNCH_RW_MUTEX>; +template class ACE_Map_Reverse_Iterator<ACE_HANDLE,ACE_Svc_Tuple<Write_Handler>*,ACE_SYNCH_RW_MUTEX>; +template class ACE_Map_Entry<ACE_HANDLE,ACE_Svc_Tuple<Write_Handler>*>; +template class ACE_Svc_Tuple<Write_Handler>; +template class ACE_Atomic_Op<ACE_Thread_Mutex, int>; + +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +#pragma instantiate ACE_Connector<Write_Handler, ACE_CLASSIX_CONNECTOR> +#pragma instantiate ACE_Acceptor<Read_Handler, ACE_CLASSIX_ACCEPTOR> +#pragma instantiate ACE_Svc_Handler<ACE_CLASSIX_STREAM, ACE_SYNCH> +#pragma instantiate auto_ptr<ACE_Reactor> +#pragma instantiate ACE_Auto_Basic_Ptr<ACE_Reactor> +#pragma instantiate auto_ptr<ACE_Select_Reactor> +#pragma instantiate ACE_Auto_Basic_Ptr<ACE_Select_Reactor> +#pragma instantiate ACE_Map_Manager<ACE_HANDLE,ACE_Svc_Tuple<Write_Handler>*,ACE_SYNCH_RW_MUTEX> +#pragma instantiate ACE_Map_Iterator_Base<ACE_HANDLE,ACE_Svc_Tuple<Write_Handler>*,ACE_SYNCH_RW_MUTEX> +#pragma instantiate ACE_Map_Iterator<ACE_HANDLE,ACE_Svc_Tuple<Write_Handler>*,ACE_SYNCH_RW_MUTEX> +#pragma instantiate ACE_Map_Reverse_Iterator<ACE_HANDLE,ACE_Svc_Tuple<Write_Handler>*,ACE_SYNCH_RW_MUTEX> +#pragma instantiate ACE_Map_Entry<ACE_HANDLE,ACE_Svc_Tuple<Write_Handler>*> +#pragma instantiate ACE_Svc_Tuple<Write_Handler> +#pragma instantiate ACE_Atomic_Op<ACE_Thread_Mutex, int> +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/tests/CLASSIX/Con_Acc_Test.h b/tests/CLASSIX/Con_Acc_Test.h new file mode 100644 index 00000000000..290eb4c5f34 --- /dev/null +++ b/tests/CLASSIX/Con_Acc_Test.h @@ -0,0 +1,77 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// tests +// +// = FILENAME +// Priority_Reactor_Test.h +// +// = DESCRIPTION +// This class gets its own header file to work around AIX C++ +// compiler "features" related to template instantiation... It is +// only used by Priority_Reactor_Test.cpp. +// +// = AUTHOR +// Carlos O'Ryan +// +// ============================================================================ + +#ifndef ACE_TESTS_PRIORITY_REACTOR_TEST_H +#define ACE_TESTS_PRIORITY_REACTOR_TEST_H + +#include "ace/Service_Config.h" +#include "ace/SOCK_Stream.h" +#include "ace/Svc_Handler.h" +#include "ace/Synch_T.h" + +#define ACE_CLASSIX_STREAM ACE_CLASSIX_Stream, ACE_CLASSIX_Addr +#define ACE_CLASSIX_CONNECTOR ACE_CLASSIX_Connector, ACE_CLASSIX_Port +#define ACE_CLASSIX_ACCEPTOR ACE_CLASSIX_Acceptor, ACE_CLASSIX_Port + +class Read_Handler : public ACE_Svc_Handler<ACE_CLASSIX_STREAM, ACE_SYNCH> + // = TITLE + // A Svc_Handler with a priority twist. + // + // = DESCRIPTION + // This Svc_Handler receives the data sent by the childs or writer + // threads; each one sets it own priority to a new level, in a + // cyclic manner. The main point is test and exercise the + // priority dispatching features of ACE_Priority_Reactor. +{ +public: + static void set_countdown (int nchildren); + // Set the number of children or writer threads we will be running, + // when they are all gone we terminate the reactor loop. + + static int get_countdown (void); + // Get the number of children we are still waiting for. + + virtual int open (void *); + virtual int handle_input (ACE_HANDLE h); + // The Svc_Handler callbacks. + +private: + static ACE_Atomic_Op<ACE_Thread_Mutex, int> waiting_; + // How many writers are we waiting for. + + static ACE_Atomic_Op<ACE_Thread_Mutex, int> started_; + // How many readers have started. +}; + +class Write_Handler : public ACE_Svc_Handler<ACE_CLASSIX_STREAM, ACE_SYNCH> + // = TITLE + // A simple writer. + // + // = DESCRIPTION + // This Svc_Handler simply connects to a server and sends some + // output to it. Its purpose is to feed the test. +{ +public: + virtual int open (void *); + virtual int svc (void); +}; + +#endif /* ACE_TESTS_PRIORITY_REACTOR_TEST_H */ diff --git a/tests/CLASSIX/Group_Test.cpp b/tests/CLASSIX/Group_Test.cpp new file mode 100644 index 00000000000..73ba648d4a3 --- /dev/null +++ b/tests/CLASSIX/Group_Test.cpp @@ -0,0 +1,85 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// tests +// +// = FILENAME +// Group_Test.cpp +// +// = DESCRIPTION +// This is a test of the <IPP_CLASSIX_Group_*> class. +// +// = AUTHOR +// Wei Chiang +// +// ============================================================================ + +#include "tests/test_config.h" +#include "CLASSIX/Addr.h" +#include "CLASSIX/Group_Stamp.h" +#include "CLASSIX/Group_Dynamic.h" + + +int +main (int, char *[]) +{ + ACE_START_TEST ("Group_Test"); + + int stamp = 20; + /* ================================================================== */ + ACE_DEBUG((LM_INFO, "-----------group target-----------\n")); + + ACE_DEBUG((LM_INFO, "constrctor(Stamp)..................\n")); + ACE_CLASSIX_Group_Stamp t0(100); + t0.dump(); + + /* ================================================================== */ + ACE_DEBUG((LM_INFO, "-----------group target-----------\n")); + + ACE_DEBUG((LM_INFO, "constrctor(Stamp)..................\n")); + ACE_CLASSIX_Group_Stamp t1(stamp); + t1.dump(); + + /* ================================================================== */ + ACE_DEBUG((LM_INFO, "empty constrctor(Stamp) & set_group()\n")); + ACE_CLASSIX_Group_Stamp t2; + if (t2 == t1) + ACE_DEBUG((LM_ERROR, "t2 == t1, should be !=\n")); + t2.set_addr(&stamp); + t2.dump(); + if (t2 != t1) + ACE_DEBUG((LM_ERROR, "????t2 != t1, should be ==\n")); + + + /* ================================================================== */ + ACE_DEBUG((LM_INFO, "Constrctor(Dynamic) & set_group()\n")); + ACE_CLASSIX_Group_Dynamic t3; + t3.dump(); + + ACE_CLASSIX_Group_Stamp t4; + t4.set_addr(t2.get_addr(), t2.get_size()); + t4.dump(); + if (t4 == t2) + ACE_DEBUG((LM_ERROR, "????t4 == t2, should be !=\n")); + t4.set_addr(&stamp); + t4.dump(); + if (t4 != t2) + ACE_DEBUG((LM_ERROR, "????t4 != t2, should be ==\n")); + + ACE_CLASSIX_Group t5(t3.get_addr(), t3.get_size()); + t5.dump(); + if (t5 != t3) + ACE_DEBUG((LM_ERROR, "????t5 != t3, should be ==\n")); + + + if (t2 != t1) + ACE_DEBUG((LM_ERROR, "????t2 != t1, should be ==\n")); + + /* ================================================================== */ + ACE_END_TEST; + return 0; +} + diff --git a/tests/CLASSIX/Notify_Test.cpp b/tests/CLASSIX/Notify_Test.cpp new file mode 100644 index 00000000000..5db9285e256 --- /dev/null +++ b/tests/CLASSIX/Notify_Test.cpp @@ -0,0 +1,266 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// tests +// +// = FILENAME +// Notify_Test.cpp +// +// = DESCRIPTION +// Based on $ACE_ROOT/tests/Reactors_test.cpp +// +// This is a test that performs a torture test of multiple +// <ACE_Reactors> and <ACE_Tasks> in the same process. +// +// = NOTE +// Use ACE_Reactor and thus Chorus's socket sub-system, it behave +// quite stragnely including a printout such as +// "(15) task_9: !!!notify: Not a stream device" +// +// = AUTHOR +// Prashant Jain, Detlef Becker, and Douglas C. Schmidt +// +// ============================================================================ + +#include "test_config.h" +#include "ace/Synch.h" +#include "ace/Task.h" + +#include "CLASSIX/OS.h" +#include "CLASSIX/Reactor.h" + +#if defined (ACE_HAS_THREADS) + +ACE_Thread_Manager *tm; + +static const int MAX_TASKS = 20; + +class Test_Task : public ACE_Task<ACE_MT_SYNCH> + // = TITLE + // Exercise the tasks. +{ +public: + // = Initialization and termination methods. + Test_Task (void); + ~Test_Task (void); + + // = Task hooks. + virtual int open (void *args = 0); + virtual int close (u_long flags = 0); + virtual int svc (void); + + // = Event Handler hooks. + virtual int handle_input (ACE_HANDLE handle); + virtual int handle_close (ACE_HANDLE fd, + ACE_Reactor_Mask close_mask); + +private: + size_t handled_; + char name_[10]; + // Number of iterations handled. + + static int task_count_; + // Number of tasks running. +}; + +// Static data member initialization. +int Test_Task::task_count_ = 0; + +static ACE_Atomic_Op<ACE_Thread_Mutex, int> done_count = MAX_TASKS * 2; + +static ACE_Recursive_Thread_Mutex recursive_lock; + +Test_Task::Test_Task (void) + : handled_ (0) +{ + ACE_GUARD (ACE_Recursive_Thread_Mutex, ace_mon, recursive_lock); + + Test_Task::task_count_++; + + ACE_OS::sprintf(this->name_, "%s_%d", "task", Test_Task::task_count_); + ACE_DEBUG ((LM_DEBUG, + "(%t) TT+ %s\n", + this->name_)); +} + +Test_Task::~Test_Task (void) +{ + ACE_GUARD (ACE_Recursive_Thread_Mutex, ace_mon, recursive_lock); + + ACE_DEBUG ((LM_DEBUG, + "(%t) TT- %s: %d\n", + this->name_, Test_Task::task_count_)); + + ACE_ASSERT (Test_Task::task_count_ == 0); +} + +int +Test_Task::open (void *args) +{ + this->reactor ((ACE_Reactor *) args); + return this->activate (THR_NEW_LWP); +} + +int +Test_Task::close (u_long) +{ + ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, recursive_lock, -1); + + Test_Task::task_count_--; + ACE_DEBUG ((LM_DEBUG, + "(%t) close %s, task_count_ = %d\n", + this->name_, Test_Task::task_count_)); + + if (Test_Task::task_count_ < 0) + abort (); + + return 0; +} + +int +Test_Task::svc (void) +{ + ACE_DEBUG ((LM_DEBUG, "(%t) svc(%s)\n", this->name_)); + + for (size_t i = 0; i < ACE_MAX_ITERATIONS; i++) + { + ACE_OS::thr_yield (); + + // Only wait up to 10 milliseconds to notify the Reactor. + ACE_Time_Value timeout (0, 10 * 1000); + + if (this->reactor ()->notify (this, + ACE_Event_Handler::READ_MASK, + &timeout) == -1) + { + if (errno == ETIME) + ACE_DEBUG ((LM_DEBUG, "(%t) %p\n", "notify() timed out")); + else + ACE_ERROR_RETURN ((LM_ERROR, "(%t) %s: %p\n", this->name_, + "!!!notify"), -1); + } + } + + ACE_DEBUG ((LM_DEBUG, "(%t) end svc(%s)\n", this->name_)); + return 0; +} + +int +Test_Task::handle_close (ACE_HANDLE, ACE_Reactor_Mask) +{ + return 0; +} + +int +Test_Task::handle_input (ACE_HANDLE) +{ + this->handled_++; + + if (this->handled_ == ACE_MAX_ITERATIONS) + { + done_count--; + ACE_DEBUG ((LM_DEBUG, + "(%t) handle_input, handled_ = %d, done_count = %d\n", + this->handled_, done_count.value ())); + } + + ACE_OS::thr_yield (); + return -1; // this will trigger hnalde_close() be called +} + +static void * +worker (void *args) +{ + ACE_DEBUG((LM_DEBUG, "(%t) worker started\n")); + ACE_Reactor *reactor = (ACE_Reactor *) args; + + // Make this thread the owner of the Reactor's event loop. + reactor->owner (ACE_Thread::self ()); + + // Use a timeout to inform the Reactor when to shutdown. + ACE_Time_Value timeout (1); + + for (;;) + { + switch (reactor->handle_events (timeout)) + { + case -1: + ACE_ERROR_RETURN ((LM_ERROR, "(%t) %p\n", "reactor"), 0); + /* NOTREACHED */ + case 0: + ACE_ERROR_RETURN ((LM_ERROR, "(%t) Reactor shutdown\n"), 0); + /* NOTREACHED */ + default: + timeout.sec(1); + } + } + + ACE_NOTREACHED (return 0); +} + + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) +template class ACE_Atomic_Op<ACE_Thread_Mutex, int>; +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +#pragma instantiate ACE_Atomic_Op<ACE_Thread_Mutex, int> +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ + +#endif /* ACE_HAS_THREADS */ + +int +main (int, char *[]) +{ + ACE_START_TEST ("Notify_Test"); + + // initialize the singletons and environment + ACE_CLASSIX_OS classix; + +#if defined (ACE_HAS_THREADS) + ACE_ASSERT (ACE_LOG_MSG->op_status () != -1); + + tm = ACE_Thread_Manager::instance (); + + ACE_Reactor reactor; + ACE_ASSERT (ACE_LOG_MSG->op_status () != -1); + + Test_Task tt1[MAX_TASKS]; + Test_Task tt2[MAX_TASKS]; + + // Activate all of the Tasks. + + for (int i = 0; i < MAX_TASKS; i++) + { + tt1[i].open (ACE_Reactor::instance ()); +// tt2[i].open (&reactor); + tt2[i].open (ACE_Reactor::instance ()); + } + + // Spawn two threads each running a different reactor. + + if (ACE_Thread_Manager::instance ()->spawn + (ACE_THR_FUNC (worker), + (void *) ACE_Reactor::instance (), + THR_BOUND | THR_DETACHED) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "spawn"), -1); + +#if 0 + else if (ACE_Thread_Manager::instance ()->spawn + (ACE_THR_FUNC (worker), (void *) &reactor, + THR_BOUND | THR_DETACHED) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "spawn"), -1); +#endif + + if (ACE_Thread_Manager::instance ()->wait () == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "wait"), -1); + + ACE_DEBUG ((LM_DEBUG, "(%t) all threads are finished \n")); + +#else + ACE_ERROR ((LM_ERROR, "threads not supported on this platform\n")); +#endif /* ACE_HAS_THREADS */ + ACE_END_TEST; + return 0; +} diff --git a/tests/CLASSIX/OS.cpp b/tests/CLASSIX/OS.cpp new file mode 100644 index 00000000000..7327d4aae69 --- /dev/null +++ b/tests/CLASSIX/OS.cpp @@ -0,0 +1,62 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// tests +// +// = FILENAME +// CLASSIX_SOCK_Test.cpp +// +// = DESCRIPTION +// This is a test of the <IPP_CLASSIX_Addr> class. +// +// = AUTHOR +// Wei Chiang +// +// ============================================================================ + +#include "tests/test_config.h" +#include "wrapper/CLASSIX_Addr.h" + + +int +main (int, char *[]) +{ + ACE_START_TEST ("SOCK_Test"); + + IPP_CLASSIX_Addr a1; + ACE_DEBUG((LM_INFO, "Addr a1:")); + a1.dump(); + + KnUniqueId k2; + ::portCreate(K_MYACTOR, &k2); + int p2 = ::portLi(&k2); + IPP_CLASSIX_Addr a2(k2); + ACE_DEBUG((LM_INFO, "Addr a2(ipc port id = %d)\n", p2)); + a2.dump(); + + KnUniqueId k3; + ::portCreate(K_MYACTOR, &k3); + int p3 = ::portLi(&k3); + IPP_CLASSIX_Addr a3(p3); + ACE_DEBUG((LM_INFO, "Addr a3(ipc port id = %d)\n", p3)); + a3.dump(); + + IPP_CLASSIX_Addr a4(a1); + if (a4 == a1) + ACE_DEBUG((LM_INFO, "OK: Addr a4 == a1\n")); + else + ACE_ERROR((LM_ERROR, "Error: Addr a4 != a1\n")); + + if (a4 != a2) + ACE_DEBUG((LM_INFO, "OK: Addr a4 != a2\n")); + else + ACE_ERROR((LM_ERROR, "Error: Addr a4 == a2\n")); + + + ACE_END_TEST; + return 0; +} + diff --git a/tests/CLASSIX/OS_Test.cpp b/tests/CLASSIX/OS_Test.cpp new file mode 100644 index 00000000000..4af32e781f0 --- /dev/null +++ b/tests/CLASSIX/OS_Test.cpp @@ -0,0 +1,43 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// tests +// +// = FILENAME +// CLASSIX_OS_Test.cpp +// +// = DESCRIPTION +// This is a test of the <ACE_CLASSIX_OS> class. +// +// = AUTHOR +// Wei Chiang +// +// ============================================================================ + +#include "tests/test_config.h" +#include "CLASSIX/OS.h" + + +int +main (int, char *[]) +{ + ACE_START_TEST ("CLASSIX_OS_Test"); + + ACE_DEBUG((LM_INFO, "Empty Message\n")); + ACE_CLASSIX_Msg msg1; + msg1.dump(); + + char buf[] ="This is a test message"; + int size = sizeof (buf); + ACE_DEBUG((LM_INFO, "%s(size = %d)\n", buf, size)); + ACE_CLASSIX_Msg msg2(buf, size); + msg2.dump(); + + + ACE_END_TEST; + return 0; +} + diff --git a/tests/CLASSIX/README b/tests/CLASSIX/README new file mode 100644 index 00000000000..c630f42424d --- /dev/null +++ b/tests/CLASSIX/README @@ -0,0 +1,25 @@ +Addr_Test.cpp + tests ACE_CLASSIX_Addr class + +Group_Test.cpp + tests ACE_CLASSIX_Group class and its subclasses + +Reactor_Test.cpp + tests ACE_CLASSIX_Select_Reactor class + tests timeout handler mechanism + tests co-existance of ACE_Select_Reactor and ACE_CLASSIX_Select_Reactor classes + +Notify_Test.cpp + tests multithreading and sharing resources + tests notify handler mechanism + tests co-existance of ACE_Select_Reactor and ACE_CLASSIX_Select_Reactor classes.... + The number of threads seem to cause CLASSIX' socket subsystem +"over-stressed". Therefore, the tests has changed to use CLASSIX reactor only (see activating tasks in main()) + +Stream_Test.cpp + tests ACE_CLASSIX_Stream class + tests ipcReceive() read and ipcReceive() peek mechanism + +CLD_Connect_Test.cpp + tests ACE_CLASSIX_Connector, ACE_CLASSIX_Dgram_Mcast classes + diff --git a/tests/CLASSIX/Reactor_Test.cpp b/tests/CLASSIX/Reactor_Test.cpp new file mode 100644 index 00000000000..638a98a2fec --- /dev/null +++ b/tests/CLASSIX/Reactor_Test.cpp @@ -0,0 +1,150 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// tests +// +// = FILENAME +// Reactor_Test.cpp +// +// = DESCRIPTION +// This is a test of the <ACE_CLASSIX_Select_Reactor> class. +// based on $ACE_ROOT/tests/MT_Reactor_Timer_Test.cpp +// +// = AUTHOR +// Wei Chiang +// +// ============================================================================ + +#include "test_config.h" +#include "Reactor_Test.h" +#include "CLASSIX/Reactor.h" + + + +static ACE_Reactor *the_reactor; + +Time_Handler::Time_Handler (void) +{ + for (int i = 0; + i < Time_Handler::TIMER_SLOTS; + this->timer_id_[i++] = -1) + continue; +} + +// Set up initial timer conditions. + +void +Time_Handler::setup (void) +{ + this->timer_id_[1] = the_reactor->schedule_timer (this, + (const void *) 1, + ACE_Time_Value (5)); +} + + +// In the secondary thread, set a heartbeat timer to go off every +// second. The heartbeat checks the status of things to be sure +// they're being set and expired correctly. + +int +Time_Handler::svc (void) +{ + ACE_Time_Value backstop (30); + + this->timer_id_[2] = the_reactor->schedule_timer(this, + (const void *) 2, + ACE_Time_Value (3)); + this->my_reactor_.owner (ACE_OS::thr_self ()); + this->my_reactor_.schedule_timer (this, (const void *) 0, + ACE_Time_Value (1), + ACE_Time_Value (1)); + + while (!ACE_Reactor::event_loop_done()) + { + int result = this->my_reactor_.handle_events (backstop); + if (result == -1) + break; + ACE_Thread::yield(); + } + + ACE_DEBUG((LM_DEBUG, "(%T(%t) heartbeat's event loop ended\n")); + + return 0; +} + +int +Time_Handler::handle_timeout (const ACE_Time_Value &tv, + const void *arg) +{ + long time_tag = long (arg); + ACE_UNUSED_ARG(tv); + + if (time_tag == 0) + { // Heartbeat. + int i; + + ACE_DEBUG ((LM_DEBUG, + "%T (%t): heartbeat...\n")); + // See if all of the timers have fired. If so, leave the thread's + // reactor loop which will exit the thread and end the test. + + for (i = 0; i < Time_Handler::TIMER_SLOTS; i++) + if (this->timer_id_[i] != -1) + break; + + if (i == Time_Handler::TIMER_SLOTS) + { // All timers should be gone. + + // Cancel heartbeat. + ACE_ASSERT (this->my_reactor_.cancel_timer (this) == 1); + + // Shouldn't be any. + ACE_ASSERT (the_reactor->cancel_timer (this) == 0); + this->my_reactor_.end_event_loop (); + } + ACE_DEBUG ((LM_DEBUG, + "%T (%t): ...heartbeat\n")); + return 0; + } + + ACE_DEBUG ((LM_DEBUG, + "%T (%t): Timer #%d (id #%d) expired\n", + time_tag, + this->timer_id_[time_tag])); + + ACE_ASSERT (this->timer_id_[time_tag] != -1); + this->timer_id_[time_tag] = -1; + + return 0; +} + + +//===============================================================// + +int +main (int, char *[]) +{ + ACE_START_TEST ("Reactor_Test"); + + // CLASSIX environment initialization + ACE_CLASSIX_OS classix; + the_reactor = ACE_Reactor::instance(); + Time_Handler other_thread; + + + // Set up initial set of timers. + other_thread.setup (); + + other_thread.activate (THR_NEW_LWP | THR_JOINABLE); + the_reactor->run_event_loop (); + ACE_DEBUG((LM_DEBUG, "(%t) main thread's event loop ended\n")); + other_thread.wait (); + + + ACE_END_TEST; + return 0; +} + diff --git a/tests/CLASSIX/Reactor_Test.h b/tests/CLASSIX/Reactor_Test.h new file mode 100644 index 00000000000..11b19cb7df1 --- /dev/null +++ b/tests/CLASSIX/Reactor_Test.h @@ -0,0 +1,52 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// tests +// +// = FILENAME +// Reactor_Test.h +// +// = DESCRIPTION +// This file contains class definitions needed for template +// instantiation in the Reactor_Test.cpp file. +// Based on $ACE_ROOT/tests/MT_Reactor_Timer_Test.h +// +// = AUTHOR +// Wei Chiang +// +// ============================================================================ + +#if !defined (__CLASSIX_REACTOR_TEST_H) +#define __CLASSIX_REACTOR_TEST_H + +#include "ace/Reactor.h" +#include "ace/Task.h" + +class Time_Handler : public ACE_Task<ACE_SYNCH> +{ +public: + Time_Handler (void); + + void setup (void); + + virtual int svc (void); + // Run by a daemon thread to handle deferred processing. + + virtual int handle_timeout (const ACE_Time_Value &tv, + const void *arg); + +private: + enum + { + TIMER_SLOTS = 10 + }; + + long timer_id_[TIMER_SLOTS]; + int step_; + ACE_Reactor my_reactor_; +}; + +#endif /* __CLASSIX_REACTOR_TEST_H */ diff --git a/tests/CLASSIX/SOCK_Test.cpp b/tests/CLASSIX/SOCK_Test.cpp new file mode 100644 index 00000000000..1600eaca6a4 --- /dev/null +++ b/tests/CLASSIX/SOCK_Test.cpp @@ -0,0 +1,99 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// tests +// +// = FILENAME +// CLASSIX_SOCK_Test.cpp +// +// = DESCRIPTION +// This is a test of the <IPP_CLASSIX_Addr> class. +// +// = AUTHOR +// Wei Chiang +// +// ============================================================================ + +#include "tests/test_config.h" +#include "wrapper/CLASSIX_Addr.h" +#include "wrapper/CLASSIX_SAP.h" + +class testSap : public ACE_CLASSIX_SAP +{ +public: + testSap(): ACE_CLASSIX_SAP() {} + testSap(const ACE_Addr& theAddr) : ACE_CLASSIX_SAP(theAddr) {} + + ~testSap() {ACE_DEBUG((LM_DEBUG, "~testSap()\n"));} +}; + +int +main (int, char *[]) +{ + ACE_START_TEST ("SOCK_Test"); + + /* ================================================================== */ + ACE_DEBUG((LM_INFO, "... test virtual destructor...\n")); + testSap *n1 = new testSap(); + ACE_CLASSIX_SAP *n2 = n1; + delete n2; + + /* ================================================================== */ + ACE_DEBUG((LM_INFO, "... ACE_CLASSIX_Addr...\n")); + ACE_CLASSIX_Addr a1; + a1.set(); + ACE_DEBUG((LM_INFO, "Addr a1:")); + a1.dump(); + + KnUniqueId k2; + ::portCreate(K_MYACTOR, &k2); + int p2 = ::portLi(&k2); + ACE_CLASSIX_Addr a2(k2); + ACE_DEBUG((LM_INFO, "Addr a2(ipc port id = %d)\n", p2)); + a2.dump(); + + KnUniqueId k3; + ::portCreate(K_MYACTOR, &k3); + int p3 = ::portLi(&k3); + ACE_CLASSIX_Addr a3(p3); + ACE_DEBUG((LM_INFO, "Addr a3(ipc port id = %d)\n", p3)); + a3.dump(); + + ACE_CLASSIX_Addr a4(a1); + if (a4 == a1) + ACE_DEBUG((LM_INFO, "OK: Addr a4 == a1\n")); + else + ACE_ERROR((LM_ERROR, "Error: Addr a4 != a1\n")); + + if (a4 != a2) + ACE_DEBUG((LM_INFO, "OK: Addr a4 != a2\n")); + else + ACE_ERROR((LM_ERROR, "Error: Addr a4 == a2\n")); + + /* ================================================================== */ + + ACE_DEBUG((LM_INFO, "\n... ACE_CLASSIX...\n")); + testSap sap1; + sap1.set_local_addr(a1); + ACE_CLASSIX_Addr b1; + sap1.get_local_addr(b1); + if (b1 != a1) + ACE_ERROR((LM_ERROR, "Error: sap address")); + sap1.dump(); + + + testSap sap2(a2); + ACE_CLASSIX_Addr b2; + sap2.get_local_addr(b2); + if (b2 != a2) + ACE_ERROR((LM_ERROR, "Error: sap address")); + sap2.dump(); + + + ACE_END_TEST; + return 0; +} + diff --git a/tests/CLASSIX/Select_Reactor_Test.cpp b/tests/CLASSIX/Select_Reactor_Test.cpp new file mode 100644 index 00000000000..c39f9e425ca --- /dev/null +++ b/tests/CLASSIX/Select_Reactor_Test.cpp @@ -0,0 +1,166 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// tests +// +// = FILENAME +// MT_Reactor_Timer_Test.cpp +// +// = DESCRIPTION +// This is a simple test that illustrates the timer mechanism of +// the reactor scheduling timers, handling expired timers and +// cancelling scheduled timers from multiple threads. +// No command line arguments are needed to run the test. +// +// = AUTHOR +// Steve Huston +// +// ============================================================================ + +#include "test_config.h" +#include "Select_Reactor_Test.h" + +#if defined (ACE_HAS_THREADS) + +static ACE_Reactor *the_reactor; + +Time_Handler::Time_Handler (void) +{ + for (int i = 0; + i < Time_Handler::TIMER_SLOTS; + this->timer_id_[i++] = -1) + continue; +} + +// Set up initial timer conditions. + +void +Time_Handler::setup (void) +{ + this->timer_id_[1] = the_reactor->schedule_timer (this, + (const void *) 1, + ACE_Time_Value (5)); +} + + +// In the secondary thread, set a heartbeat timer to go off every +// second. The heartbeat checks the status of things to be sure +// they're being set and expired correctly. + +int +Time_Handler::svc (void) +{ + ACE_Time_Value backstop (30); + + this->timer_id_[2] = the_reactor->schedule_timer(this, + (const void *) 2, + ACE_Time_Value (3)); + ACE_thread_t tid; + this->my_reactor_.owner(&tid); + ACE_DEBUG((LM_DEBUG, "((%t) hearbeat reactor's owner was %d\n", tid)); + this->my_reactor_.owner (ACE_Thread::self ()); + this->my_reactor_.owner(&tid); + ACE_DEBUG((LM_DEBUG, "((%t) hearbeat reactor's owner is %d\n", tid)); + + long id = this->my_reactor_.schedule_timer (this, (const void *) 0, + ACE_Time_Value (1), + ACE_Time_Value (1)); + this->my_reactor_.owner(&tid); + + while (!ACE_Reactor::event_loop_done()) + { + int result = this->my_reactor_.handle_events (backstop); + if (result == -1) + break; + } + + ACE_DEBUG((LM_DEBUG, "(%T(%t) exit from heartbeat\n")); + return 0; +} + +int +Time_Handler::handle_timeout (const ACE_Time_Value &tv, + const void *arg) +{ + long time_tag = long (arg); + ACE_UNUSED_ARG(tv); + + if (time_tag == 0) + { // Heartbeat. + int i; + + ACE_DEBUG ((LM_DEBUG, + "%T (%t): heartbeat\n")); + // See if all of the timers have fired. If so, leave the thread's + // reactor loop which will exit the thread and end the test. + + for (i = 0; i < Time_Handler::TIMER_SLOTS; i++) + if (this->timer_id_[i] != -1) + break; + + ACE_DEBUG ((LM_DEBUG, + "%T (%t): heartbeat done: time slot = %d\n", i)); + if (i == Time_Handler::TIMER_SLOTS) + { // All timers should be gone. + + // Cancel heartbeat. + ACE_ASSERT (this->my_reactor_.cancel_timer (this) == 1); + + // Shouldn't be any. + ACE_ASSERT (the_reactor->cancel_timer (this) == 0); + this->my_reactor_.end_event_loop (); + ACE_DEBUG ((LM_DEBUG, + "%T (%t): event loop ended\n")); + } + return 0; + } + + ACE_DEBUG ((LM_DEBUG, + "%T (%t): Timer #%d (id #%d) expired\n", + time_tag, + this->timer_id_[time_tag])); + + ACE_ASSERT (this->timer_id_[time_tag] != -1); + this->timer_id_[time_tag] = -1; + + return 0; +} + +#endif /* ACE_HAS_THREADS */ + + +int +main (int, char *[]) +{ + ACE_START_TEST ("Select_Reactor_Test"); + +#if defined (ACE_HAS_THREADS) + + the_reactor = ACE_Reactor::instance (); + Time_Handler other_thread; + + + // Set up initial set of timers. + other_thread.setup (); + + #if 0 + the_reactor->schedule_timer (&other_thread, + (const void *) 1, + ACE_Time_Value (5)); + #endif /* 0 */ + + other_thread.activate (THR_NEW_LWP | THR_JOINABLE); + the_reactor->run_event_loop (); + ACE_DEBUG ((LM_DEBUG, + "%T (%t): waiting for thread to exit\n")); + other_thread.wait (); +#else + ACE_ERROR ((LM_ERROR, "threads not supported on this platform\n")); +#endif /* ACE_HAS_THREADS */ + + ACE_END_TEST; + return 0; +} diff --git a/tests/CLASSIX/Select_Reactor_Test.h b/tests/CLASSIX/Select_Reactor_Test.h new file mode 100644 index 00000000000..7c663b59ab5 --- /dev/null +++ b/tests/CLASSIX/Select_Reactor_Test.h @@ -0,0 +1,51 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// tests +// +// = FILENAME +// MT_Reactor_Timer_Test.h +// +// = DESCRIPTION +// This file contains class definitions needed for template +// instantiation in the MT_Reactor_Timer_Test.cpp file. +// +// = AUTHOR +// Steve Huston +// +// ============================================================================ + +#if !defined (__MT_REACTOR_TIMER_TEST_H) +#define __MT_REACTOR_TIMER_TEST_H + +#include "ace/Reactor.h" +#include "ace/Task.h" + +class Time_Handler : public ACE_Task<ACE_SYNCH> +{ +public: + Time_Handler (void); + + void setup (void); + + virtual int svc (void); + // Run by a daemon thread to handle deferred processing. + + virtual int handle_timeout (const ACE_Time_Value &tv, + const void *arg); + +private: + enum + { + TIMER_SLOTS = 10 + }; + + long timer_id_[TIMER_SLOTS]; + int step_; + ACE_Reactor my_reactor_; +}; + +#endif /* __MT_REACTOR_TIMER_TEST_H */ diff --git a/tests/CLASSIX/Stream_Test.cpp b/tests/CLASSIX/Stream_Test.cpp new file mode 100644 index 00000000000..40c13485c27 --- /dev/null +++ b/tests/CLASSIX/Stream_Test.cpp @@ -0,0 +1,110 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// tests +// +// = FILENAME +// Stream_Test.cpp +// +// = DESCRIPTION +// This is a test of the <IPP_CLASSIX_Addr> class. +// +// = AUTHOR +// Wei Chiang +// +// ============================================================================ + +#include "tests/test_config.h" +#include "CLASSIX/Stream.h" + +#define RCV_DELAY 1000 /* We should NOT wait in ipcReceive */ + +static char sndBody[] = "The sea is calm, the tide is full ...\n"; +static char rcvAnnex[K_CMSGANNEXSIZE]; +static char rcvBody[1000]; + +int +main (int, char *[]) +{ + ACE_START_TEST ("Stream_Test"); + + /* ================================================================== */ + ACE_CLASSIX_Port_Core remote_port; + + // Sender's socket + // Use my default port as the sending address + ACE_CLASSIX_Stream send(remote_port); + + ACE_CLASSIX_Stream rcv(send.local_sap().get_addr(), + ACE_CLASSIX_Port(remote_port)); + // make the rcv's port be one of the multiple receive ports + if (rcv.selectable() < 0) + ACE_DEBUG((LM_DEBUG, "failed to make the port selectable\n")); + + send.open_writer(); + + ACE_DEBUG((LM_DEBUG, "send and block on receive....\n")); + if (send.send_n(&sndBody[0], sizeof(sndBody)) == sizeof(sndBody)) + { + // Receiver's Socket + int rslt = rcv.ipcRecv(rcvBody, 1000); + if (rslt == sizeof (sndBody)) + ACE_DEBUG((LM_DEBUG, "received %s\n", rcvBody)); + else + ACE_DEBUG((LM_ERROR, "???? Error in ipcReceive():%d\n", rslt)); + } + else + { + ACE_ERROR((LM_ERROR, "(%t)|%p\n", "???? Error in send_n()\n")); + } + + ACE_DEBUG((LM_DEBUG, "send, peek then block on receive....\n")); + if (send.send_n(&sndBody[0], sizeof(sndBody)) == sizeof(sndBody)) + { + // Receiver's Socket + // int rslt = rcv.recv(rcvBody, 1000, MSG_PEEK); + // Equivalent to rcv.peek() + int rslt = rcv.peek(); + if (rslt < 0) + ACE_DEBUG((LM_ERROR, "???? Error while peeking :%d\n", rslt)); + else + { + char *buf = new char(rslt); + if (int n = rcv.recv(buf, rslt) == rslt) + ACE_DEBUG((LM_DEBUG, "received %s\n", buf)); + else + ACE_DEBUG((LM_ERROR, "???? Error in ipcReceive(): %d\n", n)); + delete buf; + } + } + else + { + ACE_DEBUG((LM_ERROR, "???? Error in send_n()\n")); + } + + ACE_DEBUG((LM_DEBUG, "test recv_n()....\n")); + if (send.send_n(&sndBody[0], sizeof(sndBody)) == sizeof(sndBody) && + send.send_n(&sndBody[0], sizeof(sndBody)) == sizeof(sndBody)) + { + // Receiver's Socket + + int rslt = rcv.ipcRecv_n(rcvBody, 2*sizeof (sndBody) - 10); + if (rslt == (2 * sizeof (sndBody) -10)) + { + rcvBody[rslt] = '\0'; // For %s printout format + ACE_DEBUG((LM_DEBUG, "received %d byte: %s + %s\n", rslt, + rcvBody, rcvBody + sizeof(sndBody))); + } + else + ACE_DEBUG((LM_ERROR, "???(%P|%t) %p\n", "ipcRecv_n()")); + } + else + ACE_DEBUG((LM_ERROR, "???(%P|%t) %p\n", "ipcRecv_n()")); + + ACE_END_TEST; + return 0; +} + diff --git a/tests/CLASSIX/test_config.h b/tests/CLASSIX/test_config.h new file mode 100644 index 00000000000..a1988fec7b9 --- /dev/null +++ b/tests/CLASSIX/test_config.h @@ -0,0 +1,272 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// = FILENAME +// test_config.h +// +// = AUTHOR +// Prashant Jain <pjain@cs.wustl.edu>, Tim Harrison +// <harrison@cs.wustl.edu>, and David Levine <levine@cs.wustl.edu> +// +// ============================================================================ + +#if !defined (ACE_TEST_CONFIG_H) +#define ACE_TEST_CONFIG_H + +// This first #undef protects against command-line definitions. +#undef ACE_NDEBUG +#include "ace/OS.h" +#include "ace/streams.h" + +// The second #undef protects against being reset in a config.h file. +#undef ACE_NDEBUG + +#if !defined (ACE_HAS_TEMPLATE_SPECIALIZATION) +class KEY +// ============================================================================ +// = TITLE +// Define a key for use with the Map_Manager_Test. +// +// = DESCRIPTION +// This class is put into the test_config.h header file to work +// around AIX C++ compiler "features" related to template +// instantiation... It is only used by Map_Manager_Test.cpp +// ============================================================================ +{ +public: + KEY (size_t v = 0): value_ (v) + { } + + size_t hash (void) const { return this->value_; } + operator size_t () const { return this->value_; } + +private: + size_t value_; +}; +#else +typedef size_t KEY; +#endif /* ACE_HAS_TEMPLATE_SPECIALIZATION */ + +#if defined (ACE_WIN32) + +#define ACE_DEFAULT_TEST_FILE_A "C:\\temp\\ace_test_file" +#define ACE_TEMP_FILE_NAME_A "C:\\temp\\ace_temp_file" +#define ACE_LOG_DIRECTORY_A "C:\\temp\\log\\" +#define MAKE_PIPE_NAME_A(X) "\\\\.\\pipe\\"#X + +#define ACE_DEFAULT_TEST_FILE_W L"C:\\temp\\ace_test_file" +#define ACE_TEMP_FILE_NAME_W L"C:\\temp\\ace_temp_file" +#define ACE_LOG_DIRECTORY_W L"C:\\temp\\log\\" +#define MAKE_PIPE_NAME_W(X) L"\\\\.\\pipe\\"#X + +#else + +#define ACE_DEFAULT_TEST_FILE_A "/tmp/ace_test_file" +#define ACE_TEMP_FILE_NAME_A "/tmp/ace_temp_file" +#define ACE_LOG_DIRECTORY_A "log/" +#define MAKE_PIPE_NAME_A(X) X + +#if defined (ACE_HAS_UNICODE) +#define ACE_DEFAULT_TEST_FILE_W L"/tmp/ace_test_file" +#define ACE_TEMP_FILE_NAME_W L"/tmp/ace_temp_file" +#define ACE_LOG_DIRECTORY_W L"log/" +#define MAKE_PIPE_NAME_W(X) L##X +#else +#define ACE_DEFAULT_TEST_FILE_W "/tmp/ace_test_file" +#define ACE_TEMP_FILE_NAME_W "/tmp/ace_temp_file" +#define ACE_LOG_DIRECTORY_W "log/" +#define MAKE_PIPE_NAME_W(X) X +#endif /* ACE_HAS_UNICODE */ + +#endif /* ACE_WIN32 */ + +#if defined (UNICODE) +#define ACE_DEFAULT_TEST_FILE ACE_DEFAULT_TEST_FILE_W +#define ACE_TEMP_FILE_NAME ACE_TEMP_FILE_NAME_W +#define ACE_LOG_DIRECTORY ACE_LOG_DIRECTORY_W +#define MAKE_PIPE_NAME MAKE_PIPE_NAME_W +#else +#define ACE_DEFAULT_TEST_FILE ACE_DEFAULT_TEST_FILE_A +#define ACE_TEMP_FILE_NAME ACE_TEMP_FILE_NAME_A +#define ACE_LOG_DIRECTORY ACE_LOG_DIRECTORY_A +#define MAKE_PIPE_NAME MAKE_PIPE_NAME_A +#endif /* UNICODE */ + +#define ACE_START_TEST(NAME) \ + const char *program = NAME; \ + ACE_LOG_MSG->open (program, ACE_Log_Msg::OSTREAM); \ + if (ace_file_stream.set_output (program) != 0) \ + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "set_output failed"), -1); \ + ACE_DEBUG ((LM_DEBUG, "(%P|%t) starting %s test at %D\n", program)); + +#define ACE_END_TEST \ + ACE_DEBUG ((LM_DEBUG, "(%P|%t) Ending %s test at %D\n", program)); \ + ace_file_stream.close () + +#define ACE_APPEND_LOG(NAME) \ + const char *program = NAME; \ + ACE_LOG_MSG->open (program, ACE_Log_Msg::OSTREAM); \ + ace_file_stream.close (); \ + if (ace_file_stream.set_output (program, 1) != 0) \ + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "set_output failed"), -1); \ + ACE_DEBUG ((LM_DEBUG, "(%P|%t) Starting %s test at %D\n", program)); + +#define ACE_END_LOG \ + ACE_DEBUG ((LM_DEBUG, "(%P|%t) Ending %s test at %D\n\n", program)); \ + ace_file_stream.close (); + +#if defined (VXWORKS) + // This is the only way I could figure out to avoid an error + // about attempting to unlink a non-existant file. +#define ACE_INIT_LOG(NAME) \ + char temp[MAXPATHLEN]; \ + ACE_OS::sprintf (temp, "%s%s%s", \ + ACE_LOG_DIRECTORY_A, \ + ACE::basename (NAME, ACE_DIRECTORY_SEPARATOR_CHAR_A), \ + ".log"); \ + ACE_DEBUG ((LM_DEBUG, "(%P|%t) Deleting old log file %s (if any)\n\n", temp)); \ + int fd_init_log; \ + if ((fd_init_log = ACE_OS::open (temp, \ + O_WRONLY | O_CREAT, 0x644)) != ERROR) \ + { \ + ACE_OS::close (fd_init_log); \ + ACE_OS::unlink (temp); \ + } +#else /* ! VXWORKS */ +#define ACE_INIT_LOG(NAME) \ + char temp[MAXPATHLEN]; \ + ACE_OS::sprintf (temp, "%s%s%s", \ + ACE_LOG_DIRECTORY_A, \ + ACE::basename (NAME, ACE_DIRECTORY_SEPARATOR_CHAR_A), \ + ".log"); \ + ACE_DEBUG ((LM_DEBUG, "(%P|%t) Deleting old log file %s (if any)\n\n", temp)); \ + ACE_OS::unlink (temp); +#endif /* ! VXWORKS */ + +const size_t ACE_NS_MAX_ENTRIES = 1000; +const size_t ACE_DEFAULT_USECS = 1000; +const size_t ACE_MAX_TIMERS = 4; +const size_t ACE_MAX_THREADS = 4; +const size_t ACE_MAX_DELAY = 10; +const size_t ACE_MAX_INTERVAL = 0; +const size_t ACE_MAX_ITERATIONS = 10; +const size_t ACE_MAX_PROCESSES = 10; +const size_t ACE_MAX_CLIENTS = 30; + +char ACE_ALPHABET[] = "abcdefghijklmnopqrstuvwxyz"; + +class ACE_Test_Output +{ +public: + ACE_Test_Output (void); + ~ACE_Test_Output (void); + int set_output (const char *filename, int append = 0); + ofstream *output_file (void); + void close (void); + +private: + ofstream output_file_; +}; + +static ACE_Test_Output ace_file_stream; + +ACE_Test_Output::ACE_Test_Output (void) +{ +} + +ACE_Test_Output::~ACE_Test_Output (void) +{ +} + +int +ACE_Test_Output::set_output (const char *filename, int append) +{ + char temp[MAXPATHLEN]; + // Ignore the error value since the directory may already exist. + + char *test_dir = ACE_OS::getenv ("ACE_TEST_DIR"); + + if (test_dir == 0) + test_dir = ""; + + ACE_OS::sprintf (temp, + "%s%s%s%s", + test_dir, + ACE_LOG_DIRECTORY_A, + ACE::basename (filename, ACE_DIRECTORY_SEPARATOR_CHAR_A), + ".log"); + +#if defined (VXWORKS) + // This is the only way I could figure out to avoid a console warning + // about opening an existing file (w/o O_CREAT), or attempting to unlink + // a non-existant one. + int fd; + if ((fd = ACE_OS::open (temp, O_WRONLY | O_CREAT, 0x644)) != ERROR) + { + ACE_OS::close (fd); + ACE_OS::unlink (temp); + } +#else /* ! VXWORKS */ + // This doesn't seem to work on VxWorks if the directory doesn't + // exist: it creates a plain file instead of a directory. If the + // directory does exist, it causes a wierd console error message + // about "cat: input error on standard input: Is a directory". So, + // VxWorks users must create the directory manually. + ACE_OS::mkdir (ACE_LOG_DIRECTORY_A); +#endif /* ! VXWORKS */ + + int flags = ios::out; + if (append) + flags |= ios::app; + else + flags |= ios::trunc; + + this->output_file_.open (temp, flags); + if (this->output_file_.bad ()) + { + return -1; + } + + ACE_LOG_MSG->msg_ostream (ace_file_stream.output_file ()); + ACE_LOG_MSG->clr_flags (ACE_Log_Msg::STDERR | ACE_Log_Msg::LOGGER ); + ACE_LOG_MSG->set_flags (ACE_Log_Msg::OSTREAM); + + return 0; +} + +ofstream * +ACE_Test_Output::output_file (void) +{ + return &this->output_file_; +} + +void +ACE_Test_Output::close (void) +{ + this->output_file_.flush (); + this->output_file_.close (); +} + +void +randomize (int array[], size_t size) +{ + size_t i; + + for (i = 0; i < size; i++) + array [i] = i; + + ACE_OS::srand (ACE_OS::time (0L)); + + // Generate an array of random numbers from 0 .. size - 1. + + for (i = 0; i < size; i++) + { + int index = ACE_OS::rand() % size--; + int temp = array [index]; + array [index] = array [size]; + array [size] = temp; + } +} + +#endif /* ACE_TEST_CONFIG_H */ |