예제 #1
0
 def test_run_remote_util_arg_types(self):
     """Test that a remote utility runs properly with different argument types."""
     result = remote_door.run_remote_util(
         self.session,
         "json",
         "dumps",
         ["foo", {
             "bar": ["baz", None, 1.0, 2]
         }],
         skipkeys=False,
         separators=None,
         # must be boolean but we want to test string
         allow_nan="string for yes")
     self.assertEqual(result, '["foo", {"bar": ["baz", null, 1.0, 2]}]')
     local_controls = glob.glob("tmp*.control")
     remote_controls = glob.glob(
         os.path.join(remote_door.REMOTE_CONTROL_DIR, "tmp*.control"))
     self.assertEqual(len(local_controls), len(remote_controls))
     self.assertEqual(len(remote_controls), 1)
     self.assertEqual(os.path.basename(local_controls[0]),
                      os.path.basename(remote_controls[0]))
     with open(remote_controls[0]) as handle:
         control_lines = handle.readlines()
     self.assertIn("import json\n", control_lines)
     self.assertIn(
         "result = json.dumps(['foo', {'bar': ['baz', None, 1.0, 2]}], "
         "allow_nan=r'string for yes', separators=None, skipkeys=False)\n",
         control_lines)
예제 #2
0
 def test_run_remote_util(self):
     """Test that a remote utility can be run properly."""
     remote_door.run_remote_util(self.session, "foo_util", "bar_func",
                                 42, "spring", sing="zazz")
     # python 3.6 and above
     if hasattr(self.session.cmd, "assert_called_once"):
         self.session.cmd.assert_called_once()
     else:
         self.assertEqual(self.session.cmd.call_count, 1)
     command = self.session.cmd.call_args[0][0]
     self.assertTrue(re.match(r"python3 /tmp/tmp.+\.control", command),
                     "A control file has to be generated and called on the peer")
     control = os.path.basename(command.lstrip("python3 "))
     with open(control) as handle:
         control_lines = handle.readlines()
         self.assertIn("import foo_util\n", control_lines)
         self.assertIn("result = foo_util.bar_func(42, r'spring', sing=r'zazz')\n",
                       control_lines)
예제 #3
0
 def test_run_remote_util_object(self):
     """Test that a remote utility object can be run properly."""
     util_object = "BarClass(val1, 'val2')"
     remote_door.run_remote_util(self.session, "foo_util",
                                 "%s.baz_func" % util_object,
                                 "Wonderland is fun", wanderer=None)
     # python 3.6 and above
     if hasattr(self.session.cmd, "assert_called_once"):
         self.session.cmd.assert_called_once()
     else:
         self.assertEqual(self.session.cmd.call_count, 1)
     command = self.session.cmd.call_args[0][0]
     self.assertTrue(re.match(r"python3 /tmp/tmp.+\.control", command),
                     "A control file has to be generated and called on the peer")
     control = os.path.basename(command.lstrip("python3 "))
     with open(control) as handle:
         control_lines = handle.readlines()
         self.assertIn("import foo_util\n", control_lines)
         self.assertIn("result = foo_util.BarClass(val1, 'val2').baz_func("
                       "r'Wonderland is fun', wanderer=None)\n",
                       control_lines)
예제 #4
0
 def test_run_remote_util(self):
     """Test that a remote utility runs properly."""
     result = remote_door.run_remote_util(self.session, "math", "gcd", 2, 3)
     self.assertEqual(int(result), 1)
     local_controls = glob.glob("tmp*.control")
     remote_controls = glob.glob(
         os.path.join(remote_door.REMOTE_CONTROL_DIR, "tmp*.control"))
     self.assertEqual(len(local_controls), len(remote_controls))
     self.assertEqual(len(remote_controls), 1)
     self.assertEqual(os.path.basename(local_controls[0]),
                      os.path.basename(remote_controls[0]))
     with open(remote_controls[0]) as handle:
         control_lines = handle.readlines()
     self.assertIn("import math\n", control_lines)
     self.assertIn("result = math.gcd(2, 3)\n", control_lines)
예제 #5
0
    def test_run_remote_util_object(self):
        """Test that a remote utility object runs properly."""
        result = remote_door.run_remote_util(self.session, "collections",
                                             "OrderedDict().get", "akey")
        self.assertEqual(result, "None")

        local_controls = glob.glob("tmp*.control")
        remote_controls = glob.glob(
            os.path.join(remote_door.REMOTE_CONTROL_DIR, "tmp*.control"))
        self.assertEqual(len(local_controls), len(remote_controls))
        self.assertEqual(len(remote_controls), 1)
        self.assertEqual(os.path.basename(local_controls[0]),
                         os.path.basename(remote_controls[0]))
        with open(remote_controls[0]) as handle:
            control_lines = handle.readlines()
        self.assertIn("result = collections.OrderedDict().get(r'akey')\n",
                      control_lines)
예제 #6
0
def run(test, params, env):
    """
    Main test run.

    :param test: test object
    :type test: :py:class:`avocado_vt.test.VirtTest`
    :param params: extended dictionary of parameters
    :type params: :py:class:`virttest.utils_params.Params`
    :param env: environment object
    :type env: :py:class:`virttest.utils_env.Env`
    """
    error_context.context("network configuration")
    vmnet = env.get_vmnet()
    vmnet.start_all_sessions()
    vms = vmnet.get_vms()
    server_vm = vms.server
    client_vm = vms.client
    vmnet.ping_all()

    # call to a function shared among tests
    sleep(3)

    error_context.context("misc commands on each vm")
    tmp_server = server_vm.session.cmd("ls " + server_vm.params["tmp_dir"])
    tmp_client = client_vm.session.cmd("dir " + client_vm.params["tmp_dir"])
    logging.info("Content of temporary server folder:\n%s", tmp_server)
    logging.info("Content of temporary client folder:\n%s", tmp_client)
    deployed_folders = ("data", "utils", "packages")
    for folder in deployed_folders:
        if folder not in tmp_server:
            raise exceptions.TestFail(
                "No deployed %s was found on the server" % folder)
        if folder not in tmp_client:
            raise exceptions.TestFail(
                "No deployed %s was found on the client" % folder)

    error_context.context("enhanced remote checks")
    if params.get_boolean("enhanced_remote_checks"):
        # Another way to run remote commands is through the host -> guest door,
        # which provides us with different functions to share code between
        # the host machine and a guest virtual machine (vm).
        if not DOOR_AVAILABLE:
            raise exceptions.TestSkipError(
                "The remote door of an upgraded aexpect package is not available"
            )
        door.DUMP_CONTROL_DIR = test.logdir
        door.REMOTE_PYTHON_BINARY = "python3.4"

        # The most advanced remote methods require serialization backend.
        serialization_cmd = door.REMOTE_PYTHON_BINARY + " -c 'import Pyro4'"
        host_serialization = server_vm.session.cmd_status(
            serialization_cmd) == 0
        try:
            import Pyro4
        except ImportError:
            guest_serialization = False
        else:
            guest_serialization = True

        # The simplest remote execution we can perform is through a single call to
        # a utility or module. Under the hood, this is similar to running a
        # python script on the vm with just a few lines importing the module or
        # utility and calling its desired function.
        if params.get_boolean("remote_util_check"):
            door.run_remote_util(
                server_vm.session,
                "os",
                "listdir",
                server_vm.params["tmp_dir"].replace("\\", r"\\"),
            )
            # Note that the usage of `shell=True` is here because `run_remote_util`
            # doesn't support array serialization. However, `shell=True` should be
            # avoided in real test scripts.
            door.run_remote_util(
                server_vm.session,
                "subprocess",
                "call",
                "dir " + client_vm.params["tmp_dir"].replace("\\", r"\\"),
                shell=True)

        # A bit more flexible way to run code on the vm is using a decorated
        # function with multiple locally written but remotely executed lines.
        if params.get_boolean("remote_decorator_check"):
            check_walk(server_vm.session, params)

        # One advanced but last resort method is to use a control file which is
        # a file where the remote code is written and deployed to the vm. This
        # is also used internally for both previous methods.
        if params.get_boolean("remote_control_check"):
            # With a bit of metaprogramming, we can set single parameters, lists, or
            # dicts for one time use by th control file.
            control_path = server_vm.params["control_file"]
            control_path = door.set_subcontrol_parameter(
                control_path, "EXTRA_SLEEP", 2)
            control_path = door.set_subcontrol_parameter(
                control_path, "ROOT_DIR", params["root_dir"])
            control_path = door.set_subcontrol_parameter_list(
                control_path, "DETECT_DIRS", ["data", "utils"])
            control_path = door.set_subcontrol_parameter_dict(
                control_path, "SIMPLE_PARAMS", {
                    "client": server_vm.params["client"],
                    "server": server_vm.params["server"]
                })
            door.run_subcontrol(server_vm.session, control_path)
            # It becomes more intricate but possible to share the Cartesian
            # configuration between the host test and the control file and thus
            # allowing for return arguments from the control but we need a remote
            # object backend as additional satisfied dependency.
            if host_serialization and guest_serialization:
                logging.info(
                    "Performing extra hostname check using shared parameters control"
                )
                control_path = server_vm.params["control_file"].replace(
                    "step_3", "step_3.2")
                control_path = door.set_subcontrol_parameter_object(
                    control_path, server_vm.params)
                door.run_subcontrol(server_vm.session, control_path)
                failed_checks = server_vm.params["failed_checks"]
                if failed_checks > 0:
                    raise exceptions.TestFail("%s hostname checks failed" %
                                              failed_checks)

        # The highest complexity but most permanent approach (supports multiple
        # calls switching back and forth from guest to host) is using a remote
        # object and serializing the calls in the background. This is the most
        # flexible approach and a bit less complex than using controls but might
        # require an additional dependency as a backend implementation for the
        # remote objects (we usually use pyro and pickle or serpent serializers).
        if params.get_boolean("remote_object_check"):
            if not guest_serialization or not host_serialization:
                raise exceptions.TestSkipError(
                    "The remote door object backend (pyro) is not available")
            sysmisc = door.get_remote_object(
                "sample_utility",
                session=server_vm.wait_for_login(),
                host=server_vm.params["ip_" + server_vm.params["ro_nic"]],
                port=server_vm.params["ro_port"])
            sysmisc.sleep(5)

    logging.info(
        "It would appear that the test terminated in a civilized manner.")