Revision 11779b6c
b/snf-tools/synnefo_tools/burnin.py | ||
---|---|---|
40 | 40 |
import inspect |
41 | 41 |
import logging |
42 | 42 |
import os |
43 |
import os.path |
|
43 | 44 |
import paramiko |
44 | 45 |
import prctl |
45 | 46 |
import subprocess |
... | ... | |
47 | 48 |
import socket |
48 | 49 |
import sys |
49 | 50 |
import time |
51 |
import tempfile |
|
50 | 52 |
from base64 import b64encode |
51 | 53 |
from IPy import IP |
52 | 54 |
from multiprocessing import Process, Queue |
53 |
from random import choice |
|
55 |
from random import choice, randint
|
|
54 | 56 |
from optparse import OptionParser, OptionValueError |
55 | 57 |
|
56 | 58 |
from kamaki.clients.compute import ComputeClient |
57 | 59 |
from kamaki.clients.cyclades import CycladesClient |
58 | 60 |
from kamaki.clients.image import ImageClient |
61 |
from kamaki.clients.pithos import PithosClient |
|
59 | 62 |
from kamaki.clients import ClientError |
60 | 63 |
|
61 | 64 |
from vncauthproxy.d3des import generate_response as d3des_generate_response |
... | ... | |
74 | 77 |
TOKEN = None |
75 | 78 |
PLANKTON = None |
76 | 79 |
PLANKTON_USER = None |
80 |
PITHOS = None |
|
81 |
PITHOS_USER = None |
|
77 | 82 |
NO_IPV6 = None |
78 |
DEFAULT_API = "https://cyclades.okeanos.grnet.gr/api/v1.1" |
|
79 |
DEFAULT_PLANKTON = "https://cyclades.okeanos.grnet.gr/plankton" |
|
80 | 83 |
DEFAULT_PLANKTON_USER = "images@okeanos.grnet.gr" |
81 | 84 |
NOFAILFAST = None |
82 | 85 |
VERBOSE = None |
... | ... | |
326 | 329 |
self.assertEqual(names, dnames) |
327 | 330 |
|
328 | 331 |
|
332 |
# -------------------------------------------------------------------- |
|
333 |
# Pithos Test Cases |
|
334 |
class PithosTestCase(unittest.TestCase): |
|
335 |
"""Test pithos functionality""" |
|
336 |
@classmethod |
|
337 |
def setUpClass(cls): |
|
338 |
"""Initialize kamaki, get list of containers""" |
|
339 |
log.info("Getting list of containers") |
|
340 |
|
|
341 |
cls.client = PithosClient(PITHOS, TOKEN, PITHOS_USER) |
|
342 |
cls.containers = cls.client.list_containers() |
|
343 |
cls.result_dict = dict() |
|
344 |
|
|
345 |
def test_001_list_containers(self): |
|
346 |
"""Test container list actually returns containers""" |
|
347 |
self.assertGreater(len(self.containers), 0) |
|
348 |
|
|
349 |
def test_002_unique_containers(self): |
|
350 |
"""Test if containers have unique names""" |
|
351 |
names = [n['name'] for n in self.containers] |
|
352 |
names = sorted(names) |
|
353 |
self.assertEqual(sorted(list(set(names))), names) |
|
354 |
|
|
355 |
def test_003_create_container(self): |
|
356 |
"""Test create a container""" |
|
357 |
rand_num = randint(1000, 9999) |
|
358 |
rand_name = "%s%s" % (SNF_TEST_PREFIX, rand_num) |
|
359 |
names = [n['name'] for n in self.containers] |
|
360 |
while rand_name in names: |
|
361 |
rand_num = randint(1000, 9999) |
|
362 |
rand_name = "%s%s" % (SNF_TEST_PREFIX, rand_num) |
|
363 |
# Create container |
|
364 |
self.client.container = rand_name |
|
365 |
self.client.container_put() |
|
366 |
# Get list of containers |
|
367 |
new_containers = self.client.list_containers() |
|
368 |
new_container_names = [n['name'] for n in new_containers] |
|
369 |
self.assertIn(rand_name, new_container_names) |
|
370 |
|
|
371 |
def test_004_upload(self): |
|
372 |
"""Test uploading something to pithos+""" |
|
373 |
# Create a tmp file |
|
374 |
with tempfile.TemporaryFile() as f: |
|
375 |
f.write("This is a temp file") |
|
376 |
f.seek(0, 0) |
|
377 |
# Where to save file |
|
378 |
self.client.upload_object("test.txt", f) |
|
379 |
|
|
380 |
def test_005_download(self): |
|
381 |
"""Test download something from pithos+""" |
|
382 |
# Create tmp directory to save file |
|
383 |
tmp_dir = tempfile.mkdtemp() |
|
384 |
tmp_file = os.path.join(tmp_dir, "test.txt") |
|
385 |
with open(tmp_file, "wb+") as f: |
|
386 |
self.client.download_object("test.txt", f) |
|
387 |
# Read file |
|
388 |
f.seek(0, 0) |
|
389 |
content = f.read() |
|
390 |
# Remove files |
|
391 |
os.unlink(tmp_file) |
|
392 |
os.rmdir(tmp_dir) |
|
393 |
# Compare results |
|
394 |
self.assertEqual(content, "This is a temp file") |
|
395 |
|
|
396 |
def test_006_remove(self): |
|
397 |
"""Test removing files and containers""" |
|
398 |
cont_name = self.client.container |
|
399 |
self.client.del_object("test.txt") |
|
400 |
self.client.purge_container() |
|
401 |
# List containers |
|
402 |
containers = self.client.list_containers() |
|
403 |
cont_names = [n['name'] for n in containers] |
|
404 |
self.assertNotIn(cont_name, cont_names) |
|
405 |
|
|
406 |
|
|
407 |
# -------------------------------------------------------------------- |
|
329 | 408 |
# This class gets replicated into actual TestCases dynamically |
330 | 409 |
class SpawnServerTestCase(unittest.TestCase): |
331 | 410 |
"""Test scenario for server of the specified image""" |
... | ... | |
1673 | 1752 |
# Parse arguments functions |
1674 | 1753 |
def parse_comma(option, opt, value, parser): |
1675 | 1754 |
tests = set(['all', 'auth', 'images', 'flavors', |
1676 |
'servers', 'server_spawn', 'network_spawn']) |
|
1755 |
'pithos', 'servers', 'server_spawn', |
|
1756 |
'network_spawn']) |
|
1677 | 1757 |
parse_input = value.split(',') |
1678 | 1758 |
|
1679 | 1759 |
if not (set(parse_input)).issubset(tests): |
... | ... | |
1696 | 1776 |
parser.add_option("--api", |
1697 | 1777 |
action="store", type="string", dest="api", |
1698 | 1778 |
help="The API URI to use to reach the Synnefo API", |
1699 |
default=DEFAULT_API)
|
|
1779 |
default=None)
|
|
1700 | 1780 |
parser.add_option("--plankton", |
1701 | 1781 |
action="store", type="string", dest="plankton", |
1702 | 1782 |
help="The API URI to use to reach the Plankton API", |
1703 |
default=DEFAULT_PLANKTON)
|
|
1783 |
default=None)
|
|
1704 | 1784 |
parser.add_option("--plankton-user", |
1705 | 1785 |
action="store", type="string", dest="plankton_user", |
1706 | 1786 |
help="Owner of system images", |
1707 | 1787 |
default=DEFAULT_PLANKTON_USER) |
1788 |
parser.add_option("--pithos", |
|
1789 |
action="store", type="string", dest="pithos", |
|
1790 |
help="The API URI to use to reach the Pithos API", |
|
1791 |
default=None) |
|
1792 |
parser.add_option("--pithos_user", |
|
1793 |
action="store", type="string", dest="pithos_user", |
|
1794 |
help="Owner of the pithos account", |
|
1795 |
default=None) |
|
1708 | 1796 |
parser.add_option("--token", |
1709 | 1797 |
action="store", type="string", dest="token", |
1710 | 1798 |
help="The token to use for authentication to the API") |
... | ... | |
1793 | 1881 |
help='Set comma seperated tests for this run. \ |
1794 | 1882 |
Available tests: auth, images, flavors, \ |
1795 | 1883 |
servers, server_spawn, \ |
1796 |
network_spawn. \ |
|
1884 |
network_spawn, pithos. \
|
|
1797 | 1885 |
Default = all', |
1798 | 1886 |
default='all', |
1799 | 1887 |
callback=parse_comma) |
... | ... | |
1807 | 1895 |
if opts.delete_stale: |
1808 | 1896 |
opts.show_stale = True |
1809 | 1897 |
|
1810 |
# `image-id' is mandatory |
|
1898 |
# `token' is mandatory |
|
1899 |
_mandatory_argument(opts.token, "--token") |
|
1900 |
# `api' is mandatory |
|
1901 |
_mandatory_argument(opts.api, "--api") |
|
1902 |
|
|
1811 | 1903 |
if not opts.show_stale: |
1812 |
if not opts.force_imageid: |
|
1813 |
print >>sys.stderr, red + \ |
|
1814 |
"The --image-id argument is mandatory.\n" + \ |
|
1815 |
normal |
|
1816 |
parser.print_help() |
|
1817 |
sys.exit(1) |
|
1904 |
# `image-id' is mandatory |
|
1905 |
_mandatory_argument(opts.force_imageid, "--image_id") |
|
1818 | 1906 |
if opts.force_imageid != 'all': |
1819 | 1907 |
try: |
1820 | 1908 |
opts.force_imageid = str(opts.force_imageid) |
... | ... | |
1824 | 1912 |
"--image-id. Use a valid id, or `all'." + \ |
1825 | 1913 |
normal |
1826 | 1914 |
sys.exit(1) |
1915 |
# `pithos' is mandatory |
|
1916 |
_mandatory_argument(opts.pithos, "--pithos") |
|
1917 |
# `pithos_user' is mandatory |
|
1918 |
_mandatory_argument(opts.pithos_user, "--pithos_user") |
|
1919 |
# `plankton' is mandatory |
|
1920 |
_mandatory_argument(opts.plankton, "--plankton") |
|
1827 | 1921 |
|
1828 |
# `token' is mandatory |
|
1829 |
if not opts.token: |
|
1922 |
return (opts, args) |
|
1923 |
|
|
1924 |
|
|
1925 |
def _mandatory_argument(Arg, Str): |
|
1926 |
if not Arg: |
|
1830 | 1927 |
print >>sys.stderr, red + \ |
1831 |
"The --token argument is mandatory.\n" + \
|
|
1928 |
"The " + Str + " argument is mandatory.\n" + \
|
|
1832 | 1929 |
normal |
1833 |
parser.print_help() |
|
1834 | 1930 |
sys.exit(1) |
1835 | 1931 |
|
1836 |
return (opts, args) |
|
1837 |
|
|
1838 | 1932 |
|
1839 | 1933 |
# -------------------------------------------------------------------- |
1840 | 1934 |
# Burnin main function |
... | ... | |
1853 | 1947 |
(opts, args) = parse_arguments(sys.argv[1:]) |
1854 | 1948 |
|
1855 | 1949 |
# Some global variables |
1856 |
global API, TOKEN, PLANKTON, PLANKTON_USER, NO_IPV6, VERBOSE, NOFAILFAST |
|
1950 |
global API, TOKEN, PLANKTON, PLANKTON_USER |
|
1951 |
global PITHOS, PITHOS_USER, NO_IPV6, VERBOSE, NOFAILFAST |
|
1857 | 1952 |
API = opts.api |
1858 | 1953 |
TOKEN = opts.token |
1859 | 1954 |
PLANKTON = opts.plankton |
1860 | 1955 |
PLANKTON_USER = opts.plankton_user |
1956 |
PITHOS = opts.pithos |
|
1957 |
PITHOS_USER = opts.pithos_user |
|
1861 | 1958 |
NO_IPV6 = opts.no_ipv6 |
1862 | 1959 |
VERBOSE = opts.verbose |
1863 | 1960 |
NOFAILFAST = opts.nofailfast |
... | ... | |
1944 | 2041 |
'images': ImagesTestCase, |
1945 | 2042 |
'flavors': FlavorsTestCase, |
1946 | 2043 |
'servers': ServersTestCase, |
2044 |
'pithos': PithosTestCase, |
|
1947 | 2045 |
'server_spawn': ServerTestCase, |
1948 | 2046 |
'network_spawn': NetworkTestCase} |
1949 | 2047 |
seq_cases = [] |
1950 | 2048 |
if 'all' in opts.tests: |
1951 |
seq_cases = [UnauthorizedTestCase, ImagesTestCase, FlavorsTestCase, |
|
1952 |
ServersTestCase, ServerTestCase, NetworkTestCase] |
|
2049 |
seq_cases = [UnauthorizedTestCase, ImagesTestCase, |
|
2050 |
FlavorsTestCase, ServersTestCase, |
|
2051 |
PithosTestCase, ServerTestCase, |
|
2052 |
NetworkTestCase] |
|
1953 | 2053 |
else: |
1954 | 2054 |
for test in opts.tests: |
1955 | 2055 |
seq_cases.append(test_dict[test]) |
Also available in: Unified diff