def __init__(self, test, params, env):
            super(TestMultihostMigration, self).__init__(test, params, env)
            self.srchost = self.params.get("hosts")[0]
            self.dsthost = self.params.get("hosts")[1]
            self.is_src = params["hostid"] == self.srchost
            self.vms = params["vms"].split()

            self.sub_type = self.params.get("sub_type", None)
            self.mig_downtime = int(self.params.get("mig_downtime", "3"))
            self.max_downtime = int(self.params.get("max_mig_downtime", "10"))
            self.wait_mig_timeout = int(
                self.params.get("wait_mig_timeout", "30"))
            self.min_speed = self.params.get("min_migration_speed", "10")
            self.max_speed = self.params.get("max_migration_speed", "1000")
            self.ch_speed = int(self.params.get("change_speed_interval", 1))
            speed_count = float(self.params.get("count_of_change", 5))

            self.min_speed = utils.convert_data_size(self.min_speed, "M")
            self.max_speed = utils.convert_data_size(self.max_speed, "M")
            self.speed_step = int(
                (self.max_speed - self.min_speed) / speed_count)

            if self.sub_type == "before_migrate":
                self.before_migration = self.before_migration_downtime
                self.post_migration = self.post_migration_before_downtime
            if self.sub_type == "after_migrate":
                self.post_migration = self.post_migration_downtime
            elif self.sub_type == "speed":
                self.post_migration = self.post_migration_speed
            elif self.sub_type == "stop_during":
                self.post_migration = self.post_migration_stop
            else:
                error.TestFail("Wrong subtest type selected %s" %
                               (self.sub_type))
        def __init__(self, test, params, env):
            super(TestMultihostMigration, self).__init__(test, params, env)
            self.install_path = params.get("cpuflags_install_path", "/tmp")
            self.vm_mem = int(params.get("mem", "512"))
            self.srchost = self.params.get("hosts")[0]
            self.dsthost = self.params.get("hosts")[1]
            self.vms = params.get("vms").split()

            self.sub_type = self.params.get("sub_type", None)
            self.max_downtime = int(self.params.get("max_mig_downtime", "10"))
            self.min_speed = self.params.get("min_migration_speed", "10")
            self.max_speed = self.params.get("max_migration_speed", "1000")
            self.ch_speed = int(self.params.get("change_speed_interval", 1))
            speed_count = float(self.params.get("count_of_change", 5))

            self.min_speed = utils.convert_data_size(self.min_speed, "M")
            self.max_speed = utils.convert_data_size(self.max_speed, "M")
            self.speed_step = int((self.max_speed - self.min_speed) /
                                                                  speed_count)

            if self.sub_type == "downtime":
                self.post_migration = self.post_migration_downtime
            elif self.sub_type == "speed":
                self.post_migration = self.post_migration_speed
            elif self.sub_type == "stop_during":
                self.post_migration = self.post_migration_stop
            else:
                error.TestFail("Wrong subtest type selected %s" %
                               (self.sub_type))
        def __init__(self, test, params, env):
            super(TestMultihostMigration, self).__init__(test, params, env)
            self.srchost = self.params.get("hosts")[0]
            self.dsthost = self.params.get("hosts")[1]
            self.is_src = params["hostid"] == self.srchost
            self.vms = params["vms"].split()

            self.sub_type = self.params.get("sub_type", None)
            self.mig_downtime = int(self.params.get("mig_downtime", "3"))
            self.max_downtime = int(self.params.get("max_mig_downtime", "10"))
            self.wait_mig_timeout = int(self.params.get("wait_mig_timeout", "30"))
            self.min_speed = self.params.get("min_migration_speed", "10")
            self.max_speed = self.params.get("max_migration_speed", "1000")
            self.ch_speed = int(self.params.get("change_speed_interval", 1))
            speed_count = float(self.params.get("count_of_change", 5))

            self.min_speed = utils.convert_data_size(self.min_speed, "M")
            self.max_speed = utils.convert_data_size(self.max_speed, "M")
            self.speed_step = int((self.max_speed - self.min_speed) /
                                  speed_count)

            if self.sub_type == "before_migrate":
                self.before_migration = self.before_migration_downtime
                self.post_migration = self.post_migration_before_downtime
            if self.sub_type == "after_migrate":
                self.post_migration = self.post_migration_downtime
            elif self.sub_type == "speed":
                self.post_migration = self.post_migration_speed
            elif self.sub_type == "stop_during":
                self.post_migration = self.post_migration_stop
            else:
                error.TestFail("Wrong subtest type selected %s" %
                               (self.sub_type))
        def __init__(self, test, params, env):
            super(TestMultihostMigration, self).__init__(test, params, env)
            self.install_path = params.get("cpuflags_install_path", "/tmp")
            self.vm_mem = int(params.get("mem", "512"))
            self.srchost = self.params.get("hosts")[0]
            self.dsthost = self.params.get("hosts")[1]
            self.vms = params["vms"].split()

            self.sub_type = self.params.get("sub_type", None)
            self.max_downtime = int(self.params.get("max_mig_downtime", "10"))
            self.min_speed = self.params.get("min_migration_speed", "10")
            self.max_speed = self.params.get("max_migration_speed", "1000")
            self.ch_speed = int(self.params.get("change_speed_interval", 1))
            speed_count = float(self.params.get("count_of_change", 5))

            self.min_speed = utils.convert_data_size(self.min_speed, "M")
            self.max_speed = utils.convert_data_size(self.max_speed, "M")
            self.speed_step = int((self.max_speed - self.min_speed) /
                                  speed_count)

            if self.sub_type == "downtime":
                self.post_migration = self.post_migration_downtime
            elif self.sub_type == "speed":
                self.post_migration = self.post_migration_speed
            elif self.sub_type == "stop_during":
                self.post_migration = self.post_migration_stop
            else:
                error.TestFail("Wrong subtest type selected %s" %
                               (self.sub_type))
Exemple #5
0
 def test_simple_functionality(self):
     size = 12
     self.assertEqual(size, utils.convert_data_size('12'))
     size *= 1024
     self.assertEqual(size, utils.convert_data_size('12K'))
     size *= 1024
     self.assertEqual(size, utils.convert_data_size('12m'))
     size *= 1024
     self.assertEqual(size, utils.convert_data_size('12G'))
     size *= 1024
     self.assertEqual(size, utils.convert_data_size('12T'))
Exemple #6
0
 def test_simple_functionality(self):
     size = 12
     self.assertEqual(size, utils.convert_data_size('12'))
     size *= 1024
     self.assertEqual(size, utils.convert_data_size('12K'))
     size *= 1024
     self.assertEqual(size, utils.convert_data_size('12m'))
     size *= 1024
     self.assertEqual(size, utils.convert_data_size('12G'))
     size *= 1024
     self.assertEqual(size, utils.convert_data_size('12T'))
Exemple #7
0
        def test(self):
            self.disk_path = None
            while self.disk_path is None or os.path.exists(self.disk_path):
                self.disk_path = (
                    "%s/disk_%s" %
                    (test.tmpdir, utils.generate_random_string(3)))

            disk_size = utils.convert_data_size(params.get("disk_size", "10M"),
                                                default_sufix='M')
            disk_size /= 1024 * 1024  # To MB.

            exp_str = r".*gzip: stdout: No space left on device.*"
            vm_guest = env.get_vm("virt_test_vm1_guest")
            utils.run("mkdir -p %s" % (mount_path))

            vm_guest.verify_alive()
            vm_guest.wait_for_login(timeout=login_timeout)

            create_file_disk(self.disk_path, disk_size)
            mount(self.disk_path, mount_path, "-o loop")

            vm_guest.migrate(mig_timeout,
                             mig_protocol,
                             not_wait_for_migration=True,
                             migration_exec_cmd_src=migration_exec_cmd_src)
            try:
                vm_guest.process.read_until_last_line_matches(exp_str)
            except aexpect.ExpectTimeoutError:
                raise error.TestFail("The migration to destination with low "
                                     "storage space didn't fail as it should.")
        def test(self):
            self.disk_path = None
            while self.disk_path is None or os.path.exists(self.disk_path):
                self.disk_path = ("%s/disk_%s" %
                                 (test.tmpdir, utils.generate_random_string(3)))

            disk_size = utils.convert_data_size(params.get("disk_size", "10M"),
                                                default_sufix='M')
            disk_size /= 1024 * 1024    # To MB.

            exp_str = r".*gzip: stdout: No space left on device.*"
            vm_guest = env.get_vm("virt_test_vm1_guest")
            utils.run("mkdir -p %s" % (mount_path))

            vm_guest.verify_alive()
            vm_guest.wait_for_login(timeout=login_timeout)

            create_file_disk(self.disk_path, disk_size)
            mount(self.disk_path, mount_path, "-o loop")

            vm_guest.migrate(mig_timeout, mig_protocol,
                             not_wait_for_migration=True,
                             migration_exec_cmd_src=migration_exec_cmd_src)
            try:
                vm_guest.process.read_until_last_line_matches(exp_str)
            except aexpect.ExpectTimeoutError:
                raise error.TestFail("The migration to destination with low "
                                     "storage space didn't fail as it should.")
        def migration_scenario(self):
            sync = SyncData(self.master_id(), self.hostid, self.hosts,
                            self.id, self.sync_server)
            srchost = self.params.get("hosts")[0]
            dsthost = self.params.get("hosts")[1]
            vms = [params.get("vms").split()[0]]

            def worker(mig_data):
                vm = mig_data.vms[0]
                session = vm.wait_for_login(timeout=self.login_timeout)

                cpuflags.install_cpuflags_util_on_vm(test, vm, install_path,
                                                     extra_flags="-msse3 -msse2")

                cmd = ("%s/cpuflags-test --stressmem %d,%d" %
                       (os.path.join(install_path, "cpu_flags"),
                        vm_mem * 4, vm_mem / 2))
                logging.debug("Sending command: %s" % (cmd))
                session.sendline(cmd)

            if self.master_id() == self.hostid:
                server_port = utils_misc.find_free_port(5200, 6000)
                server = listen_server(port=server_port)
                data_len = 0
                sync.sync(server_port, timeout=120)
                client = server.socket.accept()[0]
                endtime = time.time() + 30
                while endtime > time.time():
                    data_len += len(client.recv(2048))
                client.close()
                server.close()
                self.link_speed = data_len / (30 * 1024 * 1024)
                logging.info("Link speed %d MB/s" % (self.link_speed))
                ms = utils.convert_data_size(mig_speed, 'M')
                if (ms > data_len / 30):
                    logging.warn("Migration speed %s MB/s is set faster than "
                                 "real link speed %d MB/s" % (mig_speed,
                                                              self.link_speed))
                else:
                    self.link_speed = ms / (1024 * 1024)
            else:
                data = ""
                for _ in range(10000):
                    data += "i"
                server_port = sync.sync(timeout=120)[self.master_id()]
                sock = socket.socket(socket.AF_INET,
                                     socket.SOCK_STREAM)
                sock.connect((self.master_id(), server_port))
                try:
                    endtime = time.time() + 10
                    while endtime > time.time():
                        sock.sendall(data)
                    sock.close()
                except:
                    pass
            self.migrate_wait(vms, srchost, dsthost, worker)
Exemple #10
0
        def migration_scenario(self):
            sync = SyncData(self.master_id(), self.hostid, self.hosts,
                            self.id, self.sync_server)
            srchost = self.params.get("hosts")[0]
            dsthost = self.params.get("hosts")[1]
            vms = [params.get("vms").split()[0]]

            def worker(mig_data):
                vm = mig_data.vms[0]
                session = vm.wait_for_login(timeout=self.login_timeout)

                cpuflags.install_cpuflags_util_on_vm(test, vm, install_path,
                                                     extra_flags="-msse3 -msse2")

                cmd = ("%s/cpuflags-test --stressmem %d,%d" %
                       (os.path.join(install_path, "cpu_flags"),
                        vm_mem * 4, vm_mem / 2))
                logging.debug("Sending command: %s" % (cmd))
                session.sendline(cmd)

            if self.master_id() == self.hostid:
                server_port = utils_misc.find_free_port(5200, 6000)
                server = listen_server(port=server_port)
                data_len = 0
                sync.sync(server_port, timeout=120)
                client = server.socket.accept()[0]
                endtime = time.time() + 30
                while endtime > time.time():
                    data_len += len(client.recv(2048))
                client.close()
                server.close()
                self.link_speed = data_len / (30 * 1024 * 1024)
                logging.info("Link speed %d MB/s" % (self.link_speed))
                ms = utils.convert_data_size(mig_speed, 'M')
                if (ms > data_len / 30):
                    logging.warn("Migration speed %s MB/s is set faster than "
                                 "real link speed %d MB/s" % (mig_speed,
                                                              self.link_speed))
                else:
                    self.link_speed = ms / (1024 * 1024)
            else:
                data = ""
                for _ in range(10000):
                    data += "i"
                server_port = sync.sync(timeout=120)[self.master_id()]
                sock = socket.socket(socket.AF_INET,
                                     socket.SOCK_STREAM)
                sock.connect((self.master_id(), server_port))
                try:
                    endtime = time.time() + 10
                    while endtime > time.time():
                        sock.sendall(data)
                    sock.close()
                except:
                    pass
            self.migrate_wait(vms, srchost, dsthost, worker)
Exemple #11
0
    def migrate_set_speed(self, value):
        """
        Set maximum speed (in bytes/sec) for migrations.

        @param value: Speed in bytes/sec
        @return: The response to the command
        """
        value = utils.convert_data_size(value, "M")
        args = {"value": value}
        return self.cmd("migrate_set_speed", args)
Exemple #12
0
    def migrate_set_speed(self, value):
        """
        Set maximum speed (in bytes/sec) for migrations.

        @param value: Speed in bytes/sec
        @return: The response to the command
        """
        value = utils.convert_data_size(value, "M")
        args = {"value": value}
        return self.cmd("migrate_set_speed", args)
        def test(self):
            self.copier_pid = None
            if params.get("nettype") != "bridge":
                raise error.TestNAError("Unable start test without params"
                                        " nettype=bridge.")

            self.disk_serial = params.get("drive_serial_image2_vm1",
                                          "nfs-disk-image2-vm1")
            self.disk_serial_src = params.get("drive_serial_image1_vm1",
                                              "root-image1-vm1")
            self.guest_mount_path = params.get("guest_disk_mount_path", "/mnt")
            self.copy_timeout = int(params.get("copy_timeout", "1024"))

            self.copy_block_size = params.get("copy_block_size", "100M")
            self.copy_block_size = utils.convert_data_size(
                self.copy_block_size,
                "M")
            self.disk_size = "%s" % (self.copy_block_size * 1.4)
            self.copy_block_size /= 1024 * 1024

            self.server_recover_timeout = (
                int(params.get("server_recover_timeout", "240")))

            utils.run("mkdir -p %s" % (mount_path))

            self.test_params()
            self.config()

            self.vm_guest_params = params.copy()
            self.vm_guest_params["images_base_dir_image2_vm1"] = mount_path
            self.vm_guest_params["image_name_image2_vm1"] = "ni_mount_%s/test" % (test_rand)
            self.vm_guest_params["image_size_image2_vm1"] = self.disk_size
            self.vm_guest_params = self.vm_guest_params.object_params("vm1")
            self.image2_vm_guest_params = (self.vm_guest_params.
                                           object_params("image2"))

            env_process.preprocess_image(test,
                                         self.image2_vm_guest_params,
                                         env)
            self.vm_guest.create(params=self.vm_guest_params)

            self.vm_guest.verify_alive()
            self.vm_guest.wait_for_login(timeout=login_timeout)
            self.workload()

            self.restart_server()

            self.vm_guest.migrate(mig_timeout, mig_protocol, env=env)

            try:
                self.vm_guest.verify_alive()
                self.vm_guest.wait_for_login(timeout=login_timeout)
            except aexpect.ExpectTimeoutError:
                raise error.TestFail("Migration should be successful.")
Exemple #14
0
        def test(self):
            self.copier_pid = None
            if params.get("nettype") != "bridge":
                raise error.TestNAError("Unable start test without params"
                                        " nettype=bridge.")

            self.disk_serial = params.get("drive_serial_image2_vm1",
                                          "nfs-disk-image2-vm1")
            self.disk_serial_src = params.get("drive_serial_image1_vm1",
                                              "root-image1-vm1")
            self.guest_mount_path = params.get("guest_disk_mount_path", "/mnt")
            self.copy_timeout = int(params.get("copy_timeout", "1024"))

            self.copy_block_size = params.get("copy_block_size", "100M")
            self.copy_block_size = utils.convert_data_size(
                self.copy_block_size, "M")
            self.disk_size = "%s" % (self.copy_block_size * 1.4)
            self.copy_block_size /= 1024 * 1024

            self.server_recover_timeout = (int(
                params.get("server_recover_timeout", "240")))

            utils.run("mkdir -p %s" % (mount_path))

            self.test_params()
            self.config()

            self.vm_guest_params = params.copy()
            self.vm_guest_params["images_base_dir_image2_vm1"] = mount_path
            self.vm_guest_params[
                "image_name_image2_vm1"] = "ni_mount_%s/test" % (test_rand)
            self.vm_guest_params["image_size_image2_vm1"] = self.disk_size
            self.vm_guest_params = self.vm_guest_params.object_params("vm1")
            self.image2_vm_guest_params = (
                self.vm_guest_params.object_params("image2"))

            env_process.preprocess_image(test, self.image2_vm_guest_params,
                                         env)
            self.vm_guest.create(params=self.vm_guest_params)

            self.vm_guest.verify_alive()
            self.vm_guest.wait_for_login(timeout=login_timeout)
            self.workload()

            self.restart_server()

            self.vm_guest.migrate(mig_timeout, mig_protocol, env=env)

            try:
                self.vm_guest.verify_alive()
                self.vm_guest.wait_for_login(timeout=login_timeout)
            except aexpect.ExpectTimeoutError:
                raise error.TestFail("Migration should be successful.")
def run_migration_multi_host_with_speed_measurement(test, params, env):
    """
    KVM migration test:
    1) Get a live VM and clone it.
    2) Verify that the source VM supports migration.  If it does, proceed with
            the test.
    3) Start memory load in vm.
    4) Set defined migration speed.
    5) Send a migration command to the source VM and collecting statistic
            of migration speed.
    !) Checks that migration utilisation didn't slow down in guest stresser
       which would lead to less page-changes than required for this test.
       (migration speed is set too high for current CPU)
    6) Kill both VMs.
    7) Print statistic of migration.

    @param test: kvm test object.
    @param params: Dictionary with test parameters.
    @param env: Dictionary with the test environment.
    """
    mig_protocol = params.get("mig_protocol", "tcp")
    base_class = utils_test.MultihostMigration
    if mig_protocol == "fd":
        base_class = utils_test.MultihostMigrationFd

    install_path = params.get("cpuflags_install_path", "/tmp")

    vm_mem = int(params.get("mem", "512"))

    get_mig_speed = re.compile("^transferred ram: (\d+) kbytes$",
                               re.MULTILINE)

    mig_speed = params.get("mig_speed", "1G")
    mig_speed_accuracy = float(params.get("mig_speed_accuracy", "0.2"))

    def get_migration_statistic(vm):
        last_transfer_mem = 0
        transfered_mem = 0
        mig_stat = utils.Statistic()
        for _ in range(30):
            o = vm.monitor.info("migrate")
            warning_msg = ("Migration already ended. Migration speed is"
                           " probably too high and will block vm while"
                           " filling its memory.")
            fail_msg = ("Could not determine the transferred memory from"
                        " monitor data: %s" % o)
            if isinstance(o, str):
                if not "status: active" in o:
                    raise error.TestWarn(warning_msg)
                try:
                    transfered_mem = int(get_mig_speed.search(o).groups()[0])
                except (IndexError, ValueError):
                    raise error.TestFail(fail_msg)
            else:
                if o.get("status") != "active":
                    raise error.TestWarn(warning_msg)
                try:
                    transfered_mem = o.get("ram").get("transferred") / (1024)
                except (IndexError, ValueError):
                    raise error.TestFail(fail_msg)

            real_mig_speed = (transfered_mem - last_transfer_mem) / 1024

            last_transfer_mem = transfered_mem

            logging.debug("Migration speed: %s MB/s" % (real_mig_speed))
            mig_stat.record(real_mig_speed)
            time.sleep(1)

        return mig_stat

    class TestMultihostMigration(base_class):
        def __init__(self, test, params, env):
            super(TestMultihostMigration, self).__init__(test, params, env)
            self.mig_stat = None
            self.srchost = self.params.get("hosts")[0]
            self.dsthost = self.params.get("hosts")[1]
            self.id = {'src': self.srchost,
                       'dst': self.dsthost,
                       "type": "speed_measurement"}
            self.link_speed = 0

        def check_vms(self, mig_data):
            """
            Check vms after migrate.

            @param mig_data: object with migration data.
            """
            pass

        def migrate_vms_src(self, mig_data):
            """
            Migrate vms source.

            @param mig_Data: Data for migration.

            For change way how machine migrates is necessary
            re implement this method.
            """
            super_cls = super(TestMultihostMigration, self)
            super_cls.migrate_vms_src(mig_data)
            vm = mig_data.vms[0]
            self.mig_stat = get_migration_statistic(vm)

        def migration_scenario(self):
            sync = SyncData(self.master_id(), self.hostid, self.hosts,
                            self.id, self.sync_server)
            srchost = self.params.get("hosts")[0]
            dsthost = self.params.get("hosts")[1]
            vms = [params.get("vms").split()[0]]

            def worker(mig_data):
                vm = mig_data.vms[0]
                session = vm.wait_for_login(timeout=self.login_timeout)

                utils_misc.install_cpuflags_util_on_vm(test, vm, install_path,
                                                    extra_flags="-msse3 -msse2")

                cmd = ("%s/cpuflags-test --stressmem %d" %
                    (os.path.join(install_path, "test_cpu_flags"), vm_mem / 2))
                logging.debug("Sending command: %s" % (cmd))
                session.sendline(cmd)

            if self.master_id() == self.hostid:
                server_port = utils_misc.find_free_port(5200, 6000)
                server = listen_server(port=server_port)
                data_len = 0
                sync.sync(server_port, timeout=120)
                client = server.socket.accept()[0]
                endtime = time.time() + 30
                while endtime > time.time():
                    data_len += len(client.recv(2048))
                client.close()
                server.close()
                self.link_speed = data_len / (30 * 1024 * 1024)
                logging.info("Link speed %d MB/s" % (self.link_speed))
                ms = utils.convert_data_size(mig_speed, 'M')
                if (ms > data_len / 30):
                    logging.warn("Migration speed %s MB/s is set faster than "
                                 "real link speed %d MB/s" % (mig_speed,
                                                              self.link_speed))
                else:
                    self.link_speed = ms / (1024 * 1024)
            else:
                data = ""
                for _ in range(10000):
                    data += "i"
                server_port = sync.sync(timeout=120)[self.master_id()]
                sock = socket.socket(socket.AF_INET,
                                     socket.SOCK_STREAM)
                sock.connect((self.master_id(), server_port))
                try:
                    endtime = time.time() + 10
                    while endtime > time.time():
                        sock.sendall(data)
                    sock.close()
                except:
                    pass
            self.migrate_wait(vms, srchost, dsthost, worker)

    mig = TestMultihostMigration(test, params, env)
    #Start migration
    mig.run()

    #If machine is migration master check migration statistic.
    if mig.master_id() == mig.hostid:
        mig_speed = utils.convert_data_size(mig_speed, "M")

        mig_stat = mig.mig_stat

        mig_speed = mig_speed / (1024 * 1024)
        real_speed = mig_stat.get_average()
        ack_speed = mig.link_speed * mig_speed_accuracy

        logging.info("Target migration speed: %d MB/s", mig_speed)
        logging.info("Real Link speed: %d MB/s", mig.link_speed)
        logging.info("Average migration speed: %d MB/s", mig_stat.get_average())
        logging.info("Minimum migration speed: %d MB/s", mig_stat.get_min())
        logging.info("Maximum migration speed: %d MB/s", mig_stat.get_max())

        logging.info("Maximum tolerable divergence: %3.1f%%",
                     mig_speed_accuracy*100)

        if real_speed < mig_speed - ack_speed:
            divergence = (1 - float(real_speed)/float(mig_speed)) * 100
            raise error.TestWarn("Average migration speed (%s MB/s) "
                                 "is %3.1f%% lower than target (%s MB/s)" %
                                 (real_speed, divergence, mig_speed))

        if real_speed > mig_speed + ack_speed:
            divergence = (1 - float(mig_speed)/float(real_speed)) * 100
            raise error.TestWarn("Average migration speed (%s MB/s) "
                                 "is %3.1f %% higher than target (%s MB/s)" %
                                 (real_speed, divergence, mig_speed))
def run(test, params, env):
    """
    KVM migration test:
    1) Get a live VM and clone it.
    2) Verify that the source VM supports migration.  If it does, proceed with
            the test.
    3) Start memory load in vm.
    4) Set defined migration speed.
    5) Send a migration command to the source VM and collecting statistic
            of migration speed.
    !) Checks that migration utilisation didn't slow down in guest stresser
       which would lead to less page-changes than required for this test.
       (migration speed is set too high for current CPU)
    6) Kill both VMs.
    7) Print statistic of migration.

    :param test: kvm test object.
    :param params: Dictionary with test parameters.
    :param env: Dictionary with the test environment.
    """
    mig_protocol = params.get("mig_protocol", "tcp")
    base_class = utils_test.qemu.MultihostMigration
    if mig_protocol == "fd":
        base_class = utils_test.qemu.MultihostMigrationFd
    if mig_protocol == "exec":
        base_class = utils_test.qemu.MultihostMigrationExec
    if "rdma" in mig_protocol:
        base_class = utils_test.qemu.MultihostMigrationRdma

    install_path = params.get("cpuflags_install_path", "/tmp")

    vm_mem = int(params.get("mem", "512"))

    get_mig_speed = re.compile("^transferred ram: (\d+) kbytes$", re.MULTILINE)

    mig_speed = params.get("mig_speed", "1G")
    mig_speed_accuracy = float(params.get("mig_speed_accuracy", "0.2"))

    def get_migration_statistic(vm):
        last_transfer_mem = 0
        transfered_mem = 0
        mig_stat = utils.Statistic()
        for _ in range(30):
            o = vm.monitor.info("migrate")
            warning_msg = ("Migration already ended. Migration speed is"
                           " probably too high and will block vm while"
                           " filling its memory.")
            fail_msg = ("Could not determine the transferred memory from"
                        " monitor data: %s" % o)
            if isinstance(o, str):
                if "status: active" not in o:
                    raise error.TestWarn(warning_msg)
                try:
                    transfered_mem = int(get_mig_speed.search(o).groups()[0])
                except (IndexError, ValueError):
                    raise error.TestFail(fail_msg)
            else:
                if o.get("status") != "active":
                    raise error.TestWarn(warning_msg)
                try:
                    transfered_mem = o.get("ram").get("transferred") / (1024)
                except (IndexError, ValueError):
                    raise error.TestFail(fail_msg)

            real_mig_speed = (transfered_mem - last_transfer_mem) / 1024

            last_transfer_mem = transfered_mem

            logging.debug("Migration speed: %s MB/s" % (real_mig_speed))
            mig_stat.record(real_mig_speed)
            time.sleep(1)

        return mig_stat

    class TestMultihostMigration(base_class):
        def __init__(self, test, params, env):
            super(TestMultihostMigration, self).__init__(test, params, env)
            self.mig_stat = None
            self.srchost = self.params.get("hosts")[0]
            self.dsthost = self.params.get("hosts")[1]
            self.id = {
                'src': self.srchost,
                'dst': self.dsthost,
                "type": "speed_measurement"
            }
            self.link_speed = 0

        def check_vms(self, mig_data):
            """
            Check vms after migrate.

            :param mig_data: object with migration data.
            """
            pass

        def migrate_vms_src(self, mig_data):
            """
            Migrate vms source.

            :param mig_Data: Data for migration.

            For change way how machine migrates is necessary
            re implement this method.
            """
            super_cls = super(TestMultihostMigration, self)
            super_cls.migrate_vms_src(mig_data)
            vm = mig_data.vms[0]
            self.mig_stat = get_migration_statistic(vm)

        def migration_scenario(self):
            sync = SyncData(self.master_id(), self.hostid, self.hosts, self.id,
                            self.sync_server)
            srchost = self.params.get("hosts")[0]
            dsthost = self.params.get("hosts")[1]
            vms = [params.get("vms").split()[0]]

            def worker(mig_data):
                vm = mig_data.vms[0]
                session = vm.wait_for_login(timeout=self.login_timeout)

                cpuflags.install_cpuflags_util_on_vm(
                    test, vm, install_path, extra_flags="-msse3 -msse2")

                cmd = ("%s/cpuflags-test --stressmem %d,%d" % (os.path.join(
                    install_path, "cpu_flags"), vm_mem * 4, vm_mem / 2))
                logging.debug("Sending command: %s" % (cmd))
                session.sendline(cmd)

            if self.master_id() == self.hostid:
                server_port = utils_misc.find_free_port(5200, 6000)
                server = listen_server(port=server_port)
                data_len = 0
                sync.sync(server_port, timeout=120)
                client = server.socket.accept()[0]
                endtime = time.time() + 30
                while endtime > time.time():
                    data_len += len(client.recv(2048))
                client.close()
                server.close()
                self.link_speed = data_len / (30 * 1024 * 1024)
                logging.info("Link speed %d MB/s" % (self.link_speed))
                ms = utils.convert_data_size(mig_speed, 'M')
                if (ms > data_len / 30):
                    logging.warn("Migration speed %s MB/s is set faster than "
                                 "real link speed %d MB/s" %
                                 (mig_speed, self.link_speed))
                else:
                    self.link_speed = ms / (1024 * 1024)
            else:
                data = ""
                for _ in range(10000):
                    data += "i"
                server_port = sync.sync(timeout=120)[self.master_id()]
                sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                sock.connect((self.master_id(), server_port))
                try:
                    endtime = time.time() + 10
                    while endtime > time.time():
                        sock.sendall(data)
                    sock.close()
                except:
                    pass
            self.migrate_wait(vms, srchost, dsthost, worker)

    mig = TestMultihostMigration(test, params, env)
    # Start migration
    mig.run()

    # If machine is migration master check migration statistic.
    if mig.master_id() == mig.hostid:
        mig_speed = utils.convert_data_size(mig_speed, "M")

        mig_stat = mig.mig_stat

        mig_speed = mig_speed / (1024 * 1024)
        real_speed = mig_stat.get_average()
        ack_speed = mig.link_speed * mig_speed_accuracy

        logging.info("Target migration speed: %d MB/s", mig_speed)
        logging.info("Real Link speed: %d MB/s", mig.link_speed)
        logging.info("Average migration speed: %d MB/s",
                     mig_stat.get_average())
        logging.info("Minimum migration speed: %d MB/s", mig_stat.get_min())
        logging.info("Maximum migration speed: %d MB/s", mig_stat.get_max())

        logging.info("Maximum tolerable divergence: %3.1f%%",
                     mig_speed_accuracy * 100)

        if real_speed < mig_speed - ack_speed:
            divergence = (1 - float(real_speed) / float(mig_speed)) * 100
            raise error.TestWarn("Average migration speed (%s MB/s) "
                                 "is %3.1f%% lower than target (%s MB/s)" %
                                 (real_speed, divergence, mig_speed))

        if real_speed > mig_speed + ack_speed:
            divergence = (1 - float(mig_speed) / float(real_speed)) * 100
            raise error.TestWarn("Average migration speed (%s MB/s) "
                                 "is %3.1f %% higher than target (%s MB/s)" %
                                 (real_speed, divergence, mig_speed))
def run(test, params, env):
    """
    KVM migration test:
    1) Get a live VM and clone it.
    2) Verify that the source VM supports migration.  If it does, proceed with
            the test.
    3) Start memory load on vm.
    4) Send a migration command to the source VM and collecting statistic
            of migration speed.
    !) If migration speed is too high migration could be successful and then
            test ends with warning.
    5) Kill off both VMs.
    6) Print statistic of migration.

    :param test: kvm test object.
    :param params: Dictionary with test parameters.
    :param env: Dictionary with the test environment.
    """
    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    login_timeout = int(params.get("login_timeout", 360))
    session = vm.wait_for_login(timeout=login_timeout)

    mig_timeout = float(params.get("mig_timeout", "10"))
    mig_protocol = params.get("migration_protocol", "tcp")

    install_path = params.get("cpuflags_install_path", "/tmp")

    vm_mem = int(params.get("mem", "512"))

    get_mig_speed = re.compile("^transferred ram: (\d+) kbytes$", re.MULTILINE)

    mig_speed = params.get("mig_speed", "1G")
    mig_speed_accuracy = float(params.get("mig_speed_accuracy", "0.2"))
    clonevm = None

    def get_migration_statistic(vm):
        last_transfer_mem = 0
        transfered_mem = 0
        mig_stat = utils.Statistic()
        for _ in range(30):
            o = vm.monitor.info("migrate")
            warning_msg = ("Migration already ended. Migration speed is"
                           " probably too high and will block vm while"
                           " filling its memory.")
            fail_msg = ("Could not determine the transferred memory from"
                        " monitor data: %s" % o)
            if isinstance(o, str):
                if "status: active" not in o:
                    raise error.TestWarn(warning_msg)
                try:
                    transfered_mem = int(get_mig_speed.search(o).groups()[0])
                except (IndexError, ValueError):
                    raise error.TestFail(fail_msg)
            else:
                if o.get("status") != "active":
                    raise error.TestWarn(warning_msg)
                try:
                    transfered_mem = o.get("ram").get("transferred") / (1024)
                except (IndexError, ValueError):
                    raise error.TestFail(fail_msg)

            real_mig_speed = (transfered_mem - last_transfer_mem) / 1024

            last_transfer_mem = transfered_mem

            logging.debug("Migration speed: %s MB/s" % (real_mig_speed))
            mig_stat.record(real_mig_speed)
            time.sleep(1)

        return mig_stat

    try:
        # Reboot the VM in the background
        cpuflags.install_cpuflags_util_on_vm(test,
                                             vm,
                                             install_path,
                                             extra_flags="-msse3 -msse2")

        vm.monitor.migrate_set_speed(mig_speed)

        cmd = (
            "%s/cpuflags-test --stressmem %d,%d" %
            (os.path.join(install_path, "cpu_flags"), vm_mem * 4, vm_mem / 2))
        logging.debug("Sending command: %s" % (cmd))
        session.sendline(cmd)

        time.sleep(2)

        clonevm = vm.migrate(mig_timeout,
                             mig_protocol,
                             not_wait_for_migration=True,
                             env=env)

        mig_speed = utils.convert_data_size(mig_speed, "M")

        mig_stat = get_migration_statistic(vm)

        mig_speed = mig_speed / (1024 * 1024)
        real_speed = mig_stat.get_average()
        ack_speed = mig_speed * mig_speed_accuracy

        logging.info("Target migration speed: %d MB/s.", mig_speed)
        logging.info("Average migration speed: %d MB/s",
                     mig_stat.get_average())
        logging.info("Minimum migration speed: %d MB/s", mig_stat.get_min())
        logging.info("Maximum migration speed: %d MB/s", mig_stat.get_max())

        logging.info("Maximum tolerable divergence: %3.1f%%",
                     mig_speed_accuracy * 100)

        if real_speed < mig_speed - ack_speed:
            divergence = (1 - float(real_speed) / float(mig_speed)) * 100
            raise error.TestWarn("Average migration speed (%s MB/s) "
                                 "is %3.1f%% lower than target (%s MB/s)" %
                                 (real_speed, divergence, mig_speed))

        if real_speed > mig_speed + ack_speed:
            divergence = (1 - float(mig_speed) / float(real_speed)) * 100
            raise error.TestWarn("Average migration speed (%s MB/s) "
                                 "is %3.1f %% higher than target (%s MB/s)" %
                                 (real_speed, divergence, mig_speed))

    finally:
        session.close()
        if clonevm:
            clonevm.destroy(gracefully=False)
        if vm:
            vm.destroy(gracefully=False)
def run_migration_with_speed_measurement(test, params, env):
    """
    KVM migration test:
    1) Get a live VM and clone it.
    2) Verify that the source VM supports migration.  If it does, proceed with
            the test.
    3) Start memory load on vm.
    4) Send a migration command to the source VM and collecting statistic
            of migration speed.
    !) If migration speed is too high migration could be successful and then
            test ends with warning.
    5) Kill off both VMs.
    6) Print statistic of migration.

    :param test: kvm test object.
    :param params: Dictionary with test parameters.
    :param env: Dictionary with the test environment.
    """
    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    login_timeout = int(params.get("login_timeout", 360))
    session = vm.wait_for_login(timeout=login_timeout)

    mig_timeout = float(params.get("mig_timeout", "10"))
    mig_protocol = params.get("migration_protocol", "tcp")

    install_path = params.get("cpuflags_install_path", "/tmp")

    vm_mem = int(params.get("mem", "512"))

    get_mig_speed = re.compile("^transferred ram: (\d+) kbytes$",
                               re.MULTILINE)

    mig_speed = params.get("mig_speed", "1G")
    mig_speed_accuracy = float(params.get("mig_speed_accuracy", "0.2"))
    clonevm = None

    def get_migration_statistic(vm):
        last_transfer_mem = 0
        transfered_mem = 0
        mig_stat = utils.Statistic()
        for _ in range(30):
            o = vm.monitor.info("migrate")
            warning_msg = ("Migration already ended. Migration speed is"
                           " probably too high and will block vm while"
                           " filling its memory.")
            fail_msg = ("Could not determine the transferred memory from"
                        " monitor data: %s" % o)
            if isinstance(o, str):
                if not "status: active" in o:
                    raise error.TestWarn(warning_msg)
                try:
                    transfered_mem = int(get_mig_speed.search(o).groups()[0])
                except (IndexError, ValueError):
                    raise error.TestFail(fail_msg)
            else:
                if o.get("status") != "active":
                    raise error.TestWarn(warning_msg)
                try:
                    transfered_mem = o.get("ram").get("transferred") / (1024)
                except (IndexError, ValueError):
                    raise error.TestFail(fail_msg)

            real_mig_speed = (transfered_mem - last_transfer_mem) / 1024

            last_transfer_mem = transfered_mem

            logging.debug("Migration speed: %s MB/s" % (real_mig_speed))
            mig_stat.record(real_mig_speed)
            time.sleep(1)

        return mig_stat

    try:
        # Reboot the VM in the background
        utils_misc.install_cpuflags_util_on_vm(test, vm, install_path,
                                               extra_flags="-msse3 -msse2")

        vm.monitor.migrate_set_speed(mig_speed)

        cmd = ("%s/cpuflags-test --stressmem %d,%d" %
              (os.path.join(install_path, "test_cpu_flags"),
               vm_mem * 4, vm_mem / 2))
        logging.debug("Sending command: %s" % (cmd))
        session.sendline(cmd)

        time.sleep(2)

        clonevm = vm.migrate(mig_timeout, mig_protocol,
                             not_wait_for_migration=True)

        mig_speed = utils.convert_data_size(mig_speed, "M")

        mig_stat = get_migration_statistic(vm)

        mig_speed = mig_speed / (1024 * 1024)
        real_speed = mig_stat.get_average()
        ack_speed = mig_speed * mig_speed_accuracy

        logging.info("Target migration speed: %d MB/s.", mig_speed)
        logging.info(
            "Average migration speed: %d MB/s", mig_stat.get_average())
        logging.info("Minimum migration speed: %d MB/s", mig_stat.get_min())
        logging.info("Maximum migration speed: %d MB/s", mig_stat.get_max())

        logging.info("Maximum tolerable divergence: %3.1f%%",
                     mig_speed_accuracy * 100)

        if real_speed < mig_speed - ack_speed:
            divergence = (1 - float(real_speed) / float(mig_speed)) * 100
            raise error.TestWarn("Average migration speed (%s MB/s) "
                                 "is %3.1f%% lower than target (%s MB/s)" %
                                 (real_speed, divergence, mig_speed))

        if real_speed > mig_speed + ack_speed:
            divergence = (1 - float(mig_speed) / float(real_speed)) * 100
            raise error.TestWarn("Average migration speed (%s MB/s) "
                                 "is %3.1f %% higher than target (%s MB/s)" %
                                 (real_speed, divergence, mig_speed))

    finally:
        session.close()
        if clonevm:
            clonevm.destroy(gracefully=False)
        if vm:
            vm.destroy(gracefully=False)