Revision 6e168615 snf-tools/synnefo_tools/burnin.py
b/snf-tools/synnefo_tools/burnin.py | ||
---|---|---|
35 | 35 |
|
36 | 36 |
"""Perform integration testing on a running Synnefo deployment""" |
37 | 37 |
|
38 |
import __main__ |
|
38 |
#import __main__
|
|
39 | 39 |
import datetime |
40 | 40 |
import inspect |
41 | 41 |
import logging |
... | ... | |
58 | 58 |
from kamaki.clients.image import ImageClient |
59 | 59 |
from kamaki.clients import ClientError |
60 | 60 |
|
61 |
from fabric.api import *
|
|
61 |
import fabric.api as fabric
|
|
62 | 62 |
|
63 | 63 |
from vncauthproxy.d3des import generate_response as d3des_generate_response |
64 | 64 |
|
... | ... | |
70 | 70 |
raise Exception("The unittest2 package is required for Python < 2.7") |
71 | 71 |
import unittest |
72 | 72 |
|
73 |
# -------------------------------------------------------------------- |
|
74 |
# Global Variables |
|
75 |
API = None |
|
76 |
TOKEN = None |
|
77 |
PLANKTON = None |
|
78 |
PLANKTON_USER = None |
|
79 |
NO_IPV6 = None |
|
80 |
DEFAULT_API = "https://cyclades.okeanos.grnet.gr/api/v1.1" |
|
81 |
DEFAULT_PLANKTON = "https://cyclades.okeanos.grnet.gr/plankton" |
|
82 |
DEFAULT_PLANKTON_USER = "images@okeanos.grnet.gr" |
|
83 |
NOFAILFAST = None |
|
84 |
VERBOSE = None |
|
85 |
|
|
86 |
# A unique id identifying this test run |
|
87 |
TEST_RUN_ID = datetime.datetime.strftime(datetime.datetime.now(), |
|
88 |
"%Y%m%d%H%M%S") |
|
89 |
SNF_TEST_PREFIX = "snf-test-" |
|
90 |
|
|
91 |
red = '\x1b[31m' |
|
92 |
yellow = '\x1b[33m' |
|
93 |
green = '\x1b[32m' |
|
94 |
normal = '\x1b[0m' |
|
95 |
|
|
73 | 96 |
|
97 |
# -------------------------------------------------------------------- |
|
98 |
# BurninTestReulst class |
|
74 | 99 |
class BurninTestResult(unittest.TextTestResult): |
75 | 100 |
def addSuccess(self, test): |
76 | 101 |
super(BurninTestResult, self).addSuccess(test) |
... | ... | |
85 | 110 |
|
86 | 111 |
elif self.dots: |
87 | 112 |
self.stream.write('.') |
88 |
self.stream.flush()
|
|
89 |
|
|
113 |
self.stream.flush() |
|
114 |
|
|
90 | 115 |
def addError(self, test, err): |
91 | 116 |
super(BurninTestResult, self).addError(test, err) |
92 | 117 |
if self.showAll: |
... | ... | |
120 | 145 |
self.stream.flush() |
121 | 146 |
|
122 | 147 |
|
123 |
|
|
124 |
API = None |
|
125 |
TOKEN = None |
|
126 |
DEFAULT_API = "https://cyclades.okeanos.grnet.gr/api/v1.1" |
|
127 |
DEFAULT_PLANKTON = "https://cyclades.okeanos.grnet.gr/plankton" |
|
128 |
DEFAULT_PLANKTON_USER = "images@okeanos.grnet.gr" |
|
129 |
|
|
130 |
# A unique id identifying this test run |
|
131 |
TEST_RUN_ID = datetime.datetime.strftime(datetime.datetime.now(), |
|
132 |
"%Y%m%d%H%M%S") |
|
133 |
SNF_TEST_PREFIX = "snf-test-" |
|
134 |
|
|
135 |
red = '\x1b[31m' |
|
136 |
yellow = '\x1b[33m' |
|
137 |
green = '\x1b[32m' |
|
138 |
normal = '\x1b[0m' |
|
139 |
|
|
148 |
# -------------------------------------------------------------------- |
|
149 |
# Format Results |
|
140 | 150 |
class burninFormatter(logging.Formatter): |
141 |
|
|
142 | 151 |
err_fmt = red + "ERROR: %(msg)s" + normal |
143 | 152 |
dbg_fmt = green + "* %(msg)s" + normal |
144 | 153 |
info_fmt = "%(msg)s" |
... | ... | |
147 | 156 |
logging.Formatter.__init__(self, fmt) |
148 | 157 |
|
149 | 158 |
def format(self, record): |
150 |
|
|
151 | 159 |
format_orig = self._fmt |
152 |
|
|
153 | 160 |
# Replace the original format with one customized by logging level |
154 | 161 |
if record.levelno == 10: # DEBUG |
155 | 162 |
self._fmt = burninFormatter.dbg_fmt |
156 |
|
|
157 | 163 |
elif record.levelno == 20: # INFO |
158 | 164 |
self._fmt = burninFormatter.info_fmt |
159 |
|
|
160 | 165 |
elif record.levelno == 40: # ERROR |
161 | 166 |
self._fmt = burninFormatter.err_fmt |
162 |
|
|
163 | 167 |
result = logging.Formatter.format(self, record) |
164 | 168 |
self._fmt = format_orig |
165 |
|
|
166 | 169 |
return result |
167 | 170 |
|
168 | 171 |
log = logging.getLogger("burnin") |
... | ... | |
172 | 175 |
log.addHandler(handler) |
173 | 176 |
|
174 | 177 |
|
178 |
# -------------------------------------------------------------------- |
|
179 |
# UnauthorizedTestCase class |
|
175 | 180 |
class UnauthorizedTestCase(unittest.TestCase): |
176 |
|
|
181 |
"""Test unauthorized access""" |
|
177 | 182 |
@classmethod |
178 | 183 |
def setUpClass(cls): |
179 | 184 |
cls.result_dict = dict() |
... | ... | |
181 | 186 |
def test_unauthorized_access(self): |
182 | 187 |
"""Test access without a valid token fails""" |
183 | 188 |
log.info("Authentication test") |
184 |
|
|
185 | 189 |
falseToken = '12345' |
186 | 190 |
c = ComputeClient(API, falseToken) |
187 | 191 |
|
... | ... | |
190 | 194 |
self.assertEqual(cm.exception.status, 401) |
191 | 195 |
|
192 | 196 |
|
197 |
# -------------------------------------------------------------------- |
|
198 |
# ImagesTestCase class |
|
193 | 199 |
class ImagesTestCase(unittest.TestCase): |
194 | 200 |
"""Test image lists for consistency""" |
195 | 201 |
@classmethod |
196 | 202 |
def setUpClass(cls): |
197 | 203 |
"""Initialize kamaki, get (detailed) list of images""" |
198 | 204 |
log.info("Getting simple and detailed list of images") |
199 |
|
|
200 | 205 |
cls.client = ComputeClient(API, TOKEN) |
201 | 206 |
cls.plankton = ImageClient(PLANKTON, TOKEN) |
202 | 207 |
cls.images = cls.plankton.list_public() |
... | ... | |
232 | 237 |
self.assertTrue(keys.issubset(i["metadata"]["values"].keys())) |
233 | 238 |
|
234 | 239 |
|
240 |
# -------------------------------------------------------------------- |
|
241 |
# FlavorsTestCase class |
|
235 | 242 |
class FlavorsTestCase(unittest.TestCase): |
236 | 243 |
"""Test flavor lists for consistency""" |
237 | 244 |
@classmethod |
238 | 245 |
def setUpClass(cls): |
239 | 246 |
"""Initialize kamaki, get (detailed) list of flavors""" |
240 | 247 |
log.info("Getting simple and detailed list of flavors") |
241 |
|
|
242 | 248 |
cls.client = ComputeClient(API, TOKEN) |
243 | 249 |
cls.flavors = cls.client.list_flavors() |
244 | 250 |
cls.dflavors = cls.client.list_flavors(detail=True) |
... | ... | |
265 | 271 |
|
266 | 272 |
def test_005_well_formed_flavor_names(self): |
267 | 273 |
"""Test flavors have names of the form CxxRyyDzz |
268 |
|
|
269 | 274 |
Where xx is vCPU count, yy is RAM in MiB, zz is Disk in GiB |
270 |
|
|
271 | 275 |
""" |
272 | 276 |
for f in self.dflavors: |
273 | 277 |
self.assertEqual("C%dR%dD%d" % (f["cpu"], f["ram"], f["disk"]), |
... | ... | |
275 | 279 |
"Flavor %s does not match its specs." % f["name"]) |
276 | 280 |
|
277 | 281 |
|
282 |
# -------------------------------------------------------------------- |
|
283 |
# ServersTestCase class |
|
278 | 284 |
class ServersTestCase(unittest.TestCase): |
279 | 285 |
"""Test server lists for consistency""" |
280 | 286 |
@classmethod |
... | ... | |
309 | 315 |
@classmethod |
310 | 316 |
def setUpClass(cls): |
311 | 317 |
"""Initialize a kamaki instance""" |
312 |
log.info("Spawning server for image `%s'" %cls.imagename) |
|
318 |
log.info("Spawning server for image `%s'" % cls.imagename)
|
|
313 | 319 |
cls.client = ComputeClient(API, TOKEN) |
314 | 320 |
cls.cyclades = CycladesClient(API, TOKEN) |
315 | 321 |
cls.result_dict = dict() |
... | ... | |
321 | 327 |
|
322 | 328 |
for nic in nics: |
323 | 329 |
net_id = nic["network_id"] |
324 |
if self.cyclades.get_network_details(net_id)["public"] == True:
|
|
330 |
if self.cyclades.get_network_details(net_id)["public"]: |
|
325 | 331 |
public_addrs = nic["ipv4"] |
326 |
|
|
327 |
self.assertTrue(public_addrs != None)
|
|
332 |
|
|
333 |
self.assertTrue(public_addrs is not None)
|
|
328 | 334 |
|
329 | 335 |
return public_addrs |
330 | 336 |
|
... | ... | |
335 | 341 |
|
336 | 342 |
for nic in nics: |
337 | 343 |
net_id = nic["network_id"] |
338 |
if self.cyclades.get_network_details(net_id)["public"] == True:
|
|
344 |
if self.cyclades.get_network_details(net_id)["public"]: |
|
339 | 345 |
public_addrs = nic["ipv6"] |
340 |
|
|
341 |
self.assertTrue(public_addrs != None) |
|
342 | 346 |
|
343 |
return public_addrs
|
|
347 |
self.assertTrue(public_addrs is not None)
|
|
344 | 348 |
|
349 |
return public_addrs |
|
345 | 350 |
|
346 |
def _connect_loginname(self, os): |
|
351 |
def _connect_loginname(self, os_value):
|
|
347 | 352 |
"""Return the login name for connections based on the server OS""" |
348 |
if os in ("Ubuntu", "Kubuntu", "Fedora"): |
|
353 |
if os_value in ("Ubuntu", "Kubuntu", "Fedora"):
|
|
349 | 354 |
return "user" |
350 |
elif os in ("windows", "windows_alpha1"): |
|
355 |
elif os_value in ("windows", "windows_alpha1"):
|
|
351 | 356 |
return "Administrator" |
352 | 357 |
else: |
353 | 358 |
return "root" |
... | ... | |
368 | 373 |
af, socktype, proto, canonname, sa = res |
369 | 374 |
try: |
370 | 375 |
sock = socket.socket(af, socktype, proto) |
371 |
except socket.error as msg:
|
|
376 |
except socket.error: |
|
372 | 377 |
sock = None |
373 | 378 |
continue |
374 | 379 |
try: |
375 | 380 |
sock.connect(sa) |
376 |
except socket.error as msg:
|
|
381 |
except socket.error: |
|
377 | 382 |
sock.close() |
378 | 383 |
sock = None |
379 | 384 |
continue |
... | ... | |
426 | 431 |
msg = "connect over %s to %s:%s" % \ |
427 | 432 |
(familystr.get(family, "Unknown"), host, port) |
428 | 433 |
sock = self._try_until_timeout_expires( |
429 |
self.action_timeout, self.action_timeout,
|
|
430 |
msg, self._get_connected_tcp_socket,
|
|
431 |
family, host, port)
|
|
434 |
self.action_timeout, self.action_timeout, |
|
435 |
msg, self._get_connected_tcp_socket, |
|
436 |
family, host, port) |
|
432 | 437 |
return sock |
433 | 438 |
|
434 | 439 |
def _insist_on_status_transition(self, current_status, new_status, |
435 |
fail_timeout, warn_timeout=None): |
|
440 |
fail_timeout, warn_timeout=None):
|
|
436 | 441 |
msg = "Server %d: `%s', waiting for %s -> %s" % \ |
437 | 442 |
(self.serverid, self.servername, current_status, new_status) |
438 | 443 |
if warn_timeout is None: |
... | ... | |
447 | 452 |
def _insist_on_ssh_hostname(self, hostip, username, password): |
448 | 453 |
msg = "SSH to %s, as %s/%s" % (hostip, username, password) |
449 | 454 |
hostname = self._try_until_timeout_expires( |
450 |
self.action_timeout, self.action_timeout,
|
|
451 |
msg, self._get_hostname_over_ssh,
|
|
452 |
hostip, username, password)
|
|
455 |
self.action_timeout, self.action_timeout, |
|
456 |
msg, self._get_hostname_over_ssh, |
|
457 |
hostip, username, password) |
|
453 | 458 |
|
454 | 459 |
# The hostname must be of the form 'prefix-id' |
455 | 460 |
self.assertTrue(hostname.endswith("-%d\n" % self.serverid)) |
... | ... | |
539 | 544 |
log.info("Creating server metadata") |
540 | 545 |
|
541 | 546 |
image = self.client.get_image_details(self.imageid) |
542 |
os = image["metadata"]["values"]["os"] |
|
547 |
os_value = image["metadata"]["values"]["os"]
|
|
543 | 548 |
users = image["metadata"]["values"].get("users", None) |
544 |
self.client.update_server_metadata(self.serverid, OS=os) |
|
549 |
self.client.update_server_metadata(self.serverid, OS=os_value)
|
|
545 | 550 |
|
546 | 551 |
userlist = users.split() |
547 | 552 |
|
... | ... | |
551 | 556 |
|
552 | 557 |
if "root" in userlist: |
553 | 558 |
cls.username = "root" |
554 |
elif users == None:
|
|
555 |
cls.username = self._connect_loginname(os) |
|
559 |
elif users is None:
|
|
560 |
cls.username = self._connect_loginname(os_value)
|
|
556 | 561 |
else: |
557 | 562 |
cls.username = choice(userlist) |
558 | 563 |
|
... | ... | |
573 | 578 |
|
574 | 579 |
log.info("Waiting for server to become ACTIVE") |
575 | 580 |
|
576 |
self._insist_on_status_transition("BUILD", "ACTIVE",
|
|
577 |
self.build_fail, self.build_warning)
|
|
581 |
self._insist_on_status_transition( |
|
582 |
"BUILD", "ACTIVE", self.build_fail, self.build_warning)
|
|
578 | 583 |
|
579 | 584 |
def test_003a_get_server_oob_console(self): |
580 | 585 |
"""Test getting OOB server console over VNC |
... | ... | |
585 | 590 |
""" |
586 | 591 |
console = self.cyclades.get_server_console(self.serverid) |
587 | 592 |
self.assertEquals(console['type'], "vnc") |
588 |
sock = self._insist_on_tcp_connection(socket.AF_INET,
|
|
589 |
console["host"], console["port"])
|
|
593 |
sock = self._insist_on_tcp_connection( |
|
594 |
socket.AF_INET, console["host"], console["port"])
|
|
590 | 595 |
|
591 | 596 |
# Step 1. ProtocolVersion message (par. 6.1.1) |
592 | 597 |
version = sock.recv(1024) |
... | ... | |
619 | 624 |
|
620 | 625 |
log.info("Validate server's IPv4") |
621 | 626 |
|
622 |
|
|
623 | 627 |
server = self.client.get_server_details(self.serverid) |
624 | 628 |
ipv4 = self._get_ipv4(server) |
625 | 629 |
|
... | ... | |
680 | 684 |
"""Test server becomes STOPPED""" |
681 | 685 |
|
682 | 686 |
log.info("Waiting until server becomes STOPPED") |
683 |
self._insist_on_status_transition("ACTIVE", "STOPPED", |
|
684 |
self.action_timeout, |
|
685 |
self.action_timeout) |
|
687 |
self._insist_on_status_transition( |
|
688 |
"ACTIVE", "STOPPED", self.action_timeout, self.action_timeout) |
|
686 | 689 |
|
687 | 690 |
def test_010_submit_start_request(self): |
688 | 691 |
"""Test submit start server request""" |
... | ... | |
695 | 698 |
"""Test server becomes ACTIVE again""" |
696 | 699 |
|
697 | 700 |
log.info("Waiting until server becomes ACTIVE") |
698 |
self._insist_on_status_transition("STOPPED", "ACTIVE", |
|
699 |
self.action_timeout, |
|
700 |
self.action_timeout) |
|
701 |
self._insist_on_status_transition( |
|
702 |
"STOPPED", "ACTIVE", self.action_timeout, self.action_timeout) |
|
701 | 703 |
|
702 | 704 |
def test_011a_server_responds_to_ping_IPv4(self): |
703 | 705 |
"""Test server OS is actually up and running again""" |
... | ... | |
728 | 730 |
self._skipIf(not self.is_windows, "only valid for Windows servers") |
729 | 731 |
server = self.client.get_server_details(self.serverid) |
730 | 732 |
ipv4 = self._get_ipv4(server) |
731 |
sock = _insist_on_tcp_connection(socket.AF_INET, ipv4, 3389) |
|
733 |
sock = self._insist_on_tcp_connection(socket.AF_INET, ipv4, 3389)
|
|
732 | 734 |
|
733 | 735 |
# No actual RDP processing done. We assume the RDP server is there |
734 | 736 |
# if the connection to the RDP port is successful. |
... | ... | |
742 | 744 |
|
743 | 745 |
server = self.client.get_server_details(self.serverid) |
744 | 746 |
ipv6 = self._get_ipv6(server) |
745 |
sock = _get_tcp_connection(socket.AF_INET6, ipv6, 3389) |
|
747 |
sock = self._get_tcp_connection(socket.AF_INET6, ipv6, 3389)
|
|
746 | 748 |
|
747 | 749 |
# No actual RDP processing done. We assume the RDP server is there |
748 | 750 |
# if the connection to the RDP port is successful. |
... | ... | |
751 | 753 |
def test_016_personality_is_enforced(self): |
752 | 754 |
"""Test file injection for personality enforcement""" |
753 | 755 |
self._skipIf(self.is_windows, "only implemented for Linux servers") |
754 |
self._skipIf(self.personality == None, "No personality file selected")
|
|
756 |
self._skipIf(self.personality is None, "No personality file selected")
|
|
755 | 757 |
|
756 | 758 |
log.info("Trying to inject file for personality enforcement") |
757 | 759 |
|
... | ... | |
777 | 779 |
|
778 | 780 |
log.info("Testing if server becomes DELETED") |
779 | 781 |
|
780 |
self._insist_on_status_transition("ACTIVE", "DELETED", |
|
781 |
self.action_timeout, |
|
782 |
self.action_timeout) |
|
782 |
self._insist_on_status_transition( |
|
783 |
"ACTIVE", "DELETED", self.action_timeout, self.action_timeout) |
|
783 | 784 |
|
784 | 785 |
def test_019_server_no_longer_in_server_list(self): |
785 | 786 |
"""Test server is no longer in server list""" |
... | ... | |
823 | 824 |
|
824 | 825 |
for nic in nics: |
825 | 826 |
net_id = nic["network_id"] |
826 |
if self.client.get_network_details(net_id)["public"] == True:
|
|
827 |
if self.client.get_network_details(net_id)["public"]: |
|
827 | 828 |
public_addrs = nic["ipv4"] |
828 |
|
|
829 |
self.assertTrue(public_addrs != None) |
|
830 | 829 |
|
831 |
return public_addrs
|
|
830 |
self.assertTrue(public_addrs is not None)
|
|
832 | 831 |
|
832 |
return public_addrs |
|
833 | 833 |
|
834 |
def _connect_loginname(self, os): |
|
834 |
def _connect_loginname(self, os_value):
|
|
835 | 835 |
"""Return the login name for connections based on the server OS""" |
836 |
if os in ("Ubuntu", "Kubuntu", "Fedora"): |
|
836 |
if os_value in ("Ubuntu", "Kubuntu", "Fedora"):
|
|
837 | 837 |
return "user" |
838 |
elif os in ("windows", "windows_alpha1"): |
|
838 |
elif os_value in ("windows", "windows_alpha1"):
|
|
839 | 839 |
return "Administrator" |
840 | 840 |
else: |
841 | 841 |
return "root" |
... | ... | |
874 | 874 |
|
875 | 875 |
self.result_dict["Server A ID"] = str(serverA["id"]) |
876 | 876 |
self.result_dict["Server A password"] = serverA["adminPass"] |
877 |
|
|
877 |
|
|
878 | 878 |
def test_00001b_serverA_becomes_active(self): |
879 | 879 |
"""Test server becomes ACTIVE""" |
880 | 880 |
|
... | ... | |
899 | 899 |
"""Test submit create server request""" |
900 | 900 |
|
901 | 901 |
log.info("Creating test server B") |
902 |
|
|
902 |
|
|
903 | 903 |
serverB = self.client.create_server(self.servername, self.flavorid, |
904 | 904 |
self.imageid, personality=None) |
905 | 905 |
|
... | ... | |
945 | 945 |
|
946 | 946 |
log.info("Submit new network request") |
947 | 947 |
self.result_dict.clear() |
948 |
|
|
948 |
|
|
949 | 949 |
name = SNF_TEST_PREFIX + TEST_RUN_ID |
950 |
previous_num = len(self.client.list_networks()) |
|
951 |
network = self.client.create_network(name,cidr='10.0.0.1/28') |
|
950 |
#previous_num = len(self.client.list_networks())
|
|
951 |
network = self.client.create_network(name, cidr='10.0.0.1/28')
|
|
952 | 952 |
|
953 | 953 |
#Test if right name is assigned |
954 | 954 |
self.assertEqual(network['name'], name) |
... | ... | |
956 | 956 |
# Update class attributes |
957 | 957 |
cls = type(self) |
958 | 958 |
cls.networkid = network['id'] |
959 |
networks = self.client.list_networks() |
|
959 |
#networks = self.client.list_networks()
|
|
960 | 960 |
|
961 | 961 |
fail_tmout = time.time() + self.action_timeout |
962 | 962 |
|
... | ... | |
990 | 990 |
|
991 | 991 |
while True: |
992 | 992 |
|
993 |
netsA = [x['network_id'] for x in self.client.get_server_details(self.serverid['A'])['attachments']['values']] |
|
994 |
netsB = [x['network_id'] for x in self.client.get_server_details(self.serverid['B'])['attachments']['values']] |
|
993 |
netsA = [x['network_id'] |
|
994 |
for x in self.client.get_server_details( |
|
995 |
self.serverid['A'])['attachments']['values']] |
|
996 |
netsB = [x['network_id'] |
|
997 |
for x in self.client.get_server_details( |
|
998 |
self.serverid['B'])['attachments']['values']] |
|
995 | 999 |
|
996 | 1000 |
if (self.networkid in netsA) and (self.networkid in netsB): |
997 | 1001 |
conn_exists = True |
... | ... | |
1000 | 1004 |
self.assertLess(time.time(), fail_tmout) |
1001 | 1005 |
else: |
1002 | 1006 |
time.sleep(self.query_interval) |
1003 |
|
|
1007 |
|
|
1004 | 1008 |
#Adding private IPs to class attributes |
1005 | 1009 |
cls = type(self) |
1006 | 1010 |
cls.priv_ip = dict() |
1007 | 1011 |
|
1008 |
nicsA = self.client.get_server_details(self.serverid['A'])['attachments']['values'] |
|
1009 |
nicsB = self.client.get_server_details(self.serverid['B'])['attachments']['values'] |
|
1012 |
nicsA = self.client.get_server_details( |
|
1013 |
self.serverid['A'])['attachments']['values'] |
|
1014 |
nicsB = self.client.get_server_details( |
|
1015 |
self.serverid['B'])['attachments']['values'] |
|
1010 | 1016 |
|
1011 | 1017 |
if conn_exists: |
1012 | 1018 |
for nic in nicsA: |
... | ... | |
1064 | 1070 |
fail_tmout = time.time() + self.action_timeout |
1065 | 1071 |
|
1066 | 1072 |
s = False |
1067 |
|
|
1073 |
|
|
1068 | 1074 |
self.result_dict["Server A public IP"] = str(ip) |
1069 | 1075 |
|
1070 | 1076 |
while True: |
... | ... | |
1120 | 1126 |
|
1121 | 1127 |
log.info("Testing if server B responds to IPv4 pings") |
1122 | 1128 |
self.result_dict.clear() |
1123 |
|
|
1129 |
|
|
1124 | 1130 |
server = self.client.get_server_details(self.serverid['B']) |
1125 | 1131 |
ip = self._get_ipv4(server) |
1126 | 1132 |
|
... | ... | |
1153 | 1159 |
|
1154 | 1160 |
server = self.client.get_server_details(self.serverid['A']) |
1155 | 1161 |
image = self.client.get_image_details(self.imageid) |
1156 |
os = image['metadata']['values']['os'] |
|
1162 |
os_value = image['metadata']['values']['os']
|
|
1157 | 1163 |
|
1158 | 1164 |
users = image["metadata"]["values"].get("users", None) |
1159 | 1165 |
userlist = users.split() |
1160 | 1166 |
|
1161 | 1167 |
if "root" in userlist: |
1162 | 1168 |
loginname = "root" |
1163 |
elif users == None:
|
|
1164 |
loginname = self._connect_loginname(os) |
|
1169 |
elif users is None:
|
|
1170 |
loginname = self._connect_loginname(os_value)
|
|
1165 | 1171 |
else: |
1166 | 1172 |
loginname = choice(userlist) |
1167 | 1173 |
|
... | ... | |
1173 | 1179 |
res = False |
1174 | 1180 |
|
1175 | 1181 |
if loginname != "root": |
1176 |
with settings( |
|
1177 |
hide('warnings', 'running'), |
|
1178 |
warn_only=True, |
|
1179 |
host_string=hostip, |
|
1180 |
user=loginname, password=myPass |
|
1181 |
): |
|
1182 |
|
|
1183 |
if len(sudo('ifconfig eth1 %s' % self.priv_ip["A"])) == 0: |
|
1182 |
with fabric.settings( |
|
1183 |
fabric.hide('warnings', 'running'), |
|
1184 |
warn_only=True, |
|
1185 |
host_string=hostip, |
|
1186 |
user=loginname, password=myPass): |
|
1187 |
conf_res = fabric.sudo('ifconfig eth1 %s' % self.priv_ip["A"]) |
|
1188 |
if len(conf_res) == 0: |
|
1184 | 1189 |
res = True |
1185 | 1190 |
|
1186 | 1191 |
else: |
1187 |
with settings( |
|
1188 |
hide('warnings', 'running'), |
|
1189 |
warn_only=True, |
|
1190 |
host_string=hostip, |
|
1191 |
user=loginname, password=myPass |
|
1192 |
): |
|
1193 |
|
|
1194 |
if len(run('ifconfig eth1 %s' % self.priv_ip["A"])) == 0: |
|
1192 |
with fabric.settings( |
|
1193 |
fabric.hide('warnings', 'running'), |
|
1194 |
warn_only=True, |
|
1195 |
host_string=hostip, |
|
1196 |
user=loginname, password=myPass): |
|
1197 |
conf_res = fabric.run('ifconfig eth1 %s' % self.priv_ip["A"]) |
|
1198 |
if len(conf_res) == 0: |
|
1195 | 1199 |
res = True |
1196 | 1200 |
|
1197 | 1201 |
self.assertTrue(res) |
... | ... | |
1205 | 1209 |
|
1206 | 1210 |
server = self.client.get_server_details(self.serverid['B']) |
1207 | 1211 |
image = self.client.get_image_details(self.imageid) |
1208 |
os = image['metadata']['values']['os'] |
|
1212 |
os_value = image['metadata']['values']['os']
|
|
1209 | 1213 |
|
1210 | 1214 |
users = image["metadata"]["values"].get("users", None) |
1211 | 1215 |
userlist = users.split() |
1212 | 1216 |
|
1213 | 1217 |
if "root" in userlist: |
1214 | 1218 |
loginname = "root" |
1215 |
elif users == None:
|
|
1216 |
loginname = self._connect_loginname(os) |
|
1219 |
elif users is None:
|
|
1220 |
loginname = self._connect_loginname(os_value)
|
|
1217 | 1221 |
else: |
1218 | 1222 |
loginname = choice(userlist) |
1219 | 1223 |
|
... | ... | |
1225 | 1229 |
res = False |
1226 | 1230 |
|
1227 | 1231 |
if loginname != "root": |
1228 |
with settings( |
|
1229 |
hide('warnings', 'running'), |
|
1230 |
warn_only=True, |
|
1231 |
host_string=hostip, |
|
1232 |
user=loginname, password=myPass |
|
1233 |
): |
|
1234 |
|
|
1235 |
if len(sudo('ifconfig eth1 %s' % self.priv_ip["B"])) == 0: |
|
1232 |
with fabric.settings( |
|
1233 |
fabric.hide('warnings', 'running'), |
|
1234 |
warn_only=True, |
|
1235 |
host_string=hostip, |
|
1236 |
user=loginname, password=myPass): |
|
1237 |
conf_res = fabric.sudo('ifconfig eth1 %s' % self.priv_ip["B"]) |
|
1238 |
if len(conf_res) == 0: |
|
1236 | 1239 |
res = True |
1237 | 1240 |
|
1238 | 1241 |
else: |
1239 |
with settings( |
|
1240 |
hide('warnings', 'running'), |
|
1241 |
warn_only=True, |
|
1242 |
host_string=hostip, |
|
1243 |
user=loginname, password=myPass |
|
1244 |
): |
|
1245 |
|
|
1246 |
if len(run('ifconfig eth1 %s' % self.priv_ip["B"])) == 0: |
|
1242 |
with fabric.settings( |
|
1243 |
fabric.hide('warnings', 'running'), |
|
1244 |
warn_only=True, |
|
1245 |
host_string=hostip, |
|
1246 |
user=loginname, password=myPass): |
|
1247 |
conf_res = fabric.run('ifconfig eth1 %s' % self.priv_ip["B"]) |
|
1248 |
if len(conf_res) == 0: |
|
1247 | 1249 |
res = True |
1248 | 1250 |
|
1249 | 1251 |
self.assertTrue(res) |
... | ... | |
1257 | 1259 |
|
1258 | 1260 |
server = self.client.get_server_details(self.serverid['A']) |
1259 | 1261 |
image = self.client.get_image_details(self.imageid) |
1260 |
os = image['metadata']['values']['os'] |
|
1262 |
os_value = image['metadata']['values']['os']
|
|
1261 | 1263 |
hostip = self._get_ipv4(server) |
1262 | 1264 |
|
1263 | 1265 |
users = image["metadata"]["values"].get("users", None) |
... | ... | |
1265 | 1267 |
|
1266 | 1268 |
if "root" in userlist: |
1267 | 1269 |
loginname = "root" |
1268 |
elif users == None:
|
|
1269 |
loginname = self._connect_loginname(os) |
|
1270 |
elif users is None:
|
|
1271 |
loginname = self._connect_loginname(os_value)
|
|
1270 | 1272 |
else: |
1271 | 1273 |
loginname = choice(userlist) |
1272 | 1274 |
|
... | ... | |
1298 | 1300 |
|
1299 | 1301 |
prev_state = self.client.get_network_details(self.networkid) |
1300 | 1302 |
prev_nics = prev_state['attachments']['values'] |
1301 |
prev_conn = len(prev_nics) |
|
1303 |
#prev_conn = len(prev_nics)
|
|
1302 | 1304 |
|
1303 |
nicsA=[x['id'] for x in self.client.get_server_details(self.serverid['A'])['attachments']['values']] |
|
1304 |
nicsB=[x['id'] for x in self.client.get_server_details(self.serverid['B'])['attachments']['values']] |
|
1305 |
nicsA = [x['id'] |
|
1306 |
for x in self.client.get_server_details( |
|
1307 |
self.serverid['A'])['attachments']['values']] |
|
1308 |
nicsB = [x['id'] |
|
1309 |
for x in self.client.get_server_details( |
|
1310 |
self.serverid['B'])['attachments']['values']] |
|
1305 | 1311 |
|
1306 | 1312 |
for nic in prev_nics: |
1307 | 1313 |
if nic in nicsA: |
... | ... | |
1309 | 1315 |
if nic in nicsB: |
1310 | 1316 |
self.client.disconnect_server(self.serverid['B'], nic) |
1311 | 1317 |
|
1312 |
|
|
1313 | 1318 |
#Insist on deleting until action timeout |
1314 | 1319 |
fail_tmout = time.time() + self.action_timeout |
1315 | 1320 |
|
1316 | 1321 |
while True: |
1317 |
|
|
1318 |
netsA=[x['network_id'] for x in self.client.get_server_details(self.serverid['A'])['attachments']['values']] |
|
1319 |
netsB=[x['network_id'] for x in self.client.get_server_details(self.serverid['B'])['attachments']['values']] |
|
1320 |
|
|
1321 |
|
|
1322 |
connected = (self.client.get_network_details(self.networkid)) |
|
1323 |
connections = connected['attachments']['values'] |
|
1322 |
netsA = [x['network_id'] |
|
1323 |
for x in self.client.get_server_details( |
|
1324 |
self.serverid['A'])['attachments']['values']] |
|
1325 |
netsB = [x['network_id'] |
|
1326 |
for x in self.client.get_server_details( |
|
1327 |
self.serverid['B'])['attachments']['values']] |
|
1328 |
|
|
1329 |
#connected = (self.client.get_network_details(self.networkid)) |
|
1330 |
#connections = connected['attachments']['values'] |
|
1324 | 1331 |
if (self.networkid not in netsA) and (self.networkid not in netsB): |
1325 | 1332 |
conn_exists = False |
1326 | 1333 |
break |
... | ... | |
1358 | 1365 |
else: |
1359 | 1366 |
time.sleep(self.query_interval) |
1360 | 1367 |
|
1361 |
|
|
1362 |
|
|
1363 | 1368 |
def test_006_cleanup_servers(self): |
1364 | 1369 |
"""Cleanup servers created for this test""" |
1365 | 1370 |
|
... | ... | |
1410 | 1415 |
|
1411 | 1416 |
while True: |
1412 | 1417 |
multi.debug("I am process %d, GETting from queue is %s" % |
1413 |
(os.getpid(), self.testq)) |
|
1418 |
(os.getpid(), self.testq))
|
|
1414 | 1419 |
msg = self.testq.get() |
1415 | 1420 |
|
1416 | 1421 |
multi.debug("Dequeued msg: %s" % msg) |
... | ... | |
1433 | 1438 |
TEST_RUN_ID + '.log') |
1434 | 1439 |
|
1435 | 1440 |
f = open(log_file, 'w') |
1436 |
fail = open(fail_file,'w') |
|
1441 |
fail = open(fail_file, 'w')
|
|
1437 | 1442 |
error = open(error_file, 'w') |
1438 | 1443 |
|
1439 | 1444 |
log.info(yellow + '* Starting testcase: %s' % msg + normal) |
1440 | 1445 |
|
1441 |
runner = unittest.TextTestRunner(f, verbosity=2, failfast = True, resultclass=BurninTestResult) |
|
1446 |
runner = unittest.TextTestRunner( |
|
1447 |
f, verbosity=2, failfast=True, |
|
1448 |
resultclass=BurninTestResult) |
|
1442 | 1449 |
suite = unittest.TestLoader().loadTestsFromTestCase(msg) |
1443 | 1450 |
result = runner.run(suite) |
1444 | 1451 |
|
1445 | 1452 |
for res in result.errors: |
1446 |
log.error("snf-burnin encountered an error in " \
|
|
1447 |
"testcase: %s" %msg)
|
|
1453 |
log.error("snf-burnin encountered an error in " |
|
1454 |
"testcase: %s" % msg)
|
|
1448 | 1455 |
log.error("See log for details") |
1449 | 1456 |
error.write(str(res[0]) + '\n') |
1450 | 1457 |
error.write(str(res[0].shortDescription()) + '\n') |
1451 | 1458 |
error.write('\n') |
1452 | 1459 |
|
1453 | 1460 |
for res in result.failures: |
1454 |
log.error("snf-burnin failed in testcase: %s" %msg) |
|
1461 |
log.error("snf-burnin failed in testcase: %s" % msg)
|
|
1455 | 1462 |
log.error("See log for details") |
1456 | 1463 |
fail.write(str(res[0]) + '\n') |
1457 | 1464 |
fail.write(str(res[0].shortDescription()) + '\n') |
1458 | 1465 |
fail.write('\n') |
1459 |
if NOFAILFAST == False:
|
|
1466 |
if not NOFAILFAST:
|
|
1460 | 1467 |
sys.exit() |
1461 | 1468 |
|
1462 | 1469 |
if (len(result.failures) == 0) and (len(result.errors) == 0): |
1463 |
log.debug("Passed testcase: %s" %msg) |
|
1470 |
log.debug("Passed testcase: %s" % msg)
|
|
1464 | 1471 |
|
1465 | 1472 |
f.close() |
1466 | 1473 |
fail.close() |
1467 | 1474 |
error.close() |
1468 | 1475 |
|
1469 |
|
|
1470 | 1476 |
else: |
1471 | 1477 |
raise Exception("Cannot handle msg: %s" % msg) |
1472 | 1478 |
|
1473 |
def _run_cases_in_series(cases,image_folder): |
|
1479 |
|
|
1480 |
def _run_cases_in_series(cases, image_folder): |
|
1474 | 1481 |
"""Run instances of TestCase in series""" |
1475 | 1482 |
|
1476 | 1483 |
for case in cases: |
1477 | 1484 |
|
1478 | 1485 |
test = case.__name__ |
1479 | 1486 |
|
1480 |
log.info(yellow + '* Starting testcase: %s' %test + normal) |
|
1487 |
log.info(yellow + '* Starting testcase: %s' % test + normal)
|
|
1481 | 1488 |
log_file = os.path.join(image_folder, 'details_' + |
1482 | 1489 |
(case.__name__) + "_" + |
1483 | 1490 |
TEST_RUN_ID + '.log') |
... | ... | |
1493 | 1500 |
error = open(error_file, "w") |
1494 | 1501 |
|
1495 | 1502 |
suite = unittest.TestLoader().loadTestsFromTestCase(case) |
1496 |
runner = unittest.TextTestRunner(f, verbosity=2, failfast=True, resultclass=BurninTestResult) |
|
1503 |
runner = unittest.TextTestRunner( |
|
1504 |
f, verbosity=2, failfast=True, |
|
1505 |
resultclass=BurninTestResult) |
|
1497 | 1506 |
result = runner.run(suite) |
1498 | 1507 |
|
1499 | 1508 |
for res in result.errors: |
1500 |
log.error("snf-burnin encountered an error in " \
|
|
1501 |
"testcase: %s" %test)
|
|
1509 |
log.error("snf-burnin encountered an error in " |
|
1510 |
"testcase: %s" % test)
|
|
1502 | 1511 |
log.error("See log for details") |
1503 | 1512 |
error.write(str(res[0]) + '\n') |
1504 | 1513 |
error.write(str(res[0].shortDescription()) + '\n') |
1505 | 1514 |
error.write('\n') |
1506 | 1515 |
|
1507 | 1516 |
for res in result.failures: |
1508 |
log.error("snf-burnin failed in testcase: %s" %test) |
|
1517 |
log.error("snf-burnin failed in testcase: %s" % test)
|
|
1509 | 1518 |
log.error("See log for details") |
1510 | 1519 |
fail.write(str(res[0]) + '\n') |
1511 | 1520 |
fail.write(str(res[0].shortDescription()) + '\n') |
1512 | 1521 |
fail.write('\n') |
1513 |
if NOFAILFAST == False:
|
|
1522 |
if not NOFAILFAST:
|
|
1514 | 1523 |
sys.exit() |
1515 | 1524 |
|
1516 | 1525 |
if (len(result.failures) == 0) and (len(result.errors) == 0): |
1517 |
log.debug("Passed testcase: %s" %test)
|
|
1526 |
log.debug("Passed testcase: %s" % test)
|
|
1518 | 1527 |
|
1519 |
|
|
1520 | 1528 |
|
1521 | 1529 |
def _run_cases_in_parallel(cases, fanout, image_folder): |
1522 | 1530 |
"""Run instances of TestCase in parallel, in a number of distinct processes |
... | ... | |
1543 | 1551 |
worker_folder = [] |
1544 | 1552 |
runners = [] |
1545 | 1553 |
|
1546 |
for i in xrange(0,fanout): |
|
1554 |
for i in xrange(0, fanout):
|
|
1547 | 1555 |
testq.append(Queue()) |
1548 | 1556 |
worker_folder.append(os.path.join(image_folder, 'process'+str(i))) |
1549 | 1557 |
os.mkdir(worker_folder[i]) |
... | ... | |
1552 | 1560 |
kwargs = dict(testq=testq[i], worker_folder=worker_folder[i]) |
1553 | 1561 |
runners.append(TestRunnerProcess(kwargs=kwargs)) |
1554 | 1562 |
|
1555 |
multi.debug("Spawning %d test runner processes" %len(runners)) |
|
1563 |
multi.debug("Spawning %d test runner processes" % len(runners))
|
|
1556 | 1564 |
|
1557 | 1565 |
for p in runners: |
1558 | 1566 |
p.start() |
... | ... | |
1563 | 1571 |
testq[i].put("TEST_RUNNER_TERMINATE") |
1564 | 1572 |
|
1565 | 1573 |
multi.debug("Spawned %d test runners, PIDs are %s" % |
1566 |
(len(runners), [p.pid for p in runners])) |
|
1574 |
(len(runners), [p.pid for p in runners]))
|
|
1567 | 1575 |
|
1568 | 1576 |
multi.debug("Joining %d processes" % len(runners)) |
1569 | 1577 |
|
... | ... | |
1581 | 1589 |
|
1582 | 1590 |
# Patch extra parameters into test names by manipulating method docstrings |
1583 | 1591 |
for (mname, m) in \ |
1584 |
inspect.getmembers(cls, lambda x: inspect.ismethod(x)): |
|
1592 |
inspect.getmembers(cls, lambda x: inspect.ismethod(x)):
|
|
1585 | 1593 |
if hasattr(m, __doc__): |
1586 |
m.__func__.__doc__ = "[%s] %s" % (imagename, m.__doc__) |
|
1594 |
m.__func__.__doc__ = "[%s] %s" % (cls.imagename, m.__doc__)
|
|
1587 | 1595 |
|
1588 | 1596 |
# Make sure the class can be pickled, by listing it among |
1589 | 1597 |
# the attributes of __main__. A PicklingError is raised otherwise. |
... | ... | |
1621 | 1629 |
|
1622 | 1630 |
# Show staled servers |
1623 | 1631 |
print >>sys.stderr, yellow + \ |
1624 |
"Found these stale servers from previous runs:" + \
|
|
1625 |
normal
|
|
1632 |
"Found these stale servers from previous runs:" + \ |
|
1633 |
normal |
|
1626 | 1634 |
print >>sys.stderr, " " + \ |
1627 |
"\n ".join(["%d: %s" % (s["id"], s["name"]) for s in stale])
|
|
1635 |
"\n ".join(["%d: %s" % (s["id"], s["name"]) for s in stale]) |
|
1628 | 1636 |
|
1629 | 1637 |
# Delete staled servers |
1630 | 1638 |
if delete_stale: |
... | ... | |
1635 | 1643 |
# Wait for all servers to be deleted |
1636 | 1644 |
while True: |
1637 | 1645 |
servers = c.list_servers() |
1638 |
stale = [s for s in servers if s["name"].startswith(SNF_TEST_PREFIX)] |
|
1639 |
if len(stale)==0: |
|
1646 |
stale = [s for s in servers |
|
1647 |
if s["name"].startswith(SNF_TEST_PREFIX)] |
|
1648 |
if len(stale) == 0: |
|
1640 | 1649 |
print >> sys.stderr, green + " ...done" + normal |
1641 | 1650 |
break |
1642 | 1651 |
elif time.time() > fail_tmout: |
1643 | 1652 |
print >> sys.stderr, red + \ |
1644 |
"Not all stale servers deleted. Action timed out." + \
|
|
1645 |
normal
|
|
1646 |
return
|
|
1653 |
"Not all stale servers deleted. Action timed out." + \ |
|
1654 |
normal |
|
1655 |
sys.exit(1)
|
|
1647 | 1656 |
else: |
1648 | 1657 |
time.sleep(query_interval) |
1649 | 1658 |
else: |
... | ... | |
1662 | 1671 |
|
1663 | 1672 |
# Show staled networks |
1664 | 1673 |
print >> sys.stderr, yellow + \ |
1665 |
"Found these stale networks from previous runs:" + \
|
|
1666 |
normal
|
|
1674 |
"Found these stale networks from previous runs:" + \ |
|
1675 |
normal |
|
1667 | 1676 |
print " " + \ |
1668 |
"\n ".join(["%s: %s" % (str(n["id"]), n["name"]) for n in stale])
|
|
1677 |
"\n ".join(["%s: %s" % (str(n["id"]), n["name"]) for n in stale]) |
|
1669 | 1678 |
|
1670 | 1679 |
# Delete staled networks |
1671 | 1680 |
if delete_stale: |
... | ... | |
1676 | 1685 |
# Wait for all networks to be deleted |
1677 | 1686 |
while True: |
1678 | 1687 |
networks = c.list_networks() |
1679 |
stale = [n for n in networks if n["name"].startswith(SNF_TEST_PREFIX)] |
|
1680 |
if len(stale)==0: |
|
1688 |
stale = [n for n in networks |
|
1689 |
if n["name"].startswith(SNF_TEST_PREFIX)] |
|
1690 |
if len(stale) == 0: |
|
1681 | 1691 |
print >> sys.stderr, green + " ...done" + normal |
1682 | 1692 |
break |
1683 | 1693 |
elif time.time() > fail_tmout: |
1684 | 1694 |
print >> sys.stderr, red + \ |
1685 |
"Not all stale networks deleted. Action timed out." + \
|
|
1686 |
normal
|
|
1687 |
return
|
|
1695 |
"Not all stale networks deleted. Action timed out." + \ |
|
1696 |
normal |
|
1697 |
sys.exit(1)
|
|
1688 | 1698 |
else: |
1689 | 1699 |
time.sleep(query_interval) |
1690 | 1700 |
else: |
... | ... | |
1695 | 1705 |
# Parse arguments functions |
1696 | 1706 |
def parse_comma(option, opt, value, parser): |
1697 | 1707 |
tests = set(['all', 'auth', 'images', 'flavors', |
1698 |
'servers', 'server_spawn', 'network_spawn']) |
|
1708 |
'servers', 'server_spawn', 'network_spawn'])
|
|
1699 | 1709 |
parse_input = value.split(',') |
1700 | 1710 |
|
1701 | 1711 |
if not (set(parse_input)).issubset(tests): |
... | ... | |
1732 | 1742 |
help="The token to use for authentication to the API") |
1733 | 1743 |
parser.add_option("--nofailfast", |
1734 | 1744 |
action="store_true", dest="nofailfast", |
1735 |
help="Do not fail immediately if one of the tests " \
|
|
1745 |
help="Do not fail immediately if one of the tests " |
|
1736 | 1746 |
"fails (EXPERIMENTAL)", |
1737 | 1747 |
default=False) |
1738 | 1748 |
parser.add_option("--no-ipv6", |
... | ... | |
1742 | 1752 |
parser.add_option("--action-timeout", |
1743 | 1753 |
action="store", type="int", dest="action_timeout", |
1744 | 1754 |
metavar="TIMEOUT", |
1745 |
help="Wait SECONDS seconds for a server action to " \
|
|
1755 |
help="Wait SECONDS seconds for a server action to " |
|
1746 | 1756 |
"complete, then the test is considered failed", |
1747 | 1757 |
default=100) |
1748 | 1758 |
parser.add_option("--build-warning", |
1749 | 1759 |
action="store", type="int", dest="build_warning", |
1750 | 1760 |
metavar="TIMEOUT", |
1751 |
help="Warn if TIMEOUT seconds have passed and a " \
|
|
1761 |
help="Warn if TIMEOUT seconds have passed and a " |
|
1752 | 1762 |
"build operation is still pending", |
1753 | 1763 |
default=600) |
1754 | 1764 |
parser.add_option("--build-fail", |
1755 | 1765 |
action="store", type="int", dest="build_fail", |
1756 | 1766 |
metavar="BUILD_TIMEOUT", |
1757 |
help="Fail the test if TIMEOUT seconds have passed " \
|
|
1767 |
help="Fail the test if TIMEOUT seconds have passed " |
|
1758 | 1768 |
"and a build operation is still incomplete", |
1759 | 1769 |
default=900) |
1760 | 1770 |
parser.add_option("--query-interval", |
1761 | 1771 |
action="store", type="int", dest="query_interval", |
1762 | 1772 |
metavar="INTERVAL", |
1763 |
help="Query server status when requests are pending " \
|
|
1773 |
help="Query server status when requests are pending " |
|
1764 | 1774 |
"every INTERVAL seconds", |
1765 | 1775 |
default=3) |
1766 | 1776 |
parser.add_option("--fanout", |
1767 | 1777 |
action="store", type="int", dest="fanout", |
1768 | 1778 |
metavar="COUNT", |
1769 |
help="Spawn up to COUNT child processes to execute " \
|
|
1770 |
"in parallel, essentially have up to COUNT " \
|
|
1779 |
help="Spawn up to COUNT child processes to execute " |
|
1780 |
"in parallel, essentially have up to COUNT " |
|
1771 | 1781 |
"server build requests outstanding (EXPERIMENTAL)", |
1772 | 1782 |
default=1) |
1773 | 1783 |
parser.add_option("--force-flavor", |
1774 | 1784 |
action="store", type="int", dest="force_flavorid", |
1775 | 1785 |
metavar="FLAVOR ID", |
1776 |
help="Force all server creations to use the specified "\
|
|
1777 |
"FLAVOR ID instead of a randomly chosen one, " \
|
|
1786 |
help="Force all server creations to use the specified " |
|
1787 |
"FLAVOR ID instead of a randomly chosen one, " |
|
1778 | 1788 |
"useful if disk space is scarce", |
1779 | 1789 |
default=None) |
1780 | 1790 |
parser.add_option("--image-id", |
1781 | 1791 |
action="store", type="string", dest="force_imageid", |
1782 | 1792 |
metavar="IMAGE ID", |
1783 |
help="Test the specified image id, use 'all' to test " \
|
|
1793 |
help="Test the specified image id, use 'all' to test " |
|
1784 | 1794 |
"all available images (mandatory argument)", |
1785 | 1795 |
default=None) |
1786 | 1796 |
parser.add_option("--show-stale", |
1787 | 1797 |
action="store_true", dest="show_stale", |
1788 |
help="Show stale servers from previous runs, whose "\
|
|
1798 |
help="Show stale servers from previous runs, whose " |
|
1789 | 1799 |
"name starts with `%s'" % SNF_TEST_PREFIX, |
1790 | 1800 |
default=False) |
1791 | 1801 |
parser.add_option("--delete-stale", |
1792 | 1802 |
action="store_true", dest="delete_stale", |
1793 |
help="Delete stale servers from previous runs, whose "\
|
|
1803 |
help="Delete stale servers from previous runs, whose " |
|
1794 | 1804 |
"name starts with `%s'" % SNF_TEST_PREFIX, |
1795 | 1805 |
default=False) |
1796 | 1806 |
parser.add_option("--force-personality", |
... | ... | |
1805 | 1815 |
default="/var/log/burnin/") |
1806 | 1816 |
parser.add_option("--verbose", "-V", |
1807 | 1817 |
action="store_true", dest="verbose", |
1808 |
help="Print detailed output about multiple "\
|
|
1818 |
help="Print detailed output about multiple " |
|
1809 | 1819 |
"processes spawning", |
1810 | 1820 |
default=False) |
1811 | 1821 |
parser.add_option("--set-tests", |
... | ... | |
1833 | 1843 |
if not opts.show_stale: |
1834 | 1844 |
if not opts.force_imageid: |
1835 | 1845 |
print >>sys.stderr, red + \ |
1836 |
"The --image-id argument is mandatory.\n" + \
|
|
1837 |
normal
|
|
1846 |
"The --image-id argument is mandatory.\n" + \ |
|
1847 |
normal |
|
1838 | 1848 |
parser.print_help() |
1839 | 1849 |
sys.exit(1) |
1840 | 1850 |
if opts.force_imageid != 'all': |
... | ... | |
1842 | 1852 |
opts.force_imageid = str(opts.force_imageid) |
1843 | 1853 |
except ValueError: |
1844 | 1854 |
print >>sys.stderr, red + \ |
1845 |
"Invalid value specified for" + \
|
|
1846 |
"--image-id. Use a valid id, or `all'." + \
|
|
1847 |
normal
|
|
1855 |
"Invalid value specified for" + \ |
|
1856 |
"--image-id. Use a valid id, or `all'." + \ |
|
1857 |
normal |
|
1848 | 1858 |
sys.exit(1) |
1849 | 1859 |
|
1850 | 1860 |
# `token' is mandatory |
1851 | 1861 |
if not opts.token: |
1852 | 1862 |
print >>sys.stderr, red + \ |
1853 |
"The --token argument is mandatory.\n" + \
|
|
1854 |
normal
|
|
1863 |
"The --token argument is mandatory.\n" + \ |
|
1864 |
normal |
|
1855 | 1865 |
parser.print_help() |
1856 | 1866 |
sys.exit(1) |
1857 | 1867 |
|
... | ... | |
1896 | 1906 |
|
1897 | 1907 |
# Initialize a kamaki instance, get flavors, images |
1898 | 1908 |
c = ComputeClient(API, TOKEN) |
1899 |
|
|
1900 | 1909 |
DIMAGES = c.list_images(detail=True) |
1901 | 1910 |
DFLAVORS = c.list_flavors(detail=True) |
1902 | 1911 |
|
... | ... | |
1904 | 1913 |
# Run them: FIXME: In parallel, FAILEARLY, catchbreak? |
1905 | 1914 |
#unittest.main(verbosity=2, catchbreak=True) |
1906 | 1915 |
|
1916 |
# Get a list of images we are going to test |
|
1907 | 1917 |
if opts.force_imageid == 'all': |
1908 | 1918 |
test_images = DIMAGES |
1909 | 1919 |
else: |
1910 | 1920 |
test_images = filter(lambda x: x["id"] == opts.force_imageid, DIMAGES) |
1911 | 1921 |
|
1912 |
#New folder for log per image
|
|
1922 |
# Create output (logging) folder
|
|
1913 | 1923 |
if not os.path.exists(opts.log_folder): |
1914 | 1924 |
os.mkdir(opts.log_folder) |
1915 |
|
|
1916 | 1925 |
test_folder = os.path.join(opts.log_folder, TEST_RUN_ID) |
1917 | 1926 |
os.mkdir(test_folder) |
1918 | 1927 |
|
1919 | 1928 |
for image in test_images: |
1920 |
|
|
1921 | 1929 |
imageid = str(image["id"]) |
1922 |
|
|
1930 |
imagename = image["name"] |
|
1931 |
# Choose a flavor (given from user or random) |
|
1923 | 1932 |
if opts.force_flavorid: |
1924 | 1933 |
flavorid = opts.force_flavorid |
1925 | 1934 |
else: |
1926 | 1935 |
flavorid = choice([f["id"] for f in DFLAVORS if f["disk"] >= 20]) |
1927 |
|
|
1928 |
imagename = image["name"] |
|
1929 |
|
|
1930 |
#Personality dictionary for file injection test |
|
1931 |
if opts.personality_path != None: |
|
1936 |
# Personality dictionary for file injection test |
|
1937 |
if opts.personality_path is not None: |
|
1932 | 1938 |
f = open(opts.personality_path) |
1933 | 1939 |
content = b64encode(f.read()) |
1934 | 1940 |
personality = [] |
1935 | 1941 |
st = os.stat(opts.personality_path) |
1936 | 1942 |
personality.append({ |
1937 |
'path': '/root/test_inj_file', |
|
1938 |
'owner': 'root', |
|
1939 |
'group': 'root', |
|
1940 |
'mode': 0x7777 & st.st_mode, |
|
1941 |
'contents': content |
|
1942 |
}) |
|
1943 |
'path': '/root/test_inj_file', |
|
1944 |
'owner': 'root', |
|
1945 |
'group': 'root', |
|
1946 |
'mode': 0x7777 & st.st_mode, |
|
1947 |
'contents': content}) |
|
1943 | 1948 |
else: |
1944 | 1949 |
personality = None |
1945 |
|
|
1950 |
# Give a name to our test servers |
|
1946 | 1951 |
servername = "%s%s for %s" % (SNF_TEST_PREFIX, TEST_RUN_ID, imagename) |
1947 | 1952 |
is_windows = imagename.lower().find("windows") >= 0 |
1948 | 1953 |
|
1954 |
# Create Server TestCases |
|
1949 | 1955 |
ServerTestCase = _spawn_server_test_case( |
1950 | 1956 |
imageid=imageid, |
1951 | 1957 |
flavorid=flavorid, |
... | ... | |
1956 | 1962 |
action_timeout=opts.action_timeout, |
1957 | 1963 |
build_warning=opts.build_warning, |
1958 | 1964 |
build_fail=opts.build_fail, |
1959 |
query_interval=opts.query_interval, |
|
1960 |
) |
|
1961 |
|
|
1962 |
|
|
1965 |
query_interval=opts.query_interval) |
|
1966 |
# Create Network TestCases |
|
1963 | 1967 |
NetworkTestCase = _spawn_network_test_case( |
1964 | 1968 |
action_timeout=opts.action_timeout, |
1965 | 1969 |
imageid=imageid, |
1966 | 1970 |
flavorid=flavorid, |
1967 | 1971 |
imagename=imagename, |
1968 |
query_interval=opts.query_interval, |
|
1969 |
) |
|
1972 |
query_interval=opts.query_interval) |
|
1970 | 1973 |
|
1974 |
# Choose the tests we are going to run |
|
1971 | 1975 |
test_dict = {'auth': UnauthorizedTestCase, |
1972 | 1976 |
'images': ImagesTestCase, |
1973 | 1977 |
'flavors': FlavorsTestCase, |
1974 | 1978 |
'servers': ServersTestCase, |
1975 | 1979 |
'server_spawn': ServerTestCase, |
1976 | 1980 |
'network_spawn': NetworkTestCase} |
1977 |
|
|
1978 | 1981 |
seq_cases = [] |
1979 | 1982 |
if 'all' in opts.tests: |
1980 | 1983 |
seq_cases = [UnauthorizedTestCase, ImagesTestCase, FlavorsTestCase, |
... | ... | |
1983 | 1986 |
for test in opts.tests: |
1984 | 1987 |
seq_cases.append(test_dict[test]) |
1985 | 1988 |
|
1986 |
#folder for each image
|
|
1989 |
# Folder for each image
|
|
1987 | 1990 |
image_folder = os.path.join(test_folder, imageid) |
1988 | 1991 |
os.mkdir(image_folder) |
1989 | 1992 |
|
1990 |
if opts.fanout>1: |
|
1993 |
# Run each test |
|
1994 |
if opts.fanout > 1: |
|
1991 | 1995 |
_run_cases_in_parallel(seq_cases, opts.fanout, image_folder) |
1992 | 1996 |
else: |
1993 |
_run_cases_in_series(seq_cases,image_folder) |
|
1997 |
_run_cases_in_series(seq_cases, image_folder) |
|
1998 |
|
|
1994 | 1999 |
|
2000 |
# -------------------------------------------------------------------- |
|
2001 |
# Call main |
|
1995 | 2002 |
if __name__ == "__main__": |
1996 | 2003 |
sys.exit(main()) |
Also available in: Unified diff