1AUTHOR = "Yolkfull Chow <yzhou@redhat.com>"
2TIME = "SHORT"
3NAME = "Migration across multiple hosts"
4TEST_CATEGORY = "Functional"
5TEST_CLASS = "Virtualization"
6TEST_TYPE = "Server"
7DOC = """
8Migrate KVM guest between two hosts. It parses the base config file, restricts
9it with appropriate parameters, generates the test dicts, modify the test_dicts
10so there's a distinction between the migration roles ('dest' or 'source').
11"""
12
13import sys, os, commands, glob, shutil, logging, random
14from autotest_lib.server import utils
15from autotest_lib.client.common_lib import cartesian_config
16
17# Specify the directory of autotest before you start this test
18AUTOTEST_DIR = '/usr/local/autotest'
19
20# Specify the root directory that on client machines
21rootdir = '/tmp/kvm_autotest_root'
22
23KVM_DIR = os.path.join(AUTOTEST_DIR, 'client/tests/kvm')
24
25
26def generate_mac_address():
27    r = random.SystemRandom()
28    mac = "9a:%02x:%02x:%02x:%02x:%02x" % (r.randint(0x00, 0xff),
29                                           r.randint(0x00, 0xff),
30                                           r.randint(0x00, 0xff),
31                                           r.randint(0x00, 0xff),
32                                           r.randint(0x00, 0xff))
33    return mac
34
35
36def run(pair):
37    logging.info("KVM migration running on source host [%s] and destination "
38                 "host [%s]\n", pair[0], pair[1])
39
40    source = hosts.create_host(pair[0])
41    dest = hosts.create_host(pair[1])
42    source_at = autotest.Autotest(source)
43    dest_at = autotest.Autotest(dest)
44
45    cfg_file = os.path.join(KVM_DIR, "tests_base.cfg")
46
47    if not os.path.exists(cfg_file):
48        raise error.JobError("Config file %s was not found", cfg_file)
49
50    # Get test set (dictionary list) from the configuration file
51    parser = cartesian_config.Parser()
52    test_variants = """
53image_name(_.*)? ?<= /tmp/kvm_autotest_root/images/
54cdrom(_.*)? ?<= /tmp/kvm_autotest_root/
55floppy ?<= /tmp/kvm_autotest_root/
56Linux:
57    unattended_install:
58        kernel ?<= /tmp/kvm_autotest_root/
59        initrd ?<= /tmp/kvm_autotest_root/
60qemu_binary = /usr/libexec/qemu-kvm
61qemu_img_binary = /usr/bin/qemu-img
62only qcow2
63only virtio_net
64only virtio_blk
65only smp2
66only no_pci_assignable
67only smallpages
68only Fedora.14.64
69only migrate_multi_host
70nic_mode = tap
71nic_mac_nic1 = %s
72""" % (generate_mac_address())
73    parser.parse_file(cfg_file)
74    parser.parse_string(test_variants)
75    test_dicts = parser.get_dicts()
76
77    source_control_file = dest_control_file = """
78kvm_test_dir = os.path.join(os.environ['AUTODIR'],'tests/kvm')
79sys.path.append(kvm_test_dir)\n
80"""
81    for params in test_dicts:
82        params['srchost'] = source.ip
83        params['dsthost'] = dest.ip
84        params['rootdir'] = rootdir
85
86        source_params = params.copy()
87        source_params['role'] = "source"
88
89        dest_params = params.copy()
90        dest_params['role'] = "destination"
91        dest_params['migration_mode'] = "tcp"
92
93        # Report the parameters we've received
94        print "Test parameters:"
95        keys = params.keys()
96        keys.sort()
97        for key in keys:
98            logging.debug("    %s = %s", key, params[key])
99
100        source_control_file += ("job.run_test('kvm', tag='%s', params=%s)" %
101                                (source_params['shortname'], source_params))
102        dest_control_file += ("job.run_test('kvm', tag='%s', params=%s)" %
103                              (dest_params['shortname'], dest_params))
104
105        logging.info('Source control file:\n%s', source_control_file)
106        logging.info('Destination control file:\n%s', dest_control_file)
107        dest_command = subcommand(dest_at.run,
108                                  [dest_control_file, dest.hostname])
109
110        source_command = subcommand(source_at.run,
111                                    [source_control_file, source.hostname])
112
113        parallel([dest_command, source_command])
114
115# Grab the pairs (and failures)
116(pairs, failures) = utils.form_ntuples_from_machines(machines, 2)
117
118# Log the failures
119for failure in failures:
120    job.record("FAIL", failure[0], "kvm", failure[1])
121
122# Now run through each pair and run
123job.parallel_simple(run, pairs, log=False)
124