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))
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'))
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)
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.")
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)