1
// FT_Client.cpp,v 1.2 2003/12/22 01:44:38 wilson_d Exp
3
#include "FT_TestReplicaC.h"
4
#include <ace/Vector_T.h>
5
#include <ace/SString.h>
6
#include <ace/Get_Opt.h>
12
typedef ACE_Vector<ACE_CString> StringVec;
14
///////////////////////////
15
// construction/destruction
22
int parse_args (int argc, char *argv[]);
31
void usage (ostream & out)const;
32
void commandUsage (ostream & out);
34
long & counter, // inout
36
ACE_CString & command, // inout
41
int next_replica (ACE_ENV_SINGLE_ARG_DECL);
46
FTClientMain (const FTClientMain & rhs);
47
FTClientMain & operator = (const FTClientMain & rhs);
57
const char * inFileName_;
58
std::ifstream inFile_;
59
std::istream *commandIn_;
70
StringVec replica_iors_;
72
const char * replica_name_;
73
FT_TEST::TestReplica_var replica_;
77
FTClientMain::FTClientMain ()
78
: commandIn_(&std::cin)
81
, replica_name_("none")
85
FTClientMain::~FTClientMain ()
87
if (this->inFile_.is_open())
89
this->inFile_.close();
93
void FTClientMain::commandUsage(ostream & out)
96
<< "Each command must be at the beginning of a separate line." << std::endl
97
<< "Everything after the command (and operand if any) is ignored." << std::endl
98
<< "Valid commands are:" << std::endl
99
<< " Access via method call:" << std::endl
100
<< " =N set counter to N" << std::endl
101
<< " cN get counter and compare to N (c stands for \"check\""<< std::endl
102
<< " +N increment counter by N" << std::endl
103
<< " -N decrement counter by N" << std::endl
104
<< " Access as attribute:" << std::endl
105
<< " >N set attribute to N" << std::endl
106
<< " < get attribite" << std::endl
107
<< " Try methods to be used by fault tolerant infrastructure: " << std::endl
108
<< " ! is_alive" << std::endl
109
<< " s get_state" << std::endl
110
<< " S set_state" << std::endl
111
<< " u get_update" << std::endl
112
<< " U set_update" << std::endl
113
<< " Simulate failure:" << std::endl
114
<< " dN die on condition:" << std::endl
115
<< " d" << FT_TEST::TestReplica::NOT_YET << " don't die" << std::endl
116
<< " d" << FT_TEST::TestReplica::RIGHT_NOW << " immediately" << std::endl
117
<< " d" << FT_TEST::TestReplica::WHILE_IDLE << " while idle" << std::endl
118
<< " (FT_TestReplica interface)" << std::endl
119
<< " d" << FT_TEST::TestReplica::BEFORE_STATE_CHANGE << " before state change" << std::endl
120
<< " d" << FT_TEST::TestReplica::BEFORE_REPLICATION << " after state change, before replication" << std::endl
121
<< " d" << FT_TEST::TestReplica::BEFORE_REPLY << " after replication, before reply "<< std::endl
122
<< " (Monitorable interface)" << std::endl
123
<< " d" << FT_TEST::TestReplica::DURING_IS_ALIVE << " during is alive" << std::endl
124
<< " d" << FT_TEST::TestReplica::DENY_IS_ALIVE << " is_alive returns false" << std::endl
125
<< " (Updatable interface)" << std::endl
126
<< " d" << FT_TEST::TestReplica::DURING_GET_UPDATE << " during get update" << std::endl
127
<< " d" << FT_TEST::TestReplica::BEFORE_SET_UPDATE << " before set update" << std::endl
128
<< " d" << FT_TEST::TestReplica::AFTER_SET_UPDATE << " after set update" << std::endl
129
<< " (Checkpointable interface)" << std::endl
130
<< " d" << FT_TEST::TestReplica::DURING_GET_STATE << " during get state" << std::endl
131
<< " d" << FT_TEST::TestReplica::BEFORE_SET_STATE << " before set state" << std::endl
132
<< " d" << FT_TEST::TestReplica::AFTER_SET_STATE << " after set state" << std::endl
133
<< " Logistics commands:" << std::endl
134
<< " # ignore this line (comment)." << std::endl
135
<< " v set verbosity:" << std::endl
136
<< " 0 don't check counter value." << std::endl
137
<< " 1 only display counter value mismatch." << std::endl
138
<< " 2 display counter value after every command (default)." << std::endl
139
<< " 3 display commands." << std::endl
140
<< " 4 display method calls." << std::endl
141
<< " zN sleep N seconds." << std::endl
142
<< " q quit (end the client, not the replica(s).)" << std::endl
143
<< " q1 quit (end the client, and shutdown the currently active replica.)" << std::endl
144
<< " ? help (this message)" << std::endl;
148
FTClientMain::parse_args (int argc, char *argv[])
154
// note: dfnkx are simple_util options
155
// include them here so we can detect bad args
156
ACE_Get_Opt get_opts (argc, argv, "c:f:");
159
while (result == 0 && (c = get_opts ()) != -1)
165
this->inFileName_ = get_opts.opt_arg ();
166
this->inFile_.open(this->inFileName_);
167
if(this->inFile_.is_open() && this->inFile_.good())
169
std::cout << "FT Client: Reading commands from " << this->inFileName_ << std::endl;
170
this->commandIn_ = & this->inFile_;
174
std::cout << "FT Client: Can't open input file: " << this->inFileName_ << std::endl;
181
replica_iors_.push_back(get_opts.opt_arg ());
194
void FTClientMain::usage(ostream & out)const
197
<< " -c <command file>"
198
<< " [-f <ior file>]..."
202
int FTClientMain::pass (
205
ACE_CString & command,
210
::FT::State_var state;
211
unsigned long stateValue = 0;
212
::FT::State_var update;
213
unsigned long updateValue = 0;
215
while(more && result == 0 && ! this->commandIn_->eof())
217
if (! retry || command.length () == 0 )
220
this->commandIn_->getline(buffer, sizeof(buffer)-1);
225
if (command.length() >0)
227
char op = command[0];
228
ACE_CString cdr = command.substr(1);
230
long operand = strtol(cdr.c_str(),&junque, 10);
232
if (this->verbose_ >= NOISY)
234
std::cout << "FT Client: " << command << std::endl;
237
// turn echo on (based on verbose)
238
// individual commands can turn it off
239
int echo = this->verbose_ >= QUIET;
250
if (this->verbose_ >= LOUD)
252
std::cout << "FT Client: ->set(" << operand << ");" << std::endl;
254
this->replica_->set(operand ACE_ENV_ARG_PARAMETER);
255
ACE_CHECK_RETURN (-1);
261
if (this->verbose_ >= LOUD)
263
std::cout << "FT Client: ->get();" << std::endl;
265
long value = this->replica_->counter(ACE_ENV_SINGLE_ARG_PARAMETER);
266
ACE_CHECK_RETURN (-1);
267
if (value == operand)
269
std::cout << "FT Client: Good: Read " << value << " expecting " << operand << std::endl;
274
std::cout << "FT Client: Error: Read " << value << " expecting " << operand << std::endl;
282
if (this->verbose_ >= LOUD)
284
std::cout << "FT Client: ->counter(" << operand << ");" << std::endl;
286
this->replica_->counter(operand ACE_ENV_ARG_PARAMETER);
287
ACE_CHECK_RETURN (-1);
293
if (this->verbose_ >= LOUD)
295
std::cout << "FT Client: ->increment(" << operand << ");" << std::endl;
297
this->replica_->increment(operand ACE_ENV_ARG_PARAMETER);
298
ACE_CHECK_RETURN (-1);
304
if (this->verbose_ >= LOUD)
306
std::cout << "FT Client: ->increment(" << -operand << ");" << std::endl;
308
this->replica_->increment(-operand ACE_ENV_ARG_PARAMETER);
309
ACE_CHECK_RETURN (-1);
315
if (this->verbose_ >= LOUD)
317
std::cout << "FT Client: ->counter();" << std::endl;
319
long attribute = this->replica_->counter(ACE_ENV_SINGLE_ARG_PARAMETER);
320
ACE_CHECK_RETURN (-1);
321
std::cout << "FT Client: Attribute: " << attribute << std::endl;
327
if (this->verbose_ >= LOUD)
329
std::cout << "FT Client: ->is_alive();" << std::endl;
331
int alive = this->replica_->is_alive(ACE_ENV_SINGLE_ARG_PARAMETER);
332
ACE_CHECK_RETURN (-1);
333
std::cout << "FT Client: Is alive? " << alive << std::endl;
338
if (this->verbose_ >= LOUD)
340
std::cout << "FT Client: ->die(" << operand << ");" << std::endl;
342
this->replica_->die(ACE_static_cast (FT_TEST::TestReplica::Bane, operand) ACE_ENV_ARG_PARAMETER);
343
ACE_CHECK_RETURN (-1);
349
if (this->verbose_ >= LOUD)
351
std::cout << "FT Client: ->get_state();" << std::endl;
353
state = this->replica_->get_state(ACE_ENV_SINGLE_ARG_PARAMETER);
354
ACE_CHECK_RETURN (-1);
355
stateValue = counter;
362
if (this->verbose_ >= LOUD)
364
std::cout << "FT Client: ->set_state(saved_state);" << std::endl;
366
this->replica_->set_state(state ACE_ENV_ARG_PARAMETER);
367
ACE_CHECK_RETURN (-1);
368
counter = stateValue;
372
std::cout << "FT Client: Error: no saved state." << std::endl;
378
if (this->verbose_ >= LOUD)
380
std::cout << "FT Client: ->get_update();" << std::endl;
382
update = this->replica_->get_update(ACE_ENV_SINGLE_ARG_PARAMETER);
383
ACE_CHECK_RETURN (-1);
384
updateValue = counter;
389
if (update.in() != 0)
391
if (this->verbose_ >= LOUD)
393
std::cout << "FT Client: ->set_update(saved_update);" << std::endl;
395
this->replica_->set_update(update ACE_ENV_ARG_PARAMETER);
396
ACE_CHECK_RETURN (-1);
397
counter = updateValue;
401
std::cout << "FT Client: ERROR: No saved update information." << std::endl;
407
this->verbose_ = ACE_static_cast(Verbosity, operand);
416
ACE_Time_Value tv (operand,0);
426
if (this->verbose_ >= LOUD)
428
std::cout << "FT Client: ->shutdown();" << std::endl;
430
this->replica_->shutdown( ACE_ENV_SINGLE_ARG_PARAMETER);
431
// @@ Note: this is here because the corba event loop seems to go to sleep
432
// if there's nothing for it to do.
433
// not quite sure why, yet. Dale
434
this->replica_->is_alive(ACE_ENV_SINGLE_ARG_PARAMETER);
438
std::cout << "FT Client: Ignoring expected exception during shutdown." << std::endl;
439
; // ignore exception during shutdown
451
std::cout << "FT Client: Unknown: " << command << std::endl;
453
commandUsage(std::cerr);
457
if (echo && this->verbose_ >= QUIET)
459
if (this->verbose_ >= LOUD)
461
std::cout << "FT Client: ->get();" << std::endl;
464
long value = this->replica_->get(ACE_ENV_SINGLE_ARG_PARAMETER);
465
ACE_CHECK_RETURN (-1);
466
if (value == counter)
468
if (this->verbose_ >= NORMAL)
470
std::cout << "FT Client: " << counter << std::endl;;
475
std::cout << "FT Client: Error: read " << value << " expecting " << counter << std::endl;
484
int FTClientMain::next_replica (ACE_ENV_SINGLE_ARG_DECL)
487
if (this->replica_pos_ < this->replica_iors_.size())
489
this->replica_name_ = this->replica_iors_[this->replica_pos_].c_str();
490
this->replica_pos_ += 1;
491
CORBA::Object_var rep_obj = this->orb_->string_to_object (this->replica_name_ ACE_ENV_ARG_PARAMETER);
493
replica_ = FT_TEST::TestReplica::_narrow (rep_obj.in ());
494
if (! CORBA::is_nil (replica_.in ()))
500
std::cerr << "FT Client: Can't resolve IOR: " << this->replica_name_ << std::endl;
505
std::cerr << "***OUT_OF_REPLICAS*** " << this->replica_pos_ << std::endl;
511
int FTClientMain::run ()
515
this->orb_ = CORBA::ORB_init(this->argc_, this->argv_ ACE_ENV_ARG_PARAMETER);
516
ACE_CHECK_RETURN (-1)
523
long counter = this->replica_->get(ACE_ENV_SINGLE_ARG_PARAMETER);
524
ACE_CHECK_RETURN (-1);
526
if (this->verbose_ >= NORMAL)
528
std::cout << "FT Client: Initial counter " << counter << std::endl;
530
if (ACE_OS::isatty(fileno(stdin)))
532
std::cout << "FT Client: Commands(? for help):" << std::endl;
536
while (more && result == 0 && ! this->commandIn_->eof())
540
result = pass (counter, more, command, retry);
543
ACE_CATCH (CORBA::SystemException, sysex)
545
std::cout << "FT Client: Caught system exception: " << std::endl;
546
ACE_PRINT_EXCEPTION (sysex, "FT Client");
551
handled = next_replica();
554
std::cout << "FT Client: Recovering from fault." << std::endl;
555
std::cout << "FT Client: Activate " << this->replica_name_ << std::endl;
556
if (command.length () == 0)
558
std::cout << "FT Client: No command to retry." << std::endl;
560
else if (command[0] == 'd')
562
std::cout << "FT Client: Not retrying \"die\" command." << std::endl;
564
else if (sysex.completed () == CORBA::COMPLETED_YES)
566
std::cout << "FT Client: Last command completed. No retry needed." << std::endl;
570
if (sysex.completed () == CORBA::COMPLETED_MAYBE)
572
std::cout << "FT Client: Last command may have completed. Retrying anyway." << std::endl;
575
std::cout << "FT Client: Retrying command: " << command << std::endl;
580
std::cout << "FT Client: Exception not handled. Rethrow. " << std::endl;
589
std::cerr << "FT Client: Can't connect to replica." << std::endl;
596
main (int argc, char *argv[])
599
int result = app.parse_args(argc, argv);
608
ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,
609
"FT_Client::main\t\n");
617
#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
618
template class ACE_Vector<ACE_CString>;
619
#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
620
# pragma ACE_Vector<ACE_CString>
621
#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */