diff options
Diffstat (limited to 'TAO/tests/Multiple_Retry_Tests/Retry_On_Reply_Failure')
8 files changed, 721 insertions, 0 deletions
diff --git a/TAO/tests/Multiple_Retry_Tests/Retry_On_Reply_Failure/README b/TAO/tests/Multiple_Retry_Tests/Retry_On_Reply_Failure/README new file mode 100755 index 00000000000..b24ca308f8c --- /dev/null +++ b/TAO/tests/Multiple_Retry_Tests/Retry_On_Reply_Failure/README @@ -0,0 +1,23 @@ +/** + +$Id$ + +@page Retry_On_Reply_Failure Test README File + + This is test for the invocation retry feature when a client + receives OBJECT_NOT_EXIST, COMM_FAILURE, TRANSIENT or INV_OBJREF + exceptions from server as a reply to a request. + This feature can be enabled and disabled by -ORBForwardOnObjectNotExistLimit + -ORBForwardOnCommFailureLimit, -ORBForwardOnOnTransientLimit and + -ORBForwardOnInvObjLimit options with value 0(disable) and 1(enable). + + The starting point for this test implementation was the + ForwardOnceUponException test. + + To execute the test simply run: + +$ ./run_test.pl + + the script returns 0 on success and non-zero on failures. + +*/ diff --git a/TAO/tests/Multiple_Retry_Tests/Retry_On_Reply_Failure/Retry_On_Reply_Failure.mpc b/TAO/tests/Multiple_Retry_Tests/Retry_On_Reply_Failure/Retry_On_Reply_Failure.mpc new file mode 100755 index 00000000000..ee705f01845 --- /dev/null +++ b/TAO/tests/Multiple_Retry_Tests/Retry_On_Reply_Failure/Retry_On_Reply_Failure.mpc @@ -0,0 +1,35 @@ +// -*- MPC -*- +// $Id$ + +project(*idl): taoidldefaults { + IDL_Files { + test.idl + } + custom_only = 1 +} + +project(*Server): taoserver, iortable { + after += *idl + Source_Files { + test_i.cpp + server.cpp + } + Source_Files { + testC.cpp + testS.cpp + } + IDL_Files { + } +} + +project(*Client): taoclient, anytypecode { + after += *idl + Source_Files { + client.cpp + } + Source_Files { + testC.cpp + } + IDL_Files { + } +} diff --git a/TAO/tests/Multiple_Retry_Tests/Retry_On_Reply_Failure/client.cpp b/TAO/tests/Multiple_Retry_Tests/Retry_On_Reply_Failure/client.cpp new file mode 100755 index 00000000000..ecd2d0df42d --- /dev/null +++ b/TAO/tests/Multiple_Retry_Tests/Retry_On_Reply_Failure/client.cpp @@ -0,0 +1,278 @@ +// $Id$ + +#include "testC.h" +#include "ace/Get_Opt.h" +#include "ace/Task.h" +#include "ace/streams.h" +#include "tao/Invocation_Utils.h" +#include "ace/OS_NS_unistd.h" + +const ACE_TCHAR *ior = ACE_TEXT("file://test.ior"); +int nthreads = 1; +static const ACE_TCHAR corbaloc_prefix[] = ACE_TEXT("corbaloc:"); +int expect_ex_kind = TAO::FOE_NON; +int num_requests = 1; + +int +parse_args (int argc, ACE_TCHAR *argv[]) +{ + ACE_Get_Opt get_opts (argc, argv, ACE_TEXT("k:e:")); + int c; + + while ((c = get_opts ()) != -1) + switch (c) + { + case 'k': + ior = get_opts.opt_arg (); + break; + + case 'e': + expect_ex_kind = ACE_OS::atoi (get_opts.opt_arg ()); + break; + + case '?': + default: + ACE_ERROR_RETURN ((LM_ERROR, + "usage: %s " + "-k <ior>" + "-e <expected exception kind> " + "\n", + argv [0]), + -1); + } + + if (ACE_OS::strncmp (ior, + corbaloc_prefix, + ACE_OS::strlen(corbaloc_prefix)) != 0) + return 1; + + // Indicates successful parsing of the command line + return 0; +} + +class Worker : public ACE_Task_Base +{ +public: + Worker (CORBA::ORB_ptr orb); + // Constructor + + // = The Task_Base methods + virtual int svc (void); + + // Caught any exception ? + int received_ex_kind () const; + + // Return number of received exceptions. + int num_received_ex () const; + + // Indicate if the invocation completed. + bool invocation_completed () const; + + // Is test done ? + void done (); + +private: + + // The ORB reference + CORBA::ORB_var orb_; + // The exceptions caught. + int received_ex_kind_; + // The number of received exceptions. + int num_received_ex_; + // Flag indicating that the invocation was completed. + bool invocation_completed_; + // Flag for test completion. The result is + // collected before done. + bool done_; +}; + +int +ACE_TMAIN(int argc, ACE_TCHAR *argv[]) +{ + try + { + CORBA::ORB_var orb = + CORBA::ORB_init (argc, argv); + + if (parse_args (argc, argv) != 0) + return 1; + + Worker worker (orb.in ()); + + if (worker.activate (THR_NEW_LWP | THR_JOINABLE, + nthreads) != 0) + ACE_ERROR_RETURN ((LM_ERROR, + "(%P|%t) Cannot activate worker threads\n"), + 1); + + int timeout = 30; + int now = 0; + while (now < timeout && + ((expect_ex_kind == 0 && !worker.invocation_completed ()) || + (expect_ex_kind != 0 && expect_ex_kind != worker.received_ex_kind ())) + ) + { + std::cout << "." << std::flush; + now += 1; + ACE_Time_Value tv (1, 0); + orb->run (tv); + } + ACE_ASSERT (now != 0); + + + std::cout << std::endl; + + worker.done (); + + CORBA::Object_var object = + orb->string_to_object (ior); + + Simple_Server_var server = + Simple_Server::_narrow (object.in ()); + + server->shutdown (); + + ACE_OS::sleep (1); + + orb->destroy (); + + worker.thr_mgr ()->wait (); + + + bool expect_no_ex = + expect_ex_kind == TAO::FOE_NON && worker.num_received_ex () == 0 && worker.invocation_completed (); + bool expect_ex_received = + expect_ex_kind == worker.received_ex_kind () && worker.num_received_ex () > 0 && !worker.invocation_completed (); + if (expect_no_ex || expect_ex_received) + { + ACE_DEBUG ((LM_DEBUG, "(%P|%t)client: test passed.\n")); + return 0; + } + else + { + ACE_DEBUG ((LM_ERROR, "(%P|%t)client: test failed.\n")); + return 1; + } + } + + catch (const CORBA::Exception& ex) + { + ex._tao_print_exception ("Exception caught in main:"); + return 1; + } + + return 0; +} + +// **************************************************************** + +Worker::Worker (CORBA::ORB_ptr orb) + : orb_ (CORBA::ORB::_duplicate (orb)), + received_ex_kind_ (TAO::FOE_NON), + num_received_ex_ (0), + invocation_completed_ (false), + done_ (false) +{ +} + +int +Worker::svc (void) +{ + try + { + CORBA::Object_var object = + this->orb_->string_to_object (ior); + + Simple_Server_var server = + Simple_Server::_narrow (object.in ()); + + if (CORBA::is_nil (server.in ())) + { + ACE_ERROR ((LM_ERROR, + "Object reference <%s> is nil.\n", + ior)); + return 0; + } + + try { + CORBA::Boolean r = + server->test_is_a ("IDL:Foo:1.0"); + + this->invocation_completed_ = true; + + if (r != 0) + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) unexpected result = %d\n", + r)); + + } + catch (const CORBA::OBJECT_NOT_EXIST &) + { + ACE_DEBUG ((LM_DEBUG, "(%P|%t)received OBJECT_NOT_EXIST \n")); + if (!this->done_) + { + ++ this->num_received_ex_; + received_ex_kind_ |= TAO::FOE_OBJECT_NOT_EXIST; + } + } + catch (const CORBA::COMM_FAILURE &) + { + ACE_DEBUG ((LM_DEBUG, "(%P|%t)received COMM_FAILURE \n")); + if (!this->done_) + { + ++ this->num_received_ex_; + received_ex_kind_ |= TAO::FOE_COMM_FAILURE; + } + } + catch (const CORBA::TRANSIENT &) + { + ACE_DEBUG ((LM_DEBUG, "(%P|%t)received TRANSIENT \n")); + if (!this->done_) + { + ++ this->num_received_ex_; + received_ex_kind_ |= TAO::FOE_TRANSIENT; + } + } + catch (const CORBA::INV_OBJREF &) + { + ACE_DEBUG ((LM_DEBUG, "(%P|%t)received INV_OBJREF \n")); + if (!this->done_) + { + ++ this->num_received_ex_; + received_ex_kind_ |= TAO::FOE_INV_OBJREF; + } + } + } + catch (const CORBA::Exception& ex) + { + ex._tao_print_exception ("Unexpected exception caught"); + } + + return 0; +} + + +int +Worker::received_ex_kind () const +{ + return received_ex_kind_; +} + +int +Worker::num_received_ex () const +{ + return num_received_ex_; +} + +bool +Worker::invocation_completed () const +{ + return invocation_completed_; +} + +void +Worker::done () +{ + done_ = true; +} + diff --git a/TAO/tests/Multiple_Retry_Tests/Retry_On_Reply_Failure/run_test.pl b/TAO/tests/Multiple_Retry_Tests/Retry_On_Reply_Failure/run_test.pl new file mode 100755 index 00000000000..4f779484bd7 --- /dev/null +++ b/TAO/tests/Multiple_Retry_Tests/Retry_On_Reply_Failure/run_test.pl @@ -0,0 +1,152 @@ +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::TestTarget; + +$status = 0; +$debug_level = '0'; + +foreach $i (@ARGV) { + if ($i eq '-debug') { + $debug_level = '10'; + } +} + +# Current supported forward once exceptions: +# EF_OBJECT_NOT_EXIST = 0x1, +# EF_COMM_FAILURE = 0x2, +# EF_TRANSIENT = 0x4, +# EF_INV_OBJREF = 0x8, +@configurations = ({ + description => "case 1: retry on OBJECT_NOT_EXIST exceptions until no failure", + orb_invocation_retry_opts => "-ORBForwardOnObjectNotExistLimit 10 -ORBForwardDelay 50", + client_expect_ex_kind => "0", + server_raise_ex_kind => "1", + num_exceptions_to_throw => 2, + },{ + description => "case 2: retry on OBJECT_NOT_EXIST exceptions and give up", + orb_invocation_retry_opts => "-ORBForwardOnObjectNotExistLimit 1 -ORBForwardDelay 50", + client_expect_ex_kind => "1", + server_raise_ex_kind => "1", + num_exceptions_to_throw => 2, + },{ + description => "case 3: retry on COMM_FAILURE exceptions until no failure", + orb_invocation_retry_opts => "-ORBForwardOnCommFailureLimit 10 -ORBForwardDelay 50", + client_expect_ex_kind => "0", + server_raise_ex_kind => "2", + num_exceptions_to_throw => 2, + },{ + description => "case 4: retry on COMM_FAILURE exceptions and give up", + orb_invocation_retry_opts => "-ORBForwardOnCommFailureLimit 1 -ORBForwardDelay 50", + client_expect_ex_kind => "2", + server_raise_ex_kind => "2", + num_exceptions_to_throw => 2, + },{ + description => "case 5: retry on TRANSIENT exceptions until no failure", + orb_invocation_retry_opts => "-ORBForwardOnTransientLimit 10 -ORBForwardDelay 50", + client_expect_ex_kind => "0", + server_raise_ex_kind => "4", + num_exceptions_to_throw => 2, + },{ + description => "case 6: retry on TRANSIENT exceptions and give up", + orb_invocation_retry_opts => "-ORBForwardOnTransientLimit 1 -ORBForwardDelay 50", + client_expect_ex_kind => "4", + server_raise_ex_kind => "4", + num_exceptions_to_throw => 2, + },{ + description => "case 7: retry on INV_OBJREF exceptions until no failure", + orb_invocation_retry_opts => "-ORBForwardOnInvObjrefLimit 10 -ORBForwardDelay 50", + client_expect_ex_kind => "0", + server_raise_ex_kind => "8", + num_exceptions_to_throw => 2, + },{ + description => "case 8: retry on INV_OBJREF exceptions and give up", + orb_invocation_retry_opts => "-ORBForwardOnInvObjrefLimit 1 -ORBForwardDelay 50", + client_expect_ex_kind => "8", + server_raise_ex_kind => "8", + num_exceptions_to_throw => 2, + }, + + + + ); + +my $server = PerlACE::TestTarget::create_target (1) || die "Create target 1 failed\n"; +my $client = PerlACE::TestTarget::create_target (2) || die "Create target 2 failed\n"; + +my $iorbase = "test.ior"; +my $host = $server->HostName(); +my $server_iorfile = $server->LocalFile ($iorbase); +my $client_iorfile = $client->LocalFile ($iorbase); + +for $test (@configurations) { + print STDERR "\n==== Running $test->{description} \n\n"; + + my $port = $server->RandomPort(); + $server->DeleteFile($iorbase); + $client->DeleteFile($iorbase); + + $SV = $server->CreateProcess ("server", "-ORBdebuglevel $debug_level ". + "-o $server_iorfile ". + "-ORBEndpoint iiop://$host:$port ". + "-e $test->{server_raise_ex_kind} ". + "-n $test->{num_exceptions_to_throw}"); + + $CL = $client->CreateProcess ("client", "-k corbaloc::$host:$port/Simple_Server ". + "-e $test->{client_expect_ex_kind} ". + "$test->{orb_invocation_retry_opts}"); + + print STDERR $SV->CommandLine () . "\n"; + print STDERR $CL->CommandLine () . "\n"; + + $server_status = $SV->Spawn (); + + if ($server_status != 0) { + print STDERR "ERROR: server returned $server_status\n"; + exit 1; + } + + if ($server->WaitForFileTimed ($iorbase, + $server->ProcessStartWaitInterval()) == -1) { + print STDERR "ERROR: cannot find file <$server_iorfile>\n"; + $SV->Kill (); $SV->TimedWait (1); + exit 1; + } + + if ($server->GetFile ($iorbase) == -1) { + print STDERR "ERROR: cannot retrieve file <$server_iorfile>\n"; + $SV->Kill (); $SV->TimedWait (1); + exit 1; + } + + if ($client->PutFile ($iorbase) == -1) { + print STDERR "ERROR: cannot set file <$client_iorfile>\n"; + $SV->Kill (); $SV->TimedWait (1); + exit 1; + } + + $client_status = $CL->SpawnWaitKill ($client->ProcessStartWaitInterval() + 45); + + if ($client_status != 0) { + print STDERR "ERROR: client returned $client_status\n"; + $status = 1; + } + + $server_status = $SV->WaitKill ($server->ProcessStopWaitInterval()); + + if ($server_status != 0) { + print STDERR "ERROR: server returned $server_status\n"; + $status = 1; + } + +} + +$server->DeleteFile($iorbase); +$client->DeleteFile($iorbase); + +exit $status; diff --git a/TAO/tests/Multiple_Retry_Tests/Retry_On_Reply_Failure/server.cpp b/TAO/tests/Multiple_Retry_Tests/Retry_On_Reply_Failure/server.cpp new file mode 100755 index 00000000000..295e3bd018d --- /dev/null +++ b/TAO/tests/Multiple_Retry_Tests/Retry_On_Reply_Failure/server.cpp @@ -0,0 +1,121 @@ +// $Id$ + +#include "test_i.h" +#include "tao/IORTable/IORTable.h" +#include "ace/Get_Opt.h" +#include "ace/OS_NS_stdio.h" +#include "tao/Invocation_Utils.h" + +const ACE_TCHAR *ior_output_file = ACE_TEXT("test.ior"); +int num_exceptions_to_throw = 0; +int raise_exception = TAO::FOE_NON; +int num_requests = 1; + +int +parse_args (int argc, ACE_TCHAR *argv[]) +{ + ACE_Get_Opt get_opts (argc, argv, ACE_TEXT("o:e:n:")); + int c; + + while ((c = get_opts ()) != -1) + switch (c) + { + case 'o': + ior_output_file = get_opts.opt_arg (); + break; + case 'e': + raise_exception = ACE_OS::atoi (get_opts.opt_arg ()); + break; + case 'n': + num_exceptions_to_throw = ACE_OS::atoi (get_opts.opt_arg ()); + break; + case '?': + default: + ACE_ERROR_RETURN ((LM_ERROR, + "usage: %s " + "-o <iorfile> -e <raise_exception> -n <num_exceptions_to_throw>" + "\n", + argv [0]), + -1); + } + // Indicates successful parsing of the command line + return 0; +} + +int +ACE_TMAIN(int argc, ACE_TCHAR *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) Unable to initialize the POA.\n"), + 1); + + PortableServer::POAManager_var poa_manager = + root_poa->the_POAManager (); + + if (parse_args (argc, argv) != 0) + return 1; + + Simple_Server_i server_impl (orb.in (), num_exceptions_to_throw); + + PortableServer::ObjectId_var id = + root_poa->activate_object (&server_impl); + + CORBA::Object_var object = root_poa->id_to_reference (id.in ()); + + Simple_Server_var server = + Simple_Server::_narrow (object.in ()); + + CORBA::String_var ior = + orb->object_to_string (server.in ()); + + CORBA::Object_var table_object = + orb->resolve_initial_references("IORTable"); + + IORTable::Table_var table = + IORTable::Table::_narrow (table_object.in ()); + if (CORBA::is_nil (table.in ())) + ACE_ERROR_RETURN ((LM_ERROR, + " (%P|%t) Unable to initialize the IORTable.\n"), + 1); + table->bind ("Simple_Server", ior.in ()); + + //ACE_DEBUG ((LM_DEBUG, "Activated as <%C>\n", ior.in ())); + + 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", + ior_output_file), + 1); + ACE_OS::fprintf (output_file, "%s", ior.in ()); + ACE_OS::fclose (output_file); + + poa_manager->activate (); + + orb->run (); + + ACE_DEBUG ((LM_DEBUG, "(%P|%t)server: event loop finished\n")); + + root_poa->destroy (1, 1); + + orb->destroy (); + } + catch (const CORBA::Exception& ex) + { + ex._tao_print_exception ("Exception caught in server:"); + return 1; + } + + return 0; +} diff --git a/TAO/tests/Multiple_Retry_Tests/Retry_On_Reply_Failure/test.idl b/TAO/tests/Multiple_Retry_Tests/Retry_On_Reply_Failure/test.idl new file mode 100755 index 00000000000..b9aa7108ed3 --- /dev/null +++ b/TAO/tests/Multiple_Retry_Tests/Retry_On_Reply_Failure/test.idl @@ -0,0 +1,8 @@ +// $Id$ + +interface Simple_Server +{ + boolean test_is_a (in string type); + + oneway void shutdown (); +}; diff --git a/TAO/tests/Multiple_Retry_Tests/Retry_On_Reply_Failure/test_i.cpp b/TAO/tests/Multiple_Retry_Tests/Retry_On_Reply_Failure/test_i.cpp new file mode 100755 index 00000000000..042b552b16d --- /dev/null +++ b/TAO/tests/Multiple_Retry_Tests/Retry_On_Reply_Failure/test_i.cpp @@ -0,0 +1,58 @@ +// $Id$ + +#include "test_i.h" +#include "tao/Invocation_Utils.h" + +extern int raise_exception; + +Simple_Server_i::Simple_Server_i (CORBA::ORB_ptr orb, int num_exceptions_to_throw) + : orb_ (CORBA::ORB::_duplicate (orb)) + , num_exceptions_to_throw_(num_exceptions_to_throw) + , num_exceptions_thrown_(0) + , raise_exception_ (TAO::FOE_NON) +{ +} + +CORBA::Boolean +Simple_Server_i::test_is_a (const char * /* type */) +{ + if (this->num_exceptions_thrown_ == + this->num_exceptions_to_throw_) + return 0; + + if ((raise_exception & TAO::FOE_OBJECT_NOT_EXIST) == TAO::FOE_OBJECT_NOT_EXIST) + { + //ACE_DEBUG ((LM_DEBUG, "(%P|%t) test_is_a called and raise OBJECT_NOT_EXIST\n")); + ++this->num_exceptions_thrown_; + throw ::CORBA::OBJECT_NOT_EXIST (CORBA::OMGVMCID | 1, CORBA::COMPLETED_NO); + } + + if ((raise_exception & TAO::FOE_COMM_FAILURE) == TAO::FOE_COMM_FAILURE) + { + //ACE_DEBUG ((LM_DEBUG, "(%P|%t) test_is_a called and raise COMM_FAILURE\n")); + ++this->num_exceptions_thrown_; + throw ::CORBA::COMM_FAILURE (CORBA::OMGVMCID | 1, CORBA::COMPLETED_NO); + } + + if ((raise_exception & TAO::FOE_TRANSIENT) == TAO::FOE_TRANSIENT) + { + //ACE_DEBUG ((LM_DEBUG, "(%P|%t) \t called and raise TRANSIENT\n")); + ++this->num_exceptions_thrown_; + throw ::CORBA::TRANSIENT (CORBA::OMGVMCID | 1, CORBA::COMPLETED_NO); + } + + if ((raise_exception & TAO::FOE_INV_OBJREF) == TAO::FOE_INV_OBJREF) + { + //ACE_DEBUG ((LM_DEBUG, "(%P|%t) test_is_a called %d and raise INV_OBJREF\n", ncalls_)); + ++this->num_exceptions_thrown_; + throw ::CORBA::INV_OBJREF (CORBA::OMGVMCID | 1, CORBA::COMPLETED_NO); + } + + return 0; +} + +void +Simple_Server_i::shutdown (void) +{ + this->orb_->shutdown (0); +} diff --git a/TAO/tests/Multiple_Retry_Tests/Retry_On_Reply_Failure/test_i.h b/TAO/tests/Multiple_Retry_Tests/Retry_On_Reply_Failure/test_i.h new file mode 100755 index 00000000000..8bc654aab28 --- /dev/null +++ b/TAO/tests/Multiple_Retry_Tests/Retry_On_Reply_Failure/test_i.h @@ -0,0 +1,46 @@ + +//============================================================================= +/** + * @file test_i.h + * + * $Id$ + * + * @author Carlos O'Ryan + */ +//============================================================================= + + +#ifndef TAO_RETRY_ON_REPLY_FAILURE_I_H +#define TAO_RETRY_ON_REPLY_FAILURE_I_H + +#include "testS.h" + +/** + * @class Simple_Server_i + * + * @brief Simpler Server implementation + * + * Implements the Simple_Server interface in test.idl + */ +class Simple_Server_i : public POA_Simple_Server +{ +public: + /// ctor + Simple_Server_i (CORBA::ORB_ptr orb, int num_exceptions_to_throw); + + // = The Simple_Server methods. + CORBA::Boolean test_is_a (const char * type); + + void shutdown (void); + +private: + /// The ORB + CORBA::ORB_var orb_; + + int num_exceptions_to_throw_; + int num_exceptions_thrown_; + + int raise_exception_; +}; + +#endif /* TAO_RETRY_ON_REPLY_FAILURE_I_H */ |