On 03/15/2012 01:57 PM, tangchen wrote: > This patch improves the virsh_migrate test to support more tests. > > Signed-off-by: Tang Chen<tangc...@cn.fujitsu.com> > --- > client/tests/libvirt/tests/virsh_migrate.py | 255 > +++++++++++++++++++++++---- > 1 files changed, 220 insertions(+), 35 deletions(-) > > diff --git a/client/tests/libvirt/tests/virsh_migrate.py > b/client/tests/libvirt/tests/virsh_migrate.py > index 7e74505..9bc8352 100644 > --- a/client/tests/libvirt/tests/virsh_migrate.py > +++ b/client/tests/libvirt/tests/virsh_migrate.py > @@ -1,11 +1,38 @@ > -import logging, time > +import logging, os, re, time, shutil, codecs > from autotest_lib.client.common_lib import error > +from autotest_lib.client.bin import utils > +from autotest_lib.client.virt import libvirt_vm, virt_utils > > def run_virsh_migrate(test, params, env): > """ > Test virsh migrate command. > """ > > + # vm.migrate() did some error checking, so when we want to test > + # some incorrect options, we have to construct our own command. > + def do_error_migration(vm_ref, dest_uri, options = "", extra = "", uri = > ""): > + cmd = "" > + if uri == "": > + cmd += "virsh migrate " > + else: > + cmd += "virsh -c %s migrate " % uri > + cmd += options > + if vm_ref != "": > + cmd += " --domain %s " % vm_ref > + if dest_uri != "": > + cmd += " --desturi %s " % dest_uri > + cmd += extra > + > + cmd_result = utils.run(cmd, ignore_status = True) > + logging.info("Output: %s", cmd_result.stdout.strip()) > + logging.info("Error: %s", cmd_result.stderr.strip()) s/info/error/ > + logging.info("Status: %d", cmd_result.exit_status) > + # Here we should keep the return value type the same as > do_migration(). > + if cmd_result.exit_status == 0: > + return True > + else: > + return False > + > def check_vm_state(vm, state): > """ > Return True if vm is in the correct state. > @@ -21,17 +48,24 @@ def run_virsh_migrate(test, params, env): > 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() > + 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() > > - vm.connect_uri = src_uri > + except Exception, detail: > + logging.error("Cleaning up destination failed.\n%s" % detail) > + > + finally: > + 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) > @@ -39,28 +73,33 @@ def run_virsh_migrate(test, params, env): > # Migrate the guest. > successful = vm.migrate(dest_uri, options, extra) > if not successful: > - raise error.TestFail("Migration failed for %s." % vm_name) > + logging.info("Migration failed for %s." % vm_name) s/info/error/ > + return False > > 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.info("VM not alive on destination %s" % dest_uri) s/info/error/ > + return False > > # FIXME: This needs to be tested, but won't work currently > # vm.verify_kernel_crash() Need a logging.info(). > > + 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 = "/etc/libvirt/qemu/%s.xml" % vm_name > + vm_xmlfile_bak = "/tmp/%s_bak.xml" % vm_name Make sure you haven't removed the same name file.
import tempfile vm_xmlfile_bak = tempfile.mktemp() > + if os.path.exists(vm_xmlfile_bak): > + os.remove(vm_xmlfile_bak) > + shutil.copyfile(vm_xmlfile, vm_xmlfile_bak) > + if not os.path.exists(vm_xmlfile_bak): > + logging.warning(warning_text % "Backing up xmlfile failed.") > + > src_uri = vm.connect_uri > dest_uri = params.get("virsh_migrate_desturi") > # Identify easy config. mistakes early > @@ -78,21 +117,167 @@ def run_virsh_migrate(test, params, env): > options = params.get("virsh_migrate_options") > extra = params.get("virsh_migrate_extra") > dly = int(params.get("virsh_migrate_delay", 10)) s/dly/delay/, delay is a short and completed variable name, so we don't need to ignore 'e' and 'a' in here. > + 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") > + > + # Wait till VM is up. > + time.sleep(dly) > + > + exception = False > + try: > + # Confirm VM can be accessed through network. > + vm_ip = vm.get_address(index = 0) > + logging.info("VM IP: %s" % vm_ip) > + ping_result = utils.run("ping -c 2 %s" % vm_ip, ignore_status = True) If it exists a delay on network, this result will be invalid, so you had better to use a loop to run the above ping and give a acceptance time out. > + if ping_result.exit_status != 0: > + logging.error("Pinging VM %s has no responding." % vm_name) > + > + # Prepare for --xml. > + new_nic_mac = "" > + dest_xmlfile = "" > + if options.count("xml") or extra.count("xml"): > + new_nic_mac = virt_utils.generate_mac_address(vm, 1) > + logging.info("New mac address: %s" % new_nic_mac) > + dest_xmlfile = params.get("virsh_migrate_xml", "") > + ret_attach = vm.attach_interface("bridge", "--source virbr0 > --mac %s" % new_nic_mac) > + if not ret_attach: > + exception = True > + raise error.TestError("Attaching nic to %s failed." % > vm.name) > + vm_xml_new = vm.get_xml() > + logging.info("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 erro.TestError("Creating %s failed." % dest_xmlfile) > + > + # Turn VM into certain state. > + 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. > + if libvirtd_state == "off": > + libvirt_vm.libvirtd_stop() > > + # Test uni-direction migration. > + if status_error == 'no': > + ret_migrate = do_migration(dly, vm, dest_uri, options, extra) > + else: > + vm_ref = params.get("vm_ref", vm.name) > + dest_uri_ref = params.get("dest_uri_ref", dest_uri) > + ret_migrate = do_error_migration(vm_ref, dest_uri_ref, options, > extra) > + > + # Recover libvirtd state. > + if libvirtd_state == "off": > + libvirt_vm.libvirtd_start() > + > + # Recover VM state. > + if src_state == "paused": > + vm.resume() > + elif src_state == "shut off": > + vm.start() > + > + # Check vm state on destination. > + 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\nActual state: %s" % (dest_state, > vm.state())) > + > + # Checking for --persistent. > + check_dest_persistent = True > + if options.count("persistent") or extra.count("persistent"): > + if not vm.is_persistent(): > + check_dest_persistent = False > + > + # Checking for --undefinesource. > + check_src_undefine = True > + if options.count("undefinesource") or extra.count("undefinesource"): > + if libvirt_vm.virsh_domain_exists(vm_name, src_uri): > + check_src_undefine = False > + > + # Checking for --dname. > + check_dest_dname = True > + if options.count("dname") or extra.count("dname"): > + dname = params.get("virsh_migrate_dname") > + if not libvirt_vm.virsh_domain_exists(dname, dest_uri): > + check_dest_dname = False > + > + # Checking for --xml. > + check_dest_xml = True > + if options.count("xml") or extra.count("xml"): > + 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 > > - 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. > - else: > + # 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) > + > + except Exception, detail: > + # Whatever error occurs, we have to clean up all environment. > + exception = True > + logging.error("Error occurred.\n%s" % detail) > + > + finally: > + # Cleanup destination. > + # 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 = params.get("virsh_migrate_dname") > + cleanup_dest(vm, "") > + vm.name = vm_name > 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) > + if os.path.exists(dest_xmlfile): > + os.remove(dest_xmlfile) > + > + if exception: > + raise error.TestError("Error occurred.") > + > + # 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.") > + _______________________________________________ Autotest mailing list Autotest@test.kernel.org http://test.kernel.org/cgi-bin/mailman/listinfo/autotest