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
