Signed-off-by: Tang Chen <tanc...@cn.fujitsu.com>
---
 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
Autotest@test.kernel.org
http://test.kernel.org/cgi-bin/mailman/listinfo/autotest

Reply via email to