/**
@page run_test_howto How to write a run_test.pl

ACE/TAO's auto_builds expect run_test.pl's to follow some guidelines
that are needed to keep the auto_builds from hanging and to make
sure the run_test.pl works on all platforms

- The run_test must not hang or block.
- The run_test must clean up any temporary files when it is done.
- The run_test must not require any user input
- The run_test should return a non-zero value if the test failed
- When an executable can't be spawned the test should directly exit and
  not wait for a fail to be created by that executable

Following is an example

@subsection example Example

@verbatim
eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
    & eval 'exec perl -S $0 $argv:q'
    if 0;

# $Id: run_test.txt 78057 2007-04-17 08:13:54Z johnnyw $
# -*- perl -*-

use lib "$ENV{ACE_ROOT}/bin";
use PerlACE::Run_Test;

$status = 0;

$plain_server_ior = "server.ior";
$server_ior = PerlACE::LocalFile ("$plain_server_ior");
unlink $server_ior;

if (PerlACE::is_vxworks_test()) {
    $SV = new PerlACE::ProcessVX ("server", "-o $plain_server_ior");
}
else {
    $SV = new PerlACE::Process ("server", "-o $server_ior_file");
}

$CL = new PerlACE::Process ("client", "-k file://$server_ior");

$server = $SV->Spawn ();

if ($server != 0) {
    print STDERR "ERROR: server returned $server\n";
    $status = 1;
}

if (PerlACE::waitforfile_timed ($server_ior, $PerlACE::wait_interval_for_process_creation) == -1) {
    print STDERR "ERROR: cannot find file <$server_ior>\n";
    $SV->Kill ();
    exit 1;
}

$client = $CL->SpawnWaitKill (60);

if ($client != 0) {
    print STDERR "ERROR: client returned $client\n";
    $status = 1;
}

$server = $SV->TerminateWaitKill (5);

if ($server != 0) {
    print STDERR "ERROR: server returned $server\n";
    $status = 1;
}

unlink $server_ior;

exit $status;
@endverbatim

@subsection details Example Details

@verbatim
eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
    & eval 'exec perl -S $0 $argv:q'
    if 0;

# $Id: run_test.txt 78057 2007-04-17 08:13:54Z johnnyw $
@endverbatim

This is the standard header stuff.  The eval is a trick used
to get the perl script to run if it a unix shell treats it as
a shell script.

The SVN ID string is the usual one we put in.

@verbatim
use lib "$ENV{ACE_ROOT}/bin";
use PerlACE::Run_Test;
@endverbatim

The use lib line is used to tell Perl where the PerlACE modules are.
It should NOT be a relative path to the bin directory.  This is how
it used to be done, but doing so would be incompatible with the "flat"
directory layout of ACE+TAO.  The correct way is demonstrated above.
After the "use lib" line, always use $PerlACE::TAO_ROOT to reference
the location of TAO.  Use either $ENV{ACE_ROOT} or $PerlACE::ACE_ROOT
to reference the location of ACE.

And PerlACE::Run_Test is a module to be used by all run_test.pl's.
It does a couple of things, including parsing some common command
line arguments (like -Config and -ExeSubDir) and also brings in
the PerlACE::Process module.

@verbatim
$status = 0;

$server_ior = PerlACE::LocalFile ("server.ior");

unlink $server_ior;
@endverbatim

Because of the way tests work on chorus, we need to have a fully
qualified path to all *.ior and *.conf files.  We unlink the file
immediately because we use PerlACE::waitforfile_timed later.

@verbatim
if (PerlACE::is_vxworks_test()) {
    $SV = new PerlACE::ProcessVX ("server", "-o $plain_server_ior");
}
else {
    $SV = new PerlACE::Process ("server", "-o $server_ior_file");
}
@endverbatim

We check using PerlACE::is_vxworks_test() if we are testing for VxWorks. At
that moment we have to run on part of the test on the target, the other
part on the host system. The part that has to run on the target has to
be created as PerlACE::ProcessVX. When using VxWorks the files shouldn't
be passed in created by PerlACE::LocalFile because that refers to the
ior file on the host system, that is not reachable for the target, so
the plain text filename should be passed.

@verbatim
$CL = new PerlACE::Process ("client", " -k file://$server_ior ");

$server = $SV->Spawn ();

if ($server != 0) {
    print STDERR "ERROR: server returned $server\n";
    $status = 1;
}
@endverbatim

The PerlACE::Process is constructed with an executable and
arguments.  @note Unlike the old Process module, the process
isn't started until one of the Spawn methods is used. We check
the result of the spawn, if we couldn't spawn the process
we directly exit the script.

@verbatim
if (PerlACE::waitforfile_timed ($server_ior, $PerlACE::wait_interval_for_process_creation) == -1) {
    print STDERR "ERROR: cannot find file <$server_ior>\n";
    $SV->Kill ();
    exit 1;
}
@endverbatim

The PerlACE::waitforfile_timed method waits until the file is
created.  In this way, we know when to start the client.  If
no IOR file is used, then you'd need to use Perl's sleep
method.

@verbatim
$client = $CL->SpawnWaitKill (60);

if ($client != 0) {
    print STDERR "ERROR: client returned $client\n";
    $status = 1;
}
@endverbatim

Here is an example of starting the client.  SpawnWaitKill will start
the process and wait for the specified number of seconds for the
process to end.  If the time limit is reached, it will kill the
process and return -1.

The return value of SpawnWaitKill is the return value of the
process, unless it timed out.  You don't need to check for the
timeout, since SpawnWaitKill will print out a timeout error.
Instead, just check for != 0.

@verbatim
$server = $SV->TerminateWaitKill (5);

if ($server != 0) {
    print STDERR "ERROR: server returned $server\n";
    $status = 1;
}
@endverbatim

Here is the termination of the server.  Servers are usually terminated
either by TerminateWaitKill or just WaitKill.  TerminateWaitKill is
used when the server doesn't shut down itself.  WaitKill is used when
it does (such as when the client calls a shutdown method).  Once
again, we check the return status.

@verbatim
unlink $server_ior;

exit $status;
@endverbatim

When you need the hostname the test is running on be aware of the
fact that with VxWorks we do cross host testing, part of the test
runs on the target, the other part on the host system. In your test
program add functionality to handle a commandline argument to pass
in the hostname of the target. In the run_test.pl script you can
then use the following code as example.

@verbatim
$TARGETHOSTNAME = "localhost";
if (PerlACE::is_vxworks_test()) {
  $TARGETHOSTNAME = $ENV{'ACE_RUN_VX_TGTHOST'};
  $SV = new PerlACE::ProcessVX ("server", "-ORBEndpoint iiop://$TARGETHOSTNAME:43210");
 }
 else {
  $SV = new PerlACE::Process ("server", "-ORBEndpoint iiop://$TARGETHOSTNAME:43210");
 }
$CL = new PerlACE::Process ("client", " -p 43210 -h $TARGETHOSTNAME");
@endverbatim

And finally, we unlink any files that were created and then just
exit with $status.

*/
