Revision 2aaa1336 snf-tools/synnefo_tools/burnin.py
b/snf-tools/synnefo_tools/burnin.py | ||
---|---|---|
87 | 87 |
green = '\x1b[32m' |
88 | 88 |
normal = '\x1b[0m' |
89 | 89 |
|
90 |
|
|
91 | 90 |
class burninFormatter(logging.Formatter): |
92 | 91 |
|
93 | 92 |
err_fmt = red + "ERROR: %(msg)s" + normal |
... | ... | |
116 | 115 |
|
117 | 116 |
return result |
118 | 117 |
|
119 |
|
|
120 | 118 |
log = logging.getLogger("burnin") |
121 | 119 |
log.setLevel(logging.DEBUG) |
122 | 120 |
handler = logging.StreamHandler() |
... | ... | |
260 | 258 |
def _get_ipv4(self, server): |
261 | 259 |
"""Get the public IPv4 of a server from the detailed server info""" |
262 | 260 |
|
263 |
public_addrs = filter(lambda x: x["id"] == "public", |
|
264 |
server["addresses"]["values"]) |
|
261 |
public_addrs = filter(lambda x: x["network_id"] == "public", |
|
262 |
server["attachments"]["values"]) |
|
263 |
|
|
265 | 264 |
self.assertEqual(len(public_addrs), 1) |
266 |
ipv4_addrs = filter(lambda x: x["version"] == 4, |
|
267 |
public_addrs[0]["values"])
|
|
268 |
self.assertEqual(len(ipv4_addrs), 1) |
|
269 |
return ipv4_addrs[0]["addr"]
|
|
265 |
|
|
266 |
self.assertTrue(public_addrs[0]['ipv4'] != None)
|
|
267 |
|
|
268 |
return public_addrs[0]['ipv4']
|
|
270 | 269 |
|
271 | 270 |
def _get_ipv6(self, server): |
272 | 271 |
"""Get the public IPv6 of a server from the detailed server info""" |
273 |
public_addrs = filter(lambda x: x["id"] == "public", |
|
274 |
server["addresses"]["values"]) |
|
272 |
|
|
273 |
public_addrs = filter(lambda x: x["network_id"] == "public", |
|
274 |
server["attachments"]["values"]) |
|
275 |
|
|
275 | 276 |
self.assertEqual(len(public_addrs), 1) |
276 |
ipv6_addrs = filter(lambda x: x["version"] == 6, |
|
277 |
public_addrs[0]["values"]) |
|
278 |
self.assertEqual(len(ipv6_addrs), 1) |
|
279 |
return ipv6_addrs[0]["addr"] |
|
277 |
|
|
278 |
self.assertTrue(public_addrs[0]['ipv6'] != None) |
|
279 |
|
|
280 |
return public_addrs[0]['ipv6'] |
|
281 |
|
|
282 |
|
|
280 | 283 |
|
281 | 284 |
def _connect_loginname(self, os): |
282 | 285 |
"""Return the login name for connections based on the server OS""" |
... | ... | |
446 | 449 |
|
447 | 450 |
servers = self.client.list_servers(detail=True) |
448 | 451 |
servers = filter(lambda x: x["name"] == self.servername, servers) |
449 |
self.assertEqual(len(servers), 1) |
|
452 |
|
|
450 | 453 |
server = servers[0] |
451 | 454 |
self.assertEqual(server["name"], self.servername) |
452 | 455 |
self.assertEqual(server["flavorRef"], self.flavorid) |
... | ... | |
506 | 509 |
self._insist_on_status_transition("BUILD", "ACTIVE", |
507 | 510 |
self.build_fail, self.build_warning) |
508 | 511 |
|
509 |
def test_003a_get_server_oob_console(self): |
|
510 |
"""Test getting OOB server console over VNC |
|
512 |
# def test_003a_get_server_oob_console(self):
|
|
513 |
# """Test getting OOB server console over VNC
|
|
511 | 514 |
|
512 |
Implementation of RFB protocol follows |
|
513 |
http://www.realvnc.com/docs/rfbproto.pdf. |
|
515 |
# Implementation of RFB protocol follows
|
|
516 |
# http://www.realvnc.com/docs/rfbproto.pdf.
|
|
514 | 517 |
|
515 |
""" |
|
516 |
console = self.cyclades.get_server_console(self.serverid) |
|
517 |
self.assertEquals(console['type'], "vnc") |
|
518 |
sock = self._insist_on_tcp_connection(socket.AF_INET, |
|
519 |
console["host"], console["port"]) |
|
520 |
|
|
521 |
# Step 1. ProtocolVersion message (par. 6.1.1) |
|
522 |
version = sock.recv(1024) |
|
523 |
self.assertEquals(version, 'RFB 003.008\n') |
|
524 |
sock.send(version) |
|
525 |
|
|
526 |
# Step 2. Security (par 6.1.2): Only VNC Authentication supported |
|
527 |
sec = sock.recv(1024) |
|
528 |
self.assertEquals(list(sec), ['\x01', '\x02']) |
|
529 |
|
|
530 |
# Step 3. Request VNC Authentication (par 6.1.2) |
|
531 |
sock.send('\x02') |
|
532 |
|
|
533 |
# Step 4. Receive Challenge (par 6.2.2) |
|
534 |
challenge = sock.recv(1024) |
|
535 |
self.assertEquals(len(challenge), 16) |
|
536 |
|
|
537 |
# Step 5. DES-Encrypt challenge, use password as key (par 6.2.2) |
|
538 |
response = d3des_generate_response( |
|
539 |
(console["password"] + '\0' * 8)[:8], challenge) |
|
540 |
sock.send(response) |
|
541 |
|
|
542 |
# Step 6. SecurityResult (par 6.1.3) |
|
543 |
result = sock.recv(4) |
|
544 |
self.assertEquals(list(result), ['\x00', '\x00', '\x00', '\x00']) |
|
545 |
sock.close() |
|
518 |
# """
|
|
519 |
# console = self.cyclades.get_server_console(self.serverid)
|
|
520 |
# self.assertEquals(console['type'], "vnc")
|
|
521 |
# sock = self._insist_on_tcp_connection(socket.AF_INET,
|
|
522 |
# console["host"], console["port"])
|
|
523 |
|
|
524 |
# # Step 1. ProtocolVersion message (par. 6.1.1)
|
|
525 |
# version = sock.recv(1024)
|
|
526 |
# self.assertEquals(version, 'RFB 003.008\n')
|
|
527 |
# sock.send(version)
|
|
528 |
|
|
529 |
# # Step 2. Security (par 6.1.2): Only VNC Authentication supported
|
|
530 |
# sec = sock.recv(1024)
|
|
531 |
# self.assertEquals(list(sec), ['\x01', '\x02'])
|
|
532 |
|
|
533 |
# # Step 3. Request VNC Authentication (par 6.1.2)
|
|
534 |
# sock.send('\x02')
|
|
535 |
|
|
536 |
# # Step 4. Receive Challenge (par 6.2.2)
|
|
537 |
# challenge = sock.recv(1024)
|
|
538 |
# self.assertEquals(len(challenge), 16)
|
|
539 |
|
|
540 |
# # Step 5. DES-Encrypt challenge, use password as key (par 6.2.2)
|
|
541 |
# response = d3des_generate_response(
|
|
542 |
# (console["password"] + '\0' * 8)[:8], challenge)
|
|
543 |
# sock.send(response)
|
|
544 |
|
|
545 |
# # Step 6. SecurityResult (par 6.1.3)
|
|
546 |
# result = sock.recv(4)
|
|
547 |
# self.assertEquals(list(result), ['\x00', '\x00', '\x00', '\x00'])
|
|
548 |
# sock.close()
|
|
546 | 549 |
|
547 | 550 |
def test_004_server_has_ipv4(self): |
548 | 551 |
"""Test active server has a valid IPv4 address""" |
... | ... | |
737 | 740 |
def _get_ipv4(self, server): |
738 | 741 |
"""Get the public IPv4 of a server from the detailed server info""" |
739 | 742 |
|
740 |
public_addrs = filter(lambda x: x["id"] == "public", |
|
741 |
server["addresses"]["values"]) |
|
743 |
public_addrs = filter(lambda x: x["network_id"] == "public", |
|
744 |
server["attachments"]["values"]) |
|
745 |
|
|
742 | 746 |
self.assertEqual(len(public_addrs), 1) |
743 |
ipv4_addrs = filter(lambda x: x["version"] == 4, |
|
744 |
public_addrs[0]["values"])
|
|
745 |
self.assertEqual(len(ipv4_addrs), 1) |
|
746 |
return ipv4_addrs[0]["addr"]
|
|
747 |
|
|
748 |
self.assertTrue(public_addrs[0]['ipv4'] != None)
|
|
749 |
|
|
750 |
return public_addrs[0]['ipv4']
|
|
747 | 751 |
|
748 | 752 |
def _connect_loginname(self, os): |
749 | 753 |
"""Return the login name for connections based on the server OS""" |
... | ... | |
852 | 856 |
|
853 | 857 |
name = SNF_TEST_PREFIX + TEST_RUN_ID |
854 | 858 |
previous_num = len(self.client.list_networks()) |
855 |
network = self.client.create_network(name) |
|
859 |
network = self.client.create_network(name,cidr='10.0.0.1/28')
|
|
856 | 860 |
|
857 | 861 |
#Test if right name is assigned |
858 | 862 |
self.assertEqual(network['name'], name) |
... | ... | |
862 | 866 |
cls.networkid = network['id'] |
863 | 867 |
networks = self.client.list_networks() |
864 | 868 |
|
869 |
fail_tmout = time.time() + self.action_timeout |
|
870 |
|
|
865 | 871 |
#Test if new network is created |
866 |
self.assertTrue(len(networks) > previous_num) |
|
872 |
while True: |
|
873 |
d = self.client.get_network_details(network['id']) |
|
874 |
if d['status'] == 'ACTIVE': |
|
875 |
connected = True |
|
876 |
break |
|
877 |
elif time.time() > fail_tmout: |
|
878 |
self.assertLess(time.time(), fail_tmout) |
|
879 |
else: |
|
880 |
log.info("Waiting for network to become ACTIVE") |
|
881 |
time.sleep(self.query_interval) |
|
882 |
|
|
883 |
self.assertTrue(connected) |
|
867 | 884 |
|
868 | 885 |
def test_002_connect_to_network(self): |
869 | 886 |
"""Test connect VMs to network""" |
... | ... | |
877 | 894 |
fail_tmout = time.time() + self.action_timeout |
878 | 895 |
|
879 | 896 |
while True: |
880 |
connected = (self.client.get_network_details(self.networkid)) |
|
881 |
connections = connected['servers']['values'] |
|
882 |
if (self.serverid['A'] in connections) \ |
|
883 |
and (self.serverid['B'] in connections): |
|
897 |
|
|
898 |
netsA=[x['network_id'] for x in self.client.get_server_details(self.serverid['A'])['attachments']['values']] |
|
899 |
netsB=[x['network_id'] for x in self.client.get_server_details(self.serverid['B'])['attachments']['values']] |
|
900 |
|
|
901 |
if (self.networkid in netsA) and (self.networkid in netsB): |
|
884 | 902 |
conn_exists = True |
885 | 903 |
break |
886 | 904 |
elif time.time() > fail_tmout: |
... | ... | |
1042 | 1060 |
user=loginname, password=myPass |
1043 | 1061 |
): |
1044 | 1062 |
|
1045 |
if len(sudo('ifconfig eth1 192.168.0.12')) == 0:
|
|
1063 |
if len(sudo('ifconfig eth1 10.0.0.5')) == 0:
|
|
1046 | 1064 |
res = True |
1047 | 1065 |
|
1048 | 1066 |
else: |
... | ... | |
1053 | 1071 |
user=loginname, password=myPass |
1054 | 1072 |
): |
1055 | 1073 |
|
1056 |
if len(run('ifconfig eth1 192.168.0.12')) == 0:
|
|
1074 |
if len(run('ifconfig eth1 10.0.0.5')) == 0:
|
|
1057 | 1075 |
res = True |
1058 | 1076 |
|
1059 | 1077 |
self.assertTrue(res) |
... | ... | |
1094 | 1112 |
user=loginname, password=myPass |
1095 | 1113 |
): |
1096 | 1114 |
|
1097 |
if len(sudo('ifconfig eth1 192.168.0.13')) == 0:
|
|
1115 |
if len(sudo('ifconfig eth1 10.0.0.6')) == 0:
|
|
1098 | 1116 |
res = True |
1099 | 1117 |
|
1100 | 1118 |
else: |
... | ... | |
1105 | 1123 |
user=loginname, password=myPass |
1106 | 1124 |
): |
1107 | 1125 |
|
1108 |
if len(run('ifconfig eth1 192.168.0.13')) == 0:
|
|
1126 |
if len(run('ifconfig eth1 10.0.0.6')) == 0:
|
|
1109 | 1127 |
res = True |
1110 | 1128 |
|
1111 | 1129 |
self.assertTrue(res) |
... | ... | |
1141 | 1159 |
except socket.error: |
1142 | 1160 |
raise AssertionError |
1143 | 1161 |
|
1144 |
cmd = "if ping -c 2 -w 3 192.168.0.13 >/dev/null; \
|
|
1162 |
cmd = "if ping -c 2 -w 3 10.0.0.6 >/dev/null; \
|
|
1145 | 1163 |
then echo \'True\'; fi;" |
1146 | 1164 |
stdin, stdout, stderr = ssh.exec_command(cmd) |
1147 | 1165 |
lines = stdout.readlines() |
... | ... | |
1159 | 1177 |
log.info("Disconnecting servers from private network") |
1160 | 1178 |
|
1161 | 1179 |
prev_state = self.client.get_network_details(self.networkid) |
1162 |
prev_conn = len(prev_state['servers']['values']) |
|
1180 |
prev_nics = prev_state['attachments']['values'] |
|
1181 |
prev_conn = len(prev_nics) |
|
1182 |
|
|
1183 |
nicsA=[x['id'] for x in self.client.get_server_details(self.serverid['A'])['attachments']['values']] |
|
1184 |
nicsB=[x['id'] for x in self.client.get_server_details(self.serverid['B'])['attachments']['values']] |
|
1185 |
|
|
1186 |
for nic in prev_nics: |
|
1187 |
if nic in nicsA: |
|
1188 |
self.client.disconnect_server(self.serverid['A'], nic) |
|
1189 |
if nic in nicsB: |
|
1190 |
self.client.disconnect_server(self.serverid['B'], nic) |
|
1163 | 1191 |
|
1164 |
self.client.disconnect_server(self.serverid['A'], self.networkid) |
|
1165 |
self.client.disconnect_server(self.serverid['B'], self.networkid) |
|
1166 | 1192 |
|
1167 | 1193 |
#Insist on deleting until action timeout |
1168 | 1194 |
fail_tmout = time.time() + self.action_timeout |
1169 | 1195 |
|
1170 | 1196 |
while True: |
1197 |
|
|
1198 |
netsA=[x['network_id'] for x in self.client.get_server_details(self.serverid['A'])['attachments']['values']] |
|
1199 |
netsB=[x['network_id'] for x in self.client.get_server_details(self.serverid['B'])['attachments']['values']] |
|
1200 |
|
|
1201 |
|
|
1171 | 1202 |
connected = (self.client.get_network_details(self.networkid)) |
1172 |
connections = connected['servers']['values'] |
|
1173 |
if ((self.serverid['A'] not in connections) and |
|
1174 |
(self.serverid['B'] not in connections)): |
|
1203 |
connections = connected['attachments']['values'] |
|
1204 |
if (self.networkid not in netsA) and (self.networkid not in netsB): |
|
1175 | 1205 |
conn_exists = False |
1176 | 1206 |
break |
1177 | 1207 |
elif time.time() > fail_tmout: |
... | ... | |
1187 | 1217 |
log.info("Submitting delete network request") |
1188 | 1218 |
|
1189 | 1219 |
self.client.delete_network(self.networkid) |
1190 |
networks = self.client.list_networks() |
|
1220 |
|
|
1221 |
fail_tmout = time.time() + self.action_timeout |
|
1222 |
|
|
1223 |
while True: |
|
1191 | 1224 |
|
1192 |
curr_net = [] |
|
1193 |
for net in networks: |
|
1194 |
curr_net.append(net['id']) |
|
1225 |
curr_net = [] |
|
1226 |
networks = self.client.list_networks() |
|
1227 |
|
|
1228 |
for net in networks: |
|
1229 |
curr_net.append(net['id']) |
|
1230 |
|
|
1231 |
if self.networkid not in curr_net: |
|
1232 |
self.assertTrue(self.networkid not in curr_net) |
|
1233 |
break |
|
1195 | 1234 |
|
1196 |
self.assertTrue(self.networkid not in curr_net) |
|
1235 |
elif time.time() > fail_tmout: |
|
1236 |
self.assertLess(time.time(), fail_tmout) |
|
1237 |
|
|
1238 |
else: |
|
1239 |
time.sleep(self.query_interval) |
|
1240 |
|
|
1241 |
|
|
1197 | 1242 |
|
1198 | 1243 |
def test_006_cleanup_servers(self): |
1199 | 1244 |
"""Cleanup servers created for this test""" |
... | ... | |
1230 | 1275 |
Process.__init__(self, **kw) |
1231 | 1276 |
kwargs = kw["kwargs"] |
1232 | 1277 |
self.testq = kwargs["testq"] |
1233 |
self.runner = kwargs["runner"]
|
|
1278 |
self.worker_folder = kwargs["worker_folder"]
|
|
1234 | 1279 |
|
1235 | 1280 |
def run(self): |
1236 | 1281 |
# Make sure this test runner process dies with the parent |
... | ... | |
1238 | 1283 |
# |
1239 | 1284 |
# WARNING: This uses the prctl(2) call and is |
1240 | 1285 |
# Linux-specific. |
1286 |
|
|
1241 | 1287 |
prctl.set_pdeathsig(signal.SIGHUP) |
1242 | 1288 |
|
1289 |
multi = logging.getLogger("multiprocess") |
|
1290 |
|
|
1243 | 1291 |
while True: |
1244 |
log.debug("I am process %d, GETting from queue is %s",
|
|
1245 |
os.getpid(), self.testq)
|
|
1292 |
multi.debug("I am process %d, GETting from queue is %s" %
|
|
1293 |
(os.getpid(), self.testq))
|
|
1246 | 1294 |
msg = self.testq.get() |
1247 |
log.debug("Dequeued msg: %s", msg) |
|
1295 |
|
|
1296 |
multi.debug("Dequeued msg: %s" % msg) |
|
1248 | 1297 |
|
1249 | 1298 |
if msg == "TEST_RUNNER_TERMINATE": |
1250 | 1299 |
raise SystemExit |
1300 |
|
|
1251 | 1301 |
elif issubclass(msg, unittest.TestCase): |
1252 | 1302 |
# Assemble a TestSuite, and run it |
1303 |
|
|
1304 |
log_file = os.path.join(self.worker_folder, 'details_' + |
|
1305 |
(msg.__name__) + "_" + |
|
1306 |
TEST_RUN_ID + '.log') |
|
1307 |
|
|
1308 |
fail_file = os.path.join(self.worker_folder, 'failed_' + |
|
1309 |
(msg.__name__) + "_" + |
|
1310 |
TEST_RUN_ID + '.log') |
|
1311 |
error_file = os.path.join(self.worker_folder, 'error_' + |
|
1312 |
(msg.__name__) + "_" + |
|
1313 |
TEST_RUN_ID + '.log') |
|
1314 |
|
|
1315 |
f = open(log_file, 'w') |
|
1316 |
fail = open(fail_file,'w') |
|
1317 |
error = open(error_file, 'w') |
|
1318 |
|
|
1319 |
log.info(yellow + '* Starting testcase: %s' % msg + normal) |
|
1320 |
|
|
1321 |
runner = unittest.TextTestRunner(f, verbosity=2, failfast = True) |
|
1253 | 1322 |
suite = unittest.TestLoader().loadTestsFromTestCase(msg) |
1254 |
self.runner.run(suite) |
|
1323 |
result = runner.run(suite) |
|
1324 |
|
|
1325 |
for res in result.errors: |
|
1326 |
log.error("snf-burnin encountered an error in " \ |
|
1327 |
"testcase: %s" %msg) |
|
1328 |
log.error("See log for details") |
|
1329 |
error.write(str(res[0]) + '\n') |
|
1330 |
error.write(str(res[0].shortDescription()) + '\n') |
|
1331 |
error.write('\n') |
|
1332 |
|
|
1333 |
for res in result.failures: |
|
1334 |
log.error("snf-burnin failed in testcase: %s" %msg) |
|
1335 |
log.error("See log for details") |
|
1336 |
fail.write(str(res[0]) + '\n') |
|
1337 |
fail.write(str(res[0].shortDescription()) + '\n') |
|
1338 |
fail.write('\n') |
|
1339 |
if NOFAILFAST == False: |
|
1340 |
sys.exit() |
|
1341 |
|
|
1342 |
if (len(result.failures) == 0) and (len(result.errors) == 0): |
|
1343 |
log.debug("Passed testcase: %s" %msg) |
|
1344 |
|
|
1345 |
f.close() |
|
1346 |
fail.close() |
|
1347 |
error.close() |
|
1348 |
|
|
1349 |
|
|
1255 | 1350 |
else: |
1256 | 1351 |
raise Exception("Cannot handle msg: %s" % msg) |
1257 | 1352 |
|
1258 | 1353 |
|
1259 |
def _run_cases_in_parallel(cases, fanout=1, runner=None):
|
|
1354 |
def _run_cases_in_parallel(cases, fanout, image_folder):
|
|
1260 | 1355 |
"""Run instances of TestCase in parallel, in a number of distinct processes |
1261 | 1356 |
|
1262 | 1357 |
The cases iterable specifies the TestCases to be executed in parallel, |
... | ... | |
1267 | 1362 |
runner process. |
1268 | 1363 |
|
1269 | 1364 |
""" |
1270 |
if runner is None: |
|
1271 |
runner = unittest.TextTestRunner(verbosity=2, failfast=True) |
|
1365 |
|
|
1366 |
multi = logging.getLogger("multiprocess") |
|
1367 |
handler = logging.StreamHandler() |
|
1368 |
multi.addHandler(handler) |
|
1272 | 1369 |
|
1273 |
# testq: The master process enqueues TestCase objects into this queue, |
|
1274 |
# test runner processes pick them up for execution, in parallel. |
|
1275 |
testq = Queue() |
|
1370 |
if VERBOSE: |
|
1371 |
multi.setLevel(logging.DEBUG) |
|
1372 |
else: |
|
1373 |
multi.setLevel(logging.INFO) |
|
1374 |
|
|
1375 |
testq = [] |
|
1376 |
worker_folder = [] |
|
1276 | 1377 |
runners = [] |
1378 |
|
|
1379 |
for i in xrange(0,fanout): |
|
1380 |
testq.append(Queue()) |
|
1381 |
worker_folder.append(os.path.join(image_folder, 'process'+str(i))) |
|
1382 |
os.mkdir(worker_folder[i]) |
|
1383 |
|
|
1277 | 1384 |
for i in xrange(0, fanout): |
1278 |
kwargs = dict(testq=testq, runner=runner)
|
|
1385 |
kwargs = dict(testq=testq[i], worker_folder=worker_folder[i])
|
|
1279 | 1386 |
runners.append(TestRunnerProcess(kwargs=kwargs)) |
1280 | 1387 |
|
1281 |
log.info("Spawning %d test runner processes", len(runners)) |
|
1388 |
multi.debug("Spawning %d test runner processes" %len(runners)) |
|
1389 |
|
|
1282 | 1390 |
for p in runners: |
1283 | 1391 |
p.start() |
1284 |
log.debug("Spawned %d test runners, PIDs are %s", |
|
1285 |
len(runners), [p.pid for p in runners]) |
|
1286 | 1392 |
|
1287 | 1393 |
# Enqueue test cases |
1288 |
map(testq.put, cases) |
|
1289 |
map(testq.put, ["TEST_RUNNER_TERMINATE"] * len(runners)) |
|
1394 |
for i in xrange(0, fanout): |
|
1395 |
map(testq[i].put, cases) |
|
1396 |
testq[i].put("TEST_RUNNER_TERMINATE") |
|
1397 |
|
|
1398 |
multi.debug("Spawned %d test runners, PIDs are %s" % |
|
1399 |
(len(runners), [p.pid for p in runners])) |
|
1290 | 1400 |
|
1291 |
log.debug("Joining %d processes", len(runners)) |
|
1401 |
multi.debug("Joining %d processes" % len(runners)) |
|
1402 |
|
|
1292 | 1403 |
for p in runners: |
1293 | 1404 |
p.join() |
1294 |
log.debug("Done joining %d processes", len(runners)) |
|
1405 |
|
|
1406 |
multi.debug("Done joining %d processes" % len(runners)) |
|
1295 | 1407 |
|
1296 | 1408 |
|
1297 | 1409 |
def _spawn_server_test_case(**kwargs): |
... | ... | |
1308 | 1420 |
|
1309 | 1421 |
# Make sure the class can be pickled, by listing it among |
1310 | 1422 |
# the attributes of __main__. A PicklingError is raised otherwise. |
1311 |
setattr(__main__, name, cls) |
|
1423 |
|
|
1424 |
thismodule = sys.modules[__name__] |
|
1425 |
setattr(thismodule, name, cls) |
|
1312 | 1426 |
return cls |
1313 | 1427 |
|
1314 | 1428 |
|
... | ... | |
1320 | 1434 |
|
1321 | 1435 |
# Make sure the class can be pickled, by listing it among |
1322 | 1436 |
# the attributes of __main__. A PicklingError is raised otherwise. |
1323 |
setattr(__main__, name, cls) |
|
1437 |
|
|
1438 |
thismodule = sys.modules[__name__] |
|
1439 |
setattr(thismodule, name, cls) |
|
1324 | 1440 |
return cls |
1325 | 1441 |
|
1326 | 1442 |
|
... | ... | |
1347 | 1463 |
print >> sys.stderr, "Use --delete-stale to delete them." |
1348 | 1464 |
|
1349 | 1465 |
|
1350 |
def cleanup_networks(delete_stale=False): |
|
1466 |
def cleanup_networks(action_timeout, query_interval,delete_stale=False): |
|
1467 |
def isSnfTest(s): |
|
1468 |
if s.find(SNF_TEST_PREFIX) == -1: |
|
1469 |
return False |
|
1470 |
else: |
|
1471 |
return True |
|
1351 | 1472 |
|
1352 | 1473 |
c = CycladesClient(API, TOKEN) |
1353 |
|
|
1474 |
|
|
1354 | 1475 |
networks = c.list_networks() |
1355 | 1476 |
stale = [n for n in networks if n["name"].startswith(SNF_TEST_PREFIX)] |
1356 | 1477 |
|
1357 | 1478 |
if len(stale) == 0: |
1358 | 1479 |
return |
1480 |
|
|
1481 |
fail_tmout = time.time() + action_timeout |
|
1482 |
while True: |
|
1483 |
servers = c.list_servers() |
|
1484 |
staleServers = [s for s in servers if s["name"].startswith(SNF_TEST_PREFIX)] |
|
1485 |
if len(staleServers) == 0: |
|
1486 |
break |
|
1487 |
elif time.time() > fail_tmout: |
|
1488 |
log.error("Stale servers not deleted from previous run") |
|
1489 |
sys.exit() |
|
1490 |
else: |
|
1491 |
time.sleep(query_interval) |
|
1359 | 1492 |
|
1360 | 1493 |
print >> sys.stderr, yellow + "Found these stale networks from previous runs:" + normal |
1361 | 1494 |
print " " + \ |
... | ... | |
1480 | 1613 |
help="Define the absolute path where the output \ |
1481 | 1614 |
log is stored. ", |
1482 | 1615 |
default="/var/log/burnin/") |
1616 |
parser.add_option("--verbose", "-V", |
|
1617 |
action="store_true", dest="verbose", |
|
1618 |
help="Print detailed output about multiple processes spawning", |
|
1619 |
default=False) |
|
1483 | 1620 |
parser.add_option("--set-tests", |
1484 | 1621 |
action="callback", |
1485 | 1622 |
dest="tests", |
... | ... | |
1492 | 1629 |
default='all', |
1493 | 1630 |
callback=parse_comma) |
1494 | 1631 |
|
1495 |
# FIXME: Change the default for build-fanout to 10 |
|
1496 |
# FIXME: Allow the user to specify a specific set of Images to test |
|
1497 |
|
|
1498 | 1632 |
(opts, args) = parser.parse_args(args) |
1499 | 1633 |
|
1500 | 1634 |
# Verify arguments |
... | ... | |
1538 | 1672 |
|
1539 | 1673 |
(opts, args) = parse_arguments(sys.argv[1:]) |
1540 | 1674 |
|
1541 |
global API, TOKEN, PLANKTON, PLANKTON_USER, NO_IPV6 |
|
1675 |
global API, TOKEN, PLANKTON, PLANKTON_USER, NO_IPV6, VERBOSE, NOFAILFAST
|
|
1542 | 1676 |
API = opts.api |
1543 | 1677 |
TOKEN = opts.token |
1544 | 1678 |
PLANKTON = opts.plankton |
1545 | 1679 |
PLANKTON_USER = opts.plankton_user |
1546 | 1680 |
NO_IPV6 = opts.no_ipv6 |
1681 |
VERBOSE = opts.verbose |
|
1682 |
NOFAILFAST = opts.nofailfast |
|
1547 | 1683 |
|
1548 | 1684 |
# Cleanup stale servers from previous runs |
1549 | 1685 |
if opts.show_stale: |
1550 | 1686 |
cleanup_servers(delete_stale=opts.delete_stale) |
1551 |
cleanup_networks(delete_stale=opts.delete_stale) |
|
1687 |
cleanup_networks(opts.action_timeout, opts.query_interval, delete_stale=opts.delete_stale)
|
|
1552 | 1688 |
return 0 |
1553 | 1689 |
|
1554 | 1690 |
# Initialize a kamaki instance, get flavors, images |
... | ... | |
1616 | 1752 |
query_interval=opts.query_interval, |
1617 | 1753 |
) |
1618 | 1754 |
|
1755 |
|
|
1619 | 1756 |
NetworkTestCase = _spawn_network_test_case( |
1620 | 1757 |
action_timeout=opts.action_timeout, |
1621 | 1758 |
imageid=imageid, |
... | ... | |
1643 | 1780 |
image_folder = os.path.join(test_folder, imageid) |
1644 | 1781 |
os.mkdir(image_folder) |
1645 | 1782 |
|
1646 |
for case in seq_cases: |
|
1647 |
|
|
1648 |
test = (key for key, value in test_dict.items() |
|
1649 |
if value == case).next() |
|
1650 |
|
|
1651 |
log.info(yellow + '* Starting testcase: %s' %test + normal) |
|
1652 |
log_file = os.path.join(image_folder, 'details_' + |
|
1653 |
(case.__name__) + "_" + |
|
1654 |
TEST_RUN_ID + '.log') |
|
1655 |
fail_file = os.path.join(image_folder, 'failed_' + |
|
1656 |
(case.__name__) + "_" + |
|
1657 |
TEST_RUN_ID + '.log') |
|
1658 |
error_file = os.path.join(image_folder, 'error_' + |
|
1659 |
(case.__name__) + "_" + |
|
1660 |
TEST_RUN_ID + '.log') |
|
1661 |
|
|
1662 |
f = open(log_file, "w") |
|
1663 |
fail = open(fail_file, "w") |
|
1664 |
error = open(error_file, "w") |
|
1665 |
|
|
1666 |
suite = unittest.TestLoader().loadTestsFromTestCase(case) |
|
1667 |
runner = unittest.TextTestRunner(f, verbosity=2, failfast=True) |
|
1668 |
result = runner.run(suite) |
|
1669 |
|
|
1670 |
for res in result.errors: |
|
1671 |
log.error("snf-burnin encountered an error in " \ |
|
1672 |
"testcase: %s" %test) |
|
1673 |
log.error("See log for details") |
|
1674 |
error.write(str(res[0]) + '\n') |
|
1675 |
error.write(str(res[0].shortDescription()) + '\n') |
|
1676 |
error.write('\n') |
|
1677 |
|
|
1678 |
for res in result.failures: |
|
1679 |
log.error("snf-burnin failed in testcase: %s" %test) |
|
1680 |
log.error("See log for details") |
|
1681 |
fail.write(str(res[0]) + '\n') |
|
1682 |
fail.write(str(res[0].shortDescription()) + '\n') |
|
1683 |
fail.write('\n') |
|
1684 |
if opts.nofailfast == False: |
|
1685 |
sys.exit() |
|
1686 |
|
|
1687 |
if (len(result.failures) == 0) and (len(result.errors) == 0): |
|
1688 |
log.debug("Passed testcase: %s" %test) |
|
1783 |
log.info('Parallel spawn:') |
|
1784 |
|
|
1785 |
_run_cases_in_parallel(seq_cases, opts.fanout, image_folder) |
|
1689 | 1786 |
|
1690 | 1787 |
if __name__ == "__main__": |
1691 | 1788 |
sys.exit(main()) |
Also available in: Unified diff