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)
--
1.7.10.2
_______________________________________________
Autotest mailing list
[email protected]
http://test.kernel.org/cgi-bin/mailman/listinfo/autotest