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
44 FTClientMain (const FTClientMain
& rhs
);
45 FTClientMain
& operator = (const FTClientMain
& rhs
);
54 const ACE_TCHAR
* inFileName_
;
67 StringVec replica_iors_
;
69 const char * replica_name_
;
70 FT_TEST::TestReplica_var replica_
;
74 FTClientMain::FTClientMain ()
79 , replica_name_("none")
83 FTClientMain::~FTClientMain ()
87 ACE_OS::fclose (this->inFile_
);
92 void FTClientMain::commandUsage(FILE* out
)
95 "Each command must be at the beginning of a separate line.\n"
96 "Everything after the command (and operand if any) is ignored.\n"
97 "Valid commands are:\n"
98 " Access via method call:\n"
99 " =N set counter to N\n"
100 " cN get counter and compare to N (c stands for \"check\"\n"
101 " +N increment counter by N\n"
102 " -N decrement counter by N\n"
103 " Access as attribute:\n"
104 " >N set attribute to N\n"
106 " Try methods to be used by fault tolerant infrastructure:\n"
112 " Simulate failure:\n"
113 " dN die on condition:\n"
117 " (FT_TestReplica interface)\n"
118 " d%d before state change\n"
119 " d%d after state change, before replication\n"
120 " d%d after replication, before reply\n"
121 " (Monitorable interface)\n"
122 " d%d during is alive\n"
123 " d%d is_alive returns false\n"
124 " (Updatable interface)\n"
125 " d%d during get update\n"
126 " d%d before set update\n"
127 " d%d after set update\n"
128 " (Checkpointable interface)\n"
129 " d%d during get state\n"
130 " d%d before set state\n"
131 " d%d after set state\n"
132 " Logistics commands:\n"
133 " # ignore this line (comment).\n"
134 " v set verbosity:\n"
135 " 0 don't check counter value.\n"
136 " 1 only display counter value mismatch.\n"
137 " 2 display counter value after every command (default).\n"
138 " 3 display commands.\n"
139 " 4 display method calls.\n"
140 " zN sleep N seconds.\n"
141 " q quit (end the client, not the replica(s).)\n"
142 " q1 quit (end the client, and shutdown the currently active replica.)\n"
143 " ? help (this message)\n",
144 FT_TEST::TestReplica::NOT_YET
,
145 FT_TEST::TestReplica::RIGHT_NOW
,
146 FT_TEST::TestReplica::WHILE_IDLE
,
147 FT_TEST::TestReplica::BEFORE_STATE_CHANGE
,
148 FT_TEST::TestReplica::BEFORE_REPLICATION
,
149 FT_TEST::TestReplica::BEFORE_REPLY
,
150 FT_TEST::TestReplica::DURING_IS_ALIVE
,
151 FT_TEST::TestReplica::DENY_IS_ALIVE
,
152 FT_TEST::TestReplica::DURING_GET_UPDATE
,
153 FT_TEST::TestReplica::BEFORE_SET_UPDATE
,
154 FT_TEST::TestReplica::AFTER_SET_UPDATE
,
155 FT_TEST::TestReplica::DURING_GET_STATE
,
156 FT_TEST::TestReplica::BEFORE_SET_STATE
,
157 FT_TEST::TestReplica::AFTER_SET_STATE
);
161 FTClientMain::parse_args (int argc
, ACE_TCHAR
*argv
[])
167 // note: dfnkx are simple_util options
168 // include them here so we can detect bad args
169 ACE_Get_Opt
get_opts (argc
, argv
, ACE_TEXT("c:f:"));
172 while (result
== 0 && (c
= get_opts ()) != -1)
178 this->inFileName_
= get_opts
.opt_arg ();
179 this->inFile_
= ACE_OS::fopen (this->inFileName_
, "r");
180 if(this->inFile_
&& !ferror (this->inFile_
))
182 ACE_OS::fprintf (stdout
, "FT Client: Reading commands from %s\n",
183 ACE_TEXT_ALWAYS_CHAR (this->inFileName_
));
184 this->commandIn_
= this->inFile_
;
188 ACE_OS::fprintf (stderr
, "FT Client: Can't open input file: %s\n",
189 ACE_TEXT_ALWAYS_CHAR (this->inFileName_
));
196 replica_iors_
.push_back(ACE_TEXT_ALWAYS_CHAR(get_opts
.opt_arg ()));
209 void FTClientMain::usage(FILE* out
)const
211 ACE_OS::fprintf (out
, "usage"
213 " [-f <ior file>]...\n");
216 int FTClientMain::pass (
219 ACE_CString
& command
,
224 ::FT::State_var state
;
225 unsigned long stateValue
= 0;
226 ::FT::State_var update
;
227 unsigned long updateValue
= 0;
229 while(more
&& result
== 0 && !feof (this->commandIn_
))
231 if (! retry
|| command
.length () == 0 )
234 char *str_
= ACE_OS::fgets (buffer
, sizeof(buffer
)-1, this->commandIn_
);
237 str_
= ACE_OS::strrchr (str_
, '\n');
245 if (command
.length() >0)
247 char op
= command
[0];
248 ACE_CString cdr
= command
.substr(1);
250 long operand
= ACE_OS::strtol(cdr
.c_str(),&junque
, 10);
252 if (this->verbose_
>= NOISY
)
254 ACE_OS::fprintf (stdout
, "FT Client: %s\n", command
.c_str());
257 // turn echo on (based on verbose)
258 // individual commands can turn it off
259 int echo
= this->verbose_
>= QUIET
;
270 if (this->verbose_
>= LOUD
)
272 ACE_OS::fprintf (stdout
, "FT Client: ->set(%ld);\n", operand
);
274 this->replica_
->set(operand
);
280 if (this->verbose_
>= LOUD
)
282 ACE_OS::fprintf (stdout
, "FT Client: ->get();\n");
284 long value
= this->replica_
->counter();
285 if (value
== operand
)
287 ACE_OS::fprintf (stdout
, "FT Client: Good: Read %ld expecting %ld\n", value
, operand
);
292 ACE_OS::fprintf (stdout
, "FT Client: Error: Read %ld expecting %ld\n", value
, operand
);
299 if (this->verbose_
>= LOUD
)
301 ACE_OS::fprintf (stdout
, "FT Client: ->counter(%ld);\n", operand
);
303 this->replica_
->counter(operand
);
309 if (this->verbose_
>= LOUD
)
311 ACE_OS::fprintf (stdout
, "FT Client: ->increment(%ld);\n", operand
);
313 this->replica_
->increment(operand
);
319 if (this->verbose_
>= LOUD
)
321 ACE_OS::fprintf (stdout
, "FT Client: ->increment(%ld);\n", -operand
);
323 this->replica_
->increment(-operand
);
329 if (this->verbose_
>= LOUD
)
331 ACE_OS::fprintf (stdout
, "FT Client: ->counter();\n");
333 long attribute
= this->replica_
->counter();
334 ACE_OS::fprintf (stdout
, "FT Client: Attribute: %ld\n", attribute
);
340 if (this->verbose_
>= LOUD
)
342 ACE_OS::fprintf (stdout
, "FT Client: ->is_alive();\n");
344 int alive
= this->replica_
->is_alive();
345 ACE_OS::fprintf (stdout
, "FT Client: Is alive? %d\n", alive
);
350 if (this->verbose_
>= LOUD
)
352 ACE_OS::fprintf (stdout
, "FT Client: ->die(%ld);\n", operand
);
354 this->replica_
->die(static_cast<FT_TEST::TestReplica::Bane
> (operand
));
360 if (this->verbose_
>= LOUD
)
362 ACE_OS::fprintf (stdout
, "FT Client: ->get_state();\n");
364 state
= this->replica_
->get_state();
365 stateValue
= counter
;
370 if (state
->length () > 0)
372 if (this->verbose_
>= LOUD
)
374 ACE_OS::fprintf (stdout
, "FT Client: ->set_state(saved_state);\n");
376 this->replica_
->set_state (state
.in ());
377 counter
= stateValue
;
381 ACE_OS::fprintf (stdout
, "FT Client: Error: no saved state.\n");
387 if (this->verbose_
>= LOUD
)
389 ACE_OS::fprintf (stdout
, "FT Client: ->get_update();\n");
391 update
= this->replica_
->get_update();
392 updateValue
= counter
;
397 if (update
->length () > 0)
399 if (this->verbose_
>= LOUD
)
401 ACE_OS::fprintf (stdout
, "FT Client: ->set_update(saved_update);\n");
403 this->replica_
->set_update(update
.in ());
404 counter
= updateValue
;
408 ACE_OS::fprintf (stdout
, "FT Client: ERROR: No saved update information.\n");
414 this->verbose_
= static_cast<Verbosity
> (operand
);
423 ACE_Time_Value
tv (operand
,0);
433 if (this->verbose_
>= LOUD
)
435 ACE_OS::fprintf (stdout
, "FT Client: ->shutdown();\n");
437 this->replica_
->shutdown();
438 // @@ Note: this is here because the corba event loop seems to go to sleep
439 // if there's nothing for it to do.
440 // not quite sure why, yet. Dale
441 this->replica_
->is_alive();
443 catch (const CORBA::Exception
&)
445 ACE_OS::fprintf (stdout
, "FT Client: Ignoring expected exception during shutdown.\n");
446 ; // ignore exception during shutdown
457 ACE_OS::fprintf (stdout
, "FT Client: Unknown: %s\n", command
.c_str());
459 commandUsage(stderr
);
463 if (echo
&& this->verbose_
>= QUIET
)
465 if (this->verbose_
>= LOUD
)
467 ACE_OS::fprintf (stdout
, "FT Client: ->get();\n");
470 long value
= this->replica_
->get();
471 if (value
== counter
)
473 if (this->verbose_
>= NORMAL
)
475 ACE_OS::fprintf (stdout
, "FT Client: %ld\n", counter
);
480 ACE_OS::fprintf (stdout
, "FT Client: Error: read %ld expecting %ld\n", value
, counter
);
489 int FTClientMain::next_replica ()
492 if (this->replica_pos_
< this->replica_iors_
.size())
494 this->replica_name_
= this->replica_iors_
[this->replica_pos_
].c_str();
495 this->replica_pos_
+= 1;
496 CORBA::Object_var rep_obj
= this->orb_
->string_to_object (this->replica_name_
);
497 this->replica_
= FT_TEST::TestReplica::_narrow (rep_obj
.in ());
498 if (! CORBA::is_nil (replica_
.in ()))
504 ACE_OS::fprintf (stderr
, "FT Client: Can't resolve IOR: %s\n", this->replica_name_
);
509 ACE_OS::fprintf (stderr
,
510 "***OUT_OF_REPLICAS*** "
511 ACE_SIZE_T_FORMAT_SPECIFIER_ASCII
519 int FTClientMain::run ()
523 this->orb_
= CORBA::ORB_init(this->argc_
, this->argv_
);
525 int ok
= next_replica ();
531 long counter
= this->replica_
->get();
533 if (this->verbose_
>= NORMAL
)
535 ACE_OS::fprintf (stdout
, "FT Client: Initial counter %ld\n", counter
);
537 if (ACE_OS::isatty(ACE_OS::fileno(stdin
)))
539 ACE_OS::fprintf (stdout
, "FT Client: Commands(? for help):\n");
543 while (more
&& result
== 0 && !feof (this->commandIn_
))
547 result
= pass (counter
, more
, command
, retry
);
549 catch (const CORBA::SystemException
& sysex
)
551 ACE_OS::fprintf (stdout
, "FT Client: Caught system exception:\n");
552 sysex
._tao_print_exception ("FT Client");
557 handled
= next_replica();
560 ACE_OS::fprintf (stdout
, "FT Client: Recovering from fault.\n");
561 ACE_OS::fprintf (stdout
, "FT Client: Activate %s\n", this->replica_name_
);
562 if (command
.length () == 0)
564 ACE_OS::fprintf (stdout
, "FT Client: No command to retry.\n");
566 else if (command
[0] == 'd')
568 ACE_OS::fprintf (stdout
, "FT Client: Not retrying \"die\" command.\n");
570 else if (sysex
.completed () == CORBA::COMPLETED_YES
)
572 ACE_OS::fprintf (stdout
, "FT Client: Last command completed. No retry needed.\n");
576 if (sysex
.completed () == CORBA::COMPLETED_MAYBE
)
578 ACE_OS::fprintf (stdout
, "FT Client: Last command may have completed. Retrying anyway.\n");
581 ACE_OS::fprintf (stdout
, "FT Client: Retrying command: %s\n", command
.c_str());
586 ACE_OS::fprintf (stdout
, "FT Client: Exception not handled. Rethrow. ");
594 ACE_OS::fprintf (stderr
, "FT Client: Can't connect to replica.\n");
601 ACE_TMAIN(int argc
, ACE_TCHAR
*argv
[])
604 int result
= app
.parse_args(argc
, argv
);
611 catch (const CORBA::Exception
& ex
)
613 ex
._tao_print_exception ("FT_Client::main\t\n");