Whew! this is very big test code. I'm spent from review just 
configuration!  I will take a look at this one tomorrow.  Just FYI.

On 07/11/2012 10:36 PM, tangchen wrote:
>      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<[email protected]>
> ---
>   .../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)

-- 
Chris Evich, RHCA, RHCE, RHCDS, RHCSS
Quality Assurance Engineer
e-mail: cevich + `@' + redhat.com o: 1-888-RED-HAT1 x44214
_______________________________________________
Autotest mailing list
[email protected]
http://test.kernel.org/cgi-bin/mailman/listinfo/autotest

Reply via email to