2
This script concurrently builds and migrates instances. This can be useful when
3
troubleshooting race-conditions in virt-layer code.
7
novarc to be sourced in the environment
9
Helper Script for Xen Dom0:
11
# cat /tmp/destroy_cache_vdis
13
xe vdi-list | grep "Glance Image" -C1 | grep "^uuid" | awk '{print $5}' |
14
xargs -n1 -I{} xe vdi-destroy uuid={}
18
import multiprocessing
23
DOM0_CLEANUP_SCRIPT = "/tmp/destroy_cache_vdis"
27
ret = subprocess.call(cmd, shell=True)
29
print >> sys.stderr, "Command exited non-zero: %s" % cmd
32
@contextlib.contextmanager
33
def server_built(server_name, image_name, flavor=1, cleanup=True):
34
run("nova boot --image=%(image_name)s --flavor=%(flavor)s"
35
" --poll %(server_name)s" % locals())
40
run("nova delete %(server_name)s" % locals())
43
@contextlib.contextmanager
44
def snapshot_taken(server_name, snapshot_name, cleanup=True):
45
run("nova image-create %(server_name)s %(snapshot_name)s"
51
run("nova image-delete %(snapshot_name)s" % locals())
54
def migrate_server(server_name):
55
run("nova migrate %(server_name)s --poll" % locals())
57
cmd = "nova list | grep %(server_name)s | awk '{print $6}'" % locals()
58
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
59
stdout, stderr = proc.communicate()
60
status = stdout.strip()
61
if status.upper() != 'VERIFY_RESIZE':
62
print >> sys.stderr, "Server %(server_name)s failed to rebuild"\
67
run("nova resize-confirm %(server_name)s" % locals())
71
def test_migrate(context):
73
server_name = "server%d" % count
74
cleanup = args.cleanup
75
with server_built(server_name, args.image, cleanup=cleanup):
77
result = migrate_server(server_name)
82
return migrate_server(server_name)
85
def rebuild_server(server_name, snapshot_name):
86
run("nova rebuild %(server_name)s %(snapshot_name)s --poll" % locals())
88
cmd = "nova list | grep %(server_name)s | awk '{print $6}'" % locals()
89
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
90
stdout, stderr = proc.communicate()
91
status = stdout.strip()
92
if status != 'ACTIVE':
93
print >> sys.stderr, "Server %(server_name)s failed to rebuild"\
100
def test_rebuild(context):
101
count, args = context
102
server_name = "server%d" % count
103
snapshot_name = "snap%d" % count
104
cleanup = args.cleanup
105
with server_built(server_name, args.image, cleanup=cleanup):
106
with snapshot_taken(server_name, snapshot_name, cleanup=cleanup):
107
return rebuild_server(server_name, snapshot_name)
111
parser = argparse.ArgumentParser(
112
description='Test Nova for Race Conditions.')
114
parser.add_argument('tests', metavar='TESTS', type=str, nargs='*',
115
default=['rebuild', 'migrate'],
116
help='tests to run: [rebuilt|migrate]')
118
parser.add_argument('-i', '--image', help="image to build from",
120
parser.add_argument('-n', '--num-runs', type=int, help="number of runs",
122
parser.add_argument('-c', '--concurrency', type=int, default=5,
123
help="number of concurrent processes")
124
parser.add_argument('--no-cleanup', action='store_false', dest="cleanup",
126
parser.add_argument('-d', '--dom0-ips',
127
help="IP of dom0's to run cleanup script")
129
return parser.parse_args()
133
dom0_cleanup_script = DOM0_CLEANUP_SCRIPT
137
dom0_ips = args.dom0_ips.split(',')
141
start_time = time.time()
142
batch_size = min(args.num_runs, args.concurrency)
143
pool = multiprocessing.Pool(processes=args.concurrency)
146
for test in args.tests:
147
test_func = globals().get("test_%s" % test)
149
print >> sys.stderr, "test '%s' not found" % test
152
contexts = [(x, args) for x in range(args.num_runs)]
155
results += pool.map(test_func, contexts)
158
for dom0_ip in dom0_ips:
159
run("ssh root@%(dom0_ip)s %(dom0_cleanup_script)s"
162
success = all(results)
163
result = "SUCCESS" if success else "FAILED"
165
duration = time.time() - start_time
166
print "%s, finished in %.2f secs" % (result, duration)
168
sys.exit(0 if success else 1)
171
if __name__ == "__main__":