#5 Add support to run commands in background
Merged 6 years ago by spoore. Opened 6 years ago by mrniranjan.
mrniranjan/python-pytest-multihost master  into  master

file modified
+5 -3
@@ -201,7 +201,7 @@ 

  

      def run_command(self, argv, set_env=True, stdin_text=None,

                      log_stdout=True, raiseonerr=True,

-                     cwd=None):

+                     cwd=None, bg=False):

          """Run the given command on this host

  

          Returns a Command instance. The command will have already run in the
@@ -218,6 +218,7 @@ 

          :param raiseonerr: If true, an exception will be raised if the command

                             does not exit with return code 0

          :param cwd: The working directory for the command

+         :param bg: If True, runs command in background

          """

          command = self.transport.start_shell(argv, log_stdout=log_stdout)

          # Set working directory
@@ -247,11 +248,12 @@ 

          if stdin_text:

              command.stdin.write(stdin_text)

          command.stdin.flush()

- 

-         command.wait(raiseonerr=raiseonerr)

+         if not bg:

+             command.wait(raiseonerr=raiseonerr)

          return command

  

  

+ 

  class Host(BaseHost):

      """A Unix host"""

      command_prelude = 'set -e\n'

@@ -224,3 +224,11 @@ 

          host = multihost_badpassword.host

          with pytest.raises((AuthenticationException, RuntimeError)):

              echo = host.run_command(['echo', 'hello', 'world'])

+ 

+     def test_background(self, multihost):

+ 	host = multihost.host

+ 	run_nc = 'nc -l 12080 > /tmp/filename.out'

+ 	cmd = host.run_command(run_nc, bg=True, raiseonerr=False)

+ 	send_file = 'nc localhost 12080 < /root/anaconda-ks.cfg'

+ 	cmd = host.run_command(send_file)

+ 	assert cmd.returncode == 0

Currently this patch adds support to run command when Transport class is Paramiko .

Test case added:

# py.test -s -v test_localhost.py::TestLocalhost::test_background[paramiko]
==================  test session starts  =======================
platform linux2 -- Python 2.7.11, pytest-2.9.1, py-1.4.31, pluggy-0.3.1 -- /home/mniranja  /python_proj/bin/python
cachedir: ../.cache
ansible: 2.2.1.0
rootdir: /home/mniranja/source/pagure/python-pytest-multihost, inifile:
plugins: modifyjunit-1.0, ansible-2.0.0, multihost-1.1 collected 23 items

test_localhost.py::TestLocalhost::test_background[paramiko] PASSED
================== 1 passed in 0.54 seconds =======================

Can we simplify this? Maybe:

if not bg:
    command.wait(raiseonerr=raiseonerr)
return command

rebased onto 34529cd

6 years ago

Thanks spoore, added updated patch.

Some more comments about this option. when a command is run with bg=True, there will be no stderr, stdout or returncode . And it's up the user to make sure that the command being run in background is killed in the test case.

We in sssd qe team need this as we would like to run tcpdump and capture packets over ldap to verify certain things. Grepping of logs have never been reliable.

Example:

tcpdump_cmd = 'tcpdump -s0 -w %s port 389' % pcapfile
multihost.master[0].run_command(tcpdump_cmd, bg=True)
pid_cmd = 'pidof tcpdump'
cmd = multihost.master[0].run_command(pid_cmd, raiseonerr=False)
kill_cmd = 'kill -9 %s' % cmd.stdout_text
multihost.master[0].run_command(kill_cmd)
multihost.master[0].transport.get_file(pcapfile, pcapfile)

if the command run in background is not killed , pytest would hang

Pull-Request has been merged by spoore

6 years ago