Signed-off-by: Tang Chen <[email protected]>
---
client/tests/libvirt/tests/virsh_migrate.py | 267 ++++++++++++++++++++++-----
1 files changed, 223 insertions(+), 44 deletions(-)
diff --git a/client/tests/libvirt/tests/virsh_migrate.py
b/client/tests/libvirt/tests/virsh_migrate.py
index b342987..16fd298 100644
--- a/client/tests/libvirt/tests/virsh_migrate.py
+++ b/client/tests/libvirt/tests/virsh_migrate.py
@@ -1,5 +1,6 @@
-import logging, time
-from autotest.client.shared import error
+import logging, os, re, time, shutil, codecs
+from autotest.client.shared import utils, error
+from autotest.client.virt import libvirt_vm, virt_utils, virt_test_utils
def run_virsh_migrate(test, params, env):
"""
@@ -16,51 +17,69 @@ def run_virsh_migrate(test, params, env):
else:
return False
- def cleanup_dest(vm, src_uri = ""):
+ def cleanup_dest(vm, src_uri=""):
"""
Clean up the destination host environment
when doing the uni-direction migration.
"""
- vm_state = vm.state()
- if vm_state == "running":
- vm.destroy()
- elif vm_state == "paused":
- vm.resume()
- vm.destroy()
+ logging.info("Cleaning up VMs on %s" % vm.connect_uri)
+ try:
+ if libvirt_vm.virsh_domain_exists(vm.name, vm.connect_uri):
+ vm_state = vm.state()
+ if vm_state == "paused":
+ vm.resume()
+ elif vm_state == "shut off":
+ vm.start()
+ vm.destroy()
+
+ if vm.is_persistent():
+ vm.undefine()
- if vm.is_persistent():
- vm.undefine()
+ except Exception, detail:
+ logging.error("Cleaning up destination failed.\n%s" % detail)
- vm.connect_uri = src_uri
+ if src_uri:
+ vm.connect_uri = src_uri
- def do_migration(dly, vm, dest_uri, options, extra):
- logging.info("Sleeping %d seconds before migration" % dly)
- time.sleep(dly)
+ def do_migration(delay, vm, dest_uri, options, extra):
+ logging.info("Sleeping %d seconds before migration" % delay)
+ time.sleep(delay)
# Migrate the guest.
- successful = vm.migrate(dest_uri, options, extra)
- if not successful:
- raise error.TestFail("Migration failed for %s." % vm_name)
+ successful = vm.migrate(dest_uri, options, extra, True,
True).exit_status
+ logging.info("successful: %d", successful)
+ if int(successful) != 0:
+ logging.error("Migration failed for %s." % vm_name)
+ return False
+
+ if options.count("dname") or extra.count("dname"):
+ vm.name = extra.split()[1].strip()
if vm.is_alive(): # vm.connect_uri was updated
logging.info("Alive guest found on destination %s." % dest_uri)
else:
- raise error.TestFail("VM not running on destination %s" % dest_uri)
-
- # Migration may fail, but VM is alive on destination.
- dest_state = params.get("virsh_migrate_dest_state")
- ret = check_vm_state(vm, dest_state)
- logging.info("Supposed state: %s" % dest_state)
- logging.info("Actual state: %s" % vm.state())
- if not ret:
- raise error.TestFail("VM is not in the supposed state.")
+ logging.error("VM not alive on destination %s" % dest_uri)
+ return False
# FIXME: This needs to be tested, but won't work currently
# vm.verify_kernel_crash()
+ logging.debug("vm.verify_kernel_crash() needs to be tested, "
+ "but won't work currently.")
+ return True
+
vm_name = params.get("main_vm")
vm = env.get_vm(params["main_vm"])
vm.verify_alive()
+ # For safety reasons, we'd better back up xmlfile.
+ vm_xmlfile_bak = vm.backup_xml()
+ if not vm_xmlfile_bak:
+ logging.error("Backing up xmlfile failed.")
+
+ vm.connect_uri = params.get("connect_uri", "default")
+ if vm.connect_uri == 'default':
+ vm.connect_uri = libvirt_vm.virsh_uri()
+
src_uri = vm.connect_uri
dest_uri = params.get("virsh_migrate_desturi")
# Identify easy config. mistakes early
@@ -75,24 +94,184 @@ def run_virsh_migrate(test, params, env):
if dest_uri.count('///') or dest_uri.count('EXAMPLE'):
logging.warning(warning_text % ('destination', dest_uri))
+ vm_ref = params.get("vm_ref", vm.name)
options = params.get("virsh_migrate_options")
extra = params.get("virsh_migrate_extra")
- dly = int(params.get("virsh_migrate_delay", 10))
-
-
- do_migration(dly, vm, dest_uri, options, extra)
- # Repeat the migration with a recursive call and guaranteed exit
- if params.get("virsh_migrate_back", "no") == 'yes':
- back_dest_uri = params.get("virsh_migrate_back_desturi", 'default')
- back_options = params.get("virsh_migrate_back_options", 'default')
- back_extra = params.get("virsh_migrate_back_extra", 'default')
- if back_dest_uri == 'default':
- back_dest_uri = src_uri
- if back_options == 'default':
- back_options = options
- if back_extra == 'default':
- back_extra = extra
- do_migration(dly, vm, back_dest_uri, back_options, back_extra)
- # Do the uni-direction migration here.
+ delay = int(params.get("virsh_migrate_delay", 10))
+ status_error = params.get("status_error", 'no')
+ libvirtd_state = params.get("virsh_migrate_libvirtd_state", 'on')
+ src_state = params.get("virsh_migrate_src_state", "running")
+ new_nic_mac = "ff:ff:ff:ff:ff:ff"
+ dest_xmlfile = ""
+
+ exception = False
+ try:
+ # Confirm VM can be accessed through network.
+ time.sleep(delay)
+ vm_ip = vm.get_address()
+ s_ping, o_ping = virt_test_utils.ping(vm_ip, count=2, timeout=delay)
+ logging.info(o_ping)
+ if s_ping != 0:
+ raise error.TestError("%s did not respond after %d sec." %
(vm.name, delay))
+
+ # Prepare for --xml.
+ logging.debug("Preparing new xml file for --xml option.")
+ if options.count("xml") or extra.count("xml"):
+ dest_xmlfile = params.get("virsh_migrate_xml", "")
+ if dest_xmlfile:
+ ret_attach = vm.attach_interface("--type bridge --source
virbr0 --mac %s" % new_nic_mac, True, True)
+ if not ret_attach:
+ exception = True
+ raise error.TestError("Attaching nic to %s failed." %
vm.name)
+ vm_xml_new = vm.get_xml()
+ logging.debug("Xml file on source: %s" % vm_xml_new)
+ f = codecs.open(dest_xmlfile, 'wb', encoding='utf-8')
+ f.write(vm_xml_new)
+ f.close()
+ if not os.path.exists(dest_xmlfile):
+ exception = True
+ raise error.TestError("Creating %s failed." % dest_xmlfile)
+
+ # Turn VM into certain state.
+ logging.debug("Turning %s into certain state." % vm.name)
+ if src_state == "paused":
+ if vm.is_alive():
+ vm.pause()
+ elif src_state == "shut off":
+ if vm.is_alive():
+ if not vm.shutdown():
+ vm.destroy()
+
+ # Turn libvirtd into certain state.
+ logging.debug("Turning libvirtd into certain status.")
+ if libvirtd_state == "off":
+ libvirt_vm.libvirtd_stop()
+
+ # Test uni-direction migration.
+ logging.debug("Doing migration test.")
+ if vm_ref != vm_name:
+ vm.name = vm_ref # For vm name error testing.
+ ret_migrate = do_migration(delay, vm, dest_uri, options, extra)
+ if vm_ref != vm_name:
+ vm.name = vm_name
+
+ # Recover libvirtd state.
+ logging.debug("Recovering libvirtd status.")
+ if libvirtd_state == "off":
+ libvirt_vm.libvirtd_start()
+
+ # Check vm state on destination.
+ logging.debug("Checking %s state on %s." % (vm.name, vm.connect_uri))
+ if options.count("dname") or extra.count("dname"):
+ vm.name = extra.split()[1].strip()
+ check_dest_state = True
+ dest_state = params.get("virsh_migrate_dest_state", "running")
+ check_dest_state = check_vm_state(vm, dest_state)
+ logging.info("Supposed state: %s" % dest_state)
+ logging.info("Actual state: %s" % vm.state())
+
+ # Recover VM state.
+ logging.debug("Recovering %s state." % vm.name)
+ if src_state == "paused":
+ vm.resume()
+ elif src_state == "shut off":
+ vm.start()
+
+ # Checking for --persistent.
+ logging.debug("Checking for --persistent option.")
+ check_dest_persistent = True
+ if options.count("persistent") or extra.count("persistent"):
+ if not vm.is_persistent():
+ check_dest_persistent = False
+
+ # Checking for --undefinesource.
+ logging.debug("Checking for --undefinesource option.")
+ check_src_undefine = True
+ if options.count("undefinesource") or extra.count("undefinesource"):
+ logging.info("Verifying <virsh domstate> DOES return an error."
+ "%s should not exist on %s." % (vm_name, src_uri))
+ if libvirt_vm.virsh_domain_exists(vm_name, src_uri):
+ check_src_undefine = False
+
+ # Checking for --dname.
+ logging.debug("Checking for --dname option.")
+ check_dest_dname = True
+ if options.count("dname") or extra.count("dname"):
+ dname = extra.split()[1].strip()
+ if not libvirt_vm.virsh_domain_exists(dname, dest_uri):
+ check_dest_dname = False
+
+ # Checking for --xml.
+ logging.debug("Checking for --xml option.")
+ check_dest_xml = True
+ if options.count("xml") or extra.count("xml"):
+ if dest_xmlfile:
+ vm_dest_xml = vm.get_xml()
+ logging.info("Xml file on destination: %s" % vm_dest_xml)
+ if not re.search(new_nic_mac, vm_dest_xml):
+ check_dest_xml = False
+
+ # Repeat the migration from destination to source.
+ if params.get("virsh_migrate_back", "no") == 'yes':
+ back_dest_uri = params.get("virsh_migrate_back_desturi", 'default')
+ back_options = params.get("virsh_migrate_back_options", 'default')
+ back_extra = params.get("virsh_migrate_back_extra", 'default')
+ if back_dest_uri == 'default':
+ back_dest_uri = src_uri
+ if back_options == 'default':
+ back_options = options
+ if back_extra == 'default':
+ back_extra = extra
+ ret_migrate = do_migration(delay, vm, back_dest_uri, back_options,
back_extra)
+
+ except Exception, detail:
+ exception = True
+ logging.error("%s: %s" % (detail.__class__, detail))
+
+
+ # Whatever error occurs, we have to clean up all environment.
+ # Make sure vm.connect_uri is the destination uri.
+ vm.connect_uri = dest_uri
+ if options.count("dname") or extra.count("dname"):
+ # Use the VM object to remove
+ vm.name = extra.split()[1].strip()
+ cleanup_dest(vm, src_uri)
+ vm.name = vm_name
else:
cleanup_dest(vm, src_uri)
+
+ # Recover source (just in case).
+ # vm.connect_uri has been set back to src_uri in cleanup_dest().
+ if not libvirt_vm.virsh_domain_exists(vm_name, src_uri):
+ vm.define(vm_xmlfile_bak)
+ else:
+ #if not vm.shutdown():
+ vm.destroy()
+
+ # Cleanup source.
+ if os.path.exists(vm_xmlfile_bak):
+ os.remove(vm_xmlfile_bak)
+ logging.info("%s removed." % vm_xmlfile_bak)
+ if os.path.exists(dest_xmlfile):
+ os.remove(dest_xmlfile)
+
+ if exception:
+ raise error.TestError("Error occurred. \n%s: %s" % (detail.__class__,
detail))
+
+ # Check test result.
+ if status_error == 'yes':
+ if ret_migrate:
+ raise error.TestFail("Migration finished with unexpected status.")
+ else:
+ if not ret_migrate:
+ raise error.TestFail("Migration finished with unexpected status.")
+ if not check_dest_state:
+ raise error.TestFail("Wrong VM state on destination.")
+ if not check_dest_persistent:
+ raise error.TestFail("VM is not persistent on destination.")
+ if not check_src_undefine:
+ raise error.TestFail("VM is not undefined on source.")
+ if not check_dest_dname:
+ raise error.TestFail("Wrong VM name %s on destination." % dname)
+ if not check_dest_xml:
+ raise error.TestFail("Wrong xml configuration on destination.")
--
1.7.3.1
_______________________________________________
Autotest mailing list
[email protected]
http://test.kernel.org/cgi-bin/mailman/listinfo/autotest