diff options
author | elliott_c <ocielliottc@users.noreply.github.com> | 2008-04-28 12:40:23 +0000 |
---|---|---|
committer | elliott_c <ocielliottc@users.noreply.github.com> | 2008-04-28 12:40:23 +0000 |
commit | 991b5be2aadacab5024c310935611843a0e2bfc6 (patch) | |
tree | d15d62b26b959e334abf9fbd1b8f11b00254e47b /TAO/tests | |
parent | 2378864442e1bad75fcb157f42e0433d3a1036fc (diff) | |
download | ATCD-991b5be2aadacab5024c310935611843a0e2bfc6.tar.gz |
ChangeLogTag: Mon Apr 28 12:42:36 UTC 2008 Chad Elliott <elliott_c@ociweb.com>
Diffstat (limited to 'TAO/tests')
-rw-r--r-- | TAO/tests/HandleExhaustion/HandleExhaustion.mpc | 31 | ||||
-rw-r--r-- | TAO/tests/HandleExhaustion/Makefile.am | 107 | ||||
-rw-r--r-- | TAO/tests/HandleExhaustion/README | 14 | ||||
-rw-r--r-- | TAO/tests/HandleExhaustion/Test.idl | 7 | ||||
-rw-r--r-- | TAO/tests/HandleExhaustion/client.cpp | 92 | ||||
-rwxr-xr-x | TAO/tests/HandleExhaustion/run_test.pl | 85 | ||||
-rw-r--r-- | TAO/tests/HandleExhaustion/server.cpp | 168 | ||||
-rw-r--r-- | TAO/tests/Makefile.am | 1 |
8 files changed, 505 insertions, 0 deletions
diff --git a/TAO/tests/HandleExhaustion/HandleExhaustion.mpc b/TAO/tests/HandleExhaustion/HandleExhaustion.mpc new file mode 100644 index 00000000000..5718c68b775 --- /dev/null +++ b/TAO/tests/HandleExhaustion/HandleExhaustion.mpc @@ -0,0 +1,31 @@ +// -*- MPC -*- +// $Id$ + +project(*idl): taoidldefaults { + IDL_Files { + Test.idl + } + custom_only = 1 +} + +project(*Server): taoserver { + after += *idl + IDL_Files { + } + Source_Files { + TestC.cpp + TestS.cpp + server.cpp + } +} + +project(*Client): taoclient { + after += *idl *Server + IDL_Files { + } + Source_Files { + TestC.cpp + client.cpp + } +} + diff --git a/TAO/tests/HandleExhaustion/Makefile.am b/TAO/tests/HandleExhaustion/Makefile.am new file mode 100644 index 00000000000..c29da80a90e --- /dev/null +++ b/TAO/tests/HandleExhaustion/Makefile.am @@ -0,0 +1,107 @@ +## 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 TAO.mwc + +ACE_BUILDDIR = $(top_builddir)/.. +ACE_ROOT = $(top_srcdir)/.. +TAO_BUILDDIR = $(top_builddir) +TAO_IDL = ACE_ROOT=$(ACE_ROOT) TAO_ROOT=$(TAO_ROOT) $(TAO_BUILDDIR)/TAO_IDL/tao_idl +TAO_IDL_DEP = $(TAO_BUILDDIR)/TAO_IDL/tao_idl +TAO_IDLFLAGS = -Wb,pre_include=ace/pre.h -Wb,post_include=ace/post.h -I$(TAO_ROOT) -I$(srcdir) -g $(ACE_BUILDDIR)/apps/gperf/src/gperf +TAO_ROOT = $(top_srcdir) + +noinst_PROGRAMS = + +## Makefile.HandleExhaustion_Idl.am + +BUILT_SOURCES = \ + TestC.cpp \ + TestC.h \ + TestC.inl \ + TestS.cpp \ + TestS.h \ + TestS.inl + +CLEANFILES = \ + Test-stamp \ + TestC.cpp \ + TestC.h \ + TestC.inl \ + TestS.cpp \ + TestS.h \ + TestS.inl + +TestC.cpp TestC.h TestC.inl TestS.cpp TestS.h TestS.inl: Test-stamp + +Test-stamp: $(srcdir)/Test.idl $(TAO_IDL_DEP) + $(TAO_IDL) $(TAO_IDLFLAGS) -Sa -St $(srcdir)/Test.idl + @touch "$@" + +noinst_HEADERS = \ + Test.idl + +## Makefile.HandleExhaustion_Server.am + +if BUILD_EXCEPTIONS + +noinst_PROGRAMS += server + +server_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(TAO_ROOT) \ + -I$(TAO_BUILDDIR) + +server_SOURCES = \ + TestC.cpp \ + TestS.cpp \ + server.cpp + +server_LDADD = \ + $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \ + $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \ + $(TAO_BUILDDIR)/tao/libTAO.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif BUILD_EXCEPTIONS + +## Makefile.HandleExhaustion_Client.am + +if BUILD_EXCEPTIONS + +noinst_PROGRAMS += client + +client_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(TAO_ROOT) \ + -I$(TAO_BUILDDIR) + +client_SOURCES = \ + TestC.cpp \ + client.cpp + +client_LDADD = \ + $(TAO_BUILDDIR)/tao/libTAO.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif BUILD_EXCEPTIONS + + +ACLOCAL = @ACLOCAL@ +ACLOCAL_AMFLAGS = -I m4 +AUTOMAKE_OPTIONS = foreign + +## 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/TAO/tests/HandleExhaustion/README b/TAO/tests/HandleExhaustion/README new file mode 100644 index 00000000000..5b96077a24c --- /dev/null +++ b/TAO/tests/HandleExhaustion/README @@ -0,0 +1,14 @@ +This test is designed to test the very rare situation where an accept() will +fail due to the fact that no file descriptors are available to the process +(or system). It assumes that file handles and socket handles come from the +same pool (i.e., Non-Win32 systems). + +The server opens a file (the server executable itself) read-only until it +runs out of file handles. It then enters the ORB run loop. When the client +is started it attempts to call a two-way method which will initiate the +connection. This will trigger the accept error handling code in the +TAO_Acceptor. Prior to this code, the server process would tightly spin +attempting to accept() the new connection. + +Unfortunately, the test relies on TAO debug messages to detect that the +error situation occurred and that the error handling code was run. diff --git a/TAO/tests/HandleExhaustion/Test.idl b/TAO/tests/HandleExhaustion/Test.idl new file mode 100644 index 00000000000..1406633df03 --- /dev/null +++ b/TAO/tests/HandleExhaustion/Test.idl @@ -0,0 +1,7 @@ +// $Id$ + +interface Test +{ + void simple (); + oneway void shutdown (); +}; diff --git a/TAO/tests/HandleExhaustion/client.cpp b/TAO/tests/HandleExhaustion/client.cpp new file mode 100644 index 00000000000..f8508b42e2b --- /dev/null +++ b/TAO/tests/HandleExhaustion/client.cpp @@ -0,0 +1,92 @@ +// $Id$ + +#include "TestC.h" +#include "ace/Get_Opt.h" +#include "ace/OS_NS_unistd.h" + +ACE_RCSID(ConnectionSpinning, + client, "$Id$") + +static const char *ior = "file://server.ior"; + +int +parse_args (int argc, char *argv[]) +{ + ACE_Get_Opt get_opts (argc, argv, "k:x"); + int c; + + while ((c = get_opts ()) != -1) + switch (c) + { + case 'k': + ior = get_opts.opt_arg (); + break; + + case '?': + default: + ACE_ERROR_RETURN ((LM_ERROR, + "usage: %s " + "-k <ior> " + "\n", + argv [0]), + -1); + } + // Indicates sucessful parsing of the command line + return 0; +} + +int +main (int argc, char *argv[]) +{ + try + { + CORBA::ORB_var orb = + CORBA::ORB_init (argc, argv, ""); + + if (parse_args (argc, argv) != 0) + return 1; + + CORBA::Object_var tmp = + orb->string_to_object(ior); + + Test_var test = Test::_narrow(tmp.in ()); + + if (CORBA::is_nil (test.in ())) + { + ACE_ERROR_RETURN ((LM_DEBUG, "Nil Test reference <%s>\n", ior), 1); + } + + // Try a few times until we run out of "trys" or we no longer get + // an exception. Some times it takes a little while to begin + // accepting again on AIX. + for(size_t i = 0; i < 10; i++) + try + { + // This first invocation will actually cause the connection to + // the server. Since the server has run out of file handles, + // it can not accept the new connection. On AIX, this will + // receive a CORBA::COMM_FAILURE exception because it doesn't + // complete in a timely manner. It does not mean that the test + // has failed, as long as the server performs the correct + // function. + test->simple (); + break; + } + catch (const CORBA::COMM_FAILURE&) + { + ACE_OS::sleep (1); + } + + test->simple (); + test->shutdown (); + + orb->destroy (); + } + catch (const CORBA::Exception& ex) + { + ex._tao_print_exception ("Exception caught:"); + return 1; + } + + return 0; +} diff --git a/TAO/tests/HandleExhaustion/run_test.pl b/TAO/tests/HandleExhaustion/run_test.pl new file mode 100755 index 00000000000..b5f2133a104 --- /dev/null +++ b/TAO/tests/HandleExhaustion/run_test.pl @@ -0,0 +1,85 @@ +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 strict; + +if ($^O eq 'hpux') { + print "This test will not run properly on HP-UX.\n", + "When one process uses up all of the file descriptors, no other\n", + "processes run by the same user can start.\n"; + exit(0); +} + +my $status = 0; +my $iorfile = 'server.ior'; +my $logfile = 'server.log'; +my $class = (PerlACE::is_vxworks_test() ? 'PerlACE::ProcessVX' : + 'PerlACE::Process'); +my $SV = $class->new('server', '-ORBAcceptErrorDelay 5 -ORBDebugLevel 1 ' . + "-ORBLogFile $logfile"); +my $CL = new PerlACE::Process('client'); + +unlink($iorfile, $logfile); +my $server = $SV->Spawn(); + +if ($server != 0) { + print STDERR "ERROR: server returned $server\n"; + exit(1); +} + +if (PerlACE::waitforfile_timed( + $iorfile, + $PerlACE::wait_interval_for_process_creation) == -1) { + print STDERR "ERROR: cannot find file <$iorfile>\n"; + $SV->Kill(); + exit(1); +} + +my $client = $CL->SpawnWaitKill(30); + +if ($client != 0) { + print STDERR "ERROR: client returned $client\n"; + $status = 1; +} + +$server = $SV->WaitKill(5); + +if ($server != 0) { + print STDERR "ERROR: server returned $server\n"; + $status = 1; +} + +if ($status == 0) { + if (open(FH, $logfile)) { + my $error_achieved = 0; + my $reregister = 0; + while(<FH>) { + if (/TAO_Acceptor::handle_accept_error.+Too many files open/) { + ++$error_achieved; + } + elsif (/TAO_Acceptor::handle_expiration.+registering\s+the\s+acceptor/) { + ++$reregister; + } + } + close(FH); + + if (!$error_achieved) { + print "ERROR: The error situation was not achieved\n"; + ++$status; + } + if (!$reregister) { + print "ERROR: The acceptor was not reregistered\n"; + ++$status; + } + } +} + +unlink($iorfile, $logfile); + +exit($status); diff --git a/TAO/tests/HandleExhaustion/server.cpp b/TAO/tests/HandleExhaustion/server.cpp new file mode 100644 index 00000000000..0fcd06572da --- /dev/null +++ b/TAO/tests/HandleExhaustion/server.cpp @@ -0,0 +1,168 @@ +// $Id$ + +#include "TestS.h" +#include "ace/Get_Opt.h" +#include "ace/OS_NS_stdio.h" +#include "ace/OS_NS_fcntl.h" +#include "ace/OS_NS_unistd.h" + +ACE_RCSID (ConnectionSpinning, + server, "$Id$") + +const char *ior_output_file = "server.ior"; + +class Test_i: public virtual POA_Test +{ +public: + Test_i (CORBA::ORB_ptr orb) + : orb_ (CORBA::ORB::_duplicate (orb)) { + } + + void simple (void) { + } + + void shutdown (void) { + this->orb_->shutdown (); + } + +private: + CORBA::ORB_var orb_; +}; + +class Descriptors +{ +public: + Descriptors (void) + : slast_ (ACE_INVALID_HANDLE), + last_ (ACE_INVALID_HANDLE), + ok_ (false) { + } + + int allow_accepts (void) { + ACE_OS::close(this->slast_); + ACE_OS::close(this->last_); + this->ok_ = true; + return 0; + } + + void leak (const char* file) { + for (size_t i = 0; i < 0xffff; i++) { + ACE_HANDLE h = ACE_OS::open (file, O_RDONLY); + if (h == ACE_INVALID_HANDLE) { + break; + } + + // Save the last two file handles so that they can be closed later + // on. We need two for this test to work with SHMIOP. + this->slast_ = this->last_; + this->last_ = h; + } + } + + bool ok (void) const { + return this->ok_ && this->last_ != ACE_INVALID_HANDLE; + } + +private: + ACE_HANDLE slast_; + ACE_HANDLE last_; + bool ok_; +}; + +int +parse_args (int argc, char *argv[]) +{ + ACE_Get_Opt get_opts (argc, argv, "o:"); + int c; + + while ((c = get_opts ()) != -1) + switch (c) + { + case 'o': + ior_output_file = get_opts.opt_arg (); + break; + + case '?': + default: + ACE_ERROR_RETURN ((LM_ERROR, + "usage: %s " + "-o <iorfile>" + "\n", + argv [0]), + -1); + } + // Indicates sucessful parsing of the command line + return 0; +} + +int +main (int argc, char *argv[]) +{ + try + { + CORBA::ORB_var orb = + CORBA::ORB_init (argc, argv, ""); + + CORBA::Object_var poa_object = + orb->resolve_initial_references("RootPOA"); + + PortableServer::POA_var root_poa = + PortableServer::POA::_narrow (poa_object.in ()); + + if (CORBA::is_nil (root_poa.in ())) + ACE_ERROR_RETURN ((LM_ERROR, + " (%P|%t) Panic: nil RootPOA\n"), + 1); + + if (parse_args (argc, argv) != 0) + return 1; + + Test_i* test_i; + ACE_NEW_RETURN (test_i, + Test_i (orb.in ()), + 1); + PortableServer::ServantBase_var owner_transfer(test_i); + + PortableServer::ObjectId_var id = root_poa->activate_object (test_i); + + CORBA::Object_var object = root_poa->id_to_reference (id.in ()); + + Test_var test = Test::_narrow (object.in ()); + + CORBA::String_var ior = orb->object_to_string (test.in ()); + + // Output the IOR to the <ior_output_file> + FILE *output_file= ACE_OS::fopen (ior_output_file, "w"); + if (output_file == 0) + ACE_ERROR_RETURN ((LM_ERROR, + "Cannot open output file for writing IOR: %s\n", + ior_output_file), + 1); + ACE_OS::fprintf (output_file, "%s", ior.in ()); + ACE_OS::fclose (output_file); + + PortableServer::POAManager_var poa_manager = + root_poa->the_POAManager (); + poa_manager->activate (); + + Descriptors descriptors; + descriptors.leak (argv[0]); + + ACE_Time_Value tv (10); + orb->run (tv); + + descriptors.allow_accepts (); + orb->run (); + orb->destroy (); + + if (!descriptors.ok ()) + ACE_ERROR_RETURN ((LM_ERROR, "The accept error never occurred\n"), 1); + } + catch (const CORBA::Exception& ex) + { + ex._tao_print_exception ("Exception caught:"); + return 1; + } + + return 0; +} diff --git a/TAO/tests/Makefile.am b/TAO/tests/Makefile.am index d0fa0653208..91e8a8b1d7f 100644 --- a/TAO/tests/Makefile.am +++ b/TAO/tests/Makefile.am @@ -147,6 +147,7 @@ SUBDIRS = \ File_IO \ Forwarding \ GIOP_Fragments \ + HandleExhaustion \ Hang_Shutdown \ Hello \ ICMG_Any_Bug \ |