diff options
author | wilson_d <wilson_d@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2003-09-30 21:22:23 +0000 |
---|---|---|
committer | wilson_d <wilson_d@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2003-09-30 21:22:23 +0000 |
commit | f04db615d7337acf24edf9be8e24f3e578fa5406 (patch) | |
tree | 0ffd8cd51c356a8d2d50230b87d069bb67b68651 | |
parent | eb012b1afe71dab3c0228bc6d4092ddf1edcdb2e (diff) | |
download | ATCD-f04db615d7337acf24edf9be8e24f3e578fa5406.tar.gz |
ChangeLogTag: Tue Sep 30 15:58:42 2003 Dale Wilson <wilson_d@ociweb.com>
-rw-r--r-- | TAO/ChangeLog | 124 | ||||
-rw-r--r-- | TAO/orbsvcs/Fault_Detector/Fault_Detector_i.cpp | 7 | ||||
-rw-r--r-- | TAO/orbsvcs/tests/FT_App/FTAPP_FactoryRegistry_Main.cpp | 33 | ||||
-rw-r--r-- | TAO/orbsvcs/tests/FT_App/FT_App.mpc | 27 | ||||
-rw-r--r-- | TAO/orbsvcs/tests/FT_App/FT_Client.cpp | 3 | ||||
-rw-r--r-- | TAO/orbsvcs/tests/FT_App/FT_TestReplica_i.cpp | 7 | ||||
-rw-r--r-- | TAO/orbsvcs/tests/FT_App/FT_TestReplica_i.h | 4 | ||||
-rw-r--r-- | TAO/orbsvcs/tests/FT_App/FactoryRegistry_i.cpp | 501 | ||||
-rw-r--r-- | TAO/orbsvcs/tests/FT_App/FactoryRegistry_i.h | 204 | ||||
-rw-r--r-- | TAO/orbsvcs/tests/FT_App/README | 47 | ||||
-rw-r--r-- | TAO/orbsvcs/tests/FT_App/StubBatchConsumer.cpp | 2 | ||||
-rw-r--r-- | TAO/orbsvcs/tests/FT_App/StubFaultAnalyzer.cpp | 2 | ||||
-rw-r--r-- | TAO/orbsvcs/tests/FT_App/StubFaultConsumer.cpp | 2 | ||||
-rw-r--r-- | TAO/orbsvcs/tests/FT_App/StubFaultNotifier.h | 12 | ||||
-rwxr-xr-x | TAO/orbsvcs/tests/FT_App/run_test_registry.pl | 263 |
15 files changed, 1145 insertions, 93 deletions
diff --git a/TAO/ChangeLog b/TAO/ChangeLog index f1e40cacc9d..3ba98c333c8 100644 --- a/TAO/ChangeLog +++ b/TAO/ChangeLog @@ -1,59 +1,89 @@ +Tue Sep 30 15:58:42 2003 Dale Wilson <wilson_d@ociweb.com> + + * orbsvcs/Fault_Detector/Fault_Detector_i.cpp: + New into a var rather than into a pointer that gets assigned to the var later. + + * orbsvcs/tests/FT_App/FTAPP_FactoryRegistry_Main.cpp: + * orbsvcs/tests/FT_App/FactoryRegistry_i.h: + * orbsvcs/tests/FT_App/FactoryRegistry_i.cpp: + * orbsvcs/tests/FT_App/run_test_registry.pl: + New files: First implementation of FactoryRegistry interface (not working, yet.) + + * orbsvcs/tests/FT_App/FT_App.mpc: + Add project for FactoryRegistry + + * orbsvcs/tests/FT_App/README: + Mention FactoryRegistry in documentation. + + * orbsvcs/tests/FT_App/FT_TestReplica_i.h: + * orbsvcs/tests/FT_App/FT_TestReplica_i.cpp: + * orbsvcs/tests/FT_App/FT_Client.cpp: + * orbsvcs/tests/FT_App/StubBatchConsumer.cpp: + * orbsvcs/tests/FT_App/StubFaultAnalyzer.cpp: + * orbsvcs/tests/FT_App/StubFaultConsumer.cpp: + * orbsvcs/tests/FT_App/StubFaultNotifier.h: + Minor changes to make these more ACE-like. + + + + + Tue Sep 30 11:45:49 2003 Balachandran Natarajan <bala@dre.vanderbilt.edu> - * orbsvcs/tests/FaultTolerance/Replay_Reply/Server_Request_Interceptor.cpp: - - The send_reply () method now uses generic ways to marshall the - value inside an Any into the CDR stream. This now uses the - undocumented marshal_value () in Any_Impl class. - + * orbsvcs/tests/FaultTolerance/Replay_Reply/Server_Request_Interceptor.cpp: + + The send_reply () method now uses generic ways to marshall the + value inside an Any into the CDR stream. This now uses the + undocumented marshal_value () in Any_Impl class. + Mon Sep 29 18:55:08 2003 Balachandran Natarajan <bala@dre.vanderbilt.edu> - * orbsvcs/tests/FaultTolerance/Replay_Reply: + * orbsvcs/tests/FaultTolerance/Replay_Reply: - A new test for the feature mentioned below. + A new test for the feature mentioned below. Mon Sep 29 18:39:05 2003 Balachandran Natarajan <bala@dre.vanderbilt.edu> - A temporary hack for Boris to keep progressing. The aim of this - hack in the branch is to add a propreietary interception - point. This is what this checkin is all about - - - Added a new interception point, tao_ft_interception_point () - on the server side. - - - This will be called on the server even before the - receive_request_service_context () is called - - - The server can use this interception point to send back a - reply without dispatching it to the object. - - * tao/PortableInterceptor.pidl: - * tao/PortableInterceptorC.h: Added the new interception point. A - default implementation is provided, so that application - developers don't need to implement the proprietary interception - point. - - * tao/TAO_Server_Request.cpp: - * tao/TAO_Server_Request.h: - * tao/TAO_Server_Request.i: Added a new method which will be used - to send cached replies back to the client. - - * tao/PortableServer/Object_Adapter.cpp: Called the proprietary - interception point. - - * tao/PortableServer/ServerInterceptorAdapter.cpp: - * tao/PortableServer/ServerInterceptorAdapter.h: Added the first - interception point to be the tao's proprietary interception - point. - - This shouldn't be needed once we merge in 1369. But till then we - may need this hack. - + A temporary hack for Boris to keep progressing. The aim of this + hack in the branch is to add a propreietary interception + point. This is what this checkin is all about + + - Added a new interception point, tao_ft_interception_point () + on the server side. + + - This will be called on the server even before the + receive_request_service_context () is called + + - The server can use this interception point to send back a + reply without dispatching it to the object. + + * tao/PortableInterceptor.pidl: + * tao/PortableInterceptorC.h: Added the new interception point. A + default implementation is provided, so that application + developers don't need to implement the proprietary interception + point. + + * tao/TAO_Server_Request.cpp: + * tao/TAO_Server_Request.h: + * tao/TAO_Server_Request.i: Added a new method which will be used + to send cached replies back to the client. + + * tao/PortableServer/Object_Adapter.cpp: Called the proprietary + interception point. + + * tao/PortableServer/ServerInterceptorAdapter.cpp: + * tao/PortableServer/ServerInterceptorAdapter.h: Added the first + interception point to be the tao's proprietary interception + point. + + This shouldn't be needed once we merge in 1369. But till then we + may need this hack. + Mon Sep 29 18:19:51 2003 Steve Totten <totten_s@ociweb.com> * orbsvcs/orbsvcs/PortableGroup/PG_Utils.cpp: - Fixed compilation error in VC++ 6.0 involving re-use + Fixed compilation error in VC++ 6.0 involving re-use of 'i' as a for loop control variable. Mon Sep 29 16:15:55 2003 Curt Hibbs <hibbs_c@ociweb.com> @@ -98,7 +128,7 @@ Mon Sep 29 07:22:35 2003 Curt Hibbs <hibbs_c@ociweb.com> Fri Sep 26 19:31:11 2003 Balachandran Natarajan <bala@dre.vanderbilt.edu> - * orbsvcs/orbsvcs/PortableGroup/PG_Utils.cpp (TAO): + * orbsvcs/orbsvcs/PortableGroup/PG_Utils.cpp (TAO): * orbsvcs/orbsvcs/PortableGroup/PG_Utils.h: Moved group reference manipulation functions to a new file which will be used within the PortableGroup. @@ -109,8 +139,8 @@ Fri Sep 26 19:31:11 2003 Balachandran Natarajan <bala@dre.vanderbilt.edu> * orbsvcs/orbsvcs/PortableGroup/PG_ObjectGroup_Map.cpp: * orbsvcs/orbsvcs/PortableGroup/PG_Property_Utils.cpp: Removed dependency on the FT library which was unnecessary in the first - place. - + place. + Fixed warnings and errors with g++ builds. Thu Sep 25 16:08:35 2003 Dale Wilson <wilson_d@ociweb.com> diff --git a/TAO/orbsvcs/Fault_Detector/Fault_Detector_i.cpp b/TAO/orbsvcs/Fault_Detector/Fault_Detector_i.cpp index 7db5f878691..ef3be4b0b85 100644 --- a/TAO/orbsvcs/Fault_Detector/Fault_Detector_i.cpp +++ b/TAO/orbsvcs/Fault_Detector/Fault_Detector_i.cpp @@ -120,11 +120,10 @@ void Fault_Detector_i::run() void Fault_Detector_i::notify() { - CosNotification::StructuredEvent * pEvent; - ACE_NEW_NORETURN(pEvent, CosNotification::StructuredEvent ); - if (pEvent != 0) + CosNotification::StructuredEvent_var vEvent; + ACE_NEW_NORETURN(vEvent, CosNotification::StructuredEvent ); + if (vEvent.ptr() != 0) { - CosNotification::StructuredEvent_var vEvent(pEvent); short length = 2; if( object_type_ != 0) { diff --git a/TAO/orbsvcs/tests/FT_App/FTAPP_FactoryRegistry_Main.cpp b/TAO/orbsvcs/tests/FT_App/FTAPP_FactoryRegistry_Main.cpp new file mode 100644 index 00000000000..b09ab0cb3da --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/FTAPP_FactoryRegistry_Main.cpp @@ -0,0 +1,33 @@ +/* -*- C++ -*- */ +//============================================================================= +/** + * @file FTAPP_FactoryRegistry_Main.cpp + * + * $Id$ + * + * This file is part of Fault Tolerant CORBA. + * This file provides the main routine for a stub FactoryRegistry + * + * @author Dale Wilson <wilson_d@ociweb.com> + */ +//============================================================================= + +#include <tao/Utils/ServantMain.h> +#include "FactoryRegistry_i.h" + +int ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + TAO::Utils::ServantMain<FactoryRegistry_i> servantMain("FactoryRegistry"); + return servantMain.Main(argc, argv); +} + +/////////////////////////////////// +// Template instantiation for +// inept compilers. + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) + template TAO::Utils::ServantMain<FactoryRegistry_i>; +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +# pragma instantiate TAO::Utils::ServantMain<FactoryRegistry_i> +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ + diff --git a/TAO/orbsvcs/tests/FT_App/FT_App.mpc b/TAO/orbsvcs/tests/FT_App/FT_App.mpc index e0f2129fe93..121a7ea3a1f 100644 --- a/TAO/orbsvcs/tests/FT_App/FT_App.mpc +++ b/TAO/orbsvcs/tests/FT_App/FT_App.mpc @@ -85,3 +85,30 @@ project(*Analyzer): taoclient, fault_tolerance, orbsvcsexe { run_test_notifier.pl } } + +project(*FactoryRegistry): taoclient, fault_tolerance, orbsvcsexe { + exename = ft_registry + + Source_Files { + FTAPP_FactoryRegistry_Main.cpp + FactoryRegistry_i.cpp + } + +// // Custom folder: script to run this test +// Define_Custom(Script){ +// inputext = .pl, .py, .rb +// generic_outputext = .txt +// } +// +// Script_Files { +// run_test_detector.pl +// } + + // explicitly omit IDL files + IDL_Files { + } + Documentation_Files { + // pretend the pl file is documentation for now + run_test_registry.pl + } +} diff --git a/TAO/orbsvcs/tests/FT_App/FT_Client.cpp b/TAO/orbsvcs/tests/FT_App/FT_Client.cpp index 4704340c261..e1a18c42e45 100644 --- a/TAO/orbsvcs/tests/FT_App/FT_Client.cpp +++ b/TAO/orbsvcs/tests/FT_App/FT_Client.cpp @@ -2,7 +2,7 @@ #include "FT_TestReplicaC.h" // the following include is relative to $TAO_ROOT -#include "examples/Simple/Simple_util.h" +#include <examples/Simple/Simple_util.h> #include <iostream> #include <fstream> @@ -597,6 +597,7 @@ int FTClientMain::run () } if (! handled) { + std::cout << "FT Client: Exception not handled. Rethrow. " << std::endl; ACE_RE_THROW; } } diff --git a/TAO/orbsvcs/tests/FT_App/FT_TestReplica_i.cpp b/TAO/orbsvcs/tests/FT_App/FT_TestReplica_i.cpp index a232fd7cea1..d4334e51ca1 100644 --- a/TAO/orbsvcs/tests/FT_App/FT_TestReplica_i.cpp +++ b/TAO/orbsvcs/tests/FT_App/FT_TestReplica_i.cpp @@ -298,7 +298,7 @@ void FT_TestReplica_i::shutdown (ACE_ENV_SINGLE_ARG_DECL) ACE_THROW_SPEC ((CORBA::SystemException)) { factory_->removeReplica(factoryId_, this); -// death_pending_ = FT_TEST::TestReplica::CLEAN_EXIT; + death_pending_ = FT_TEST::TestReplica::CLEAN_EXIT; } ////////////////////////////////////////////// @@ -318,11 +318,6 @@ int FT_TestReplica_i::idle (int & result) } else if (death_pending_ == FT_TEST::TestReplica::CLEAN_EXIT) { - ACE_ERROR ((LM_ERROR, - "%s#%d: Simulated fault CLEAN_EXIT", - factory_->identity(), - ACE_static_cast(int, factoryId_ ) - )); result = 0; quit = 1; } diff --git a/TAO/orbsvcs/tests/FT_App/FT_TestReplica_i.h b/TAO/orbsvcs/tests/FT_App/FT_TestReplica_i.h index 1e543c4df57..63d646ca1b1 100644 --- a/TAO/orbsvcs/tests/FT_App/FT_TestReplica_i.h +++ b/TAO/orbsvcs/tests/FT_App/FT_TestReplica_i.h @@ -17,7 +17,7 @@ #pragma once #endif /* ACE_LACKS_PRAGMA_ONCE */ -#include "ace/pre.h" +#include /**/ <ace/pre.h> #include "FT_TestReplicaS.h" //////////////////// @@ -191,6 +191,6 @@ private: }; -#include "ace/post.h" +#include /**/ "ace/post.h" #endif /* FT_TESTREPLICA_I_H_ */ diff --git a/TAO/orbsvcs/tests/FT_App/FactoryRegistry_i.cpp b/TAO/orbsvcs/tests/FT_App/FactoryRegistry_i.cpp new file mode 100644 index 00000000000..6db1278c848 --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/FactoryRegistry_i.cpp @@ -0,0 +1,501 @@ +// -*- C++ -*- +// +// $Id$ + +#include "FactoryRegistry_i.h" + +#include <ace/Get_Opt.h> +#include <ace/Vector_T.h> +#include <tao/PortableServer/ORB_Manager.h> +#include <orbsvcs/PortableGroup/PG_Operators.h> // Borrow operator == on CosNaming::Name + +// Use this macro at the beginning of CORBA methods +// to aid in debugging. +#define METHOD_ENTRY(name) \ + ACE_DEBUG (( LM_DEBUG, \ + "Enter %s\n", #name \ + )) + +// Use this macro to return from CORBA methods +// to aid in debugging. Note that you can specify +// the return value after the macro, for example: +// METHOD_RETURN(Plugh::plover) xyzzy; is equivalent +// to return xyzzy; +// METHOD_RETURN(Plugh::troll); is equivalent to +// return; +// WARNING: THIS GENERATES TWO STATEMENTS!!! THE FOLLOWING +// will not do what you want it to: +// if (cave_is_closing) METHOD_RETURN(Plugh::pirate) aarrggh; +// Moral: Always use braces. +#define METHOD_RETURN(name) \ + ACE_DEBUG (( LM_DEBUG, \ + "Leave %s\n", #name \ + )); \ + return /* value goes here */ + +FactoryRegistry_i::FactoryRegistry_i () + : iorOutputFile(0) + , nsName_(0) + , quitOnIdle_(0) + , quitRequested_(0) + +{ +} + +FactoryRegistry_i::~FactoryRegistry_i (void) +{ +} + +////////////////////////////////////////////////////// +// FactoryRegistry_i public, non-CORBA methods + +int FactoryRegistry_i::parse_args (int argc, char * argv[]) +{ + ACE_Get_Opt get_opts (argc, argv, "o:t:r:q"); + int c; + + while ((c = get_opts ()) != -1) + { + switch (c) + { + case 'o': + { + iorOutputFile = get_opts.opt_arg (); + break; + } + case 'q': + { + quitOnIdle_ = 1; + break; + } + + case '?': + // fall thru + default: + ACE_ERROR_RETURN ((LM_ERROR, + "usage: %s" + " -o <factory ior file>" + " -t <test replica ior file>" + " -q{uit on idle}" + "\n", + argv [0]), + -1); + break; + } + } + // Indicates sucessful parsing of the command line + return 0; +} + +const char * FactoryRegistry_i::identity () const +{ + return identity_.c_str(); +} + +int FactoryRegistry_i::idle (int & result) +{ + result = 0; + int quit = quitRequested_; + return quit; +} + + +int FactoryRegistry_i::fini (ACE_ENV_SINGLE_ARG_DECL) +{ + if (iorOutputFile != 0) + { + ACE_OS::unlink (iorOutputFile); + iorOutputFile = 0; + } + if (nsName_ != 0) + { + naming_context_->unbind (this_name_ + ACE_ENV_ARG_PARAMETER); + nsName_ = 0; + } + return 0; +} + +int FactoryRegistry_i::init (TAO_ORB_Manager & orbManager + ACE_ENV_ARG_DECL) +{ + int result = 0; + + orbManager_ = & orbManager; + orb_ = orbManager.orb(); + + // Register with the ORB. + ior_ = orbManager.activate (this + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + if (iorOutputFile != 0) + { + identity_ = "file:"; + identity_ += iorOutputFile; + result = writeIOR (iorOutputFile, ior_); + } + else + { + // if no IOR file specified, + // then always try to register with name service + nsName_ = "FactoryRegistry"; + } + + if (nsName_ != 0) + { + identity_ = "name:"; + identity_ += nsName_; + + CORBA::Object_var naming_obj = + orb_->resolve_initial_references ("NameService" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + if (CORBA::is_nil(naming_obj.in ())){ + ACE_ERROR_RETURN ((LM_ERROR, + "%T %n (%P|%t) Unable to find the Naming Service\n"), + 1); + } + + naming_context_ = + CosNaming::NamingContext::_narrow (naming_obj.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + this_name_.length (1); + this_name_[0].id = CORBA::string_dup (nsName_); + + naming_context_->rebind (this_name_, _this() + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + } + + return result; +} + +////////////////////////////////////////// +// FactoryRegistry_i CORBA methods + +/* Reference:info + typedef CosNaming::Name Name; + typedef Name Location; + struct FactoryInfo { + GenericFactory the_factory; + Location the_location; + Criteria the_criteria; + }; + typedef sequence<FactoryInfo> FactoryInfos; +*/ + + +void FactoryRegistry_i::register_factory ( + const char * type_id, + const PortableGroup::FactoryInfo & factory_info + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC ((CORBA::SystemException, PortableGroup::MemberAlreadyPresent)) +{ + METHOD_ENTRY(FactoryRegistry_i::register_factory); + + PortableGroup::FactoryInfos * infos; + if (registry_.find(type_id, infos) ) + { + ACE_DEBUG(( LM_DEBUG, + "register_factory found infos for %s", type_id + )); + } + else + { + ACE_DEBUG(( LM_DEBUG, + "register_factory: no infos for %s", type_id + )); + // Note the 5. It's a guess about the number of factories + // that might exist for any particular type of object. + // todo: make it a parameter. + ACE_NEW_NORETURN (infos, PortableGroup::FactoryInfos(5)); + if (infos == 0) + { + ACE_ERROR(( LM_ERROR, + "Can't allocate infos for type: %s\n" , type_id)); + ACE_THROW (CORBA::NO_MEMORY (TAO_DEFAULT_MINOR_CODE, + CORBA::COMPLETED_NO)); + } + registry_.bind(type_id, infos); + } + // at this point infos points to the infos structure + // for this type.. + size_t length = infos->length(); + for (size_t nInfo = 0; nInfo < length; ++nInfo) + { + PortableGroup::FactoryInfo & info = (*infos)[nInfo]; + if (info.the_location == factory_info.the_location) + { + ACE_ERROR(( LM_ERROR, + "Found duplicate location for type: %s\n" , type_id)); + ACE_THROW (PortableGroup::MemberAlreadyPresent() ); + } + } + + infos->length(length + 1); + (*infos)[length] = factory_info; + + METHOD_RETURN(FactoryRegistry_i::register_factory); +} + +void FactoryRegistry_i::unregister_factory ( + const char * type_id, + const PortableGroup::Location & location + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC ((CORBA::SystemException, PortableGroup::MemberNotFound)) +{ + METHOD_ENTRY(FactoryRegistry_i::unregister_factory); + + PortableGroup::FactoryInfos * infos; + if (registry_.find(type_id, infos) ) + { + ACE_DEBUG(( LM_DEBUG, + "register_factory found infos for %s", type_id + )); + // at this point infos points to the infos structure + // for this type.. + + int found = 0; + size_t length = infos->length(); + for (size_t nInfo = 0; !found && nInfo < length; ++nInfo) + { + PortableGroup::FactoryInfo & info = (*infos)[nInfo]; + if (info.the_location == location) + { + found = 1; + if (length > 1) + { + while (nInfo + 1 < length) + { + (*infos)[nInfo] = (*infos)[nInfo + 1]; + nInfo += 1; + } + infos->length(nInfo); + } + else + { + assert ( length == 1 ); + registry_.unbind (type_id); + delete infos; + } + } + } + } + else + { + ACE_ERROR(( LM_ERROR, + "nregister_factory: no infos for %s", type_id + )); + ACE_THROW ( PortableGroup::MemberNotFound() ); + infos->length(0); + registry_.bind(type_id, infos); + } + + METHOD_RETURN(FactoryRegistry_i::unregister_factory); +} + +void FactoryRegistry_i::unregister_factory_by_type ( + const char * type_id + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + METHOD_ENTRY(FactoryRegistry_i::unregister_factory_by_type); + PortableGroup::FactoryInfos * infos; + if (registry_.unbind(type_id, infos) ) + { + ACE_DEBUG(( LM_DEBUG, + "unregister_factory_by_type found infos for %s", type_id + )); + // delete the entire set of factories for this location. + delete infos; + } + else + { + ACE_ERROR(( LM_INFO, + "Info: unregister_factory_by_type: no infos for %s", type_id + )); + } + METHOD_RETURN(FactoryRegistry_i::unregister_factory_by_type); +} + +void FactoryRegistry_i::unregister_factory_by_location ( + const PortableGroup::Location & location + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + METHOD_ENTRY(FactoryRegistry_i::unregister_factory_by_location); + + ACE_Vector<ACE_CString> hitList; + + // iterate through the registery + for (RegistryType_Iterator it = registry_.begin(); + it != registry_.end(); + ++it) + { + RegistryType_Entry & entry = *it; + PortableGroup::FactoryInfos * infos = entry.int_id_; + + int found = 0; + size_t length = infos->length(); + for (size_t nInfo = 0; !found && nInfo < length; ++nInfo) + { + PortableGroup::FactoryInfo & info = (*infos)[nInfo]; + if (info.the_location == location) + { + found = 1; + if (length > 1) + { + while (nInfo + 1 < length) + { + infos[nInfo] = infos[nInfo + 1]; + nInfo += 1; + } + infos->length(nInfo); + } + else + { + assert ( length == 1 ); + // remember entries to be deleted + hitList.push_back(entry.ext_id_); + } + } + } + } + + // now remove any types that became empty + + for (size_t nHit = 0; nHit < hitList.size(); ++nHit) + { + PortableGroup::FactoryInfos * infos; + if (registry_.unbind(hitList[nHit], infos) ) + { + delete infos; + } + else + { + ACE_ERROR ((LM_ERROR, + "LOGIC ERROR AT " __FILE__ " (%d): Entry to be deleted disappeared", __LINE__)); + } + } + + METHOD_RETURN(FactoryRegistry_i::unregister_factory_by_location); +} + +::PortableGroup::FactoryInfos * FactoryRegistry_i::list_factories_by_type ( + const char * type_id + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + METHOD_ENTRY(FactoryRegistry_i::list_factories_by_type); + + PortableGroup::FactoryInfos_var infos; + ACE_NEW_NORETURN(infos, ::PortableGroup::FactoryInfos() ); + if (infos.ptr() == 0) + { + ACE_ERROR(( LM_ERROR, + "list_factories_by_type: Can't allocate infos for type: %s\n" , type_id)); + ACE_THROW (CORBA::NO_MEMORY (TAO_DEFAULT_MINOR_CODE, + CORBA::COMPLETED_NO)); + } + + PortableGroup::FactoryInfos * typeInfos; + if (registry_.unbind(type_id, typeInfos) ) + { + ACE_DEBUG(( LM_DEBUG, + "unregister_factory_by_type found infos for %s", type_id + )); + (*infos) = (*typeInfos); + } + METHOD_RETURN(FactoryRegistry_i::list_factories_by_type) infos._retn(); +} + +::PortableGroup::FactoryInfos * FactoryRegistry_i::list_factories_by_location ( + const PortableGroup::Location & location + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + METHOD_ENTRY(FactoryRegistry_i::list_factories_by_location); + ::PortableGroup::FactoryInfos_var infos; + ACE_NEW_NORETURN(infos, ::PortableGroup::FactoryInfos(registry_.current_size()) ); + if (infos.ptr() == 0) + { + ACE_ERROR(( LM_ERROR, + "list_factories_by_location: Can't allocate infos\n")); + ACE_THROW (CORBA::NO_MEMORY (TAO_DEFAULT_MINOR_CODE, + CORBA::COMPLETED_NO)); + } + + size_t count = 0; + + // iterate through the registery + for (RegistryType_Iterator it = registry_.begin(); + it != registry_.end(); + ++it) + { + RegistryType_Entry & entry = *it; + PortableGroup::FactoryInfos * infos = entry.int_id_; + + // iterate through the entry for this type + int found = 0; + size_t length = infos->length(); + for (size_t nInfo = 0; !found && nInfo < length; ++nInfo) + { + PortableGroup::FactoryInfo & info = (*infos)[nInfo]; + if (info.the_location == location) + { + found = 1; + count += 1; + infos->length(count); + (*infos)[count-1] = info; + } + } + } + + METHOD_RETURN(FactoryRegistry_i::list_factories_by_location) infos._retn(); +} + +////////////////////////////// +// Implementation methods + +int FactoryRegistry_i::writeIOR(const char * outputFile, const char * ior) +{ + int result = -1; + FILE* out = ACE_OS::fopen (outputFile, "w"); + if (out) + { + ACE_OS::fprintf (out, "%s", ior); + ACE_OS::fclose (out); + result = 0; + } + else + { + ACE_ERROR ((LM_ERROR, + "Open failed for %s\n", outputFile + )); + } + return result; +} + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) + + template class ACE_Hash_Map_Manager <ACE_CString, PortableGroup::FactoryInfos *, MapMutex>; + template class ACE_Hash_Map_Entry <ACE_CString, PortableGroup::FactoryInfos *>; + template class ACE_Hash_Map_Iterator <ACE_CString, PortableGroup::FactoryInfos *, MapMutex>; + template class ACE_Vector<ACE_CString>; + +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) + +# pragma instantiate ACE_Hash_Map_Manager <ACE_CString, PortableGroup::FactoryInfos *, MapMutex> +# pragma instantiate ACE_Hash_Map_Entry <ACE_CString, PortableGroup::FactoryInfos *> +# pragma instantiate ACE_Hash_Map_Iterator <ACE_CString, PortableGroup::FactoryInfos *, MapMutex> +# pragma instantiate ACE_Vector<ACE_CString> + +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/orbsvcs/tests/FT_App/FactoryRegistry_i.h b/TAO/orbsvcs/tests/FT_App/FactoryRegistry_i.h new file mode 100644 index 00000000000..58d5f2c8ca6 --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/FactoryRegistry_i.h @@ -0,0 +1,204 @@ +// -*- C++ -*- +//============================================================================= +/** + * @file FactoryRegistry_i.h + * + * $Id$ + * + * This file declares the implementation of PortableGroup::FactoryRegistry. + * Eventually this should be folded into the Fault Tolerance ReplicationManager + * + * @author Dale Wilson <wilson_d@ociweb.com> + */ +//============================================================================= + +#ifndef FACTORYREGISTRY_I_H_ +#define FACTORYREGISTRY_I_H_ + +#include <orbsvcs/PortableGroupS.h> +#include <ace/Hash_Map_Manager.h> + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +////////////////////////////////// +// Classes declared in this header +class FactoryRegistry_i; + +///////////////////////////////// +// Includes needed by this header + +///////////////////// +// Forward references +class TAO_ORB_Manager; + +/** + * Implement the PortableGroup::FactoryRegistry interface + * Note FactoryRegistry is not part of the OMG standard. It was added + * as part of the TAO implementation of Fault Tolerant Corba + */ +class FactoryRegistry_i : public virtual POA_PortableGroup::FactoryRegistry +{ + /* <DESIGN> originally I used FactoryInfos_vars rather than FactoryInfos *, + but it actually made memory management harder. DLW </DESIGN> */ + typedef ACE_Null_Mutex MapMutex; + typedef ACE_Hash_Map_Manager <ACE_CString, PortableGroup::FactoryInfos *, MapMutex> RegistryType; + typedef ACE_Hash_Map_Entry <ACE_CString, PortableGroup::FactoryInfos *> RegistryType_Entry; + typedef ACE_Hash_Map_Iterator <ACE_CString, PortableGroup::FactoryInfos *, MapMutex> RegistryType_Iterator; + + ////////////////////// + // non-CORBA interface +public: + /// Constructor + FactoryRegistry_i (void); + + /// virtual Destructor + virtual ~FactoryRegistry_i (void); + + /** + * Parse command line arguments. + * @param argc traditional C argc + * @param argv traditional C argv + * @return zero for success; nonzero is process return code for failure. + */ + int parse_args (int argc, char * argv[]); + + /** + * Initialize this object. + * @param orbManager our ORB -- we keep var to it. + * @return zero for success; nonzero is process return code for failure. + */ + int init (TAO_ORB_Manager & orbManager ACE_ENV_ARG_DECL_WITH_DEFAULTS); + + /** + * Prepare to exit. + * @return zero for success; nonzero is process return code for failure. + */ + int fini (ACE_ENV_SINGLE_ARG_DECL); + + /** + * Processing to happen when the ORB's event loop is idle. + * @param result is a place to return status to be returned by the process + * @returns 0 to continue. 1 to quit. + */ + int idle(int & result); + + /** + * Identify this object. + * @return a string to identify this object for logging/console message purposes. + */ + const char * identity () const; + + ////////////////// + // CORBA interface + // See IDL for documentation + + virtual void register_factory ( + const char * type_id, + const PortableGroup::FactoryInfo & factory_info + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC ((CORBA::SystemException, PortableGroup::MemberAlreadyPresent)); + + virtual void unregister_factory ( + const char * type_id, + const PortableGroup::Location & location + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC ((CORBA::SystemException, PortableGroup::MemberNotFound)); + + virtual void unregister_factory_by_type ( + const char * type_id + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual void unregister_factory_by_location ( + const PortableGroup::Location & location + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual ::PortableGroup::FactoryInfos * list_factories_by_type ( + const char * type_id + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual ::PortableGroup::FactoryInfos * list_factories_by_location ( + const PortableGroup::Location & location + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC ((CORBA::SystemException)); + + ///////////////////////// + // Implementation methods +private: + /** + * Write this factory's IOR to a file + */ + int writeIOR (const char * outputFile, const char * ior); + + /////////////// + // Data Members +private: + + /** + * A human-readable string to distinguish this from other Notifiers. + */ + ACE_CString identity_; + + /** + * Protect internal state. + * Mutex should be locked by corba methods, or by + * external (public) methods before calling implementation + * methods. + * Implementation methods should assume the mutex is + * locked if necessary. + */ + ACE_Mutex internals_; + typedef ACE_Guard<ACE_Mutex> InternalGuard; + + TAO_ORB_Manager * orbManager_; + /** + * The orb + */ + CORBA::ORB_var orb_; + + /** + * IOR of this object as assigned by poa. + */ + CORBA::String_var ior_; + + /** + * A file to which the factory's IOR should be written. + */ + const char * iorOutputFile; + + /** + * A name to be used to register the factory with the name service. + */ + const char * nsName_; + + CosNaming::NamingContext_var naming_context_; + + CosNaming::Name this_name_; + + /** + * Quit on idle flag. + */ + int quitOnIdle_; + + /** + * boolean: starts false. Set to true when it's time to quit. + */ + int quitRequested_; + + + RegistryType registry_; + +}; + + +#endif /* __FACTORYREGISTRY_I_H_ */ diff --git a/TAO/orbsvcs/tests/FT_App/README b/TAO/orbsvcs/tests/FT_App/README index 824c203fb90..2430fac4723 100644 --- a/TAO/orbsvcs/tests/FT_App/README +++ b/TAO/orbsvcs/tests/FT_App/README @@ -2,16 +2,16 @@ $Id$ This is a simple application intended to test Fault Tolerant Corba. -The server implements the IDL in FT_TestReplica.idl which defines -the interface FT_TEST::TestReplica . +The server implements GenericFactory as a factory that creates TestReplicas. +TestReplicas are defined in the IDL in FT_TestReplica.idl. FT_TEST::TestReplica inherits from PullMonitorable and Checkpointable to provide access needed by FT Corba's FaultDetector and Orb. -An FT_TEST::TestReplica contains a long counter. Methods are defined -to set, increment, and get the value of the counter. The counter -is also exposed as an attribute named counter. (i.e. set(x) is -exactly equivalent to counter(x), and get() is exactly equivalent +An FT_TEST::TestReplica contains a long counter. Methods are defined +to set, increment, and get the value of the counter. The counter +is also exposed as an attribute named counter. (i.e. set(x) is +exactly equivalent to counter(x), and get() is exactly equivalent to counter()) In addition there is a method named die that lets the client request @@ -28,6 +28,11 @@ to 10. +5 increments the counter by 5 (thereby setting the value to 15). The '?' commmand lists the possible commands and their options. +Additional programs: + ft_notifier is a stub implementation of a fault notifier for testing fault detectors. + ft_analyzer is a stub implementation of a fault analyzer for testing the fault notifier + ft_registry is an implementation of FactoryRegistry for testing GenericFactories. + To run: Start one or more FT_Replicas. Use a -o <filename> to tell the replica where to write its ior.. @@ -35,21 +40,23 @@ where to write its ior.. Start the FT_Client with -f file1<,filen>... (i.e. a comma separated list of replica IOR files. To read commands from a file, use -c <command file> -The counter is persistent and will survive server failures. It's -stored in a file named persistent.dat. +The counter is persistent and will survive server failures. It's +stored in a file named persistent.dat. -Replicas of the server may be run in separate directories to simulate -replicated stateful objects (each replica has its own distinct state), or -multiple replicas can be run in the same directory to simulate a server -with a shared state or one that executes real-world unsafe-to-repeat -action (i.e. "fire the retro rockets" or "expose the patient to +Replicas of the server may be run in separate directories to simulate +replicated stateful objects (each replica has its own distinct state), or +multiple replicas can be run in the same directory to simulate a server +with a shared state or one that executes real-world unsafe-to-repeat +action (i.e. "fire the retro rockets" or "expose the patient to theraputic radiation.") -Tests: - -Two Fault Detection unit tests have been created based on this application. - run_test_detector.pl uses this application plus a "stub" fault notifier - to test the fault detectors and the fault detector factory. - run_test_notifier.pl uses this application, the fault detectors+factory, - and a stub fault analyzer to test the fault notifier. +Unit Tests based on this application: + run_test_basic.pl tests this application, thereby answering the question, + "who will test the tester?". + run_test_detector.pl uses this application plus a "stub" fault notifier + to test the fault detectors and the fault detector factory. + run_test_notifier.pl uses this application, the fault detectors+factory, + and a stub fault analyzer to test the fault notifier. + run_test_factory.pl uses this application, et. al. to test the GenericFactory + implementation in FT_Replica. See the internal documentation of the .pl files for more details. diff --git a/TAO/orbsvcs/tests/FT_App/StubBatchConsumer.cpp b/TAO/orbsvcs/tests/FT_App/StubBatchConsumer.cpp index 1d2416615dd..743c80625aa 100644 --- a/TAO/orbsvcs/tests/FT_App/StubBatchConsumer.cpp +++ b/TAO/orbsvcs/tests/FT_App/StubBatchConsumer.cpp @@ -2,7 +2,6 @@ // // $Id$ -#include <ace/pre.h> #include "StubBatchConsumer.h" #include <ace/Get_Opt.h> #include <tao/PortableServer/ORB_Manager.h> @@ -127,4 +126,3 @@ void StubBatchConsumer::disconnect_sequence_push_consumer ( //# pragma instantiate ACE_Vector < const char * > #endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ -#include "ace/post.h" diff --git a/TAO/orbsvcs/tests/FT_App/StubFaultAnalyzer.cpp b/TAO/orbsvcs/tests/FT_App/StubFaultAnalyzer.cpp index e82018997d1..5eac532ee7c 100644 --- a/TAO/orbsvcs/tests/FT_App/StubFaultAnalyzer.cpp +++ b/TAO/orbsvcs/tests/FT_App/StubFaultAnalyzer.cpp @@ -2,7 +2,6 @@ // // $Id$ -#include <ace/pre.h> #include "StubFaultAnalyzer.h" #include <ace/Get_Opt.h> #include <tao/PortableServer/ORB_Manager.h> @@ -367,4 +366,3 @@ int StubFaultAnalyzer::readIORFile(const char * fileName, CORBA::String_var & io # pragma instantiate ACE_Vector < FT::PullMonitorable_var > #endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ -#include "ace/post.h" diff --git a/TAO/orbsvcs/tests/FT_App/StubFaultConsumer.cpp b/TAO/orbsvcs/tests/FT_App/StubFaultConsumer.cpp index ace3b39ad99..083c1643daa 100644 --- a/TAO/orbsvcs/tests/FT_App/StubFaultConsumer.cpp +++ b/TAO/orbsvcs/tests/FT_App/StubFaultConsumer.cpp @@ -2,7 +2,6 @@ // // $Id$ -#include <ace/pre.h> #include "StubFaultConsumer.h" #include <ace/Get_Opt.h> #include <tao/PortableServer/ORB_Manager.h> @@ -256,4 +255,3 @@ void StubFaultConsumer::disconnect_structured_push_consumer(ACE_ENV_SINGLE_ARG_D //# pragma instantiate ACE_Vector < const char * > #endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ -#include "ace/post.h" diff --git a/TAO/orbsvcs/tests/FT_App/StubFaultNotifier.h b/TAO/orbsvcs/tests/FT_App/StubFaultNotifier.h index 21c51538099..6daeeb9c49a 100644 --- a/TAO/orbsvcs/tests/FT_App/StubFaultNotifier.h +++ b/TAO/orbsvcs/tests/FT_App/StubFaultNotifier.h @@ -6,11 +6,11 @@ #if !defined (ACE_LACKS_PRAGMA_ONCE) #pragma once #endif /* ACE_LACKS_PRAGMA_ONCE */ -#include "ace/pre.h" +#include /**/ <ace/pre.h> -#include "orbsvcs/FT_NotifierS.h" -#include "orbsvcs/FT_FaultDetectorFactoryC.h" -#include "ace/Vector_T.h" +#include <orbsvcs/FT_NotifierS.h> +#include <orbsvcs/FT_FaultDetectorFactoryC.h> +#include <ace/Vector_T.h> ////////////////////// // Forward references @@ -164,10 +164,8 @@ private: * A human-readable string to distinguish this from other Notifiers. */ ACE_CString identity_; - - }; -#include "ace/post.h" +#include /**/ <ace/post.h> #endif /* STUBFAULTNOTIFIER_H_ */ diff --git a/TAO/orbsvcs/tests/FT_App/run_test_registry.pl b/TAO/orbsvcs/tests/FT_App/run_test_registry.pl new file mode 100755 index 00000000000..12beb068146 --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/run_test_registry.pl @@ -0,0 +1,263 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ +# -*- perl -*- + +# Purpose: +# To test the FaultNotifier +# +# Process being tested: +# Fault_Notifier +# implements FaultNotifier interface. +# Processes used in test: +# FT_Replica +# implements TestReplica interface. +# implements PullMonitorable. +# Fault_Detector +# implements FaultDetectorFactory interface +# implements PullMonitorable interface +# FT_Client +# client for TestReplica interface. +# client for PullMonitorable. +# StubAnalyzer +# Subscribes to Fault_Notfier +# +# Test Scenario (***Test: marks behavior being tested): +# Phase 1: +# Start two FT_Replicas +# FT_Replicas write TestReplica IORs (FR#1 and FR#2) to files +# Start the Fault_Detector +# Fault_Detector writes its IOR (FDF) to a file +# Start the Fault_Notifier +# Fault_Notifier writes its IOR (FN) to a file. +# Phase 2: +# Wait for IORs: FR#1, FR#2, FDF, and FN +# Start the StubAnalyzer giving it IORS: FR#1, FR#2 FDF, FN +# StubAnalyzer calls FDF to create a FaultDetector +# for each Replica. +# StubAnalyzer subscribes to Fault_Notifier +# StubAnalyzer writes dummy message(READY) to a file. +# Phase 3: +# Wait for READY +# Start FT_Client giving it IORS: FR#1 and FR#2. [1] +# FT_Client interacts with FR#1. +# FT_Client asks FR#1 to fault. It does so. +# FT_Client notices fault and switches to FR#2. [1] +# FD#1 notices fault and notifies Fault_Notifier +# FD#1 terminates +# ***Test: Fault_Notifier forwards notification to StubAnalyzer +# StubAnalyzer prints notification. +# FT_Client interacts with FR#2. +# FT_Client asks FR#2 to shut down. +# FT_Client shuts down. +# FD#2 notices FR2 is gone, interprets this +# as a fault, and sends notification to Fault_Notifier +# FD#2 terminates. +# ***Test: Fault_Notifier forwards notification to StubAnalyzer +# StubAnalyzer prints notification. +# Phase 4: shutting down. +# All FaultDetectors have terminated so the FaultDetectorFactory +# honors the "quit-on-idle" option on it's command line and exits. +# StubAnalyzer compares # fault notifications to # replicas. When +# they match, it "knows" that the test is over, so it shuts down. +# As it does so, it disconnects its fault consumers from the FaultNotifier. +# FaultNotifier notices the last fault consumer disconnecting and exits because +# the "quit-on-idle" option was specified on the command line. +# Phase 5: housekeeping +# Wait for all processes to terminate. +# Check termination status. +# Delete temp files. +# +# [1] Client mediated fault tolerance. These points will +# change when IOGR support is available. +use lib '../../../../bin'; +#use lib '$ENV{ACE_ROOT}/bin'; +use PerlACE::Run_Test; + +######################## +#command line options +#set defaults: +my($verbose) = 0; # 1: report perl actions before executing them +my($debug_builds) = 0; # 0: use exes from Release directories +my($simulated) = 1; # 1: use "client simulated" fault tolerance + +foreach $i (@ARGV) { + if ($i eq "--debug_build") + { + $debug_builds = 1; + } + elsif ($i eq "--no_simulate") # reverse this once we have FT ORB support + { + $simulated = 0; + } + elsif ($i eq "-v") + { + $verbose += 1; + } +} + + +my($build_directory) = "/Release"; +if ( $debug_builds ) { + $build_directory = ""; +} + +if ( $verbose > 1) { + print "verbose: $verbose\n"; + print "debug_builds: $debug_builds -> $build_directory\n"; + print "simulated: $simulated\n"; +} + + +#define temp files +my($factory1_ior) = PerlACE::LocalFile ("factory1.ior"); +my($factory2_ior) = PerlACE::LocalFile ("factory2.ior"); +my($replica1_ior) = PerlACE::LocalFile ("replica1.ior"); +my($replica2_ior) = PerlACE::LocalFile ("replica2.ior"); +my($detector_ior) = PerlACE::LocalFile ("detector.ior"); +my($notifier_ior) = PerlACE::LocalFile ("notifier.ior"); +my($ready_file) = PerlACE::LocalFile ("ready.file"); +my($client_data) = PerlACE::LocalFile ("persistent.dat"); + +#discard junk from previous tests +unlink $factory1_ior; +unlink $factory2_ior; +unlink $replica1_ior; +unlink $replica2_ior; +unlink $detector_ior; +unlink $notifier_ior; +unlink $ready_file; +unlink $client_data; + +my($status) = 0; + +my($REP1) = new PerlACE::Process (".$build_directory/ft_replica", "-o $factory1_ior -t $replica1_ior -r 1 -q"); +my($REP2) = new PerlACE::Process (".$build_directory/ft_replica", "-o $factory2_ior -t $replica2_ior -r 2 -q"); +my($DET) = new PerlACE::Process ("$ENV{'TAO_ROOT'}/orbsvcs/Fault_Detector$build_directory/Fault_Detector", "-o $detector_ior -q"); +my($NOT) = new PerlACE::Process ("$ENV{'TAO_ROOT'}/orbsvcs/Fault_Notifier$build_directory/Fault_Notifier", "-o $notifier_ior -v -q"); +my($ANA) = new PerlACE::Process (".$build_directory/ft_analyzer", "-o $ready_file -n $notifier_ior -q -d $detector_ior -r $replica1_ior,$replica2_ior"); + +my($CL); +if (simulated) { + $CL = new PerlACE::Process (".$build_directory/ft_client", "-f $replica1_ior,$replica2_ior -c testscript"); +}else{ + #todo figure out how to get iogr + $CL = new PerlACE::Process (".$build_directory/ft_client", "-f $replica1_iogr -c testscript"); +} + +print "TEST: starting replica1 " . $REP1->CommandLine . "\n" if ($verbose); +$REP1->Spawn (); + +print "TEST: waiting for replica 1's IOR\n" if ($verbose); +if (PerlACE::waitforfile_timed ($replica1_ior, 5) == -1) { + print STDERR "ERROR: cannot find file <$replica1_ior>\n"; + $REP1->Kill (); $REP1->TimedWait (1); + exit 1; +} + +print "\nTEST: starting replica2 " . $REP2->CommandLine . "\n" if ($verbose); +$REP2->Spawn (); + +print "TEST: waiting for replica 2's IOR\n" if ($verbose); +if (PerlACE::waitforfile_timed ($replica2_ior, 5) == -1) { + print STDERR "ERROR: cannot find file <$replica2_ior>\n"; + $REP1->Kill (); $REP1->TimedWait (1); + $REP2->Kill (); $REP2->TimedWait (1); + exit 1; +} + +print "\nTEST: starting detector factory " . $DET->CommandLine . "\n" if ($verbose); +$DET->Spawn (); + +print "TEST: waiting for detector's IOR\n" if ($verbose); +if (PerlACE::waitforfile_timed ($detector_ior, 5) == -1) { + print STDERR "ERROR: cannot find file <$detector_ior>\n"; + $REP1->Kill (); $REP1->TimedWait (1); + $REP2->Kill (); $REP2->TimedWait (1); + $DET->Kill (); $DET2->TimedWait(1); + exit 1; +} + +print "\nTEST: starting notifier " . $NOT->CommandLine . "\n" if ($verbose); +$NOT->Spawn (); + +print "TEST: waiting for notifier's IOR\n" if ($verbose); +if (PerlACE::waitforfile_timed ($notifier_ior, 5) == -1) { + print STDERR "ERROR: cannot find file <$notifier_ior>\n"; + $REP1->Kill (); $REP1->TimedWait (1); + $REP2->Kill (); $REP2->TimedWait (1); + $DET->Kill (); $DET2->TimedWait(1); + $ANA->Kill (); $ANA->TimedWait(1); + exit 1; +} + +print "\nTEST: starting analyzer " . $ANA->CommandLine . "\n" if ($verbose); +$ANA->Spawn (); + +print "TEST: waiting for READY.FILE from analyzer\n" if ($verbose); +if (PerlACE::waitforfile_timed ($ready_file, 5) == -1) { + print STDERR "ERROR: cannot find file <$ready_file>\n"; + $REP1->Kill (); $REP1->TimedWait (1); + $REP2->Kill (); $REP2->TimedWait (1); + $DET->Kill (); $DET2->TimedWait(1); + $NOT->Kill (); $NOT->TimedWait(1); + $ANA->Kill (); $ANA->TimedWait(1); + exit 1; +} + +print "\nTEST: starting client " . $CL->CommandLine . "\n" if ($verbose); +$client = $CL->SpawnWaitKill (60); + +if ($client != 0) { + print STDERR "ERROR: client returned $client\n"; + $status = 1; +} + +print "\nTEST: wait for replica 1.\n" if ($verbose); +$replica1 = $REP1->WaitKill (60); +if ($replica1 != 0) { + print STDERR "ERROR: replica returned $replica1\n"; + $status = 1; +} + +print "\nTEST: wait for replica 2.\n" if ($verbose); +$replica2 = $REP2->WaitKill (60); +if ($replica2 != 0) { + print STDERR "ERROR: replica returned $replica2\n"; + $status = 1; +} + +print "\nTEST: wait for detector factory to leave.\n" if ($verbose); +$detector = $DET->WaitKill (60); +if ($detector != 0) { + print STDERR "ERROR: detector returned $detector\n"; + $status = 1; +} + +print "\nTEST: wait for notifier to leave.\n" if ($verbose); +$notifier = $NOT->WaitKill (60); +if ($notifier != 0) { + print STDERR "ERROR: notifier returned $notifier\n"; + $status = 1; +} + +print "\nTEST: wait for analyzer to leave.\n" if ($verbose); +$analyzer = $ANA->WaitKill (60); +if ($analyzer != 0) { + print STDERR "ERROR: analyzer returned $analyzer\n"; + $status = 1; +} + +print "\nTEST: releasing scratch files.\n" if ($verbose); +unlink $replica1_ior; +unlink $replica2_ior; +unlink $detector_ior; +unlink $notifier_ior; +unlink $ready_file; + +#client's work file +unlink $client_data; + +exit $status; |