1)  attach-interface without vm name
    2)  detach-interface without vm name
    3)  attach-interface with vm id
    4)  detach-interface with vm id
    5)  attach-interface with hex vm id
    6)  detach-interface with hex vm id
    7)  attach-interface with invalid vm id
    8)  detach-interface with invalid vm id
    9)  attach-interface with correct vm name
    10) detach-interface with correct vm name
    11) attach-interface with vm name beginning with number
    12) detach-interface with vm name beginning with number
    13) attach-interface with vm name beginning with #
    14) detach-interface with vm name beginning with #
    15) attach-interface with vm name beginning with -
    16) detach-interface with vm name beginning with -
    17) attach-interface with vm suppend
    18) detach-interface with vm suppend
    19) attach-interface with libvirtd stop
    20) detach-interface with libvirtd stop
    21) attach-interface with vm uuid
    22) detach-interface with vm uuid
    23) attach-interface with invalid vm uuid
    24) detach-interface with invalid vm uuid
    25) attach-interface with vm shutdown
    26) detach-interface with vm shutdown
    27) attach-interface with invalid --type option
    28) detach-interface with invalid --type option
    29) attach-interface with invalid option xyz with mac address
    30) detach-interface with invalid option xyz with mac address
    31) attach-interface with invalid option --xyz with mac address
    32) detach-interface with invalid option --xyz with mac address
    33) detach-interface with invalid option xyz without mac address
    34) attach-interface with invalid source option
    35) attach-interface with vnet0(which already exists) --target option
    36) attach-interface with invalid mac address
    37) detach-interface with invalid mac address
    38) attach-interface twice with the same mac address
    39) detach-interface twice with the same mac address
    40) attach-interface with invalid --script option
    41) attach-interface 10 times
    42) attach-interface on remote host
    43) detach-interface on remote host
    44) attach-interface with --persistent option when vm is running
    45) detach-interface with --persistent option when vm is running
    46) attach-interface with --persistent option when vm is shut off
    47) detach-interface with --persistent option when vm is shut off

Signed-off-by: Tang Chen <tanc...@cn.fujitsu.com>
---
 .../libvirt/tests/virsh_attach_detach_interface.py |  493 ++++++++++++++++++++
 1 file changed, 493 insertions(+)
 create mode 100644 client/tests/libvirt/tests/virsh_attach_detach_interface.py

diff --git a/client/tests/libvirt/tests/virsh_attach_detach_interface.py 
b/client/tests/libvirt/tests/virsh_attach_detach_interface.py
new file mode 100644
index 0000000..2926fa4
--- /dev/null
+++ b/client/tests/libvirt/tests/virsh_attach_detach_interface.py
@@ -0,0 +1,493 @@
+import re, os, logging, shutil, codecs, time
+from autotest.client.shared import utils, error
+from autotest.client.virt import libvirt_vm, virt_remote
+from xml.dom import minidom
+from xml.dom.minidom import parse, parseString
+
+
+def build_attach_options(type, source, target, mac, extra):
+    """
+    Return the attach-interface commandline options.
+    """
+    options = ""
+    if type:
+        options += " --type %s" % type
+    if source:
+        options += " --source %s" % source
+    if target:
+        options += " --target %s" % target
+    if mac:
+        options += " --mac %s" % mac
+    if extra:
+        options += " %s" % extra
+    return options
+
+
+def build_detach_options(type, mac, extra):
+    """
+    Return the detach-interface commandline options.
+    """
+    options = ""
+    if type:
+        options += " --type %s" % type
+    if mac:
+        options += " --mac %s" % mac
+    if extra:
+        options += " %s" % extra
+    return options
+
+
+def check_vm_xml_interface(vm_xml, device = "interface", type = "bridge",
+                           source = "bridge", target = "vnet1", mac = ""):
+    """
+    Check VM's xml file for certain device.
+    """
+
+    logging.debug("xml:\n%s" % vm_xml)
+    dom = parseString(vm_xml)
+
+    devices = dom.getElementsByTagName("interface")
+    logging.debug("All devices: %s" % devices)
+
+    if type == "bridge":
+        attribute_source = "bridge"
+        attribute_target = "dev"
+        attribute_mac = "address"
+    else:
+        logging.error("Unknown device type: %s" % type)
+        return False
+
+    ret = False
+    for element in devices:
+        if element.getAttribute("type") == type:
+            nodelist = element.childNodes
+            for node in nodelist:
+                if node.nodeName == "source" and 
node.getAttribute(attribute_source) == source:
+                    for node in nodelist:
+                        if node.nodeName == "mac":
+                            mac_lower = mac.lower()
+                            mac_upper = mac.upper()
+                            mac_address = node.getAttribute(attribute_mac)
+                            if mac_address == mac_lower or mac_address == 
mac_upper:
+                                if target == "":
+                                    return True
+                                else:
+                                    for node in nodelist:
+                                        if node.nodeName == "target" and 
node.getAttribute(attribute_target) == target:
+                                            return True
+    dom.unlink
+    return False
+
+
+def check_native_bridge(source, targets):
+    cmd = "brctl show %s" % source
+    cmd_result = utils.run(cmd, ignore_status=True)
+    logging.info("Output: %s", cmd_result.stdout.strip())
+    logging.info("Error: %s", cmd_result.stderr.strip())
+    logging.info("Status: %d", cmd_result.exit_status)
+
+    if cmd_result.exit_status == 0:
+        i = 0
+        while (i < len(targets)):
+            if not re.search(targets[i], cmd_result.stdout.strip()):
+                logging.info("Tap %s not found on host." % targets[i])
+                return False
+            i = i + 1
+        return True
+    else:
+        return False
+
+
+def check_vm_nic(vm, os_type = "linux", mac = "", loop = 1):
+    logging.info("Checking VM nic...")
+    if vm.is_dead():
+        logging.debug("%s is not alive, starting it (30 sec)...")
+        vm.start()
+        vm.verify_alive()
+        time.sleep(30)
+    try:
+        if os_type == "linux":
+            session = vm.wait_for_login(nic_index=0)
+            s, o = session.cmd_status_output("ifconfig -a")
+            logging.info("ifconfig in VM:\n%s" % o)
+            i = 0
+            while (i < loop):
+                s, o = session.cmd_status_output("ifconfig -a | grep -i 
\"%s\"" % mac[i])
+                logging.info("Virtio devices in VM:\n%s" % o)
+                i = i + 1
+                if s != 0:
+                    return False
+            session.close()
+        else:
+            #Fix me.
+            pass
+        return True
+    except Exception, detail:
+        logging.error("%s: %s" % (detail.__class__, detail))
+        return False
+
+
+def run_virsh_attach_detach_interface(test, params, env):
+    """
+    Test virsh {at|de}tach-interface command.
+    """
+
+    # Get test command.
+    test_cmd = params.get("test_cmd", "attach-interface")
+    if test_cmd != "attach-interface" and test_cmd != "detach-interface":
+        raise error.TestError("Command %s is not support "
+                              "in this test." % test_cmd)
+
+    # Basic parameters.
+    vm_ref = params.get("vm_ref", "name")
+    at_options = params.get("at_options", "")
+    dt_options = params.get("dt_options", "")
+    back_uri = params.get("back_uri", "")
+    pre_vm_state = params.get("pre_vm_state", "running")
+    libvirtd_state = params.get("libvirtd_state", "on")
+    status_error = params.get("status_error", 'no')
+    no_attach = params.get("no_attach", 'no')
+    os_type = params.get("os_type", "linux")
+    dly = int(params.get("delay", 10))
+
+    # Interface specific attributes.
+    device = params.get("device", "interface")
+    device_type = params.get("device_type", "bridge")
+    device_source = params.get("device_source", "virbr0")
+    device_targets = params.get("device_targets", "vnet1").split(" ")
+    bus_type = params.get("bus_type", "virtio")
+    auto_nic_mac = params.get("auto_nic_mac", 'yes')
+    auto_target = params.get("auto_target", 'no')
+    test_times = int(params.get("test_times", "1"))
+
+    mac_need_free = False
+
+    try:
+        exception = False
+
+        main_vm_name = params.get("main_vm")
+        new_vm_name = main_vm_name
+        vm = env.get_vm(params["main_vm"])
+
+        # Back up xml file.
+        vm_xml_file_bak = vm.backup_xml()
+        vm_xml_file = "/etc/libvirt/qemu/%s.xml" % vm.name
+
+        vm.start()
+        vm.verify_alive()
+        time.sleep(dly)
+        vm_id = vm.get_id()
+        vm_uuid = vm.get_uuid()
+
+        # Confirm how to reference a VM.
+        # For example: no name, wrong id or uuid, and so on.
+        if vm_ref == "name":
+            vm_ref = main_vm_name
+        elif vm_ref == "new_name":
+            vm_ref = params.get("new_vm_name")
+            # vm should be shutdown when we try to rename it.
+            vm.destroy()
+            vm.rename(vm_ref)
+            new_vm_name = vm.name
+            vm.start()
+            vm.verify_alive()
+            time.sleep(dly)
+            # And we should get id again, because vm has been
+            # shut down and started again.
+            vm_id = vm.get_id()
+        elif vm_ref == "id":
+            vm_ref = vm_id
+        elif vm_ref == "hex_id":
+            vm_ref = hex(int(vm_id))
+        elif vm_ref == "invalid_id":
+            vm_ref = params.get("invalid_vm_id")
+        elif vm_ref == "invalid_vm_name":
+            vm_ref = params.get("invalid_vm_name")
+        elif vm_ref == "uuid":
+            vm_ref = vm_uuid
+        elif vm_ref == "invalid_vm_uuid":
+            vm_ref = params.get("invalid_vm_uuid")
+        else:
+            vm_ref = ""
+
+        # Get nic number in VM, and the index should start from 
original_nic_num.
+        original_nic_num = len(params.objects("nics"))
+        i = 0
+        check_in_vm = False
+        nic_macs = []
+        if auto_nic_mac == "yes":
+            mac_need_free = True
+            while (i < test_times):
+                nic_dict = {'nic_model': 'virtio', 'nettype': 'bridge', 
'netdst': 'virbr0'}
+                nic_dict = vm.add_nic(**dict(nic_dict))
+                nic_macs.append(nic_dict.mac)
+                logging.debug("Generated mac address in loop %d: %s" % (i, 
nic_macs[i]))
+                i = i + 1
+            check_in_vm = True
+            time.sleep(dly)
+        elif params.has_key("nic_macs"):
+            nic_macs = params.get("nic_macs").split(" ")
+            check_in_vm = True
+        else:
+            while (i < test_times):
+                nic_macs.append("")
+                i = i + 1
+
+        # Automatically generate target names.
+        if auto_target == "yes":
+            device_targets = []
+            i = 0
+            while (i < test_times):
+                target = "vnet%d" % (i + original_nic_num)
+                device_targets.append(target)
+                i = i + 1
+
+        # If we are testing detach-interface, we need to attach certain device 
first.
+        if test_cmd == "detach-interface" and no_attach != "yes":
+            if bus_type == "ide" and vm.is_alive():
+                vm.destroy(gracefully=True)
+            i = 0
+            while (i < test_times):
+                tmp_option = build_attach_options(device_type,
+                                                  device_source,
+                                                  device_targets[i],
+                                                  nic_macs[i],
+                                                  "--persistent")
+                s_attach = vm.attach_interface(tmp_option, True, 
True).exit_status
+                i = i + 1
+                if s_attach != 0:
+                    logging.error("Attaching device failed "
+                                  "before testing detach-disk.")
+            time.sleep(dly)
+
+        # Turn VM into certain state.
+        if pre_vm_state == "paused":
+            logging.info("Suspending %s..." % vm.name)
+            if vm.is_alive():
+                vm.pause()
+        elif pre_vm_state == "shut off":
+            logging.info("Shuting down %s..." % vm.name)
+            if vm.is_alive():
+                vm.destroy(gracefully=True)
+
+        time.sleep(dly)
+        # Get xml file before test.
+        vm_xml_before_cmd = vm.get_xml()
+
+        # Turn libvirtd into certain state.
+        if libvirtd_state == "off":
+            libvirt_vm.libvirtd_stop()
+
+        # Test.
+        vm.name = vm_ref        # For error name testing.
+        if back_uri == "":
+            if params.has_key("invalid_nic_mac"):
+                invalid_nic_mac = params.get("invalid_nic_mac")
+                if test_cmd == "attach-interface":
+                    tmp_option = build_attach_options(device_type,
+                                                      device_source,
+                                                      device_targets[0],
+                                                      invalid_nic_mac,
+                                                      at_options)
+                    status = vm.attach_interface(tmp_option, True, 
True).exit_status
+                else:
+                    tmp_option = build_detach_options(device_type,
+                                                      invalid_nic_mac,
+                                                      dt_options)
+                    status = vm.detach_interface(tmp_option, True, 
True).exit_status
+
+            else:
+                i = 0
+                while (i < test_times):
+                    if test_cmd == "attach-interface":
+                        tmp_option = build_attach_options(device_type,
+                                                          device_source,
+                                                          device_targets[i],
+                                                          nic_macs[i],
+                                                          at_options)
+                        status = vm.attach_interface(tmp_option, True, 
True).exit_status
+                        logging.info("TOM: %d" % status)
+                    else:
+                        tmp_option = build_detach_options(device_type,
+                                                          nic_macs[i],
+                                                          dt_options)
+                        status = vm.detach_interface(tmp_option, True, 
True).exit_status
+
+                    i = i+1
+                    time.sleep(dly)
+        else:
+            remote_ip = params.get("remote_ip")
+            remote_user = params.get("remote_user", "root")
+            remote_pwd = params.get("remote_pwd", "rootxen")
+            remote_prompt = params.get("remote_prompt", "#")
+            session = virt_remote.remote_login("ssh", remote_ip,
+                                              "22", remote_user,
+                                              remote_pwd,
+                                              remote_prompt)
+
+            if test_cmd == "attach-interface":
+                tmp_option = build_attach_options(device_type,
+                                                  device_source,
+                                                  device_targets[0],
+                                                  nic_macs[0],
+                                                  at_options)
+            else:
+                tmp_option = build_detach_options(device_type,
+                                                  nic_macs[0],
+                                                  dt_options)
+            cmd_interface = "virsh -c %s %s --domain %s %s" \
+                            % (back_uri, test_cmd, vm_ref, tmp_option)
+            logging.info("TOM: %s" % cmd_interface)
+            status, output = session.cmd_status_output(cmd = cmd_interface, 
internal_timeout = 30)
+            logging.info("Output: %s" % output)
+
+        # Recover vm.name in VM object.
+        if vm_ref != main_vm_name:
+            vm.name = new_vm_name
+
+        time.sleep(dly)
+
+        # Recover libvirtd state.
+        if libvirtd_state == "off":
+            libvirt_vm.libvirtd_start()
+
+        time.sleep(dly)
+        # Get xml file after test.
+        vm_xml_after_cmd = vm.get_xml()
+
+        # Recover VM state.
+        if pre_vm_state == "paused":
+            vm.resume()
+        elif pre_vm_state == "shut off":
+            vm.start()
+
+        # Check on native for tap device.
+        check_native_after_cmd = True
+        check_native_after_cmd = check_native_bridge(device_source, 
device_targets)
+
+        # Check in VM after command.
+        check_vm_after_cmd = True
+        if os_type == 'linux':
+            if check_in_vm:
+                check_vm_after_cmd = check_vm_nic(vm, os_type, nic_macs, 
test_times)
+        else:
+            if test_cmd == 'attach-interface':
+                check_vm_after_cmd = True
+            else:
+                check_vm_after_cmd = False
+
+        # Destroy VM.
+        vm.destroy(gracefully=True)
+
+        time.sleep(dly)
+        # Get xml file after VM is shut down.
+        vm_xml_after_shutdown = vm.get_xml()
+
+        # Check xml file after command.
+        check_xml_after_cmd = True
+        i = 0
+        if pre_vm_state != "shut off":
+            while (i < test_times):
+                tmp = check_vm_xml_interface(vm_xml_after_cmd, device,
+                                             device_type, device_source,
+                                             device_targets[i], nic_macs[i])
+                if not tmp:
+                    check_xml_after_cmd = False
+                    break
+                i = i + 1
+        else:
+            while (i < test_times):
+                tmp = check_vm_xml_interface(vm_xml_after_cmd, device,
+                                             device_type, device_source,
+                                             "", nic_macs[i])
+                if not tmp:
+                    check_xml_after_cmd = False
+                    break
+                i = i + 1
+
+        # Check xml file after VM is shut down (with --persistent).
+        check_xml_after_shutdown = True
+        i = 0
+        while (i < test_times):
+            # We should not check target after VM is shut down.
+            tmp = check_vm_xml_interface(vm_xml_after_shutdown, device,
+                                         device_type, device_source,
+                                         "", nic_macs[i])
+            if not tmp:
+                check_xml_after_shutdown = False
+                break
+            i = i + 1
+
+    except Exception, detail:
+        # Whatever error occurs, we have to clean up all environment.
+        exception = True
+        logging.error("%s: %s" % (detail.__class__, detail))
+
+    # Free all generated mac addresses.
+    if mac_need_free:
+        i = 0
+        while (i < test_times):
+            # Since the lenth of vm.virtnet will be decreased each time
+            # we delete a nic in it, we don't need to increase del_nic's
+            # parameter, otherwise it will lead to list out of range error.
+            vm.del_nic(original_nic_num)
+            i = i + 1
+
+    # Clean up.
+    # Redefine the main_vm.
+    vm.destroy(gracefully=True)
+    vm.undefine()
+    if os.path.exists(vm_xml_file):
+        logging.error("Undefine %s failed." % vm.name)
+    vm.define(vm_xml_file_bak)
+    if not os.path.exists(vm_xml_file):
+        logging.error("Define %s failed." % vm.name)
+
+    # Remove
+    if os.path.exists(vm_xml_file_bak):
+        os.remove(vm_xml_file_bak)
+
+    if exception:
+        raise error.TestError("Error occurred.")
+
+    # Check results.
+    if status_error == 'yes':
+        if status == 0:
+            raise error.TestFail("virsh %s exit with unexpected "
+                                 "value." % test_cmd)
+    else:
+        if status != 0:
+            raise error.TestFail("virsh %s failed." % test_cmd)
+        if test_cmd == "attach-interface":
+            if not check_xml_after_cmd:
+                raise error.TestFail("Cannot see deivce in "
+                                     "xml file after attach.")
+            if not check_native_after_cmd:
+                raise error.TestFail("Cannot see tap device "
+                                     "in native after attach.")
+            if not check_vm_after_cmd:
+                raise error.TestFail("Cannot see deivce in "
+                                     "VM after attach.")
+            if at_options.count("persistent"):
+                if not check_xml_after_shutdown:
+                    raise error.TestFail("Cannot see persistent attached "
+                                         "deivce in xml file after VM 
shutdown.")
+            else:
+                if check_xml_after_shutdown:
+                    raise error.TestFail("See non-persistent attached "
+                                         "deivce in xml file after VM 
shutdown.")
+        elif test_cmd == "detach-interface":
+            if check_xml_after_cmd:
+                raise error.TestFail("See deivce in xml file after detach.")
+            if check_vm_after_cmd:
+                raise error.TestFail("See deivce in VM after detach.")
+            if dt_options.count("persistent"):
+                if check_xml_after_shutdown:
+                    raise error.TestFail("See persistent detached device "
+                                         "in xml file after VM shutdown.")
+            else:
+                if not check_xml_after_shutdown:
+                    raise error.TestFail("Cannot see non-persistent detached "
+                                         "device in xml file after VM 
shutdown.")
+        else:
+            raise error.TestError("Unknown command %s." % test_cmd)
-- 
1.7.10.2

_______________________________________________
Autotest mailing list
Autotest@test.kernel.org
http://test.kernel.org/cgi-bin/mailman/listinfo/autotest

Reply via email to