diff options
Diffstat (limited to 'ACE/protocols/tests/HTBP')
25 files changed, 2599 insertions, 0 deletions
diff --git a/ACE/protocols/tests/HTBP/HTBP_Config.conf b/ACE/protocols/tests/HTBP/HTBP_Config.conf new file mode 100644 index 00000000000..49dfd238ec3 --- /dev/null +++ b/ACE/protocols/tests/HTBP/HTBP_Config.conf @@ -0,0 +1,4 @@ +[htbp] +proxy_port=3128 +proxy_host=rtai.ociweb.com +htid_url=http://rtai.ociweb.com/cgi-bin/HTIOP_ID_Generator.cgi diff --git a/ACE/protocols/tests/HTBP/Makefile.am b/ACE/protocols/tests/HTBP/Makefile.am new file mode 100644 index 00000000000..d38309ca6a4 --- /dev/null +++ b/ACE/protocols/tests/HTBP/Makefile.am @@ -0,0 +1,16 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ./bin/mwc.pl -type automake -noreldefs ACE.mwc + +SUBDIRS = \ + Reactor_Tests \ + Send_Large_Msg \ + Send_Recv_Tests \ + ping + diff --git a/ACE/protocols/tests/HTBP/README b/ACE/protocols/tests/HTBP/README new file mode 100644 index 00000000000..65a2bde0320 --- /dev/null +++ b/ACE/protocols/tests/HTBP/README @@ -0,0 +1,16 @@ +$Id$ + +Test cases for the HTTP Tunneling Bidirectional Protocol. For more +information on the protocol itself, refer to ace/HTBP/README. These +tests are adaptations of essential ACE SOCK tests, with the minimal +changes to support using HTBP rather than SOCK. + +Contained in this directory: + +HTBP_Config.conf A sample configuration file. This file is site + specific, and must be editted before use. +ping This test is shows the most basic connection + establishment with one request and reply. +Reactor_Tests A test to show use through the reactor. +Send_Large_Msg A test for sending large messages +Send_Recv_Tests A test for a variety of message sending methods. diff --git a/ACE/protocols/tests/HTBP/Reactor_Tests/Makefile.am b/ACE/protocols/tests/HTBP/Reactor_Tests/Makefile.am new file mode 100644 index 00000000000..153e1206bb1 --- /dev/null +++ b/ACE/protocols/tests/HTBP/Reactor_Tests/Makefile.am @@ -0,0 +1,64 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ./bin/mwc.pl -type automake -noreldefs ACE.mwc + +ACE_BUILDDIR = $(top_builddir) +ACE_ROOT = $(top_srcdir) + +noinst_PROGRAMS = + +## Makefile.Reactor_Tests_Client.am + +if !BUILD_ACE_FOR_TAO + +noinst_PROGRAMS += client + +client_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(ACE_ROOT)/protocols + +client_SOURCES = \ + client.cpp \ + test_config.h + +client_LDADD = \ + $(ACE_BUILDDIR)/protocols/ace/HTBP/libACE_HTBP.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_ACE_FOR_TAO + +## Makefile.Reactor_Tests_Server.am + +if !BUILD_ACE_FOR_TAO + +noinst_PROGRAMS += server + +server_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(ACE_ROOT)/protocols + +server_SOURCES = \ + server.cpp \ + test_config.h + +server_LDADD = \ + $(ACE_BUILDDIR)/protocols/ace/HTBP/libACE_HTBP.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_ACE_FOR_TAO + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/ACE/protocols/tests/HTBP/Reactor_Tests/Reactor_Tests.mpc b/ACE/protocols/tests/HTBP/Reactor_Tests/Reactor_Tests.mpc new file mode 100755 index 00000000000..61e59146a93 --- /dev/null +++ b/ACE/protocols/tests/HTBP/Reactor_Tests/Reactor_Tests.mpc @@ -0,0 +1,19 @@ +// -*- MPC -*- +// +// $Id$ + +project(*Server): aceexe, htbp { + exename = server + + Source_Files { + server.cpp + } +} + +project(*Client): aceexe, htbp { + exename = client + + Source_Files { + client.cpp + } +} diff --git a/ACE/protocols/tests/HTBP/Reactor_Tests/client.cpp b/ACE/protocols/tests/HTBP/Reactor_Tests/client.cpp new file mode 100644 index 00000000000..9d4dffe0ee9 --- /dev/null +++ b/ACE/protocols/tests/HTBP/Reactor_Tests/client.cpp @@ -0,0 +1,201 @@ +/** + * client for a reactor based connection establishment test using HTBP + * + * $Id$ + */ + +#include "ace/Log_Msg.h" +#include "ace/Get_Opt.h" + +#include "ace/HTBP/HTBP_Session.h" +#include "ace/HTBP/HTBP_Stream.h" +#include "ace/HTBP/HTBP_Addr.h" +#include "ace/HTBP/HTBP_ID_Requestor.h" +#include "ace/HTBP/HTBP_Environment.h" + +const ACE_TCHAR * remote_host = 0; +const ACE_TCHAR * config_file = 0; +unsigned remote_port = 8088; + +int +parse_args (int argc, ACE_TCHAR *argv[]) +{ + ACE_Get_Opt get_opts (argc, argv, ACE_TEXT("p:h:c:")); + int c; + + while ((c = get_opts ()) != -1) + switch (c) + { + case 'p': + remote_port = static_cast<unsigned>(ACE_OS::atoi (get_opts.opt_arg())); + break; + case 'h': + remote_host = get_opts.opt_arg (); + break; + case 'c': + config_file = get_opts.opt_arg (); + break; + case '?': + default: + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("usage: %s ") + ACE_TEXT ("-h remote_host ") + ACE_TEXT ("-p remote_port ") + ACE_TEXT ("-c config_file ") + ACE_TEXT ("\n"), + argv [0]), + -1); + } + // Indicates sucessful parsing of the command line + return 0; +} + +int +ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + + ACE_OS::socket_init (ACE_WSOCK_VERSION); + + if (parse_args(argc, argv) != 0) + return 1; + if (remote_host == 0) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("Client: No remote host specified\n")),1); + + ACE::HTBP::Environment env; + if (config_file != 0) + env.import_config (config_file); + + ACE::HTBP::ID_Requestor req (&env); + ACE::HTBP::Addr local (ACE_TEXT_ALWAYS_CHAR(req.get_HTID())); + + unsigned proxy_port = 0; + ACE_TString proxy_host; + + if (env.get_proxy_port(proxy_port) != 0 || + env.get_proxy_host(proxy_host) != 0) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Client: ") + ACE_TEXT("no proxy address in ") + ACE_TEXT("config, using direct connect\n"))); + proxy_port = remote_port; + proxy_host = remote_host; + } + + ACE_INET_Addr proxy (proxy_port, proxy_host.c_str ()); + ACE::HTBP::Addr remote (remote_port, ACE_TEXT_ALWAYS_CHAR (remote_host)); + + ACE_TCHAR local_s[512], remote_s[512], proxy_s[512]; + remote.addr_to_string (remote_s, 512); + local.addr_to_string (local_s, 512); + proxy.addr_to_string (proxy_s, 512); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Client starting session for ") + ACE_TEXT ("remote %s, local %s, proxy %s\n"), + remote_s, + local_s, + proxy_s)); + ACE::HTBP::Session session (remote, + local, + ACE::HTBP::Session::next_session_id(), + &proxy); + ACE::HTBP::Stream stream (&session); + + char buffer[1000]; + ssize_t n = 0; + int retrycount = 10; + for (int i = 0; i < 3; i++) + { + ACE::HTBP::Channel *ch = session.outbound(); + ACE_OS::sprintf (buffer,"Do you hear me? %d",i); + n = stream.send (buffer,ACE_OS::strlen(buffer)+1); + if (n == -1) + ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT("%p\n"), + ACE_TEXT("stream send")),-1); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Client: ") + ACE_TEXT("send returned %d\n"),n)); + + retrycount = 10; + while ((n = ch->recv_ack()) == -1 + && (errno == EWOULDBLOCK || errno == ETIME) + && retrycount > 0) + { + retrycount--; + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Client: ") + ACE_TEXT("waiting for ack, %d tries left\n"), + retrycount)); + ACE_OS::sleep (1); + } + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Client: ") + ACE_TEXT("After wait for ack, n = %d, retry = %d\n"), + n,retrycount,errno)); + + retrycount = 10; + while ((n = stream.recv(buffer,1000)) == -1 + && (errno == EWOULDBLOCK || errno == ETIME) + && retrycount > 0) + { + retrycount--; + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Client: ") + ACE_TEXT("waiting for inbound data, %d tries left\n"), + retrycount)); + ACE_OS::sleep(1); + } + if (retrycount == 0 || n < 0) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Client: ") + ACE_TEXT("bailing after wait, %p\n"), + ACE_TEXT("recv"))); + break; + } + + buffer[n] = 0; + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Client: ") + ACE_TEXT("Got: \"%s\"\n"), + buffer)); + } + ACE::HTBP::Channel *ch = session.outbound(); + if (ch == 0) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("(%P|%t) Client: ") + ACE_TEXT("session's outbound channel is null!\n")),1); + n = stream.send ("goodbye",7); + if (n == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("(%P|%t) Client: ") + ACE_TEXT("%p\n"), + ACE_TEXT("stream send")),-1); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Client: ") + ACE_TEXT("send returned %d\n"),n)); + + retrycount = 10; + while (ch && + (n = ch->recv_ack()) == -1 + && (errno == EWOULDBLOCK || errno == ETIME) + && retrycount > 0) + { + retrycount--; + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Client: ") + ACE_TEXT("waiting for ack, %d tries left\n"), + retrycount)); + ACE_OS::sleep (1); + } + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Client: ") + ACE_TEXT("After wait for ack, n = %d, retry = %d\n"), + n,retrycount,errno)); + + return 0; +} diff --git a/ACE/protocols/tests/HTBP/Reactor_Tests/inside.conf b/ACE/protocols/tests/HTBP/Reactor_Tests/inside.conf new file mode 100644 index 00000000000..a5bcbc14420 --- /dev/null +++ b/ACE/protocols/tests/HTBP/Reactor_Tests/inside.conf @@ -0,0 +1,5 @@ +[root] +[htbp] +proxy_port=3128 +proxy_host=rtai.ociweb.com +htid_url=http://rtai.ociweb.com/cgi-bin/HTIOP_ID_Generator.cgi diff --git a/ACE/protocols/tests/HTBP/Reactor_Tests/run_test.pl b/ACE/protocols/tests/HTBP/Reactor_Tests/run_test.pl new file mode 100755 index 00000000000..eda33881a66 --- /dev/null +++ b/ACE/protocols/tests/HTBP/Reactor_Tests/run_test.pl @@ -0,0 +1,58 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ +# -*- perl -*- + +use lib "$ENV{ACE_ROOT}/bin"; +use PerlACE::Run_Test; +use Sys::Hostname; + +$status = 0; + +$host = hostname(); +$port = PerlACE::random_port(); +$synchbase = "ready"; +$synchfile = PerlACE::LocalFile ("$synchbase"); + +if (PerlACE::is_vxworks_test()) { + $host = $ENV{'ACE_RUN_VX_TGTHOST'}; + $SV = new PerlACE::ProcessVX ("server", "-p $port -o $synchbase"); +} +else { + $SV = new PerlACE::Process ("server", "-p $port -o $synchfile"); +} + +unlink $synchfile; +$SV->Spawn (); + +if (PerlACE::waitforfile_timed ($synchfile, + $PerlACE::wait_interval_for_process_creation) == -1) { + print STDERR "ERROR: cannot find file <$synchfile>\n"; + $SV->Kill (); $SV->TimedWait (1); + exit 1; +} + +unlink $synchfile; + +# The client code should later be modified to get the hostname +# using ACE_OS::hostname so the same script can be run on all +# hosts without havng to reset the host where it has to be run. +$CL = new PerlACE::Process ("client", "-h $host -p $port"); + +$client = $CL->SpawnWaitKill (300); + +if ($client != 0) { + print STDERR "ERROR: client returned $client\n"; + $status = 1; +} + +$server = $SV->WaitKill (10); + +if ($server != 0) { + print STDERR "ERROR: server returned $server\n"; + $status = 1; +} + +exit $status; diff --git a/ACE/protocols/tests/HTBP/Reactor_Tests/server.cpp b/ACE/protocols/tests/HTBP/Reactor_Tests/server.cpp new file mode 100644 index 00000000000..7bc3d8ac0ee --- /dev/null +++ b/ACE/protocols/tests/HTBP/Reactor_Tests/server.cpp @@ -0,0 +1,251 @@ +/** + * server for a reactor based connection establishment test using HTBP + * + * $Id$ + */ + +#include "ace/Log_Msg.h" + +#include "ace/HTBP/HTBP_Session.h" +#include "ace/HTBP/HTBP_Stream.h" +#include "ace/HTBP/HTBP_Addr.h" + +#include "ace/SOCK_Acceptor.h" +#include "ace/SOCK_Stream.h" +#include "ace/Event_Handler.h" +#include "ace/Reactor.h" +#include "ace/Get_Opt.h" +#include "ace/OS_NS_stdio.h" +#include "ace/OS_NS_unistd.h" + +unsigned port = 8088; +const ACE_TCHAR *notifier_file = 0; + +int +parse_args (int argc, ACE_TCHAR *argv[]) +{ + ACE_Get_Opt get_opts (argc, argv, ACE_TEXT("o:p:")); + int c; + + while ((c = get_opts ()) != -1) + switch (c) + { + case 'o': + notifier_file = get_opts.opt_arg(); + break; + + case 'p': + port = static_cast<unsigned>(ACE_OS::atoi (get_opts.opt_arg())); + break; + case '?': + default: + ACE_ERROR_RETURN ((LM_ERROR, + "usage: %s " + "-p port " + "\n", + argv [0]), + -1); + } + // Indicates sucessful parsing of the command line + return 0; +} + +class Accept_Handler : public ACE_Event_Handler +{ +public: + Accept_Handler (ACE_SOCK_Acceptor& a); + virtual ~Accept_Handler (void); + virtual int handle_input (ACE_HANDLE ); +private: + ACE_SOCK_Acceptor& acceptor_; + ACE::HTBP::Channel *channels_[2]; +}; + +class Stream_Handler : public ACE_Event_Handler +{ +public: + Stream_Handler (ACE::HTBP::Stream &s); + virtual ~Stream_Handler (); + virtual int handle_input (ACE_HANDLE ); +private: + ACE::HTBP::Stream &stream_; +}; + + +Accept_Handler::Accept_Handler(ACE_SOCK_Acceptor &a) + :ACE_Event_Handler(), + acceptor_(a) +{ + this->channels_[0] = this->channels_[1] = 0; + if (this->reactor() == 0) + this->reactor(ACE_Reactor::instance()); + this->reactor()->register_handler (acceptor_.get_handle(), + this, + ACE_Event_Handler::ACCEPT_MASK); +} + +Accept_Handler::~Accept_Handler() +{ + this->reactor()->remove_handler (acceptor_.get_handle(), + ACE_Event_Handler::ACCEPT_MASK| + ACE_Event_Handler::DONT_CALL); + acceptor_.close(); +} + +int +Accept_Handler::handle_input (ACE_HANDLE h) +{ + ACE::HTBP::Channel **ch = 0; + if (h == acceptor_.get_handle()) + { + ACE_SOCK_Stream *sock = new ACE_SOCK_Stream; + acceptor_.accept(*sock); + ch = channels_[0] == 0 ? &channels_[0] :& channels_[1]; + *ch = new ACE::HTBP::Channel(*sock); + this->reactor()->register_handler (sock->get_handle(), + this, + ACE_Event_Handler::READ_MASK); + return 0; + } + for (int i = 0; i < 2; i++) + if (channels_[i] && channels_[i]->get_handle() == h) + { + ch = &channels_[i]; + break; + } + if (ch == 0) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("(%P|%t) Server Accept_Handler::handle_input, ") + ACE_TEXT ("unknown handle %d\n") ,h), + -1); + int result = (*ch)->pre_recv(); + if (result == 0) + { + this->reactor()->remove_handler (h, + ACE_Event_Handler::READ_MASK | + ACE_Event_Handler::DONT_CALL); + + (*ch)->register_notifier(this->reactor()); + ACE::HTBP::Session *session = (*ch)->session(); + + ACE::HTBP::Stream *stream = new ACE::HTBP::Stream(session); + ACE_Event_Handler *handler = session->handler(); + + if (handler == 0) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Server Accept_Handler::handle_input ") + ACE_TEXT ("Creating new stream handler for %d\n"), + stream->get_handle())); + Stream_Handler *sh = new Stream_Handler(*stream); + session->handler (sh); + } + else + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Server Accept_Handler::handle_input ") + ACE_TEXT ("There is already a handler for %d\n"), + stream->get_handle())); + + if ((*ch)->state() == ACE::HTBP::Channel::Data_Queued) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Server Accept_Handler::handle_input \n"), + ACE_TEXT ("Issuing notification on handler\n"))); + this->reactor()->notify (session->handler(), + ACE_Event_Handler::READ_MASK); + } + + *ch = 0; + } + return 0; +} + +Stream_Handler::Stream_Handler (ACE::HTBP::Stream &s) + :stream_(s) +{} +Stream_Handler::~Stream_Handler () +{ +} + +int +Stream_Handler::handle_input (ACE_HANDLE h) +{ + char buffer[1000]; + ssize_t n = this->stream_.recv (buffer,1000); + if (n == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("(%P|%t) Server Stream_Handler::handle_input %p\n"), + ACE_TEXT ("recv")), + 0); + buffer[n] = 0; + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Server Stream_Handler::handle_input ") + ACE_TEXT (" (%d) read %b:\n%C\n"), + h, n, buffer)); + + const char *tok_loc = ACE_OS::strstr (buffer, "goodbye"); + if (tok_loc != 0) + this->reactor()->end_event_loop(); + else + { + ACE::HTBP::Channel *ch = stream_.session()->outbound(); + if (ch != 0) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Server Stream_Handler::handle_input ") + ACE_TEXT ("Sending reply on %d\n"), + ch->ace_stream().get_handle())); + else + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Server Stream_Handler::handle_input ") + ACE_TEXT ("Can't send reply on nul channel\n"))); + this->stream_.send ("Back atcha!",11); + } + return 0; +} + +int +ACE_TMAIN (int argc, ACE_TCHAR * argv[]) +{ + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Server: ") + ACE_TEXT ("At start of main\n"))); + ACE_OS::socket_init (ACE_WSOCK_VERSION); + + if (parse_args (argc, argv) != 0) + return 1; + + ACE_TCHAR host[MAXHOSTNAMELEN+1]; + if (ACE_OS::hostname (host, MAXHOSTNAMELEN) != 0) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("(%P|%t) Server failure: %p\n"), + ACE_TEXT ("hostname")), + 1); + + ACE_INET_Addr local (port, host); + local.addr_to_string (host, MAXHOSTNAMELEN); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Server: ") + ACE_TEXT ("listening at %s\n"), + host)); + + ACE_SOCK_Acceptor acc (local, 1); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Server: ") + ACE_TEXT ("opened listener\n"))); + + Accept_Handler handler (acc); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Server: ") + ACE_TEXT ("server is ready\n"))); + + if (notifier_file != 0) + { + FILE *f = ACE_OS::fopen (notifier_file,ACE_TEXT("w+")); + const char *msg = "server ready"; + ACE_OS::fwrite (msg,ACE_OS::strlen(msg),1,f); + ACE_OS::fclose (f); + } + + ACE_Reactor::instance()->run_reactor_event_loop(); + return 0; +} diff --git a/ACE/protocols/tests/HTBP/Reactor_Tests/test_config.h b/ACE/protocols/tests/HTBP/Reactor_Tests/test_config.h new file mode 100644 index 00000000000..02b32956691 --- /dev/null +++ b/ACE/protocols/tests/HTBP/Reactor_Tests/test_config.h @@ -0,0 +1,316 @@ +// -*- C++ -*- + + +// ============================================================================ +/** + * @file test_config.h + * + * $Id$ + * + * This file factors out common macros and other utilities used by the + * ACE automated regression tests. + * + * @author Prashant Jain <pjain@cs.wustl.edu> + * @author Tim Harrison <harrison@cs.wustl.edu> + * @author David Levine <levine@cs.wustl.edu> + */ +// ============================================================================ + +#ifndef ACE_TEST_CONFIG_H +#define ACE_TEST_CONFIG_H + +#include "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if defined (ACE_NLOGGING) +// ACE_NLOGGING must not be set if the tests are to produce any output. +#undef ACE_NLOGGING +#endif /* ACE_NLOGGING */ + +// This first #undef protects against command-line definitions. +#undef ACE_NDEBUG +#include "ace/OS.h" +#include "ace/streams.h" +#include "ace/Singleton.h" +#include "ace/Synch.h" +#include "ace/Log_Msg.h" +#include "ace/ACE.h" + +// The second #undef protects against being reset in a config.h file. +#undef ACE_NDEBUG + +#if defined (ACE_HAS_WINCE) +// Note that Pocket PC 2002 will NOT create a directory if it does not start with a leading '\'. +// PPC 2002 only accepts '\log' as a valid directory name, while 'log\' works under WinCE 3.0. +# define ACE_LOG_DIRECTORY_FOR_MKDIR ACE_TEXT ("\\log") +# define ACE_LOG_DIRECTORY ACE_TEXT ("\\log\\") +# define MAKE_PIPE_NAME(X) ACE_TEXT ("\\\\.\\pipe\\"#X) +#elif defined (ACE_WIN32) +# define ACE_LOG_DIRECTORY ACE_TEXT ("log\\") +# define MAKE_PIPE_NAME(X) ACE_TEXT ("\\\\.\\pipe\\"#X) +#else +# define ACE_LOG_DIRECTORY ACE_TEXT ("log/") +# define MAKE_PIPE_NAME(X) ACE_TEXT (X) +#endif /* ACE_WIN32 */ + +#if defined (ACE_HAS_WINCE) +#define ACE_LOG_FILE_EXT_NAME ACE_TEXT (".txt") +#else +#define ACE_LOG_FILE_EXT_NAME ACE_TEXT (".log") +#endif /* ACE_HAS_WINCE */ + +#if defined (ACE_HAS_WINCE) || defined (ACE_HAS_PHARLAP) +const size_t ACE_MAX_CLIENTS = 4; +#else +const size_t ACE_MAX_CLIENTS = 30; +#endif /* ACE_HAS_WINCE */ + +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_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_THREADS = 4; + +#define ACE_START_TEST(NAME) \ + const ACE_TCHAR *program = NAME; \ + ACE_LOG_MSG->open (program, ACE_Log_Msg::OSTREAM | ACE_Log_Msg::VERBOSE_LITE); \ + if (ace_file_stream::instance()->set_output (program) != 0) \ + ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("set_output failed")), -1); \ + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) Starting %s test at %D\n"), program)) + +#define ACE_END_TEST \ + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) Ending %s test at %D\n"), program)); \ + ace_file_stream::instance()->close () + +#define ACE_CLOSE_TEST_LOG ace_file_stream::instance()->close () + +#if !defined (ACE_WIN32) +#define ACE_APPEND_LOG(NAME) \ + const ACE_TCHAR *program = NAME; \ + ACE_LOG_MSG->open (program, ACE_Log_Msg::OSTREAM | ACE_Log_Msg::VERBOSE_LITE); \ + ace_file_stream::instance()->close (); \ + if (ace_file_stream::instance()->set_output (program, 1) != 0) \ + ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("set_output failed")), -1); \ + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) Starting %s test at %D\n"), program)); +#else /* ACE_WIN32 */ +#define ACE_APPEND_LOG(NAME) \ + const ACE_TCHAR *program = NAME; \ + ACE_LOG_MSG->open (program, ACE_Log_Msg::OSTREAM | ACE_Log_Msg::VERBOSE_LITE); \ + if (ace_file_stream::instance()->set_output (program, 1) != 0) \ + ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("set_output failed")), -1); \ + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) Starting %s test at %D\n"), program)); +#endif /* ACE_WIN32 */ + +#define ACE_END_LOG \ + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) Ending %s test at %D\n\n"), program)); \ + ACE_LOG_MSG->set_flags(ACE_Log_Msg::SILENT); \ + ace_file_stream::instance()->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) \ + ACE_TCHAR temp[MAXPATHLEN]; \ + ACE_OS::sprintf (temp, ACE_TEXT ("%s%s%s"), \ + ACE_LOG_DIRECTORY, \ + ACE::basename (NAME, ACE_DIRECTORY_SEPARATOR_CHAR), \ + ACE_LOG_FILE_EXT_NAME); \ + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%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, \ + S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) != ERROR) \ + { \ + ACE_OS::close (fd_init_log); \ + ACE_OS::unlink (temp); \ + } + +#if defined (ghs) +# // Rename main to ace_main for compatibility with run_tests.vxworks. +# undef ACE_MAIN +# define ACE_MAIN ace_main +#endif /* ghs */ +#else /* ! VXWORKS */ +#define ACE_INIT_LOG(NAME) \ + ACE_TCHAR temp[MAXPATHLEN]; \ + ACE_OS::sprintf (temp, ACE_TEXT ("%s%s%s"), \ + ACE_LOG_DIRECTORY, \ + ACE::basename (NAME, ACE_DIRECTORY_SEPARATOR_CHAR), \ + ACE_LOG_FILE_EXT_NAME); \ + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) Deleting old log file %s (if any)\n\n"), temp)); \ + ACE_OS::unlink (temp); +#endif /* ! VXWORKS */ + +#if defined (ACE_LACKS_IOSTREAM_TOTALLY) +#define OFSTREAM FILE +#else +#define OFSTREAM ofstream +#endif /* ACE_LACKS_IOSTREAM_TOTALLY */ + +class ACE_Test_Output +{ +public: + ACE_Test_Output (void); + ~ACE_Test_Output (void); + int set_output (const ACE_TCHAR *filename, int append = 0); + OFSTREAM *output_file (void); + void close (void); + +private: + OFSTREAM *output_file_; +}; + +inline ACE_Test_Output::ACE_Test_Output (void) + : output_file_ (0) +{ +#if !defined (ACE_LACKS_IOSTREAM_TOTALLY) + this->output_file_ = new OFSTREAM; +#endif /* ACE_LACKS_IOSTREAM_TOTALLY */ +} + +inline ACE_Test_Output::~ACE_Test_Output (void) +{ +#if !defined (ACE_LACKS_IOSTREAM_TOTALLY) && !defined (ACE_PSOS) + ACE_LOG_MSG->msg_ostream (&cerr); +#endif /* ! ACE_LACKS_IOSTREAM_TOTALLY && ! ACE_PSOS */ + + ACE_LOG_MSG->clr_flags (ACE_Log_Msg::OSTREAM); + ACE_LOG_MSG->set_flags (ACE_Log_Msg::STDERR); + +#if !defined (ACE_LACKS_IOSTREAM_TOTALLY) && !defined (ACE_HAS_PHARLAP) + delete this->output_file_; +#endif /* ! ACE_LACKS_IOSTREAM_TOTALLY */ +} + +inline OFSTREAM * +ACE_Test_Output::output_file (void) +{ + return this->output_file_; +} + +inline int +ACE_Test_Output::set_output (const ACE_TCHAR *filename, int append) +{ +#if defined (ACE_HAS_PHARLAP) + // For PharLap, just send it all to the host console for now - redirect + // to a file there for saving/analysis. + EtsSelectConsole(ETS_CO_HOST); + ACE_LOG_MSG->msg_ostream (&cout); + +#else + ACE_TCHAR temp[MAXPATHLEN]; + // Ignore the error value since the directory may already exist. + const ACE_TCHAR *test_dir; + +#if !defined (ACE_HAS_WINCE) + test_dir = ACE_OS::getenv (ACE_TEXT ("ACE_TEST_DIR")); + + if (test_dir == 0) +#endif /* ACE_HAS_WINCE */ + test_dir = ACE_TEXT (""); + + ACE_OS::sprintf (temp, + ACE_TEXT ("%s%s%s%s"), + test_dir, + ACE_LOG_DIRECTORY, + ACE::basename (filename, ACE_DIRECTORY_SEPARATOR_CHAR), + ACE_LOG_FILE_EXT_NAME); + +#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. + ACE_HANDLE fd = ACE_OS::open (temp, + O_WRONLY|O_CREAT, + S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); + if (fd != 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. +# if defined (ACE_HAS_WINCE) + ACE_OS::mkdir (ACE_LOG_DIRECTORY_FOR_MKDIR); +# else + ACE_OS::mkdir (ACE_LOG_DIRECTORY); +# endif // ACE_HAS_WINCE +# endif /* ! VXWORKS */ + +# if !defined (ACE_LACKS_IOSTREAM_TOTALLY) + this->output_file_->open (ACE_TEXT_ALWAYS_CHAR (temp), + ios::out | (append ? ios::app : ios::trunc)); + if (this->output_file_->bad ()) + return -1; +#else /* when ACE_LACKS_IOSTREAM_TOTALLY */ + ACE_TCHAR *fmode = 0; + if (append) + fmode = ACE_TEXT ("a"); + else + fmode = ACE_TEXT ("w"); + this->output_file_ = ACE_OS::fopen (temp, fmode); +# endif /* ACE_LACKS_IOSTREAM_TOTALLY */ + + ACE_LOG_MSG->msg_ostream (this->output_file ()); +#endif /* ACE_HAS_PHARLAP */ + + ACE_LOG_MSG->clr_flags (ACE_Log_Msg::STDERR | ACE_Log_Msg::LOGGER ); + ACE_LOG_MSG->set_flags (ACE_Log_Msg::OSTREAM); + + return 0; +} + +inline void +ACE_Test_Output::close (void) +{ +#if !defined (ACE_LACKS_IOSTREAM_TOTALLY) + this->output_file_->flush (); + this->output_file_->close (); +#else + ACE_OS::fflush (this->output_file_); + ACE_OS::fclose (this->output_file_); +#endif /* !ACE_LACKS_IOSTREAM_TOTALLY */ + ACE_LOG_MSG->msg_ostream (0); +} + +inline void +randomize (int array[], size_t size) +{ + size_t i; + + for (i = 0; i < size; i++) + array [i] = static_cast<int> (i); + + // See with a fixed number so that we can produce "repeatable" + // random numbers. + ACE_OS::srand (0); + + // Generate an array of random numbers from 0 .. size - 1. + + for (i = 0; i < size; i++) + { + size_t index = ACE_OS::rand() % size--; + int temp = array [index]; + array [index] = array [size]; + array [size] = temp; + } +} + +typedef ACE_Singleton<ACE_Test_Output, ACE_Null_Mutex> ace_file_stream; + +#if defined (ACE_HAS_EXPLICIT_STATIC_TEMPLATE_MEMBER_INSTANTIATION) +template ACE_Singleton<ACE_Test_Output, ACE_Null_Mutex> * +ACE_Singleton<ACE_Test_Output, ACE_Null_Mutex>::singleton_; +#endif /* ACE_HAS_EXPLICIT_STATIC_TEMPLATE_MEMBER_INSTANTIATION */ + +#endif /* ACE_TEST_CONFIG_H */ diff --git a/ACE/protocols/tests/HTBP/Send_Large_Msg/Makefile.am b/ACE/protocols/tests/HTBP/Send_Large_Msg/Makefile.am new file mode 100644 index 00000000000..870836f47f4 --- /dev/null +++ b/ACE/protocols/tests/HTBP/Send_Large_Msg/Makefile.am @@ -0,0 +1,64 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ./bin/mwc.pl -type automake -noreldefs ACE.mwc + +ACE_BUILDDIR = $(top_builddir) +ACE_ROOT = $(top_srcdir) + +noinst_PROGRAMS = + +## Makefile.Send_Large_Msg_Client.am + +if !BUILD_ACE_FOR_TAO + +noinst_PROGRAMS += client + +client_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(ACE_ROOT)/protocols + +client_SOURCES = \ + client.cpp + +client_LDADD = \ + $(top_builddir)/tests/libTest_Output.la \ + $(ACE_BUILDDIR)/protocols/ace/HTBP/libACE_HTBP.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_ACE_FOR_TAO + +## Makefile.Send_Large_Msg_Server.am + +if !BUILD_ACE_FOR_TAO + +noinst_PROGRAMS += server + +server_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(ACE_ROOT)/protocols + +server_SOURCES = \ + server.cpp + +server_LDADD = \ + $(top_builddir)/tests/libTest_Output.la \ + $(ACE_BUILDDIR)/protocols/ace/HTBP/libACE_HTBP.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_ACE_FOR_TAO + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/ACE/protocols/tests/HTBP/Send_Large_Msg/Send_Large_Msg.mpc b/ACE/protocols/tests/HTBP/Send_Large_Msg/Send_Large_Msg.mpc new file mode 100644 index 00000000000..61e59146a93 --- /dev/null +++ b/ACE/protocols/tests/HTBP/Send_Large_Msg/Send_Large_Msg.mpc @@ -0,0 +1,19 @@ +// -*- MPC -*- +// +// $Id$ + +project(*Server): aceexe, htbp { + exename = server + + Source_Files { + server.cpp + } +} + +project(*Client): aceexe, htbp { + exename = client + + Source_Files { + client.cpp + } +} diff --git a/ACE/protocols/tests/HTBP/Send_Large_Msg/client.cpp b/ACE/protocols/tests/HTBP/Send_Large_Msg/client.cpp new file mode 100644 index 00000000000..72c35536f89 --- /dev/null +++ b/ACE/protocols/tests/HTBP/Send_Large_Msg/client.cpp @@ -0,0 +1,143 @@ +// $Id$ + +#include "ace/HTBP/HTBP_Session.h" +#include "ace/HTBP/HTBP_Stream.h" +#include "ace/HTBP/HTBP_Addr.h" +#include "ace/HTBP/HTBP_ID_Requestor.h" +#include "ace/HTBP/HTBP_Environment.h" + +#include "ace/Log_Msg.h" +#include "ace/Get_Opt.h" + +const ssize_t Send_Size = 4*1024; +const size_t Loops = 10; +const size_t Total_Size = Send_Size * Loops; +const ACE_TCHAR * remote_host = 0; +const ACE_TCHAR * config_file = 0; +unsigned remote_port = 8088; + +int +parse_args (int argc, ACE_TCHAR *argv[]) +{ + ACE_Get_Opt get_opts (argc, argv, ACE_TEXT("p:h:c:")); + int c; + + while ((c = get_opts ()) != -1) + switch (c) + { + case 'p': + remote_port = static_cast<unsigned>(ACE_OS::atoi (get_opts.opt_arg())); + break; + case 'h': + remote_host = get_opts.opt_arg (); + break; + case 'c': + config_file = get_opts.opt_arg (); + break; + case '?': + default: + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("usage: %s ") + ACE_TEXT ("-h remote_host ") + ACE_TEXT ("-p remote_port ") + ACE_TEXT ("-c config_file ") + ACE_TEXT ("\n"), + argv [0]), + -1); + } + // Indicates sucessful parsing of the command line + return 0; +} + +int +ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + ACE_OS::socket_init (ACE_WSOCK_VERSION); + + if (parse_args(argc, argv) != 0) + return 1; + if (remote_host == 0) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("Client: No remote host specified\n")),1); + + ACE::HTBP::Environment env; + if (config_file != 0) + env.import_config (config_file); + + ACE::HTBP::ID_Requestor req (&env); + ACE::HTBP::Addr local(ACE_TEXT_ALWAYS_CHAR(req.get_HTID())); + + unsigned proxy_port = 0; + ACE_TString proxy_host; + + if (env.get_proxy_port(proxy_port) != 0 || + env.get_proxy_host(proxy_host) != 0) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT("(%P|%t) Client: ") + ACE_TEXT("no proxy address in ") + ACE_TEXT("config, using direct connect\n"))); + proxy_port = remote_port; + proxy_host = remote_host; + } + + ACE_INET_Addr proxy(proxy_port,proxy_host.c_str()); + ACE::HTBP::Addr remote (remote_port,ACE_TEXT_ALWAYS_CHAR(remote_host)); + + ACE::HTBP::Session session(remote, + local, + ACE::HTBP::Session::next_session_id(), + &proxy); + + ACE::HTBP::Stream *stream = new ACE::HTBP::Stream(&session); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT("(%P|%t) Client: ") + ACE_TEXT("Sending message\n"))); + char buffer[Send_Size]; + ACE_OS::memset (buffer,'a',Send_Size); + ssize_t n = 0; + for (size_t i = 0; i < Loops ; ++i) + { + errno = 0; + while (n < Send_Size) + { + n += stream->send (buffer+n,Send_Size); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT("(%P|%t) Client: ") + ACE_TEXT("Sending %d of %d\n"), + n, Send_Size)); + } + if (n == -1 && errno != 0) + { + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT("(%P|%t) Client: ") + ACE_TEXT("%p\n %d"), + ACE_TEXT("stream send"), errno), + -1); + } + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT("(%P|%t) Client: ") + ACE_TEXT("In round %d, send returned %d\n"), + i, n)); + } + + buffer[0] = 0; + n = stream->recv (buffer,1000); + while (n == -1) + { + if (errno == EWOULDBLOCK) + n = stream->recv (buffer,1000); + else + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT("(%P|%t) Client: ") + ACE_TEXT("%p\n"), + ACE_TEXT("stream.recv")), + -1); + } + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT("(%P|%t) Client: ") + ACE_TEXT("received %d, %s\n"), + n,buffer)); + return 0; +} diff --git a/ACE/protocols/tests/HTBP/Send_Large_Msg/run_test.pl b/ACE/protocols/tests/HTBP/Send_Large_Msg/run_test.pl new file mode 100755 index 00000000000..a1bfaafb77f --- /dev/null +++ b/ACE/protocols/tests/HTBP/Send_Large_Msg/run_test.pl @@ -0,0 +1,59 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ +# -*- perl -*- + +use lib "$ENV{ACE_ROOT}/bin"; +use PerlACE::Run_Test; +use Sys::Hostname; + +$status = 0; + +$host = hostname(); +$port = PerlACE::random_port(); +$synchbase = "ready"; +$synchfile = PerlACE::LocalFile ("$synchbase"); + +if (PerlACE::is_vxworks_test()) { + $host = $ENV{'ACE_RUN_VX_TGTHOST'}; + $SV = new PerlACE::ProcessVX ("server", "-p $port -o $synchbase"); +} +else { + $SV = new PerlACE::Process ("server", "-p $port -o $synchfile"); +} + +# The client code should later be modified to get the hostname +# using ACE_OS::hostname so the same script can be run on all +# hosts without having to reset the host where it has to be run. +$CL = new PerlACE::Process ("client", "-h $host -p $port"); + +unlink $synchfile; +$SV->Spawn (); + +if (PerlACE::waitforfile_timed ($synchfile, + $PerlACE::wait_interval_for_process_creation) == -1) { + print STDERR "ERROR: cannot find file <$synchfile>\n"; + $SV->Kill (); $SV->TimedWait (1); + exit 1; +} + +unlink $synchfile; + +$client = $CL->SpawnWaitKill (300); + +if ($client != 0) { + print STDERR "ERROR: client returned $client\n"; + $status = 1; +} + +$server = $SV->WaitKill (10); + +if ($server != 0) { + print STDERR "ERROR: server returned $server\n"; + $status = 1; +} + + +exit $status; diff --git a/ACE/protocols/tests/HTBP/Send_Large_Msg/server.cpp b/ACE/protocols/tests/HTBP/Send_Large_Msg/server.cpp new file mode 100644 index 00000000000..34f037148c5 --- /dev/null +++ b/ACE/protocols/tests/HTBP/Send_Large_Msg/server.cpp @@ -0,0 +1,170 @@ +// $Id$ + +#include "ace/Log_Msg.h" +#include "ace/Get_Opt.h" + +#include "ace/HTBP/HTBP_Session.h" +#include "ace/HTBP/HTBP_Stream.h" +#include "ace/HTBP/HTBP_Addr.h" + +#include "ace/SOCK_Acceptor.h" +#include "ace/SOCK_Stream.h" +#include "ace/OS_NS_stdio.h" + +const size_t Send_Size = 4*1024; +const size_t Loops = 10; +const size_t Total_Size = Send_Size * Loops; +unsigned port = 8088; +const ACE_TCHAR *notifier_file = 0; + +int +parse_args (int argc, ACE_TCHAR *argv[]) +{ + ACE_Get_Opt get_opts (argc, argv, ACE_TEXT("o:p:")); + int c; + + while ((c = get_opts ()) != -1) + switch (c) + { + case 'o': + notifier_file = get_opts.opt_arg(); + break; + case 'p': + port = static_cast<unsigned>(ACE_OS::atoi (get_opts.opt_arg())); + break; + case '?': + default: + ACE_ERROR_RETURN ((LM_ERROR, + "usage: %s " + "-p port " + "\n", + argv [0]), + -1); + } + // Indicates sucessful parsing of the command line + return 0; +} + +int +ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + char buffer[5000]; + + ACE_OS::socket_init (ACE_WSOCK_VERSION); + + if (parse_args (argc, argv) != 0) + return 1; + + ACE_TCHAR host[MAXHOSTNAMELEN+1]; + if (ACE_OS::hostname (host,MAXHOSTNAMELEN) != 0) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("(%P|%t) Server failure: %p\n"), + ACE_TEXT ("hostname")), + 1); + + ACE_INET_Addr local (port, host); + ACE_SOCK_Stream sock[2]; + ACE::HTBP::Channel *channels[2]; + ACE_SOCK_Acceptor acc(local,1); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT("(%P|%t) Server: ") + ACE_TEXT("server is ready\n"))); + + if (notifier_file != 0) + { + FILE *f = ACE_OS::fopen (notifier_file,ACE_TEXT("w+")); + const char *msg = "server ready"; + ACE_OS::fwrite (msg,ACE_OS::strlen(msg),1,f); + ACE_OS::fclose (f); + } + + acc.accept(sock[0]); + channels[0] = new ACE::HTBP::Channel (sock[0]); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT("(%P|%t) Server: ") + ACE_TEXT("Got sock[0], handle = %d\n"), + sock[0].get_handle())); + acc.accept(sock[1]); + channels[1] = new ACE::HTBP::Channel(sock[1]); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT("(%P|%t) Server: ") + ACE_TEXT("Got sock[1], handle = %d\n"), + sock[1].get_handle())); + int res = 0; + while ((res = channels[0]->pre_recv()) != 0) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT("(%P|%t) Server: ") + ACE_TEXT("res = %d. waiting 1 sec. %p\n"), + res, + ACE_TEXT("stream.pre_recv()"))); + ACE_OS::sleep (1); + } + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT("(%P|%t) Server: ") + ACE_TEXT("Read from channel2\n"))); + while ((res = channels[1]->pre_recv()) != 0) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT("(%P|%t) Server: ") + ACE_TEXT("res = %d, waiting 1 sec. %p\n"), + res, + ACE_TEXT("stream2.pre_recv()"))); + ACE_OS::sleep (1); + } + + ACE::HTBP::Session *session = channels[0]->session(); + ACE::HTBP::Stream stream (session); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT("(%P|%t) Server: ") + ACE_TEXT("using streams %d, %d. Got sesssion = %x\n"), + sock[0].get_handle(),sock[1].get_handle(),session)); + + ssize_t got = 1; + ssize_t total_recv = 0; + + while (got != 0) + { + errno = 0; + got = stream.recv (buffer, sizeof (buffer)); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT("(%P|%t) Server: ") + ACE_TEXT("got = %b\n"), got)); + + if (got < 0) + break; + total_recv += got; + } + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT("(%P|%t) Server: ") + ACE_TEXT("received %b \n"),total_recv)); + + + ACE_OS::strcpy (buffer,"I hear you !"); + ssize_t n = stream.send (buffer, ACE_OS::strlen (buffer)+1); + if (n == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT("(%P|%t) Server: ") + ACE_TEXT("%p\n"), + ACE_TEXT("stream.send")),-1); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT("(%P|%t) Server: ") + ACE_TEXT("send returned %b\n"), + n)); + + ACE_OS::sleep(1); // prevent test failure on windows when the connection + // closes too fast. + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT("(%P|%t) Server: ") + ACE_TEXT("deleting channels[1]\n"))); + delete channels[1]; + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT("(%P|%t) Server: ") + ACE_TEXT("deleting channels[0]\n"))); + delete channels[0]; + return 0; +} diff --git a/ACE/protocols/tests/HTBP/Send_Recv_Tests/Makefile.am b/ACE/protocols/tests/HTBP/Send_Recv_Tests/Makefile.am new file mode 100644 index 00000000000..cd211acf455 --- /dev/null +++ b/ACE/protocols/tests/HTBP/Send_Recv_Tests/Makefile.am @@ -0,0 +1,66 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ./bin/mwc.pl -type automake -noreldefs ACE.mwc + +ACE_BUILDDIR = $(top_builddir) +ACE_ROOT = $(top_srcdir) + +noinst_PROGRAMS = + +## Makefile.SendRecv_Test_Client.am + +if BUILD_ACE_UUID +if !BUILD_ACE_FOR_TAO + +noinst_PROGRAMS += client + +client_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(ACE_ROOT)/protocols + +client_SOURCES = \ + client.cpp + +client_LDADD = \ + $(ACE_BUILDDIR)/protocols/ace/HTBP/libACE_HTBP.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_ACE_FOR_TAO +endif BUILD_ACE_UUID + +## Makefile.SendRecv_Test_Server.am + +if BUILD_ACE_UUID +if !BUILD_ACE_FOR_TAO + +noinst_PROGRAMS += server + +server_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(ACE_ROOT)/protocols + +server_SOURCES = \ + server.cpp + +server_LDADD = \ + $(ACE_BUILDDIR)/protocols/ace/HTBP/libACE_HTBP.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_ACE_FOR_TAO +endif BUILD_ACE_UUID + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/ACE/protocols/tests/HTBP/Send_Recv_Tests/SendRecv_Test.mpc b/ACE/protocols/tests/HTBP/Send_Recv_Tests/SendRecv_Test.mpc new file mode 100644 index 00000000000..b91c55e9763 --- /dev/null +++ b/ACE/protocols/tests/HTBP/Send_Recv_Tests/SendRecv_Test.mpc @@ -0,0 +1,20 @@ +// -*- MPC -*- +// +// $Id$ +// + +project(*server): aceexe, htbp { + exename = server + + Source_Files { + server.cpp + } +} + +project(*client): aceexe, htbp { + exename = client + + Source_Files { + client.cpp + } +} diff --git a/ACE/protocols/tests/HTBP/Send_Recv_Tests/client.cpp b/ACE/protocols/tests/HTBP/Send_Recv_Tests/client.cpp new file mode 100644 index 00000000000..c8d224c9380 --- /dev/null +++ b/ACE/protocols/tests/HTBP/Send_Recv_Tests/client.cpp @@ -0,0 +1,232 @@ +// $Id$ + +// =========================================================================== +// +// = LIBRARY +// tests +// +// = FILENAME +// Send_Recv_Test.cpp +// +// = DESCRIPTION This is a test of the <ACE_SOCK>'s various send and +// receive methods, over HTBP. The test forks two processes or spawns +// two threads (depending upon the platform) and then executes client +// and server allowing them to connect and exchange data in ways +// designed to exercise the send and recv functions. +// +// Right now, it primarily tests the iov-like send and recv +// functions, but others should be added to completely cover the +// possible scenarios. +// +// = AUTHOR +// Steve Huston <shuston@riverace.com> +// +// ============================================================================ + +#include "ace/HTBP/HTBP_Stream.h" +#include "ace/HTBP/HTBP_Session.h" +#include "ace/HTBP/HTBP_ID_Requestor.h" +#include "ace/HTBP/HTBP_Environment.h" + +#include "ace/OS.h" +#include "ace/Thread.h" +#include "ace/Thread_Manager.h" +#include "ace/SOCK_Connector.h" +#include "ace/SOCK_Acceptor.h" +#include "ace/SOCK_Stream.h" +#include "ace/Get_Opt.h" + +// Change to non-zero if test fails +static int Test_Result = 0; + +const size_t Test3_Send_Size = 4*1024; +const size_t Test3_Loops = 10; +const size_t Test3_Total_Size = Test3_Send_Size * Test3_Loops; + +const ACE_TCHAR * remote_host = 0; +const ACE_TCHAR * config_file = 0; +unsigned remote_port = 8088; + +int +parse_args (int argc, ACE_TCHAR *argv[]) +{ + ACE_Get_Opt get_opts (argc, argv, ACE_TEXT("p:h:c:")); + int c; + + while ((c = get_opts ()) != -1) + switch (c) + { + case 'p': + remote_port = static_cast<unsigned>(ACE_OS::atoi (get_opts.opt_arg())); + break; + case 'h': + remote_host = get_opts.opt_arg (); + break; + case 'c': + config_file = get_opts.opt_arg (); + break; + case '?': + default: + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("usage: %s ") + ACE_TEXT ("-h remote_host ") + ACE_TEXT ("-p remote_port ") + ACE_TEXT ("-c config_file ") + ACE_TEXT ("\n"), + argv [0]), + -1); + } + // Indicates sucessful parsing of the command line + return 0; +} + +int +ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + ACE_OS::socket_init (ACE_WSOCK_VERSION); + + if (parse_args(argc, argv) != 0) + return 1; + if (remote_host == 0) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("Client: No remote host specified\n")),1); + + ACE::HTBP::Environment env; + if (config_file != 0) + env.import_config (config_file); + + ACE::HTBP::ID_Requestor req (&env); + ACE::HTBP::Addr local(ACE_TEXT_ALWAYS_CHAR(req.get_HTID())); + + unsigned proxy_port = 0; + ACE_TString proxy_host; + + if (env.get_proxy_port(proxy_port) != 0 || + env.get_proxy_host(proxy_host) != 0) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT("(%P|%t) Client: ") + ACE_TEXT("no proxy address in ") + ACE_TEXT("config, using direct connect\n"))); + proxy_port = remote_port; + proxy_host = remote_host; + } + + ACE_INET_Addr proxy(proxy_port,proxy_host.c_str()); + ACE::HTBP::Addr remote (remote_port, + ACE_TEXT_ALWAYS_CHAR(remote_host)); + + ACE::HTBP::Session session(remote, + local, + ACE::HTBP::Session::next_session_id(), + &proxy); + + ACE::HTBP::Stream stream(&session); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Connecting to port %d\n"), + remote.get_port_number())); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) connected to %s\n"), + ACE_TEXT_CHAR_TO_TCHAR(remote.get_host_name ()))); + + ACE_DEBUG ((LM_DEBUG, "(%P) ***** client TEST 1 ***** \n")); + + //******************* TEST 1 ****************************** + // + // Do a iovec sendv - send the 255 byte buffer in 5 chunks. The + // server will verify that the correct data is sent, and that there + // is no more and no less. + + u_char buffer[255]; + size_t i; + ssize_t len; + + // The server will verify that this data pattern gets there intact. + + for (i = 0; i < sizeof buffer; ++i) + buffer[i] = static_cast<u_char> (i); + + iovec iov[5]; + + iov[0].iov_base = reinterpret_cast<char *> (&buffer[0]); + iov[0].iov_len = 50; + + iov[1].iov_base = reinterpret_cast<char *> (&buffer[50]); + iov[1].iov_len = 25; + + iov[2].iov_base = reinterpret_cast<char *> (&buffer[75]); + iov[2].iov_len = 150; + + iov[3].iov_base = reinterpret_cast<char *> (&buffer[225]); + iov[3].iov_len = 29; + + iov[4].iov_base = reinterpret_cast<char *> (&buffer[254]); + iov[4].iov_len = 1; + + len = stream.sendv (iov, 5); + ACE_DEBUG ((LM_DEBUG,"(%P) after send, len = %d\n")); + if (len == -1) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) %p\n"), + ACE_TEXT ("Test 1, sendv failed"))); + Test_Result = 1; + } + else + if (len != 255) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) %p\n"), + ACE_TEXT ("Test 1, len = %d != 255\n"), len)); + Test_Result = 1; + } + + // ACE_OS::sleep (10); + ACE_DEBUG ((LM_DEBUG, "(%P) ***** client TEST 2 ***** \n")); + + //******************* TEST 2 ****************************** + // + // The same data is coming back - receive it using recv (size_t n, + // ...) and compare it to the original data. + + u_char buffer2[255]; + + ssize_t total = 0; + do { + len = stream.recv (buffer2+total, 145 - total); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT("(%P) Test 2: want %d bytes, got %d\n"), + 145 - total,len)); + if (len == -1 || errno == EWOULDBLOCK) + ACE_OS::sleep (1); + else + total += len; + } while ((len == -1 && errno == EWOULDBLOCK) || total < 145); + + if (total != 145) + Test_Result = 1; + + len = stream.recv (buffer2 + total, 110); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT("(%P) Test 2: second read want 110 bytes, got %d\n"), + len)); + + if (len != 110) + Test_Result = 1; + + for (i = 0; Test_Result == 0 && i < 255; i++) + if (buffer2[i] != buffer[i]) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) Test 2, rcvd byte %d is %d, not %d\n"), + i, buffer2[i], buffer[i])); + Test_Result = 1; + } + + + stream.close (); + + return Test_Result; +} diff --git a/ACE/protocols/tests/HTBP/Send_Recv_Tests/run_test.pl b/ACE/protocols/tests/HTBP/Send_Recv_Tests/run_test.pl new file mode 100755 index 00000000000..5a7fb2b3289 --- /dev/null +++ b/ACE/protocols/tests/HTBP/Send_Recv_Tests/run_test.pl @@ -0,0 +1,56 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ +# -*- perl -*- + +use lib "$ENV{ACE_ROOT}/bin"; +use PerlACE::Run_Test; +use Sys::Hostname; + +$status = 0; + +$host = hostname(); +$port = PerlACE::random_port(); +$synchbase = "ready"; +$synchfile = PerlACE::LocalFile ("$synchbase"); + +if (PerlACE::is_vxworks_test()) { + $host = $ENV{'ACE_RUN_VX_TGTHOST'}; + $SV = new PerlACE::ProcessVX ("server", "-p $port -o $synchbase"); +} +else { + $SV = new PerlACE::Process ("server", "-p $port -o $synchfile"); +} + +# The client code should later be modified to get the hostname +# using ACE_OS::hostname so the same script can be run on all +# hosts without havng to reset the host where it has to be run. +$CL = new PerlACE::Process ("client", "-h $host -p $port"); + +unlink $synchfile; +$SV->Spawn (); +if (PerlACE::waitforfile_timed ($synchfile, + $PerlACE::wait_interval_for_process_creation) == -1) { + print STDERR "ERROR: cannot find file <$synchfile>\n"; + $SV->Kill (); $SV->TimedWait (1); + exit 1; +} +unlink $synchfile; + +$client = $CL->SpawnWaitKill (300); + +if ($client != 0) { + print STDERR "ERROR: client returned $client\n"; + $status = 1; +} + +$server = $SV->WaitKill (10); + +if ($server != 0) { + print STDERR "ERROR: server returned $server\n"; + $status = 1; +} + +exit $status; diff --git a/ACE/protocols/tests/HTBP/Send_Recv_Tests/server.cpp b/ACE/protocols/tests/HTBP/Send_Recv_Tests/server.cpp new file mode 100644 index 00000000000..758fdc90a21 --- /dev/null +++ b/ACE/protocols/tests/HTBP/Send_Recv_Tests/server.cpp @@ -0,0 +1,286 @@ +// $Id$ + +// =========================================================================== +// +// = LIBRARY +// tests +// +// = FILENAME +// Send_Recv_Test.cpp +// +// = DESCRIPTION This is a test of the <ACE_SOCK>'s various send and +// receive methods, over HTBP. The test forks two processes or spawns +// two threads (depending upon the platform) and then executes client +// and server allowing them to connect and exchange data in ways +// designed to exercise the send and recv functions. +// +// Right now, it primarily tests the iov-like send and recv +// functions, but others should be added to completely cover the +// possible scenarios. +// +// = AUTHOR +// Steve Huston <shuston@riverace.com> +// +// ============================================================================ + +#include "ace/HTBP/HTBP_Stream.h" +#include "ace/HTBP/HTBP_Session.h" +#include "ace/HTBP/HTBP_ID_Requestor.h" +#include "ace/HTBP/HTBP_Environment.h" + +#include "ace/OS.h" +#include "ace/Thread.h" +#include "ace/Thread_Manager.h" +#include "ace/SOCK_Connector.h" +#include "ace/SOCK_Acceptor.h" +#include "ace/SOCK_Stream.h" +#include "ace/Get_Opt.h" +#include "ace/OS_NS_stdio.h" + +// Change to non-zero if test fails +static int Test_Result = 0; + +// In test 3, a large amount of data is sent. The purpose is to overflow the +// TCP send window, causing the sender to block (it's a send_n). This value +// is the amount to send. The assumption is that no implementation has a +// receive window larger than 128K bytes. If one is found, this is the place +// to change it. +// For some odd reason, NT will try to send a single large buffer, but not +// multiple smaller ones that add up to the large size. +const size_t Test3_Send_Size = 4*1024; +const size_t Test3_Loops = 10; +const size_t Test3_Total_Size = Test3_Send_Size * Test3_Loops; +unsigned port = 8088; +const ACE_TCHAR *notifier_file = 0; + +int +parse_args (int argc, ACE_TCHAR *argv[]) +{ + ACE_Get_Opt get_opts (argc, argv, ACE_TEXT("o:p:")); + int c; + + while ((c = get_opts ()) != -1) + switch (c) + { + case 'o': + notifier_file = get_opts.opt_arg(); + break; + case 'p': + port = static_cast<unsigned>(ACE_OS::atoi (get_opts.opt_arg())); + break; + case '?': + default: + ACE_ERROR_RETURN ((LM_ERROR, + "usage: %s " + "-p port " + "\n", + argv [0]), + -1); + } + // Indicates sucessful parsing of the command line + return 0; +} + +int +ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + ACE_OS::socket_init (ACE_WSOCK_VERSION); + + if (parse_args(argc, argv) != 0) + return 1; + + // Acceptor + ACE_SOCK_Acceptor peer_acceptor; + + // Create a server address. + ACE_INET_Addr server_addr; + + char hostname[BUFSIZ]; + + if (ACE_OS::hostname (hostname, BUFSIZ) != 0) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("Could not get the hostname\n"))); + } + + ACE::HTBP::Addr addr (port, hostname); + + // Bind listener to any port and then find out what the port was. + if (peer_acceptor.open (addr) == -1 + || peer_acceptor.get_local_addr (server_addr) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("(%P|%t) %p\n"), + ACE_TEXT ("open")), 1); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) starting server at port %d\n"), + server_addr.get_port_number ())); + + if (notifier_file != 0) + { + FILE *f = ACE_OS::fopen (notifier_file,ACE_TEXT("w+")); + const char *msg = "server ready"; + ACE_OS::fwrite (msg,ACE_OS::strlen(msg),1,f); + ACE_OS::fclose (f); + } + + ACE_INET_Addr cli_addr; + + ACE_SOCK_Stream sock_stream[2]; + ACE_DEBUG ((LM_DEBUG,"(%P) server is ready\n")); + + if (peer_acceptor.accept(sock_stream[0],&cli_addr,0) == -1) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) %p\n"), + ACE_TEXT ("accept"))); + return 1; + } + + ACE::HTBP::Channel channel1(sock_stream[0]); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT("(%P) Got sock[0], handle = %d\n"), + sock_stream[0].get_handle())); + + if (peer_acceptor.accept(sock_stream[1],&cli_addr,0) == -1) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) %p\n"), + ACE_TEXT ("accept"))); + return 1; + } + + ACE::HTBP::Channel channel2(sock_stream[1]); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT("(%P) Got sock_stream[1], handle = %d\n"), + sock_stream[1].get_handle())); + int res = 0; + while ((res = channel1.pre_recv()) != 0) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT("(%P)res = %d. waiting 1 sec. %p\n"), + res, + ACE_TEXT("stream.pre_recv()"))); + ACE_OS::sleep (1); + } + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT("(%P)Read from channel2\n"))); + while ((res = channel2.pre_recv()) != 0) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT("(%P)res = %d, waiting 1 sec. %p\n"),res, + ACE_TEXT("stream2.pre_recv()"))); + ACE_OS::sleep (1); + } + + ACE::HTBP::Session *session = channel1.session(); + ACE::HTBP::Stream stream (session); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) client %s connected from %d\n"), + ACE_TEXT_CHAR_TO_TCHAR(cli_addr.get_host_name ()), + cli_addr.get_port_number ())); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT("(%P) ***** server TEST 1 ***** \n"))); + //******************* TEST 1 ****************************** + // + // Do a iovec recvv - the client should send 255 bytes, which we + // will be detected and read into a ACE-allocated buffer. Use a 5 + // second timeout to give the client a chance to send it all. + + ACE_OS::sleep (2); + + u_char buffer[255]; + + iovec iov[3]; + + ssize_t len; + int i; + + iov[0].iov_base = reinterpret_cast<char *> (&buffer[0]); + iov[0].iov_len = 75; + + iov[1].iov_base = reinterpret_cast<char *> (&buffer[75]); + iov[1].iov_len = 100; + + iov[2].iov_base = reinterpret_cast<char *> (&buffer[175]); + iov[2].iov_len = 80; + + len = stream.recvv (iov, 3); + if (len == -1) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) %p\n"), + ACE_TEXT ("Test 1, recvv failed"))); + Test_Result = 1; + } + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT("(%P) server, Test 1: recvd len = %d\n"),len)); + + for (i = 0; i < 255; i++) + if (buffer[i] != i) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) Test 1, rcvd byte %d is %d, not %d\n"), + i, + buffer[i], + i)); + Test_Result = 1; + } + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT("(%P) ***** server TEST 2 ***** \n"))); + + //******************* TEST 2 ****************************** + // + // Send the buffer back, using send (size_t n, ...) in 3 pieces. + + len = stream.send (buffer, 6); + len += stream.send (buffer + 6,42); + len += stream.send (buffer + 48,189); + len += stream.send (buffer + 237,18); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT("(%P) server sent len=%d\n"),len)); + // ACE_OS::sleep(10); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT("(%P) flushing outbound queue\n"))); + + while ((res = channel1.pre_recv()) != 0 && + (res = channel2.pre_recv()) != 0) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT("(%P)res = %d. waiting 1 sec. %p\n"), + res, + ACE_TEXT("stream.pre_recv()"))); + ACE_OS::sleep (1); + } + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT("(%P)Read from channel2\n"))); + + int result = session->flush_outbound_queue(); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT("(%P) server: shutting down, flush returned %d\n"), result)); + + ACE_OS::sleep(1); // prevent test failure on windows when the connection + // closes too fast. + + sock_stream[0].close(); + sock_stream[1].close(); + stream.close (); + + peer_acceptor.close (); + + + if (len != 255) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT("(%P} server: send result %d != 255\n"), len)); + return 1; + } + + return Test_Result; +} diff --git a/ACE/protocols/tests/HTBP/ping/Makefile.am b/ACE/protocols/tests/HTBP/ping/Makefile.am new file mode 100644 index 00000000000..b59b297e535 --- /dev/null +++ b/ACE/protocols/tests/HTBP/ping/Makefile.am @@ -0,0 +1,62 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ./bin/mwc.pl -type automake -noreldefs ACE.mwc + +ACE_BUILDDIR = $(top_builddir) +ACE_ROOT = $(top_srcdir) + +noinst_PROGRAMS = + +## Makefile.Ping_Client.am + +if !BUILD_ACE_FOR_TAO + +noinst_PROGRAMS += client + +client_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(ACE_ROOT)/protocols + +client_SOURCES = \ + client.cpp + +client_LDADD = \ + $(ACE_BUILDDIR)/protocols/ace/HTBP/libACE_HTBP.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_ACE_FOR_TAO + +## Makefile.Ping_Server.am + +if !BUILD_ACE_FOR_TAO + +noinst_PROGRAMS += server + +server_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(ACE_ROOT)/protocols + +server_SOURCES = \ + server.cpp + +server_LDADD = \ + $(ACE_BUILDDIR)/protocols/ace/HTBP/libACE_HTBP.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_ACE_FOR_TAO + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/ACE/protocols/tests/HTBP/ping/client.cpp b/ACE/protocols/tests/HTBP/ping/client.cpp new file mode 100644 index 00000000000..481be629208 --- /dev/null +++ b/ACE/protocols/tests/HTBP/ping/client.cpp @@ -0,0 +1,203 @@ +/** + * $Id$ + * + * client for a basic connection establishment test using HTBP + */ + +#include "ace/ACE.h" +#include "ace/Log_Msg.h" +#include "ace/Get_Opt.h" + +#include "ace/HTBP/HTBP_Session.h" +#include "ace/HTBP/HTBP_Stream.h" +#include "ace/HTBP/HTBP_Addr.h" +#include "ace/HTBP/HTBP_ID_Requestor.h" +#include "ace/HTBP/HTBP_Environment.h" + +const ACE_TCHAR * remote_host = 0; +const ACE_TCHAR * config_file = 0; +unsigned int remote_port = 8088; + +int +parse_args (int argc, ACE_TCHAR *argv[]) +{ + ACE_Get_Opt get_opts (argc, argv, ACE_TEXT ("p:h:c:d")); + int c; + + while ((c = get_opts ()) != -1) + switch (c) + { + case 'p': + remote_port = static_cast<unsigned>(ACE_OS::atoi (get_opts.opt_arg())); + break; + case 'h': + remote_host = get_opts.opt_arg (); + break; + case 'c': + config_file = get_opts.opt_arg (); + break; + case 'd': + ACE::debug (true); + break; + case '?': + default: + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("usage: %s ") + ACE_TEXT ("-h remote_host ") + ACE_TEXT ("-p remote_port ") + ACE_TEXT ("-c config_file ") + ACE_TEXT ("-d (turn on extra logging)") + ACE_TEXT ("\n"), + argv [0]), + -1); + } + // Indicates sucessful parsing of the command line + return 0; +} + +int +ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + ACE_OS::socket_init (ACE_WSOCK_VERSION); + + if (parse_args (argc, argv) != 0) + return 1; + if (remote_host == 0) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("Client: No remote host specified\n")), + 1); + + ACE::HTBP::Environment env; + if (config_file != 0) + env.import_config (config_file); + + ACE::HTBP::ID_Requestor req (&env); + ACE::HTBP::Addr local (ACE_TEXT_ALWAYS_CHAR (req.get_HTID ())); + + unsigned int proxy_port = 0; + ACE_TString proxy_host; + + if (env.get_proxy_port (proxy_port) != 0 || + env.get_proxy_host (proxy_host) != 0) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Client: ") + ACE_TEXT("no proxy address in ") + ACE_TEXT("config, using direct connect\n"))); + proxy_port = remote_port; + proxy_host = remote_host; + } + + ACE_INET_Addr proxy (proxy_port, proxy_host.c_str ()); + ACE::HTBP::Addr remote (remote_port, ACE_TEXT_ALWAYS_CHAR (remote_host)); + ACE_TCHAR proxy_s[MAXHOSTNAMELEN+1]; + proxy.addr_to_string (proxy_s, MAXHOSTNAMELEN); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Client: connecting to %s\n"), + proxy_s)); + ACE::HTBP::Session session (remote, + local, + ACE::HTBP::Session::next_session_id (), + &proxy); + ACE::HTBP::Stream stream (&session); + + char buffer[1000]; + ssize_t n = 0; + int retrycount = 10; + for (int i = 0; i < 3; i++) + { + ACE_OS::sprintf (buffer, "Do you hear me? %d", i); + ACE::HTBP::Channel *ob = session.outbound (); + n = stream.send (buffer, ACE_OS::strlen (buffer)+1); + if (n == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("(%P|%t) Client: ") + ACE_TEXT ("%p\n"), + ACE_TEXT("stream send")), + -1); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Client: ") + ACE_TEXT ("send returned %b\n"), + n)); + + retrycount = 10; + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Client: ") + ACE_TEXT ("after send, outbound = %@, ob = %@\n"), + session.outbound (), ob)); + while ((n = ob->recv_ack ()) == -1 + && (errno == EWOULDBLOCK || errno == ETIME) + && retrycount > 0) + { + retrycount--; + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Client: ") + ACE_TEXT ("waiting for ack, %d tries left\n"), + retrycount)); + ACE_OS::sleep (1); + } + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Client: ") + ACE_TEXT ("After wait for ack, n = %b, retry = %d\n"), + n, retrycount)); + + retrycount = 10; + while ((n = stream.recv (buffer, 1000)) == -1 + && (errno == EWOULDBLOCK || errno == ETIME) + && retrycount > 0) + { + retrycount--; + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Client: ") + ACE_TEXT ("waiting for inbound data, %d tries left\n"), + retrycount)); + ACE_OS::sleep (1); + } + if (retrycount == 0 || n < 0) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Client: ") + ACE_TEXT ("bailing after wait, %p\n"), + ACE_TEXT ("recv"))); + break; + } + + buffer[n] = 0; + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Client: Got: \"%C\"\n"), + buffer)); + } + + ACE::HTBP::Channel *ob = session.outbound (); + n = stream.send ("goodbye", 7); + if (n == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("(%P|%t) Client: %p\n"), + ACE_TEXT ("stream send")), + -1); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Client: ") + ACE_TEXT ("send returned %b\n"), + n)); + + retrycount = 10; + while ((n = ob->recv_ack ()) == -1 + && (errno == EWOULDBLOCK || errno == ETIME) + && retrycount > 0) + { + retrycount--; + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Client: ") + ACE_TEXT ("waiting for ack, %d tries left\n"), + retrycount)); + ACE_OS::sleep (1); + } + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Client: ") + ACE_TEXT ("After wait for ack, n = %b, retry = %d\n"), + n, retrycount)); + stream.close (); + return 0; +} diff --git a/ACE/protocols/tests/HTBP/ping/ping.mpc b/ACE/protocols/tests/HTBP/ping/ping.mpc new file mode 100755 index 00000000000..61e59146a93 --- /dev/null +++ b/ACE/protocols/tests/HTBP/ping/ping.mpc @@ -0,0 +1,19 @@ +// -*- MPC -*- +// +// $Id$ + +project(*Server): aceexe, htbp { + exename = server + + Source_Files { + server.cpp + } +} + +project(*Client): aceexe, htbp { + exename = client + + Source_Files { + client.cpp + } +} diff --git a/ACE/protocols/tests/HTBP/ping/run_test.pl b/ACE/protocols/tests/HTBP/ping/run_test.pl new file mode 100755 index 00000000000..b769c37757e --- /dev/null +++ b/ACE/protocols/tests/HTBP/ping/run_test.pl @@ -0,0 +1,59 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ +# -*- perl -*- + +use lib "$ENV{ACE_ROOT}/bin"; +use PerlACE::Run_Test; +use Sys::Hostname; + +$status = 0; +$host = hostname(); +$port = PerlACE::random_port(); +$synchbase = "ready"; +$synchfile = PerlACE::LocalFile ("$synchbase"); + +print "port = $port\n"; +if (PerlACE::is_vxworks_test()) { + $host = $ENV{'ACE_RUN_VX_TGTHOST'}; + $SV = new PerlACE::ProcessVX ("server", "-p $port -o $synchbase"); +} +else { + $SV = new PerlACE::Process ("server", "-p $port -o $synchfile"); +} + +# The client code should later be modified to get the hostname +# using ACE_OS::hostname so the same script can be run on all +# hosts without havng to reset the host where it has to be run. +$CL = new PerlACE::Process ("client", " -h $host -p $port"); + +unlink $synchfile; + +$SV->Spawn (); + +if (PerlACE::waitforfile_timed ($synchfile, + $PerlACE::wait_interval_for_process_creation) == -1) { + print STDERR "ERROR: cannot find file <$synchfile>\n"; + $SV->Kill (); $SV->TimedWait (1); + exit 1; +} + +unlink $synchfile; + +$client = $CL->SpawnWaitKill (300); + +if ($client != 0) { + print STDERR "ERROR: client returned $client\n"; + $status = 1; +} + +$server = $SV->WaitKill (10); + +if ($server != 0) { + print STDERR "ERROR: server returned $server\n"; + $status = 1; +} + +exit $status; diff --git a/ACE/protocols/tests/HTBP/ping/server.cpp b/ACE/protocols/tests/HTBP/ping/server.cpp new file mode 100644 index 00000000000..7bde988c3cf --- /dev/null +++ b/ACE/protocols/tests/HTBP/ping/server.cpp @@ -0,0 +1,191 @@ +/** + * server for a basic connection establishment test using HTBP + * + * $Id$ + */ + +#include "ace/Log_Msg.h" + +#include "ace/HTBP/HTBP_Session.h" +#include "ace/HTBP/HTBP_Stream.h" +#include "ace/HTBP/HTBP_Addr.h" + +#include "ace/SOCK_Acceptor.h" +#include "ace/SOCK_Stream.h" +#include "ace/Get_Opt.h" +#include "ace/OS_NS_stdio.h" + +unsigned port = 8088; +const ACE_TCHAR *notifier_file = 0; +int +parse_args (int argc, ACE_TCHAR *argv[]) +{ + ACE_Get_Opt get_opts (argc, argv, ACE_TEXT("p:o:")); + int c; + + while ((c = get_opts ()) != -1) + switch (c) + { + case 'o': + notifier_file = get_opts.opt_arg(); + break; + case 'p': + port = static_cast<unsigned>(ACE_OS::atoi (get_opts.opt_arg())); + break; + case '?': + default: + ACE_ERROR_RETURN ((LM_ERROR, + "usage: %s " + "-p port " + "\n", + argv [0]), + -1); + } + // Indicates sucessful parsing of the command line + return 0; +} + +int +ACE_TMAIN (int argc , ACE_TCHAR *argv[]) +{ + char buffer[1000]; + ssize_t n = 0; + ACE_OS::socket_init (ACE_WSOCK_VERSION); + + if (parse_args(argc, argv) != 0) + return 1; + + ACE_TCHAR host[MAXHOSTNAMELEN+1]; + if (ACE_OS::hostname (host, MAXHOSTNAMELEN) != 0) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("(%P|%t) Server failure: %p\n"), + ACE_TEXT ("hostname")), + 1); + + ACE_INET_Addr local (port, host); + ACE_SOCK_Stream sock[2]; + ACE_SOCK_Acceptor acc(local, 1); + local.addr_to_string (host, MAXHOSTNAMELEN); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Server is ready on %s\n"), + host)); + if (notifier_file != 0) + { + FILE *f = ACE_OS::fopen (notifier_file,ACE_TEXT("w+")); + const char *msg = "server ready"; + ACE_OS::fwrite (msg,ACE_OS::strlen(msg),1,f); + ACE_OS::fclose (f); + } + acc.accept (sock[0]); + ACE::HTBP::Channel channel1(sock[0]); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Server: ") + ACE_TEXT ("Got sock[0], handle = %d\n"), + sock[0].get_handle())); + acc.accept (sock[1]); + ACE::HTBP::Channel channel2 (sock[1]); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Server: ") + ACE_TEXT ("Got sock[1], handle = %d\n"), + sock[1].get_handle())); + int res = 0; + while ((res = channel1.pre_recv ()) != 0) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Server: ") + ACE_TEXT ("res = %d. waiting 1 sec. %p\n"), + res, + ACE_TEXT ("stream.pre_recv()"))); + ACE_OS::sleep (1); + } + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Read from channel2\n"))); + while ((res = channel2.pre_recv()) != 0) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Server: ") + ACE_TEXT ("res = %d, waiting 1 sec. %p\n"), + res, + ACE_TEXT ("stream2.pre_recv()"))); + ACE_OS::sleep (1); + } + + ACE::HTBP::Session *session = channel1.session(); + ACE::HTBP::Stream stream (session); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Server: ") + ACE_TEXT ("using streams %d, %d. Got sesssion = %@\n"), + sock[0].get_handle(), + sock[1].get_handle(), + session)); + + for (int i = 0; i >= 0; i++) + { + int retrycount = 10; + while ((n = stream.recv(buffer,1000)) == -1 + && (errno == EWOULDBLOCK || errno == ETIME) + && retrycount > 0) + { + retrycount--; + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Server: ") + ACE_TEXT ("waiting for inbound data, %d tries left\n"), + retrycount)); + ACE_OS::sleep(1); + } + if (retrycount == 0 || n < 0) + break; + + buffer[n] = 0; + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Server: ") + ACE_TEXT ("Got: \"%C\"\n"), buffer)); + + if (ACE_OS::strstr (buffer,"goodbye") != 0) + break; + + ACE_OS::sprintf (buffer,"I hear you %d",i); + n = stream.send (buffer,ACE_OS::strlen(buffer)+1); + if (n == -1) + ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), + ACE_TEXT ("stream.send")), + -1); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Server: Send returned %d\n"), n)); + + int got[2] = {-1,-1}; + while (got[0] == -1 || got[1] == -1) + { + if (got[0] == -1) + { + if ((got[0] = (res =channel1.pre_recv())) == -1) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Server: ") + ACE_TEXT ("res = %d, waiting 1 sec. %p\n"), + got[0], + ACE_TEXT ("channel1.pre_recv()"))); + } + if (got[1] == -1) + { + if ((got[1] = (res =channel2.pre_recv())) == -1) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Server: ") + ACE_TEXT ("res = %d, waiting 1 sec. %p\n"), + got[1], + ACE_TEXT ("channel2.pre_recv()"))); + } + if (got[0] == -1 || got[1] == -1) + ACE_OS::sleep (1); + } + } + ACE_OS::sleep(1); // prevent test failure on windows when the connection + // closes too fast. + + stream.close(); + acc.close(); + + return 0; +} |