I've never tried this with autotest but with other test harnesses in my
previous life.  The idea should be the same with Autotest.  What I did was
basically choreographed the scenario using synchronization, eg:

      host1                 host2                    host3
host4

<---------------------------------------------------------------------->
sync 0 to get everybody ready
T0     start A             start B

<---------------------------------------------------------------------->
sync 1
         ...                ...                       ...
...
T5       ...               start C                    ...
...
         ...                ...                       ...
...
T7       ...                ...                       start D
...

<------------------------------------------------------------------------>
sync 2
         kill A            kill C

<------------------------------------------------------------------------->
sync 3 to wait for everybody to finish

So A and C get run locally in the background as a daemon and also killed
locally.  host1, host2, host3, host4 are roles.  You can even code all this
within one function/file, e.g.

         sync  # sync 0 to get everybody ready
         if myrole == "host1":
                start A
         elif myrole == "host2":
               start B
         sync  # sync 1
         ...
         if myrole =='host2":
               start C

To decision for which host gets what role could be determined in the
control file, eg based on some machine features.

def run(machine):
    host = hosts.create_host(machine, initialize=False)
    feature = host.run('get some features')
    if feature == 'this feature':
         role = 'host1'
    elif feature == 'that feature':
         role = 'host2'
    job.run_test('yourtest', host=host, role=role)

job.parallel_simple(run, machines)

Or it could be done on the remote machines themselves.

The advantage of this is you don't need to create special subcommand
subclasses just to run/wait/kill remote commands; everything is done
locally.  You're just using existing autotest features.  Also, each machine
gets to manage its own stuff locally.  The important tool is the
synchronization.

In Autotest the synchronization tools is the barrier.  See
client/common_lib/*barrier*.py.   You can even use it to synchronize a
subset of the machines instead of all for even more complex choreography.

-Jongki



On Tue, Nov 8, 2011 at 8:57 AM, David Greenberg <
[email protected]> wrote:

> I’ve found autoserv’s ability to start several remote commands, wait for
> one to finish, and then kill the others (which is their expected lifecycle)
> somewhat lacking.****
>
> ** **
>
> My test scenario is this:****
>
> ** **
>
> We have 4 programs: A, B, C, and D and 3 hosts: host1, host2, and host3
> (the hosts and programs are all connected over the network)****
>
> At T=0, start A on host1 and B on host2****
>
> At T=5, start C on host2****
>
> At T=7, start D on host3****
>
> When D finishes, B should also have finished, but A and C are daemons that
> never normally finish.****
>
> A and C should now be killed, and the log files and stdout/stderr from all
> 4 programs must be retrieved and analyzed before determining whether the
> test passes.****
>
> ** **
>
> It appears that the best way to do this now is to start all the jobs in
> subcommands and then use e.g. host2.run(‘kill %s’ % B.remote_pid) to kill
> them, and then suppress the abnormal termination error from the subcommand
> and fetch the stdout and stderr through the result_pickle property of the
> subcommand.****
>
> ** **
>
> I’d like to write subclass/reimplementation of subcommand which is
> host-aware, so that the remote command can be controlled through the
> object, allowing the stdout and stderr to be accessible while the command
> is executing, and so that signals can be sent to the remote command.****
>
> ** **
>
> I’m planning on adding a new global method “start_on_host(cmd, host)” that
> returns a HostCommand object. This HostCommand object represents the
> remotely executing command. It will have the following function:****
>
> **-          **wait_for(timeout=None)  #wait for the remote command to
> terminate, at most the given timeout. If it’s not done by them, forcibly
> kill it. Timeout=0 means kill immediately, timeout=None means wait forever.
> It will return the exit code of the process****
>
> **-          **get_result() #get the CmdResult for the process, raise an
> exception if the process is still running****
>
> **-          **kill(signal=9) # send a signal to the remote command,
> default is kill****
>
> ** **
>
> Also, while reading about paramiko, I read that it doesn’t work properly
> in fork()ed environments. Can anyone comment on how autotest is able to use
> paramiko with subcommands?****
>
> ** **
>
> I’m looking forward to your advice, experiences, and feedback J****
>
> ** **
>
> Thanks,****
>
> David****
>
> _______________________________________________
> Autotest mailing list
> [email protected]
> http://test.kernel.org/cgi-bin/mailman/listinfo/autotest
>
>
_______________________________________________
Autotest mailing list
[email protected]
http://test.kernel.org/cgi-bin/mailman/listinfo/autotest

Reply via email to