diff options
author | wilson_d <wilson_d@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2003-12-22 01:44:39 +0000 |
---|---|---|
committer | wilson_d <wilson_d@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2003-12-22 01:44:39 +0000 |
commit | 8baa9efef6fb74b6882c89ca6b198784a89e8256 (patch) | |
tree | 8262d7e8599334f6f03607a19fbea89556dd952f /TAO/orbsvcs/tests | |
parent | bee9b009502570c2ccda8417563f268d6a3c0087 (diff) | |
download | ATCD-8baa9efef6fb74b6882c89ca6b198784a89e8256.tar.gz |
ChangeLogTag: Sun Dec 21 19:35:44 2003 Dale Wilson <wilson_d@ociweb.com>
Diffstat (limited to 'TAO/orbsvcs/tests')
48 files changed, 8941 insertions, 15 deletions
diff --git a/TAO/orbsvcs/tests/FT_App/.cvsignore b/TAO/orbsvcs/tests/FT_App/.cvsignore new file mode 100644 index 00000000000..8e4cf88d091 --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/.cvsignore @@ -0,0 +1,16 @@ +*.dsp +*.dsw +*.ilk +*.pdb +*.plg +*.ncb +*.opt +*.exe +*.ior +*.dat +Release +Debug +FT_ReplicaC* +FT_ReplicaS* +FT_TestReplicaC* +FT_TestReplicaS* diff --git a/TAO/orbsvcs/tests/FT_App/FTAPP_Analyzer_Main.cpp b/TAO/orbsvcs/tests/FT_App/FTAPP_Analyzer_Main.cpp new file mode 100644 index 00000000000..36657366c10 --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/FTAPP_Analyzer_Main.cpp @@ -0,0 +1,33 @@ +/* -*- C++ -*- */ +//============================================================================= +/** + * @file FTAPP_Analyzer_Main.cpp + * + * $Id$ + * + * This file is part of Fault Tolerant CORBA. + * This file provides the main routine for a stub FaultAnalyzer + * + * @author Dale Wilson <wilson_d@ociweb.com> + */ +//============================================================================= + +#include <tao/Utils/Server_Main.h> +#include "StubFaultAnalyzer.h" + +int ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + TAO::Utils::Server_Main<StubFaultAnalyzer> server_run("FaultAnalyzer"); + return server_run.run(argc, argv); +} + +/////////////////////////////////// +// Template instantiation for +// inept compilers. + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) + template class TAO::Utils::Server_Main<StubFaultAnalyzer>; +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +# pragma instantiate TAO::Utils::Server_Main<StubFaultAnalyzer> +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ + 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..af2524a1fe1 --- /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/Server_Main.h> +#include <orbsvcs/PortableGroup/PG_FactoryRegistry.h> + +int ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + TAO::Utils::Server_Main<TAO::PG_FactoryRegistry> server_main("FactoryRegistry"); + return server_main.run(argc, argv); +} + +/////////////////////////////////// +// Template instantiation for +// inept compilers. + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) + template class TAO::Utils::Server_Main<TAO::PG_FactoryRegistry>; +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +# pragma instantiate TAO::Utils::Server_Main<TAO::PG_FactoryRegistry> +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ + diff --git a/TAO/orbsvcs/tests/FT_App/FTAPP_FaultConsumer_Main.cpp b/TAO/orbsvcs/tests/FT_App/FTAPP_FaultConsumer_Main.cpp new file mode 100644 index 00000000000..8236a0465d0 --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/FTAPP_FaultConsumer_Main.cpp @@ -0,0 +1,33 @@ +/* -*- C++ -*- */ +//============================================================================= +/** + * @file FTApp_FaultConsumer_Main.cpp + * + * $Id$ + * + * This file is part of Fault Tolerant CORBA. + * This file provides the main routine for a stub FaultConsumer. + * + * @author Steve Totten <totten_s@ociweb.com> + */ +//============================================================================= + +#include <tao/Utils/Server_Main.h> +#include "ReplicationManagerFaultConsumerAdapter.h" + +int ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + TAO::Utils::Server_Main<ReplicationManagerFaultConsumerAdapter> + server_main("FaultConsumer"); + return server_main.run(argc, argv); +} + +/////////////////////////////////// +// Template instantiation for +// inept compilers. + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) + template class TAO::Utils::Server_Main<ReplicationManagerFaultConsumerAdapter>; +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +# pragma instantiate TAO::Utils::Server_Main<ReplicationManagerFaultConsumerAdapter> +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/orbsvcs/tests/FT_App/FTAPP_Notifier_Main.cpp b/TAO/orbsvcs/tests/FT_App/FTAPP_Notifier_Main.cpp new file mode 100644 index 00000000000..9c89038cdbb --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/FTAPP_Notifier_Main.cpp @@ -0,0 +1,34 @@ +/* -*- C++ -*- */ +//============================================================================= +/** + * @file FTAPP_Notifier_Main.cpp + * + * $Id$ + * + * This file is part of Fault Tolerant CORBA. + * This file provides the main routine for a stub implementation + * of the FaultNotifier interface. + * + * @author Dale Wilson <wilson_d@ociweb.com> + */ +//============================================================================= + +#include "StubFaultNotifier.h" +#include <tao/Utils/Server_Main.h> + +int ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + TAO::Utils::Server_Main<StubFaultNotifier> server_main("FaultNotifier"); + return server_main.run(argc, argv); +} + +/////////////////////////////////// +// Template instantiation for +// inept compilers. + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) + template class TAO::Utils::Server_Main<StubFaultNotifier>; +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +# pragma instantiate TAO::Utils::Server_Main<StubFaultNotifier> +#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 new file mode 100644 index 00000000000..0b91e76f89f --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/FT_App.mpc @@ -0,0 +1,135 @@ +project(*Server): taoserver, fault_tolerance, orbsvcsexe{ + exename = ft_replica + Source_Files { + FT_Replica.cpp + FT_TestReplica_i.cpp + FT_ReplicaFactory_i.cpp + } +// Custom folder: test scripts +// too bad this doesn't work! +// If you omit the generic_outputext, it creates an empty folder +// if you include the generic_outputext, it tries to "build" the .pl +// file which runs the test even when you don't want to. +// Define_Custom(Script) { +// inputext = .pl, .py, .rb +// generic_outputext = .txt +// } +// Script_Files { +// run_test_detector.pl +// } + + Documentation_Files { + README + FT_App.mpc + run_test_basic.pl // can the client talk to the server + run_test_detector.pl // does a detector notice a server fault + run_test_notifier.pl // does the notification get to an analyzer + run_test_fault_consumer.pl // Is the notification analyzed correctly + run_test_registry.pl // does the stand-along factory registry work + run_test_rmregistry.pl // does the factory registry in the RM work + run_test_replication_mgr.pl // + run_test_demo.pl // test it all together + } +} + +project(*Client): taoclient, fault_tolerance, orbsvcsexe { + exename = ft_client + includes += $(TAO_ROOT) + after += *Server + Source_Files { + FT_Client.cpp + } + Documentation_Files { + } +} + +project(*Notifier): taoserver, fault_tolerance, orbsvcsexe { + exename = ft_notifier + Source_Files { + FTAPP_Notifier_Main.cpp + StubFaultNotifier.cpp + } + + // explicitly omit IDL and doc files + IDL_Files { + } + Documentation_Files { + } +} + +project(*Analyzer): taoclient, fault_tolerance, orbsvcsexe { + exename = ft_analyzer + + Source_Files { + FTAPP_Analyzer_Main.cpp + StubFaultAnalyzer.cpp + StubFaultConsumer.cpp + StubBatchConsumer.cpp + } + + // explicitly omit IDL files + IDL_Files { + } + Documentation_Files { + } +} + +project(*FaultConsumer): taoserver, fault_tolerance, orbsvcsexe { + exename = ft_fault_consumer + libs += TAO_ReplicationManagerLib + Source_Files { + FTAPP_FaultConsumer_Main.cpp + ReplicationManagerFaultConsumerAdapter.cpp + } + + // explicitly omit IDL files + IDL_Files { + } + Documentation_Files { + } +} + +project(*FactoryRegistry): taoclient, fault_tolerance, orbsvcsexe { + exename = ft_registry + + Source_Files { + FTAPP_FactoryRegistry_Main.cpp + } + + Header_Files { + + } + // explicitly omit IDL files + IDL_Files { + } + Documentation_Files { + } +} + +project(*Creator): taoclient, fault_tolerance, orbsvcsexe { + exename = ft_create + + Source_Files { + FT_Creator.cpp + TAO_Object_Group_Creator.cpp + } + + // explicitly omit IDL files + IDL_Files { + } + + Documentation_Files { + } +} + +project(*RMController): taoclient, fault_tolerance, orbsvcsexe { + exename = replmgr_controller + Source_Files { + FT_ReplicationManagerController.cpp + } + // explicitly omit IDL files + IDL_Files { + } + Documentation_Files { + } +} diff --git a/TAO/orbsvcs/tests/FT_App/FT_Client.cpp b/TAO/orbsvcs/tests/FT_App/FT_Client.cpp new file mode 100644 index 00000000000..ddbe4984adf --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/FT_Client.cpp @@ -0,0 +1,621 @@ +// $Id$ + +#include "FT_TestReplicaC.h" +#include <ace/Vector_T.h> +#include <ace/SString.h> +#include <ace/Get_Opt.h> +#include <iostream> +#include <fstream> + +class FTClientMain +{ + typedef ACE_Vector<ACE_CString> StringVec; + public: + /////////////////////////// + // construction/destruction + FTClientMain (); + + ~FTClientMain (); + + ///////////////// + // initialization + int parse_args (int argc, char *argv[]); + + //////////// + // execution + int run (); + + ///////////////// + // implementation +private: + void usage (ostream & out)const; + void commandUsage (ostream & out); + int pass ( + long & counter, // inout + int & more, // out + ACE_CString & command, // inout + int retry // in + ); + + + int next_replica (ACE_ENV_SINGLE_ARG_DECL); + + //////////////////// + // forbidden methods + private: + FTClientMain (const FTClientMain & rhs); + FTClientMain & operator = (const FTClientMain & rhs); + + //////////////// + // Data members + private: + + CORBA::ORB_var orb_; + + int argc_; + char ** argv_; + const char * inFileName_; + std::ifstream inFile_; + std::istream *commandIn_; + + enum Verbosity{ + SILENT, + QUIET, + NORMAL, + NOISY, + LOUD} + verbose_; + + + StringVec replica_iors_; + size_t replica_pos_; + const char * replica_name_; + FT_TEST::TestReplica_var replica_; +}; + + +FTClientMain::FTClientMain () + : commandIn_(&std::cin) + , verbose_(NORMAL) + , replica_pos_(0) + , replica_name_("none") +{ +} + +FTClientMain::~FTClientMain () +{ + if (this->inFile_.is_open()) + { + this->inFile_.close(); + } +} + +void FTClientMain::commandUsage(ostream & out) +{ + out + << "Each command must be at the beginning of a separate line." << std::endl + << "Everything after the command (and operand if any) is ignored." << std::endl + << "Valid commands are:" << std::endl + << " Access via method call:" << std::endl + << " =N set counter to N" << std::endl + << " cN get counter and compare to N (c stands for \"check\""<< std::endl + << " +N increment counter by N" << std::endl + << " -N decrement counter by N" << std::endl + << " Access as attribute:" << std::endl + << " >N set attribute to N" << std::endl + << " < get attribite" << std::endl + << " Try methods to be used by fault tolerant infrastructure: " << std::endl + << " ! is_alive" << std::endl + << " s get_state" << std::endl + << " S set_state" << std::endl + << " u get_update" << std::endl + << " U set_update" << std::endl + << " Simulate failure:" << std::endl + << " dN die on condition:" << std::endl + << " d" << FT_TEST::TestReplica::NOT_YET << " don't die" << std::endl + << " d" << FT_TEST::TestReplica::RIGHT_NOW << " immediately" << std::endl + << " d" << FT_TEST::TestReplica::WHILE_IDLE << " while idle" << std::endl + << " (FT_TestReplica interface)" << std::endl + << " d" << FT_TEST::TestReplica::BEFORE_STATE_CHANGE << " before state change" << std::endl + << " d" << FT_TEST::TestReplica::BEFORE_REPLICATION << " after state change, before replication" << std::endl + << " d" << FT_TEST::TestReplica::BEFORE_REPLY << " after replication, before reply "<< std::endl + << " (Monitorable interface)" << std::endl + << " d" << FT_TEST::TestReplica::DURING_IS_ALIVE << " during is alive" << std::endl + << " d" << FT_TEST::TestReplica::DENY_IS_ALIVE << " is_alive returns false" << std::endl + << " (Updatable interface)" << std::endl + << " d" << FT_TEST::TestReplica::DURING_GET_UPDATE << " during get update" << std::endl + << " d" << FT_TEST::TestReplica::BEFORE_SET_UPDATE << " before set update" << std::endl + << " d" << FT_TEST::TestReplica::AFTER_SET_UPDATE << " after set update" << std::endl + << " (Checkpointable interface)" << std::endl + << " d" << FT_TEST::TestReplica::DURING_GET_STATE << " during get state" << std::endl + << " d" << FT_TEST::TestReplica::BEFORE_SET_STATE << " before set state" << std::endl + << " d" << FT_TEST::TestReplica::AFTER_SET_STATE << " after set state" << std::endl + << " Logistics commands:" << std::endl + << " # ignore this line (comment)." << std::endl + << " v set verbosity:" << std::endl + << " 0 don't check counter value." << std::endl + << " 1 only display counter value mismatch." << std::endl + << " 2 display counter value after every command (default)." << std::endl + << " 3 display commands." << std::endl + << " 4 display method calls." << std::endl + << " zN sleep N seconds." << std::endl + << " q quit (end the client, not the replica(s).)" << std::endl + << " q1 quit (end the client, and shutdown the currently active replica.)" << std::endl + << " ? help (this message)" << std::endl; +} + +int +FTClientMain::parse_args (int argc, char *argv[]) +{ + this->argc_ = argc; + this->argv_ = argv; + int result = 0; + + // note: dfnkx are simple_util options + // include them here so we can detect bad args + ACE_Get_Opt get_opts (argc, argv, "c:f:"); + int c; + + while (result == 0 && (c = get_opts ()) != -1) + { + switch (c) + { + case 'c': + { + this->inFileName_ = get_opts.opt_arg (); + this->inFile_.open(this->inFileName_); + if(this->inFile_.is_open() && this->inFile_.good()) + { + std::cout << "FT Client: Reading commands from " << this->inFileName_ << std::endl; + this->commandIn_ = & this->inFile_; + } + else + { + std::cout << "FT Client: Can't open input file: " << this->inFileName_ << std::endl; + result = -1; + } + break; + } + case 'f': + { + replica_iors_.push_back(get_opts.opt_arg ()); + break; + } + + default: + case '?': + usage(std::cerr); + result = 1; + } + } + return result; +} + +void FTClientMain::usage(ostream & out)const +{ + out << "usage" + << " -c <command file>" + << " [-f <ior file>]..." + << std::endl; +} + +int FTClientMain::pass ( + long & counter, + int & more, + ACE_CString & command, + int retry) +{ + int result = 0; + + ::FT::State_var state; + unsigned long stateValue = 0; + ::FT::State_var update; + unsigned long updateValue = 0; + + while(more && result == 0 && ! this->commandIn_->eof()) + { + if (! retry || command.length () == 0 ) + { + char buffer[1000]; + this->commandIn_->getline(buffer, sizeof(buffer)-1); + command = buffer; + } + retry = 0; + + if (command.length() >0) + { + char op = command[0]; + ACE_CString cdr = command.substr(1); + char * junque; + long operand = strtol(cdr.c_str(),&junque, 10); + + if (this->verbose_ >= NOISY) + { + std::cout << "FT Client: " << command << std::endl; + } + + // turn echo on (based on verbose) + // individual commands can turn it off + int echo = this->verbose_ >= QUIET; + + switch(op) + { + case '#': + { + echo = 0; + break; + } + case '=': + { + if (this->verbose_ >= LOUD) + { + std::cout << "FT Client: ->set(" << operand << ");" << std::endl; + } + this->replica_->set(operand ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + counter = operand; + break; + } + case 'c': + { + if (this->verbose_ >= LOUD) + { + std::cout << "FT Client: ->get();" << std::endl; + } + long value = this->replica_->counter(ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + if (value == operand) + { + std::cout << "FT Client: Good: Read " << value << " expecting " << operand << std::endl; + counter = operand; + } + else + { + std::cout << "FT Client: Error: Read " << value << " expecting " << operand << std::endl; + } + echo = 0; + break; + + } + case '>': + { + if (this->verbose_ >= LOUD) + { + std::cout << "FT Client: ->counter(" << operand << ");" << std::endl; + } + this->replica_->counter(operand ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + counter = operand; + break; + } + case '+': + { + if (this->verbose_ >= LOUD) + { + std::cout << "FT Client: ->increment(" << operand << ");" << std::endl; + } + this->replica_->increment(operand ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + counter += operand; + break; + } + case '-': + { + if (this->verbose_ >= LOUD) + { + std::cout << "FT Client: ->increment(" << -operand << ");" << std::endl; + } + this->replica_->increment(-operand ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + counter -= operand; + break; + } + case '<': + { + if (this->verbose_ >= LOUD) + { + std::cout << "FT Client: ->counter();" << std::endl; + } + long attribute = this->replica_->counter(ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + std::cout << "FT Client: Attribute: " << attribute << std::endl; + echo = 0; + break; + } + case '!': + { + if (this->verbose_ >= LOUD) + { + std::cout << "FT Client: ->is_alive();" << std::endl; + } + int alive = this->replica_->is_alive(ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + std::cout << "FT Client: Is alive? " << alive << std::endl; + break; + } + case 'd': + { + if (this->verbose_ >= LOUD) + { + std::cout << "FT Client: ->die(" << operand << ");" << std::endl; + } + this->replica_->die(ACE_static_cast (FT_TEST::TestReplica::Bane, operand) ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + echo = 0; + break; + } + case 's': + { + if (this->verbose_ >= LOUD) + { + std::cout << "FT Client: ->get_state();" << std::endl; + } + state = this->replica_->get_state(ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + stateValue = counter; + break; + } + case 'S': + { + if (state.in() != 0) + { + if (this->verbose_ >= LOUD) + { + std::cout << "FT Client: ->set_state(saved_state);" << std::endl; + } + this->replica_->set_state(state ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + counter = stateValue; + } + else + { + std::cout << "FT Client: Error: no saved state." << std::endl; + } + break; + } + case 'u': + { + if (this->verbose_ >= LOUD) + { + std::cout << "FT Client: ->get_update();" << std::endl; + } + update = this->replica_->get_update(ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + updateValue = counter; + break; + } + case 'U': + { + if (update.in() != 0) + { + if (this->verbose_ >= LOUD) + { + std::cout << "FT Client: ->set_update(saved_update);" << std::endl; + } + this->replica_->set_update(update ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + counter = updateValue; + } + else + { + std::cout << "FT Client: ERROR: No saved update information." << std::endl; + } + break; + } + case 'v': + { + this->verbose_ = ACE_static_cast(Verbosity, operand); + break; + } + case 'z': + { + if (operand == 0) + { + operand = 1; + } + ACE_Time_Value tv (operand,0); + ACE_OS::sleep(tv); + break; + } + case 'q': + { + if (operand != 0) + { + ACE_TRY_NEW_ENV + { + if (this->verbose_ >= LOUD) + { + std::cout << "FT Client: ->shutdown();" << std::endl; + } + this->replica_->shutdown( ACE_ENV_SINGLE_ARG_PARAMETER); + // @@ Note: this is here because the corba event loop seems to go to sleep + // if there's nothing for it to do. + // not quite sure why, yet. Dale + this->replica_->is_alive(ACE_ENV_SINGLE_ARG_PARAMETER); + } + ACE_CATCHANY + { + std::cout << "FT Client: Ignoring expected exception during shutdown." << std::endl; + ; // ignore exception during shutdown + } + ACE_ENDTRY; + } + echo = 0; + more = 0; + break; + } + default: + { + if (op != '?') + { + std::cout << "FT Client: Unknown: " << command << std::endl; + } + commandUsage(std::cerr); + break; + } + } + if (echo && this->verbose_ >= QUIET) + { + if (this->verbose_ >= LOUD) + { + std::cout << "FT Client: ->get();" << std::endl; + } + + long value = this->replica_->get(ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + if (value == counter) + { + if (this->verbose_ >= NORMAL) + { + std::cout << "FT Client: " << counter << std::endl;; + } + } + else + { + std::cout << "FT Client: Error: read " << value << " expecting " << counter << std::endl; + result = -1; + } + } + } + } + return result; +} + +int FTClientMain::next_replica (ACE_ENV_SINGLE_ARG_DECL) +{ + int result = 0; + if (this->replica_pos_ < this->replica_iors_.size()) + { + this->replica_name_ = this->replica_iors_[this->replica_pos_].c_str(); + this->replica_pos_ += 1; + CORBA::Object_var rep_obj = this->orb_->string_to_object (this->replica_name_ ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0) + replica_ = FT_TEST::TestReplica::_narrow (rep_obj.in ()); + if (! CORBA::is_nil (replica_.in ())) + { + result = 1; + } + else + { + std::cerr << "FT Client: Can't resolve IOR: " << this->replica_name_ << std::endl; + } + } + else + { + std::cerr << "***OUT_OF_REPLICAS*** " << this->replica_pos_ << std::endl; + } + return result; +} + + +int FTClientMain::run () +{ + int result = 0; + + this->orb_ = CORBA::ORB_init(this->argc_, this->argv_ ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1) + + if (next_replica ()) + { + // retry information + ACE_CString command; + int retry = 0; + long counter = this->replica_->get(ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + if (this->verbose_ >= NORMAL) + { + std::cout << "FT Client: Initial counter " << counter << std::endl; + } + if (ACE_OS::isatty(fileno(stdin))) + { + std::cout << "FT Client: Commands(? for help):" << std::endl; + } + + int more = 1; + while (more && result == 0 && ! this->commandIn_->eof()) + { + ACE_TRY_NEW_ENV + { + result = pass (counter, more, command, retry); + ACE_TRY_CHECK; + } + ACE_CATCH (CORBA::SystemException, sysex) + { + std::cout << "FT Client: Caught system exception: " << std::endl; + ACE_PRINT_EXCEPTION (sysex, "FT Client"); + + retry = 0; + int handled = 0; + + handled = next_replica(); + if (handled) + { + std::cout << "FT Client: Recovering from fault." << std::endl; + std::cout << "FT Client: Activate " << this->replica_name_ << std::endl; + if (command.length () == 0) + { + std::cout << "FT Client: No command to retry." << std::endl; + } + else if (command[0] == 'd') + { + std::cout << "FT Client: Not retrying \"die\" command." << std::endl; + } + else if (sysex.completed () == CORBA::COMPLETED_YES) + { + std::cout << "FT Client: Last command completed. No retry needed." << std::endl; + } + else + { + if (sysex.completed () == CORBA::COMPLETED_MAYBE) + { + std::cout << "FT Client: Last command may have completed. Retrying anyway." << std::endl; + } + retry = 1; + std::cout << "FT Client: Retrying command: " << command << std::endl; + } + } + if (! handled) + { + std::cout << "FT Client: Exception not handled. Rethrow. " << std::endl; + ACE_RE_THROW; + } + } + ACE_ENDTRY; + } + } + else + { + std::cerr << "FT Client: Can't connect to replica." << std::endl; + } + return result; +} + + +int +main (int argc, char *argv[]) +{ + FTClientMain app; + int result = app.parse_args(argc, argv); + if (result == 0) + { + ACE_TRY_NEW_ENV + { + result = app.run (); + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + "FT_Client::main\t\n"); + result = -1; + } + ACE_ENDTRY; + } + return result; +} + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) + template class ACE_Vector<ACE_CString>; +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +# pragma ACE_Vector<ACE_CString> +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/orbsvcs/tests/FT_App/FT_Creator.cpp b/TAO/orbsvcs/tests/FT_App/FT_Creator.cpp new file mode 100644 index 00000000000..f8f39abca76 --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/FT_Creator.cpp @@ -0,0 +1,293 @@ +/* -*- C++ -*- */ +//============================================================================= +/** + * @file TAO_Object_Group_Creator.cpp + * + * $Id$ + * + * This file is part of Fault Tolerant CORBA. + * Main wrapped around TAO_Object_Group_Creator + * + * @author Dale Wilson <wilson_d@ociweb.com> + */ +//============================================================================= + +#include "FT_Creator.h" +#include <iostream> +#include <fstream> +#include <orbsvcs/PortableGroup/PG_Properties_Encoder.h> + +#include <ace/Get_Opt.h> + + +FTAPP::FT_Creator::FT_Creator () + : creator_ () + , orb_ (CORBA::ORB::_nil ()) + , registry_ior_(0) + , replication_manager_ (::FT::ReplicationManager::_nil ()) + , have_replication_manager_ (0) + , write_iors_ (0) + , write_iogr_ (0) + , ns_register_ (1) + , iogr_seq_ (0) + , prefix_ ("") +{ +} + +FTAPP::FT_Creator::~FT_Creator () +{ +} + +int +FTAPP::FT_Creator::parse_args (int argc, char *argv[]) +{ + int result = 0; + + ACE_Get_Opt get_opts (argc, argv, "r:ignf:u:p:"); + int c; + + while (result == 0 && (c = get_opts ()) != -1) + { + switch (c) + { + case 'r': + { + this->create_roles_.push_back (get_opts.opt_arg ()); + break; + } + case 'u': + { + this->unregister_roles_.push_back (get_opts.opt_arg ()); + break; + } + case 'f': + { + this->registry_ior_ = get_opts.opt_arg (); + break; + } + + case 'g': + { + this->write_iogr_ = !this->write_iogr_; + break; + } + + case 'i': + { + this->write_iors_ = ! this->write_iors_; + break; + } + + case 'n': + { + this->ns_register_ = !this->ns_register_; + break; + } + + case 'p': + { + this->prefix_ = get_opts.opt_arg(); + break; + } + + default: + { + std::cerr << "Creator: Unknown argument -" << (char) c << std::endl; + usage(std::cerr); + result = 1; + break; + } + case '?': + { + usage(std::cerr); + result = 1; + break; + } + } + } + + if ( this->create_roles_.size() == 0 && this->unregister_roles_.size() == 0) + { + std::cerr << "Creator: neither create (-t) nor kill (-u) specified. Nothing to do." << std::endl; + usage (std::cerr); + result = -1; + } + + return result; +} + +void FTAPP::FT_Creator::usage(ostream & out)const +{ + out << "usage\n" + << " -r <role for objects to be created>\n" + << " -f <factory registry ior file> (if not specified, ReplicationManager is used.)\n" + << " -u <role to be unregistered (for testing factory registry)>\n" + << " -i (toggle write ior for each object (default false))\n" + << " -p <prefix for registration & file names>\n" + << " -g (toggle write iogr to file (default false))\n" + << " -n (toggle register iogr with name service (default true))\n" + ; +} + + + +int FTAPP::FT_Creator::init (CORBA::ORB_ptr orb ACE_ENV_ARG_DECL) +{ + int result = 0; + this->orb_ = CORBA::ORB::_duplicate (orb); + + // if a factory IOR was specified on command line + if ( this->registry_ior_ != 0) + { + CORBA::Object_var registry_obj = this->orb_->string_to_object (this->registry_ior_ ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + PortableGroup::FactoryRegistry_var registry = PortableGroup::FactoryRegistry::_narrow(registry_obj.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + if (! CORBA::is_nil (registry.in ())) + { + result = this->creator_.set_factory_registry(registry.in()); + } + } + + if (result == 0) + { + result = this->creator_.init (orb ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + } + + + if (result == 0 && this->ns_register_) + { + CORBA::Object_var naming_obj = + this->orb_->resolve_initial_references ("NameService" ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + if (CORBA::is_nil(naming_obj.in ())) + { + ACE_ERROR_RETURN ((LM_ERROR, + "%T %n (%P|%t) Unable to find the Naming Service\n"), + 1); + } + this->naming_context_= + CosNaming::NamingContext::_narrow (naming_obj.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + } + + return result; +} + +int FTAPP::FT_Creator::run (ACE_ENV_SINGLE_ARG_DECL) +{ + int result = 0; + size_t typeCount = this->create_roles_.size(); + size_t nType = 0; + for ( nType = 0; result == 0 && nType < typeCount; ++nType) + { + const char * role = this->create_roles_[nType].c_str(); + std::cout << std::endl << "Creator: Creating group of " << role << std::endl; + PortableGroup::ObjectGroup_var group = this->creator_.create_group ( + role, + this->write_iors_ + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (1); + + if (this->write_iogr_) + { + CORBA::String_var iogr = this->orb_->object_to_string (group.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (1); + + char iogr_filename[1000]; + ACE_OS::snprintf (iogr_filename, sizeof(iogr_filename)-1, "%s%s_%d.iogr", + this->prefix_, + role, + this->iogr_seq_); + FILE * iogr_file = fopen (iogr_filename, "w"); + if (iogr_file != 0) + { + char const * siogr = ACE_static_cast (const char *, iogr); + fwrite (siogr, 1, strlen(siogr), iogr_file); + fclose (iogr_file); + } + else + { + std::cerr << "Can't open iogr output file " << iogr_filename << std::endl; + result = 1; + } + } + + if(this->ns_register_) + { + char iogr_name[1000]; + ACE_OS::snprintf (iogr_name, sizeof(iogr_name)-1, "%s_%s_%d", + this->prefix_, + role, + this->iogr_seq_); + + CosNaming::Name this_name (1); + this_name.length (1); + this_name[0].id = CORBA::string_dup (iogr_name); + + this->naming_context_->rebind (this_name, group.in() + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (1); + } + + iogr_seq_ += 1; + + } + + typeCount = this->unregister_roles_.size(); + for ( nType = 0; result == 0 && nType < typeCount; ++nType) + { + const char * role = this->unregister_roles_[nType].c_str(); + result = this->creator_.unregister_role (role); + } + + return result; +} + +int FTAPP::FT_Creator::fini () +{ + return this->creator_.fini(); +} + +int +main (int argc, char *argv[]) +{ + int result = 0; + ACE_TRY_NEW_ENV + { + CORBA::ORB_var orb = CORBA::ORB_init(argc, argv ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + FTAPP::FT_Creator app; + result = app.parse_args(argc, argv); + if (result == 0) + { + result = app.init (orb.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + if (result == 0) + { + result = app.run (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + } + if (result == 0) + { + result = app.fini(); + } + } + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + "FT_Creator::main\t\n"); + result = -1; + } + ACE_ENDTRY; + return result; +} + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) + template class ACE_Vector<ACE_CString>; +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +# pragma instantiate ACE_Vector<ACE_CString> +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/orbsvcs/tests/FT_App/FT_Creator.h b/TAO/orbsvcs/tests/FT_App/FT_Creator.h new file mode 100644 index 00000000000..c0ca6d8d2be --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/FT_Creator.h @@ -0,0 +1,111 @@ +/* -*- C++ -*- */ +//============================================================================= +/** + * @file TAO_FT_Creator.h + * + * $Id$ + * + * This file is part of Fault Tolerant CORBA. + * Main wrapped around TAO_Object_Group_Creator + * + * @author Dale Wilson <wilson_d@ociweb.com> + */ +//============================================================================= + +#ifndef FT_CREATOR_H +#define FT_CREATOR_H +#include <ace/ACE.h> + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "TAO_Object_Group_Creator.h" + +namespace FTAPP +{ + class FT_Creator + { + typedef ACE_Vector<ACE_CString> StringVec; + public: + /////////////////////////// + // construction/destruction + FT_Creator (); + + ~FT_Creator (); + + ///////////////// + // initialization + int parse_args (int argc, char *argv[]); + + int init (CORBA::ORB_ptr orb ACE_ENV_ARG_DECL); + + //////////// + // execution + int run (ACE_ENV_SINGLE_ARG_DECL); + + //////////// + // shut down + int fini (); + + ///////////////// + // implementation + private: + void usage (ostream & out)const; + + //////////////////// + // forbidden methods + private: + FT_Creator (const FT_Creator & rhs); + FT_Creator & operator = (const FT_Creator & rhs); + + //////////////// + // Data members + private: + + TAO::Object_Group_Creator creator_; + CORBA::ORB_var orb_; + const char * registry_ior_; + StringVec create_roles_; + StringVec unregister_roles_; + + + CosNaming::NamingContext_var naming_context_; + + ::FT::ReplicationManager_var replication_manager_; + /** + * bool: true if we have a real replication manager + */ + int have_replication_manager_; + + /** + * bool: true if we should write individual IOR files + */ + int write_iors_; + + /** + * bool: true if we should write IOGR to a file + */ + int write_iogr_; + + /** + * bool: true if we should write IOGR to a Name Service + */ + int ns_register_; + + /** + * sequence number applied to created IOGRs + */ + unsigned long iogr_seq_; + + /** + * prefix for names + */ + const char * prefix_; + + + }; + +} // namespace TAO + +#endif // FT_CREATOR_H diff --git a/TAO/orbsvcs/tests/FT_App/FT_Replica.cpp b/TAO/orbsvcs/tests/FT_App/FT_Replica.cpp new file mode 100644 index 00000000000..43bd2b8b219 --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/FT_Replica.cpp @@ -0,0 +1,28 @@ +/* -*- C++ -*- */ +//============================================================================= +/** + * @file FT_Replica.cpp + * + * $Id$ + * + * This file is part of Fault Tolerant CORBA. + * Implement the FT_TEST::Replica IDL interface. + * + * @author Dale Wilson <wilson_d@ociweb.com> + */ +//============================================================================= + +#include <tao/Utils/Server_Main.h> +#include "FT_ReplicaFactory_i.h" + +int ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + TAO::Utils::Server_Main<FT_ReplicaFactory_i> server_main("TestReplicaFactory"); + return server_main.run(argc, argv); +} + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) + template class TAO::Utils::Server_Main<FT_ReplicaFactory_i>; +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +# pragma instantiate TAO::Utils::Server_Main<FT_ReplicaFactory_i> +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/orbsvcs/tests/FT_App/FT_ReplicaFactory_i.cpp b/TAO/orbsvcs/tests/FT_App/FT_ReplicaFactory_i.cpp new file mode 100644 index 00000000000..6347e0cfdc9 --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/FT_ReplicaFactory_i.cpp @@ -0,0 +1,774 @@ +/* -*- C++ -*- */ +//============================================================================= +/** + * @file FT_ReplicaFactory_i.cpp + * + * $Id$ + * + * This file is part of Fault Tolerant CORBA. + * + * @author Dale Wilson <wilson_d@ociweb.com> + */ +//============================================================================= +#include "FT_ReplicaFactory_i.h" +#include "FT_TestReplica_i.h" +#include <ace/Get_Opt.h> +#include <orbsvcs/CosNamingC.h> +#include <orbsvcs/PortableGroupC.h> +#include <tao/PortableServer/ORB_Manager.h> +#include <orbsvcs/PortableGroup/PG_Property_Set.h> + +// 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 */ + + +static const char * criterion_initial_value = "INITIAL_VALUE"; + +////////////////////////////////////////////////////// +// FT_ReplicaFactory_i Construction/destruction + +FT_ReplicaFactory_i::FT_ReplicaFactory_i () + : internals_ () + , orb_ (CORBA::ORB::_nil ()) + , poa_ (PortableServer::POA::_nil ()) + , object_id_ () + , ior_ () + , ior_output_file_ (0) + , identity_ () + , have_replication_manager_(0) + , replication_manager_(0) + , factory_registry_ior_(0) + , factory_registry_ (0) + , registered_(0) + , test_output_file_(0) + , ns_name_(0) + , naming_context_ (CosNaming::NamingContext::_nil ()) + , this_name_ () + , roles_ () + , location_ ("unknown") + , quit_on_idle_ (0) + , unregister_by_location_ (0) + , replicas_ () + , empty_slots_(0) + , quit_requested_(0) +{ + ACE_DEBUG((LM_DEBUG, "TestReplica type_id: %s\n", FT_TEST::_tc_TestReplica->id() )); +// ACE_DEBUG((LM_DEBUG, "Hobbit type_id: %s\n", FT_TEST::_tc_Hobbit->id() )); +// ACE_DEBUG((LM_DEBUG, "Elf type_id: %s\n", FT_TEST::_tc_Elf->id() )); +// ACE_DEBUG((LM_DEBUG, "Human type_id: %s\n", FT_TEST::_tc_Human->id() )); + +} + + +FT_ReplicaFactory_i::~FT_ReplicaFactory_i () +{ + //scope the guard + { + InternalGuard guard (this->internals_); + + // be sure all replicas are gone + // before this object disappears + shutdown_i (); + } +} + +//////////////////////////////////////////// +// FT_ReplicaFactory_i private methods + +CORBA::ULong FT_ReplicaFactory_i::allocate_id() +{ + // assume mutex is locked + CORBA::ULong id = this->replicas_.size(); + if (this->empty_slots_ != 0) + { + for(CORBA::ULong pos = 0; pos < id; ++pos) + { + if (this->replicas_[pos] == 0) + { + id = pos; + } + } + } + else + { + this->replicas_.push_back(0); + this->empty_slots_ += 1; + } + return id; +} + +void FT_ReplicaFactory_i::shutdown_i() +{ + // assume mutex is locked + for (size_t nReplica = 0; nReplica < this->replicas_.size(); ++nReplica) + { + FT_TestReplica_i * replica = this->replicas_[nReplica]; + if (replica != 0) + { + replica->request_quit(); + } + } +} + +int FT_ReplicaFactory_i::write_ior(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; +} + +////////////////////////////////////////////////////// +// FT_ReplicaFactory_i public, non-CORBA methods + +int FT_ReplicaFactory_i::parse_args (int argc, char * argv[]) +{ + ACE_Get_Opt get_opts (argc, argv, "o:n:f:i:l:t:qu"); + int c; + + while ((c = get_opts ()) != -1) + { + switch (c) + { + case 'o': + { + this->ior_output_file_ = get_opts.opt_arg (); + break; + } + case 'n': + { + this->ns_name_ = get_opts.opt_arg (); + break; + } + case 'f': + { + this->factory_registry_ior_ = get_opts.opt_arg (); + break; + } + case 'i': + { + this->roles_.push_back(get_opts.opt_arg ()); + break; + } + case 'l': + { + this->location_ = get_opts.opt_arg (); + break; + } + case 'q': + { + this->quit_on_idle_ = 1; + break; + } + case 'u': + { + this->unregister_by_location_ = 1; + break; + } + + case 't': + { + this->test_output_file_ = get_opts.opt_arg (); + break; + } + + case '?': + // fall thru + default: + ACE_ERROR_RETURN ((LM_ERROR, + "usage: %s \n" + " -o <factory ior file>\n" + " -n <naming service registration name>\n" + " -f <factory registry ior file>\n" + " -i <registration: role>\n" + " -l <registration: location>\n" + " -t <test replica ior file>\n" + " -u{nregister by location}\n" + " -q{uit on idle}\n", + argv [0]), + -1); + break; + } + } + // Indicates sucessful parsing of the command line + return 0; +} + +const char * FT_ReplicaFactory_i::location () const +{ + return this->location_; +} + +const char * FT_ReplicaFactory_i::identity () const +{ + return this->identity_.c_str(); +} + +int FT_ReplicaFactory_i::idle (int & result) +{ + result = 0; + size_t replicaCount = this->replicas_.size(); + if (replicaCount != this->empty_slots_) + { + for (size_t nReplica = 0; result == 0 && nReplica < replicaCount; ++nReplica) + { + FT_TestReplica_i * replica = this->replicas_[nReplica]; + if (replica != 0) + { + // give the replica's idle processing a change + // ignore the return status (the replica should shut itself down + // unless result is non-zero. + // non-zero result means panic. + replica->idle(result); + } + } + } + + int quit = (this->quit_requested_ || result != 0); + if (!quit && this->replicas_.size() == this->empty_slots_) + { +/* if you re-enable this, add some kind of throttle to avoid noise. + ACE_ERROR (( LM_ERROR, + "ReplicaFactory is idle.\n" + )); +*/ + if (this->quit_on_idle_ && this->empty_slots_ != 0) + { + ACE_ERROR (( LM_ERROR, + "%s exits due to quit on idle option.\n", + identity() + )); + quit = 1; + } + } + + return quit; +} + + + +int FT_ReplicaFactory_i::init (CORBA::ORB_ptr orb ACE_ENV_ARG_DECL) +{ + int result = 0; + + this->orb_ = CORBA::ORB::_duplicate (orb); + + // Use the ROOT POA for now + CORBA::Object_var poa_object = + this->orb_->resolve_initial_references (TAO_OBJID_ROOTPOA + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + if (CORBA::is_nil (poa_object.in ())) + { + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT (" (%P|%t) Unable to initialize the POA.\n")), + -1); + } + + // Get the POA object. + this->poa_ = + PortableServer::POA::_narrow (poa_object.in () + ACE_ENV_ARG_PARAMETER); + + ACE_CHECK_RETURN (-1); + if (CORBA::is_nil(this->poa_.in ())) + { + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT (" (%P|%t) Unable to narrow the POA.\n")), + -1); + } + + PortableServer::POAManager_var poa_manager = + this->poa_->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + // Register with the POA. + + this->object_id_ = this->poa_->activate_object (this ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + CORBA::Object_var this_obj = + this->poa_->id_to_reference (object_id_.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + this->ior_ = this->orb_->object_to_string (this_obj.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + if (this->factory_registry_ior_ != 0) + { + if (ACE_OS::strcmp (this->factory_registry_ior_, "none") != 0) + { + CORBA::Object_var reg_obj = this->orb_->string_to_object(factory_registry_ior_ + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + this->factory_registry_ = ::PortableGroup::FactoryRegistry::_narrow(reg_obj.in ()); + if (CORBA::is_nil(this->factory_registry_.in ())) + { + ACE_ERROR (( LM_ERROR, + "Can't resolve Factory Registry IOR %s\n", + this->factory_registry_ior_ + )); + result = -1; + } + } + } + else // no -f option. Try RIR(RM) + { + /////////////////////////////// + // Find the ReplicationManager + ACE_TRY_NEW_ENV + { + CORBA::Object_var rm_obj = orb->resolve_initial_references("ReplicationManager" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + this->replication_manager_ = ::FT::ReplicationManager::_narrow(rm_obj.in() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + if (!CORBA::is_nil (replication_manager_.in ())) + { + this->have_replication_manager_ = 1; + // empty criteria + ::PortableGroup::Criteria criteria; + this->factory_registry_ = this->replication_manager_->get_factory_registry(criteria ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + if (CORBA::is_nil (this->factory_registry_.in ())) + { + ACE_ERROR ((LM_ERROR,"ReplicaFactory: ReplicationManager failed to return FactoryRegistry. Factory will not be registered.\n" )); + } + } + else + { + this->factory_registry_ = ::PortableGroup::FactoryRegistry::_narrow(rm_obj.in() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + if (!CORBA::is_nil(this->factory_registry_.in ())) + { + ACE_DEBUG ((LM_DEBUG,"Found a FactoryRegistry DBA ReplicationManager\n" )); + } + else + { + ACE_ERROR ((LM_ERROR,"ReplicaFactory: Can't resolve ReplicationManager.\n" )); + } + } + } + ACE_CATCHANY + { + if (this->test_output_file_ == 0) // ignore if this is a test run + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + "ReplicaFactory: Exception resolving ReplicationManager. Factory will not be registered.\n" ); + } + } + ACE_ENDTRY; + + } + + if ( ! CORBA::is_nil (this->factory_registry_.in ())) + { + size_t roleCount = roles_.size(); + for (size_t nRole = 0; nRole < roleCount; ++nRole) + { + const char * roleName = this->roles_[nRole].c_str(); + + PortableGroup::FactoryInfo info; + info.the_factory = ::PortableGroup::GenericFactory::_narrow(this_obj.in ()); + info.the_location.length(1); + info.the_location[0].id = CORBA::string_dup(this->location_); + info.the_criteria.length(1); + info.the_criteria[0].nam.length(1); + info.the_criteria[0].nam[0].id = CORBA::string_dup(PortableGroup::role_criterion); + info.the_criteria[0].val <<= CORBA::string_dup(roleName); + + ACE_ERROR (( LM_INFO, + "Factory: %s@%s registering with factory registry\n", + roleName, + location_ + )); + + this->factory_registry_->register_factory( + roleName, + FT_TEST::_tc_TestReplica->id(), + info + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + } + this->registered_ = 1; + } + + int identified = 0; // bool + + if (this->roles_.size() > 0) + { + this->identity_ = "Factory"; + if (this->location_ != 0) + { + this->identity_ += "@"; + this->identity_ += this->location_; + } + identified = 1; + } + + if (this->ior_output_file_ != 0) + { + if (!identified) + { + this->identity_ = "file:"; + this->identity_ += this->ior_output_file_; + // note: don't set identified--ns identity overrides file identitiy + } + result = write_ior (this->ior_output_file_, this->ior_); + } + else + { + if (this->registered_) + { + // if we didn't register with a FactoryRegistry + // and no IOR file specified, + // then always try to register with name service + this->ns_name_ = "FT_ReplicaFactory"; + } + } + + if (this->ns_name_ != 0) + { + if (!identified) + { + this->identity_ = "name:"; + this->identity_ += this->ns_name_; + } + + CORBA::Object_var naming_obj = + this->orb_->resolve_initial_references ("NameService" ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + if (CORBA::is_nil(naming_obj.in ())){ + ACE_ERROR_RETURN ((LM_ERROR, + "%T %n (%P|%t) Unable to find the Naming Service\n"), + 1); + } + + this->naming_context_ = + CosNaming::NamingContext::_narrow (naming_obj.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + this->this_name_.length (1); + this->this_name_[0].id = CORBA::string_dup (this->ns_name_); + + this->naming_context_->rebind (this->this_name_, this_obj.in() // CORBA::Object::_duplicate(this_obj) + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + } + + // if we're testing. Create a replica at startup time + if (this->test_output_file_ != 0) + { + // shouldn't be necessary, but create_replica assumes this + InternalGuard guard (this->internals_); + FT_TestReplica_i * replica = create_replica ("test"); + + PortableServer::POA_var poa = replica->_default_POA (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + ::CORBA::Object_var replica_obj = poa->servant_to_reference(replica ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + ::CORBA::String_var replicaIOR = this->orb_->object_to_string(replica_obj.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + write_ior (this->test_output_file_, replicaIOR); + } + + return result; +} + +int FT_ReplicaFactory_i::fini (ACE_ENV_SINGLE_ARG_DECL) +{ + if (this->ior_output_file_ != 0) + { + ACE_OS::unlink (this->ior_output_file_); + this->ior_output_file_ = 0; + } + if (this->ns_name_ != 0) + { + this->naming_context_->unbind (this_name_ + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + this->ns_name_ = 0; + } + + if (registered_) + { + registered_ = 0; + + if (this->unregister_by_location_) + { + ACE_ERROR (( LM_INFO, + "%s: unregistering all factories at %s\n", + identity(), + location_ + )); + + PortableGroup::Location location(1); + location.length(1); + location[0].id = CORBA::string_dup(location_); + this->factory_registry_->unregister_factory_by_location ( + location + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + } + else + { + size_t roleCount = roles_.size(); + for (size_t nRole = 0; nRole < roleCount; ++nRole) + { + const char * roleName = this->roles_[nRole].c_str(); + ACE_ERROR (( LM_INFO, + "Factory for: %s@%s unregistering from factory registry\n", + roleName, + location_ + )); + + PortableGroup::Location location(1); + location.length(1); + location[0].id = CORBA::string_dup(location_); + this->factory_registry_->unregister_factory ( + roleName, + location + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + } + } + } + + return 0; +} + + +void FT_ReplicaFactory_i::remove_replica(CORBA::ULong id, FT_TestReplica_i * replica) +{ + InternalGuard guard (this->internals_); + if (id < this->replicas_.size()) + { + if(this->replicas_[id] == replica) + { + replica->fini(); + delete replica; + this->replicas_[id] = 0; + this->empty_slots_ += 1; + } + else + { + ACE_ERROR (( LM_ERROR, + "Remove replica %d mismatch.\n", + ACE_static_cast(int, id) + )); + } + } + else + { + ACE_ERROR (( LM_ERROR, + "Attempt to remove invalid replica %d. Limit %d.\n", + ACE_static_cast(int, id), + ACE_static_cast(int, this->replicas_.size()) + )); + } +} + +////////////////////////////////////////// +// FT_ReplicaFactory_i CORBA methods + +CORBA::Object_ptr FT_ReplicaFactory_i::create_object ( + const char * type_id, + const PortableGroup::Criteria & the_criteria, + PortableGroup::GenericFactory::FactoryCreationId_out factory_creation_id + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException + , PortableGroup::NoFactory + , PortableGroup::ObjectNotCreated + , PortableGroup::InvalidCriteria + , PortableGroup::InvalidProperty + , PortableGroup::CannotMeetCriteria + )) +{ + METHOD_ENTRY(FT_ReplicaFactory_i::create_object); + ACE_UNUSED_ARG (type_id); + InternalGuard guard (this->internals_); + + ::TAO::PG_Property_Set decoder (the_criteria); + + // boolean, becomes true if a required parameter is missing + int missingParameter = 0; + const char * missingParameterName = 0; + + CORBA::Long initialValue = 0; + if (! ::TAO::find (decoder, criterion_initial_value, initialValue) ) + { + // not required. Otherwise: + // missingParameter = 1; + // missingParameterName = criterion_initial_value; + } + + const char * role = "replica"; + if (! ::TAO::find (decoder, PortableGroup::role_criterion, role) ) + { + ACE_ERROR((LM_INFO, + "Property \"%s\" not found?\n", PortableGroup::role_criterion + )); + // not required. Otherwise: + // missingParameter = 1; + // missingParameterName = PortableGroup::role_criterion; + } + + if (missingParameter) + { + ACE_ERROR ((LM_ERROR, + "Throwing 'InvalidCriteria' due to missing %s\n", + missingParameterName + )); + ACE_THROW ( PortableGroup::InvalidCriteria() ); + } + + FT_TestReplica_i * replica = create_replica(role); + if (replica == 0) + { + ACE_ERROR ((LM_ERROR, + "New Replica_i returned NULL. Throwing ObjectNotCreated.\n" + )); + ACE_THROW ( PortableGroup::ObjectNotCreated() ); + } + + ACE_NEW_THROW_EX ( factory_creation_id, + PortableGroup::GenericFactory::FactoryCreationId, + PortableGroup::ObjectNotCreated()); + CORBA::ULong factory_id = replica->factory_id(); + (*factory_creation_id) <<= factory_id; + + ACE_ERROR ((LM_INFO, + "Created %s@%s#%d.\n", role, this->location_, ACE_static_cast(int, factory_id) + )); + + + ::CORBA::Object_ptr replica_obj = replica->_default_POA()->servant_to_reference(replica); + METHOD_RETURN(FT_ReplicaFactory_i::create_object) replica_obj->_duplicate(replica_obj ACE_ENV_ARG_PARAMETER); +} + +FT_TestReplica_i * FT_ReplicaFactory_i::create_replica(const char * name) +{ + // assume mutex is locked + CORBA::ULong factoryId = allocate_id(); + + FT_TestReplica_i * pFTReplica = 0; + + ACE_NEW_NORETURN(pFTReplica, FT_TestReplica_i( + this, + name, + factoryId + )); + + this->replicas_[factoryId] = pFTReplica; + this->empty_slots_ -= 1; + + pFTReplica->init (this->orb_ ACE_ENV_ARG_PARAMETER); + return pFTReplica; +} + +void FT_ReplicaFactory_i::delete_object ( + const PortableGroup::GenericFactory::FactoryCreationId & factory_creation_id + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException + , PortableGroup::ObjectNotFound + )) +{ + METHOD_ENTRY(FT_ReplicaFactory_i::delete_object); + + InternalGuard guard (this->internals_); + + CORBA::ULong factoryId; + factory_creation_id >>= factoryId; + if (factoryId < this->replicas_.size()) + { + if(this->replicas_[factoryId] != 0) + { + this->replicas_[factoryId]->request_quit(); + } + else + { + ACE_THROW(::PortableGroup::ObjectNotFound()); + } + } + else + { + ACE_THROW(::PortableGroup::ObjectNotFound()); + } + METHOD_RETURN(FT_ReplicaFactory_i::delete_object); +} + +CORBA::Boolean FT_ReplicaFactory_i::is_alive (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + METHOD_RETURN(FT_ReplicaFactory_i::is_alive) + 1; +} + +void FT_ReplicaFactory_i::shutdown (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC (( + CORBA::SystemException + )) +{ + METHOD_ENTRY(FT_FaultDetectorFactory_i::shutdown); + InternalGuard guard (this->internals_); + shutdown_i (); + this->quit_requested_ = 1; + METHOD_RETURN(FT_FaultDetectorFactory_i::shutdown); +} + + +/////////////////////////////////// +// Template instantiation for +// competence-challenged compilers. + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) + template class ACE_Vector<FT_TestReplica_i *>; + template class ACE_Guard<ACE_Mutex>; + template class ACE_Vector<ACE_CString>; +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +# pragma instantiate ACE_Vector<FT_TestReplica_i *> +# pragma instantiate ACE_Guard<ACE_Mutex> +# pragma instantiate ACE_Vector<ACE_CString> +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/orbsvcs/tests/FT_App/FT_ReplicaFactory_i.h b/TAO/orbsvcs/tests/FT_App/FT_ReplicaFactory_i.h new file mode 100644 index 00000000000..b22d82204e9 --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/FT_ReplicaFactory_i.h @@ -0,0 +1,293 @@ +/* -*- C++ -*- */ +//============================================================================= +/** + * @file FT_ReplicaFactory_i.h + * + * $Id$ + * + * This file is part of Fault Tolerant CORBA. + * It declares the implementation of ReplicaFactory which + * creates and manages replicas as an agent for + * the ReplicationManager as defined in the FT CORBA specification. + * + * @author Dale Wilson <wilson_d@ociweb.com> + */ +//============================================================================= + +#ifndef FT_REPLICAFACTORY_H_ +#define FT_REPLICAFACTORY_H_ +#include <ace/ACE.h> +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +////////////////////////////////// +// Classes declared in this header +class FT_ReplicaFactory_i; + +///////////////////////////////// +// Includes needed by this header +#include <ace/Vector_T.h> +#include "FT_TestReplicaS.h" +#include <ace/Thread_Manager.h> +#include <orbsvcs/FT_ReplicationManagerC.h> + +///////////////////// +// Forward references +class TAO_ORB_Manager; +class FT_TestReplica_i; + +/** + * Implement the GenericFactory interface. + */ +class FT_ReplicaFactory_i +//FT_TEST::ReplicaFactory + : public virtual POA_PortableGroup::GenericFactory +{ + typedef ACE_Vector<FT_TestReplica_i *> ReplicaVec; + typedef ACE_Vector<ACE_CString> StringVec; + + ////////////////////// + // non-CORBA interface +public: + /** + * Default constructor. + */ + FT_ReplicaFactory_i (); + + /** + * Virtual destructor. + */ + virtual ~FT_ReplicaFactory_i (); + + /** + * 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 orb our ORB -- we keep var to it. + * @return zero for success; nonzero is process return code for failure. + */ + int init (CORBA::ORB_ptr orb ACE_ENV_ARG_DECL); + + /** + * Prepare to exit. + * @return zero for success; nonzero is process return code for failure. + */ + int fini (ACE_ENV_SINGLE_ARG_DECL); + + int idle(int & result); + + + /** + * Identify this replica factory. + * @return a string to identify this object for logging/console message purposes. + */ + const char * identity () const; + + const char * location () const; + + /** + * Remove pointer to individual replica; delete FT_TestReplica_i. + * See replica life cycle description. + * @param id the numerical id assigned to this replica. + * @param replica a pointer to the Replica object (redundant for safety.) + */ + void remove_replica (CORBA::ULong id, FT_TestReplica_i * replica); + + ////////////////// + // CORBA interface + // See IDL for documentation + + virtual void shutdown (ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC (( + CORBA::SystemException + )); + + ///////////////////////////////////////// + // CORBA interface GenericFactory methods + virtual CORBA::Object_ptr create_object ( + const char * type_id, + const PortableGroup::Criteria & the_criteria, + PortableGroup::GenericFactory::FactoryCreationId_out factory_creation_id + ACE_ENV_ARG_DECL_WITH_DEFAULTS + ) + ACE_THROW_SPEC (( + CORBA::SystemException + , PortableGroup::NoFactory + , PortableGroup::ObjectNotCreated + , PortableGroup::InvalidCriteria + , PortableGroup::InvalidProperty + , PortableGroup::CannotMeetCriteria + )); + + virtual void delete_object ( + const PortableGroup::GenericFactory::FactoryCreationId & factory_creation_id + ACE_ENV_ARG_DECL_WITH_DEFAULTS + ) + ACE_THROW_SPEC (( + CORBA::SystemException + , PortableGroup::ObjectNotFound + )); + + ////////////////////////////////////////// + // CORBA interface PullMonitorable methods + + virtual CORBA::Boolean is_alive (ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + + ///////////////////////// + // Implementation methods +private: + /** + * Actual replica creation happens in this method. + * @param name becomes part of the objects identity. + */ + FT_TestReplica_i * create_replica(const char * name); + + /** + * Find or allocate an ID for a new replica + */ + CORBA::ULong allocate_id(); + + /** + * Write this factory's IOR to a file + */ + int write_ior (const char * outputFile, const char * ior); + + /** + * Clean house for factory shut down. + */ + void shutdown_i (); + + /////////////// + // Data Members +private: + + /** + * 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_SYNCH_MUTEX internals_; + typedef ACE_Guard<ACE_SYNCH_MUTEX> InternalGuard; + + /** + * The orb + */ + CORBA::ORB_var orb_; + + /** + * The POA used to activate this object. + */ + PortableServer::POA_var poa_; + + /** + * The CORBA object id assigned to this object. + */ + PortableServer::ObjectId_var object_id_; + + /** + * 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 * ior_output_file_; + + /** + * A human-readable string to distinguish this from other Notifiers. + */ + ACE_CString identity_; + + /** + * bool: true if we found a replication manager + */ + int have_replication_manager_; + + /** + * The replication manager + */ + + ::FT::ReplicationManager_var replication_manager_; + + + /** + * The factory registry IOR + */ + const char * factory_registry_ior_; + + /** + * The factory registry with which to register. + */ + PortableGroup::FactoryRegistry_var factory_registry_; + + /** + * true if registered with FactoryRegistry + */ + int registered_; // bool + + /** + * A file to which the test replica's IOR will be written + */ + const char * test_output_file_; + + /** + * A name to be used to register the factory with the name service. + */ + const char * ns_name_; + + CosNaming::NamingContext_var naming_context_; + + CosNaming::Name this_name_; + + ///////////////// + // The roles used to register types + StringVec roles_; + + /** + * the PortableGroup::Location within the domain + */ + const char * location_; + + /** + * bool: quit on idle flag. + */ + int quit_on_idle_; + + /** + * bool: use a single call to unregister. + */ + int unregister_by_location_; + + /** + * A vector of Replicas. Note that the Replica ID + * is an index into this vector. + */ + ReplicaVec replicas_; + + /** + * count of entries in Replicas_ that have been deleted. + * Used to determine when the factory is idle and to avoid futile + * searches for empty slots. + */ + size_t empty_slots_; + + /** + * boolean: starts false. Set to true when it's time to quit. + */ + int quit_requested_; + +}; + +#endif /* FT_REPLICAFACTORY_H_ */ diff --git a/TAO/orbsvcs/tests/FT_App/FT_ReplicationManagerController.cpp b/TAO/orbsvcs/tests/FT_App/FT_ReplicationManagerController.cpp new file mode 100755 index 00000000000..96c660e4a7e --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/FT_ReplicationManagerController.cpp @@ -0,0 +1,197 @@ +// $Id$ + +#include "orbsvcs/FT_ReplicationManagerC.h" +#include <ace/Get_Opt.h> +#include <iostream> + +// A simple class for building a client that "controls' the +// Replication Manager (right now it just shuts it down). +class TAO_FT_ReplicationManagerController +{ +///////////////////////////// +// Public interface. +public: + TAO_FT_ReplicationManagerController (); + virtual ~TAO_FT_ReplicationManagerController (); + + int init (int & argc, char * argv[]); + int parse_args (int & argc, char* argv[]); + int run (); + +///////////////////////////// +// Forbidden. +private: + TAO_FT_ReplicationManagerController ( + const TAO_FT_ReplicationManagerController & rhs); + TAO_FT_ReplicationManagerController & operator = ( + const TAO_FT_ReplicationManagerController & rhs); + +///////////////////////////// +// Private implementation. +private: + void usage (ostream & out) const; + +///////////////////////////// +// Data members. +private: + CORBA::ORB_var orb_; + FT::ReplicationManager_var replication_manager_; + const char * rm_ior_; + int shutdown_; + +}; + +TAO_FT_ReplicationManagerController::TAO_FT_ReplicationManagerController () + : orb_ (CORBA::ORB::_nil()) + , replication_manager_ (FT::ReplicationManager::_nil()) + , rm_ior_ (0) + , shutdown_ (0) +{ +} + +TAO_FT_ReplicationManagerController::~TAO_FT_ReplicationManagerController () +{ +} + +int TAO_FT_ReplicationManagerController::init (int & argc, char * argv[]) +{ + int result = 0; + + ACE_TRY_NEW_ENV + { + // Initialize the ORB. + this->orb_ = CORBA::ORB_init (argc, argv, "" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Parse arguments. + result = this->parse_args (argc, argv); + if (result == 0) + { + CORBA::Object_var obj = CORBA::Object::_nil (); + if (this->rm_ior_ != 0) + { + obj = this->orb_->string_to_object ( + this->rm_ior_ ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + } + else + { + obj = this->orb_->resolve_initial_references ( + "ReplicationManager" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + } + this->replication_manager_ = FT::ReplicationManager::_narrow ( + obj.in() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + if (CORBA::is_nil (this->replication_manager_.in())) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ( + "TAO_FT_ReplicationManagerController::init: " + "Could not get Replication Manager's IOR.\n") + )); + result = -1; + } + } + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION ( + ACE_ANY_EXCEPTION, + ACE_TEXT ( + "TAO_FT_ReplicationManagerController::init: \n") + ); + result = -1; + } + ACE_ENDTRY; + + return result; +} + + +int TAO_FT_ReplicationManagerController::parse_args (int & argc, char * argv[]) +{ + int result = 0; + + ACE_Get_Opt get_opts (argc, argv, "k:x"); + int c; + + while (result == 0 && (c = get_opts ()) != -1) + { + switch (c) + { + case 'k': + { + this->rm_ior_ = get_opts.opt_arg (); + break; + } + + case 'x': + { + this->shutdown_ = 1; + break; + } + + default: + std::cerr << argv[0] << ": Unknown argument -" << (char) c << std::endl; + this->usage(std::cerr); + result = -1; + break; + + case '?': + this->usage(std::cerr); + result = -1; + } + } + + return result; +} + +void TAO_FT_ReplicationManagerController::usage (ostream & out) const +{ + out << "usage" + << " -k <replication manager ior file>" + << " -x (shutdown the Replication Manager)" + << std::endl; +} + +int TAO_FT_ReplicationManagerController::run () +{ + int result = 0; + + ACE_TRY_NEW_ENV + { + if (this->shutdown_ == 1) + { + this->replication_manager_->shutdown (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + ACE_Time_Value tv (0, 500000); + ACE_OS::sleep (tv); + } + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION ( + ACE_ANY_EXCEPTION, + ACE_TEXT ( + "TAO_FT_ReplicationManagerController::run: \n") + ); + result = -1; + } + ACE_ENDTRY; + + return result; +} + +int main (int argc, char * argv[]) +{ + int result = 0; + TAO_FT_ReplicationManagerController rmctrl; + result = rmctrl.init (argc, argv); + if (result == 0) + { + result = rmctrl.run (); + } + return result; +} + diff --git a/TAO/orbsvcs/tests/FT_App/FT_TestReplica.idl b/TAO/orbsvcs/tests/FT_App/FT_TestReplica.idl new file mode 100644 index 00000000000..b9d41ed7429 --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/FT_TestReplica.idl @@ -0,0 +1,117 @@ +/* -*- IDL -*- */ +//============================================================================= +/** + * @file FT_TestReplica.idl + * + * $Id$ + * + * This file defines an interface used to test Fault Tolerant CORBA. + * + * @author Dale Wilson <wilson_d@ociweb.com> + */ +//============================================================================= +// +#ifndef FT_TESTREPLICA_IDL +#define FT_TESTREPLICA_IDL + +#include "orbsvcs/FT_Replica.idl" + +module FT_TEST +{ + /** + * A FT_TEST::Replica provides a test target for a FT::FaultDetector + * It is Updateable (and therefore Checkpointable) + * and PullMonitorable + * It declares a simple counter that can be set, incremented, and read + * via method calls. The counter is also exposed as a property. + */ + interface TestReplica : ::FT::Updateable, ::FT::PullMonitorable, ::PortableGroup::TAO_UpdateObjectGroup + { + /** + * set the counter to an specific value. + * @param value is the number to be set. + */ + void set(in long value); + + /** + * add delta to the counter. + * @param delta is the number to be added: (delta may be positive, negative or zero). + * @returns the new value of the counter. + */ + long increment(in long delta); + + /** + * retrieve the current counter. + * @returns the value of the counter. + */ + long get(); + + + /** + * enumerate the points at which + * the test replica might be convinced to die. + */ + enum Bane + { + NOT_YET, // normal state, also used to revoke a previous request + RIGHT_NOW, // fault immediately during the die() call + WHILE_IDLE, // fault while not processing a request + // FT_TestReplica interface: + BEFORE_STATE_CHANGE, // after receiving request + BEFORE_REPLICATION, // after state change + BEFORE_REPLY, // after state replication + // FT::PullMonitorable interface: + DURING_IS_ALIVE, + DENY_IS_ALIVE, + // FT::Updatable interface: + DURING_GET_UPDATE, + BEFORE_SET_UPDATE, + AFTER_SET_UPDATE, + // FT::Checkpointable interface: + DURING_GET_STATE, + BEFORE_SET_STATE, + AFTER_SET_STATE, + // Reserved + CLEAN_EXIT // reserved for use by shutdown + }; + + + /** + * die a horrid death. + * @param when is an arbitrary code to indicate how and when to die. + */ + void die(in Bane when); + + + /** + * die a clean death. + */ + oneway void shutdown(); + + /** + * provide direct access to the counter. + * Suports the same functionality as set and get. + * Can you say "Encapsulization???" this is a test, remember. + */ + attribute long counter; + }; + + interface ReplicaFactory : ::PortableGroup::GenericFactory, ::FT::PullMonitorable + { + /** + * die a clean death. + */ + oneway void shutdown(); + }; + + /////////////////////// + // roles for unit tests + // A TestReplica can act as a... + +// typedef TestReplica Hobbit; +// typedef TestReplica Elf; +// typedef TestReplica Human; + +}; + +#endif // for #ifndef FT_TESTREPLICA_IDL diff --git a/TAO/orbsvcs/tests/FT_App/FT_TestReplica_i.cpp b/TAO/orbsvcs/tests/FT_App/FT_TestReplica_i.cpp new file mode 100644 index 00000000000..89b2b5c1aa2 --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/FT_TestReplica_i.cpp @@ -0,0 +1,468 @@ +// $Id$ +/* -*- C++ -*- */ +//============================================================================= +/** + * @file FT_TestReplica_i.cpp + * + * $Id$ + * + * Implements CORBA interface TestReplica. + * + * @author Dale Wilson <wilson_d@ociweb.com> + */ +//============================================================================= +// + +#include "FT_TestReplica_i.h" +#include "FT_ReplicaFactory_i.h" +#include <tao/PortableServer/ORB_Manager.h> +#include <iostream> +#include "FT_TestReplicaC.h" + +////////////////// +// TestReplica_i + +namespace +{ + /** + * Endian neutral store of long into indexable object. + * BUFFER can be sequence of Octet, unsigned char[], etc. + * + * TODO: Find this a good home. + * + * @param state an object that supports char & operator[] (size_t index); + * @param offset is the position within state where the first character should be stored. + * @param value is the data to be inserted into state. + */ + template<typename BUFFER> + void storeLong(BUFFER & state, size_t offset, long value) + { + state[offset ] = ACE_static_cast (unsigned char, value >> 24); + state[offset + 1] = ACE_static_cast (unsigned char, value >> 16); + state[offset + 2] = ACE_static_cast (unsigned char, value >> 8); + state[offset + 3] = ACE_static_cast (unsigned char, value ); + } + + /** + * Endian neutral load of long from indexable object. + * BUFFER can be sequence of Octet, unsigned char[], etc. + * + * TODO: Find this a good home. + * + * @param state an object that supports const char & operator[] (size_t index) const; + * @param offset is the position within state where the first character can be found + * @returns value is the data loaded from state. + */ + template<typename BUFFER> + long loadLong(const BUFFER & state, size_t offset) + { + long result + = ((state[offset ] & 0xFF) << 24) + | ((state[offset + 1] & 0xFF) << 16) + | ((state[offset + 2] & 0xFF) << 8) + | ((state[offset + 3] & 0xFF) ); + return result; + } +} + +// NO_RESPONSE ->no reinvocation + +#define FAULT_CODE CORBA::TRANSIENT + +// Macros to simplify suicide. +#define KEVORKIAN(value, method) \ + if (this->death_pending_ == (FT_TEST::TestReplica::value)){ \ + suicide (#value " in method " #method); \ + ACE_THROW (FAULT_CODE ( \ + CORBA::SystemException::_tao_minor_code ( \ + TAO_DEFAULT_MINOR_CODE, \ + EFAULT), \ + CORBA::COMPLETED_NO)); \ + } else ; + +#define KEVORKIAN_DURING(method) \ + if (this->death_pending_ == FT_TEST::TestReplica::BEFORE_REPLY ){\ + suicide ("read-only method " #method); \ + ACE_THROW (FAULT_CODE ( \ + CORBA::SystemException::_tao_minor_code ( \ + TAO_DEFAULT_MINOR_CODE, \ + EFAULT), \ + CORBA::COMPLETED_NO)); \ + } else ; + + +////////////////////////////////////////////////// +// class FT_TestReplica_i construction/destruction + +FT_TestReplica_i::FT_TestReplica_i (FT_ReplicaFactory_i * factory, const char * name, unsigned long factory_id) + : death_pending_ (FT_TEST::TestReplica::NOT_YET) + , verbose_ (1) + , name_ (name) + , factory_id_ (factory_id) + , factory_ (factory) + , orb_ (0) + , poa_ (0) + , object_id_ (0) +{ +// std::cout << name_.c_str() << '@' << this->factory_->location() << '#' << this->factory_id_ << " Construct" << std::endl; +} + +FT_TestReplica_i::~FT_TestReplica_i () +{ +// std::cout << name_.c_str() << '@' << this->factory_->location() << '#' << this->factory_id_ << " Destruct" << std::endl; +} + + +void FT_TestReplica_i::suicide(const char * note) +{ + std::cout << name_.c_str() << '@' << this->factory_->location() << '#' << this->factory_id_ << " Simulate FAULT_CODE fault: " << note << std::endl; + + // Tell the poa we aren't accepting future calls + this->poa_->deactivate_object (this->object_id_.in () + ACE_ENV_ARG_PARAMETER); +} + +///////////////////////////////////////////////////// +// class FT_TestReplica_i public, non-CORBA interface + + + +//static +const char * FT_TestReplica_i::repository_id() +{ + return FT_TEST::_tc_TestReplica->id(); +} + +int +FT_TestReplica_i::parse_args (int argc, char *argv[]) +{ + ACE_UNUSED_ARG (argc); + ACE_UNUSED_ARG (argv); + return 0; +} + +//static +const char * +FT_TestReplica_i::usage_options() +{ + return ""; +} + +unsigned long FT_TestReplica_i::factory_id()const +{ + return this->factory_id_; +} + +::PortableServer::POA_ptr FT_TestReplica_i::_default_POA (ACE_ENV_SINGLE_ARG_DECL) +{ + return ::PortableServer::POA::_duplicate(this->poa_.in () ACE_ENV_ARG_PARAMETER); +} + +PortableServer::ObjectId FT_TestReplica_i::object_id()const +{ + return this->object_id_.in(); +} + + +/** + * Initialize this object. + * @param orbManager our ORB -- we keep var to it. + * @return zero for success; nonzero is process return code for failure. + */ +int FT_TestReplica_i::init (CORBA::ORB_var & orb ACE_ENV_ARG_DECL) +{ + this->orb_ = orb; + + // Use the ROOT POA for now + CORBA::Object_var poa_object = + this->orb_->resolve_initial_references (TAO_OBJID_ROOTPOA + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + if (CORBA::is_nil (poa_object.in ())) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT (" (%P|%t) Unable to initialize the POA.\n")), + -1); + + // Get the POA object. + this->poa_ = + PortableServer::POA::_narrow (poa_object.in () + ACE_ENV_ARG_PARAMETER); + + ACE_CHECK_RETURN (-1); + + if (CORBA::is_nil(this->poa_.in ())) + { + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT (" (%P|%t) Unable to narrow the POA.\n")), + -1); + } + + PortableServer::POAManager_var poa_manager = + this->poa_->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + + // Register with the POA. + + this->object_id_ = this->poa_->activate_object (this ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + return 0; +} + +void FT_TestReplica_i::_remove_ref (ACE_ENV_SINGLE_ARG_DECL) +{ + ////////////////////////////////////////////////// + // WARNING: The following call invokes fini then deletes this object + this->factory_->remove_replica(this->factory_id_, this); +} + +int FT_TestReplica_i::fini (ACE_ENV_SINGLE_ARG_DECL) +{ + return 0; +} + + + +///////////////////////////////////////////////////// +// class FT_TestReplica_i: PullMonitorable interface +CORBA::Boolean FT_TestReplica_i::is_alive () + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + KEVORKIAN(DURING_IS_ALIVE, is_alive) + ACE_ERROR ((LM_ERROR, + "%s@%s#%d: is_alive: %d\n", + this->name_.c_str(), + this->factory_->location(), + this->factory_id_, + (this->death_pending_ != FT_TEST::TestReplica::DENY_IS_ALIVE) + )); + + return this->death_pending_ != FT_TEST::TestReplica::DENY_IS_ALIVE; +} + +///////////////////////////////////////////////////// +// class FT_TestReplica_i: Updateable interface +FT::State * FT_TestReplica_i::get_update () + ACE_THROW_SPEC ((CORBA::SystemException, FT::NoUpdateAvailable)) +{ + KEVORKIAN(DURING_GET_UPDATE, get_update) + long counter = load(); + ::FT::State_var vState = new ::FT::State; + vState->length(sizeof(counter)); + storeLong(vState, 0, counter); + return vState._retn(); +} + +void FT_TestReplica_i::set_update (const FT::State & s) + ACE_THROW_SPEC ((CORBA::SystemException, FT::InvalidUpdate)) +{ +#if defined(FT_TEST_LACKS_UPDATE) + ACE_THROW ( FT::InvalidUpdate () ); +#else // FT_TEST_LACKS_UPDATE + KEVORKIAN(BEFORE_SET_UPDATE, set_update) + long counter = loadLong<FT::State>(s, 0); + store(counter); + KEVORKIAN(AFTER_SET_UPDATE, set_update) +#endif // FT_TEST_LACKS_UPDATE +} + +///////////////////////////////////////////////////// +// class FT_TestReplica_i: Checkpointable interface +::FT::State * FT_TestReplica_i::get_state () + ACE_THROW_SPEC ((CORBA::SystemException, FT::NoStateAvailable)) +{ +#if defined(FT_TEST_LACKS_STATE) + ACE_THROW( FT::NoStateAvailable () ); +#else // FT_TEST_LACKS_STATE + KEVORKIAN(DURING_GET_STATE, get_state) + long counter = load(); + ::FT::State_var vState = new ::FT::State; + vState->length(sizeof(counter)); + storeLong(vState, 0, counter); + return vState._retn(); +#endif // FT_TEST_LACKS_STATE +} + +void FT_TestReplica_i::set_state (const FT::State & s) + ACE_THROW_SPEC ((CORBA::SystemException, FT::InvalidState)) +{ +#if defined(FT_TEST_LACKS_STATE) + ACE_THROW ( FT::InvalidState () ); +#else // FT_TEST_LACKS_STATE + KEVORKIAN(BEFORE_SET_STATE, set_state) + long counter = loadLong<FT::State>(s, 0); + store(counter); + KEVORKIAN(AFTER_SET_STATE, set_state) +#endif // FT_TEST_LACKS_STATE +} + +void FT_TestReplica_i::tao_update_object_group ( + const char * iogr, + PortableGroup::ObjectGroupRefVersion version, + CORBA::Boolean is_primary + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + ACE_UNUSED_ARG (iogr); + ACE_UNUSED_ARG (version); + ACE_UNUSED_ARG (is_primary); + + ACE_THROW (CORBA::NO_IMPLEMENT()); +} + +////////////////////////////// +// implement FT_TEST::Replica + +void FT_TestReplica_i::set (CORBA::Long value + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + KEVORKIAN(BEFORE_STATE_CHANGE, set) + long counter = value; + store(counter); + KEVORKIAN(BEFORE_REPLY, set) +} + +CORBA::Long FT_TestReplica_i::increment (CORBA::Long delta + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + KEVORKIAN(BEFORE_STATE_CHANGE, increment) + long counter = load (); + counter += delta; + store (counter); + KEVORKIAN(BEFORE_REPLY, increment) + return counter; +} + +CORBA::Long FT_TestReplica_i::get (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + KEVORKIAN_DURING(get) + long counter = load (); + return counter; +} + +CORBA::Long FT_TestReplica_i::counter (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + KEVORKIAN_DURING([get]counter) + long counter = load (); + return counter; +} + +void FT_TestReplica_i::counter (CORBA::Long counter + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + KEVORKIAN(BEFORE_STATE_CHANGE, [set]counter) + store (counter); + KEVORKIAN(BEFORE_REPLY, [set]counter) +} + +void FT_TestReplica_i::die (FT_TEST::TestReplica::Bane when + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + std::cout << name_.c_str() << '@' << this->factory_->location() << '#' << this->factory_id_ << " Received death threat: " << when << std::endl; + + this->death_pending_ = when; + KEVORKIAN(RIGHT_NOW, die) +} + +void FT_TestReplica_i::shutdown (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + std::cout << name_.c_str() << '@' << this->factory_->location() << '#' << this->factory_id_ << " Shut down requested" << std::endl; + this->death_pending_ = FT_TEST::TestReplica::CLEAN_EXIT; +} + +////////////////////////////////////////////// +// FT_TestReplica_i public non-CORBA interface +int FT_TestReplica_i::idle (int & result) +{ + int quit = 0; + if (this->death_pending_ == FT_TEST::TestReplica::WHILE_IDLE) + { + ACE_ERROR ((LM_ERROR, + "%s@%s#%d: Simulated fault WHILE_IDLE", + this->name_.c_str(), + this->factory_->location(), + ACE_static_cast(int, this->factory_id_ ) + )); + this->poa_->deactivate_object (this->object_id_.in () + ACE_ENV_ARG_PARAMETER); + result = 0; + quit = 1; + } + else if (this->death_pending_ == FT_TEST::TestReplica::CLEAN_EXIT) + { + this->poa_->deactivate_object (this->object_id_.in () + ACE_ENV_ARG_PARAMETER); + result = 0; + quit = 1; + } + return quit; +} + +void FT_TestReplica_i::request_quit() +{ + this->death_pending_ = FT_TEST::TestReplica::WHILE_IDLE; +} + + +void FT_TestReplica_i::store(long counter) +{ + FILE * f = ACE_OS::fopen("Persistent.dat", "w"); + if(f != 0) + { + unsigned char buffer[sizeof(long)]; + storeLong(buffer, 0, counter); + ACE_OS::fwrite(buffer, 1, sizeof(long), f); + ACE_OS::fclose(f); + if (this->verbose_) + { + std::cout << name_.c_str() << '@' << this->factory_->location() << '#' << this->factory_id_ << ": " << counter << std::endl; + } + } +} + +long FT_TestReplica_i::load () +{ + long counter = 0; + FILE * f = ACE_OS::fopen("Persistent.dat","r"); + if(f != 0) + { + unsigned char buffer[sizeof(long)]; + ACE_OS::fread(buffer, 1, sizeof(long), f); + ACE_OS::fclose(f); + counter = loadLong<unsigned char *>(buffer, 0); + } + return counter; +} + +/////////////////////////////////// +// Template instantiation for +// competence-challenged compilers. + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) + template void storeLong <> (::FT::State_var & state, size_t offset, long value); + template long loadLong <> (const ::FT::State_var & state, size_t offset); + + template void storeLong <> (unsigned char * & state, size_t offset, long value); + template long loadLong <> (const unsigned char * & state, size_t offset); + +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +# pragma instantiate void storeLong(::FT::State_var & state, size_t offset, long value) +# pragma long loadLong(const ::FT::State_var & state, size_t offset) + +# pragma instantiate void storeLong(unsigned char * & state, size_t offset, long value) +# pragma long loadLong(const unsigned char * & state, size_t offset) + +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/orbsvcs/tests/FT_App/FT_TestReplica_i.h b/TAO/orbsvcs/tests/FT_App/FT_TestReplica_i.h new file mode 100644 index 00000000000..2bbc53064b1 --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/FT_TestReplica_i.h @@ -0,0 +1,217 @@ +/* -*- C++ -*- */ +//============================================================================= +/** + * @file FT_TestReplica_i.h + * + * $Id$ + * + * This file declares an implementation of CORBA interface TestReplica. + * + * @author Dale Wilson <wilson_d@ociweb.com> + */ +//============================================================================= +// +#ifndef FT_TESTREPLICA_I_H_ +#define FT_TESTREPLICA_I_H_ +#include /**/ <ace/pre.h> + +#include <ace/ACE.h> +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "FT_TestReplicaS.h" + +//////////////////// +// Forward Reference +class FT_ReplicaFactory_i; + +/** + * Implement the TestReplica IDL interface. + * + * Persistent storage simulated by storing the counter + * in Persistent.dat. + */ +class FT_TestReplica_i : public virtual POA_FT_TEST::TestReplica +{ +public: + FT_TestReplica_i (FT_ReplicaFactory_i * factory, const char * name, unsigned long factory_id); + virtual ~FT_TestReplica_i (); + + /** + * parse command line arguments. + * remove any that are recognized, adjusting argc accordingly. + * @param argc classic C argc + * @param argv classic C argv + * @return 0 if ok, otherwise process exit code. + */ + int parse_args (int argc, char *argv[]); + + /** + * provide information to appear in a "usage" display. + * caller will display: + * usage: [program] <usageMessage()> [other usage] + * @returns c-style string containing "bare" usage options. + */ + const char * usage_options(); + + /** + * 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 (CORBA::ORB_var & orb ACE_ENV_ARG_DECL); + + /** + * Prepare to exit. + * @return zero for success; nonzero is process return code for failure. + */ + int fini (ACE_ENV_SINGLE_ARG_DECL); + + /** + * idle time activity. + * @param result [out] status code to return from process + * @returns 0 to continue; nonzero to quit + */ + int idle(int &result); + + void request_quit(); + + unsigned long factory_id()const; + + static const char * repository_id(); + + ::FT_TEST::TestReplica_ptr object_reference(); + + PortableServer::ObjectId object_id()const; + + ////////////////////////////////////////// + // Override CORBA servant virtual methods + virtual PortableServer::POA_ptr _default_POA (ACE_ENV_SINGLE_ARG_DECL); + + virtual void FT_TestReplica_i::_remove_ref (ACE_ENV_SINGLE_ARG_DECL); + +private: + /////////////////////////// + // override Replica methods + virtual void set (CORBA::Long value + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC (( CORBA::SystemException)); + + virtual CORBA::Long increment (CORBA::Long delta + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual CORBA::Long get (ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual CORBA::Long counter (ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual void counter (CORBA::Long counter + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual void die (FT_TEST::TestReplica::Bane when + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual void shutdown (ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + + /////////////////////////// + // override PullMonitorable + + virtual CORBA::Boolean is_alive (ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + + /////////////////////////// + // override Updatable + + virtual ::FT::State * get_update () + ACE_THROW_SPEC ((CORBA::SystemException, FT::NoUpdateAvailable)); + + virtual void set_update (const FT::State & s) + ACE_THROW_SPEC ((CORBA::SystemException, FT::InvalidUpdate)); + + virtual ::FT::State * get_state () + ACE_THROW_SPEC ((CORBA::SystemException, FT::NoStateAvailable)); + + virtual void set_state (const FT::State & s) + ACE_THROW_SPEC ((CORBA::SystemException, FT::InvalidState)); + + //////////////// + // Implement TAO_UpdateObjectGroup + + virtual void tao_update_object_group ( + const char * iogr, + PortableGroup::ObjectGroupRefVersion version, + CORBA::Boolean is_primary + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC ((CORBA::SystemException)); + + ///////////////// + // implementation +private: + /** + * Load the persistent data. + * returns the data loaded. + */ + long load(); + /** + * Store the persistent data. + * @param the data to be stored. + */ + void store(long value); + + void suicide(const char *); + + /////////////// + // data members +private: + /** + * a bane code for when we should die. + */ + FT_TEST::TestReplica::Bane death_pending_; + + /** + * verbosity level, settable by client. + */ + int verbose_; + + /** + * who am I? + */ + ACE_CString name_; + + /** + * The ID number assigned by the factory + */ + unsigned long factory_id_; + + /** + * the factory that created thsi replica + */ + FT_ReplicaFactory_i * factory_; + + /** + * The orb + */ + CORBA::ORB_var orb_; + + /** + * The POA used to activate this object. + */ + PortableServer::POA_var poa_; + + /** + * The CORBA object id assigned to this object. + */ + PortableServer::ObjectId_var object_id_; + +}; + +#include /**/ "ace/post.h" + +#endif /* FT_TESTREPLICA_I_H_ */ diff --git a/TAO/orbsvcs/tests/FT_App/README b/TAO/orbsvcs/tests/FT_App/README new file mode 100644 index 00000000000..33b790044b6 --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/README @@ -0,0 +1,88 @@ +$Id$ + +This is a simple application intended to test Fault Tolerant Corba. + +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 +to counter()) + +In addition there is a method named die that lets the client request +a server "failure" at a variety of interesting times. See the "die" +command to find out when death can be scheduled. + +The client provides a command interface to operate on the server. +Tests may be run manually by typing commands, or may be automated by +reading the commands from a file. + +Commands consist of a single character followed by an optional number +(with no space between). For example: =10 sets the value of the counter +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.. + +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. + +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.") + +Unit Tests based on this application: + + run_test_basic.pl + tests ft_client and ft_replica, thereby answering the question, + "who will test the tester?". + + run_test_detector.pl + uses ft_client, ft_replica, and ft_notifier (a "stub" fault notifier) + to test the Fault_Detector (from orbsvcs) + + run_test_notifier.pl + uses ft_client, ft_replica, Fault_Detector and ft_analyzer (a "stub" fault analyzer) + to test the Fault_Notifier (from orbsvcs) + + run_test_fault_consumer.pl + uses ft_client, ft_replica, Fault_Detector, Fault_Notifier to test + ft_fault_consumer (the implementation of a fault consumer) + + run_test_registry.pl + uses ft_client, ft_replica, and ft_creator to test ft_registry + (i.e. to test the implementation of PortableServer::FactoryRegistry) + + run_test_rmregistry.pl + uses ft_client, ft_replica, and ft_creator to test the FactoryRegistery + implementation in the ReplicationManager. + + + run_test_rmnotifier.pl + uses ft_client, ft_replica, Fault_Detector to test the connection between + the Fault_Notifier and the ReplicationManager + + demo.pl + tests the entire FT system. + + +See the internal documentation of the .pl files for more details. diff --git a/TAO/orbsvcs/tests/FT_App/ReplicationManagerFaultConsumerAdapter.cpp b/TAO/orbsvcs/tests/FT_App/ReplicationManagerFaultConsumerAdapter.cpp new file mode 100755 index 00000000000..e8a4cf3c9a3 --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/ReplicationManagerFaultConsumerAdapter.cpp @@ -0,0 +1,383 @@ +// -*- C++ -*- +// +// $Id$ + +#include "ReplicationManagerFaultConsumerAdapter.h" +#include "ace/Get_Opt.h" +#include "orbsvcs/orbsvcs/PortableGroup/PG_Properties_Encoder.h" +#include "orbsvcs/FT_ReplicationManager/FT_DefaultFaultAnalyzer.h" +#include <iostream> +#include <fstream> + +ReplicationManagerFaultConsumerAdapter::ReplicationManagerFaultConsumerAdapter() + : orb_(CORBA::ORB::_nil()) + , quit_(0) + , readyFile_(0) + , detector_ior_(0) + , factory_(FT::FaultDetectorFactory::_nil()) + , notifier_ior_(0) + , notifier_(FT::FaultNotifier::_nil()) + , p_fault_consumer_(0) + , consumer_servant_(0) +{ +} + + +ReplicationManagerFaultConsumerAdapter::~ReplicationManagerFaultConsumerAdapter() +{ +} + +size_t ReplicationManagerFaultConsumerAdapter::notifications () const +{ + // Delegate to the FT_FaultConsumer. + return this->p_fault_consumer_->notifications (); +} + + +int ReplicationManagerFaultConsumerAdapter::parse_args (int argc, char * argv[]) +{ + int optionError = 0; + ACE_Get_Opt get_opts (argc, argv, "o:r:d:n:"); + int c; + while ((c = get_opts ()) != -1) + { + switch (c) + { + case 'r': + { + this->replica_iors_.push_back (get_opts.opt_arg ()); + break; + } + case 'd': + { + this->detector_ior_ = get_opts.opt_arg (); + break; + } + case 'n': + { + this->notifier_ior_ = get_opts.opt_arg (); + break; + } + case 'o': + { + this->readyFile_ = get_opts.opt_arg (); + break; + } + + default: + // fall thru + case '?': + { + break; + } + } + } + + if(! optionError) + { + if (0 == this->replica_iors_.size()) + { + ACE_ERROR ((LM_ERROR, + "-r option is required.\n" + )); + optionError = -1; + } + if (0 == this->detector_ior_) + { + ACE_ERROR ((LM_ERROR, + "-d option is required.\n" + )); + optionError = -1; + } + } + + if(optionError) + { + ACE_ERROR ((LM_ERROR, + "usage: %s" + " -r <replica.ior[ -r replica.ior]>" + " -d <detector.ior>" + " -o <this.ior>" + " -n <nameService name>" + "\n", + argv [0] + )); + } + return optionError; +} + +/** + * Register this object. + */ +int ReplicationManagerFaultConsumerAdapter::init ( + CORBA::ORB_ptr orb + ACE_ENV_ARG_DECL) +{ + ACE_DEBUG (( + LM_DEBUG, + ACE_TEXT ("Entered ReplicationManagerFaultConsumerAdapter::init.\n") + )); + + int result = 0; + this->orb_ = CORBA::ORB::_duplicate (orb); + + ////////////////////////////////////////// + // resolve reference to detector factory + ACE_DEBUG (( + LM_DEBUG, + ACE_TEXT ("ReplicationManagerFaultConsumerAdapter::init: ") + ACE_TEXT ("Getting ready to read iorDetectorFile.\n") + )); + + CORBA::Object_var detector_obj = this->orb_->string_to_object ( + this->detector_ior_ ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + this->factory_ = ::FT::FaultDetectorFactory::_narrow ( + detector_obj.in() ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + if (CORBA::is_nil (this->factory_.in())) + { + ACE_ERROR_RETURN (( + LM_ERROR, + ACE_TEXT ("ReplicationManagerFaultConsumerAdapter::init: ") + ACE_TEXT ("FaultDetectorFactory IOR is nil: %s\n"), + this->detector_ior_), + -1); + } + + ////////////////////////////////////////// + // resolve references to notifier + ACE_DEBUG (( + LM_DEBUG, + ACE_TEXT ("ReplicationManagerFaultConsumerAdapter::init: ") + ACE_TEXT ("Getting ready to read Notifier IOR file.\n") + )); + + CORBA::Object_var notifier_ior = this->orb_->string_to_object ( + this->notifier_ior_ ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + this->notifier_ = ::FT::FaultNotifier::_narrow ( + notifier_ior.in() ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + if (CORBA::is_nil (this->notifier_.in())) + { + ACE_ERROR_RETURN (( + LM_ERROR, + ACE_TEXT ("ReplicationManagerFaultConsumerAdapter::init: ") + ACE_TEXT ("FaultNotifier IOR is nil: %s\n"), + this->notifier_ior_), + -1); + } + + // Create the real FaultConsumer. + // + // Note: We have to hang onto the servant class pointer so we can + // invoke member functions on it, but we also give ownership of it + // to a PortableServer::ServantBase_var. + ACE_DEBUG (( + LM_DEBUG, + ACE_TEXT ("ReplicationManagerFaultConsumerAdapter::init: ") + ACE_TEXT ("Getting ready to create the real FaultConsumer.\n") + )); + + ACE_NEW_RETURN (this->p_fault_consumer_, TAO::FT_FaultConsumer (), -1); + if (this->p_fault_consumer_ != 0) + { + this->consumer_servant_ = this->p_fault_consumer_; + } + + ////////////////////////// + // Get ready to initialize the consumer. We need to provide it + // with the following: + // - The POA in which it is to be activated. + // - FT::FaultNotifier IOR. + // - FT::ReplicationManager IOR (fake it for now). + + // Get the RootPOA from the ORB. + CORBA::Object_var poa_obj = this->orb_->resolve_initial_references ( + "RootPOA" ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + PortableServer::POA_var poa = PortableServer::POA::_narrow ( + poa_obj.in() ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + // Create a fault analyzer. + TAO::FT_FaultAnalyzer * analyzer = 0; + ACE_NEW_RETURN (analyzer, TAO::FT_DefaultFaultAnalyzer (), -1); + + // Initialize the FaultConsumer. + // It will activate itself in the POA we pass it and connect to the + // Fault Notifier we pass it. + ACE_DEBUG (( + LM_DEBUG, + ACE_TEXT ("ReplicationManagerFaultConsumerAdapter::init: ") + ACE_TEXT ("Getting ready to initialize the real FaultConsumer.\n") + )); + + result = this->p_fault_consumer_->init ( + poa.in(), + this->notifier_.in(), + analyzer + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + if (result != 0) + { + ACE_ERROR_RETURN (( + LM_ERROR, + ACE_TEXT ("ReplicationManagerFaultConsumerAdapter::init: ") + ACE_TEXT ("Unable to initialize the real FaultConsumer.\n")), + result); + } + + this->identity_ = "ReplicationManagerFaultConsumerAdapter"; + + // Activate the RootPOA. + PortableServer::POAManager_var poa_manager = + poa->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + ///////////////////////// + // Set up fault detectors + if (result == 0) + { + //////////////////////////////////// + // resolve references to replicas + // create a fault detector for each replica + size_t replicaCount = this->replica_iors_.size(); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Number of replicas being monitored: (%u)\n"), + ACE_static_cast (unsigned int, replicaCount) + )); + for (size_t nRep = 0; result == 0 && nRep < replicaCount; ++nRep) + { + const char * iorName = this->replica_iors_[nRep]; + CORBA::Object_var replica_obj = this->orb_->string_to_object ( + iorName ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + FT::PullMonitorable_var replica = FT::PullMonitorable::_narrow ( + replica_obj.in() ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + if (CORBA::is_nil(replica.in())) + { + ACE_ERROR_RETURN (( + LM_ERROR, + ACE_TEXT ("ReplicationManagerFaultConsumerAdapter::init: ") + ACE_TEXT ("Can't resolve Replica IOR: %s\n"), + iorName), + -1); + } + else + { + this->replicas_.push_back(replica); + + CORBA::String_var type_id = CORBA::string_dup("FaultDetector"); + + TAO_PG::Properties_Encoder encoder; + + PortableGroup::Value value; + value <<= notifier_.in (); + encoder.add(::FT::FT_NOTIFIER, value); + + value <<= replica.in (); + encoder.add(::FT::FT_MONITORABLE, value); + + FT::FTDomainId domain_id = 0; + value <<= domain_id; + encoder.add(::FT::FT_DOMAIN_ID, value); + + PortableGroup::Location object_location; + object_location.length(2); + object_location[0].id = CORBA::string_dup("test"); + object_location[1].id = CORBA::string_dup("Location_A"); + value <<= object_location; + encoder.add(::FT::FT_LOCATION, value); + + PortableGroup::TypeId_var object_type = CORBA::string_dup ( + "IDL:org.omg/CosNaming/NamingContextExt:1.0"); + value <<= object_type; + encoder.add(::FT::FT_TYPE_ID, value); + + PortableGroup::ObjectGroupId group_id = + ACE_static_cast (PortableGroup::ObjectGroupId, 6191982); + value <<= group_id; + encoder.add(::FT::FT_GROUP_ID, value); + + // allocate and populate the criteria + PortableGroup::Criteria_var criteria; + ACE_NEW_NORETURN (criteria, + PortableGroup::Criteria); + if (criteria.ptr() == 0) + { + ACE_ERROR_RETURN (( + LM_ERROR, + ACE_TEXT ("ReplicationManagerFaultConsumerAdapter::init: ") + ACE_TEXT ("Error cannot allocate criteria.\n")), + -1); + } + else + { + encoder.encode(criteria); + PortableGroup::GenericFactory::FactoryCreationId_var factory_creation_id; + + this->factory_->create_object ( + type_id.in(), + criteria.in(), + factory_creation_id + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + } + } + } + + // Signal that we are ready to go. + if (result == 0 && this->readyFile_ != 0) + { + std::ofstream ready (this->readyFile_, ios::out); + ready << "ready" << std::endl; + ready.close(); + } + } + + return result; +} + +/** + * Return a string to identify this object for logging/console message purposes. + */ +const char * ReplicationManagerFaultConsumerAdapter::identity () const +{ + return this->identity_.c_str(); +} + +/** + * Clean house for process shut down. + */ +int ReplicationManagerFaultConsumerAdapter::fini (ACE_ENV_SINGLE_ARG_DECL) +{ + // Delegate to the FT_FaultConsumer. + return this->p_fault_consumer_->fini (ACE_ENV_SINGLE_ARG_PARAMETER); +} + + +int ReplicationManagerFaultConsumerAdapter::idle(int & result) +{ + ACE_UNUSED_ARG(result); + int quit = 0; + + if (this->replicas_.size() == this->p_fault_consumer_->notifications()) + { + quit = 1; + } + return quit; +} + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) + template class ACE_Vector < const char * >; + template class ACE_Vector < FT::PullMonitorable_var > ; +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +# pragma instantiate ACE_Vector < const char * > +# pragma instantiate ACE_Vector < FT::PullMonitorable_var > +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ + diff --git a/TAO/orbsvcs/tests/FT_App/ReplicationManagerFaultConsumerAdapter.h b/TAO/orbsvcs/tests/FT_App/ReplicationManagerFaultConsumerAdapter.h new file mode 100755 index 00000000000..f0301274ce0 --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/ReplicationManagerFaultConsumerAdapter.h @@ -0,0 +1,150 @@ +// -*- C++ -*- +// +// $Id$ +#ifndef REPLICATION_MANAGER_FAULT_CONSUMER_ADAPTER_H +#define REPLICATION_MANAGER_FAULT_CONSUMER_ADAPTER_H +#include /**/ <ace/pre.h> +#include <ace/ACE.h> +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include <orbsvcs/FT_ReplicationManager/FT_FaultConsumer.h> +#include <orbsvcs/FT_NotifierC.h> +#include <orbsvcs/FT_FaultDetectorFactoryC.h> +#include <ace/Vector_T.h> + +///////////////////// +// Class declarations + +/** + * An adapter to the Replication Manager's fault consumer + * for use in unit testing Fault Notifier and Fault Consumer. + */ +class ReplicationManagerFaultConsumerAdapter +{ +public: + /** + * Default constructor. + */ + ReplicationManagerFaultConsumerAdapter (); + + /** + * virtual destructor. + */ + virtual ~ReplicationManagerFaultConsumerAdapter (); + + /** + * Parse command line arguments. + */ + int parse_args (int argc, char * argv[]); + + /** + * Initialize this object + */ + int init (CORBA::ORB_ptr orb ACE_ENV_ARG_DECL_WITH_DEFAULTS); + + /** + * Return a string to identify this object for logging/console message purposes. + */ + const char * identity () const; + + /** + * idle time activity. + * @param result [out] status code to return from process + * @returns 0 to continue; nonzero to quit + */ + int idle(int &result); + + /** + * Clean house for process shut down. + */ + int fini (ACE_ENV_SINGLE_ARG_DECL); + + + size_t notifications() const; + + ///////////////// + // Implementation +private: + + //////////////////// + // Forbidden methods +private: + ReplicationManagerFaultConsumerAdapter ( + const ReplicationManagerFaultConsumerAdapter & rhs); + ReplicationManagerFaultConsumerAdapter & operator = + (const ReplicationManagerFaultConsumerAdapter & rhs); + + ///////////////////////// + // Implementation methods +private: + + /////////////// + // Data Members +private: + /** + * The orb + */ + CORBA::ORB_var orb_; + + /** + * A human-readable string to distinguish this from other FaultConsumers. + */ + ACE_CString identity_; + + /** + * boolean: request quit + */ + int quit_; + + /** + * a file to write to to signal "ready" + */ + const char * readyFile_; + + /** + * Detecor's IOR + */ + const char * detector_ior_; + + /** + * The FaultDetectorFactory object reference. + */ + ::FT::FaultDetectorFactory_var factory_; + + /** + * A collection of replica IORs + */ + ACE_Vector < const char * > replica_iors_; + + /** + * A collection of replica references. + */ + ACE_Vector < FT::PullMonitorable_var > replicas_; + + /** + * A file from which the notifier's IOR should be read. + */ + const char * notifier_ior_; + + /** + * the fault notifier + */ + ::FT::FaultNotifier_var notifier_; + + /** + * consumer id assigned by the notifier + */ + ::FT::FaultNotifier::ConsumerId consumerId_; + + /** + * the real fault consumer + */ + TAO::FT_FaultConsumer* p_fault_consumer_; + PortableServer::ServantBase_var consumer_servant_; + +}; +#include /**/ <ace/post.h> + +#endif /* REPLICATION_MANAGER_FAULT_CONSUMER_ADAPTER_H */ diff --git a/TAO/orbsvcs/tests/FT_App/StubBatchConsumer.cpp b/TAO/orbsvcs/tests/FT_App/StubBatchConsumer.cpp new file mode 100644 index 00000000000..ae54dfa1af3 --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/StubBatchConsumer.cpp @@ -0,0 +1,180 @@ +// -*- C++ -*- +// +// $Id$ + +#include "StubBatchConsumer.h" +#include <ace/Get_Opt.h> +#include <tao/PortableServer/ORB_Manager.h> +#include <orbsvcs/orbsvcs/PortableGroup/PG_Properties_Encoder.h> + +StubBatchConsumer::StubBatchConsumer () + : quit_(0) +{ +} + + +StubBatchConsumer::~StubBatchConsumer () +{ +} + + +int StubBatchConsumer::parse_args (int argc, char * argv[]) +{ + ACE_UNUSED_ARG (argc); + ACE_UNUSED_ARG (argv); + int optionError = 0; + // No options for now + return optionError; +} + + +::PortableServer::POA_ptr StubBatchConsumer::_default_POA (ACE_ENV_SINGLE_ARG_DECL) +{ + return ::PortableServer::POA::_duplicate(this->poa_.in () ACE_ENV_ARG_PARAMETER); +} + +PortableServer::ObjectId StubBatchConsumer::objectId()const +{ + return this->object_id_.in(); +} + + +/** + * register this object + */ +int StubBatchConsumer::init (CORBA::ORB_ptr orb, ::FT::FaultNotifier_var & notifier ACE_ENV_ARG_DECL) +{ + int result = 0; + this->orb_ = CORBA::ORB::_duplicate (orb); + this->notifier_ = notifier; + this->identity_ = "StubBatchConsumer"; + + + // Use the ROOT POA for now + CORBA::Object_var poa_object = + this->orb_->resolve_initial_references (TAO_OBJID_ROOTPOA + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + if (CORBA::is_nil (poa_object.in ())) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT (" (%P|%t) Unable to initialize the POA.\n")), + -1); + + // Get the POA . + this->poa_ = PortableServer::POA::_narrow (poa_object.in () + ACE_ENV_ARG_PARAMETER); + + ACE_CHECK_RETURN (-1); + + if (CORBA::is_nil(this->poa_.in ())) + { + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT (" (%P|%t) Unable to narrow the POA.\n")), + -1); + } + + PortableServer::POAManager_var poa_manager = + this->poa_->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + // Register with the POA. + + this->object_id_ = this->poa_->activate_object (this ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + // find my identity as an object + + CORBA::Object_var this_obj = + this->poa_->id_to_reference (object_id_.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + CosNotifyFilter::Filter_var filter = CosNotifyFilter::Filter::_nil(); + + this->consumer_id_ = notifier->connect_sequence_fault_consumer( + CosNotifyComm::SequencePushConsumer::_narrow(this_obj.in ()), + filter.in ()); + + return result; +} + +/** + * Return a string to identify this object for logging/console message purposes. + */ +const char * StubBatchConsumer::identity () const +{ + return this->identity_.c_str(); +} + +/** + * Clean house for process shut down. + */ +void StubBatchConsumer::fini (ACE_ENV_SINGLE_ARG_DECL) +{ + this->notifier_->disconnect_consumer(this->consumer_id_ ACE_ENV_ARG_PARAMETER); +} + + +int StubBatchConsumer::idle(int & result) +{ + ACE_UNUSED_ARG(result); + return this->quit_; +} + +//////////////// +// CORBA methods + + +//virtual +void StubBatchConsumer::push_structured_events ( + const CosNotification::EventBatch & notifications + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException + , CosEventComm::Disconnected + )) +{ + ACE_UNUSED_ARG (notifications); + //@@ sequence of structured event handling not written yet +} + +void StubBatchConsumer::offer_change ( + const CosNotification::EventTypeSeq & added, + const CosNotification::EventTypeSeq & removed + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC ((CORBA::SystemException, CosNotifyComm::InvalidEventType)) +{ + ACE_UNUSED_ARG (added); + ACE_UNUSED_ARG (removed); + ACE_ERROR ((LM_ERROR, + "StubBatchConsumer: offer_change call ignored.\n" + )); + // @@ not implemented (not likely to be needed) +} + +//virtual +void StubBatchConsumer::disconnect_sequence_push_consumer ( + ACE_ENV_SINGLE_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException + )) +{ + ACE_ERROR ((LM_ERROR, + "StubBatchConsumer:disconnect_sequence_push_consumer interpreted as quit request.\n" + )); + this->quit_ = 1; +} + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) +// template instantiate ACE_Vector < const char * >; +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +//# pragma instantiate ACE_Vector < const char * > +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ + diff --git a/TAO/orbsvcs/tests/FT_App/StubBatchConsumer.h b/TAO/orbsvcs/tests/FT_App/StubBatchConsumer.h new file mode 100644 index 00000000000..d81d9fa061c --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/StubBatchConsumer.h @@ -0,0 +1,149 @@ +// -*- C++ -*- +// +// $Id$ +#ifndef STUBBATCHCONSUMER_H +#define STUBBATCHCONSUMER_H +#include /**/ <ace/pre.h> +#include <ace/ACE.h> + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include <orbsvcs/CosNotifyChannelAdminS.h> +#include <orbsvcs/FT_NotifierC.h> + +////////////////////// +// Forward references + +///////////////////// +// Class declarations + +/** + * A stub fault consumer for use in unit testing Fault Notifier. + */ +class StubBatchConsumer + : public virtual POA_CosNotifyComm::SequencePushConsumer +{ +public: + /** + * Default constructor. + */ + StubBatchConsumer (); + + /** + * virtual destructor. + */ + virtual ~StubBatchConsumer (); + + ::PortableServer::POA_ptr _default_POA (ACE_ENV_SINGLE_ARG_DECL); + ::PortableServer::ObjectId objectId()const; + + /** + * Parse command line arguments. + */ + int parse_args (int argc, char * argv[]); + + /** + * Publish this objects IOR. + */ + int init (CORBA::ORB_ptr orbManager, ::FT::FaultNotifier_var & notifier ACE_ENV_ARG_DECL); + + /** + * Return a string to identify this object for logging/console message purposes. + */ + const char * identity () const; + + /** + * idle time activity. + * @param result [out] status code to return from process + * @returns 0 to continue; nonzero to quit + */ + int idle(int &result); + + /** + * Clean house for process shut down. + */ + void fini (ACE_ENV_SINGLE_ARG_DECL); + + +public: + + //////////////// + // CORBA methods + + virtual void push_structured_events ( + const CosNotification::EventBatch & notifications + ACE_ENV_ARG_DECL_WITH_DEFAULTS + ) + ACE_THROW_SPEC (( + CORBA::SystemException + , CosEventComm::Disconnected + )); + + virtual void disconnect_sequence_push_consumer ( + ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS + ) + ACE_THROW_SPEC (( + CORBA::SystemException + )); + + virtual void offer_change ( + const CosNotification::EventTypeSeq & added, + const CosNotification::EventTypeSeq & removed + ACE_ENV_ARG_DECL_WITH_DEFAULTS + ) + throw (CORBA::SystemException, CosNotifyComm::InvalidEventType); + + //////////////////// + // Forbidden methods +private: + StubBatchConsumer (const StubBatchConsumer & rhs); + StubBatchConsumer & operator = (const StubBatchConsumer & rhs); + + ///////////////////////// + // Implementation methods +private: + + /////////////// + // Data Members +private: + /** + * The orb + */ + CORBA::ORB_var orb_; + + /** + * The POA used to activate this object. + */ + PortableServer::POA_var poa_; + + /** + * The CORBA object id assigned to this object. + */ + PortableServer::ObjectId_var object_id_; + + /** + * A human-readable string to distinguish this from other FaultConsumers. + */ + ACE_CString identity_; + + /** + * boolean: request quit + */ + int quit_; + + /** + * the notifier + */ + ::FT::FaultNotifier_var notifier_; + + /** + * consumer id assigned by the notifier + */ + ::FT::FaultNotifier::ConsumerId consumer_id_; +}; + +#include /**/ <ace/post.h> + +#endif /* STUBBATCHCONSUMER_H */ diff --git a/TAO/orbsvcs/tests/FT_App/StubFaultAnalyzer.cpp b/TAO/orbsvcs/tests/FT_App/StubFaultAnalyzer.cpp new file mode 100644 index 00000000000..ab4d67fbe2b --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/StubFaultAnalyzer.cpp @@ -0,0 +1,275 @@ +// -*- C++ -*- +// +// $Id$ + +#include "StubFaultAnalyzer.h" +#include <ace/Get_Opt.h> +#include <tao/PortableServer/ORB_Manager.h> +#include <orbsvcs/PortableGroup/PG_Properties_Encoder.h> +#include <iostream> +#include <fstream> + +StubFaultAnalyzer::StubFaultAnalyzer () + : readyFile_(0) + , detector_ior_(0) + , notifier_ior_(0) +{ +} + + +StubFaultAnalyzer::~StubFaultAnalyzer () +{ +} + + +int StubFaultAnalyzer::parse_args (int argc, char * argv[]) +{ + int optionError = 0; + ACE_Get_Opt get_opts (argc, argv, "o:r:d:n:"); + int c; + while ((c = get_opts ()) != -1) + { + switch (c) + { + case 'r': + { + this->replicaIORs.push_back (get_opts.opt_arg ()); + break; + } + case 'd': + { + this->detector_ior_ = get_opts.opt_arg (); + break; + } + case 'n': + { + this->notifier_ior_ = get_opts.opt_arg (); + break; + } + case 'o': + { + this->readyFile_ = get_opts.opt_arg (); + break; + } + + default: + // fall thru + case '?': + { + break; + } + } + } + + if(! optionError) + { + if (0 == replicaIORs.size()) + { + ACE_ERROR ((LM_ERROR, + "at least one -r option is required.\n" + )); + optionError = -1; + } + + if (0 == this->detector_ior_) + { + ACE_ERROR ((LM_ERROR, + "-d option is required.\n" + )); + optionError = -1; + } + if (0 == this->notifier_ior_) + { + ACE_ERROR ((LM_ERROR, + "-n option is required.\n" + )); + optionError = -1; + } + } + + if(optionError) + { + ACE_ERROR ((LM_ERROR, + "usage: %s" + " -r <replica.ior[,replica.ior]>" + " -d <detector.ior>" + " -o <ready.file>" // note: not an IOR file. just an "I'm alive" indicator." + " -n <notifier.ior>" + "\n", + argv [0] + )); + } + return optionError; +} + +/** + * Register this object as necessary + */ +int StubFaultAnalyzer::init (CORBA::ORB_ptr orb ACE_ENV_ARG_DECL) +{ + int result = 0; + this->orb_ = CORBA::ORB::_duplicate (orb); + ////////////////////////////////////////// + // resolve reference to detector factory + CORBA::Object_var detector_obj = this->orb_->string_to_object(this->detector_ior_); + this->factory_ = ::FT::FaultDetectorFactory::_narrow(detector_obj.in ()); + if (CORBA::is_nil(this->factory_.in ())) + { + std::cerr << "Can't resolve Detector Factory IOR " << this->detector_ior_ << std::endl; + result = -1; + } + + ////////////////////////////////////////// + // resolve references to notifier + CORBA::Object_var not_obj = this->orb_->string_to_object(this->notifier_ior_); + this->notifier_ = ::FT::FaultNotifier::_narrow(not_obj.in ()); + if (CORBA::is_nil(this->notifier_.in ())) + { + std::cerr << "Can't resolve Notifier IOR " << this->notifier_ior_ << std::endl; + result = -1; + } + + + ////////////////////////////////// + // register fault consumers + if (result == 0) + { + result = this->faultConsumer_.init(orb, this->notifier_); + } + + if (result == 0) + { + result = this->batchConsumer_.init(orb, this->notifier_); + } + + ///////////////////////// + // Set up fault detectors + if (result == 0) + { + //////////////////////////////////// + // resolve references to replicas + // create a fault detector for each replica + size_t replicaCount = this->replicaIORs.size(); + for(size_t nRep = 0; result == 0 && nRep < replicaCount; ++nRep) + { + const char * iorName = this->replicaIORs[nRep]; + CORBA::Object_var rep_obj = this->orb_->string_to_object(iorName); + FT::PullMonitorable_var replica = FT::PullMonitorable::_narrow(rep_obj.in ()); + if (CORBA::is_nil(replica.in ())) + { + std::cerr << "Can't resolve Replica IOR " << iorName << std::endl; + result = -1; + } + else + { + this->replicas_.push_back(replica); + + CORBA::String_var type_id = CORBA::string_dup("FaultDetector"); + + TAO_PG::Properties_Encoder encoder; + + PortableGroup::Value value; + value <<= this->notifier_.in (); + encoder.add(::FT::FT_NOTIFIER, value); + + value <<= replica.in (); + encoder.add(::FT::FT_MONITORABLE, value); + + FT::FTDomainId domain_id = 0; + value <<= domain_id; + encoder.add(::FT::FT_DOMAIN_ID, value); + + PortableGroup::Location object_location; + object_location.length(1); + object_location[0].id = CORBA::string_dup("Test location"); + value <<= object_location; + encoder.add(::FT::FT_LOCATION, value); + + PortableGroup::TypeId object_type = CORBA::string_dup("dummy_type"); + value <<= object_type; + encoder.add(::FT::FT_TYPE_ID, value); + + FT::ObjectGroupId group_id = 0; + value <<= group_id; + encoder.add(::FT::FT_GROUP_ID, value); + + // allocate and populate the criteria + PortableGroup::Criteria_var criteria; + ACE_NEW_NORETURN (criteria, + PortableGroup::Criteria); + if (criteria.ptr() == 0) + { + ACE_ERROR((LM_ERROR, + "Error cannot allocate criteria.\n" + )); + result = -1; + } + else + { + encoder.encode(criteria); + PortableGroup::GenericFactory::FactoryCreationId_var factory_creation_id; + + ACE_DEBUG((LM_DEBUG, + "Call create_object with type: %s\n", type_id.in() + )); + this->factory_->create_object ( + type_id.in(), + criteria.in(), + factory_creation_id + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + } + } + } + + if (result == 0 && this->readyFile_ != 0) + { + std::ofstream ready(this->readyFile_, ios::out); + ready << "ready" << std::endl; + ready.close(); + } + } + return result; +} + + +/** + * Return a string to identify this object for logging/console message purposes. + */ +const char * StubFaultAnalyzer::identity () const +{ + return this->identity_.c_str(); +} + +/** + * Clean house for process shut down. + */ +int StubFaultAnalyzer::fini (ACE_ENV_SINGLE_ARG_DECL) +{ + this->faultConsumer_.fini(ACE_ENV_SINGLE_ARG_PARAMETER); + this->batchConsumer_.fini(ACE_ENV_SINGLE_ARG_PARAMETER); + return 0; +} + + +int StubFaultAnalyzer::idle(int & result) +{ + ACE_UNUSED_ARG(result); + int quit = 0; + + if (this->replicas_.size() == this->faultConsumer_.notifications()) + { + quit = 1; + } + return quit; +} + + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) + template class ACE_Vector < const char * >; + template class ACE_Vector < FT::PullMonitorable_var > ; +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +# pragma instantiate ACE_Vector < const char * > +# pragma instantiate ACE_Vector < FT::PullMonitorable_var > +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ + diff --git a/TAO/orbsvcs/tests/FT_App/StubFaultAnalyzer.h b/TAO/orbsvcs/tests/FT_App/StubFaultAnalyzer.h new file mode 100644 index 00000000000..cbf8eaf6e35 --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/StubFaultAnalyzer.h @@ -0,0 +1,132 @@ +// -*- C++ -*- +// +// $Id$ +#ifndef STUBFAULTANALYZER_H +#define STUBFAULTANALYZER_H +#include /**/ <ace/pre.h> +#include <ace/ACE.h> + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "StubFaultConsumer.h" +#include "StubBatchConsumer.h" +#include <orbsvcs/FT_NotifierC.h> +#include <orbsvcs/FT_FaultDetectorFactoryC.h> + +#include "ace/Vector_T.h" + +////////////////////// +// Forward references + +///////////////////// +// Class declarations + +/** + * A stub fault analyzer for use in unit testing. + */ +class StubFaultAnalyzer +{ +public: + /** + * Default constructor. + */ + StubFaultAnalyzer (); + + /** + * destructor. + */ + ~StubFaultAnalyzer (); + + /** + * Parse command line arguments. + */ + int parse_args (int argc, char * argv[]); + + /** + * Initialize this object + */ + int init (CORBA::ORB_ptr orb); + + /** + * Return a string to identify this object for logging/console message purposes. + */ + const char * identity () const; + + /** + * idle time activity. + * @param result [out] status code to return from process + * @returns 0 to continue; nonzero to quit + */ + int idle(int &result); + + /** + * Prepare to exit. + * @return zero for success; nonzero is process return code for failure. + */ + int fini (ACE_ENV_SINGLE_ARG_DECL); + + ///////////////// + // Implementation +private: + int readIORFile(const char * fileName, CORBA::String_var & ior); + + /////////////// + // Data Members +private: + /** + * The orb + */ + CORBA::ORB_var orb_; + + /** + * The POA used to activate this object. + */ + PortableServer::POA_var poa_; + + /** + * The CORBA object id assigned to this object. + */ + PortableServer::ObjectId_var objectId_; + + /** + * A human-readable string to distinguish this from other Notifiers. + */ + ACE_CString identity_; + + /** + * a file to write to to signal "ready" + */ + const char * readyFile_; + + /** + * The detecor's IOR (-d option) + */ + const char * detector_ior_; + + ::FT::FaultDetectorFactory_var factory_; + + /** + * The notifier's IOR (-n option) + */ + const char * notifier_ior_; + + ::FT::FaultNotifier_var notifier_; + + /** + * A collection of files containing replica IORs + */ + ACE_Vector < const char * > replicaIORs; + + ACE_Vector < FT::PullMonitorable_var > replicas_; + + + StubFaultConsumer faultConsumer_; + StubBatchConsumer batchConsumer_; + +}; + +#include /**/ <ace/post.h> + +#endif /* STUBFAULTANALYZER_H */ diff --git a/TAO/orbsvcs/tests/FT_App/StubFaultConsumer.cpp b/TAO/orbsvcs/tests/FT_App/StubFaultConsumer.cpp new file mode 100644 index 00000000000..94d93e97483 --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/StubFaultConsumer.cpp @@ -0,0 +1,318 @@ +// -*- C++ -*- +// +// $Id$ + +#include "StubFaultConsumer.h" +#include <ace/Get_Opt.h> +#include <tao/PortableServer/ORB_Manager.h> +#include <orbsvcs/orbsvcs/PortableGroup/PG_Properties_Encoder.h> + +StubFaultConsumer::StubFaultConsumer () + : quit_(0) + , notifications_(0) +{ +} + + +StubFaultConsumer::~StubFaultConsumer () +{ +} + +::PortableServer::POA_ptr StubFaultConsumer::_default_POA (ACE_ENV_SINGLE_ARG_DECL) +{ + return ::PortableServer::POA::_duplicate(this->poa_.in () ACE_ENV_ARG_PARAMETER); +} + +PortableServer::ObjectId StubFaultConsumer::objectId()const +{ + return this->object_id_.in(); +} + +size_t StubFaultConsumer::notifications () const +{ + return this->notifications_; +} + + +int StubFaultConsumer::parse_args (int argc, char * argv[]) +{ + int optionError = 0; +#ifndef NO_ARGS_FOR_NOW + ACE_UNUSED_ARG (argc); + ACE_UNUSED_ARG (argv); +#else // NO_ARGS_FOR_NOW + ACE_Get_Opt get_opts (argc, argv, ""); + int c; + while ((c = get_opts ()) != -1) + { + switch (c) + { + case 'r': + { + if (this->replicaIorBuffer_ == 0) + { + const char * repNames = get_opts.opt_arg (); + size_t repNameLen = ACE_OS::strlen(repNames); + + // make a working copy of the string + ACE_NEW_NORETURN(this->replicaIorBuffer_, + char[repNameLen + 1]); + if ( this->replicaIorBuffer_ != 0) + { + ACE_OS::memcpy(this->replicaIorBuffer_, repNames, repNameLen+1); + + // tokenize the string on ',' + // into iorReplicaFiles_ + char * pos = this->replicaIorBuffer_; + while (pos != 0) + { + this->iorReplicaFiles_.push_back(pos); + // find a comma delimiter, and + // chop the string there. + pos = ACE_OS::strchr (pos, ','); + if (pos != 0) + { + *pos = '\0'; + pos += 1; + } + } + } + else + { + ACE_ERROR ((LM_ERROR, + "Command line option error: -r can't allocate buffer.\n" + )); + optionError = -1; + } + } + else + { + ACE_ERROR ((LM_ERROR, + "Command line option error: -r specified more than once.\n" + )); + optionError = -1; + } + break; + } + case 'd': + { + this->iorDetectorFile_ = get_opts.opt_arg (); + break; + } + case 'n': + { + this->nsName_ = get_opts.opt_arg (); + break; + } + case 'o': + { + this->iorOutputFile_ = get_opts.opt_arg (); + break; + } + + default: + // fall thru + case '?': + { + break; + } + } + } + + if(! optionError) + { + if (0 == this->replicaIorBuffer_) + { + ACE_ERROR ((LM_ERROR, + "-r option is required.\n" + )); + optionError = -1; + } + if (0 == this->iorDetectorFile_) + { + ACE_ERROR ((LM_ERROR, + "-d option is required.\n" + )); + optionError = -1; + } + } + + if(optionError) + { + ACE_ERROR ((LM_ERROR, + "usage: %s" + " -r <replica.ior[,replica.ior]>" + " -d <detector.ior>" + " -o <this.ior>" + " -n <nameService name>" + "\n", + argv [0] + )); + } +#endif NO_ARGS_FOR_NOW + return optionError; +} + +/** + * Register this object. + */ +int StubFaultConsumer::init (CORBA::ORB_ptr orb, + ::FT::FaultNotifier_var & notifier + ACE_ENV_ARG_DECL) +{ + int result = 0; + this->orb_ = CORBA::ORB::_duplicate (orb); + this->notifier_ = notifier; + this->identity_ = "StubFaultConsumer"; + + + // Use the ROOT POA for now + CORBA::Object_var poa_object = + this->orb_->resolve_initial_references (TAO_OBJID_ROOTPOA + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + if (CORBA::is_nil (poa_object.in ())) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT (" (%P|%t) Unable to initialize the POA.\n")), + -1); + + // Get the POA object. + this->poa_ = + PortableServer::POA::_narrow (poa_object.in () + ACE_ENV_ARG_PARAMETER); + + ACE_CHECK_RETURN (-1); + if (CORBA::is_nil(this->poa_.in ())) + { + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT (" (%P|%t) Unable to narrow the POA.\n")), + -1); + } + + PortableServer::POAManager_var poa_manager = + this->poa_->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + // Register with the POA. + + this->object_id_ = this->poa_->activate_object (this ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + // find my identity as an object + + CORBA::Object_var this_obj = + this->poa_->id_to_reference (object_id_.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + CosNotifyFilter::Filter_var filter = CosNotifyFilter::Filter::_nil(); + + this->consumer_id_ = notifier->connect_structured_fault_consumer( + CosNotifyComm::StructuredPushConsumer::_narrow(this_obj.in ()), + filter.in ()); + + return result; +} + +/** + * Return a string to identify this object for logging/console message purposes. + */ +const char * StubFaultConsumer::identity () const +{ + return this->identity_.c_str(); +} + +/** + * Clean house for process shut down. + */ +int StubFaultConsumer::fini (ACE_ENV_SINGLE_ARG_DECL) +{ + this->notifier_->disconnect_consumer(this->consumer_id_ ACE_ENV_ARG_PARAMETER); + return 0; +} + + +int StubFaultConsumer::idle(int & result) +{ + ACE_UNUSED_ARG(result); + return this->quit_; +} + +//////////////// +// CORBA methods +void StubFaultConsumer::push_structured_event( + const CosNotification::StructuredEvent ¬ification + ACE_ENV_ARG_DECL + ) + throw (CORBA::SystemException, CosEventComm::Disconnected) +{ + //////////////////////////////////////// + // keep track of how many we've received + this->notifications_ += 1; + ACE_ERROR ((LM_ERROR, + "FaultConsumer: Received Fault notification(%d):\n" + "FaultConsumer: Header EventType domain: %s\n" + "FaultConsumer: Header EventType type: %s\n" + "FaultConsumer: Header EventName: %s\n", + ACE_static_cast (unsigned int, this->notifications_), + ACE_static_cast (const char *, notification.header.fixed_header.event_type.domain_name), + ACE_static_cast (const char *, notification.header.fixed_header.event_type.type_name), + ACE_static_cast (const char *, notification.header.fixed_header.event_name) + )); + const CosNotification::FilterableEventBody & filterable = notification.filterable_data; + + size_t propertyCount = filterable.length (); + for (size_t nProp = 0; nProp < propertyCount; ++nProp) + { + const CosNotification::Property & property = filterable[nProp]; + + const char * property_name = ACE_static_cast (const char *, property.name); + const char * value = "<unknown>"; + if (property.value >>= value ) + { + // ok! + } + ACE_ERROR ((LM_ERROR, + "FaultConsumer: Property Name: %s=%s\n", + property_name, + value + )); + + +// int todo_finish_decode; + } + +} + +void StubFaultConsumer::offer_change ( + const CosNotification::EventTypeSeq & added, + const CosNotification::EventTypeSeq & removed + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC ((CORBA::SystemException, CosNotifyComm::InvalidEventType)) +{ + ACE_UNUSED_ARG (added); + ACE_UNUSED_ARG (removed); + ACE_ERROR ((LM_ERROR, + "StubFaultConsumer: offer_change call ignored.\n" + )); +} + +void StubFaultConsumer::disconnect_structured_push_consumer(ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + ACE_ERROR ((LM_ERROR, + "StubFaultConsumer:disconnect_structured_push_consumer interpreted as quit request.\n" + )); + this->quit_ = 1; +} + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) +// template instantiate ACE_Vector < const char * >; +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +//# pragma instantiate ACE_Vector < const char * > +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/orbsvcs/tests/FT_App/StubFaultConsumer.h b/TAO/orbsvcs/tests/FT_App/StubFaultConsumer.h new file mode 100644 index 00000000000..374b2e7b588 --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/StubFaultConsumer.h @@ -0,0 +1,149 @@ +// -*- C++ -*- +// +// $Id$ +#ifndef STUBFAULTCONSUMER_H +#define STUBFAULTCONSUMER_H +#include /**/ <ace/pre.h> +#include <ace/ACE.h> + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "orbsvcs/CosNotifyChannelAdminS.h" +#include <orbsvcs/FT_NotifierC.h> + +////////////////////// +// Forward references + +///////////////////// +// Class declarations + +/** + * A stub fault consumer for use in unit testing Fault Notifier. + */ +class StubFaultConsumer + : public virtual POA_CosNotifyComm::StructuredPushConsumer +{ +public: + /** + * Default constructor. + */ + StubFaultConsumer (); + + /** + * virtual destructor. + */ + virtual ~StubFaultConsumer (); + + + ::PortableServer::POA_ptr _default_POA (ACE_ENV_SINGLE_ARG_DECL); + ::PortableServer::ObjectId objectId()const; + + /** + * Parse command line arguments. + */ + int parse_args (int argc, char * argv[]); + + /** + * Publish this objects IOR. + */ + int init (CORBA::ORB_ptr orb, ::FT::FaultNotifier_var & notifier + ACE_ENV_ARG_DECL); + + /** + * Return a string to identify this object for logging/console message purposes. + */ + const char * identity () const; + + /** + * idle time activity. + * @param result [out] status code to return from process + * @returns 0 to continue; nonzero to quit + */ + int idle(int &result); + + /** + * Clean house for process shut down. + */ + int fini (ACE_ENV_SINGLE_ARG_DECL); + + + size_t notifications() const; + +public: + + //////////////// + // CORBA methods + virtual void push_structured_event( + const CosNotification::StructuredEvent ¬ification + ACE_ENV_ARG_DECL_WITH_DEFAULTS + ) + throw (CORBA::SystemException, CosEventComm::Disconnected); + + virtual void offer_change ( + const CosNotification::EventTypeSeq & added, + const CosNotification::EventTypeSeq & removed + ACE_ENV_ARG_DECL_WITH_DEFAULTS + ) + throw (CORBA::SystemException, CosNotifyComm::InvalidEventType); + + virtual void disconnect_structured_push_consumer(ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS) + throw (CORBA::SystemException); + + //////////////////// + // Forbidden methods +private: + StubFaultConsumer (const StubFaultConsumer & rhs); + StubFaultConsumer & operator = (const StubFaultConsumer & rhs); + + ///////////////////////// + // Implementation methods +private: + + /////////////// + // Data Members +private: + /** + * The orb + */ + CORBA::ORB_var orb_; + + /** + * The POA used to activate this object. + */ + PortableServer::POA_var poa_; + + /** + * The CORBA object id assigned to this object. + */ + PortableServer::ObjectId_var object_id_; + + + /** + * A human-readable string to distinguish this from other FaultConsumers. + */ + ACE_CString identity_; + + /** + * boolean: request quit + */ + int quit_; + + /** + * the notifier + */ + ::FT::FaultNotifier_var notifier_; + + /** + * consumer id assigned by the notifier + */ + ::FT::FaultNotifier::ConsumerId consumer_id_; + + size_t notifications_; + +}; + +#include /**/ <ace/post.h> + +#endif /* STUBFAULTCONSUMER_H */ diff --git a/TAO/orbsvcs/tests/FT_App/StubFaultNotifier.cpp b/TAO/orbsvcs/tests/FT_App/StubFaultNotifier.cpp new file mode 100644 index 00000000000..4254cbe73ff --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/StubFaultNotifier.cpp @@ -0,0 +1,494 @@ +// -*- C++ -*- +// +// $Id$ + +#include "StubFaultNotifier.h" +#include <ace/Get_Opt.h> +#include <tao/PortableServer/ORB_Manager.h> +#include <orbsvcs/orbsvcs/PortableGroup/PG_Properties_Encoder.h> +#include <iostream> + +StubFaultNotifier::StubFaultNotifier () + : ior_output_file_(0) + , detector_ior_(0) + , ns_name_(0) +{ +} + + +StubFaultNotifier::~StubFaultNotifier () +{ +} + + +::PortableServer::POA_ptr StubFaultNotifier::_default_POA (ACE_ENV_SINGLE_ARG_DECL) +{ + return ::PortableServer::POA::_duplicate(this->poa_.in () ACE_ENV_ARG_PARAMETER); +} + +PortableServer::ObjectId StubFaultNotifier::objectId()const +{ + return this->object_id_.in(); +} + +int StubFaultNotifier::parse_args (int argc, char * argv[]) +{ + int optionError = 0; + ACE_Get_Opt get_opts (argc, argv, "o:r:d:n:"); + int c; + while ((c = get_opts ()) != -1) + { + switch (c) + { + case 'r': + { + this->iorReplicaFiles_.push_back( get_opts.opt_arg ()); + break; + } + case 'd': + { + this->detector_ior_ = get_opts.opt_arg (); + break; + } + case 'n': + { + this->ns_name_ = get_opts.opt_arg (); + break; + } + case 'o': + { + this->ior_output_file_ = get_opts.opt_arg (); + break; + } + + default: + // fall thru + case '?': + { + break; + } + } + } + + if(! optionError) + { + if (iorReplicaFiles_.size() == 0) + { + ACE_ERROR ((LM_ERROR, + "-r option is required.\n" + )); + optionError = -1; + } + if (0 == this->detector_ior_) + { + ACE_ERROR ((LM_ERROR, + "-d option is required.\n" + )); + optionError = -1; + } + } + + if(optionError) + { + ACE_ERROR ((LM_ERROR, + "usage: %s" + " -r <replica.ior [-r <replica2.ior]...>" + " -d <detector.ior>" + " -o <this.ior>" + " -n <nameService name>" + "\n", + argv [0] + )); + } + return optionError; +} + +/** + * Prepare to exit. + */ +int StubFaultNotifier::fini () +{ + if(this->ns_name_ != 0) + { + ACE_TRY_NEW_ENV + { + CORBA::Object_var naming_obj = + this->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); + } + + CosNaming::NamingContext_var naming_context = + CosNaming::NamingContext::_narrow (naming_obj.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + CosNaming::Name this_name (1); + this_name.length (1); + this_name[0].id = CORBA::string_dup (this->ns_name_); + + naming_context->unbind (this_name + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + } + ACE_ENDTRY; + } + return 0; +} + + +/** + * Publish this objects IOR. + */ +int StubFaultNotifier::init (CORBA::ORB_ptr orb ACE_ENV_ARG_DECL) +{ + int result = 0; + this->orb_ = CORBA::ORB::_duplicate (orb); + + // Use the ROOT POA for now + CORBA::Object_var poa_object = + this->orb_->resolve_initial_references (TAO_OBJID_ROOTPOA + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + if (CORBA::is_nil (poa_object.in ())) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT (" (%P|%t) Unable to initialize the POA.\n")), + -1); + + // Get the POA object. + this->poa_ = + PortableServer::POA::_narrow (poa_object.in () + ACE_ENV_ARG_PARAMETER); + + ACE_CHECK_RETURN (-1); + + if (CORBA::is_nil(this->poa_.in ())) + { + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT (" (%P|%t) Unable to narrow the POA.\n")), + -1); + } + + PortableServer::POAManager_var poa_manager = + this->poa_->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + // Register with the POA. + + this->object_id_ = this->poa_->activate_object (this ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + // find my identity as a corba object + CORBA::Object_var this_obj = + this->poa_->id_to_reference (object_id_.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + ////////////////////////////////////////// + // resolve references to detector factory + + CORBA::Object_var obj = this->orb_->string_to_object(detector_ior_); + this->factory_ = ::FT::FaultDetectorFactory::_narrow(obj.in ()); + if (CORBA::is_nil(this->factory_.in ())) + { + std::cerr << "Can't resolve Detector Factory IOR " << this->detector_ior_ << std::endl; + result = -1; + } + if (result == 0) + { + //////////////////////////////////// + // resolve references to replicas + size_t replicaCount = this->iorReplicaFiles_.size(); + for(size_t nRep = 0; result == 0 && nRep < replicaCount; ++nRep) + { + const char * iorName = this->iorReplicaFiles_[nRep]; + CORBA::Object_var obj = this->orb_->string_to_object(iorName); + FT::PullMonitorable_var replica = FT::PullMonitorable::_narrow(obj.in ()); + if (CORBA::is_nil(replica.in ())) + { + std::cerr << "Can't resolve Replica IOR " << iorName << std::endl; + result = -1; + } + else + { + this->replicas_.push_back(replica); + + CORBA::String_var type_id = CORBA::string_dup("FaultDetector"); + + TAO_PG::Properties_Encoder encoder; + + PortableGroup::Value value; + ////////////////// + // FaultDetectorFactory gets picky about FaultNotifier's object type. + // coddle it. + ::FT::FaultNotifier_var notifier = ::FT::FaultNotifier::_narrow(this_obj.in ()); + value <<= notifier.in (); + encoder.add(::FT::FT_NOTIFIER, value); + + + value <<= replica.in (); + encoder.add(::FT::FT_MONITORABLE, value); + + FT::FTDomainId domain_id = 0; + value <<= domain_id; + encoder.add(::FT::FT_DOMAIN_ID, value); + + PortableGroup::Location object_location; + object_location.length(1); + object_location[0].id = CORBA::string_dup("Test location"); + value <<= object_location; + encoder.add(::FT::FT_LOCATION, value); + + PortableGroup::TypeId object_type = 0; + value <<= object_type; + encoder.add(::FT::FT_TYPE_ID, value); + + PortableGroup::ObjectGroupId group_id = 0; + value <<= group_id; + encoder.add(::FT::FT_GROUP_ID, value); + + // allocate and populate the criteria + PortableGroup::Criteria_var criteria; + ACE_NEW_NORETURN (criteria, + PortableGroup::Criteria); + if (criteria.ptr() == 0) + { + ACE_ERROR((LM_ERROR, + "Error cannot allocate criteria.\n" + )); + result = -1; + } + else + { + encoder.encode(criteria); + PortableGroup::GenericFactory::FactoryCreationId_var factory_creation_id; + + this->factory_->create_object ( + type_id.in(), + criteria.in(), + factory_creation_id + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + } + } + } + + if (this->ior_output_file_ != 0) + { + this->identity_ = "file:"; + this->identity_ += this->ior_output_file_; + result = write_ior_file(); + } + else + { + // if no IOR file specified, + // then always try to register with name service + this->ns_name_ = "FT_FaultNotifier"; + } + + if(this->ns_name_ != 0) + { + this->identity_ = "name:"; + this->identity_ += this->ns_name_; + + CORBA::Object_var naming_obj = + this->orb_->resolve_initial_references ("NameService" ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + if (CORBA::is_nil(naming_obj.in ())){ + ACE_ERROR_RETURN ((LM_ERROR, + "%T %n (%P|%t) Unable to find the Naming Service\n"), + 1); + } + + CosNaming::NamingContext_var naming_context = + CosNaming::NamingContext::_narrow (naming_obj.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + CosNaming::Name this_name (1); + this_name.length (1); + this_name[0].id = CORBA::string_dup (this->ns_name_); + + naming_context->rebind (this_name, this_obj.in() + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + } + } + return result; +} + +int StubFaultNotifier::write_ior_file() +{ + int result = -1; + FILE* out = ACE_OS::fopen (this->ior_output_file_, "w"); + if (out) + { + ACE_OS::fprintf (out, "%s", ACE_static_cast(const char *, this->ior_)); + ACE_OS::fclose (out); + result = 0; + } + return result; +} + +/** + * Return a string to identify this object for logging/console message purposes. + */ +const char * StubFaultNotifier::identity () const +{ + return this->identity_.c_str(); +} + +/** + * Clean house for process shut down. + */ +void StubFaultNotifier::shutdown_i () +{ + this->orb_->shutdown (0 ACE_ENV_ARG_PARAMETER); +} + +void StubFaultNotifier::push_structured_fault ( + const CosNotification::StructuredEvent & event + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + ACE_ERROR ((LM_ERROR, + "FaultNotifier: Received Fault notification:\n" + "FaultNotifier: Header EventType domain: %s\n" + "FaultNotifier: Header EventType type: %s\n" + "FaultNotifier: Header EventName: %s\n", + ACE_static_cast (const char *, event.header.fixed_header.event_type.domain_name), + ACE_static_cast (const char *, event.header.fixed_header.event_type.type_name), + ACE_static_cast (const char *, event.header.fixed_header.event_name) + )); + const CosNotification::FilterableEventBody & filterable = event.filterable_data; + + size_t propertyCount = filterable.length (); + for (size_t nProp = 0; nProp < propertyCount; ++nProp) + { + const CosNotification::Property & property = filterable[nProp]; + ACE_ERROR ((LM_ERROR, + "FaultNotifier: Property Name: %s\n", + ACE_static_cast (const char *, property.name) + )); + //@@ we could stand to decode more--just for completeness + } +} + + +void StubFaultNotifier::push_sequence_fault ( + const CosNotification::EventBatch & events + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException + )) +{ + ACE_UNUSED_ARG (events); + ACE_THROW (CORBA::NO_IMPLEMENT()); +} + +::CosNotifyFilter::Filter_ptr StubFaultNotifier::create_subscription_filter ( + const char * constraint_grammar + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException + , CosNotifyFilter::InvalidGrammar + )) +{ + ACE_UNUSED_ARG (constraint_grammar); + ACE_THROW (CORBA::NO_IMPLEMENT()); +} + + +FT::FaultNotifier::ConsumerId StubFaultNotifier::connect_structured_fault_consumer ( + CosNotifyComm::StructuredPushConsumer_ptr push_consumer, + CosNotifyFilter::Filter_ptr filter + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException + )) +{ + ACE_UNUSED_ARG(push_consumer); + ACE_UNUSED_ARG(filter); + + ACE_THROW (CORBA::NO_IMPLEMENT()); +} + + +FT::FaultNotifier::ConsumerId StubFaultNotifier::connect_sequence_fault_consumer ( + CosNotifyComm::SequencePushConsumer_ptr push_consumer, + CosNotifyFilter::Filter_ptr filter + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException + )) +{ + ACE_UNUSED_ARG(push_consumer); + ACE_UNUSED_ARG(filter); + + ACE_THROW (CORBA::NO_IMPLEMENT()); +} + +void StubFaultNotifier::disconnect_consumer ( + FT::FaultNotifier::ConsumerId connection + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException + , CosEventComm::Disconnected + )) +{ + ACE_UNUSED_ARG(connection); + + ACE_THROW (CORBA::NO_IMPLEMENT()); +} + +CORBA::Boolean StubFaultNotifier::is_alive (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + return 1; +} + +int StubFaultNotifier::idle(int & result) +{ + ACE_UNUSED_ARG(result); + int quit = 0; + ACE_TRY_NEW_ENV + { + if(!CORBA::is_nil(this->factory_.in ())) + { + if (!this->factory_->is_alive( ACE_ENV_SINGLE_ARG_PARAMETER)) + { + quit = 1; + } + } + } + ACE_CATCHANY + { + quit = 1; + } + ACE_ENDTRY; + return quit; +} + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) + template class ACE_Vector < const char * >; + template class ACE_Vector < FT::PullMonitorable_var > ; +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +# pragma instantiate ACE_Vector < const char * > +# pragma instantiate ACE_Vector < FT::PullMonitorable_var > +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/orbsvcs/tests/FT_App/StubFaultNotifier.h b/TAO/orbsvcs/tests/FT_App/StubFaultNotifier.h new file mode 100644 index 00000000000..38a285cdce6 --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/StubFaultNotifier.h @@ -0,0 +1,187 @@ +// -*- C++ -*- +// +// $Id$ +#ifndef STUBFAULTNOTIFIER_H_ +#define STUBFAULTNOTIFIER_H_ + +#include <ace/ACE.h> + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ +#include /**/ <ace/pre.h> + +#include <orbsvcs/FT_NotifierS.h> +#include <orbsvcs/FT_FaultDetectorFactoryC.h> +#include <ace/Vector_T.h> + +////////////////////// +// Forward references + +///////////////////// +// Class declarations + +/** + * A stub implementation of the FaultNotifier interface + */ +class StubFaultNotifier : public virtual POA_FT::FaultNotifier +{ + ////////////////////// + // non-CORBA interface +public: + /** + * Default constructor. + */ + StubFaultNotifier (); + + /** + * Virtual destructor. + */ + virtual ~StubFaultNotifier (); + + /** + * Parse command line arguments. + */ + int parse_args (int argc, char * argv[]); + + /** + * Initialize. + */ + int init (CORBA::ORB_ptr orb ACE_ENV_ARG_DECL); + + /** + * Prepare to exit. + */ + int fini (); + + /** + * Return a string to identify this object for logging/console message purposes. + */ + const char * identity () const; + + /** + * idle time activity. + * @param result [out] status code to return from process + * @returns 0 to continue; nonzero to quit + */ + int idle(int &result); + + // override virtuals +::PortableServer::POA_ptr _default_POA (ACE_ENV_SINGLE_ARG_DECL); + + PortableServer::ObjectId objectId()const; + + + /** + * Clean house for process shut down. + */ + void shutdown_i (); + + //////////////////////////////// + // CORBA interface FaultNotifier + + + virtual void push_structured_fault ( + const CosNotification::StructuredEvent & event + ACE_ENV_ARG_DECL_WITH_DEFAULTS + ) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual void push_sequence_fault ( + const CosNotification::EventBatch & events + ACE_ENV_ARG_DECL_WITH_DEFAULTS + ) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual ::CosNotifyFilter::Filter_ptr create_subscription_filter ( + const char * constraint_grammar + ACE_ENV_ARG_DECL_WITH_DEFAULTS + ) + ACE_THROW_SPEC ((CORBA::SystemException, CosNotifyFilter::InvalidGrammar)); + + virtual FT::FaultNotifier::ConsumerId connect_structured_fault_consumer ( + CosNotifyComm::StructuredPushConsumer_ptr push_consumer, + CosNotifyFilter::Filter_ptr filter + ACE_ENV_ARG_DECL_WITH_DEFAULTS + ) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual FT::FaultNotifier::ConsumerId connect_sequence_fault_consumer ( + CosNotifyComm::SequencePushConsumer_ptr push_consumer, + CosNotifyFilter::Filter_ptr filter + ACE_ENV_ARG_DECL_WITH_DEFAULTS + ) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual void disconnect_consumer ( + FT::FaultNotifier::ConsumerId connection + ACE_ENV_ARG_DECL_WITH_DEFAULTS + ) + ACE_THROW_SPEC ((CORBA::SystemException, CosEventComm::Disconnected)); + + ////////////////////////////////////////// + // CORBA interface PullMonitorable methods + virtual CORBA::Boolean is_alive (ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + + ///////////////// + // Implementation +private: + int write_ior_file(); + + /////////////// + // Data Members +private: + /** + * The orb + */ + CORBA::ORB_var orb_; + + /** + * The POA used to activate this object. + */ + PortableServer::POA_var poa_; + + /** + * The CORBA object id assigned to this object. + */ + PortableServer::ObjectId_var object_id_; + + /** + * 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 * ior_output_file_; + + /** + * A file from which the detecor's IOR should be read. + */ + const char * detector_ior_; + + ::FT::FaultDetectorFactory_var factory_; + + /** + * A collection of files containing replica IORs + */ + ACE_Vector < const char * > iorReplicaFiles_; + + + ACE_Vector < FT::PullMonitorable_var > replicas_; + /** + * A name to be used to register with the name service. + */ + const char * ns_name_; + + /** + * A human-readable string to distinguish this from other Notifiers. + */ + ACE_CString identity_; +}; + +#include /**/ <ace/post.h> + +#endif /* STUBFAULTNOTIFIER_H_ */ diff --git a/TAO/orbsvcs/tests/FT_App/TAO_Object_Group_Creator.cpp b/TAO/orbsvcs/tests/FT_App/TAO_Object_Group_Creator.cpp new file mode 100644 index 00000000000..5da8173f8fa --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/TAO_Object_Group_Creator.cpp @@ -0,0 +1,470 @@ +/* -*- C++ -*- */ +//============================================================================= +/** + * @file TAO_Object_Group_Creator.cpp + * + * $Id$ + * + * This file is part of Fault Tolerant CORBA. + * Utility to Create Object Group + * + * @author Dale Wilson <wilson_d@ociweb.com> + */ +//============================================================================= + +#include "TAO_Object_Group_Creator.h" +#include <iostream> +#include <fstream> +#include <orbsvcs/PortableGroup/PG_Properties_Encoder.h> +#include <orbsvcs/FT_FaultDetectorFactoryC.h> +#include <orbsvcs/PortableGroup/PG_Operators.h> + +#include <ace/Get_Opt.h> + +TAO::Object_Group_Creator::Object_Group_Creator () + : orb_(CORBA::ORB::_nil ()) + , registry_ (PortableGroup::FactoryRegistry::_nil ()) + , replication_manager_ (FT::ReplicationManager::_nil ()) + , detector_infos_ (0) + , have_replication_manager_ (0) +{ +} + +TAO::Object_Group_Creator::~Object_Group_Creator () +{ +} + +int TAO::Object_Group_Creator::set_factory_registry (PortableGroup::FactoryRegistry_ptr factory) +{ + this->registry_ = PortableGroup::FactoryRegistry::_duplicate (factory); + return CORBA::is_nil (this->registry_.in ()) ? -1 : 0 ; +} + + +int TAO::Object_Group_Creator::init (CORBA::ORB_ptr orb ACE_ENV_ARG_DECL) +{ + int result = 0; + this->orb_ = CORBA::ORB::_duplicate (orb); + + if (CORBA::is_nil (this->registry_.in ())) + { + /////////////////////////////// + // Find the ReplicationManager + ACE_TRY_NEW_ENV + { + CORBA::Object_var rm_obj = orb->resolve_initial_references ("ReplicationManager" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + this->replication_manager_ = ::FT::ReplicationManager::_narrow (rm_obj.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + if (!CORBA::is_nil (this->replication_manager_.in ())) + { + this->have_replication_manager_ = 1; + // empty criteria + ::PortableGroup::Criteria criteria; + this->registry_ = this->replication_manager_->get_factory_registry (criteria ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + if (!CORBA::is_nil (this->registry_.in ())) + { + this->detector_infos_ = this->registry_->list_factories_by_role (FT::FAULT_DETECTOR_ROLE_NAME, this->detector_type_id_.out () + ACE_ENV_ARG_PARAMETER) + ACE_TRY_CHECK; + CORBA::ULong count = this->detector_infos_->length (); + ACE_DEBUG ( (LM_DEBUG, + "%T %n (%P|%t)Object_Group_Creator: found %u factories for FaultDetectors\n", + ACE_static_cast (unsigned, count) + )); + } + else + { + ACE_ERROR ( (LM_ERROR, + "%T %n (%P|%t) Object_Group_Creator: ReplicationManager failed to return FactoryRegistry.\n" + )); + ACE_TRY_THROW (CORBA::NO_IMPLEMENT ()); + } + } + else + { + ACE_ERROR ( (LM_ERROR, + "%T %n (%P|%t) Object_Group_Creator: resolve_initial_references for ReplicationManager failed.\n" + )); + ACE_TRY_THROW (CORBA::OBJECT_NOT_EXIST ()); + } + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + "Creator: Exception resolving ReplicationManager,\n"); + + result = 1; + } + ACE_ENDTRY; + } + + return result; +} + +int TAO::Object_Group_Creator::unregister_role (const char * role ACE_ENV_ARG_DECL) +{ + int result = 0; + ACE_ERROR ( (LM_INFO, + "%T %n (%P|%t) Object_Group_Creator: Unregistering all factories for %s\n", + role + )); + this->registry_->unregister_factory_by_role (role ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + return result; +} + + + +int TAO::Object_Group_Creator::create_detector_for_replica ( + CORBA::Object_ptr replica, + const char * role, + const char * type_id, + PortableGroup::ObjectGroupId group_id, + const PortableGroup::Location & location + ACE_ENV_ARG_DECL) +{ + int result = 0; + + if (this->have_replication_manager_) + { + CORBA::ULong detector_count = this->detector_infos_->length (); + for (CORBA::ULong n_detector = 0; result == 0 && n_detector < detector_count; ++n_detector) + { + PortableGroup::FactoryInfo & info = (*this->detector_infos_)[n_detector]; + if ( info.the_location == location || n_detector + 1 == detector_count) + { + TAO_PG::Properties_Encoder encoder; + + PortableGroup::Value value; + + FT::PullMonitorable_ptr monitorable = FT::PullMonitorable::_narrow (replica); + value <<= monitorable; + encoder.add (::FT::FT_MONITORABLE, value); + + FT::FTDomainId domain_id = 0; + value <<= domain_id; + encoder.add (::FT::FT_DOMAIN_ID, value); + + value <<= location; + encoder.add (::FT::FT_LOCATION, value); + + value <<= type_id; + encoder.add (::FT::FT_TYPE_ID, value); + + value <<= group_id; + encoder.add (::FT::FT_GROUP_ID, value); + + value <<= CORBA::string_dup (role); + encoder.add (PortableGroup::role_criterion, value); + + // allocate and populate the criteria + PortableGroup::Criteria_var criteria; + ACE_NEW_NORETURN (criteria, + PortableGroup::Criteria); + if (criteria.ptr () == 0) + { + ACE_ERROR ( (LM_ERROR, + "%T %n (%P|%t)Object_Group_Creater: Error cannot allocate criteria.\n" + )); + result = -1; + } + else + { + encoder.encode (criteria); + PortableGroup::GenericFactory::FactoryCreationId_var factory_creation_id; + + info.the_factory->create_object ( + type_id, + criteria.in (), + factory_creation_id + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + result = 1; + } + } + } + } + return result; +} + + +CORBA::Object_ptr TAO::Object_Group_Creator::create_infrastructure_managed_group ( + const char * type_id + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ( (CORBA::SystemException )) +{ + CORBA::Object_var group = CORBA::Object::_nil (); + + PortableGroup::ObjectGroupId group_id = 0; + + if (this->have_replication_manager_) + { + // set typeid properties + PortableGroup::Properties properties (1); + properties.length (3); + + properties[0].nam.length (1); + properties[0].nam[0].id = PortableGroup::PG_MEMBERSHIP_STYLE; + properties[0].val <<= PortableGroup::MEMB_INF_CTRL; + + PortableGroup::InitialNumberMembersValue inm(2); + properties[1].nam.length (1); + properties[1].nam[0].id = PortableGroup::PG_INITIAL_NUMBER_MEMBERS; + properties[1].val <<= inm; + + PortableGroup::MinimumNumberMembersValue mnm(1); + properties[2].nam.length (1); + properties[2].nam[0].id = PortableGroup::PG_MINIMUM_NUMBER_MEMBERS; + properties[2].val <<= mnm; + + this->replication_manager_->set_type_properties ( + type_id, + properties + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (group._retn ()); + + ::PortableGroup::GenericFactory::FactoryCreationId_var creation_id; + PortableGroup::Criteria criteria (1); + criteria.length (1); + criteria[0].nam.length (1); + criteria[0].nam[0].id = PortableGroup::PG_MEMBERSHIP_STYLE; + criteria[0].val <<= PortableGroup::MEMB_APP_CTRL; + + group = this->replication_manager_->create_object ( + type_id, + criteria, + creation_id + ACE_ENV_ARG_PARAMETER + ); + ACE_CHECK_RETURN (CORBA::Object::_nil ()); + } + else + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT("%T %n (%P|%t): Object_Group_Creator: infrastructure managed group requires Replication Manager\n") + )); + } + return group._retn (); +} + +CORBA::Object_ptr TAO::Object_Group_Creator::create_group ( + const char * role, + int write_iors + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ( (CORBA::SystemException )) +{ + CORBA::Object_var group = CORBA::Object::_nil (); + + PortableGroup::ObjectGroupId group_id = 0; + CORBA::String_var type_id; + ::PortableGroup::FactoryInfos_var infos = this->registry_->list_factories_by_role (role, type_id + ACE_ENV_ARG_PARAMETER) + ACE_CHECK_RETURN (CORBA::Object::_nil ()); + + CORBA::ULong count = infos->length (); + ACE_ERROR ( (LM_INFO, + ACE_TEXT("%T %n (%P|%t): Object_Group_Creator: found %u factories for %s : %s\n"), + ACE_static_cast (unsigned, count), + role, + ACE_static_cast (const char *, type_id) + )); + + if (count > 0) + { + /////////////////////////// + // Begin with an empty IOGR + ::PortableGroup::GenericFactory::FactoryCreationId_var creation_id; + if (this->have_replication_manager_) + { + + ////////////////////////////////////////////////////// + // note infrastructure controlled because we want the + // ReplicationManager to manage the object after it's created. + // Initial number members = 0 because we do not want the Replication + // Manager to populate the group. + // Minimum number of members = 0 because we do not want the + // Replication Manager to replace failed members. + // Semi-active, because that's what we do. + PortableGroup::Criteria criteria (3); + criteria.length (4); + criteria[0].nam.length (1); + criteria[0].nam[0].id = PortableGroup::PG_MEMBERSHIP_STYLE; + criteria[0].val <<= PortableGroup::MEMB_INF_CTRL; + + criteria[1].nam.length (1); + criteria[1].nam[0].id = PortableGroup::PG_INITIAL_NUMBER_MEMBERS; + criteria[1].val <<= PortableGroup::InitialNumberMembersValue (0); + + criteria[2].nam.length (1); + criteria[2].nam[0].id = PortableGroup::PG_MINIMUM_NUMBER_MEMBERS; + criteria[2].val <<= PortableGroup::MinimumNumberMembersValue (0); + + criteria[3].nam.length (1); + criteria[3].nam[0].id = FT::FT_REPLICATION_STYLE; + criteria[3].val <<= FT::SEMI_ACTIVE; + + group = this->replication_manager_->create_object ( + type_id.in (), + criteria, + creation_id + ACE_ENV_ARG_PARAMETER + ); + ACE_CHECK_RETURN (CORBA::Object::_nil ()); + + //@@ this is a bit of a hack + creation_id >>= group_id; + + } + + const PortableGroup::Location * first_location = 0; + + for (CORBA::ULong nFact = 0; nFact < count; ++nFact) + { + ::PortableGroup::FactoryInfo & info = infos[nFact]; + + const char * loc_name = info.the_location[0].id; + ACE_ERROR ( (LM_INFO, + "%T %n (%P|%t) Object_Group_Creator: Creating %s@%s\n", + role, + loc_name + )); + + PortableGroup::GenericFactory::FactoryCreationId_var factory_creation_id; + CORBA::Object_var created_obj = info.the_factory->create_object ( + type_id.in (), + info.the_criteria, + factory_creation_id.out () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (CORBA::Object::_nil ()); + if ( !CORBA::is_nil (created_obj.in ()) ) + { +// that which was first shall now be last if (nFact == 0) + { + first_location = & info.the_location; + } + + // try to create a detector, but don't worry if it doesn't happen + (void) create_detector_for_replica ( + created_obj.in (), + role, + type_id.in (), + group_id, + info.the_location + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (CORBA::Object::_nil ()); + + const char * replica_ior = orb_->object_to_string (created_obj.in () ACE_ENV_ARG_PARAMETER ); + ACE_CHECK_RETURN (CORBA::Object::_nil ()); + + + if (write_iors) + { + //////////////////////////////////// + // Somewhat of a hack + // guess at role of factory creation id + CORBA::ULong ulong_id = 0; + CORBA::Long long_id = 0; + if (factory_creation_id >>= ulong_id) + { + // ok + } + else if (factory_creation_id >>= long_id) + { + ulong_id = ACE_static_cast (CORBA::ULong, long_id); + } + else + { + ACE_ERROR ( (LM_ERROR, + "%T %n (%P|%t) Object_Group_Creator: Can't decypher factory creation id.\n" + )); + // Guessed wrong. Just use default value + } + + char replica_ior_filename[200]; // "${role}_$ (location)_${factory_id}.ior" + + ACE_OS::snprintf (replica_ior_filename, sizeof (replica_ior_filename)-1, "%s_%s_%lu.ior", + role, + loc_name, + ACE_static_cast (unsigned long, ulong_id)); + replica_ior_filename[sizeof (replica_ior_filename)-1] = '\0'; + + ACE_ERROR ( (LM_INFO, + "%T %n (%P|%t) Object_Group_Creator: Writing ior for created object to %s\n", + replica_ior_filename + )); + + if (write_ior_file (replica_ior_filename, replica_ior) != 0) + { + ACE_ERROR ( (LM_ERROR, + "%T %n (%P|%t) Object_Group_Creator: Error writing ior [%s] to %s\n", + replica_ior, + replica_ior_filename + )); + } + } + + if (this->have_replication_manager_) + { + group = this->replication_manager_->add_member ( + group.in (), + info.the_location, + created_obj.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (CORBA::Object::_nil ()); + } + } + else + { + ACE_ERROR ( (LM_ERROR, + "%T %n (%P|%t) Object_Group_Creator: create_object returned nil????\n" + )); + } + } + + if (first_location != 0 && this->have_replication_manager_) + { + group = this->replication_manager_->set_primary_member (group.in (), * first_location ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (CORBA::Object::_nil ()); + } + ACE_ERROR ( (LM_INFO, + "%T %n (%P|%t) Object_Group_Creator: Successfully created group of %s\n", + role + )); + } + + return group._retn (); +} + + +int TAO::Object_Group_Creator::fini () +{ + return 0; +} + +int TAO::Object_Group_Creator::write_ior_file (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, + "%T %n (%P|%t) Object_Group_Creator: Open failed for %s\n", outputFile + )); + } + return result; +} + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) +// template ACE_Vector<ACE_CString>; +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +//# pragma instantiate ACE_Vector<ACE_CString> +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/orbsvcs/tests/FT_App/TAO_Object_Group_Creator.h b/TAO/orbsvcs/tests/FT_App/TAO_Object_Group_Creator.h new file mode 100644 index 00000000000..5bf6c6aae58 --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/TAO_Object_Group_Creator.h @@ -0,0 +1,108 @@ +/* -*- C++ -*- */ +//============================================================================= +/** + * @file TAO_Object_Group_Creator.h + * + * $Id$ + * + * This file is part of Fault Tolerant CORBA. + * Utility to Create Object Group + * + * @author Dale Wilson <wilson_d@ociweb.com> + */ +//============================================================================= + +#ifndef TAO_OBJECT_GROUP_CREATOR_H +#define TAO_OBJECT_GROUP_CREATOR_H +#include <ace/ACE.h> + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include <orbsvcs/FT_ReplicationManagerC.h> +#include <orbsvcs/PortableGroupC.h> +#include <ace/SString.h> +#include <ace/Vector_T.h> + +namespace TAO +{ + class Object_Group_Creator + { + typedef ACE_Vector<ACE_CString> StringVec; + public: + /////////////////////////// + // construction/destruction + Object_Group_Creator (); + + ~Object_Group_Creator (); + + ///////////////// + // pre-init methods + int set_factory_registry (PortableGroup::FactoryRegistry_ptr factory); + + ///////////////// + // initialization + int init (CORBA::ORB_ptr orb ACE_ENV_ARG_DECL); + + ///////////////// + // functionality + CORBA::Object_ptr create_group( + const char * role, + int write_iors + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)); + + ///////////////// + // functionality + CORBA::Object_ptr create_infrastructure_managed_group( + const char * type_id + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)); + + int unregister_role(const char * role ACE_ENV_ARG_DECL); + + //////////// + // shut down + int fini (); + + ///////////////// + // implementation + private: + int write_ior_file(const char * outputFile, const char * ior); + + int create_detector_for_replica ( + CORBA::Object_ptr replica, + const char * role, + const char * type_id, + PortableGroup::ObjectGroupId group_id, + const PortableGroup::Location & location + ACE_ENV_ARG_DECL); + + //////////////////// + // forbidden methods + private: + Object_Group_Creator (const Object_Group_Creator & rhs); + Object_Group_Creator & operator = (const Object_Group_Creator & rhs); + + //////////////// + // Data members + private: + CORBA::ORB_var orb_; + PortableGroup::FactoryRegistry_var registry_; + + ::FT::ReplicationManager_var replication_manager_; + + ::PortableGroup::FactoryInfos_var detector_infos_; + CORBA::String_var detector_type_id_; + + + /** + * bool: true if we have a real replication manager + */ + int have_replication_manager_; + }; + +} // namespace TAO + +#endif // TAO_OBJECT_GROUP_CREATOR_H diff --git a/TAO/orbsvcs/tests/FT_App/replica.cmd b/TAO/orbsvcs/tests/FT_App/replica.cmd new file mode 100755 index 00000000000..6c242ad4a00 --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/replica.cmd @@ -0,0 +1,9 @@ +@if "%1a" == "a" goto error +@if "%2a" == "a" goto error +release\ft_replica -o %1.ior -q -f none -l %1 -i %2 %3 %4 %5 %6 %7 %8 %9 +@goto end +@:error +@echo Usage %0 location role [options] +@:end +pause +exit diff --git a/TAO/orbsvcs/tests/FT_App/run_test_basic.pl b/TAO/orbsvcs/tests/FT_App/run_test_basic.pl new file mode 100755 index 00000000000..dea17745fb6 --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/run_test_basic.pl @@ -0,0 +1,107 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ +# -*- perl -*- + +use lib '../../../../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 + +foreach $i (@ARGV) { + if ($i eq "--debug_build") + { + $debug_builds = 1; + } + 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"; +} + +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($data_file) = PerlACE::LocalFile ("persistent.dat"); + +unlink $factory1_ior; +unlink $factory2_ior; +unlink $replica1_ior; +unlink $replica2_ior; +unlink $data_file; +my($status) = 0; + +my($SV1) = new PerlACE::Process ("./$build_directory/ft_replica", "-o $factory1_ior -t $replica1_ior -q -f none"); +my($SV2) = new PerlACE::Process ("./$build_directory/ft_replica", "-o $factory2_ior -t $replica2_ior -q -f none"); +my($CL) = new PerlACE::Process ("./$build_directory/ft_client", "-f file://$replica1_ior -f file://$replica2_ior -c testscript"); + +print "\nTest: Starting replica 1 " . $SV1->CommandLine . "\n" if ($verbose); +$SV1->Spawn (); + +print "waiting for replica 1's IOR\n" if ($verbose); + +if (PerlACE::waitforfile_timed ($replica1_ior, 5) == -1) { + print STDERR "TEST ERROR: cannot find replica 1 file <$replica1_ior>\n"; + $SV1->Kill (); $SV1->TimedWait (1); + exit 1; +} + +print "\nTest: Starting replica 2 " . $SV2->CommandLine . "\n" if ($verbose); +$SV2->Spawn (); + +print "waiting for replica 2's IOR\n" if ($verbose); +if (PerlACE::waitforfile_timed ($replica2_ior, 5) == -1) { + print STDERR "TEST ERROR: cannot find replica 2 file <$replica2_ior>\n"; + $SV1->Kill (); $SV1->TimedWait (1); + $SV2->Kill (); $SV2->TimedWait (1); + exit 1; +} + +print "\nTest: Starting client " . $CL->CommandLine . "\n" if ($verbose); + +$client = $CL->SpawnWaitKill (60); + +if ($client != 0) { + print STDERR "TEST ERROR: client returned $client\n"; + $status = 1; +} + +print "wait for server 1.\n" if ($verbose); +$server = $SV1->WaitKill (60); + +print "wait for server 2.\n" if ($verbose); +$server = $SV2->WaitKill (60); + +if ($server != 0) { + print STDERR "TEST ERROR: server returned $server\n"; + $status = 1; +} + +if ($status == 0) { +print "Clean up scratch files\n" if ($verbose); + +unlink $factory1_ior; +unlink $factory2_ior; +unlink $replica1_ior; +unlink $replica2_ior; +unlink $data_file; +} + +exit $status; diff --git a/TAO/orbsvcs/tests/FT_App/run_test_demo.pl b/TAO/orbsvcs/tests/FT_App/run_test_demo.pl new file mode 100755 index 00000000000..eb18a88023a --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/run_test_demo.pl @@ -0,0 +1,433 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ +# -*- perl -*- + +# Purpose: +# Integration test for all FT services. +# +# Command line options: +# --debug_build use exes from this directory +# if not specified use exes from ./release +# --no_simulate +# use real IOGR-based recovery. +# -v display test progress messages (repeating option increases verbosity +# Process being tested: +# FT_ReplicationManager +# Fault_Detector +# Fault_Notifier +# +# Processes used in test: +# FT_Replica * 3 +# implements GenericFactory interface to create TestReplicas +# TestReplica implements TestReplica interface. +# TestReplica implements PullMonitorable interface. +# FT_Client +# client for TestReplica interface. +# client for PullMonitorable. +# Object Group Creator +# Creates groups of objects. +# +# Test Scenario +# +# 1) Start the ReplicationManager (RM), +# 2) Start the Fault Notification Server(FN) +# 2.1) FN registers with RM. +# 2.2) RM registers as consumer with FN +# 3) Start FaultDetectorFactory at location shire (FD@shire) +# 3.1) FD@shire registers with RM +# 4) Start FaultDetectorFactory at location bree (FD@bree) +# 4.1) FD@bree registers with RM +# 5) Start Replica Factory at location shire (RF@shire) that can create hobbits +# 5.1) RF@shire registers with RM to create hobbit@shire +# 6) Start Replica Factory at location bree (RF@bree) that can create hobbits and elves. +# 6.1) RF@bree registers with RM to create hobbit@bree +# 6.1) RF@bree registers with RM to create elf@bree +# 6) Start Replica Factory at location rivendell (RF@rivendell) that can create elves. +# 6.1) RF@bree registers with RM to create elf@rivendell +# 7) Start ObjectGroupCreator (OGC) +# 7.1) OGC calls RM to create group of hobbits (IOGR1) +# 7.1.1) OGC calls RF@shire to create hobbit@shire[1] +# 7.1.1.1) OGC calls FD@shire to create FaultDetector for hobbit@shire[1] +# 7.1.1.2) OGC adds hobbit@shire[1] to IOGR1. +# 7.1.2) OGC calls RF@bree to craate hobbit@bree[1] +# 7.1.2.1) OGC calls FD@bree to create FaultDetector for hobbit@bree[1] +# 7.1.2.2) OGC adds hobbit@bree[1] to IOGR1. +# 7.2) OGC calls RM to create group of elves (IOGR2) +# 7.2.1) OGC calls RF@bree to create elf@bree[2] +# 7.2.1.1) OGC calls FD@bree to create FaultDetector for elf@bree[2] +# 7.2.1.2) OGC adds elf@bree[2] to IOGR2. +# 7.2.2) OGC calls RF@rivendell to create elf@rivendell[1] +# 7.2.2.1) OGC calls FD@shire to create FaultDetector for elf@rivendell[1] +# 7.2.2.2) OGC adds elf@rivendell[1] to IOGR2. +# 7.3) OGC calls RM to create group of hobbits (IOGR3) +# 7.3.1) OGC calls RF@shire to create hobbit@shire[2] +# 7.3.1.1) OGC calls FD@shire to create FaultDetector for hobbit@shire[2] +# 7.3.1.2) OGC adds hobbit@shire[2] to IOGR2. +# 7.3.2) OGC calls RF@bree to craate hobbit@bree[3] +# 7.3.2.1) OGC calls FD@bree to create FaultDetector for hobbit@bree[3] +# 7.3.2.2) OGC adds hobbit@bree[3] to IOGR3. +# 8) Start client1 with IOGR1 +# 8.1) Hobbit@shire[1] fails. FD sends notification FN. +# 8.1.1) FN sends notification to RM. +# 8.1.2) RM removes hobbit@shire[1] from IOGR1. +# 8.2) Client1 terminates itself and hobbit@bree[1]. +# 9) Start Cient2 with IOGR2. +# 9.1) Repeat 8.1 & 8.2 using IOGR3. +# 10) Start Cient3 with IOGR3. +# 10.1) Repeat 8.1 & 8.2 using IOGR3. +# 11) System manages to shut itself down. + +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"; +} + +my($role1) = "hobbit"; +my($role2) = "elf"; + +my($location1) = "shire"; +my($location2) = "bree"; +my($location3) = "rivendell"; + +my ($rm_endpoint) = "-ORBEndpoint iiop://localhost:2833"; +my ($rm_initref) = "-ORBInitRef ReplicationManager=corbaloc::localhost:2833/ReplicationManager"; + +#define temp files +my($rm_ior) = PerlACE::LocalFile ("rm.ior"); +my($notifier_ior) = PerlACE::LocalFile ("notifier.ior"); +my($detector1_ior) = PerlACE::LocalFile ("detector1.ior"); +my($detector2_ior) = PerlACE::LocalFile ("detector2.ior"); +my($factory1_ior) = PerlACE::LocalFile ("factory1.ior"); +my($factory2_ior) = PerlACE::LocalFile ("factory2.ior"); +my($factory3_ior) = PerlACE::LocalFile ("factory3.ior"); +my($replica1_ior) = PerlACE::LocalFile ("${role1}_${location1}_0.ior"); +my($replica2_ior) = PerlACE::LocalFile ("${role1}_${location2}_0.ior"); +my($replica3_ior) = PerlACE::LocalFile ("${role2}_${location2}_1.ior"); +my($replica4_ior) = PerlACE::LocalFile ("${role2}_${location3}_0.ior"); +my($replica5_ior) = PerlACE::LocalFile ("${role1}_${location1}_1.ior"); +my($replica6_ior) = PerlACE::LocalFile ("${role1}_${location2}_2.ior"); + +my($replica1_iogr) = PerlACE::LocalFile ("${role1}_0.iogr"); +my($replica2_iogr) = PerlACE::LocalFile ("${role2}_1.iogr"); +my($replica3_iogr) = PerlACE::LocalFile ("${role1}_2.iogr"); + +my($client_data) = PerlACE::LocalFile ("persistent.dat"); + +#discard junk from previous tests +unlink $rm_ior; +unlink $notifier_ior; +unlink $detector1_ior; +unlink $detector2_ior; +unlink $factory1_ior; +unlink $factory2_ior; +unlink $factory3_ior; +unlink $replica1_ior; +unlink $replica2_ior; +unlink $replica3_ior; +unlink $replica4_ior; +unlink $replica5_ior; +unlink $replica6_ior; +unlink $replica1_iogr; +unlink $replica2_iogr; + +unlink $client_data; + +my($status) = 0; + +my($RM) = new PerlACE::Process ("$ENV{'TAO_ROOT'}/orbsvcs/FT_ReplicationManager$build_directory/FT_ReplicationManager", "-o $rm_ior $rm_endpoint"); +my($RMC) = new PerlACE::Process (".$build_directory/replmgr_controller", "$rm_initref -x"); +my($NOT) = new PerlACE::Process ("$ENV{'TAO_ROOT'}/orbsvcs/Fault_Notifier$build_directory/Fault_Notifier", "$rm_initref -o $notifier_ior -q"); +my($DET1) = new PerlACE::Process ("$ENV{'TAO_ROOT'}/orbsvcs/Fault_Detector$build_directory/Fault_Detector", "$rm_initref -o $detector1_ior -l $location1 -q"); +my($DET2) = new PerlACE::Process ("$ENV{'TAO_ROOT'}/orbsvcs/Fault_Detector$build_directory/Fault_Detector", "$rm_initref -o $detector2_ior -l $location2 -q"); +my($FAC1) = new PerlACE::Process (".$build_directory/ft_replica", "$rm_initref -o $factory1_ior -l $location1 -i $role1 -q"); +my($FAC2) = new PerlACE::Process (".$build_directory/ft_replica", "$rm_initref -o $factory2_ior -l $location2 -i $role1 -i $role2 -q"); +my($FAC3) = new PerlACE::Process (".$build_directory/ft_replica", "$rm_initref -o $factory3_ior -l $location3 -i $role2 -q"); + +my($OGC); +my($CL1); +my($CL2); +my($CL3); +if ($simulated) { + print "\nTEST: Preparing Client Mediated Fault Tolerance test.\n" if ($verbose); + $OGC= new PerlACE::Process (".$build_directory/ft_create", "$rm_initref -r $role1 -r $role2 -r $role1 -i -n"); + $CL1 = new PerlACE::Process (".$build_directory/ft_client", "-f file://$replica1_ior -f file://$replica2_ior -c testscript"); + $CL2 = new PerlACE::Process (".$build_directory/ft_client", "-f file://$replica3_ior -f file://$replica4_ior -c testscript"); + $CL3 = new PerlACE::Process (".$build_directory/ft_client", "-f file://$replica5_ior -f file://$replica6_ior -c testscript"); +}else{ + print "\nTEST: Preparing IOGR based test.\n" if ($verbose); + $OGC = new PerlACE::Process (".$build_directory/ft_create", "$rm_initref -r $role1 -r $role2 -r $role1 -g -n"); + $CL1 = new PerlACE::Process (".$build_directory/ft_client", "-f file://$replica1_iogr -c testscript"); + $CL2 = new PerlACE::Process (".$build_directory/ft_client", "-f file://$replica2_iogr -c testscript"); + $CL3 = new PerlACE::Process (".$build_directory/ft_client", "-f file://$replica3_iogr -c testscript"); +} + +####################### +# Start ReplicationManager + +print "\nTEST: Starting ReplicationManager " . $RM->CommandLine . "\n" if ($verbose); +$RM->Spawn (); + +print "TEST: waiting for registry's IOR\n" if ($verbose); +if (PerlACE::waitforfile_timed ($rm_ior, 5) == -1) { + print STDERR "TEST ERROR: cannot find file <$rm_ior>\n"; + $RM->Kill (); $RM->TimedWait (1); + exit 1; +} + +####################### +# Start FaultNotifier +print "\nTEST: Starting FaultNotifier " . $NOT->CommandLine . "\n" if ($verbose); +$NOT->Spawn (); + +print "TEST: waiting for FaultNotifier's IOR\n" if ($verbose); +if (PerlACE::waitforfile_timed ($notifier_ior, 5) == -1) { + print STDERR "TEST ERROR: cannot find file <$notifier_ior>\n"; + $RM->Kill (); $RM->TimedWait (1); + $NOT->Kill (); $NOT->TimedWait (1); + exit 1; +} + + +############################## +# Start FaultDetectorFactory 1 +print "\nTEST: Starting FaultDetectorFactory at $location1 " . $DET1->CommandLine . "\n" if ($verbose); +$DET1->Spawn (); + +print "TEST: waiting for FaultDetector's IOR\n" if ($verbose); +if (PerlACE::waitforfile_timed ($detector1_ior, 5) == -1) { + print STDERR "TEST ERROR: cannot find file <$detector1_ior>\n"; + $RM->Kill (); $RM->TimedWait (1); + $NOT->Kill (); $NOT->TimedWait (1); + $DET1->Kill (); $DET1->TimedWait (1); + exit 1; +} + +############################## +# Start FaultDetectorFactory 2 +print "\nTEST: Starting FaultDetectorFactory at $location2 " . $DET2->CommandLine . "\n" if ($verbose); +$DET2->Spawn (); + +print "TEST: waiting for FaultDetector's IOR\n" if ($verbose); +if (PerlACE::waitforfile_timed ($detector2_ior, 5) == -1) { + print STDERR "TEST ERROR: cannot find file <$detector2_ior>\n"; + $RM->Kill (); $RM->TimedWait (1); + $NOT->Kill (); $NOT->TimedWait (1); + $DET1->Kill (); $DET1->TimedWait (1); + $DET2->Kill (); $DET2->TimedWait (1); + exit 1; +} + + +################# +# Start Factories + +print "\nTEST: Starting replica factory at $location1 " . $FAC1->CommandLine . "\n" if ($verbose); +$FAC1->Spawn (); + +print "TEST: waiting for factory 1's IOR\n" if ($verbose); +if (PerlACE::waitforfile_timed ($factory1_ior, 5) == -1) { + print STDERR "TEST ERROR: cannot find file <$factory1_ior>\n"; + $RM->Kill (); $RM->TimedWait (1); + $NOT->Kill (); $NOT->TimedWait (1); + $DET1->Kill (); $DET1->TimedWait (1); + $DET2->Kill (); $DET2->TimedWait (1); + $FAC1->Kill (); $FAC1->TimedWait (1); + exit 1; +} + +print "\nTEST: Starting replica factory at $location2 " . $FAC2->CommandLine . "\n" if ($verbose); +$FAC2->Spawn (); + +print "TEST: waiting for factory 2's IOR\n" if ($verbose); +if (PerlACE::waitforfile_timed ($factory2_ior, 5) == -1) { + print STDERR "TEST ERROR: cannot find file <$factory2_ior>\n"; + $RM->Kill (); $RM->TimedWait (1); + $NOT->Kill (); $NOT->TimedWait (1); + $DET1->Kill (); $DET1->TimedWait (1); + $DET2->Kill (); $DET2->TimedWait (1); + $FAC1->Kill (); $FAC1->TimedWait (1); + $FAC2->Kill (); $FAC2->TimedWait (1); + exit 1; +} + +print "\nTEST: Starting replica factory at $location3 " . $FAC3->CommandLine . "\n" if ($verbose); +$FAC3->Spawn (); + +print "TEST: waiting for factory 3's IOR\n" if ($verbose); +if (PerlACE::waitforfile_timed ($factory3_ior, 5) == -1) { + print STDERR "TEST ERROR: cannot find file <$factory3_ior>\n"; + $RM->Kill (); $RM->TimedWait (1); + $NOT->Kill (); $NOT->TimedWait (1); + $DET1->Kill (); $DET1->TimedWait (1); + $DET2->Kill (); $DET2->TimedWait (1); + $FAC1->Kill (); $FAC1->TimedWait (1); + $FAC2->Kill (); $FAC2->TimedWait (1); + $FAC3->Kill (); $FAC3->TimedWait (1); + exit 1; +} + +###################### +# Create object groups + +print "\nTEST: Starting object group creator " . $OGC->CommandLine . "\n" if ($verbose); +$OGC->Spawn (); + +print "\nTEST: wait for object group creator.\n" if ($verbose); +$config = $OGC->WaitKill (30); +if ($config != 0) { + print STDERR "TEST ERROR: Object Group Creator returned $config\n"; + $RM->Kill (); $RM->TimedWait (1); + $NOT->Kill (); $NOT->TimedWait (1); + $DET1->Kill (); $DET1->TimedWait (1); + $DET2->Kill (); $DET2->TimedWait (1); + $FAC1->Kill (); $FAC1->TimedWait (1); + $FAC2->Kill (); $FAC2->TimedWait (1); + $FAC3->Kill (); $FAC3->TimedWait (1); + exit 1; +} + +############# +# Run clients + +print "\nTEST: Starting client using first group of hobbits " . $CL1->CommandLine . "\n" if ($verbose); +$client = $CL1->SpawnWaitKill (60); + +if ($client != 0) { + print STDERR "TEST ERROR: client returned $client\n"; + $status = 1; +} + +print "\nTEST: Starting client using group of elves " . $CL2->CommandLine . "\n" if ($verbose); +$client2 = $CL2->SpawnWaitKill (60); + +if ($client2 != 0) { + print STDERR "TEST ERROR: client returned $client2\n"; + $status = 1; +} + +print "\nTEST: Starting client using second group of hobbits " . $CL3->CommandLine . "\n" if ($verbose); +$client3 = $CL3->SpawnWaitKill (60); + +if ($client3 != 0) { + print STDERR "TEST ERROR: client returned $client3\n"; + $status = 1; +} + +###################### +# Clean house and exit + +print "\nTEST: wait for factory 1.\n" if ($verbose); +$factory1 = $FAC1->WaitKill (30); +if ($factory1 != 0) { + print STDERR "TEST ERROR: replica returned $factory 1\n"; + $status = 1; +} + +print "\nTEST: wait for factory 2.\n" if ($verbose); +$factory2 = $FAC2->WaitKill (30); +if ($factory2 != 0) { + print STDERR "TEST ERROR: factory 2 returned $factory2\n"; + $status = 1; +} + +print "\nTEST: wait for factory 3.\n" if ($verbose); +$factory3 = $FAC3->WaitKill (30); +if ($factory3 != 0) { + print STDERR "TEST ERROR: factory 3 returned $factory3\n"; + $status = 1; +} + +print "\nTEST: wait for FaultDetectorFactory 1.\n" if ($verbose); +$detector1 = $DET1->WaitKill (30); +if ($detector1 != 0) { + print STDERR "TEST ERROR: FaultDetectorFactory returned $detector1\n"; + $status = 1; +} + +print "\nTEST: wait for FaultDetectorFactory 2.\n" if ($verbose); +$detector2 = $DET2->WaitKill (30); +if ($detector2 != 0) { + print STDERR "TEST ERROR: FaultDetectorFactory returned $detector2\n"; + $status = 1; +} + +print "\nTEST: shutting down the replication manager.\n" if ($verbose); +$controller = $RMC->SpawnWaitKill (300); +if ($controller != 0) { + print STDERR "TEST ERROR: replication manager controller returned $controller\n"; + $status = 1; +} + +print "\nTEST: wait for ReplicationManager.\n" if ($verbose); +#$RM->Kill (); +$repmgr = $RM->WaitKill (30); +if ($repmgr != 0) { + print STDERR "TEST ERROR: ReplicationManager returned $repmgr\n"; + $status = 1; +} + +print "\nTEST: wait for FaultNotifier.\n" if ($verbose); +$notifier = $NOT->WaitKill (30); +if ($notifier != 0) { + print STDERR "TEST ERROR: FaultNotifier returned $notifier\n"; + $status = 1; +} + +if ($status == 0 && 0) { + print "\nTEST: releasing scratch files.\n" if ($verbose); + unlink $rm_ior; + unlink $detector1_ior; + unlink $detector2_ior; + unlink $notifier_ior; + unlink $factory1_ior; + unlink $factory2_ior; + unlink $factory3_ior; + unlink $replica1_ior; + unlink $replica2_ior; + unlink $replica3_ior; + unlink $replica4_ior; + unlink $replica5_ior; + unlink $replica6_ior; + unlink $replica1_iogr; + unlink $replica2_iogr; + + unlink $client_data; +} + + +exit $status; diff --git a/TAO/orbsvcs/tests/FT_App/run_test_detector.pl b/TAO/orbsvcs/tests/FT_App/run_test_detector.pl new file mode 100755 index 00000000000..f7886fb6dab --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/run_test_detector.pl @@ -0,0 +1,221 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ +# -*- perl -*- + +# Purpose: +# To test the FaultDetectorFactory and FaultDetectors +# +# Command line options: +# --debug_build use exes from this directory +# if not specified use exes from ./release +# -v display test progress messages (repeating option increases verbosity +# +# Process being tested: +# Fault_Detector +# implements FaultDetectorFactory interface +# implements PullMonitorable interface +# +# Processes used in test: +# FT_Replica +# implements TestReplica interface. +# implements PullMonitorable. +# StubNotifier +# implements FaultNotifier interface (as a stub.) +# implements PullMonitorable. +# client for FaultDetectorFactory interface. +# FT_Client +# client for TestReplica interface. +# client for PullMonitorable. +# +# Test Scenario ( ***Test: marks behavior being tested): +# 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 +# Wait for IORs: FR#1, FR#2, and FDF +# Start the StubNotifier giving it IORS: FR#1, FR#2 and FDF +# StubNotifier calls FDF to create a FaultDetector +# for each Replica. +# StubNotifier writes FaultNotifier IOR (FN) to a file. +# Wait for IOR: FN +# Start FT_Client giving it IORS: FR#1 and FR#2. +# 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. +# ***Test: FD#1 notices fault and notifies StubNotifier +# ***Test: FD#1 terminates +# FT_Client interacts with FR#2. +# FT_Client asks FR#2 to shut down. +# FT_Client shuts down. +# ***Test: FD#2 notices FR2 is gone, interprets this +# as a fault, and notifies StubNotifier. +# ***Test: FD#2 terminates. +# Shut down +# ***Test: FDF is idle, so it terminates. +# StubNotifier sees FDF terminate, so it terminates +# Cleanup +# Wait for all processes to terminate. +# Check termination status. +# Delete temp files. +# +use lib '../../../../bin'; +use PerlACE::Run_Test; + +######################## +#command line options +#set defaults: +my($verbose) = 0; # 1: report perl actions before executing them; 2 display settings from command line +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 "-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($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 #client_data + +my($status) = 0; + +my ($rm_endpoint) = "-ORBEndpoint iiop://localhost:2833"; +my ($rm_initref) = "-ORBInitRef ReplicationManager=corbaloc::localhost:2833/ReplicationManager"; + + +my($REP1) = new PerlACE::Process (".$build_directory/ft_replica", "-o $factory1_ior -f none -t $replica1_ior -l loc1 -i type1 -q"); +my($REP2) = new PerlACE::Process (".$build_directory/ft_replica", "-o $factory2_ior -f none -t $replica2_ior -l loc2 -i type1 -q"); +my($DET) = new PerlACE::Process ("$ENV{'TAO_ROOT'}/orbsvcs/Fault_Detector$build_directory/Fault_Detector", "$rm_initref -o $detector_ior -q"); +my($NOT) = new PerlACE::Process (".$build_directory/ft_notifier", "-o $notifier_ior -q -d file://$detector_ior -r file://$replica1_ior -r file://$replica2_ior"); +my($CL) = new PerlACE::Process (".$build_directory/ft_client", "-f file://$replica1_ior -f file://$replica2_ior -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 "TEST 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 "TEST 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 "TEST 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 "TEST ERROR: cannot find file <$notifier_ior>\n"; + $REP1->Kill (); $REP1->TimedWait (1); + $REP2->Kill (); $REP2->TimedWait (1); + $DET->Kill (); $DET2->TimedWait(1); + $NOT->Kill (); $NOT->TimedWait(1); + exit 1; +} + +print "\nTEST: starting client." . $CL->CommandLine . "\n" if ($verbose); +$client = $CL->SpawnWaitKill (60); + +if ($client != 0) { + print STDERR "TEST 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 "TEST 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 "TEST 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 "TEST 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 "TEST ERROR: notifier returned $notifier\n"; + $status = 1; +} + +print "\nTEST: releasing scratch files.\n" if ($verbose); +unlink $factory1_ior; +unlink $factory2_ior; +unlink $replica1_ior; +unlink $replica2_ior; +unlink $detector_ior; +unlink $notifier_ior; + +#client's work file +unlink #client_data; + +exit $status; diff --git a/TAO/orbsvcs/tests/FT_App/run_test_fault_consumer.pl b/TAO/orbsvcs/tests/FT_App/run_test_fault_consumer.pl new file mode 100755 index 00000000000..bfb3f98db2a --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/run_test_fault_consumer.pl @@ -0,0 +1,270 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ +# -*- perl -*- + +# Purpose: +# To test the FaultConsumer +# +# Process being tested: +# Fault_Consumer +# implements FaultConsumer 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. +# Fault_Notifier +# implements the FaultNotifier interface. +# propagates fault reports to the FaultConsumer. +# +# 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. +# Start the Fault_Consumer +# Subscribes to the Fault_Notifier for fault reports. +# 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 ($rm_endpoint) = "-ORBEndpoint iiop://localhost:2833"; +my ($rm_initref) = "-ORBInitRef ReplicationManager=corbaloc::localhost:2833/ReplicationManager"; + +my($status) = 0; + +my($REP1) = new PerlACE::Process (".$build_directory/ft_replica", "-f none -o $factory1_ior -t $replica1_ior -l loc1 -i type1 -q"); +my($REP2) = new PerlACE::Process (".$build_directory/ft_replica", "-f none -o $factory2_ior -t $replica2_ior -l loc2 -i type1 -q"); +my($DET) = new PerlACE::Process ("$ENV{'TAO_ROOT'}/orbsvcs/Fault_Detector$build_directory/Fault_Detector", "-r -o $detector_ior -q"); +my($NOT) = new PerlACE::Process ("$ENV{'TAO_ROOT'}/orbsvcs/Fault_Notifier$build_directory/Fault_Notifier", "-r -o $notifier_ior -q"); +my($CONS) = new PerlACE::Process (".$build_directory/ft_fault_consumer", "-o $ready_file -n file://$notifier_ior -q -d file://$detector_ior -r file://$replica1_ior -r file://$replica2_ior"); + +my($CL); +if ($simulated) { + print "\nTEST: Preparing Client Mediated Fault Tolerance test.\n" if ($verbose); + $CL = new PerlACE::Process (".$build_directory/ft_client", "-f file://$replica1_ior -f file://$replica2_ior -c testscript"); +}else{ + print "\nTEST: Preparing IOGR based test.\n" if ($verbose); + $CL = new PerlACE::Process (".$build_directory/ft_client", "-f file://$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 "TEST 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 "TEST 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 "TEST ERROR: cannot find file <$detector_ior>\n"; + $REP1->Kill (); $REP1->TimedWait (1); + $REP2->Kill (); $REP2->TimedWait (1); + $DET->Kill (); $DET->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 "TEST ERROR: cannot find file <$notifier_ior>\n"; + $REP1->Kill (); $REP1->TimedWait (1); + $REP2->Kill (); $REP2->TimedWait (1); + $DET->Kill (); $DET->TimedWait(1); + $NOT->Kill (); $NOT->TimedWait(1); + exit 1; +} + +print "\nTEST: starting fault consumer " . $CONS->CommandLine . "\n" if ($verbose); +$CONS->Spawn (); + +print "TEST: waiting for READY.FILE from fault consumer\n" if ($verbose); +if (PerlACE::waitforfile_timed ($ready_file, 5) == -1) { + print STDERR "TEST ERROR: cannot find file <$ready_file>\n"; + $REP1->Kill (); $REP1->TimedWait (1); + $REP2->Kill (); $REP2->TimedWait (1); + $DET->Kill (); $DET->TimedWait(1); + $NOT->Kill (); $NOT->TimedWait(1); + $CONS->Kill (); $CONS->TimedWait(1); + exit 1; +} + +print "\nTEST: starting client " . $CL->CommandLine . "\n" if ($verbose); +$client = $CL->SpawnWaitKill (60); + +if ($client != 0) { + print STDERR "TEST ERROR: client returned $client\n"; + $status = 1; +} + +print "\nTEST: wait for replica 1.\n" if ($verbose); +$replica1 = $REP1->WaitKill (5); +if ($replica1 != 0) { + print STDERR "TEST ERROR: replica returned $replica1\n"; + $status = 1; +} + +print "\nTEST: wait for replica 2.\n" if ($verbose); +$replica2 = $REP2->WaitKill (5); +if ($replica2 != 0) { + print STDERR "TEST ERROR: replica returned $replica2\n"; + $status = 1; +} + +print "\nTEST: wait for detector factory to leave.\n" if ($verbose); +$detector = $DET->WaitKill (20); +if ($detector != 0) { + print STDERR "TEST ERROR: detector returned $detector\n"; + $status = 1; +} + +print "\nTEST: wait for notifier to leave.\n" if ($verbose); +$notifier = $NOT->WaitKill (20); +if ($notifier != 0) { + print STDERR "TEST ERROR: notifier returned $notifier\n"; + $status = 1; +} + +print "\nTEST: wait for fault consumer to leave.\n" if ($verbose); +$consumer = $CONS->WaitKill (20); +if ($consumer != 0) { + print STDERR "TEST ERROR: fault consumer returned $consumer\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; diff --git a/TAO/orbsvcs/tests/FT_App/run_test_notifier.pl b/TAO/orbsvcs/tests/FT_App/run_test_notifier.pl new file mode 100755 index 00000000000..521860b7ac3 --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/run_test_notifier.pl @@ -0,0 +1,248 @@ +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 +# +# Command line options: +# --debug_build use exes from this directory +# if not specified use exes from ./release +# -v display test progress messages (repeating option increases verbosity +# +# 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): +# 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. +# 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. +# Wait for READY +# Start FT_Client giving it IORS: FR#1 and FR#2. +# 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. +# 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. +# 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. +# Housekeeping +# Wait for all processes to terminate. +# Check termination status. +# Delete temp files. +# +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 + +foreach $i (@ARGV) { + if ($i eq "--debug_build") + { + $debug_builds = 1; + } + 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"; +} + + +#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 -f none -t $replica1_ior -l loc1 -i type1 -q"); +my($REP2) = new PerlACE::Process (".$build_directory/ft_replica", "-o $factory2_ior -f none -t $replica2_ior -l loc2 -i type1 -q"); +my($DET) = new PerlACE::Process ("$ENV{'TAO_ROOT'}/orbsvcs/Fault_Detector$build_directory/Fault_Detector", "-r -o $detector_ior -q"); +my($NOT) = new PerlACE::Process ("$ENV{'TAO_ROOT'}/orbsvcs/Fault_Notifier$build_directory/Fault_Notifier", "-r -o $notifier_ior -q"); +my($ANA) = new PerlACE::Process (".$build_directory/ft_analyzer", "-o $ready_file -n file://$notifier_ior -d file://$detector_ior -r file://$replica1_ior -r file://$replica2_ior -q"); +my($CL) = new PerlACE::Process (".$build_directory/ft_client", "-f file://$replica1_ior -f file://$replica2_ior -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 "TEST 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 "TEST 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 "TEST 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 "TEST 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 "TEST 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 "TEST ERROR: client returned $client\n"; + $status = 1; +} + +print "\nTEST: wait for replica 1.\n" if ($verbose); +$replica1 = $REP1->WaitKill (5); +if ($replica1 != 0) { + print STDERR "TEST ERROR: replica returned $replica1\n"; + $status = 1; +} + +print "\nTEST: wait for replica 2.\n" if ($verbose); +$replica2 = $REP2->WaitKill (5); +if ($replica2 != 0) { + print STDERR "TEST ERROR: replica returned $replica2\n"; + $status = 1; +} + +print "\nTEST: wait for detector factory to leave.\n" if ($verbose); +$detector = $DET->WaitKill (20); +if ($detector != 0) { + print STDERR "TEST ERROR: detector returned $detector\n"; + $status = 1; +} + +print "\nTEST: wait for notifier to leave.\n" if ($verbose); +$notifier = $NOT->WaitKill (20); +if ($notifier != 0) { + print STDERR "TEST ERROR: notifier returned $notifier\n"; + $status = 1; +} + +print "\nTEST: wait for analyzer to leave.\n" if ($verbose); +$analyzer = $ANA->WaitKill (20); +if ($analyzer != 0) { + print STDERR "TEST 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; 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..dd73b739a52 --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/run_test_registry.pl @@ -0,0 +1,438 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ +# -*- perl -*- + +# Purpose: +# To test the FactoryRegistry either as a stand-alone application or as part +# of the replication manager +# +# Command line options: +# --debug_build use exes from this directory +# if not specified use exes from ./release +# -r use ReplicationManager rather than stand-alone factory +# --no_simulate +# use real IOGR-based recovery. +# -v display test progress messages (repeating option increases verbosity +# +# Process being tested: +# FT_Registry +# implements PortableGroup::FactoryRegistry interface. +# or +# FT_ReplicationManager (if -r option is used) +# +# Processes used in test: +# FT_Replica * 3 +# implements GenericFactory interface to create TestReplicas +# TestReplica implements TestReplica interface. +# TestReplica implements PullMonitorable interface. +# FT_Client +# client for TestReplica interface. +# client for PullMonitorable. +# Object Group Creator +# Creates groups of objects. +# +# Test Scenario (***Test: marks behavior being tested): +# +# First the test starts a factory registry, +# Then starts three factories. Each factory exists at a separate location. +# The locations are named shire, bree, and rivendell. In a "real" system +# these locations would be on separate computers. +# +# The factory at the shire location knows how to create hobbits. +# The factory at the bree location knows how to create hobbits, elves, and humans. +# The factory at rivendell can create elves. +# Hobbits, elves, and humans are actually TestReplica objects. A creation parameter +# included as part of the registration information specifies which species they are. +# +# ***Test: The factories register themselves with the factory registry. Registration +# information includes the location, the type of object created, a object reference +# to the factory and set of parameters to be passed to the factory's create_object +# method. +# +# An object group creator is started and asked to create three object groups: +# a group of hobbits, a group of elves; and another group of hobbits. +# +# ***Test: the object group creator asks the registry for the set of factories +# that can create the type of object needed, then uses the create_object method +# for each factory to create the actual object. +# +# [temporary until IOGR's are working: The object group creator writes the +# IOR's of the create objects to files -- using a file naming convention to +# distinguish members of the group. It will be enhanced to assemble these +# IORs into an IOGR and either write the IOGR to a file or register it with +# the Naming Service.] +# +# The object group creator is also told to unregister all factories that create humans. +# ***Test: It does so using the unregister_factory_by_type method. +# +# Three clients are started, one at a time. Each client is given a reference +# to an object group +# +# [temporary until IOGRs and transparent reinvocaton work: each client is +# given references to the members of the group and manages its own recovery +# (client mediated fault tolerance)] +# +# Each client sends a few requests to first member of the object group. Eventually +# this member fails and the requests are then rerouted to the second (and last) +# member of the group. +# +# When a clients job is done, it exits and asks the remaining group member to +# exit, too. +# +# The factories are run with the quit-on-idle option so when the last object +# created at that location goes away, the factory exits. +# +# ***Test: As it exits the factory unregisters itself with the factory registry. +# ***Test: A command line option determines whether it uses a single +# unregister_factory_by_location call, or separate unregister_factory calles for +# each type of object created. In this test, the shire location uses unregister_factory, +# and bree and rivendell use unregister_factory_by_location. +# +# The factory registry is also run with the quit-on-idle option so when the last +# factory unregisters itself, the factory registry shuts down to end the test. + +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 +my($use_rm) = 0; # 1: use replication manager; 0 use stand-alone factory registry + +foreach $i (@ARGV) { + if ($i eq "--debug_build") + { + $debug_builds = 1; + } + elsif ($i eq "-r") # use RegistrationManager + { + $use_rm = 1 + } + elsif ($i eq "--no_simulate") # reverse this once we have FT ORB support + { + $simulated = 0; + } + elsif ($i eq "-v") + { + $verbose += 1; + } + else + { + print "unknown option $i. Expecting: --debug_build, -r --no_simulate, -v\n"; + exit(-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"; +} + +my($species1) = "hobbit"; +my($species2) = "elf"; +my($species3) = "human"; +my($location1) = "shire"; +my($location2) = "bree"; +my($location3) = "rivendell"; +my($location4) = "rohan"; + +#define temp files +my($rm_ior) = PerlACE::LocalFile ("rm.ior"); +my($registry_ior) = PerlACE::LocalFile ("registry.ior"); +my($factory1_ior) = PerlACE::LocalFile ("factory1.ior"); +my($factory2_ior) = PerlACE::LocalFile ("factory2.ior"); +my($factory3_ior) = PerlACE::LocalFile ("factory3.ior"); +my($replica1_ior) = PerlACE::LocalFile ("${species1}_${location1}_0.ior"); +my($replica2_ior) = PerlACE::LocalFile ("${species1}_${location2}_0.ior"); +my($replica3_ior) = PerlACE::LocalFile ("${species2}_${location2}_1.ior"); +my($replica4_ior) = PerlACE::LocalFile ("${species2}_${location3}_0.ior"); +my($replica5_ior) = PerlACE::LocalFile ("${species1}_${location1}_1.ior"); +my($replica6_ior) = PerlACE::LocalFile ("${species1}_${location2}_2.ior"); + +my($replica1_iogr) = PerlACE::LocalFile ("${species1}_0.iogr"); +my($replica2_iogr) = PerlACE::LocalFile ("${species2}_1.iogr"); +my($replica3_iogr) = PerlACE::LocalFile ("${species1}_2.iogr"); + +my($client_data) = PerlACE::LocalFile ("persistent.dat"); + +#discard junk from previous tests +unlink $rm_ior; +unlink $registry_ior; +unlink $factory1_ior; +unlink $factory2_ior; +unlink $factory3_ior; +unlink $replica1_ior; +unlink $replica2_ior; +unlink $replica3_ior; +unlink $replica4_ior; +unlink $replica5_ior; +unlink $replica6_ior; +unlink $replica1_iogr; +unlink $replica2_iogr; + +unlink $client_data; + +my($status) = 0; + +my ($rm_endpoint) = "-ORBEndpoint iiop://localhost:2833"; +my ($registry_opt) = "-f file://$registry_ior"; + +if ($use_rm) { + $registry_opt = "-ORBInitRef ReplicationManager=corbaloc::localhost:2833/ReplicationManager"; +} + +my($RM) = new PerlACE::Process ("$ENV{'TAO_ROOT'}/orbsvcs/FT_ReplicationManager$build_directory/FT_ReplicationManager", "-ORBDebugLevel 0 -o $rm_ior $rm_endpoint"); +my($RMC) = new PerlACE::Process (".$build_directory/replmgr_controller", "$registry_opt -x"); +my($REG) = new PerlACE::Process (".$build_directory/ft_registry", "-o $registry_ior -q"); +my($FAC1) = new PerlACE::Process (".$build_directory/ft_replica", "-o $factory1_ior $registry_opt -l $location1 -i $species1 -q"); +my($FAC2) = new PerlACE::Process (".$build_directory/ft_replica", "-o $factory2_ior $registry_opt -l $location2 -i $species1 -i $species2 -i $species3 -q -u"); +my($FAC3) = new PerlACE::Process (".$build_directory/ft_replica", "-o $factory3_ior $registry_opt -l $location3 -i $species2 -q -u"); + # -n means no name service -i means write individual iors +my($CTR) = new PerlACE::Process (".$build_directory/ft_create", "$registry_opt -r $species1 -r $species2 -r $species1 -u $species3 -n -i"); + +my($CL1); +my($CL2); +my($CL3); +if ($simulated) +{ + print "\nTEST: Preparing Client Mediated Fault Tolerance test.\n" if ($verbose); + $CL1 = new PerlACE::Process (".$build_directory/ft_client", "-f file://$replica1_ior -f file://$replica2_ior -c testscript"); + $CL2 = new PerlACE::Process (".$build_directory/ft_client", "-f file://$replica3_ior -f file://$replica4_ior -c testscript"); + $CL3 = new PerlACE::Process (".$build_directory/ft_client", "-f file://$replica5_ior -f file://$replica6_ior -c testscript"); +} +else +{ + print "\nTEST: Preparing IOGR based test.\n" if ($verbose); + $CL1 = new PerlACE::Process (".$build_directory/ft_client", "-f file://$replica1_iogr -c testscript"); + $CL2 = new PerlACE::Process (".$build_directory/ft_client", "-f file://$replica2_iogr -c testscript"); + $CL3 = new PerlACE::Process (".$build_directory/ft_client", "-f file://$replica3_iogr -c testscript"); +} + +####################### +# Start FactoryRegistry +if ($use_rm) +{ + print "\nTEST: starting ReplicationManager " . $RM->CommandLine . "\n" if ($verbose); + $RM->Spawn (); + + print "TEST: waiting for registry's IOR\n" if ($verbose); + if (PerlACE::waitforfile_timed ($rm_ior, 5) == -1) { + print STDERR "TEST ERROR: cannot find file <$rm_ior>\n"; + $RM->Kill (); $RM->TimedWait (1); + exit 1; + } +} +else +{ + print "\nTEST: starting registry " . $REG->CommandLine . "\n" if ($verbose); + $REG->Spawn (); + + print "TEST: waiting for registry's IOR\n" if ($verbose); + if (PerlACE::waitforfile_timed ($registry_ior, 5) == -1) { + print STDERR "TEST ERROR: cannot find file <$registry_ior>\n"; + $REG->Kill (); $REG->TimedWait (1); + exit 1; + } +} + +################# +# Start Factories + +print "\nTEST: starting factory 1 " . $FAC1->CommandLine . "\n" if ($verbose); +$FAC1->Spawn (); + +print "TEST: waiting for factory 1's IOR\n" if ($verbose); +if (PerlACE::waitforfile_timed ($factory1_ior, 5) == -1) { + print STDERR "TEST ERROR: cannot find file <$factory1_ior>\n"; + $REG->Kill (); $REG->TimedWait (1); + $FAC1->Kill (); $FAC1->TimedWait (1); + exit 1; +} + +print "\nTEST: starting factory 2 " . $FAC2->CommandLine . "\n" if ($verbose); +$FAC2->Spawn (); + +print "TEST: waiting for factory 2's IOR\n" if ($verbose); +if (PerlACE::waitforfile_timed ($factory2_ior, 5) == -1) { + print STDERR "TEST ERROR: cannot find file <$factory2_ior>\n"; + $FAC1->Kill (); $FAC1->TimedWait (1); + $REG->Kill (); $REG->TimedWait (1); + $FAC2->Kill (); $FAC2->TimedWait (1); + exit 1; +} + +print "\nTEST: starting factory 3 " . $FAC3->CommandLine . "\n" if ($verbose); +$FAC3->Spawn (); + +print "TEST: waiting for factory 3's IOR\n" if ($verbose); +if (PerlACE::waitforfile_timed ($factory3_ior, 5) == -1) { + print STDERR "TEST ERROR: cannot find file <$factory3_ior>\n"; + $FAC1->Kill (); $FAC1->TimedWait (1); + $FAC2->Kill (); $FAC2->TimedWait (1); + $REG->Kill (); $REG->TimedWait (1); + $FAC3->Kill (); $FAC3->TimedWait (1); + exit 1; +} + +###################### +# Create object groups + +print "\nTEST: starting object group creator " . $CTR->CommandLine . "\n" if ($verbose); +$CTR->Spawn (); + +print "TEST: waiting for Replica IOR files from object group creator\n" if ($verbose); +if (PerlACE::waitforfile_timed ($replica1_ior, 5) == -1){ + print STDERR "TEST ERROR: cannot find file <$replica1_ior>\n"; + $status = 1; +} +elsif (PerlACE::waitforfile_timed ($replica2_ior, 5) == -1){ + print STDERR "TEST ERROR: cannot find file <$replica2_ior> \n"; + $status = 1; +} +elsif (PerlACE::waitforfile_timed ($replica3_ior, 5) == -1){ + print STDERR "TEST ERROR: cannot find file <$replica3_ior> \n"; + $status = 1; +} +elsif (PerlACE::waitforfile_timed ($replica4_ior, 5) == -1){ + print STDERR "TEST ERROR: cannot find file <$replica4_ior> \n"; + $status = 1; +} +elsif (PerlACE::waitforfile_timed ($replica5_ior, 5) == -1){ + print STDERR "TEST ERROR: cannot find file <$replica5_ior> \n"; + $status = 1; +} +elsif (PerlACE::waitforfile_timed ($replica6_ior, 5) == -1){ + print STDERR "TEST ERROR: cannot find file <$replica6_ior> \n"; + $status = 1; +} + +if($status != 0){ + $FAC3->Kill (); $FAC3->TimedWait (1); + $FAC2->Kill (); $FAC2->TimedWait (1); + $FAC1->Kill (); $FAC1->TimedWait (1); + $REG->Kill (); $REG->TimedWait (1); + $CTR->Kill (); $CTR->TimedWait(1); + exit 1; +} + +print "\nTEST: wait for object group creator.\n" if ($verbose); +$config = $CTR->WaitKill (5); +if ($config != 0) { + print STDERR "TEST ERROR: configuration manager returned $config\n"; + $FAC3->Kill (); $FAC3->TimedWait (1); + $FAC2->Kill (); $FAC2->TimedWait (1); + $FAC1->Kill (); $FAC1->TimedWait (1); + $REG->Kill (); $REG->TimedWait (1); + exit 1; +} + + +############# +# Run clients + +print "\nTEST: starting client " . $CL1->CommandLine . "\n" if ($verbose); +$client = $CL1->SpawnWaitKill (60); + +if ($client != 0) { + print STDERR "TEST ERROR: client returned $client\n"; + $status = 1; +} + +print "\nTEST: starting client again " . $CL2->CommandLine . "\n" if ($verbose); +$client2 = $CL2->SpawnWaitKill (60); + +if ($client2 != 0) { + print STDERR "TEST ERROR: client returned $client2\n"; + $status = 1; +} + +print "\nTEST: starting client, one more time with feeling " . $CL3->CommandLine . "\n" if ($verbose); +$client3 = $CL3->SpawnWaitKill (60); + +if ($client3 != 0) { + print STDERR "TEST ERROR: client returned $client3\n"; + $status = 1; +} + +###################### +# Clean house and exit + +print "\nTEST: wait for factory 1.\n" if ($verbose); +$factory1 = $FAC1->WaitKill (30); +if ($factory1 != 0) { + print STDERR "TEST ERROR: replica returned $factory 1\n"; + $status = 1; +} + +print "\nTEST: wait for factory 2.\n" if ($verbose); +$factory2 = $FAC2->WaitKill (30); +if ($factory2 != 0) { + print STDERR "TEST ERROR: factory 2 returned $factory2\n"; + $status = 1; +} + +print "\nTEST: wait for factory 3.\n" if ($verbose); +$factory3 = $FAC3->WaitKill (30); +if ($factory3 != 0) { + print STDERR "TEST ERROR: factory 3 returned $factory3\n"; + $status = 1; +} + +if ($use_rm) +{ + print "\nTEST: shutting down the replication manager.\n" if ($verbose); + $controller = $RMC->SpawnWaitKill (300); + if ($controller != 0) { + print STDERR "TEST ERROR: replication manager controller returned $controller\n"; + $status = 1; + } + + print "\nTEST: wait for ReplicationManager.\n" if ($verbose); + #$RM->Kill (); + $repmgr = $RM->WaitKill (30); + if ($repmgr != 0) { + print STDERR "TEST ERROR: ReplicationManager returned $repmgr\n"; + $status = 1; + } +} +else +{ + print "\nTEST: wait for FactoryRegistry.\n" if ($verbose); + $registry = $REG->WaitKill (30); + if ($registry != 0) { + print STDERR "TEST ERROR: FactoryRegistry returned $registry\n"; + $status = 1; + } +} +print "\nTEST: releasing scratch files.\n" if ($verbose); +unlink $rm_ior; +unlink $registry_ior; +unlink $factory1_ior; +unlink $factory2_ior; +unlink $factory3_ior; +unlink $replica1_ior; +unlink $replica2_ior; +unlink $replica3_ior; +unlink $replica4_ior; +unlink $replica5_ior; +unlink $replica6_ior; +unlink $replica1_iogr; +unlink $replica2_iogr; + +unlink $client_data; + + +exit $status; diff --git a/TAO/orbsvcs/tests/FT_App/run_test_rmnotifier.pl b/TAO/orbsvcs/tests/FT_App/run_test_rmnotifier.pl new file mode 100755 index 00000000000..b5023240650 --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/run_test_rmnotifier.pl @@ -0,0 +1,319 @@ +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: +# ReplicationManager +# +# 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 ($rm_endpoint) = "-ORBEndpoint iiop://localhost:2833"; +my ($rm_initref) = "-ORBInitRef ReplicationManager=corbaloc::localhost:2833/ReplicationManager"; +my($rm_ior) = PerlACE::LocalFile ("rm.ior"); +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 $rm_ior; +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($RM) = new PerlACE::Process ("$ENV{'TAO_ROOT'}/orbsvcs/FT_ReplicationManager$build_directory/FT_ReplicationManager", "-o $rm_ior $rm_endpoint"); +my($RMC) = new PerlACE::Process (".$build_directory/replmgr_controller", "$rm_initref -x"); +my($REP1) = new PerlACE::Process (".$build_directory/ft_replica", "-o $factory1_ior -f none -t $replica1_ior -l loc1 -i type1 -q"); +my($REP2) = new PerlACE::Process (".$build_directory/ft_replica", "-o $factory2_ior -f none -t $replica2_ior -l loc2 -i type1 -q"); +my($DET) = new PerlACE::Process ("$ENV{'TAO_ROOT'}/orbsvcs/Fault_Detector$build_directory/Fault_Detector", "$rm_initref -o $detector_ior -q"); +my($NOT) = new PerlACE::Process ("$ENV{'TAO_ROOT'}/orbsvcs/Fault_Notifier$build_directory/Fault_Notifier", "$rm_initref -o $notifier_ior -q"); +my($ANA) = new PerlACE::Process (".$build_directory/ft_analyzer", "-o $ready_file -n file://$notifier_ior -d file://$detector_ior -r file://$replica1_ior -r file://$replica2_ior -q"); + +my($CL); +if ($simulated) { + print "\nTEST: Preparing Client Mediated Fault Tolerance test.\n" if ($verbose); + $CL = new PerlACE::Process (".$build_directory/ft_client", "-f file://$replica1_ior -f file://$replica2_ior -c testscript"); +}else{ + print "\nTEST: Preparing IOGR based test.\n" if ($verbose); + $CL = new PerlACE::Process (".$build_directory/ft_client", "-f file://$replica1_iogr -c testscript"); +} + +####################### +# ReplicationManager + +print "\nTEST: starting ReplicationManager " . $RM->CommandLine . "\n" if ($verbose); +$RM->Spawn (); + +print "TEST: waiting for registry's IOR\n" if ($verbose); +if (PerlACE::waitforfile_timed ($rm_ior, 5) == -1) { + print STDERR "TEST ERROR: cannot find file <$rm_ior>\n"; + $RM->Kill (); $RM->TimedWait (1); + exit 1; +} + +########## +# Notifier +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 "TEST ERROR: cannot find file <$notifier_ior>\n"; + $RM->Kill (); $RM->TimedWait (1); + $NOT->Kill (); $NOT->TimedWait(1); + exit 1; +} + +########## +# Detector +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, 20) == -1) { + print STDERR "TEST ERROR: cannot find file <$detector_ior>\n"; + $RM->Kill (); $RM->TimedWait (1); + $NOT->Kill (); $NOT->TimedWait(1); + $DET->Kill (); $DET2->TimedWait(1); + exit 1; +} + +########### +# Replica 1 +print "\nTEST: 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 "TEST ERROR: cannot find file <$replica1_ior>\n"; + $RM->Kill (); $RM->TimedWait (1); + $NOT->Kill (); $NOT->TimedWait(1); + $DET->Kill (); $DET->TimedWait(1); + $REP1->Kill (); $REP1->TimedWait (1); + exit 1; +} + +########### +# Replica 2 +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 "TEST ERROR: cannot find file <$replica2_ior>\n"; + $RM->Kill (); $RM->TimedWait (1); + $NOT->Kill (); $NOT->TimedWait(1); + $DET->Kill (); $DET->TimedWait(1); + $REP1->Kill (); $REP1->TimedWait (1); + $REP2->Kill (); $REP2->TimedWait (1); + exit 1; +} + +########## +# Analyzer +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 "TEST ERROR: cannot find file <$ready_file>\n"; + $RM->Kill (); $RM->TimedWait (1); + $NOT->Kill (); $NOT->TimedWait(1); + $DET->Kill (); $DET->TimedWait(1); + $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; +} + +######## +# Client +print "\nTEST: starting client " . $CL->CommandLine . "\n" if ($verbose); +$client = $CL->SpawnWaitKill (60); + +if ($client != 0) { + print STDERR "TEST ERROR: client returned $client\n"; + $status = 1; +} + +print "\nTEST: wait for replica 1.\n" if ($verbose); +$replica1 = $REP1->WaitKill (5); +if ($replica1 != 0) { + print STDERR "TEST ERROR: replica returned $replica1\n"; + $status = 1; +} + +print "\nTEST: wait for replica 2.\n" if ($verbose); +$replica2 = $REP2->WaitKill (5); +if ($replica2 != 0) { + print STDERR "TEST ERROR: replica returned $replica2\n"; + $status = 1; +} + +print "\nTEST: wait for detector factory to leave.\n" if ($verbose); +$detector = $DET->WaitKill (20); +if ($detector != 0) { + print STDERR "TEST ERROR: detector returned $detector\n"; + $status = 1; +} + +print "\nTEST: wait for analyzer to leave.\n" if ($verbose); +$analyzer = $ANA->WaitKill (20); +if ($analyzer != 0) { + print STDERR "TEST ERROR: analyzer returned $analyzer\n"; + $status = 1; +} + +print "\nTEST: shutting down the replication manager.\n" if ($verbose); +$controller = $RMC->SpawnWaitKill (300); +if ($controller != 0) { + print STDERR "TEST ERROR: replication manager controller returned $controller\n"; + $status = 1; +} + +print "\nTEST: wait for ReplicationManager.\n" if ($verbose); +#$RM->Kill (); +$repmgr = $RM->WaitKill (30); +if ($repmgr != 0) { + print STDERR "TEST ERROR: ReplicationManager returned $repmgr\n"; + $status = 1; +} + +print "\nTEST: wait for notifier to leave.\n" if ($verbose); +$notifier = $NOT->WaitKill (20); +if ($notifier != 0) { + print STDERR "TEST ERROR: notifier returned $notifier\n"; + $status = 1; +} + +print "\nTEST: releasing scratch files.\n" if ($verbose); +unlink $rm_ior; +unlink $replica1_ior; +unlink $replica2_ior; +unlink $detector_ior; +unlink $notifier_ior; +unlink $ready_file; + +#client's work file +unlink $client_data; + +exit $status; diff --git a/TAO/orbsvcs/tests/FT_App/run_test_rmregistry.pl b/TAO/orbsvcs/tests/FT_App/run_test_rmregistry.pl new file mode 100755 index 00000000000..5facd17d085 --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/run_test_rmregistry.pl @@ -0,0 +1,385 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ +# -*- perl -*- + +# Purpose: +# To test the FactoryRegistry as a component of ReplicationManager +# +# Process being tested: +# FT_ReplicationManager +# implements PortableGroup::FactoryRegistry interface. +# Processes used in test: +# FT_Replica * 3 +# implements GenericFactory interface to create TestReplicas +# TestReplica implements TestReplica interface. +# TestReplica implements PullMonitorable interface. +# FT_Client +# client for TestReplica interface. +# client for PullMonitorable. +# Object Group Creator +# Creates groups of objects. +# +# Test Scenario (***Test: marks behavior being tested): +# +# First the test starts The ReplicationManager, +# Then starts three factories. Each factory exists at a separate location. +# The locations are named shire, bree, and rivendell. In a "real" system +# these locations would be on separate computers. +# +# The factory at the shire location knows how to create hobbits. +# The factory at the bree location knows how to create hobbits, elves, and humans. +# The factory at rivendell can create elves. +# Hobbits, elves, and humans are roles for TestReplica objects. A creation parameter +# included as part of the registration information specifies which role they are playing. +# +# ***Test: The factories register themselves with the factory registry in the ReplicationManager. +# Registration information includes: +# the role, +# the type of object created, +# the location, +# an object reference to the factory and +# a set of parameters to be passed to the factory's create_object method. +# +# An object group creator is started and asked to create three object groups: +# a group of hobbits, a group of elves; and another group of hobbits. +# +# ***Test: the object group creator asks the ReplicationManager::FactoryRegistry +# for the set of factories that can create objects for the desired role. +# Then it uses the create_object method for each factory to create the actual object. +# +# [temporary until IOGR's are working: The object group creator writes the +# IOR's of the create objects to files -- using a file naming convention to +# distinguish members of the group. It will be enhanced to assemble these +# IORs into an IOGR and either write the IOGR to a file or register it with +# the Naming Service.] +# +# The object group creator is also told to unregister all factories that create humans. +# ***Test: It does so using the unregister_factory_by_role method. +# +# Three clients are started, one at a time. Each client is given a reference +# to an object group +# +# [temporary until IOGRs and transparent reinvocaton work: each client is +# given references to the members of the group and manages its own recovery +# (client mediated fault tolerance)] +# +# Each client sends a few requests to first member of the object group. Eventually +# this member fails and the requests are then rerouted to the second (and last) +# member of the group. +# +# When a clients job is done, it exits and asks the remaining group member to +# exit, too. +# +# The factories are run with the quit-on-idle option so when the last object +# created at that location goes away, the factory exits. +# +# ***Test: As it exits the factory unregisters itself with the ReplicationManager::FactoryRegistry. +# ***Test: A command line option determines whether it uses a single +# unregister_factory_by_location call, or separate unregister_factory calles for +# each type of object created. In this test, the shire location uses unregister_factory, +# and bree and rivendell use unregister_factory_by_location. +# +# The factory registry is also run with the quit-on-idle option so when the last +# factory unregisters itself. +# The ReplicationManager is killed because it doesn't have a quit-on-idle option. + +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"; +} + +my($role1) = "hobbit"; +my($role2) = "elf"; +my($role3) = "human"; + +my($location1) = "shire"; +my($location2) = "bree"; +my($location3) = "rivendell"; +my($location4) = "rohan"; + +my ($rm_endpoint) = "-ORBEndpoint iiop://localhost:2833"; +my ($rm_initref) = "-ORBInitRef ReplicationManager=corbaloc::localhost:2833/ReplicationManager"; + +#define temp files +my($rm_ior) = PerlACE::LocalFile ("rm.ior"); +my($factory1_ior) = PerlACE::LocalFile ("factory1.ior"); +my($factory2_ior) = PerlACE::LocalFile ("factory2.ior"); +my($factory3_ior) = PerlACE::LocalFile ("factory3.ior"); +my($replica1_ior) = PerlACE::LocalFile ("${role1}_${location1}_0.ior"); +my($replica2_ior) = PerlACE::LocalFile ("${role1}_${location2}_0.ior"); +my($replica3_ior) = PerlACE::LocalFile ("${role2}_${location2}_1.ior"); +my($replica4_ior) = PerlACE::LocalFile ("${role2}_${location3}_0.ior"); +my($replica5_ior) = PerlACE::LocalFile ("${role1}_${location1}_1.ior"); +my($replica6_ior) = PerlACE::LocalFile ("${role1}_${location2}_2.ior"); + +my($replica1_iogr) = PerlACE::LocalFile ("${role1}_0.iogr"); +my($replica2_iogr) = PerlACE::LocalFile ("${role2}_1.iogr"); +my($replica3_iogr) = PerlACE::LocalFile ("${role1}_2.iogr"); + +my($client_data) = PerlACE::LocalFile ("persistent.dat"); + +#discard junk from previous tests +unlink $rm_ior; +unlink $factory1_ior; +unlink $factory2_ior; +unlink $factory3_ior; +unlink $replica1_ior; +unlink $replica2_ior; +unlink $replica3_ior; +unlink $replica4_ior; +unlink $replica5_ior; +unlink $replica6_ior; +unlink $replica1_iogr; +unlink $replica2_iogr; + +unlink $client_data; + +my($status) = 0; + +my($RM) = new PerlACE::Process ("$ENV{'TAO_ROOT'}/orbsvcs/FT_ReplicationManager$build_directory/FT_ReplicationManager", "-ORBDebugLevel 0 -o $rm_ior $rm_endpoint"); +my($RMC) = new PerlACE::Process (".$build_directory/replmgr_controller", "$rm_initref -x"); +my($FAC1) = new PerlACE::Process (".$build_directory/ft_replica", "-o $factory1_ior $rm_initref -l $location1 -i $role1 -q"); +my($FAC2) = new PerlACE::Process (".$build_directory/ft_replica", "-o $factory2_ior $rm_initref -l $location2 -i $role1 -i $role2 -i $role3 -q -u"); +my($FAC3) = new PerlACE::Process (".$build_directory/ft_replica", "-o $factory3_ior $rm_initref -l $location3 -i $role2 -q -u"); +my($CTR) = new PerlACE::Process (".$build_directory/ft_create", "$rm_initref -n -r $role1 -r $role2 -r $role1 -u $role3 -i"); + +my($CL1); +my($CL2); +my($CL3); +if ($simulated) { + print "\nTEST: Preparing Client Mediated Fault Tolerance test.\n" if ($verbose); + $CL1 = new PerlACE::Process (".$build_directory/ft_client", "-f file://$replica1_ior -f file://$replica2_ior -c testscript"); + $CL2 = new PerlACE::Process (".$build_directory/ft_client", "-f file://$replica3_ior -f file://$replica4_ior -c testscript"); + $CL3 = new PerlACE::Process (".$build_directory/ft_client", "-f file://$replica5_ior -f file://$replica6_ior -c testscript"); +}else{ + print "\nTEST: Preparing IOGR based test.\n" if ($verbose); + $CL1 = new PerlACE::Process (".$build_directory/ft_client", "-f file://$replica1_iogr -c testscript"); + $CL2 = new PerlACE::Process (".$build_directory/ft_client", "-f file://$replica2_iogr -c testscript"); + $CL3 = new PerlACE::Process (".$build_directory/ft_client", "-f file://$replica3_iogr -c testscript"); +} + +####################### +# Start ReplicationManager + +print "\nTEST: starting ReplicationManager " . $RM->CommandLine . "\n" if ($verbose); +$RM->Spawn (); + +print "TEST: waiting for registry's IOR\n" if ($verbose); +if (PerlACE::waitforfile_timed ($rm_ior, 5) == -1) { + print STDERR "TEST ERROR: cannot find file <$rm_ior>\n"; + $RM->Kill (); $RM->TimedWait (1); + exit 1; +} + + +################# +# Start Factories + +print "\nTEST: starting factory 1 " . $FAC1->CommandLine . "\n" if ($verbose); +$FAC1->Spawn (); + +print "TEST: waiting for factory 1's IOR\n" if ($verbose); +if (PerlACE::waitforfile_timed ($factory1_ior, 5) == -1) { + print STDERR "TEST ERROR: cannot find file <$factory1_ior>\n"; + $RM->Kill (); $RM->TimedWait (1); + $FAC1->Kill (); $FAC1->TimedWait (1); + exit 1; +} + +print "\nTEST: starting factory 2 " . $FAC2->CommandLine . "\n" if ($verbose); +$FAC2->Spawn (); + +print "TEST: waiting for factory 2's IOR\n" if ($verbose); +if (PerlACE::waitforfile_timed ($factory2_ior, 5) == -1) { + print STDERR "TEST ERROR: cannot find file <$factory2_ior>\n"; + $FAC1->Kill (); $FAC1->TimedWait (1); + $RM->Kill (); $RM->TimedWait (1); + $FAC2->Kill (); $FAC2->TimedWait (1); + exit 1; +} + +print "\nTEST: starting factory 3 " . $FAC3->CommandLine . "\n" if ($verbose); +$FAC3->Spawn (); + +print "TEST: waiting for factory 3's IOR\n" if ($verbose); +if (PerlACE::waitforfile_timed ($factory3_ior, 5) == -1) { + print STDERR "TEST ERROR: cannot find file <$factory3_ior>\n"; + $FAC1->Kill (); $FAC1->TimedWait (1); + $FAC2->Kill (); $FAC2->TimedWait (1); + $RM->Kill (); $RM->TimedWait (1); + $FAC3->Kill (); $FAC3->TimedWait (1); + exit 1; +} + +###################### +# Create object groups + +print "\nTEST: starting object group creator " . $CTR->CommandLine . "\n" if ($verbose); +$CTR->Spawn (); + +print "TEST: waiting for Replica IOR files from object group creator\n" if ($verbose); +if (PerlACE::waitforfile_timed ($replica1_ior, 5) == -1){ + print STDERR "TEST ERROR: cannot find file <$replica1_ior>\n"; + $status = 1; +} +elsif (PerlACE::waitforfile_timed ($replica2_ior, 5) == -1){ + print STDERR "TEST ERROR: cannot find file <$replica2_ior> \n"; + $status = 1; +} +elsif (PerlACE::waitforfile_timed ($replica3_ior, 5) == -1){ + print STDERR "TEST ERROR: cannot find file <$replica3_ior> \n"; + $status = 1; +} +elsif (PerlACE::waitforfile_timed ($replica4_ior, 5) == -1){ + print STDERR "TEST ERROR: cannot find file <$replica4_ior> \n"; + $status = 1; +} +elsif (PerlACE::waitforfile_timed ($replica5_ior, 5) == -1){ + print STDERR "TEST ERROR: cannot find file <$replica5_ior> \n"; + $status = 1; +} +elsif (PerlACE::waitforfile_timed ($replica6_ior, 5) == -1){ + print STDERR "TEST ERROR: cannot find file <$replica6_ior> \n"; + $status = 1; +} + +if($status != 0){ + $FAC3->Kill (); $FAC3->TimedWait (1); + $FAC2->Kill (); $FAC2->TimedWait (1); + $FAC1->Kill (); $FAC1->TimedWait (1); + $RM->Kill (); $RM->TimedWait (1); + $CTR->Kill (); $CTR->TimedWait(1); + exit 1; +} + +print "\nTEST: wait for object group creator.\n" if ($verbose); +$config = $CTR->WaitKill (5); +if ($config != 0) { + print STDERR "TEST ERROR: configuration manager returned $config\n"; + $FAC3->Kill (); $FAC3->TimedWait (1); + $FAC2->Kill (); $FAC2->TimedWait (1); + $FAC1->Kill (); $FAC1->TimedWait (1); + $RM->Kill (); $RM->TimedWait (1); + exit 1; +} + + +############# +# Run clients + +print "\nTEST: starting client " . $CL1->CommandLine . "\n" if ($verbose); +$client = $CL1->SpawnWaitKill (60); + +if ($client != 0) { + print STDERR "TEST ERROR: client returned $client\n"; + $status = 1; +} + +print "\nTEST: starting client again " . $CL2->CommandLine . "\n" if ($verbose); +$client2 = $CL2->SpawnWaitKill (60); + +if ($client2 != 0) { + print STDERR "TEST ERROR: client returned $client2\n"; + $status = 1; +} + +print "\nTEST: starting client, one more time with feeling " . $CL3->CommandLine . "\n" if ($verbose); +$client3 = $CL3->SpawnWaitKill (60); + +if ($client3 != 0) { + print STDERR "TEST ERROR: client returned $client3\n"; + $status = 1; +} + +###################### +# Clean house and exit + +print "\nTEST: wait for factory 1.\n" if ($verbose); +$factory1 = $FAC1->WaitKill (30); +if ($factory1 != 0) { + print STDERR "TEST ERROR: replica returned $factory 1\n"; + $status = 1; +} + +print "\nTEST: wait for factory 2.\n" if ($verbose); +$factory2 = $FAC2->WaitKill (30); +if ($factory2 != 0) { + print STDERR "TEST ERROR: factory 2 returned $factory2\n"; + $status = 1; +} + +print "\nTEST: wait for factory 3.\n" if ($verbose); +$factory3 = $FAC3->WaitKill (30); +if ($factory3 != 0) { + print STDERR "TEST ERROR: factory 3 returned $factory3\n"; + $status = 1; +} + +print "\nTEST: shutting down the replication manager.\n" if ($verbose); +$controller = $RMC->SpawnWaitKill (300); +if ($controller != 0) { + print STDERR "TEST ERROR: replication manager controller returned $controller\n"; + $status = 1; +} + +print "\nTEST: wait for ReplicationManager.\n" if ($verbose); +#$RM->Kill (); +$repmgr = $RM->WaitKill (30); +if ($repmgr != 0) { + print STDERR "TEST ERROR: ReplicationManager returned $repmgr\n"; + $status = 1; +} + +print "\nTEST: releasing scratch files.\n" if ($verbose); +unlink $rm_ior; +unlink $factory1_ior; +unlink $factory2_ior; +unlink $factory3_ior; +unlink $replica1_ior; +unlink $replica2_ior; +unlink $replica3_ior; +unlink $replica4_ior; +unlink $replica5_ior; +unlink $replica6_ior; +unlink $replica1_iogr; +unlink $replica2_iogr; + +unlink $client_data; + + +exit $status; diff --git a/TAO/orbsvcs/tests/FT_App/testscript b/TAO/orbsvcs/tests/FT_App/testscript new file mode 100644 index 00000000000..a428a227ef3 --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/testscript @@ -0,0 +1,10 @@ +v3 echo commands +=0 ++5 +d3 FMI: d3 is before state change; d4 is before replication;d5 is before reply ++5 +c10 ++5 +z3 sleep for a while ++7 +q1 quit and bring down current primary replica diff --git a/TAO/orbsvcs/tests/FaultTolerance/GroupRef_Manipulation/GroupRef_Manipulation.mpc b/TAO/orbsvcs/tests/FaultTolerance/GroupRef_Manipulation/GroupRef_Manipulation.mpc index 2ec4d716749..efaf9f234d1 100644 --- a/TAO/orbsvcs/tests/FaultTolerance/GroupRef_Manipulation/GroupRef_Manipulation.mpc +++ b/TAO/orbsvcs/tests/FaultTolerance/GroupRef_Manipulation/GroupRef_Manipulation.mpc @@ -1,4 +1,4 @@ -project(*Server): taoserver, orbsvcsexe, iormanip, ftorb { +project(*Server): taoserver, orbsvcsexe, iormanip, ftorb, messaging{ requires += interceptors idlflags += -Gv -DCORBA3 -I$(TAO_ROOT) diff --git a/TAO/orbsvcs/tests/FaultTolerance/GroupRef_Manipulation/Makefile b/TAO/orbsvcs/tests/FaultTolerance/GroupRef_Manipulation/Makefile index 443f0ea0b13..b4f0aa70b33 100644 --- a/TAO/orbsvcs/tests/FaultTolerance/GroupRef_Manipulation/Makefile +++ b/TAO/orbsvcs/tests/FaultTolerance/GroupRef_Manipulation/Makefile @@ -58,7 +58,7 @@ include $(TAO_ROOT)/taoconfig.mk .PRECIOUS: $(foreach ext, $(IDL_EXT), test$(ext)) -TAO_FT_LIBS = -lTAO_FTORB -lTAO_IORManip +TAO_FT_LIBS = -lTAO_FTORB -lTAO_IORManip -lTAO_Messaging server: $(addprefix $(VDIR),$(SERVER_OBJS)) $(LINK.cc) $(LDFLAGS) -o $@ $^ $(TAO_FT_LIBS) $(TAO_SRVR_LIBS) $(POSTLINK) diff --git a/TAO/orbsvcs/tests/FaultTolerance/GroupRef_Manipulation/server.cpp b/TAO/orbsvcs/tests/FaultTolerance/GroupRef_Manipulation/server.cpp index 4522cdf4f60..ee1bd7e9d0e 100644 --- a/TAO/orbsvcs/tests/FaultTolerance/GroupRef_Manipulation/server.cpp +++ b/TAO/orbsvcs/tests/FaultTolerance/GroupRef_Manipulation/server.cpp @@ -64,12 +64,12 @@ add_ft_prop (CORBA::ORB_ptr o, // Property values // Major and Minor revision numbers - ft_tag_component.version.major = (CORBA::Octet) 1; - ft_tag_component.version.minor = (CORBA::Octet) 0; + ft_tag_component.component_version.major = (CORBA::Octet) 1; + ft_tag_component.component_version.minor = (CORBA::Octet) 0; // Domain id const char *id = "version_testing"; - ft_tag_component.ft_domain_id = id; + ft_tag_component.group_domain_id = id; // Object group id ft_tag_component.object_group_id = diff --git a/TAO/orbsvcs/tests/FaultTolerance/IOGR/FaultTolerance_IOGR.mpc b/TAO/orbsvcs/tests/FaultTolerance/IOGR/FaultTolerance_IOGR.mpc index 52f12659a37..ff0e21543c6 100644 --- a/TAO/orbsvcs/tests/FaultTolerance/IOGR/FaultTolerance_IOGR.mpc +++ b/TAO/orbsvcs/tests/FaultTolerance/IOGR/FaultTolerance_IOGR.mpc @@ -1,4 +1,4 @@ -project(*server): portableserver, orbsvcsexe, iormanip, ftorb { +project(*server): portableserver, orbsvcsexe, iormanip, ftorb, messaging { Source_Files { test_i.cpp server.cpp diff --git a/TAO/orbsvcs/tests/FaultTolerance/IOGR/Makefile b/TAO/orbsvcs/tests/FaultTolerance/IOGR/Makefile index 3c290a0aa6c..7bb5ee15d69 100644 --- a/TAO/orbsvcs/tests/FaultTolerance/IOGR/Makefile +++ b/TAO/orbsvcs/tests/FaultTolerance/IOGR/Makefile @@ -46,7 +46,7 @@ include $(TAO_ROOT)/taoconfig.mk .PRECIOUS: $(foreach ext, $(IDL_EXT), test$(ext)) -TAO_FT_LIBS = -lTAO_FTORB -lTAO_IORManip +TAO_FT_LIBS = -lTAO_FTORB -lTAO_IORManip -lTAO_Messaging server: $(addprefix $(VDIR),$(SERVER_OBJS)) $(LINK.cc) $(LDFLAGS) -o $@ $^ $(TAO_SRVR_LIBS) $(POSTLINK) diff --git a/TAO/orbsvcs/tests/FaultTolerance/IOGR/Manager.cpp b/TAO/orbsvcs/tests/FaultTolerance/IOGR/Manager.cpp index 4e175275ae1..e876e51290b 100644 --- a/TAO/orbsvcs/tests/FaultTolerance/IOGR/Manager.cpp +++ b/TAO/orbsvcs/tests/FaultTolerance/IOGR/Manager.cpp @@ -194,12 +194,12 @@ Manager::set_properties (ACE_ENV_SINGLE_ARG_DECL) // Property values // Major and Minor revision numbers - ft_tag_component.version.major = (CORBA::Octet) 1; - ft_tag_component.version.minor = (CORBA::Octet) 0; + ft_tag_component.component_version.major = (CORBA::Octet) 1; + ft_tag_component.component_version.minor = (CORBA::Octet) 0; // Domain id const char *id = "iogr_testing"; - ft_tag_component.ft_domain_id = id; + ft_tag_component.group_domain_id = id; // Object group id ft_tag_component.object_group_id = diff --git a/TAO/orbsvcs/tests/FaultTolerance/IOGRManipulation/FaultTolerance_IOGRManipulation.mpc b/TAO/orbsvcs/tests/FaultTolerance/IOGRManipulation/FaultTolerance_IOGRManipulation.mpc index a7d46dbeccb..7c3d36af851 100644 --- a/TAO/orbsvcs/tests/FaultTolerance/IOGRManipulation/FaultTolerance_IOGRManipulation.mpc +++ b/TAO/orbsvcs/tests/FaultTolerance/IOGRManipulation/FaultTolerance_IOGRManipulation.mpc @@ -1,3 +1,3 @@ -project(IOGRTest): portableserver, orbsvcsexe, iormanip, ftorb { +project(IOGRTest): taoserver, orbsvcsexe, iormanip, ftorb, messaging { exename = IOGRTest } diff --git a/TAO/orbsvcs/tests/FaultTolerance/IOGRManipulation/IOGRTest.cpp b/TAO/orbsvcs/tests/FaultTolerance/IOGRManipulation/IOGRTest.cpp index 00138a7f466..c0120577eab 100644 --- a/TAO/orbsvcs/tests/FaultTolerance/IOGRManipulation/IOGRTest.cpp +++ b/TAO/orbsvcs/tests/FaultTolerance/IOGRManipulation/IOGRTest.cpp @@ -144,12 +144,12 @@ main (int argc, char *argv[]) // Property values // Major and Minor revision numbers - ft_tag_component.version.major = (CORBA::Octet) 1; - ft_tag_component.version.minor = (CORBA::Octet) 0; + ft_tag_component.component_version.major = (CORBA::Octet) 1; + ft_tag_component.component_version.minor = (CORBA::Octet) 0; // Domain id const char *id = "iogr_regression"; - ft_tag_component.ft_domain_id = id; + ft_tag_component.group_domain_id = id; // Object group id ft_tag_component.object_group_id = diff --git a/TAO/orbsvcs/tests/FaultTolerance/IOGRManipulation/Makefile b/TAO/orbsvcs/tests/FaultTolerance/IOGRManipulation/Makefile index 5e3e771b81b..7772f454da9 100644 --- a/TAO/orbsvcs/tests/FaultTolerance/IOGRManipulation/Makefile +++ b/TAO/orbsvcs/tests/FaultTolerance/IOGRManipulation/Makefile @@ -12,7 +12,7 @@ ifndef TAO_ROOT TAO_ROOT = $(ACE_ROOT)/TAO endif # ! TAO_ROOT -LDLIBS = -lTAO_FTORB -lTAO_IORManip -lTAO_PortableServer -lTAO_Valuetype -lTAO_ObjRefTemplate -lTAO_IORInterceptor -lTAO +LDLIBS = -lTAO_Messaging -lTAO_FTORB -lTAO_IORManip -lTAO_PortableServer -lTAO_Valuetype -lTAO_ObjRefTemplate -lTAO_IORInterceptor -lTAO PROG_SRCS = IOGRTest.cpp |