qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 00/11] Acceptance Test: introduce base class for Linux based tests
@ 2021-04-12  4:46 Cleber Rosa
  2021-04-12  4:46 ` [PATCH v3 01/11] tests/acceptance/virtiofs_submounts.py: add missing accel tag Cleber Rosa
                   ` (10 more replies)
  0 siblings, 11 replies; 18+ messages in thread
From: Cleber Rosa @ 2021-04-12  4:46 UTC (permalink / raw)
  To: qemu-devel
  Cc: Thomas Huth, Eduardo Habkost, Philippe Mathieu-Daudé,
	Wainer dos Santos Moschetta, Willian Rampazzo, John Snow,
	Willian Rampazzo, Cleber Rosa, Alex Bennée, Aurelien Jarno,
	Beraldo Leal

This introduces a base class for tests that need to interact with a\r
Linux guest.  It generalizes the "boot_linux.py" code, already been\r
used by the "virtiofs_submounts.py" and also SSH related code being\r
used by that and "linux_ssh_mips_malta.py".\r
\r
While at it, a number of fixes on hopeful improvements to those tests\r
were added.\r
\r
Changes from v2:\r
\r
* Removed type information in docstring on python/qemu/utils.py, as\r
  that's already present on the type hints (John Snow)\r
\r
* Reworded commit message about moving ssh-related methods to a auxiliary,\r
  mix-in class, and not to the base LinuxTest class (Eric Auger)\r
\r
* Removed unused import of get_info_usernet_hostfwd_port on\r
  tests/acceptance/linux_ssh_mips_malta.py (Eric Auger)\r
\r
* Added note on commit message about setUp() method also allowing one\r
  to define network device, which is by default, set to virtio-net\r
  (Eric Auger)\r
\r
* Kept note about the network device that allows for SSH connections\r
  (Wainer Moschetta)\r
\r
* Do not set up an SSH connection on tests that won't be using it\r
  (Eric Auger)\r
\r
* Mention the use of a Fedora 31 guest image (Wainer Moschetta)\r
\r
* Fix of SSH pubkey setup on tests/acceptance/virtiofs_submounts.py\r
  (new patch, reported by Wainer Moschetta)\r
\r
Changes from v1:\r
\r
* Majority of v1 patches have been merged.\r
\r
* New patches:\r
  - Acceptance Tests: make username/password configurable\r
  - Acceptance Tests: set up SSH connection by default after boot for LinuxTest\r
  - tests/acceptance/virtiofs_submounts.py: remove launch_vm()\r
\r
* Allowed for the configuration of the network device type (defaulting\r
  to virtio-net) [Phil]\r
\r
* Fix module name typo (s/qemu.util/qemu.utils/) in the commit message\r
  [John]\r
\r
* Tests based on LinuxTest will have the SSH connection already prepared\r
\r
Cleber Rosa (11):\r
  tests/acceptance/virtiofs_submounts.py: add missing accel tag\r
  tests/acceptance/virtiofs_submounts.py: evaluate string not length\r
  Python: add utility function for retrieving port redirection\r
  Acceptance Tests: move useful ssh methods to base class\r
  Acceptance Tests: add port redirection for ssh by default\r
  Acceptance Tests: make username/password configurable\r
  Acceptance Tests: set up SSH connection by default after boot for\r
    LinuxTest\r
  tests/acceptance/virtiofs_submounts.py: remove launch_vm()\r
  Acceptance Tests: add basic documentation on LinuxTest base class\r
  Acceptance Tests: introduce CPU hotplug test\r
  tests/acceptance/virtiofs_submounts.py: fix setup of SSH pubkey\r
\r
 docs/devel/testing.rst                    | 26 +++++++++\r
 python/qemu/utils.py                      | 33 +++++++++++\r
 tests/acceptance/avocado_qemu/__init__.py | 64 ++++++++++++++++++--\r
 tests/acceptance/boot_linux.py            | 18 +++---\r
 tests/acceptance/hotplug_cpu.py           | 37 ++++++++++++\r
 tests/acceptance/info_usernet.py          | 29 +++++++++\r
 tests/acceptance/linux_ssh_mips_malta.py  | 42 +-------------\r
 tests/acceptance/virtiofs_submounts.py    | 71 +++--------------------\r
 tests/vm/basevm.py                        |  7 +--\r
 9 files changed, 206 insertions(+), 121 deletions(-)\r
 create mode 100644 python/qemu/utils.py\r
 create mode 100644 tests/acceptance/hotplug_cpu.py\r
 create mode 100644 tests/acceptance/info_usernet.py\r
\r
-- \r
2.30.2\r
\r



^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v3 01/11] tests/acceptance/virtiofs_submounts.py: add missing accel tag
  2021-04-12  4:46 [PATCH v3 00/11] Acceptance Test: introduce base class for Linux based tests Cleber Rosa
@ 2021-04-12  4:46 ` Cleber Rosa
  2021-04-12  4:46 ` [PATCH v3 02/11] tests/acceptance/virtiofs_submounts.py: evaluate string not length Cleber Rosa
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 18+ messages in thread
From: Cleber Rosa @ 2021-04-12  4:46 UTC (permalink / raw)
  To: qemu-devel
  Cc: Thomas Huth, Eduardo Habkost, Philippe Mathieu-Daudé,
	Wainer dos Santos Moschetta, Willian Rampazzo, Eric Auger,
	John Snow, Willian Rampazzo, Cleber Rosa, Alex Bennée,
	Aurelien Jarno, Beraldo Leal

The tag is useful to select tests that depend/use a particular
feature.

Signed-off-by: Cleber Rosa <crosa@redhat.com>
Reviewed-by: Wainer dos Santos Moschetta <wainersm@redhat.com>
Reviewed-by: Willian Rampazzo <willianr@redhat.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
---
 tests/acceptance/virtiofs_submounts.py | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tests/acceptance/virtiofs_submounts.py b/tests/acceptance/virtiofs_submounts.py
index 46fa65392a1..5b74ce2929b 100644
--- a/tests/acceptance/virtiofs_submounts.py
+++ b/tests/acceptance/virtiofs_submounts.py
@@ -70,6 +70,7 @@ def test_something_that_needs_cmd1_and_cmd2(self):
 class VirtiofsSubmountsTest(LinuxTest):
     """
     :avocado: tags=arch:x86_64
+    :avocado: tags=accel:kvm
     """
 
     def get_portfwd(self):
-- 
2.30.2



^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v3 02/11] tests/acceptance/virtiofs_submounts.py: evaluate string not length
  2021-04-12  4:46 [PATCH v3 00/11] Acceptance Test: introduce base class for Linux based tests Cleber Rosa
  2021-04-12  4:46 ` [PATCH v3 01/11] tests/acceptance/virtiofs_submounts.py: add missing accel tag Cleber Rosa
@ 2021-04-12  4:46 ` Cleber Rosa
  2021-04-12  4:46 ` [PATCH v3 03/11] Python: add utility function for retrieving port redirection Cleber Rosa
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 18+ messages in thread
From: Cleber Rosa @ 2021-04-12  4:46 UTC (permalink / raw)
  To: qemu-devel
  Cc: Thomas Huth, Eduardo Habkost, Philippe Mathieu-Daudé,
	Wainer dos Santos Moschetta, Willian Rampazzo, Eric Auger,
	John Snow, Willian Rampazzo, Cleber Rosa, Alex Bennée,
	Aurelien Jarno, Beraldo Leal

If the vmlinuz variable is set to anything that evaluates to True,
then the respective arguments should be set.  If the variable contains
an empty string, than it will evaluate to False, and the extra
arguments will not be set.

This keeps the same logic, but improves readability a bit.

Signed-off-by: Cleber Rosa <crosa@redhat.com>
Reviewed-by: Beraldo Leal <bleal@redhat.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Willian Rampazzo <willianr@redhat.com>
---
 tests/acceptance/virtiofs_submounts.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/acceptance/virtiofs_submounts.py b/tests/acceptance/virtiofs_submounts.py
index 5b74ce2929b..ca64b76301f 100644
--- a/tests/acceptance/virtiofs_submounts.py
+++ b/tests/acceptance/virtiofs_submounts.py
@@ -251,7 +251,7 @@ def setUp(self):
 
         super(VirtiofsSubmountsTest, self).setUp(pubkey)
 
-        if len(vmlinuz) > 0:
+        if vmlinuz:
             self.vm.add_args('-kernel', vmlinuz,
                              '-append', 'console=ttyS0 root=/dev/sda1')
 
-- 
2.30.2



^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v3 03/11] Python: add utility function for retrieving port redirection
  2021-04-12  4:46 [PATCH v3 00/11] Acceptance Test: introduce base class for Linux based tests Cleber Rosa
  2021-04-12  4:46 ` [PATCH v3 01/11] tests/acceptance/virtiofs_submounts.py: add missing accel tag Cleber Rosa
  2021-04-12  4:46 ` [PATCH v3 02/11] tests/acceptance/virtiofs_submounts.py: evaluate string not length Cleber Rosa
@ 2021-04-12  4:46 ` Cleber Rosa
  2021-05-13 19:10   ` John Snow
  2021-04-12  4:46 ` [PATCH v3 04/11] Acceptance Tests: move useful ssh methods to base class Cleber Rosa
                   ` (7 subsequent siblings)
  10 siblings, 1 reply; 18+ messages in thread
From: Cleber Rosa @ 2021-04-12  4:46 UTC (permalink / raw)
  To: qemu-devel
  Cc: Thomas Huth, Eduardo Habkost, Philippe Mathieu-Daudé,
	Wainer dos Santos Moschetta, Willian Rampazzo, Eric Auger,
	John Snow, Willian Rampazzo, Cleber Rosa, Alex Bennée,
	Aurelien Jarno, Beraldo Leal

Slightly different versions for the same utility code are currently
present on different locations.  This unifies them all, giving
preference to the version from virtiofs_submounts.py, because of the
last tweaks added to it.

While at it, this adds a "qemu.utils" module to host the utility
function and a test.

Signed-off-by: Cleber Rosa <crosa@redhat.com>
Reviewed-by: Wainer dos Santos Moschetta <wainersm@redhat.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Willian Rampazzo <willianr@redhat.com>
---
 python/qemu/utils.py                     | 33 ++++++++++++++++++++++++
 tests/acceptance/info_usernet.py         | 29 +++++++++++++++++++++
 tests/acceptance/linux_ssh_mips_malta.py | 16 +++++-------
 tests/acceptance/virtiofs_submounts.py   | 21 ++++-----------
 tests/vm/basevm.py                       |  7 ++---
 5 files changed, 76 insertions(+), 30 deletions(-)
 create mode 100644 python/qemu/utils.py
 create mode 100644 tests/acceptance/info_usernet.py

diff --git a/python/qemu/utils.py b/python/qemu/utils.py
new file mode 100644
index 00000000000..5ed789275ee
--- /dev/null
+++ b/python/qemu/utils.py
@@ -0,0 +1,33 @@
+"""
+QEMU utility library
+
+This offers miscellaneous utility functions, which may not be easily
+distinguishable or numerous to be in their own module.
+"""
+
+# Copyright (C) 2021 Red Hat Inc.
+#
+# Authors:
+#  Cleber Rosa <crosa@redhat.com>
+#
+# This work is licensed under the terms of the GNU GPL, version 2.  See
+# the COPYING file in the top-level directory.
+#
+
+import re
+from typing import Optional
+
+
+def get_info_usernet_hostfwd_port(info_usernet_output: str) -> Optional[int]:
+    """
+    Returns the port given to the hostfwd parameter via info usernet
+
+    :param info_usernet_output: output generated by hmp command "info usernet"
+    :return: the port number allocated by the hostfwd option
+    """
+    for line in info_usernet_output.split('\r\n'):
+        regex = r'TCP.HOST_FORWARD.*127\.0\.0\.1\s+(\d+)\s+10\.'
+        match = re.search(regex, line)
+        if match is not None:
+            return int(match[1])
+    return None
diff --git a/tests/acceptance/info_usernet.py b/tests/acceptance/info_usernet.py
new file mode 100644
index 00000000000..9c1fd903a0b
--- /dev/null
+++ b/tests/acceptance/info_usernet.py
@@ -0,0 +1,29 @@
+# Test for the hmp command "info usernet"
+#
+# Copyright (c) 2021 Red Hat, Inc.
+#
+# Author:
+#  Cleber Rosa <crosa@redhat.com>
+#
+# This work is licensed under the terms of the GNU GPL, version 2 or
+# later.  See the COPYING file in the top-level directory.
+
+from avocado_qemu import Test
+
+from qemu.utils import get_info_usernet_hostfwd_port
+
+
+class InfoUsernet(Test):
+
+    def test_hostfwd(self):
+        self.vm.add_args('-netdev', 'user,id=vnet,hostfwd=:127.0.0.1:0-:22')
+        self.vm.launch()
+        res = self.vm.command('human-monitor-command',
+                              command_line='info usernet')
+        port = get_info_usernet_hostfwd_port(res)
+        self.assertIsNotNone(port,
+                             ('"info usernet" output content does not seem to '
+                              'contain the redirected port'))
+        self.assertGreater(port, 0,
+                           ('Found a redirected port that is not greater than'
+                            ' zero'))
diff --git a/tests/acceptance/linux_ssh_mips_malta.py b/tests/acceptance/linux_ssh_mips_malta.py
index 6dbd02d49d5..052008f02d4 100644
--- a/tests/acceptance/linux_ssh_mips_malta.py
+++ b/tests/acceptance/linux_ssh_mips_malta.py
@@ -18,6 +18,8 @@
 from avocado.utils import archive
 from avocado.utils import ssh
 
+from qemu.utils import get_info_usernet_hostfwd_port
+
 
 class LinuxSSH(Test):
 
@@ -70,18 +72,14 @@ def get_kernel_info(self, endianess, wordsize):
     def setUp(self):
         super(LinuxSSH, self).setUp()
 
-    def get_portfwd(self):
+    def ssh_connect(self, username, password):
+        self.ssh_logger = logging.getLogger('ssh')
         res = self.vm.command('human-monitor-command',
                               command_line='info usernet')
-        line = res.split('\r\n')[2]
-        port = re.split(r'.*TCP.HOST_FORWARD.*127\.0\.0\.1 (\d+)\s+10\..*',
-                        line)[1]
+        port = get_info_usernet_hostfwd_port(res)
+        if not port:
+            self.cancel("Failed to retrieve SSH port")
         self.log.debug("sshd listening on port:" + port)
-        return port
-
-    def ssh_connect(self, username, password):
-        self.ssh_logger = logging.getLogger('ssh')
-        port = self.get_portfwd()
         self.ssh_session = ssh.Session(self.VM_IP, port=int(port),
                                        user=username, password=password)
         for i in range(10):
diff --git a/tests/acceptance/virtiofs_submounts.py b/tests/acceptance/virtiofs_submounts.py
index ca64b76301f..57a7047342f 100644
--- a/tests/acceptance/virtiofs_submounts.py
+++ b/tests/acceptance/virtiofs_submounts.py
@@ -9,6 +9,8 @@
 from avocado_qemu import wait_for_console_pattern
 from avocado.utils import ssh
 
+from qemu.utils import get_info_usernet_hostfwd_port
+
 
 def run_cmd(args):
     subp = subprocess.Popen(args,
@@ -73,27 +75,14 @@ class VirtiofsSubmountsTest(LinuxTest):
     :avocado: tags=accel:kvm
     """
 
-    def get_portfwd(self):
-        port = None
-
+    def ssh_connect(self, username, keyfile):
+        self.ssh_logger = logging.getLogger('ssh')
         res = self.vm.command('human-monitor-command',
                               command_line='info usernet')
-        for line in res.split('\r\n'):
-            match = \
-                re.search(r'TCP.HOST_FORWARD.*127\.0\.0\.1\s+(\d+)\s+10\.',
-                          line)
-            if match is not None:
-                port = int(match[1])
-                break
-
+        port = get_info_usernet_hostfwd_port(res)
         self.assertIsNotNone(port)
         self.assertGreater(port, 0)
         self.log.debug('sshd listening on port: %d', port)
-        return port
-
-    def ssh_connect(self, username, keyfile):
-        self.ssh_logger = logging.getLogger('ssh')
-        port = self.get_portfwd()
         self.ssh_session = ssh.Session('127.0.0.1', port=port,
                                        user=username, key=keyfile)
         for i in range(10):
diff --git a/tests/vm/basevm.py b/tests/vm/basevm.py
index 00f1d5ca8da..75ce07df364 100644
--- a/tests/vm/basevm.py
+++ b/tests/vm/basevm.py
@@ -21,6 +21,7 @@
 sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python'))
 from qemu.accel import kvm_available
 from qemu.machine import QEMUMachine
+from qemu.utils import get_info_usernet_hostfwd_port
 import subprocess
 import hashlib
 import argparse
@@ -306,11 +307,7 @@ def boot(self, img, extra_args=[]):
         self.console_init()
         usernet_info = guest.qmp("human-monitor-command",
                                  command_line="info usernet")
-        self.ssh_port = None
-        for l in usernet_info["return"].splitlines():
-            fields = l.split()
-            if "TCP[HOST_FORWARD]" in fields and "22" in fields:
-                self.ssh_port = l.split()[3]
+        self.ssh_port = get_info_usernet_hostfwd_port(usernet_info)
         if not self.ssh_port:
             raise Exception("Cannot find ssh port from 'info usernet':\n%s" % \
                             usernet_info)
-- 
2.30.2



^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v3 04/11] Acceptance Tests: move useful ssh methods to base class
  2021-04-12  4:46 [PATCH v3 00/11] Acceptance Test: introduce base class for Linux based tests Cleber Rosa
                   ` (2 preceding siblings ...)
  2021-04-12  4:46 ` [PATCH v3 03/11] Python: add utility function for retrieving port redirection Cleber Rosa
@ 2021-04-12  4:46 ` Cleber Rosa
  2021-04-19 15:22   ` Philippe Mathieu-Daudé
  2021-04-12  4:46 ` [PATCH v3 05/11] Acceptance Tests: add port redirection for ssh by default Cleber Rosa
                   ` (6 subsequent siblings)
  10 siblings, 1 reply; 18+ messages in thread
From: Cleber Rosa @ 2021-04-12  4:46 UTC (permalink / raw)
  To: qemu-devel
  Cc: Thomas Huth, Eduardo Habkost, Philippe Mathieu-Daudé,
	Wainer dos Santos Moschetta, Willian Rampazzo, Eric Auger,
	John Snow, Willian Rampazzo, Cleber Rosa, Alex Bennée,
	Aurelien Jarno, Beraldo Leal

Both the virtiofs submounts and the linux ssh mips malta tests
contains useful methods related to ssh that deserve to be made
available to other tests.  Let's move them to an auxiliary, mix-in
class that will be used on the base LinuxTest class.

The method that helps with setting up an ssh connection will now
support both key and password based authentication, defaulting to key
based.

Signed-off-by: Cleber Rosa <crosa@redhat.com>
Reviewed-by: Wainer dos Santos Moschetta <wainersm@redhat.com>
Reviewed-by: Willian Rampazzo <willianr@redhat.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Cleber Rosa <crosa@redhat.com>
---
 tests/acceptance/avocado_qemu/__init__.py | 48 ++++++++++++++++++++++-
 tests/acceptance/linux_ssh_mips_malta.py  | 40 ++-----------------
 tests/acceptance/virtiofs_submounts.py    | 37 -----------------
 3 files changed, 50 insertions(+), 75 deletions(-)

diff --git a/tests/acceptance/avocado_qemu/__init__.py b/tests/acceptance/avocado_qemu/__init__.py
index 83b1741ec85..67f75f66e56 100644
--- a/tests/acceptance/avocado_qemu/__init__.py
+++ b/tests/acceptance/avocado_qemu/__init__.py
@@ -20,6 +20,7 @@
 from avocado.utils import cloudinit
 from avocado.utils import datadrainer
 from avocado.utils import network
+from avocado.utils import ssh
 from avocado.utils import vmimage
 from avocado.utils.path import find_command
 
@@ -43,6 +44,8 @@
 from qemu.accel import kvm_available
 from qemu.accel import tcg_available
 from qemu.machine import QEMUMachine
+from qemu.utils import get_info_usernet_hostfwd_port
+
 
 def is_readable_executable_file(path):
     return os.path.isfile(path) and os.access(path, os.R_OK | os.X_OK)
@@ -253,7 +256,50 @@ def fetch_asset(self, name,
                         cancel_on_missing=cancel_on_missing)
 
 
-class LinuxTest(Test):
+class LinuxSSHMixIn:
+    """Contains utility methods for interacting with a guest via SSH."""
+
+    def ssh_connect(self, username, credential, credential_is_key=True):
+        self.ssh_logger = logging.getLogger('ssh')
+        res = self.vm.command('human-monitor-command',
+                              command_line='info usernet')
+        port = get_info_usernet_hostfwd_port(res)
+        self.assertIsNotNone(port)
+        self.assertGreater(port, 0)
+        self.log.debug('sshd listening on port: %d', port)
+        if credential_is_key:
+            self.ssh_session = ssh.Session('127.0.0.1', port=port,
+                                           user=username, key=credential)
+        else:
+            self.ssh_session = ssh.Session('127.0.0.1', port=port,
+                                           user=username, password=credential)
+        for i in range(10):
+            try:
+                self.ssh_session.connect()
+                return
+            except:
+                time.sleep(4)
+                pass
+        self.fail('ssh connection timeout')
+
+    def ssh_command(self, command):
+        self.ssh_logger.info(command)
+        result = self.ssh_session.cmd(command)
+        stdout_lines = [line.rstrip() for line
+                        in result.stdout_text.splitlines()]
+        for line in stdout_lines:
+            self.ssh_logger.info(line)
+        stderr_lines = [line.rstrip() for line
+                        in result.stderr_text.splitlines()]
+        for line in stderr_lines:
+            self.ssh_logger.warning(line)
+
+        self.assertEqual(result.exit_status, 0,
+                         f'Guest command failed: {command}')
+        return stdout_lines, stderr_lines
+
+
+class LinuxTest(Test, LinuxSSHMixIn):
     """Facilitates having a cloud-image Linux based available.
 
     For tests that indend to interact with guests, this is a better choice
diff --git a/tests/acceptance/linux_ssh_mips_malta.py b/tests/acceptance/linux_ssh_mips_malta.py
index 052008f02d4..61c9079d047 100644
--- a/tests/acceptance/linux_ssh_mips_malta.py
+++ b/tests/acceptance/linux_ssh_mips_malta.py
@@ -12,16 +12,14 @@
 import time
 
 from avocado import skipUnless
-from avocado_qemu import Test
+from avocado_qemu import Test, LinuxSSHMixIn
 from avocado_qemu import wait_for_console_pattern
 from avocado.utils import process
 from avocado.utils import archive
 from avocado.utils import ssh
 
-from qemu.utils import get_info_usernet_hostfwd_port
 
-
-class LinuxSSH(Test):
+class LinuxSSH(Test, LinuxSSHMixIn):
 
     timeout = 150 # Not for 'configure --enable-debug --enable-debug-tcg'
 
@@ -72,41 +70,9 @@ def get_kernel_info(self, endianess, wordsize):
     def setUp(self):
         super(LinuxSSH, self).setUp()
 
-    def ssh_connect(self, username, password):
-        self.ssh_logger = logging.getLogger('ssh')
-        res = self.vm.command('human-monitor-command',
-                              command_line='info usernet')
-        port = get_info_usernet_hostfwd_port(res)
-        if not port:
-            self.cancel("Failed to retrieve SSH port")
-        self.log.debug("sshd listening on port:" + port)
-        self.ssh_session = ssh.Session(self.VM_IP, port=int(port),
-                                       user=username, password=password)
-        for i in range(10):
-            try:
-                self.ssh_session.connect()
-                return
-            except:
-                time.sleep(4)
-                pass
-        self.fail("ssh connection timeout")
-
     def ssh_disconnect_vm(self):
         self.ssh_session.quit()
 
-    def ssh_command(self, command, is_root=True):
-        self.ssh_logger.info(command)
-        result = self.ssh_session.cmd(command)
-        stdout_lines = [line.rstrip() for line
-                        in result.stdout_text.splitlines()]
-        for line in stdout_lines:
-            self.ssh_logger.info(line)
-        stderr_lines = [line.rstrip() for line
-                        in result.stderr_text.splitlines()]
-        for line in stderr_lines:
-            self.ssh_logger.warning(line)
-        return stdout_lines, stderr_lines
-
     def boot_debian_wheezy_image_and_ssh_login(self, endianess, kernel_path):
         image_url, image_hash = self.get_image_info(endianess)
         image_path = self.fetch_asset(image_url, asset_hash=image_hash)
@@ -127,7 +93,7 @@ def boot_debian_wheezy_image_and_ssh_login(self, endianess, kernel_path):
         wait_for_console_pattern(self, console_pattern, 'Oops')
         self.log.info('sshd ready')
 
-        self.ssh_connect('root', 'root')
+        self.ssh_connect('root', 'root', False)
 
     def shutdown_via_ssh(self):
         self.ssh_command('poweroff')
diff --git a/tests/acceptance/virtiofs_submounts.py b/tests/acceptance/virtiofs_submounts.py
index 57a7047342f..bed8ce44dfc 100644
--- a/tests/acceptance/virtiofs_submounts.py
+++ b/tests/acceptance/virtiofs_submounts.py
@@ -9,8 +9,6 @@
 from avocado_qemu import wait_for_console_pattern
 from avocado.utils import ssh
 
-from qemu.utils import get_info_usernet_hostfwd_port
-
 
 def run_cmd(args):
     subp = subprocess.Popen(args,
@@ -75,41 +73,6 @@ class VirtiofsSubmountsTest(LinuxTest):
     :avocado: tags=accel:kvm
     """
 
-    def ssh_connect(self, username, keyfile):
-        self.ssh_logger = logging.getLogger('ssh')
-        res = self.vm.command('human-monitor-command',
-                              command_line='info usernet')
-        port = get_info_usernet_hostfwd_port(res)
-        self.assertIsNotNone(port)
-        self.assertGreater(port, 0)
-        self.log.debug('sshd listening on port: %d', port)
-        self.ssh_session = ssh.Session('127.0.0.1', port=port,
-                                       user=username, key=keyfile)
-        for i in range(10):
-            try:
-                self.ssh_session.connect()
-                return
-            except:
-                time.sleep(4)
-                pass
-        self.fail('ssh connection timeout')
-
-    def ssh_command(self, command):
-        self.ssh_logger.info(command)
-        result = self.ssh_session.cmd(command)
-        stdout_lines = [line.rstrip() for line
-                        in result.stdout_text.splitlines()]
-        for line in stdout_lines:
-            self.ssh_logger.info(line)
-        stderr_lines = [line.rstrip() for line
-                        in result.stderr_text.splitlines()]
-        for line in stderr_lines:
-            self.ssh_logger.warning(line)
-
-        self.assertEqual(result.exit_status, 0,
-                         f'Guest command failed: {command}')
-        return stdout_lines, stderr_lines
-
     def run(self, args, ignore_error=False):
         stdout, stderr, ret = run_cmd(args)
 
-- 
2.30.2



^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v3 05/11] Acceptance Tests: add port redirection for ssh by default
  2021-04-12  4:46 [PATCH v3 00/11] Acceptance Test: introduce base class for Linux based tests Cleber Rosa
                   ` (3 preceding siblings ...)
  2021-04-12  4:46 ` [PATCH v3 04/11] Acceptance Tests: move useful ssh methods to base class Cleber Rosa
@ 2021-04-12  4:46 ` Cleber Rosa
  2021-04-12  4:46 ` [PATCH v3 06/11] Acceptance Tests: make username/password configurable Cleber Rosa
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 18+ messages in thread
From: Cleber Rosa @ 2021-04-12  4:46 UTC (permalink / raw)
  To: qemu-devel
  Cc: Thomas Huth, Eduardo Habkost, Philippe Mathieu-Daudé,
	Wainer dos Santos Moschetta, Willian Rampazzo, Eric Auger,
	John Snow, Willian Rampazzo, Cleber Rosa, Marc-André Lureau,
	Alex Bennée, Aurelien Jarno, Beraldo Leal

For users of the LinuxTest class, let's set up the VM with the port
redirection for SSH, instead of requiring each test to set the same
arguments.

It also sets the network device, by default, to virtio-net.

Signed-off-by: Cleber Rosa <crosa@redhat.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Willian Rampazzo <willianr@redhat.com>
---
 tests/acceptance/avocado_qemu/__init__.py | 5 ++++-
 tests/acceptance/virtiofs_submounts.py    | 4 ----
 2 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/tests/acceptance/avocado_qemu/__init__.py b/tests/acceptance/avocado_qemu/__init__.py
index 67f75f66e56..0856880000f 100644
--- a/tests/acceptance/avocado_qemu/__init__.py
+++ b/tests/acceptance/avocado_qemu/__init__.py
@@ -309,10 +309,13 @@ class LinuxTest(Test, LinuxSSHMixIn):
     timeout = 900
     chksum = None
 
-    def setUp(self, ssh_pubkey=None):
+    def setUp(self, ssh_pubkey=None, network_device_type='virtio-net'):
         super(LinuxTest, self).setUp()
         self.vm.add_args('-smp', '2')
         self.vm.add_args('-m', '1024')
+        # The following network device allows for SSH connections
+        self.vm.add_args('-netdev', 'user,id=vnet,hostfwd=:127.0.0.1:0-:22',
+                         '-device', '%s,netdev=vnet' % network_device_type)
         self.set_up_boot()
         if ssh_pubkey is None:
             ssh_pubkey, self.ssh_key = self.set_up_existing_ssh_keys()
diff --git a/tests/acceptance/virtiofs_submounts.py b/tests/acceptance/virtiofs_submounts.py
index bed8ce44dfc..e10a935ac4e 100644
--- a/tests/acceptance/virtiofs_submounts.py
+++ b/tests/acceptance/virtiofs_submounts.py
@@ -207,10 +207,6 @@ def setUp(self):
             self.vm.add_args('-kernel', vmlinuz,
                              '-append', 'console=ttyS0 root=/dev/sda1')
 
-        # Allow us to connect to SSH
-        self.vm.add_args('-netdev', 'user,id=vnet,hostfwd=:127.0.0.1:0-:22',
-                         '-device', 'virtio-net,netdev=vnet')
-
         self.require_accelerator("kvm")
         self.vm.add_args('-accel', 'kvm')
 
-- 
2.30.2



^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v3 06/11] Acceptance Tests: make username/password configurable
  2021-04-12  4:46 [PATCH v3 00/11] Acceptance Test: introduce base class for Linux based tests Cleber Rosa
                   ` (4 preceding siblings ...)
  2021-04-12  4:46 ` [PATCH v3 05/11] Acceptance Tests: add port redirection for ssh by default Cleber Rosa
@ 2021-04-12  4:46 ` Cleber Rosa
  2021-04-12  4:46 ` [PATCH v3 07/11] Acceptance Tests: set up SSH connection by default after boot for LinuxTest Cleber Rosa
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 18+ messages in thread
From: Cleber Rosa @ 2021-04-12  4:46 UTC (permalink / raw)
  To: qemu-devel
  Cc: Thomas Huth, Eduardo Habkost, Philippe Mathieu-Daudé,
	Wainer dos Santos Moschetta, Willian Rampazzo, Eric Auger,
	John Snow, Willian Rampazzo, Cleber Rosa, Marc-André Lureau,
	Alex Bennée, Aurelien Jarno, Beraldo Leal

This makes the username/password used for authentication configurable,
because some guest operating systems may have restrictions on accounts
to be used for logins, and it just makes it better documented.

Signed-off-by: Cleber Rosa <crosa@redhat.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Willian Rampazzo <willianr@redhat.com>
---
 tests/acceptance/avocado_qemu/__init__.py | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/tests/acceptance/avocado_qemu/__init__.py b/tests/acceptance/avocado_qemu/__init__.py
index 0856880000f..25f871f5bc6 100644
--- a/tests/acceptance/avocado_qemu/__init__.py
+++ b/tests/acceptance/avocado_qemu/__init__.py
@@ -308,6 +308,8 @@ class LinuxTest(Test, LinuxSSHMixIn):
 
     timeout = 900
     chksum = None
+    username = 'root'
+    password = 'password'
 
     def setUp(self, ssh_pubkey=None, network_device_type='virtio-net'):
         super(LinuxTest, self).setUp()
@@ -371,8 +373,8 @@ def prepare_cloudinit(self, ssh_pubkey=None):
                 with open(ssh_pubkey) as pubkey:
                     pubkey_content = pubkey.read()
             cloudinit.iso(cloudinit_iso, self.name,
-                          username='root',
-                          password='password',
+                          username=self.username,
+                          password=self.password,
                           # QEMU's hard coded usermode router address
                           phone_home_host='10.0.2.2',
                           phone_home_port=self.phone_home_port,
-- 
2.30.2



^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v3 07/11] Acceptance Tests: set up SSH connection by default after boot for LinuxTest
  2021-04-12  4:46 [PATCH v3 00/11] Acceptance Test: introduce base class for Linux based tests Cleber Rosa
                   ` (5 preceding siblings ...)
  2021-04-12  4:46 ` [PATCH v3 06/11] Acceptance Tests: make username/password configurable Cleber Rosa
@ 2021-04-12  4:46 ` Cleber Rosa
  2021-04-19 15:05   ` Auger Eric
  2021-04-12  4:46 ` [PATCH v3 08/11] tests/acceptance/virtiofs_submounts.py: remove launch_vm() Cleber Rosa
                   ` (3 subsequent siblings)
  10 siblings, 1 reply; 18+ messages in thread
From: Cleber Rosa @ 2021-04-12  4:46 UTC (permalink / raw)
  To: qemu-devel
  Cc: Thomas Huth, Eduardo Habkost, Philippe Mathieu-Daudé,
	Wainer dos Santos Moschetta, Willian Rampazzo, John Snow,
	Willian Rampazzo, Cleber Rosa, Marc-André Lureau,
	Alex Bennée, Aurelien Jarno, Beraldo Leal

The LinuxTest specifically targets users that need to interact with Linux
guests.  So, it makes sense to give a connection by default, and avoid
requiring it as boiler-plate code.

Signed-off-by: Cleber Rosa <crosa@redhat.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Willian Rampazzo <willianr@redhat.com>
---
 tests/acceptance/avocado_qemu/__init__.py |  5 ++++-
 tests/acceptance/boot_linux.py            | 18 +++++++++---------
 tests/acceptance/virtiofs_submounts.py    |  1 -
 3 files changed, 13 insertions(+), 11 deletions(-)

diff --git a/tests/acceptance/avocado_qemu/__init__.py b/tests/acceptance/avocado_qemu/__init__.py
index 25f871f5bc6..1062a851b97 100644
--- a/tests/acceptance/avocado_qemu/__init__.py
+++ b/tests/acceptance/avocado_qemu/__init__.py
@@ -391,7 +391,7 @@ def set_up_cloudinit(self, ssh_pubkey=None):
         cloudinit_iso = self.prepare_cloudinit(ssh_pubkey)
         self.vm.add_args('-drive', 'file=%s,format=raw' % cloudinit_iso)
 
-    def launch_and_wait(self):
+    def launch_and_wait(self, set_up_ssh_connection=True):
         self.vm.set_console()
         self.vm.launch()
         console_drainer = datadrainer.LineLogger(self.vm.console_socket.fileno(),
@@ -399,3 +399,6 @@ def launch_and_wait(self):
         console_drainer.start()
         self.log.info('VM launched, waiting for boot confirmation from guest')
         cloudinit.wait_for_phone_home(('0.0.0.0', self.phone_home_port), self.name)
+        if set_up_ssh_connection:
+            self.log.info('Setting up the SSH connection')
+            self.ssh_connect(self.username, self.ssh_key)
diff --git a/tests/acceptance/boot_linux.py b/tests/acceptance/boot_linux.py
index 0d178038a09..314370fd1f5 100644
--- a/tests/acceptance/boot_linux.py
+++ b/tests/acceptance/boot_linux.py
@@ -29,7 +29,7 @@ def test_pc_i440fx_tcg(self):
         """
         self.require_accelerator("tcg")
         self.vm.add_args("-accel", "tcg")
-        self.launch_and_wait()
+        self.launch_and_wait(set_up_ssh_connection=False)
 
     def test_pc_i440fx_kvm(self):
         """
@@ -38,7 +38,7 @@ def test_pc_i440fx_kvm(self):
         """
         self.require_accelerator("kvm")
         self.vm.add_args("-accel", "kvm")
-        self.launch_and_wait()
+        self.launch_and_wait(set_up_ssh_connection=False)
 
     def test_pc_q35_tcg(self):
         """
@@ -47,7 +47,7 @@ def test_pc_q35_tcg(self):
         """
         self.require_accelerator("tcg")
         self.vm.add_args("-accel", "tcg")
-        self.launch_and_wait()
+        self.launch_and_wait(set_up_ssh_connection=False)
 
     def test_pc_q35_kvm(self):
         """
@@ -56,7 +56,7 @@ def test_pc_q35_kvm(self):
         """
         self.require_accelerator("kvm")
         self.vm.add_args("-accel", "kvm")
-        self.launch_and_wait()
+        self.launch_and_wait(set_up_ssh_connection=False)
 
 
 class BootLinuxAarch64(LinuxTest):
@@ -85,7 +85,7 @@ def test_virt_tcg(self):
         self.vm.add_args("-cpu", "max")
         self.vm.add_args("-machine", "virt,gic-version=2")
         self.add_common_args()
-        self.launch_and_wait()
+        self.launch_and_wait(set_up_ssh_connection=False)
 
     def test_virt_kvm_gicv2(self):
         """
@@ -98,7 +98,7 @@ def test_virt_kvm_gicv2(self):
         self.vm.add_args("-cpu", "host")
         self.vm.add_args("-machine", "virt,gic-version=2")
         self.add_common_args()
-        self.launch_and_wait()
+        self.launch_and_wait(set_up_ssh_connection=False)
 
     def test_virt_kvm_gicv3(self):
         """
@@ -111,7 +111,7 @@ def test_virt_kvm_gicv3(self):
         self.vm.add_args("-cpu", "host")
         self.vm.add_args("-machine", "virt,gic-version=3")
         self.add_common_args()
-        self.launch_and_wait()
+        self.launch_and_wait(set_up_ssh_connection=False)
 
 
 class BootLinuxPPC64(LinuxTest):
@@ -128,7 +128,7 @@ def test_pseries_tcg(self):
         """
         self.require_accelerator("tcg")
         self.vm.add_args("-accel", "tcg")
-        self.launch_and_wait()
+        self.launch_and_wait(set_up_ssh_connection=False)
 
 
 class BootLinuxS390X(LinuxTest):
@@ -146,4 +146,4 @@ def test_s390_ccw_virtio_tcg(self):
         """
         self.require_accelerator("tcg")
         self.vm.add_args("-accel", "tcg")
-        self.launch_and_wait()
+        self.launch_and_wait(set_up_ssh_connection=False)
diff --git a/tests/acceptance/virtiofs_submounts.py b/tests/acceptance/virtiofs_submounts.py
index e10a935ac4e..e019d3b896b 100644
--- a/tests/acceptance/virtiofs_submounts.py
+++ b/tests/acceptance/virtiofs_submounts.py
@@ -136,7 +136,6 @@ def set_up_virtiofs(self):
 
     def launch_vm(self):
         self.launch_and_wait()
-        self.ssh_connect('root', self.ssh_key)
 
     def set_up_nested_mounts(self):
         scratch_dir = os.path.join(self.shared_dir, 'scratch')
-- 
2.30.2



^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v3 08/11] tests/acceptance/virtiofs_submounts.py: remove launch_vm()
  2021-04-12  4:46 [PATCH v3 00/11] Acceptance Test: introduce base class for Linux based tests Cleber Rosa
                   ` (6 preceding siblings ...)
  2021-04-12  4:46 ` [PATCH v3 07/11] Acceptance Tests: set up SSH connection by default after boot for LinuxTest Cleber Rosa
@ 2021-04-12  4:46 ` Cleber Rosa
  2021-04-12  4:46 ` [PATCH v3 09/11] Acceptance Tests: add basic documentation on LinuxTest base class Cleber Rosa
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 18+ messages in thread
From: Cleber Rosa @ 2021-04-12  4:46 UTC (permalink / raw)
  To: qemu-devel
  Cc: Thomas Huth, Eduardo Habkost, Philippe Mathieu-Daudé,
	Wainer dos Santos Moschetta, Willian Rampazzo, Eric Auger,
	John Snow, Willian Rampazzo, Cleber Rosa, Marc-André Lureau,
	Alex Bennée, Aurelien Jarno, Beraldo Leal

The LinuxTest class' launch_and_wait() method now behaves the same way
as this test's custom launch_vm(), so let's just use the upper layer
(common) method.

Signed-off-by: Cleber Rosa <crosa@redhat.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Willian Rampazzo <willianr@redhat.com>
---
 tests/acceptance/virtiofs_submounts.py | 13 +++++--------
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/tests/acceptance/virtiofs_submounts.py b/tests/acceptance/virtiofs_submounts.py
index e019d3b896b..d77ee356740 100644
--- a/tests/acceptance/virtiofs_submounts.py
+++ b/tests/acceptance/virtiofs_submounts.py
@@ -134,9 +134,6 @@ def set_up_virtiofs(self):
                          '-numa',
                          'node,memdev=mem')
 
-    def launch_vm(self):
-        self.launch_and_wait()
-
     def set_up_nested_mounts(self):
         scratch_dir = os.path.join(self.shared_dir, 'scratch')
         try:
@@ -225,7 +222,7 @@ def test_pre_virtiofsd_set_up(self):
         self.set_up_nested_mounts()
 
         self.set_up_virtiofs()
-        self.launch_vm()
+        self.launch_and_wait()
         self.mount_in_guest()
         self.check_in_guest()
 
@@ -235,14 +232,14 @@ def test_pre_launch_set_up(self):
 
         self.set_up_nested_mounts()
 
-        self.launch_vm()
+        self.launch_and_wait()
         self.mount_in_guest()
         self.check_in_guest()
 
     def test_post_launch_set_up(self):
         self.set_up_shared_dir()
         self.set_up_virtiofs()
-        self.launch_vm()
+        self.launch_and_wait()
 
         self.set_up_nested_mounts()
 
@@ -252,7 +249,7 @@ def test_post_launch_set_up(self):
     def test_post_mount_set_up(self):
         self.set_up_shared_dir()
         self.set_up_virtiofs()
-        self.launch_vm()
+        self.launch_and_wait()
         self.mount_in_guest()
 
         self.set_up_nested_mounts()
@@ -265,7 +262,7 @@ def test_two_runs(self):
         self.set_up_nested_mounts()
 
         self.set_up_virtiofs()
-        self.launch_vm()
+        self.launch_and_wait()
         self.mount_in_guest()
         self.check_in_guest()
 
-- 
2.30.2



^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v3 09/11] Acceptance Tests: add basic documentation on LinuxTest base class
  2021-04-12  4:46 [PATCH v3 00/11] Acceptance Test: introduce base class for Linux based tests Cleber Rosa
                   ` (7 preceding siblings ...)
  2021-04-12  4:46 ` [PATCH v3 08/11] tests/acceptance/virtiofs_submounts.py: remove launch_vm() Cleber Rosa
@ 2021-04-12  4:46 ` Cleber Rosa
  2021-04-12  4:46 ` [PATCH v3 10/11] Acceptance Tests: introduce CPU hotplug test Cleber Rosa
  2021-04-12  4:46 ` [PATCH v3 11/11] tests/acceptance/virtiofs_submounts.py: fix setup of SSH pubkey Cleber Rosa
  10 siblings, 0 replies; 18+ messages in thread
From: Cleber Rosa @ 2021-04-12  4:46 UTC (permalink / raw)
  To: qemu-devel
  Cc: Thomas Huth, Eduardo Habkost, Philippe Mathieu-Daudé,
	Wainer dos Santos Moschetta, Willian Rampazzo, Eric Auger,
	John Snow, Willian Rampazzo, Cleber Rosa, Marc-André Lureau,
	Alex Bennée, Aurelien Jarno, Beraldo Leal

Signed-off-by: Cleber Rosa <crosa@redhat.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Willian Rampazzo <willianr@redhat.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Wainer dos Santos Moschetta <wainersm@redhat.com>
---
 docs/devel/testing.rst | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/docs/devel/testing.rst b/docs/devel/testing.rst
index 1da4c4e4c4e..4e423928106 100644
--- a/docs/devel/testing.rst
+++ b/docs/devel/testing.rst
@@ -810,6 +810,32 @@ and hypothetical example follows:
 At test "tear down", ``avocado_qemu.Test`` handles all the QEMUMachines
 shutdown.
 
+The ``avocado_qemu.LinuxTest`` base test class
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The ``avocado_qemu.LinuxTest`` is further specialization of the
+``avocado_qemu.Test`` class, so it contains all the characteristics of
+the later plus some extra features.
+
+First of all, this base class is intended for tests that need to
+interact with a fully booted and operational Linux guest.  At this
+time, it uses a Fedora 31 guest image.  The most basic example looks
+like this:
+
+.. code::
+
+  from avocado_qemu import LinuxTest
+
+
+  class SomeTest(LinuxTest):
+
+      def test(self):
+          self.launch_and_wait()
+          self.ssh_command('some_command_to_be_run_in_the_guest')
+
+Please refer to tests that use ``avocado_qemu.LinuxTest`` under
+``tests/acceptance`` for more examples.
+
 QEMUMachine
 ~~~~~~~~~~~
 
-- 
2.30.2



^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v3 10/11] Acceptance Tests: introduce CPU hotplug test
  2021-04-12  4:46 [PATCH v3 00/11] Acceptance Test: introduce base class for Linux based tests Cleber Rosa
                   ` (8 preceding siblings ...)
  2021-04-12  4:46 ` [PATCH v3 09/11] Acceptance Tests: add basic documentation on LinuxTest base class Cleber Rosa
@ 2021-04-12  4:46 ` Cleber Rosa
  2021-04-12  4:46 ` [PATCH v3 11/11] tests/acceptance/virtiofs_submounts.py: fix setup of SSH pubkey Cleber Rosa
  10 siblings, 0 replies; 18+ messages in thread
From: Cleber Rosa @ 2021-04-12  4:46 UTC (permalink / raw)
  To: qemu-devel
  Cc: Thomas Huth, Eduardo Habkost, Philippe Mathieu-Daudé,
	Wainer dos Santos Moschetta, Willian Rampazzo, Eric Auger,
	John Snow, Willian Rampazzo, Cleber Rosa, Marc-André Lureau,
	Alex Bennée, Aurelien Jarno, Beraldo Leal

Even though there are qtest based tests for hotplugging CPUs (from
which this test took some inspiration from), this one adds checks
from a Linux guest point of view.

It should also serve as an example for tests that follow a similar
pattern and need to interact with QEMU (via qmp) and with the Linux
guest via SSH.

Signed-off-by: Cleber Rosa <crosa@redhat.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Willian Rampazzo <willianr@redhat.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
---
 tests/acceptance/hotplug_cpu.py | 37 +++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)
 create mode 100644 tests/acceptance/hotplug_cpu.py

diff --git a/tests/acceptance/hotplug_cpu.py b/tests/acceptance/hotplug_cpu.py
new file mode 100644
index 00000000000..6374bf1b546
--- /dev/null
+++ b/tests/acceptance/hotplug_cpu.py
@@ -0,0 +1,37 @@
+# Functional test that hotplugs a CPU and checks it on a Linux guest
+#
+# Copyright (c) 2021 Red Hat, Inc.
+#
+# Author:
+#  Cleber Rosa <crosa@redhat.com>
+#
+# This work is licensed under the terms of the GNU GPL, version 2 or
+# later.  See the COPYING file in the top-level directory.
+
+from avocado_qemu import LinuxTest
+
+
+class HotPlugCPU(LinuxTest):
+
+    def test(self):
+        """
+        :avocado: tags=arch:x86_64
+        :avocado: tags=machine:q35
+        :avocado: tags=accel:kvm
+        """
+        self.require_accelerator('kvm')
+        self.vm.add_args('-accel', 'kvm')
+        self.vm.add_args('-cpu', 'Haswell')
+        self.vm.add_args('-smp', '1,sockets=1,cores=2,threads=1,maxcpus=2')
+        self.launch_and_wait()
+
+        self.ssh_command('test -e /sys/devices/system/cpu/cpu0')
+        with self.assertRaises(AssertionError):
+            self.ssh_command('test -e /sys/devices/system/cpu/cpu1')
+
+        self.vm.command('device_add',
+                        driver='Haswell-x86_64-cpu',
+                        socket_id=0,
+                        core_id=1,
+                        thread_id=0)
+        self.ssh_command('test -e /sys/devices/system/cpu/cpu1')
-- 
2.30.2



^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v3 11/11] tests/acceptance/virtiofs_submounts.py: fix setup of SSH pubkey
  2021-04-12  4:46 [PATCH v3 00/11] Acceptance Test: introduce base class for Linux based tests Cleber Rosa
                   ` (9 preceding siblings ...)
  2021-04-12  4:46 ` [PATCH v3 10/11] Acceptance Tests: introduce CPU hotplug test Cleber Rosa
@ 2021-04-12  4:46 ` Cleber Rosa
  2021-04-12 15:08   ` Wainer dos Santos Moschetta
                     ` (2 more replies)
  10 siblings, 3 replies; 18+ messages in thread
From: Cleber Rosa @ 2021-04-12  4:46 UTC (permalink / raw)
  To: qemu-devel
  Cc: Thomas Huth, Eduardo Habkost, Philippe Mathieu-Daudé,
	Wainer dos Santos Moschetta, Willian Rampazzo, John Snow,
	Willian Rampazzo, Cleber Rosa, Alex Bennée, Aurelien Jarno,
	Beraldo Leal

The public key argument should be a path to a file, and not the
public key data.

Reported-by: Wainer dos Santos Moschetta <wainersm@redhat.com>
Signed-off-by: Cleber Rosa <crosa@redhat.com>
---
 tests/acceptance/virtiofs_submounts.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/acceptance/virtiofs_submounts.py b/tests/acceptance/virtiofs_submounts.py
index d77ee356740..21ad7d792e7 100644
--- a/tests/acceptance/virtiofs_submounts.py
+++ b/tests/acceptance/virtiofs_submounts.py
@@ -195,7 +195,7 @@ def setUp(self):
 
         self.run(('ssh-keygen', '-N', '', '-t', 'ed25519', '-f', self.ssh_key))
 
-        pubkey = open(self.ssh_key + '.pub').read()
+        pubkey = self.ssh_key + '.pub'
 
         super(VirtiofsSubmountsTest, self).setUp(pubkey)
 
-- 
2.30.2



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v3 11/11] tests/acceptance/virtiofs_submounts.py: fix setup of SSH pubkey
  2021-04-12  4:46 ` [PATCH v3 11/11] tests/acceptance/virtiofs_submounts.py: fix setup of SSH pubkey Cleber Rosa
@ 2021-04-12 15:08   ` Wainer dos Santos Moschetta
  2021-04-12 18:59   ` Willian Rampazzo
  2021-04-19 15:03   ` Auger Eric
  2 siblings, 0 replies; 18+ messages in thread
From: Wainer dos Santos Moschetta @ 2021-04-12 15:08 UTC (permalink / raw)
  To: Cleber Rosa, qemu-devel
  Cc: Thomas Huth, Eduardo Habkost, Philippe Mathieu-Daudé,
	Willian Rampazzo, John Snow, Willian Rampazzo, Alex Bennée,
	Aurelien Jarno, Beraldo Leal


On 4/12/21 1:46 AM, Cleber Rosa wrote:
> The public key argument should be a path to a file, and not the
> public key data.
>
> Reported-by: Wainer dos Santos Moschetta <wainersm@redhat.com>
> Signed-off-by: Cleber Rosa <crosa@redhat.com>
> ---
>   tests/acceptance/virtiofs_submounts.py | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)


Reviewed-by: Wainer dos Santos Moschetta <wainersm@redhat.com>


>
> diff --git a/tests/acceptance/virtiofs_submounts.py b/tests/acceptance/virtiofs_submounts.py
> index d77ee356740..21ad7d792e7 100644
> --- a/tests/acceptance/virtiofs_submounts.py
> +++ b/tests/acceptance/virtiofs_submounts.py
> @@ -195,7 +195,7 @@ def setUp(self):
>   
>           self.run(('ssh-keygen', '-N', '', '-t', 'ed25519', '-f', self.ssh_key))
>   
> -        pubkey = open(self.ssh_key + '.pub').read()
> +        pubkey = self.ssh_key + '.pub'
>   
>           super(VirtiofsSubmountsTest, self).setUp(pubkey)
>   



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v3 11/11] tests/acceptance/virtiofs_submounts.py: fix setup of SSH pubkey
  2021-04-12  4:46 ` [PATCH v3 11/11] tests/acceptance/virtiofs_submounts.py: fix setup of SSH pubkey Cleber Rosa
  2021-04-12 15:08   ` Wainer dos Santos Moschetta
@ 2021-04-12 18:59   ` Willian Rampazzo
  2021-04-19 15:03   ` Auger Eric
  2 siblings, 0 replies; 18+ messages in thread
From: Willian Rampazzo @ 2021-04-12 18:59 UTC (permalink / raw)
  To: Cleber Rosa
  Cc: Thomas Huth, Eduardo Habkost, Philippe Mathieu-Daudé,
	qemu-devel, Wainer dos Santos Moschetta, John Snow,
	Alex Bennée, Aurelien Jarno, Beraldo Leal

On Mon, Apr 12, 2021 at 1:48 AM Cleber Rosa <crosa@redhat.com> wrote:
>
> The public key argument should be a path to a file, and not the
> public key data.
>
> Reported-by: Wainer dos Santos Moschetta <wainersm@redhat.com>
> Signed-off-by: Cleber Rosa <crosa@redhat.com>
> ---
>  tests/acceptance/virtiofs_submounts.py | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>

Reviewed-by: Willian Rampazzo <willianr@redhat.com>



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v3 11/11] tests/acceptance/virtiofs_submounts.py: fix setup of SSH pubkey
  2021-04-12  4:46 ` [PATCH v3 11/11] tests/acceptance/virtiofs_submounts.py: fix setup of SSH pubkey Cleber Rosa
  2021-04-12 15:08   ` Wainer dos Santos Moschetta
  2021-04-12 18:59   ` Willian Rampazzo
@ 2021-04-19 15:03   ` Auger Eric
  2 siblings, 0 replies; 18+ messages in thread
From: Auger Eric @ 2021-04-19 15:03 UTC (permalink / raw)
  To: Cleber Rosa, qemu-devel
  Cc: Thomas Huth, Eduardo Habkost, Alex Bennée,
	Philippe Mathieu-Daudé,
	Wainer dos Santos Moschetta, Willian Rampazzo, Willian Rampazzo,
	John Snow, Aurelien Jarno, Beraldo Leal

Hi Cleber,

On 4/12/21 6:46 AM, Cleber Rosa wrote:
> The public key argument should be a path to a file, and not the
> public key data.
> 
> Reported-by: Wainer dos Santos Moschetta <wainersm@redhat.com>
> Signed-off-by: Cleber Rosa <crosa@redhat.com>
> ---
>  tests/acceptance/virtiofs_submounts.py | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/tests/acceptance/virtiofs_submounts.py b/tests/acceptance/virtiofs_submounts.py
> index d77ee356740..21ad7d792e7 100644
> --- a/tests/acceptance/virtiofs_submounts.py
> +++ b/tests/acceptance/virtiofs_submounts.py
> @@ -195,7 +195,7 @@ def setUp(self):
>  
>          self.run(('ssh-keygen', '-N', '', '-t', 'ed25519', '-f', self.ssh_key))
>  
> -        pubkey = open(self.ssh_key + '.pub').read()
> +        pubkey = self.ssh_key + '.pub'
>  
>          super(VirtiofsSubmountsTest, self).setUp(pubkey)
>  
> 
Reviewed-by: Eric Auger <eric.auger@redhat.com>

Thanks

Eric



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v3 07/11] Acceptance Tests: set up SSH connection by default after boot for LinuxTest
  2021-04-12  4:46 ` [PATCH v3 07/11] Acceptance Tests: set up SSH connection by default after boot for LinuxTest Cleber Rosa
@ 2021-04-19 15:05   ` Auger Eric
  0 siblings, 0 replies; 18+ messages in thread
From: Auger Eric @ 2021-04-19 15:05 UTC (permalink / raw)
  To: Cleber Rosa, qemu-devel
  Cc: Thomas Huth, Eduardo Habkost, Alex Bennée,
	Philippe Mathieu-Daudé,
	Wainer dos Santos Moschetta, Willian Rampazzo, Willian Rampazzo,
	Marc-André Lureau, John Snow, Aurelien Jarno, Beraldo Leal

Hi Cleber,

On 4/12/21 6:46 AM, Cleber Rosa wrote:
> The LinuxTest specifically targets users that need to interact with Linux
> guests.  So, it makes sense to give a connection by default, and avoid
> requiring it as boiler-plate code.
> 
> Signed-off-by: Cleber Rosa <crosa@redhat.com>
> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> Reviewed-by: Willian Rampazzo <willianr@redhat.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>

Thanks

Eric
> ---
>  tests/acceptance/avocado_qemu/__init__.py |  5 ++++-
>  tests/acceptance/boot_linux.py            | 18 +++++++++---------
>  tests/acceptance/virtiofs_submounts.py    |  1 -
>  3 files changed, 13 insertions(+), 11 deletions(-)
> 
> diff --git a/tests/acceptance/avocado_qemu/__init__.py b/tests/acceptance/avocado_qemu/__init__.py
> index 25f871f5bc6..1062a851b97 100644
> --- a/tests/acceptance/avocado_qemu/__init__.py
> +++ b/tests/acceptance/avocado_qemu/__init__.py
> @@ -391,7 +391,7 @@ def set_up_cloudinit(self, ssh_pubkey=None):
>          cloudinit_iso = self.prepare_cloudinit(ssh_pubkey)
>          self.vm.add_args('-drive', 'file=%s,format=raw' % cloudinit_iso)
>  
> -    def launch_and_wait(self):
> +    def launch_and_wait(self, set_up_ssh_connection=True):
>          self.vm.set_console()
>          self.vm.launch()
>          console_drainer = datadrainer.LineLogger(self.vm.console_socket.fileno(),
> @@ -399,3 +399,6 @@ def launch_and_wait(self):
>          console_drainer.start()
>          self.log.info('VM launched, waiting for boot confirmation from guest')
>          cloudinit.wait_for_phone_home(('0.0.0.0', self.phone_home_port), self.name)
> +        if set_up_ssh_connection:
> +            self.log.info('Setting up the SSH connection')
> +            self.ssh_connect(self.username, self.ssh_key)
> diff --git a/tests/acceptance/boot_linux.py b/tests/acceptance/boot_linux.py
> index 0d178038a09..314370fd1f5 100644
> --- a/tests/acceptance/boot_linux.py
> +++ b/tests/acceptance/boot_linux.py
> @@ -29,7 +29,7 @@ def test_pc_i440fx_tcg(self):
>          """
>          self.require_accelerator("tcg")
>          self.vm.add_args("-accel", "tcg")
> -        self.launch_and_wait()
> +        self.launch_and_wait(set_up_ssh_connection=False)
>  
>      def test_pc_i440fx_kvm(self):
>          """
> @@ -38,7 +38,7 @@ def test_pc_i440fx_kvm(self):
>          """
>          self.require_accelerator("kvm")
>          self.vm.add_args("-accel", "kvm")
> -        self.launch_and_wait()
> +        self.launch_and_wait(set_up_ssh_connection=False)
>  
>      def test_pc_q35_tcg(self):
>          """
> @@ -47,7 +47,7 @@ def test_pc_q35_tcg(self):
>          """
>          self.require_accelerator("tcg")
>          self.vm.add_args("-accel", "tcg")
> -        self.launch_and_wait()
> +        self.launch_and_wait(set_up_ssh_connection=False)
>  
>      def test_pc_q35_kvm(self):
>          """
> @@ -56,7 +56,7 @@ def test_pc_q35_kvm(self):
>          """
>          self.require_accelerator("kvm")
>          self.vm.add_args("-accel", "kvm")
> -        self.launch_and_wait()
> +        self.launch_and_wait(set_up_ssh_connection=False)
>  
>  
>  class BootLinuxAarch64(LinuxTest):
> @@ -85,7 +85,7 @@ def test_virt_tcg(self):
>          self.vm.add_args("-cpu", "max")
>          self.vm.add_args("-machine", "virt,gic-version=2")
>          self.add_common_args()
> -        self.launch_and_wait()
> +        self.launch_and_wait(set_up_ssh_connection=False)
>  
>      def test_virt_kvm_gicv2(self):
>          """
> @@ -98,7 +98,7 @@ def test_virt_kvm_gicv2(self):
>          self.vm.add_args("-cpu", "host")
>          self.vm.add_args("-machine", "virt,gic-version=2")
>          self.add_common_args()
> -        self.launch_and_wait()
> +        self.launch_and_wait(set_up_ssh_connection=False)
>  
>      def test_virt_kvm_gicv3(self):
>          """
> @@ -111,7 +111,7 @@ def test_virt_kvm_gicv3(self):
>          self.vm.add_args("-cpu", "host")
>          self.vm.add_args("-machine", "virt,gic-version=3")
>          self.add_common_args()
> -        self.launch_and_wait()
> +        self.launch_and_wait(set_up_ssh_connection=False)
>  
>  
>  class BootLinuxPPC64(LinuxTest):
> @@ -128,7 +128,7 @@ def test_pseries_tcg(self):
>          """
>          self.require_accelerator("tcg")
>          self.vm.add_args("-accel", "tcg")
> -        self.launch_and_wait()
> +        self.launch_and_wait(set_up_ssh_connection=False)
>  
>  
>  class BootLinuxS390X(LinuxTest):
> @@ -146,4 +146,4 @@ def test_s390_ccw_virtio_tcg(self):
>          """
>          self.require_accelerator("tcg")
>          self.vm.add_args("-accel", "tcg")
> -        self.launch_and_wait()
> +        self.launch_and_wait(set_up_ssh_connection=False)
> diff --git a/tests/acceptance/virtiofs_submounts.py b/tests/acceptance/virtiofs_submounts.py
> index e10a935ac4e..e019d3b896b 100644
> --- a/tests/acceptance/virtiofs_submounts.py
> +++ b/tests/acceptance/virtiofs_submounts.py
> @@ -136,7 +136,6 @@ def set_up_virtiofs(self):
>  
>      def launch_vm(self):
>          self.launch_and_wait()
> -        self.ssh_connect('root', self.ssh_key)
>  
>      def set_up_nested_mounts(self):
>          scratch_dir = os.path.join(self.shared_dir, 'scratch')
> 



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v3 04/11] Acceptance Tests: move useful ssh methods to base class
  2021-04-12  4:46 ` [PATCH v3 04/11] Acceptance Tests: move useful ssh methods to base class Cleber Rosa
@ 2021-04-19 15:22   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 18+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-04-19 15:22 UTC (permalink / raw)
  To: Cleber Rosa, qemu-devel
  Cc: Thomas Huth, Eduardo Habkost, John Snow,
	Wainer dos Santos Moschetta, Willian Rampazzo, Eric Auger,
	Willian Rampazzo, Alex Bennée, Aurelien Jarno, Beraldo Leal

On 4/12/21 6:46 AM, Cleber Rosa wrote:
> Both the virtiofs submounts and the linux ssh mips malta tests
> contains useful methods related to ssh that deserve to be made
> available to other tests.  Let's move them to an auxiliary, mix-in
> class that will be used on the base LinuxTest class.
> 
> The method that helps with setting up an ssh connection will now
> support both key and password based authentication, defaulting to key
> based.
> 
> Signed-off-by: Cleber Rosa <crosa@redhat.com>
> Reviewed-by: Wainer dos Santos Moschetta <wainersm@redhat.com>
> Reviewed-by: Willian Rampazzo <willianr@redhat.com>
> Reviewed-by: Eric Auger <eric.auger@redhat.com>
> Signed-off-by: Cleber Rosa <crosa@redhat.com>
> ---
>  tests/acceptance/avocado_qemu/__init__.py | 48 ++++++++++++++++++++++-
>  tests/acceptance/linux_ssh_mips_malta.py  | 40 ++-----------------
>  tests/acceptance/virtiofs_submounts.py    | 37 -----------------
>  3 files changed, 50 insertions(+), 75 deletions(-)
> 
> diff --git a/tests/acceptance/avocado_qemu/__init__.py b/tests/acceptance/avocado_qemu/__init__.py
> index 83b1741ec85..67f75f66e56 100644
> --- a/tests/acceptance/avocado_qemu/__init__.py
> +++ b/tests/acceptance/avocado_qemu/__init__.py

Don't we need to update the copyright in this file?
I ask because I'm never sure how that works.... In my patches
when I move code which is in a copyrighted file, I add the same
copyright lines to the copied file.

> @@ -20,6 +20,7 @@
>  from avocado.utils import cloudinit
>  from avocado.utils import datadrainer
>  from avocado.utils import network
> +from avocado.utils import ssh
>  from avocado.utils import vmimage
>  from avocado.utils.path import find_command
>  
> @@ -43,6 +44,8 @@
>  from qemu.accel import kvm_available
>  from qemu.accel import tcg_available
>  from qemu.machine import QEMUMachine
> +from qemu.utils import get_info_usernet_hostfwd_port
> +
>  
>  def is_readable_executable_file(path):
>      return os.path.isfile(path) and os.access(path, os.R_OK | os.X_OK)
> @@ -253,7 +256,50 @@ def fetch_asset(self, name,
>                          cancel_on_missing=cancel_on_missing)
>  
>  
> -class LinuxTest(Test):
> +class LinuxSSHMixIn:
> +    """Contains utility methods for interacting with a guest via SSH."""
> +
> +    def ssh_connect(self, username, credential, credential_is_key=True):
> +        self.ssh_logger = logging.getLogger('ssh')
> +        res = self.vm.command('human-monitor-command',
> +                              command_line='info usernet')
> +        port = get_info_usernet_hostfwd_port(res)
> +        self.assertIsNotNone(port)
> +        self.assertGreater(port, 0)
> +        self.log.debug('sshd listening on port: %d', port)
> +        if credential_is_key:
> +            self.ssh_session = ssh.Session('127.0.0.1', port=port,
> +                                           user=username, key=credential)
> +        else:
> +            self.ssh_session = ssh.Session('127.0.0.1', port=port,
> +                                           user=username, password=credential)
> +        for i in range(10):
> +            try:
> +                self.ssh_session.connect()
> +                return
> +            except:
> +                time.sleep(4)
> +                pass
> +        self.fail('ssh connection timeout')
> +
> +    def ssh_command(self, command):
> +        self.ssh_logger.info(command)
> +        result = self.ssh_session.cmd(command)
> +        stdout_lines = [line.rstrip() for line
> +                        in result.stdout_text.splitlines()]
> +        for line in stdout_lines:
> +            self.ssh_logger.info(line)
> +        stderr_lines = [line.rstrip() for line
> +                        in result.stderr_text.splitlines()]
> +        for line in stderr_lines:
> +            self.ssh_logger.warning(line)
> +
> +        self.assertEqual(result.exit_status, 0,
> +                         f'Guest command failed: {command}')
> +        return stdout_lines, stderr_lines
> +
> +
> +class LinuxTest(Test, LinuxSSHMixIn):
>      """Facilitates having a cloud-image Linux based available.
>  
>      For tests that indend to interact with guests, this is a better choice
> diff --git a/tests/acceptance/linux_ssh_mips_malta.py b/tests/acceptance/linux_ssh_mips_malta.py
> index 052008f02d4..61c9079d047 100644
> --- a/tests/acceptance/linux_ssh_mips_malta.py
> +++ b/tests/acceptance/linux_ssh_mips_malta.py
> @@ -12,16 +12,14 @@
>  import time
>  
>  from avocado import skipUnless
> -from avocado_qemu import Test
> +from avocado_qemu import Test, LinuxSSHMixIn
>  from avocado_qemu import wait_for_console_pattern
>  from avocado.utils import process
>  from avocado.utils import archive
>  from avocado.utils import ssh
>  
> -from qemu.utils import get_info_usernet_hostfwd_port
>  
> -
> -class LinuxSSH(Test):
> +class LinuxSSH(Test, LinuxSSHMixIn):
>  
>      timeout = 150 # Not for 'configure --enable-debug --enable-debug-tcg'
>  
> @@ -72,41 +70,9 @@ def get_kernel_info(self, endianess, wordsize):
>      def setUp(self):
>          super(LinuxSSH, self).setUp()
>  
> -    def ssh_connect(self, username, password):
> -        self.ssh_logger = logging.getLogger('ssh')
> -        res = self.vm.command('human-monitor-command',
> -                              command_line='info usernet')
> -        port = get_info_usernet_hostfwd_port(res)
> -        if not port:
> -            self.cancel("Failed to retrieve SSH port")
> -        self.log.debug("sshd listening on port:" + port)
> -        self.ssh_session = ssh.Session(self.VM_IP, port=int(port),
> -                                       user=username, password=password)
> -        for i in range(10):
> -            try:
> -                self.ssh_session.connect()
> -                return
> -            except:
> -                time.sleep(4)
> -                pass
> -        self.fail("ssh connection timeout")
> -
>      def ssh_disconnect_vm(self):
>          self.ssh_session.quit()
>  
> -    def ssh_command(self, command, is_root=True):
> -        self.ssh_logger.info(command)
> -        result = self.ssh_session.cmd(command)
> -        stdout_lines = [line.rstrip() for line
> -                        in result.stdout_text.splitlines()]
> -        for line in stdout_lines:
> -            self.ssh_logger.info(line)
> -        stderr_lines = [line.rstrip() for line
> -                        in result.stderr_text.splitlines()]
> -        for line in stderr_lines:
> -            self.ssh_logger.warning(line)
> -        return stdout_lines, stderr_lines
> -
>      def boot_debian_wheezy_image_and_ssh_login(self, endianess, kernel_path):
>          image_url, image_hash = self.get_image_info(endianess)
>          image_path = self.fetch_asset(image_url, asset_hash=image_hash)
> @@ -127,7 +93,7 @@ def boot_debian_wheezy_image_and_ssh_login(self, endianess, kernel_path):
>          wait_for_console_pattern(self, console_pattern, 'Oops')
>          self.log.info('sshd ready')
>  
> -        self.ssh_connect('root', 'root')
> +        self.ssh_connect('root', 'root', False)
>  
>      def shutdown_via_ssh(self):
>          self.ssh_command('poweroff')


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v3 03/11] Python: add utility function for retrieving port redirection
  2021-04-12  4:46 ` [PATCH v3 03/11] Python: add utility function for retrieving port redirection Cleber Rosa
@ 2021-05-13 19:10   ` John Snow
  0 siblings, 0 replies; 18+ messages in thread
From: John Snow @ 2021-05-13 19:10 UTC (permalink / raw)
  To: Cleber Rosa, qemu-devel
  Cc: Thomas Huth, Eduardo Habkost, Philippe Mathieu-Daudé,
	Wainer dos Santos Moschetta, Willian Rampazzo, Eric Auger,
	Willian Rampazzo, Alex Bennée, Aurelien Jarno, Beraldo Leal

On 4/12/21 12:46 AM, Cleber Rosa wrote:
> Slightly different versions for the same utility code are currently
> present on different locations.  This unifies them all, giving
> preference to the version from virtiofs_submounts.py, because of the
> last tweaks added to it.
> 
> While at it, this adds a "qemu.utils" module to host the utility
> function and a test.
> 
> Signed-off-by: Cleber Rosa <crosa@redhat.com>
> Reviewed-by: Wainer dos Santos Moschetta <wainersm@redhat.com>
> Reviewed-by: Eric Auger <eric.auger@redhat.com>
> Reviewed-by: Willian Rampazzo <willianr@redhat.com>
> ---
>   python/qemu/utils.py                     | 33 ++++++++++++++++++++++++
>   tests/acceptance/info_usernet.py         | 29 +++++++++++++++++++++
>   tests/acceptance/linux_ssh_mips_malta.py | 16 +++++-------
>   tests/acceptance/virtiofs_submounts.py   | 21 ++++-----------
>   tests/vm/basevm.py                       |  7 ++---
>   5 files changed, 76 insertions(+), 30 deletions(-)
>   create mode 100644 python/qemu/utils.py
>   create mode 100644 tests/acceptance/info_usernet.py
> 
> diff --git a/python/qemu/utils.py b/python/qemu/utils.py
> new file mode 100644
> index 00000000000..5ed789275ee
> --- /dev/null
> +++ b/python/qemu/utils.py
> @@ -0,0 +1,33 @@
> +"""
> +QEMU utility library
> +
> +This offers miscellaneous utility functions, which may not be easily
> +distinguishable or numerous to be in their own module.
> +"""
> +
> +# Copyright (C) 2021 Red Hat Inc.
> +#
> +# Authors:
> +#  Cleber Rosa <crosa@redhat.com>
> +#
> +# This work is licensed under the terms of the GNU GPL, version 2.  See
> +# the COPYING file in the top-level directory.
> +#
> +
> +import re
> +from typing import Optional
> +
> +
> +def get_info_usernet_hostfwd_port(info_usernet_output: str) -> Optional[int]:
> +    """
> +    Returns the port given to the hostfwd parameter via info usernet
> +
> +    :param info_usernet_output: output generated by hmp command "info usernet"
> +    :return: the port number allocated by the hostfwd option
> +    """
> +    for line in info_usernet_output.split('\r\n'):
> +        regex = r'TCP.HOST_FORWARD.*127\.0\.0\.1\s+(\d+)\s+10\.'
> +        match = re.search(regex, line)
> +        if match is not None:
> +            return int(match[1])
> +    return None
> diff --git a/tests/acceptance/info_usernet.py b/tests/acceptance/info_usernet.py
> new file mode 100644
> index 00000000000..9c1fd903a0b
> --- /dev/null
> +++ b/tests/acceptance/info_usernet.py
> @@ -0,0 +1,29 @@
> +# Test for the hmp command "info usernet"
> +#
> +# Copyright (c) 2021 Red Hat, Inc.
> +#
> +# Author:
> +#  Cleber Rosa <crosa@redhat.com>
> +#
> +# This work is licensed under the terms of the GNU GPL, version 2 or
> +# later.  See the COPYING file in the top-level directory.
> +
> +from avocado_qemu import Test
> +
> +from qemu.utils import get_info_usernet_hostfwd_port
> +
> +
> +class InfoUsernet(Test):
> +
> +    def test_hostfwd(self):
> +        self.vm.add_args('-netdev', 'user,id=vnet,hostfwd=:127.0.0.1:0-:22')
> +        self.vm.launch()
> +        res = self.vm.command('human-monitor-command',
> +                              command_line='info usernet')
> +        port = get_info_usernet_hostfwd_port(res)
> +        self.assertIsNotNone(port,
> +                             ('"info usernet" output content does not seem to '
> +                              'contain the redirected port'))
> +        self.assertGreater(port, 0,
> +                           ('Found a redirected port that is not greater than'
> +                            ' zero'))
> diff --git a/tests/acceptance/linux_ssh_mips_malta.py b/tests/acceptance/linux_ssh_mips_malta.py
> index 6dbd02d49d5..052008f02d4 100644
> --- a/tests/acceptance/linux_ssh_mips_malta.py
> +++ b/tests/acceptance/linux_ssh_mips_malta.py
> @@ -18,6 +18,8 @@
>   from avocado.utils import archive
>   from avocado.utils import ssh
>   
> +from qemu.utils import get_info_usernet_hostfwd_port
> +
>   
>   class LinuxSSH(Test):
>   
> @@ -70,18 +72,14 @@ def get_kernel_info(self, endianess, wordsize):
>       def setUp(self):
>           super(LinuxSSH, self).setUp()
>   
> -    def get_portfwd(self):
> +    def ssh_connect(self, username, password):
> +        self.ssh_logger = logging.getLogger('ssh')
>           res = self.vm.command('human-monitor-command',
>                                 command_line='info usernet')
> -        line = res.split('\r\n')[2]
> -        port = re.split(r'.*TCP.HOST_FORWARD.*127\.0\.0\.1 (\d+)\s+10\..*',
> -                        line)[1]
> +        port = get_info_usernet_hostfwd_port(res)
> +        if not port:
> +            self.cancel("Failed to retrieve SSH port")
>           self.log.debug("sshd listening on port:" + port)
> -        return port
> -
> -    def ssh_connect(self, username, password):
> -        self.ssh_logger = logging.getLogger('ssh')
> -        port = self.get_portfwd()
>           self.ssh_session = ssh.Session(self.VM_IP, port=int(port),
>                                          user=username, password=password)
>           for i in range(10):
> diff --git a/tests/acceptance/virtiofs_submounts.py b/tests/acceptance/virtiofs_submounts.py
> index ca64b76301f..57a7047342f 100644
> --- a/tests/acceptance/virtiofs_submounts.py
> +++ b/tests/acceptance/virtiofs_submounts.py
> @@ -9,6 +9,8 @@
>   from avocado_qemu import wait_for_console_pattern
>   from avocado.utils import ssh
>   
> +from qemu.utils import get_info_usernet_hostfwd_port
> +
>   
>   def run_cmd(args):
>       subp = subprocess.Popen(args,
> @@ -73,27 +75,14 @@ class VirtiofsSubmountsTest(LinuxTest):
>       :avocado: tags=accel:kvm
>       """
>   
> -    def get_portfwd(self):
> -        port = None
> -
> +    def ssh_connect(self, username, keyfile):
> +        self.ssh_logger = logging.getLogger('ssh')
>           res = self.vm.command('human-monitor-command',
>                                 command_line='info usernet')
> -        for line in res.split('\r\n'):
> -            match = \
> -                re.search(r'TCP.HOST_FORWARD.*127\.0\.0\.1\s+(\d+)\s+10\.',
> -                          line)
> -            if match is not None:
> -                port = int(match[1])
> -                break
> -
> +        port = get_info_usernet_hostfwd_port(res)
>           self.assertIsNotNone(port)
>           self.assertGreater(port, 0)
>           self.log.debug('sshd listening on port: %d', port)
> -        return port
> -
> -    def ssh_connect(self, username, keyfile):
> -        self.ssh_logger = logging.getLogger('ssh')
> -        port = self.get_portfwd()
>           self.ssh_session = ssh.Session('127.0.0.1', port=port,
>                                          user=username, key=keyfile)
>           for i in range(10):
> diff --git a/tests/vm/basevm.py b/tests/vm/basevm.py
> index 00f1d5ca8da..75ce07df364 100644
> --- a/tests/vm/basevm.py
> +++ b/tests/vm/basevm.py
> @@ -21,6 +21,7 @@
>   sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python'))
>   from qemu.accel import kvm_available
>   from qemu.machine import QEMUMachine
> +from qemu.utils import get_info_usernet_hostfwd_port
>   import subprocess
>   import hashlib
>   import argparse
> @@ -306,11 +307,7 @@ def boot(self, img, extra_args=[]):
>           self.console_init()
>           usernet_info = guest.qmp("human-monitor-command",
>                                    command_line="info usernet")
> -        self.ssh_port = None
> -        for l in usernet_info["return"].splitlines():
> -            fields = l.split()
> -            if "TCP[HOST_FORWARD]" in fields and "22" in fields:
> -                self.ssh_port = l.split()[3]
> +        self.ssh_port = get_info_usernet_hostfwd_port(usernet_info)
>           if not self.ssh_port:
>               raise Exception("Cannot find ssh port from 'info usernet':\n%s" % \
>                               usernet_info)
> 

ACK on this.

Can we stick it on top of https://gitlab.com/jsnow/qemu/-/merge_requests/4 ?

(You posted this before I posted v6 of the Python series, but I am not 
sure how close you are with this series. Actually, I'm not sure how 
close we are on mine either.)



^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2021-05-13 19:12 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-12  4:46 [PATCH v3 00/11] Acceptance Test: introduce base class for Linux based tests Cleber Rosa
2021-04-12  4:46 ` [PATCH v3 01/11] tests/acceptance/virtiofs_submounts.py: add missing accel tag Cleber Rosa
2021-04-12  4:46 ` [PATCH v3 02/11] tests/acceptance/virtiofs_submounts.py: evaluate string not length Cleber Rosa
2021-04-12  4:46 ` [PATCH v3 03/11] Python: add utility function for retrieving port redirection Cleber Rosa
2021-05-13 19:10   ` John Snow
2021-04-12  4:46 ` [PATCH v3 04/11] Acceptance Tests: move useful ssh methods to base class Cleber Rosa
2021-04-19 15:22   ` Philippe Mathieu-Daudé
2021-04-12  4:46 ` [PATCH v3 05/11] Acceptance Tests: add port redirection for ssh by default Cleber Rosa
2021-04-12  4:46 ` [PATCH v3 06/11] Acceptance Tests: make username/password configurable Cleber Rosa
2021-04-12  4:46 ` [PATCH v3 07/11] Acceptance Tests: set up SSH connection by default after boot for LinuxTest Cleber Rosa
2021-04-19 15:05   ` Auger Eric
2021-04-12  4:46 ` [PATCH v3 08/11] tests/acceptance/virtiofs_submounts.py: remove launch_vm() Cleber Rosa
2021-04-12  4:46 ` [PATCH v3 09/11] Acceptance Tests: add basic documentation on LinuxTest base class Cleber Rosa
2021-04-12  4:46 ` [PATCH v3 10/11] Acceptance Tests: introduce CPU hotplug test Cleber Rosa
2021-04-12  4:46 ` [PATCH v3 11/11] tests/acceptance/virtiofs_submounts.py: fix setup of SSH pubkey Cleber Rosa
2021-04-12 15:08   ` Wainer dos Santos Moschetta
2021-04-12 18:59   ` Willian Rampazzo
2021-04-19 15:03   ` Auger Eric

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).