1 #include "FT_TestReplicaC.h"
2 #include <ace/Vector_T.h>
3 #include <ace/SString.h>
4 #include <ace/Get_Opt.h>
5 // FUZZ: disable check_for_streams_include
6 #include "ace/streams.h"
7 #include "ace/OS_NS_unistd.h"
8 #include "ace/OS_NS_stdio.h"
12 typedef ACE_Vector
<ACE_CString
> StringVec
;
14 ///////////////////////////
15 // construction/destruction
22 int parse_args (int argc
, ACE_TCHAR
*argv
[]);
31 void usage (FILE* out
)const;
32 void commandUsage (FILE* out
);
34 long & counter
, // inout
36 ACE_CString
& command
, // inout
41 int next_replica (void);
46 FTClientMain (const FTClientMain
& rhs
);
47 FTClientMain
& operator = (const FTClientMain
& rhs
);
57 const ACE_TCHAR
* inFileName_
;
70 StringVec replica_iors_
;
72 const char * replica_name_
;
73 FT_TEST::TestReplica_var replica_
;
77 FTClientMain::FTClientMain ()
82 , replica_name_("none")
86 FTClientMain::~FTClientMain ()
90 ACE_OS::fclose (this->inFile_
);
95 void FTClientMain::commandUsage(FILE* out
)
98 "Each command must be at the beginning of a separate line.\n"
99 "Everything after the command (and operand if any) is ignored.\n"
100 "Valid commands are:\n"
101 " Access via method call:\n"
102 " =N set counter to N\n"
103 " cN get counter and compare to N (c stands for \"check\"\n"
104 " +N increment counter by N\n"
105 " -N decrement counter by N\n"
106 " Access as attribute:\n"
107 " >N set attribute to N\n"
109 " Try methods to be used by fault tolerant infrastructure:\n"
115 " Simulate failure:\n"
116 " dN die on condition:\n"
120 " (FT_TestReplica interface)\n"
121 " d%d before state change\n"
122 " d%d after state change, before replication\n"
123 " d%d after replication, before reply\n"
124 " (Monitorable interface)\n"
125 " d%d during is alive\n"
126 " d%d is_alive returns false\n"
127 " (Updatable interface)\n"
128 " d%d during get update\n"
129 " d%d before set update\n"
130 " d%d after set update\n"
131 " (Checkpointable interface)\n"
132 " d%d during get state\n"
133 " d%d before set state\n"
134 " d%d after set state\n"
135 " Logistics commands:\n"
136 " # ignore this line (comment).\n"
137 " v set verbosity:\n"
138 " 0 don't check counter value.\n"
139 " 1 only display counter value mismatch.\n"
140 " 2 display counter value after every command (default).\n"
141 " 3 display commands.\n"
142 " 4 display method calls.\n"
143 " zN sleep N seconds.\n"
144 " q quit (end the client, not the replica(s).)\n"
145 " q1 quit (end the client, and shutdown the currently active replica.)\n"
146 " ? help (this message)\n",
147 FT_TEST::TestReplica::NOT_YET
,
148 FT_TEST::TestReplica::RIGHT_NOW
,
149 FT_TEST::TestReplica::WHILE_IDLE
,
150 FT_TEST::TestReplica::BEFORE_STATE_CHANGE
,
151 FT_TEST::TestReplica::BEFORE_REPLICATION
,
152 FT_TEST::TestReplica::BEFORE_REPLY
,
153 FT_TEST::TestReplica::DURING_IS_ALIVE
,
154 FT_TEST::TestReplica::DENY_IS_ALIVE
,
155 FT_TEST::TestReplica::DURING_GET_UPDATE
,
156 FT_TEST::TestReplica::BEFORE_SET_UPDATE
,
157 FT_TEST::TestReplica::AFTER_SET_UPDATE
,
158 FT_TEST::TestReplica::DURING_GET_STATE
,
159 FT_TEST::TestReplica::BEFORE_SET_STATE
,
160 FT_TEST::TestReplica::AFTER_SET_STATE
);
164 FTClientMain::parse_args (int argc
, ACE_TCHAR
*argv
[])
170 // note: dfnkx are simple_util options
171 // include them here so we can detect bad args
172 ACE_Get_Opt
get_opts (argc
, argv
, ACE_TEXT("c:f:"));
175 while (result
== 0 && (c
= get_opts ()) != -1)
181 this->inFileName_
= get_opts
.opt_arg ();
182 this->inFile_
= ACE_OS::fopen (this->inFileName_
, "r");
183 if(this->inFile_
&& !ferror (this->inFile_
))
185 ACE_OS::fprintf (stdout
, "FT Client: Reading commands from %s\n",
186 ACE_TEXT_ALWAYS_CHAR (this->inFileName_
));
187 this->commandIn_
= this->inFile_
;
191 ACE_OS::fprintf (stderr
, "FT Client: Can't open input file: %s\n",
192 ACE_TEXT_ALWAYS_CHAR (this->inFileName_
));
199 replica_iors_
.push_back(ACE_TEXT_ALWAYS_CHAR(get_opts
.opt_arg ()));
212 void FTClientMain::usage(FILE* out
)const
214 ACE_OS::fprintf (out
, "usage"
216 " [-f <ior file>]...\n");
219 int FTClientMain::pass (
222 ACE_CString
& command
,
227 ::FT::State_var state
;
228 unsigned long stateValue
= 0;
229 ::FT::State_var update
;
230 unsigned long updateValue
= 0;
232 while(more
&& result
== 0 && !feof (this->commandIn_
))
234 if (! retry
|| command
.length () == 0 )
237 char *str_
= ACE_OS::fgets (buffer
, sizeof(buffer
)-1, this->commandIn_
);
240 str_
= ACE_OS::strrchr (str_
, '\n');
248 if (command
.length() >0)
250 char op
= command
[0];
251 ACE_CString cdr
= command
.substr(1);
253 long operand
= ACE_OS::strtol(cdr
.c_str(),&junque
, 10);
255 if (this->verbose_
>= NOISY
)
257 ACE_OS::fprintf (stdout
, "FT Client: %s\n", command
.c_str());
260 // turn echo on (based on verbose)
261 // individual commands can turn it off
262 int echo
= this->verbose_
>= QUIET
;
273 if (this->verbose_
>= LOUD
)
275 ACE_OS::fprintf (stdout
, "FT Client: ->set(%ld);\n", operand
);
277 this->replica_
->set(operand
);
283 if (this->verbose_
>= LOUD
)
285 ACE_OS::fprintf (stdout
, "FT Client: ->get();\n");
287 long value
= this->replica_
->counter();
288 if (value
== operand
)
290 ACE_OS::fprintf (stdout
, "FT Client: Good: Read %ld expecting %ld\n", value
, operand
);
295 ACE_OS::fprintf (stdout
, "FT Client: Error: Read %ld expecting %ld\n", value
, operand
);
303 if (this->verbose_
>= LOUD
)
305 ACE_OS::fprintf (stdout
, "FT Client: ->counter(%ld);\n", operand
);
307 this->replica_
->counter(operand
);
313 if (this->verbose_
>= LOUD
)
315 ACE_OS::fprintf (stdout
, "FT Client: ->increment(%ld);\n", operand
);
317 this->replica_
->increment(operand
);
323 if (this->verbose_
>= LOUD
)
325 ACE_OS::fprintf (stdout
, "FT Client: ->increment(%ld);\n", -operand
);
327 this->replica_
->increment(-operand
);
333 if (this->verbose_
>= LOUD
)
335 ACE_OS::fprintf (stdout
, "FT Client: ->counter();\n");
337 long attribute
= this->replica_
->counter();
338 ACE_OS::fprintf (stdout
, "FT Client: Attribute: %ld\n", attribute
);
344 if (this->verbose_
>= LOUD
)
346 ACE_OS::fprintf (stdout
, "FT Client: ->is_alive();\n");
348 int alive
= this->replica_
->is_alive();
349 ACE_OS::fprintf (stdout
, "FT Client: Is alive? %d\n", alive
);
354 if (this->verbose_
>= LOUD
)
356 ACE_OS::fprintf (stdout
, "FT Client: ->die(%ld);\n", operand
);
358 this->replica_
->die(static_cast<FT_TEST::TestReplica::Bane
> (operand
));
364 if (this->verbose_
>= LOUD
)
366 ACE_OS::fprintf (stdout
, "FT Client: ->get_state();\n");
368 state
= this->replica_
->get_state();
369 stateValue
= counter
;
374 if (state
->length () > 0)
376 if (this->verbose_
>= LOUD
)
378 ACE_OS::fprintf (stdout
, "FT Client: ->set_state(saved_state);\n");
380 this->replica_
->set_state (state
.in ());
381 counter
= stateValue
;
385 ACE_OS::fprintf (stdout
, "FT Client: Error: no saved state.\n");
391 if (this->verbose_
>= LOUD
)
393 ACE_OS::fprintf (stdout
, "FT Client: ->get_update();\n");
395 update
= this->replica_
->get_update();
396 updateValue
= counter
;
401 if (update
->length () > 0)
403 if (this->verbose_
>= LOUD
)
405 ACE_OS::fprintf (stdout
, "FT Client: ->set_update(saved_update);\n");
407 this->replica_
->set_update(update
.in ());
408 counter
= updateValue
;
412 ACE_OS::fprintf (stdout
, "FT Client: ERROR: No saved update information.\n");
418 this->verbose_
= static_cast<Verbosity
> (operand
);
427 ACE_Time_Value
tv (operand
,0);
437 if (this->verbose_
>= LOUD
)
439 ACE_OS::fprintf (stdout
, "FT Client: ->shutdown();\n");
441 this->replica_
->shutdown();
442 // @@ Note: this is here because the corba event loop seems to go to sleep
443 // if there's nothing for it to do.
444 // not quite sure why, yet. Dale
445 this->replica_
->is_alive();
447 catch (const CORBA::Exception
&)
449 ACE_OS::fprintf (stdout
, "FT Client: Ignoring expected exception during shutdown.\n");
450 ; // ignore exception during shutdown
461 ACE_OS::fprintf (stdout
, "FT Client: Unknown: %s\n", command
.c_str());
463 commandUsage(stderr
);
467 if (echo
&& this->verbose_
>= QUIET
)
469 if (this->verbose_
>= LOUD
)
471 ACE_OS::fprintf (stdout
, "FT Client: ->get();\n");
474 long value
= this->replica_
->get();
475 if (value
== counter
)
477 if (this->verbose_
>= NORMAL
)
479 ACE_OS::fprintf (stdout
, "FT Client: %ld\n", counter
);
484 ACE_OS::fprintf (stdout
, "FT Client: Error: read %ld expecting %ld\n", value
, counter
);
493 int FTClientMain::next_replica (void)
496 if (this->replica_pos_
< this->replica_iors_
.size())
498 this->replica_name_
= this->replica_iors_
[this->replica_pos_
].c_str();
499 this->replica_pos_
+= 1;
500 CORBA::Object_var rep_obj
= this->orb_
->string_to_object (this->replica_name_
);
501 this->replica_
= FT_TEST::TestReplica::_narrow (rep_obj
.in ());
502 if (! CORBA::is_nil (replica_
.in ()))
508 ACE_OS::fprintf (stderr
, "FT Client: Can't resolve IOR: %s\n", this->replica_name_
);
513 ACE_OS::fprintf (stderr
,
514 "***OUT_OF_REPLICAS*** "
515 ACE_SIZE_T_FORMAT_SPECIFIER_ASCII
523 int FTClientMain::run (void)
527 this->orb_
= CORBA::ORB_init(this->argc_
, this->argv_
);
529 int ok
= next_replica ();
535 long counter
= this->replica_
->get();
537 if (this->verbose_
>= NORMAL
)
539 ACE_OS::fprintf (stdout
, "FT Client: Initial counter %ld\n", counter
);
541 if (ACE_OS::isatty(ACE_OS::fileno(stdin
)))
543 ACE_OS::fprintf (stdout
, "FT Client: Commands(? for help):\n");
547 while (more
&& result
== 0 && !feof (this->commandIn_
))
551 result
= pass (counter
, more
, command
, retry
);
553 catch (const CORBA::SystemException
& sysex
)
555 ACE_OS::fprintf (stdout
, "FT Client: Caught system exception:\n");
556 sysex
._tao_print_exception ("FT Client");
561 handled
= next_replica();
564 ACE_OS::fprintf (stdout
, "FT Client: Recovering from fault.\n");
565 ACE_OS::fprintf (stdout
, "FT Client: Activate %s\n", this->replica_name_
);
566 if (command
.length () == 0)
568 ACE_OS::fprintf (stdout
, "FT Client: No command to retry.\n");
570 else if (command
[0] == 'd')
572 ACE_OS::fprintf (stdout
, "FT Client: Not retrying \"die\" command.\n");
574 else if (sysex
.completed () == CORBA::COMPLETED_YES
)
576 ACE_OS::fprintf (stdout
, "FT Client: Last command completed. No retry needed.\n");
580 if (sysex
.completed () == CORBA::COMPLETED_MAYBE
)
582 ACE_OS::fprintf (stdout
, "FT Client: Last command may have completed. Retrying anyway.\n");
585 ACE_OS::fprintf (stdout
, "FT Client: Retrying command: %s\n", command
.c_str());
590 ACE_OS::fprintf (stdout
, "FT Client: Exception not handled. Rethrow. ");
598 ACE_OS::fprintf (stderr
, "FT Client: Can't connect to replica.\n");
605 ACE_TMAIN(int argc
, ACE_TCHAR
*argv
[])
608 int result
= app
.parse_args(argc
, argv
);
615 catch (const CORBA::Exception
& ex
)
617 ex
._tao_print_exception ("FT_Client::main\t\n");