Improve documentation of arnied wrapper and tests
authorSamir Aguiar <samir.aguiar@intra2net.com>
Tue, 31 Aug 2021 22:39:04 +0000 (19:39 -0300)
committerChristian Herdtweck <christian.herdtweck@intra2net.com>
Fri, 10 Sep 2021 11:57:58 +0000 (13:57 +0200)
src/arnied_wrapper.py
test/test_arnied_wrapper.py

index 991e2a4..88f3344 100644 (file)
@@ -81,7 +81,7 @@ def run_cmd(cmd="", ignore_errors=False, vm=None, timeout=60):
     :param str cmd: command to run
     :param bool ignore_errors: whether not to raise error on command failure
     :param vm: vm to run on if running on a guest instead of the host
-    :type vm: VM object or None
+    :type vm: :py:class:`virttest.qemu_vm.VM` or None
     :param int timeout: amount of seconds to wait for the program to run
     :returns: command result output
     :rtype: str
@@ -108,7 +108,7 @@ def verify_running(process='arnied', timeout=60, vm=None):
     :param str process: process to verify if running
     :param int timeout: run verification timeout
     :param vm: vm to run on if running on a guest instead of the host
-    :type vm: VM object or None
+    :type vm: :py:class:`virttest.qemu_vm.VM` or None
     :raises: :py:class:`RuntimeError` if process is not running
     """
     platform_str = ""
@@ -135,7 +135,7 @@ def accept_licence(vm=None):
     Accept the Intra2net license.
 
     :param vm: vm to run on if running on a guest instead of the host
-    :type vm: VM object or None
+    :type vm: :py:class:`virttest.qemu_vm.VM` or None
 
     This is mostly useful for simplified webpage access.
     """
@@ -155,7 +155,7 @@ def go_online(provider_id, wait_online=True, timeout=60, vm=None):
     :param wait_online: whether to wait until online
     :type wait_online: bool
     :param vm: vm to run on if running on a guest instead of the host
-    :type vm: VM object or None
+    :type vm: :py:class:`virttest.qemu_vm.VM` or None
 
     .. seealso:: :py:func:`go_offline`, :py:func:`wait_for_online`
     """
@@ -182,7 +182,7 @@ def go_offline(wait_offline=True, vm=None):
     :param wait_offline: whether to wait until offline
     :type wait_offline: bool
     :param vm: vm to run on if running on a guest instead of the host
-    :type vm: VM object or None
+    :type vm: :py:class:`virttest.qemu_vm.VM` or None
 
     .. seealso:: :py:func:`go_online`, :py:func:`wait_for_offline`
     """
@@ -203,7 +203,7 @@ def wait_for_offline(timeout=60, vm=None):
 
     :param int timeout: maximum timeout for waiting
     :param vm: vm to run on if running on a guest instead of the host
-    :type vm: VM object or None
+    :type vm: :py:class:`virttest.qemu_vm.VM` or None
     """
     _wait_for_online_status('offline', None, timeout, vm)
 
@@ -216,7 +216,7 @@ def wait_for_online(provider_id, timeout=60, vm=None):
     :type provider_id: int
     :param int timeout: maximum timeout for waiting
     :param vm: vm to run on if running on a guest instead of the host
-    :type vm: VM object or None
+    :type vm: :py:class:`virttest.qemu_vm.VM` or None
     """
     _wait_for_online_status('online', provider_id, timeout, vm)
 
@@ -265,7 +265,7 @@ def disable_virscan(vm=None):
     Disable virscan that could block GENERATE and thus all configurations.
 
     :param vm: vm to run on if running on a guest instead of the host
-    :type vm: VM object or None
+    :type vm: :py:class:`virttest.qemu_vm.VM` or None
     """
     log.info("Disabling virus database update")
     unset_cnf("VIRSCAN_UPDATE_CRON", vm=vm)
@@ -286,7 +286,7 @@ def email_transfer(vm=None):
     Transfer all the emails using the guest tool arnied_helper.
 
     :param vm: vm to run on if running on a guest instead of the host
-    :type vm: VM object or None
+    :type vm: :py:class:`virttest.qemu_vm.VM` or None
     """
     cmd = f"{BIN_ARNIED_HELPER} --transfer-mail"
     result = run_cmd(cmd=cmd, vm=vm)
@@ -299,7 +299,7 @@ def wait_for_email_transfer(timeout=300, vm=None):
 
     :param int timeout: email transfer timeout
     :param vm: vm to run on if running on a guest instead of the host
-    :type vm: VM object or None
+    :type vm: :py:class:`virttest.qemu_vm.VM` or None
     """
     for i in range(timeout):
         if i % 10 == 0:
@@ -324,7 +324,7 @@ def schedule(program, exec_time=0, optional_args="", vm=None):
     :param int exec_time: scheduled time of program's execution
     :param str optional_args: optional command line arguments
     :param vm: vm to run on if running on a guest instead of the host
-    :type vm: VM object or None
+    :type vm: :py:class:`virttest.qemu_vm.VM` or None
     """
     log.info("Scheduling %s to be executed at %i", program, exec_time)
     schedule_dir = "/var/intranator/schedule"
@@ -366,7 +366,7 @@ def wait_for_run(program, timeout=300, retries=10, vm=None):
     :param int timeout: program run timeout
     :param int retries: number of tries to verify that the program is scheduled or running
     :param vm: vm to run on if running on a guest instead of the host
-    :type vm: VM object or None
+    :type vm: :py:class:`virttest.qemu_vm.VM` or None
     """
     log.info("Waiting for program %s to finish with timeout %i",
              program, timeout)
@@ -393,7 +393,7 @@ def wait_for_arnied(timeout=60, vm=None):
 
     :param int timeout: maximum number of seconds to wait
     :param vm: vm to run on if running on a guest instead of the host
-    :type vm: VM object or None
+    :type vm: :py:class:`virttest.qemu_vm.VM` or None
     """
     cmd = f"{BIN_ARNIED_HELPER} --wait-for-arnied-socket " \
           f"--wait-for-arnied-socket-timeout {timeout}"
@@ -414,7 +414,7 @@ def get_cnf(cnf_key, cnf_index=1, regex=".*", compact=False, timeout=30, vm=None
     :param bool compact: whether to retrieve compact version of the matched cnf keys
     :param int timeout: arnied run verification timeout
     :param vm: vm to run on if running on a guest instead of the host
-    :type vm: VM object or None
+    :type vm: :py:class:`virttest.qemu_vm.VM` or None
     :returns: extracted information via the regex
     :rtype: Match object
 
@@ -440,7 +440,7 @@ def get_cnf_id(cnf_key, value, timeout=30, vm=None):
     :param str value: cnf value of the cnf key
     :param int timeout: arnied run verification timeout
     :param vm: vm to run on if running on a guest instead of the host
-    :type vm: VM object or None
+    :type vm: :py:class:`virttest.qemu_vm.VM` or None
     :returns: the cnf id or -1 if no such cnf variable
     :rtype: int
     """
@@ -465,7 +465,7 @@ def get_cnfvar(varname=None, instance=None, data=None, timeout=30, vm=None):
     :param str data: "data" field by which the resulting CNF_VAR list should be filtered
     :param int timeout: arnied run verification timeout
     :param vm: vm to run on if running on a guest instead of the host
-    :type vm: VM object or None
+    :type vm: :py:class:`virttest.qemu_vm.VM` or None
     :returns: the resulting "cnfvar" structure or None if the lookup fails or the result could not be parsed
     :rtype: cnfvar option
     """
@@ -514,7 +514,7 @@ def get_cnfvar_id(varname, data, timeout=30, vm=None):
     :param str data: "data" field by which the resulting CNF_VAR list should be filtered
     :param int timeout: arnied run verification timeout
     :param vm: vm to run on if running on a guest instead of the host
-    :type vm: VM object or None
+    :type vm: :py:class:`virttest.qemu_vm.VM` or None
     :returns: the cnf id or -1 if no such cnf variable
     :rtype: int
     """
@@ -551,7 +551,7 @@ def unset_cnf(varname="", instance="", timeout=30, vm=None):
     :param int instance: "instance" of that variable to unset
     :param int timeout: arnied run verification timeout
     :param vm: vm to run on if running on a guest instead of the host
-    :type vm: VM object or None
+    :type vm: :py:class:`virttest.qemu_vm.VM` or None
     """
     wait_for_arnied(timeout=timeout, vm=vm)
 
@@ -570,7 +570,7 @@ def set_cnf(config_files, kind="cnf", timeout=30, vm=None):
     :param str kind: "json" or "cnf"
     :param int timeout: arnied run verification timeout
     :param vm: vm to run on if running on a guest instead of the host
-    :type vm: VM object or None
+    :type vm: :py:class:`virttest.qemu_vm.VM` or None
     :raises: :py:class:`ConfigError` if cannot apply file
 
     The config files must be provided and are always expected to be found on
@@ -626,7 +626,7 @@ def set_cnf_semidynamic(config_files, params_dict, regex_dict=None,
     :param str kind: "json" or "cnf"
     :param int timeout: arnied run verification timeout
     :param vm: vm to run on if running on a guest instead of the host
-    :type vm: VM object or None
+    :type vm: :py:class:`virttest.qemu_vm.VM` or None
 
     The config files must be provided and are always expected to be found on
     the host. If these are absolute paths, they will be kept as is or
@@ -652,7 +652,7 @@ def set_cnf_dynamic(cnf, config_file=None, kind="cnf", timeout=30, vm=None):
     :param str kind: "json", "cnf", or "raw"
     :param int timeout: arnied run verification timeout
     :param vm: vm to run on if running on a guest instead of the host
-    :type vm: VM object or None
+    :type vm: :py:class:`virttest.qemu_vm.VM` or None
     :raises: :py:class:`ValueError` if `kind` is not an acceptable value
     :raises: :py:class:`ConfigError` if cannot apply file
 
index 57ab125..e061150 100755 (executable)
@@ -28,8 +28,19 @@ from src import arnied_wrapper
 
 
 class DummyCmdOutputMapping(object):
+    """
+    Class to replace the :py:function:`arnied_wrapper.run_cmd` function.
 
+    In the arnied_wrapper, when running a command, instead of calling the actual
+    function, this class' constructor will be invoked and an instance returned
+    instead. It stubs :py:class:`subprocess.CompletedProcess`, such that the
+    returncode and stdout attributes are set depending on the command or on the
+    test.
+    """
+
+    # whether to return 1 as a fail indicator
     fail_switch = False
+    # mapping between expected commands and their mocked output + return code
     cmds = [
         {"cmd": "pgrep -l -x arnied", "stdout": b"", "returncode": 0},
 
@@ -57,6 +68,11 @@ class DummyCmdOutputMapping(object):
     asserted_cmds = []
 
     def __init__(self, cmd="", ignore_errors=False, vm=None, timeout=60):
+        """
+        Class constructor to mimic the run function of the arnied wrapper.
+
+        Arguments are the same of the mocked function.
+        """
         self.returncode = 0
         self.stdout = b""
         self._get_result(cmd)
@@ -64,9 +80,19 @@ class DummyCmdOutputMapping(object):
             self.returncode = 1
 
     def __str__(self):
+        """String representation of this class."""
         return "status %i, stdout %s" % (self.returncode, self.stdout)
 
     def _get_result(self, cmd):
+        """
+        Return the first (or raise) values in the mapping matching the command.
+
+        :param str cmd: command to check the mapping against
+        :raises: :py:class:`ValueError` if the command has no corresponding
+                 mapping
+        :returns: this instance with the return code and stdout attributes set
+        :rtype: :py:class:`DummyCmdOutputMapping`
+        """
         for dummy_cmd in self.asserted_cmds:
             if dummy_cmd['cmd'] == cmd:
                 self.returncode = dummy_cmd['returncode']
@@ -76,15 +102,16 @@ class DummyCmdOutputMapping(object):
                          "for the universe" % cmd)
 
 
-@mock.patch('src.arnied_wrapper.run_cmd', DummyCmdOutputMapping)
+# make sure that invoking `run_cmd` returns an instance of DummyCmdOutputMapping
+@mock.patch("src.arnied_wrapper.run_cmd", DummyCmdOutputMapping)
 class ArniedWrapperTest(unittest.TestCase):
-
     def setUp(self):
         DummyCmdOutputMapping.fail_switch = False
         DummyCmdOutputMapping.asserted_cmds = []
         self.cmd_db = DummyCmdOutputMapping.cmds
 
     def test_verify_running(self):
+        """Test checking for running programs."""
         DummyCmdOutputMapping.asserted_cmds = self.cmd_db[0:1]
         arnied_wrapper.verify_running(timeout=1)
         DummyCmdOutputMapping.fail_switch = True
@@ -92,10 +119,12 @@ class ArniedWrapperTest(unittest.TestCase):
             arnied_wrapper.verify_running(timeout=1)
 
     def test_wait_for_arnied(self):
+        """Test waiting for arnied to be ready."""
         DummyCmdOutputMapping.asserted_cmds = self.cmd_db
         arnied_wrapper.wait_for_arnied(timeout=10)
 
     def test_accept_license(self):
+        """Test accepting license."""
         DummyCmdOutputMapping.asserted_cmds = self.cmd_db[1:3]
         arnied_wrapper.accept_licence()
         # make sure an error is ignored since license might
@@ -108,9 +137,11 @@ class ArniedWrapperTest(unittest.TestCase):
         arnied_wrapper.go_online(1)
 
     def test_disable_virscan(self):
+        """Test disabling the virus scanner."""
         DummyCmdOutputMapping.asserted_cmds = self.cmd_db[6:]
         arnied_wrapper.disable_virscan()
 
     def test_email_transfer(self):
+        """Test e-mail transferring."""
         DummyCmdOutputMapping.asserted_cmds = self.cmd_db[14:15]
         arnied_wrapper.email_transfer()