[Autotest][PATCH V2] KVM Test: Extend migration test to test unix, exec and migrate_cancel

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Update migrate() in kvm_test_utils.py to support unix, exec protocol and
migration cancel test.
Add four migration sub test. There are tcp, unix, exec and mig_cancel.
migrate_cancel only work in tcp protocol.
For exec protocol, we need first save VM status to a file, then load the status
file to dest VM.

Note:
for_migration parameter in create() in kvm_vm.py is useless now.
Corresponding code have been deleted from create(). Keep this parameter in 
order to keep interface stability. It may be delete later. Please use
extra_params for migration.

Signed-off-by: Feng Yang <fyang@xxxxxxxxxx>
---
 client/tests/kvm/kvm_test_utils.py     |   92 +++++++++++++++++++++++++------
 client/tests/kvm/kvm_vm.py             |   21 +++++---
 client/tests/kvm/tests/migration.py    |    7 ++-
 client/tests/kvm/tests_base.cfg.sample |   11 ++++
 4 files changed, 105 insertions(+), 26 deletions(-)

diff --git a/client/tests/kvm/kvm_test_utils.py b/client/tests/kvm/kvm_test_utils.py
index 24e2bf5..3ef76a1 100644
--- a/client/tests/kvm/kvm_test_utils.py
+++ b/client/tests/kvm/kvm_test_utils.py
@@ -108,13 +108,17 @@ def reboot(vm, session, method="shell", sleep_before_reset=10, nic_index=0,
     return session
 
 
-def migrate(vm, env=None):
+def migrate(vm, env=None, mig_timeout=3600, mig_protocol="tcp",
+            mig_cancel=False):
     """
     Migrate a VM locally and re-register it in the environment.
 
     @param vm: The VM to migrate.
     @param env: The environment dictionary.  If omitted, the migrated VM will
             not be registered.
+    @param mig_timeout: timeout value for migration.
+    @param mig_protocol: migration protocol
+    @param mig_cancel: Test migrate_cancel or not when protocol is tcp.
     @return: The post-migration VM.
     """
     # Helper functions
@@ -126,6 +130,10 @@ def migrate(vm, env=None):
         s, o = vm.send_monitor_cmd("info migrate")
         return s == 0 and "Migration status: completed" in o
 
+    def mig_canceled():
+        s, o = vm.send_monitor_cmd("info migrate")
+        return s == 0 and "Migration status: cancelled" in o
+
     def mig_failed():
         s, o = vm.send_monitor_cmd("info migrate")
         return s == 0 and "Migration status: failed" in o
@@ -135,28 +143,68 @@ def migrate(vm, env=None):
     if not "info migrate" in o:
         raise error.TestError("Migration is not supported")
 
+    if mig_protocol == "tcp":
+        mig_extra_params = " -incoming tcp:0:%d"
+    elif mig_protocol == "unix":
+        file = os.path.join("/tmp/", mig_protocol +
+                                     time.strftime("%Y%m%d-%H%M%S"))
+        mig_extra_params = " -incoming unix:%s"
+    elif mig_protocol == "exec":
+        file = os.path.join("/tmp/", mig_protocol +
+                                     time.strftime("%Y%m%d-%H%M%S"))
+        mig_extra_params = " -incoming \"exec: gzip -c -d %s\"" % file
+        mig_cmd = "migrate \"exec:gzip -c > %s\"" % file
+
+        vm.send_monitor_cmd("stop")
+        vm.send_monitor_cmd(mig_cmd, timeout=mig_timeout)
+        if not kvm_utils.wait_for(mig_finished, mig_timeout, 2, 2,
+                                  "Waiting for migration to finish..."):
+            raise error.TestFail("Timeout elapsed while waiting for migration "
+                                 "to finish")
+
     # Clone the source VM and ask the clone to wait for incoming migration
     dest_vm = vm.clone()
-    if not dest_vm.create(for_migration=True):
+    if not dest_vm.create(extra_params=mig_extra_params):
         raise error.TestError("Could not create dest VM")
 
+    if mig_protocol == "tcp":
+        mig_cmd = "migrate -d tcp:localhost:%d" % dest_vm.migration_port
+    elif mig_protocol == "unix":
+        mig_cmd = "migrate unix:%s" % dest_vm.migration_file
+
     try:
-        # Define the migration command
-        cmd = "migrate -d tcp:localhost:%d" % dest_vm.migration_port
-        logging.debug("Migrating with command: %s" % cmd)
-
-        # Migrate
-        s, o = vm.send_monitor_cmd(cmd)
-        if s:
-            logging.error("Migration command failed (command: %r, output: %r)"
-                          % (cmd, o))
-            raise error.TestFail("Migration command failed")
-
-        # Wait for migration to finish
-        if not kvm_utils.wait_for(mig_finished, 90, 2, 2,
-                                  "Waiting for migration to finish..."):
-            raise error.TestFail("Timeout elapsed while waiting for migration "
-                                 "to finish")
+        if mig_protocol != "exec":
+            logging.debug("Migrating with command: %s" % mig_cmd)
+
+            # Migrate
+            s, o = vm.send_monitor_cmd(mig_cmd, timeout=mig_timeout)
+            if s:
+                logging.error("Migration command failed (command: %r, output:"
+                              " %r)"  % (mig_cmd, o))
+                raise error.TestFail("Migration command failed")
+
+            if mig_protocol == "tcp" and mig_cancel:
+                # Sleep two seconds before send migrate_cancel command.
+                time.sleep(2)
+                s, o = vm.send_monitor_cmd("migrate_cancel")
+                if not kvm_utils.wait_for(mig_canceled, 60, 2, 2,
+                                          "Waiting for migration cancel"):
+                    raise error.TestFail("Fail to cancel migration")
+                s, o = dest_vm.send_monitor_cmd("info status")
+                if "paused" not in o:
+                    raise error.TestFail("Fail to cancel migration, dest VM"
+                                          "is not paused")
+                s, o = vm.send_monitor_cmd("info status")
+                if "running" not in o:
+                     raise error.TestFail("VM status is not running after"
+                                          " migration canceled")
+                return vm
+
+            # Wait for migration to finish
+            if not kvm_utils.wait_for(mig_finished, mig_timeout, 2, 2,
+                                      "Waiting for migration to finish..."):
+                raise error.TestFail("Timeout elapsed while waiting for "
+                                      "migration to finish")
 
         # Report migration status
         if mig_succeeded():
@@ -166,6 +214,14 @@ def migrate(vm, env=None):
         else:
             raise error.TestFail("Migration ended with unknown status")
 
+        if mig_protocol == "exec":
+            s, o = dest_vm.send_monitor_cmd("info status")
+            if "paused" in o:
+                logging.debug("Dest VM is in paused status")
+                dest_vm.send_monitor_cmd("c")
+            if os.path.exists(file):
+                 os.remove(file)
+
         # Kill the source VM
         vm.destroy(gracefully=False)
 
diff --git a/client/tests/kvm/kvm_vm.py b/client/tests/kvm/kvm_vm.py
index 3943207..8362b6b 100755
--- a/client/tests/kvm/kvm_vm.py
+++ b/client/tests/kvm/kvm_vm.py
@@ -392,7 +392,7 @@ class VM:
 
 
     def create(self, name=None, params=None, root_dir=None,
-               for_migration=False, timeout=5.0):
+               for_migration=False, timeout=5.0, extra_params=None):
         """
         Start the VM by running a qemu command.
         All parameters are optional. The following applies to all parameters
@@ -405,6 +405,8 @@ class VM:
         @param root_dir: Base directory for relative filenames
         @param for_migration: If True, start the VM with the -incoming
         option
+        @param extra_params: extra params for qemu command.e.g -incoming option
+        Please use this parameter instead of for_migration.
         """
         self.destroy()
 
@@ -523,12 +525,17 @@ class VM:
             # Make qemu command
             qemu_command = self.make_qemu_command()
 
-            # Is this VM supposed to accept incoming migrations?
-            if for_migration:
-                # Find available migration port
-                self.migration_port = kvm_utils.find_free_port(5200, 6000)
-                # Add -incoming option to the qemu command
-                qemu_command += " -incoming tcp:0:%d" % self.migration_port
+            # Enable migration support for VM by adding extra_params.
+            if extra_params is not None:
+                if " -incoming tcp:0:%d" == extra_params:
+                    self.migration_port = kvm_utils.find_free_port(5200, 6000)
+                    qemu_command += extra_params % self.migration_port
+                elif " -incoming unix:%s" == extra_params:
+                    self.migration_file = os.path.join("/tmp/", "unix-" +
+                                          time.strftime("%Y%m%d-%H%M%S"))
+                    qemu_command += extra_params % self.migration_file
+                else:
+                    qemu_command += extra_params
 
             logging.debug("Running qemu command:\n%s", qemu_command)
             self.process = kvm_subprocess.run_bg(qemu_command, None,
diff --git a/client/tests/kvm/tests/migration.py b/client/tests/kvm/tests/migration.py
index b8f171c..9cdafc9 100644
--- a/client/tests/kvm/tests/migration.py
+++ b/client/tests/kvm/tests/migration.py
@@ -22,6 +22,10 @@ def run_migration(test, params, env):
     vm = kvm_test_utils.get_living_vm(env, params.get("main_vm"))
     session = kvm_test_utils.wait_for_login(vm)
 
+    mig_timeout = float(params.get("mig_timeout", "3600"))
+    mig_protocol = params.get("migration_protocol", "tcp")
+    mig_cancel = bool(params.get("mig_cancel"))
+
     # Get the output of migration_test_command
     test_command = params.get("migration_test_command")
     reference_output = session.get_command_output(test_command)
@@ -43,7 +47,8 @@ def run_migration(test, params, env):
         session2.close()
 
         # Migrate the VM
-        dest_vm = kvm_test_utils.migrate(vm, env)
+        dest_vm = kvm_test_utils.migrate(vm, env,mig_timeout, mig_protocol,
+                                         mig_cancel)
 
         # Log into the guest again
         logging.info("Logging into guest after migration...")
diff --git a/client/tests/kvm/tests_base.cfg.sample b/client/tests/kvm/tests_base.cfg.sample
index afbed2f..ae9c0d8 100644
--- a/client/tests/kvm/tests_base.cfg.sample
+++ b/client/tests/kvm/tests_base.cfg.sample
@@ -106,6 +106,17 @@ variants:
         kill_vm_on_error = yes
         iterations = 2
         used_mem = 1024
+        mig_timeout = 3600
+        variants:
+            - tcp:
+                migration_protocol = "tcp"
+            - unix:
+                migration_protocol = "unix"
+            - exec:
+                migration_protocol = "exec"
+            - mig_cancel:
+                migration_protocol = "tcp"
+                mig_cancel = True
 
     - boot_savevm: install setup unattended_install
         type = boot_savevm
-- 
1.6.5.2

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux