Statistics
| Branch: | Tag: | Revision:

root / snf-tools / synnefo_tools / burnin.py @ 3fc0273f

History | View | Annotate | Download (76.6 kB)

1 65462ca9 John Giannelos
#!/usr/bin/env python
2 5a140b23 Vangelis Koukis
3 5a140b23 Vangelis Koukis
# Copyright 2011 GRNET S.A. All rights reserved.
4 5a140b23 Vangelis Koukis
#
5 5a140b23 Vangelis Koukis
# Redistribution and use in source and binary forms, with or
6 5a140b23 Vangelis Koukis
# without modification, are permitted provided that the following
7 5a140b23 Vangelis Koukis
# conditions are met:
8 5a140b23 Vangelis Koukis
#
9 5a140b23 Vangelis Koukis
#   1. Redistributions of source code must retain the above
10 5a140b23 Vangelis Koukis
#      copyright notice, this list of conditions and the following
11 5a140b23 Vangelis Koukis
#      disclaimer.
12 5a140b23 Vangelis Koukis
#
13 5a140b23 Vangelis Koukis
#   2. Redistributions in binary form must reproduce the above
14 5a140b23 Vangelis Koukis
#      copyright notice, this list of conditions and the following
15 5a140b23 Vangelis Koukis
#      disclaimer in the documentation and/or other materials
16 5a140b23 Vangelis Koukis
#      provided with the distribution.
17 5a140b23 Vangelis Koukis
#
18 5a140b23 Vangelis Koukis
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
19 5a140b23 Vangelis Koukis
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 5a140b23 Vangelis Koukis
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 5a140b23 Vangelis Koukis
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
22 5a140b23 Vangelis Koukis
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 5a140b23 Vangelis Koukis
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 5a140b23 Vangelis Koukis
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
25 5a140b23 Vangelis Koukis
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26 5a140b23 Vangelis Koukis
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 5a140b23 Vangelis Koukis
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28 5a140b23 Vangelis Koukis
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 5a140b23 Vangelis Koukis
# POSSIBILITY OF SUCH DAMAGE.
30 5a140b23 Vangelis Koukis
#
31 5a140b23 Vangelis Koukis
# The views and conclusions contained in the software and
32 5a140b23 Vangelis Koukis
# documentation are those of the authors and should not be
33 5a140b23 Vangelis Koukis
# interpreted as representing official policies, either expressed
34 5a140b23 Vangelis Koukis
# or implied, of GRNET S.A.
35 5a140b23 Vangelis Koukis
36 5a140b23 Vangelis Koukis
"""Perform integration testing on a running Synnefo deployment"""
37 5a140b23 Vangelis Koukis
38 6e168615 Ilias Tsitsimpis
#import __main__
39 5a140b23 Vangelis Koukis
import datetime
40 5a140b23 Vangelis Koukis
import inspect
41 5a140b23 Vangelis Koukis
import logging
42 5a140b23 Vangelis Koukis
import os
43 11779b6c Ilias Tsitsimpis
import os.path
44 5a140b23 Vangelis Koukis
import paramiko
45 21bbbc9b Vangelis Koukis
import prctl
46 5a140b23 Vangelis Koukis
import subprocess
47 21bbbc9b Vangelis Koukis
import signal
48 5a140b23 Vangelis Koukis
import socket
49 5a140b23 Vangelis Koukis
import sys
50 5a140b23 Vangelis Koukis
import time
51 11779b6c Ilias Tsitsimpis
import tempfile
52 9659e075 John Giannelos
from base64 import b64encode
53 5a140b23 Vangelis Koukis
from IPy import IP
54 21bbbc9b Vangelis Koukis
from multiprocessing import Process, Queue
55 11779b6c Ilias Tsitsimpis
from random import choice, randint
56 22efe1fe John Giannelos
from optparse import OptionParser, OptionValueError
57 21bbbc9b Vangelis Koukis
58 96da37c8 John Giannelos
from kamaki.clients.compute import ComputeClient
59 96da37c8 John Giannelos
from kamaki.clients.cyclades import CycladesClient
60 946da8b6 John Giannelos
from kamaki.clients.image import ImageClient
61 11779b6c Ilias Tsitsimpis
from kamaki.clients.pithos import PithosClient
62 21dcb666 John Giannelos
from kamaki.clients import ClientError
63 96da37c8 John Giannelos
64 bc14ba88 Vangelis Koukis
from vncauthproxy.d3des import generate_response as d3des_generate_response
65 5a140b23 Vangelis Koukis
66 5a140b23 Vangelis Koukis
# Use backported unittest functionality if Python < 2.7
67 5a140b23 Vangelis Koukis
try:
68 5a140b23 Vangelis Koukis
    import unittest2 as unittest
69 5a140b23 Vangelis Koukis
except ImportError:
70 bc14ba88 Vangelis Koukis
    if sys.version_info < (2, 7):
71 bc14ba88 Vangelis Koukis
        raise Exception("The unittest2 package is required for Python < 2.7")
72 5a140b23 Vangelis Koukis
    import unittest
73 5a140b23 Vangelis Koukis
74 6e168615 Ilias Tsitsimpis
# --------------------------------------------------------------------
75 6e168615 Ilias Tsitsimpis
# Global Variables
76 6e168615 Ilias Tsitsimpis
API = None
77 6e168615 Ilias Tsitsimpis
TOKEN = None
78 6e168615 Ilias Tsitsimpis
PLANKTON = None
79 6e168615 Ilias Tsitsimpis
PLANKTON_USER = None
80 11779b6c Ilias Tsitsimpis
PITHOS = None
81 11779b6c Ilias Tsitsimpis
PITHOS_USER = None
82 6e168615 Ilias Tsitsimpis
NO_IPV6 = None
83 6e168615 Ilias Tsitsimpis
DEFAULT_PLANKTON_USER = "images@okeanos.grnet.gr"
84 6e168615 Ilias Tsitsimpis
NOFAILFAST = None
85 6e168615 Ilias Tsitsimpis
VERBOSE = None
86 6e168615 Ilias Tsitsimpis
87 6e168615 Ilias Tsitsimpis
# A unique id identifying this test run
88 6e168615 Ilias Tsitsimpis
TEST_RUN_ID = datetime.datetime.strftime(datetime.datetime.now(),
89 6e168615 Ilias Tsitsimpis
                                         "%Y%m%d%H%M%S")
90 6e168615 Ilias Tsitsimpis
SNF_TEST_PREFIX = "snf-test-"
91 6e168615 Ilias Tsitsimpis
92 6e168615 Ilias Tsitsimpis
red = '\x1b[31m'
93 6e168615 Ilias Tsitsimpis
yellow = '\x1b[33m'
94 6e168615 Ilias Tsitsimpis
green = '\x1b[32m'
95 6e168615 Ilias Tsitsimpis
normal = '\x1b[0m'
96 6e168615 Ilias Tsitsimpis
97 5a140b23 Vangelis Koukis
98 6e168615 Ilias Tsitsimpis
# --------------------------------------------------------------------
99 2a410f76 Ilias Tsitsimpis
# Global functions
100 2a410f76 Ilias Tsitsimpis
def _ssh_execute(hostip, username, password, command):
101 2a410f76 Ilias Tsitsimpis
    """Execute a command via ssh"""
102 2a410f76 Ilias Tsitsimpis
    ssh = paramiko.SSHClient()
103 2a410f76 Ilias Tsitsimpis
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
104 2a410f76 Ilias Tsitsimpis
    try:
105 2a410f76 Ilias Tsitsimpis
        ssh.connect(hostip, username=username, password=password)
106 2a410f76 Ilias Tsitsimpis
    except socket.error:
107 2a410f76 Ilias Tsitsimpis
        raise AssertionError
108 2a410f76 Ilias Tsitsimpis
    try:
109 2a410f76 Ilias Tsitsimpis
        stdin, stdout, stderr = ssh.exec_command(command)
110 2a410f76 Ilias Tsitsimpis
    except paramiko.SSHException:
111 2a410f76 Ilias Tsitsimpis
        raise AssertionError
112 2a410f76 Ilias Tsitsimpis
    status = stdout.channel.recv_exit_status()
113 2a410f76 Ilias Tsitsimpis
    output = stdout.readlines()
114 2a410f76 Ilias Tsitsimpis
    ssh.close()
115 2a410f76 Ilias Tsitsimpis
    return output, status
116 2a410f76 Ilias Tsitsimpis
117 2a410f76 Ilias Tsitsimpis
118 2a410f76 Ilias Tsitsimpis
# --------------------------------------------------------------------
119 6e168615 Ilias Tsitsimpis
# BurninTestReulst class
120 66eba2cf John Giannelos
class BurninTestResult(unittest.TextTestResult):
121 66eba2cf John Giannelos
    def addSuccess(self, test):
122 66eba2cf John Giannelos
        super(BurninTestResult, self).addSuccess(test)
123 66eba2cf John Giannelos
        if self.showAll:
124 3e4c5c32 John Giannelos
            if hasattr(test, 'result_dict'):
125 66eba2cf John Giannelos
                run_details = test.result_dict
126 66eba2cf John Giannelos
127 66eba2cf John Giannelos
                self.stream.write("\n")
128 66eba2cf John Giannelos
                for i in run_details:
129 66eba2cf John Giannelos
                    self.stream.write("%s : %s \n" % (i, run_details[i]))
130 66eba2cf John Giannelos
                self.stream.write("\n")
131 66eba2cf John Giannelos
132 66eba2cf John Giannelos
        elif self.dots:
133 66eba2cf John Giannelos
            self.stream.write('.')
134 6e168615 Ilias Tsitsimpis
            self.stream.flush()
135 6e168615 Ilias Tsitsimpis
136 66eba2cf John Giannelos
    def addError(self, test, err):
137 66eba2cf John Giannelos
        super(BurninTestResult, self).addError(test, err)
138 66eba2cf John Giannelos
        if self.showAll:
139 66eba2cf John Giannelos
            self.stream.writeln("ERROR")
140 3e4c5c32 John Giannelos
            if hasattr(test, 'result_dict'):
141 3e4c5c32 John Giannelos
                run_details = test.result_dict
142 66eba2cf John Giannelos
143 3e4c5c32 John Giannelos
                self.stream.write("\n")
144 3e4c5c32 John Giannelos
                for i in run_details:
145 3e4c5c32 John Giannelos
                    self.stream.write("%s : %s \n" % (i, run_details[i]))
146 3e4c5c32 John Giannelos
                self.stream.write("\n")
147 66eba2cf John Giannelos
148 66eba2cf John Giannelos
        elif self.dots:
149 66eba2cf John Giannelos
            self.stream.write('E')
150 66eba2cf John Giannelos
            self.stream.flush()
151 66eba2cf John Giannelos
152 66eba2cf John Giannelos
    def addFailure(self, test, err):
153 66eba2cf John Giannelos
        super(BurninTestResult, self).addFailure(test, err)
154 66eba2cf John Giannelos
        if self.showAll:
155 66eba2cf John Giannelos
            self.stream.writeln("FAIL")
156 3e4c5c32 John Giannelos
            if hasattr(test, 'result_dict'):
157 3e4c5c32 John Giannelos
                run_details = test.result_dict
158 66eba2cf John Giannelos
159 3e4c5c32 John Giannelos
                self.stream.write("\n")
160 3e4c5c32 John Giannelos
                for i in run_details:
161 3e4c5c32 John Giannelos
                    self.stream.write("%s : %s \n" % (i, run_details[i]))
162 3e4c5c32 John Giannelos
                self.stream.write("\n")
163 66eba2cf John Giannelos
164 66eba2cf John Giannelos
        elif self.dots:
165 66eba2cf John Giannelos
            self.stream.write('F')
166 66eba2cf John Giannelos
            self.stream.flush()
167 66eba2cf John Giannelos
168 66eba2cf John Giannelos
169 6e168615 Ilias Tsitsimpis
# --------------------------------------------------------------------
170 6e168615 Ilias Tsitsimpis
# Format Results
171 746540cd John Giannelos
class burninFormatter(logging.Formatter):
172 746540cd John Giannelos
    err_fmt = red + "ERROR: %(msg)s" + normal
173 9b013c3a John Giannelos
    dbg_fmt = green + "* %(msg)s" + normal
174 746540cd John Giannelos
    info_fmt = "%(msg)s"
175 746540cd John Giannelos
176 746540cd John Giannelos
    def __init__(self, fmt="%(levelno)s: %(msg)s"):
177 746540cd John Giannelos
        logging.Formatter.__init__(self, fmt)
178 746540cd John Giannelos
179 746540cd John Giannelos
    def format(self, record):
180 746540cd John Giannelos
        format_orig = self._fmt
181 746540cd John Giannelos
        # Replace the original format with one customized by logging level
182 746540cd John Giannelos
        if record.levelno == 10:    # DEBUG
183 746540cd John Giannelos
            self._fmt = burninFormatter.dbg_fmt
184 746540cd John Giannelos
        elif record.levelno == 20:  # INFO
185 746540cd John Giannelos
            self._fmt = burninFormatter.info_fmt
186 746540cd John Giannelos
        elif record.levelno == 40:  # ERROR
187 746540cd John Giannelos
            self._fmt = burninFormatter.err_fmt
188 746540cd John Giannelos
        result = logging.Formatter.format(self, record)
189 746540cd John Giannelos
        self._fmt = format_orig
190 746540cd John Giannelos
        return result
191 746540cd John Giannelos
192 00f87624 Vangelis Koukis
log = logging.getLogger("burnin")
193 746540cd John Giannelos
log.setLevel(logging.DEBUG)
194 746540cd John Giannelos
handler = logging.StreamHandler()
195 746540cd John Giannelos
handler.setFormatter(burninFormatter())
196 746540cd John Giannelos
log.addHandler(handler)
197 5a140b23 Vangelis Koukis
198 2bcfb712 John Giannelos
199 6e168615 Ilias Tsitsimpis
# --------------------------------------------------------------------
200 6e168615 Ilias Tsitsimpis
# UnauthorizedTestCase class
201 5a140b23 Vangelis Koukis
class UnauthorizedTestCase(unittest.TestCase):
202 6e168615 Ilias Tsitsimpis
    """Test unauthorized access"""
203 66eba2cf John Giannelos
    @classmethod
204 66eba2cf John Giannelos
    def setUpClass(cls):
205 66eba2cf John Giannelos
        cls.result_dict = dict()
206 66eba2cf John Giannelos
207 5a140b23 Vangelis Koukis
    def test_unauthorized_access(self):
208 5a140b23 Vangelis Koukis
        """Test access without a valid token fails"""
209 81e8cbf6 John Giannelos
        log.info("Authentication test")
210 1c636ad6 John Giannelos
        falseToken = '12345'
211 2bcfb712 John Giannelos
        c = ComputeClient(API, falseToken)
212 1c636ad6 John Giannelos
213 5a140b23 Vangelis Koukis
        with self.assertRaises(ClientError) as cm:
214 5a140b23 Vangelis Koukis
            c.list_servers()
215 21dcb666 John Giannelos
            self.assertEqual(cm.exception.status, 401)
216 5a140b23 Vangelis Koukis
217 5a140b23 Vangelis Koukis
218 6e168615 Ilias Tsitsimpis
# --------------------------------------------------------------------
219 95a87099 Ilias Tsitsimpis
# This class gest replicated into Images TestCases dynamically
220 5a140b23 Vangelis Koukis
class ImagesTestCase(unittest.TestCase):
221 5a140b23 Vangelis Koukis
    """Test image lists for consistency"""
222 5a140b23 Vangelis Koukis
    @classmethod
223 5a140b23 Vangelis Koukis
    def setUpClass(cls):
224 5a140b23 Vangelis Koukis
        """Initialize kamaki, get (detailed) list of images"""
225 5a140b23 Vangelis Koukis
        log.info("Getting simple and detailed list of images")
226 846980fe John Giannelos
        cls.client = ComputeClient(API, TOKEN)
227 946da8b6 John Giannelos
        cls.plankton = ImageClient(PLANKTON, TOKEN)
228 946da8b6 John Giannelos
        cls.images = cls.plankton.list_public()
229 946da8b6 John Giannelos
        cls.dimages = cls.plankton.list_public(detail=True)
230 66eba2cf John Giannelos
        cls.result_dict = dict()
231 95a87099 Ilias Tsitsimpis
        # Create temp directory and store it inside our class
232 95a87099 Ilias Tsitsimpis
        # XXX: In my machine /tmp has not enough space
233 95a87099 Ilias Tsitsimpis
        #      so use current directory to be sure.
234 95a87099 Ilias Tsitsimpis
        cls.temp_dir = tempfile.mkdtemp(dir=os.getcwd())
235 95a87099 Ilias Tsitsimpis
        cls.temp_image_name = \
236 95a87099 Ilias Tsitsimpis
            SNF_TEST_PREFIX + cls.imageid + ".diskdump"
237 5a140b23 Vangelis Koukis
238 5a140b23 Vangelis Koukis
    def test_001_list_images(self):
239 5a140b23 Vangelis Koukis
        """Test image list actually returns images"""
240 6207533f John Giannelos
        self.assertGreater(len(self.images), 0)
241 74ec726f John Giannelos
242 5a140b23 Vangelis Koukis
    def test_002_list_images_detailed(self):
243 5a140b23 Vangelis Koukis
        """Test detailed image list is the same length as list"""
244 6207533f John Giannelos
        self.assertEqual(len(self.dimages), len(self.images))
245 74ec726f John Giannelos
246 5a140b23 Vangelis Koukis
    def test_003_same_image_names(self):
247 5a140b23 Vangelis Koukis
        """Test detailed and simple image list contain same names"""
248 5a140b23 Vangelis Koukis
        names = sorted(map(lambda x: x["name"], self.images))
249 5a140b23 Vangelis Koukis
        dnames = sorted(map(lambda x: x["name"], self.dimages))
250 5a140b23 Vangelis Koukis
        self.assertEqual(names, dnames)
251 5a140b23 Vangelis Koukis
252 5a140b23 Vangelis Koukis
    def test_004_unique_image_names(self):
253 946da8b6 John Giannelos
        """Test system images have unique names"""
254 946da8b6 John Giannelos
        sys_images = filter(lambda x: x['owner'] == PLANKTON_USER,
255 946da8b6 John Giannelos
                            self.dimages)
256 946da8b6 John Giannelos
        names = sorted(map(lambda x: x["name"], sys_images))
257 5a140b23 Vangelis Koukis
        self.assertEqual(sorted(list(set(names))), names)
258 5a140b23 Vangelis Koukis
259 5a140b23 Vangelis Koukis
    def test_005_image_metadata(self):
260 5a140b23 Vangelis Koukis
        """Test every image has specific metadata defined"""
261 2e3b7dc8 John Giannelos
        keys = frozenset(["osfamily", "root_partition"])
262 846980fe John Giannelos
        details = self.client.list_images(detail=True)
263 846980fe John Giannelos
        for i in details:
264 5a140b23 Vangelis Koukis
            self.assertTrue(keys.issubset(i["metadata"]["values"].keys()))
265 5a140b23 Vangelis Koukis
266 95a87099 Ilias Tsitsimpis
    def test_006_download_image(self):
267 95a87099 Ilias Tsitsimpis
        """Download image from pithos+"""
268 95a87099 Ilias Tsitsimpis
        # Get image location
269 95a87099 Ilias Tsitsimpis
        image = filter(
270 95a87099 Ilias Tsitsimpis
            lambda x: x['id'] == self.imageid, self.dimages)[0]
271 95a87099 Ilias Tsitsimpis
        image_location = \
272 95a87099 Ilias Tsitsimpis
            image['location'].replace("://", " ").replace("/", " ").split()
273 95a87099 Ilias Tsitsimpis
        log.info("Download image, with owner %s\n\tcontainer %s, and name %s"
274 95a87099 Ilias Tsitsimpis
                 % (image_location[1], image_location[2], image_location[3]))
275 95a87099 Ilias Tsitsimpis
        pithos_client = PithosClient(PITHOS, TOKEN, image_location[1])
276 95a87099 Ilias Tsitsimpis
        pithos_client.container = image_location[2]
277 95a87099 Ilias Tsitsimpis
        temp_file = os.path.join(self.temp_dir, self.temp_image_name)
278 95a87099 Ilias Tsitsimpis
        with open(temp_file, "wb+") as f:
279 95a87099 Ilias Tsitsimpis
            pithos_client.download_object(image_location[3], f)
280 95a87099 Ilias Tsitsimpis
281 95a87099 Ilias Tsitsimpis
    def test_007_upload_image(self):
282 95a87099 Ilias Tsitsimpis
        """Upload and register image"""
283 95a87099 Ilias Tsitsimpis
        temp_file = os.path.join(self.temp_dir, self.temp_image_name)
284 95a87099 Ilias Tsitsimpis
        log.info("Upload image to pithos+")
285 95a87099 Ilias Tsitsimpis
        # Create container `images'
286 95a87099 Ilias Tsitsimpis
        pithos_client = PithosClient(PITHOS, TOKEN, PITHOS_USER)
287 95a87099 Ilias Tsitsimpis
        pithos_client.container = "images"
288 95a87099 Ilias Tsitsimpis
        pithos_client.container_put()
289 95a87099 Ilias Tsitsimpis
        with open(temp_file, "rb+") as f:
290 95a87099 Ilias Tsitsimpis
            pithos_client.upload_object(self.temp_image_name, f)
291 95a87099 Ilias Tsitsimpis
        log.info("Register image to plankton")
292 95a87099 Ilias Tsitsimpis
        location = "pithos://" + PITHOS_USER + \
293 95a87099 Ilias Tsitsimpis
            "/images/" + self.temp_image_name
294 95a87099 Ilias Tsitsimpis
        params = {'is_public': True}
295 95a87099 Ilias Tsitsimpis
        properties = {'OSFAMILY': "linux", 'ROOT_PARTITION': 1}
296 95a87099 Ilias Tsitsimpis
        self.plankton.register(self.temp_image_name, location,
297 95a87099 Ilias Tsitsimpis
                               params, properties)
298 95a87099 Ilias Tsitsimpis
299 5a140b23 Vangelis Koukis
300 6e168615 Ilias Tsitsimpis
# --------------------------------------------------------------------
301 6e168615 Ilias Tsitsimpis
# FlavorsTestCase class
302 5a140b23 Vangelis Koukis
class FlavorsTestCase(unittest.TestCase):
303 5a140b23 Vangelis Koukis
    """Test flavor lists for consistency"""
304 5a140b23 Vangelis Koukis
    @classmethod
305 5a140b23 Vangelis Koukis
    def setUpClass(cls):
306 5a140b23 Vangelis Koukis
        """Initialize kamaki, get (detailed) list of flavors"""
307 5a140b23 Vangelis Koukis
        log.info("Getting simple and detailed list of flavors")
308 567ffb85 John Giannelos
        cls.client = ComputeClient(API, TOKEN)
309 5a140b23 Vangelis Koukis
        cls.flavors = cls.client.list_flavors()
310 5a140b23 Vangelis Koukis
        cls.dflavors = cls.client.list_flavors(detail=True)
311 66eba2cf John Giannelos
        cls.result_dict = dict()
312 5a140b23 Vangelis Koukis
313 5a140b23 Vangelis Koukis
    def test_001_list_flavors(self):
314 5a140b23 Vangelis Koukis
        """Test flavor list actually returns flavors"""
315 5a140b23 Vangelis Koukis
        self.assertGreater(len(self.flavors), 0)
316 5a140b23 Vangelis Koukis
317 5a140b23 Vangelis Koukis
    def test_002_list_flavors_detailed(self):
318 5a140b23 Vangelis Koukis
        """Test detailed flavor list is the same length as list"""
319 5a140b23 Vangelis Koukis
        self.assertEquals(len(self.dflavors), len(self.flavors))
320 5a140b23 Vangelis Koukis
321 5a140b23 Vangelis Koukis
    def test_003_same_flavor_names(self):
322 5a140b23 Vangelis Koukis
        """Test detailed and simple flavor list contain same names"""
323 5a140b23 Vangelis Koukis
        names = sorted(map(lambda x: x["name"], self.flavors))
324 5a140b23 Vangelis Koukis
        dnames = sorted(map(lambda x: x["name"], self.dflavors))
325 5a140b23 Vangelis Koukis
        self.assertEqual(names, dnames)
326 5a140b23 Vangelis Koukis
327 5a140b23 Vangelis Koukis
    def test_004_unique_flavor_names(self):
328 5a140b23 Vangelis Koukis
        """Test flavors have unique names"""
329 5a140b23 Vangelis Koukis
        names = sorted(map(lambda x: x["name"], self.flavors))
330 5a140b23 Vangelis Koukis
        self.assertEqual(sorted(list(set(names))), names)
331 5a140b23 Vangelis Koukis
332 5a140b23 Vangelis Koukis
    def test_005_well_formed_flavor_names(self):
333 5a140b23 Vangelis Koukis
        """Test flavors have names of the form CxxRyyDzz
334 5a140b23 Vangelis Koukis
        Where xx is vCPU count, yy is RAM in MiB, zz is Disk in GiB
335 5a140b23 Vangelis Koukis
        """
336 5a140b23 Vangelis Koukis
        for f in self.dflavors:
337 5a140b23 Vangelis Koukis
            self.assertEqual("C%dR%dD%d" % (f["cpu"], f["ram"], f["disk"]),
338 5a140b23 Vangelis Koukis
                             f["name"],
339 5a140b23 Vangelis Koukis
                             "Flavor %s does not match its specs." % f["name"])
340 5a140b23 Vangelis Koukis
341 5a140b23 Vangelis Koukis
342 6e168615 Ilias Tsitsimpis
# --------------------------------------------------------------------
343 6e168615 Ilias Tsitsimpis
# ServersTestCase class
344 5a140b23 Vangelis Koukis
class ServersTestCase(unittest.TestCase):
345 5a140b23 Vangelis Koukis
    """Test server lists for consistency"""
346 5a140b23 Vangelis Koukis
    @classmethod
347 5a140b23 Vangelis Koukis
    def setUpClass(cls):
348 5a140b23 Vangelis Koukis
        """Initialize kamaki, get (detailed) list of servers"""
349 5a140b23 Vangelis Koukis
        log.info("Getting simple and detailed list of servers")
350 1c636ad6 John Giannelos
351 567ffb85 John Giannelos
        cls.client = ComputeClient(API, TOKEN)
352 5a140b23 Vangelis Koukis
        cls.servers = cls.client.list_servers()
353 5a140b23 Vangelis Koukis
        cls.dservers = cls.client.list_servers(detail=True)
354 66eba2cf John Giannelos
        cls.result_dict = dict()
355 5a140b23 Vangelis Koukis
356 139d3a0b Ilias Tsitsimpis
    # def test_001_list_servers(self):
357 139d3a0b Ilias Tsitsimpis
    #     """Test server list actually returns servers"""
358 139d3a0b Ilias Tsitsimpis
    #     self.assertGreater(len(self.servers), 0)
359 5a140b23 Vangelis Koukis
360 5a140b23 Vangelis Koukis
    def test_002_list_servers_detailed(self):
361 5a140b23 Vangelis Koukis
        """Test detailed server list is the same length as list"""
362 5a140b23 Vangelis Koukis
        self.assertEqual(len(self.dservers), len(self.servers))
363 5a140b23 Vangelis Koukis
364 5a140b23 Vangelis Koukis
    def test_003_same_server_names(self):
365 5a140b23 Vangelis Koukis
        """Test detailed and simple flavor list contain same names"""
366 5a140b23 Vangelis Koukis
        names = sorted(map(lambda x: x["name"], self.servers))
367 5a140b23 Vangelis Koukis
        dnames = sorted(map(lambda x: x["name"], self.dservers))
368 5a140b23 Vangelis Koukis
        self.assertEqual(names, dnames)
369 5a140b23 Vangelis Koukis
370 5a140b23 Vangelis Koukis
371 11779b6c Ilias Tsitsimpis
# --------------------------------------------------------------------
372 11779b6c Ilias Tsitsimpis
# Pithos Test Cases
373 11779b6c Ilias Tsitsimpis
class PithosTestCase(unittest.TestCase):
374 11779b6c Ilias Tsitsimpis
    """Test pithos functionality"""
375 11779b6c Ilias Tsitsimpis
    @classmethod
376 11779b6c Ilias Tsitsimpis
    def setUpClass(cls):
377 11779b6c Ilias Tsitsimpis
        """Initialize kamaki, get list of containers"""
378 11779b6c Ilias Tsitsimpis
        log.info("Getting list of containers")
379 11779b6c Ilias Tsitsimpis
380 11779b6c Ilias Tsitsimpis
        cls.client = PithosClient(PITHOS, TOKEN, PITHOS_USER)
381 11779b6c Ilias Tsitsimpis
        cls.containers = cls.client.list_containers()
382 11779b6c Ilias Tsitsimpis
        cls.result_dict = dict()
383 11779b6c Ilias Tsitsimpis
384 11779b6c Ilias Tsitsimpis
    def test_001_list_containers(self):
385 11779b6c Ilias Tsitsimpis
        """Test container list actually returns containers"""
386 11779b6c Ilias Tsitsimpis
        self.assertGreater(len(self.containers), 0)
387 11779b6c Ilias Tsitsimpis
388 11779b6c Ilias Tsitsimpis
    def test_002_unique_containers(self):
389 11779b6c Ilias Tsitsimpis
        """Test if containers have unique names"""
390 11779b6c Ilias Tsitsimpis
        names = [n['name'] for n in self.containers]
391 11779b6c Ilias Tsitsimpis
        names = sorted(names)
392 11779b6c Ilias Tsitsimpis
        self.assertEqual(sorted(list(set(names))), names)
393 11779b6c Ilias Tsitsimpis
394 11779b6c Ilias Tsitsimpis
    def test_003_create_container(self):
395 11779b6c Ilias Tsitsimpis
        """Test create a container"""
396 11779b6c Ilias Tsitsimpis
        rand_num = randint(1000, 9999)
397 11779b6c Ilias Tsitsimpis
        rand_name = "%s%s" % (SNF_TEST_PREFIX, rand_num)
398 11779b6c Ilias Tsitsimpis
        names = [n['name'] for n in self.containers]
399 11779b6c Ilias Tsitsimpis
        while rand_name in names:
400 11779b6c Ilias Tsitsimpis
            rand_num = randint(1000, 9999)
401 11779b6c Ilias Tsitsimpis
            rand_name = "%s%s" % (SNF_TEST_PREFIX, rand_num)
402 11779b6c Ilias Tsitsimpis
        # Create container
403 11779b6c Ilias Tsitsimpis
        self.client.container = rand_name
404 11779b6c Ilias Tsitsimpis
        self.client.container_put()
405 11779b6c Ilias Tsitsimpis
        # Get list of containers
406 11779b6c Ilias Tsitsimpis
        new_containers = self.client.list_containers()
407 11779b6c Ilias Tsitsimpis
        new_container_names = [n['name'] for n in new_containers]
408 11779b6c Ilias Tsitsimpis
        self.assertIn(rand_name, new_container_names)
409 11779b6c Ilias Tsitsimpis
410 11779b6c Ilias Tsitsimpis
    def test_004_upload(self):
411 11779b6c Ilias Tsitsimpis
        """Test uploading something to pithos+"""
412 11779b6c Ilias Tsitsimpis
        # Create a tmp file
413 11779b6c Ilias Tsitsimpis
        with tempfile.TemporaryFile() as f:
414 11779b6c Ilias Tsitsimpis
            f.write("This is a temp file")
415 11779b6c Ilias Tsitsimpis
            f.seek(0, 0)
416 11779b6c Ilias Tsitsimpis
            # Where to save file
417 11779b6c Ilias Tsitsimpis
            self.client.upload_object("test.txt", f)
418 11779b6c Ilias Tsitsimpis
419 11779b6c Ilias Tsitsimpis
    def test_005_download(self):
420 11779b6c Ilias Tsitsimpis
        """Test download something from pithos+"""
421 11779b6c Ilias Tsitsimpis
        # Create tmp directory to save file
422 11779b6c Ilias Tsitsimpis
        tmp_dir = tempfile.mkdtemp()
423 11779b6c Ilias Tsitsimpis
        tmp_file = os.path.join(tmp_dir, "test.txt")
424 11779b6c Ilias Tsitsimpis
        with open(tmp_file, "wb+") as f:
425 11779b6c Ilias Tsitsimpis
            self.client.download_object("test.txt", f)
426 11779b6c Ilias Tsitsimpis
            # Read file
427 11779b6c Ilias Tsitsimpis
            f.seek(0, 0)
428 11779b6c Ilias Tsitsimpis
            content = f.read()
429 11779b6c Ilias Tsitsimpis
        # Remove files
430 11779b6c Ilias Tsitsimpis
        os.unlink(tmp_file)
431 11779b6c Ilias Tsitsimpis
        os.rmdir(tmp_dir)
432 11779b6c Ilias Tsitsimpis
        # Compare results
433 11779b6c Ilias Tsitsimpis
        self.assertEqual(content, "This is a temp file")
434 11779b6c Ilias Tsitsimpis
435 11779b6c Ilias Tsitsimpis
    def test_006_remove(self):
436 11779b6c Ilias Tsitsimpis
        """Test removing files and containers"""
437 11779b6c Ilias Tsitsimpis
        cont_name = self.client.container
438 11779b6c Ilias Tsitsimpis
        self.client.del_object("test.txt")
439 11779b6c Ilias Tsitsimpis
        self.client.purge_container()
440 11779b6c Ilias Tsitsimpis
        # List containers
441 11779b6c Ilias Tsitsimpis
        containers = self.client.list_containers()
442 11779b6c Ilias Tsitsimpis
        cont_names = [n['name'] for n in containers]
443 11779b6c Ilias Tsitsimpis
        self.assertNotIn(cont_name, cont_names)
444 11779b6c Ilias Tsitsimpis
445 11779b6c Ilias Tsitsimpis
446 11779b6c Ilias Tsitsimpis
# --------------------------------------------------------------------
447 5a140b23 Vangelis Koukis
# This class gets replicated into actual TestCases dynamically
448 5a140b23 Vangelis Koukis
class SpawnServerTestCase(unittest.TestCase):
449 5a140b23 Vangelis Koukis
    """Test scenario for server of the specified image"""
450 5a140b23 Vangelis Koukis
    @classmethod
451 5a140b23 Vangelis Koukis
    def setUpClass(cls):
452 5a140b23 Vangelis Koukis
        """Initialize a kamaki instance"""
453 6e168615 Ilias Tsitsimpis
        log.info("Spawning server for image `%s'" % cls.imagename)
454 567ffb85 John Giannelos
        cls.client = ComputeClient(API, TOKEN)
455 567ffb85 John Giannelos
        cls.cyclades = CycladesClient(API, TOKEN)
456 66eba2cf John Giannelos
        cls.result_dict = dict()
457 5a140b23 Vangelis Koukis
458 5a140b23 Vangelis Koukis
    def _get_ipv4(self, server):
459 bc14ba88 Vangelis Koukis
        """Get the public IPv4 of a server from the detailed server info"""
460 1c636ad6 John Giannelos
461 e50133da John Giannelos
        nics = server["attachments"]["values"]
462 2aaa1336 John Giannelos
463 e50133da John Giannelos
        for nic in nics:
464 e50133da John Giannelos
            net_id = nic["network_id"]
465 6e168615 Ilias Tsitsimpis
            if self.cyclades.get_network_details(net_id)["public"]:
466 e50133da John Giannelos
                public_addrs = nic["ipv4"]
467 6e168615 Ilias Tsitsimpis
468 6e168615 Ilias Tsitsimpis
        self.assertTrue(public_addrs is not None)
469 2aaa1336 John Giannelos
470 e50133da John Giannelos
        return public_addrs
471 5a140b23 Vangelis Koukis
472 5a140b23 Vangelis Koukis
    def _get_ipv6(self, server):
473 bc14ba88 Vangelis Koukis
        """Get the public IPv6 of a server from the detailed server info"""
474 2aaa1336 John Giannelos
475 e50133da John Giannelos
        nics = server["attachments"]["values"]
476 2aaa1336 John Giannelos
477 e50133da John Giannelos
        for nic in nics:
478 e50133da John Giannelos
            net_id = nic["network_id"]
479 6e168615 Ilias Tsitsimpis
            if self.cyclades.get_network_details(net_id)["public"]:
480 e50133da John Giannelos
                public_addrs = nic["ipv6"]
481 2aaa1336 John Giannelos
482 6e168615 Ilias Tsitsimpis
        self.assertTrue(public_addrs is not None)
483 2aaa1336 John Giannelos
484 6e168615 Ilias Tsitsimpis
        return public_addrs
485 5a140b23 Vangelis Koukis
486 6e168615 Ilias Tsitsimpis
    def _connect_loginname(self, os_value):
487 bc14ba88 Vangelis Koukis
        """Return the login name for connections based on the server OS"""
488 6e168615 Ilias Tsitsimpis
        if os_value in ("Ubuntu", "Kubuntu", "Fedora"):
489 21bbbc9b Vangelis Koukis
            return "user"
490 6e168615 Ilias Tsitsimpis
        elif os_value in ("windows", "windows_alpha1"):
491 21bbbc9b Vangelis Koukis
            return "Administrator"
492 bc14ba88 Vangelis Koukis
        else:
493 21bbbc9b Vangelis Koukis
            return "root"
494 bc14ba88 Vangelis Koukis
495 bc14ba88 Vangelis Koukis
    def _verify_server_status(self, current_status, new_status):
496 bc14ba88 Vangelis Koukis
        """Verify a server has switched to a specified status"""
497 bc14ba88 Vangelis Koukis
        server = self.client.get_server_details(self.serverid)
498 21bbbc9b Vangelis Koukis
        if server["status"] not in (current_status, new_status):
499 21bbbc9b Vangelis Koukis
            return None  # Do not raise exception, return so the test fails
500 bc14ba88 Vangelis Koukis
        self.assertEquals(server["status"], new_status)
501 bc14ba88 Vangelis Koukis
502 bc14ba88 Vangelis Koukis
    def _get_connected_tcp_socket(self, family, host, port):
503 bc14ba88 Vangelis Koukis
        """Get a connected socket from the specified family to host:port"""
504 bc14ba88 Vangelis Koukis
        sock = None
505 bc14ba88 Vangelis Koukis
        for res in \
506 bc14ba88 Vangelis Koukis
            socket.getaddrinfo(host, port, family, socket.SOCK_STREAM, 0,
507 bc14ba88 Vangelis Koukis
                               socket.AI_PASSIVE):
508 bc14ba88 Vangelis Koukis
            af, socktype, proto, canonname, sa = res
509 bc14ba88 Vangelis Koukis
            try:
510 bc14ba88 Vangelis Koukis
                sock = socket.socket(af, socktype, proto)
511 6e168615 Ilias Tsitsimpis
            except socket.error:
512 bc14ba88 Vangelis Koukis
                sock = None
513 bc14ba88 Vangelis Koukis
                continue
514 bc14ba88 Vangelis Koukis
            try:
515 bc14ba88 Vangelis Koukis
                sock.connect(sa)
516 6e168615 Ilias Tsitsimpis
            except socket.error:
517 bc14ba88 Vangelis Koukis
                sock.close()
518 bc14ba88 Vangelis Koukis
                sock = None
519 bc14ba88 Vangelis Koukis
                continue
520 bc14ba88 Vangelis Koukis
        self.assertIsNotNone(sock)
521 bc14ba88 Vangelis Koukis
        return sock
522 bc14ba88 Vangelis Koukis
523 bc14ba88 Vangelis Koukis
    def _ping_once(self, ipv6, ip):
524 bc14ba88 Vangelis Koukis
        """Test server responds to a single IPv4 or IPv6 ping"""
525 bc14ba88 Vangelis Koukis
        cmd = "ping%s -c 2 -w 3 %s" % ("6" if ipv6 else "", ip)
526 bc14ba88 Vangelis Koukis
        ping = subprocess.Popen(cmd, shell=True,
527 bc14ba88 Vangelis Koukis
                                stdout=subprocess.PIPE, stderr=subprocess.PIPE)
528 bc14ba88 Vangelis Koukis
        (stdout, stderr) = ping.communicate()
529 bc14ba88 Vangelis Koukis
        ret = ping.wait()
530 bc14ba88 Vangelis Koukis
        self.assertEquals(ret, 0)
531 5a140b23 Vangelis Koukis
532 bc14ba88 Vangelis Koukis
    def _get_hostname_over_ssh(self, hostip, username, password):
533 2a410f76 Ilias Tsitsimpis
        lines, status = _ssh_execute(
534 2a410f76 Ilias Tsitsimpis
            hostip, username, password, "hostname")
535 bc14ba88 Vangelis Koukis
        self.assertEqual(len(lines), 1)
536 4fdd25ab Vangelis Koukis
        return lines[0]
537 bc14ba88 Vangelis Koukis
538 bc14ba88 Vangelis Koukis
    def _try_until_timeout_expires(self, warn_timeout, fail_timeout,
539 bc14ba88 Vangelis Koukis
                                   opmsg, callable, *args, **kwargs):
540 bc14ba88 Vangelis Koukis
        if warn_timeout == fail_timeout:
541 5a140b23 Vangelis Koukis
            warn_timeout = fail_timeout + 1
542 5a140b23 Vangelis Koukis
        warn_tmout = time.time() + warn_timeout
543 5a140b23 Vangelis Koukis
        fail_tmout = time.time() + fail_timeout
544 5a140b23 Vangelis Koukis
        while True:
545 4fdd25ab Vangelis Koukis
            self.assertLess(time.time(), fail_tmout,
546 21bbbc9b Vangelis Koukis
                            "operation `%s' timed out" % opmsg)
547 5a140b23 Vangelis Koukis
            if time.time() > warn_tmout:
548 4fdd25ab Vangelis Koukis
                log.warning("Server %d: `%s' operation `%s' not done yet",
549 4fdd25ab Vangelis Koukis
                            self.serverid, self.servername, opmsg)
550 bc14ba88 Vangelis Koukis
            try:
551 4fdd25ab Vangelis Koukis
                log.info("%s... " % opmsg)
552 bc14ba88 Vangelis Koukis
                return callable(*args, **kwargs)
553 bc14ba88 Vangelis Koukis
            except AssertionError:
554 bc14ba88 Vangelis Koukis
                pass
555 5a140b23 Vangelis Koukis
            time.sleep(self.query_interval)
556 5a140b23 Vangelis Koukis
557 bc14ba88 Vangelis Koukis
    def _insist_on_tcp_connection(self, family, host, port):
558 21bbbc9b Vangelis Koukis
        familystr = {socket.AF_INET: "IPv4", socket.AF_INET6: "IPv6",
559 21bbbc9b Vangelis Koukis
                     socket.AF_UNSPEC: "Unspecified-IPv4/6"}
560 bc14ba88 Vangelis Koukis
        msg = "connect over %s to %s:%s" % \
561 bc14ba88 Vangelis Koukis
              (familystr.get(family, "Unknown"), host, port)
562 bc14ba88 Vangelis Koukis
        sock = self._try_until_timeout_expires(
563 6e168615 Ilias Tsitsimpis
            self.action_timeout, self.action_timeout,
564 6e168615 Ilias Tsitsimpis
            msg, self._get_connected_tcp_socket,
565 6e168615 Ilias Tsitsimpis
            family, host, port)
566 bc14ba88 Vangelis Koukis
        return sock
567 bc14ba88 Vangelis Koukis
568 bc14ba88 Vangelis Koukis
    def _insist_on_status_transition(self, current_status, new_status,
569 6e168615 Ilias Tsitsimpis
                                     fail_timeout, warn_timeout=None):
570 4fdd25ab Vangelis Koukis
        msg = "Server %d: `%s', waiting for %s -> %s" % \
571 4fdd25ab Vangelis Koukis
              (self.serverid, self.servername, current_status, new_status)
572 bc14ba88 Vangelis Koukis
        if warn_timeout is None:
573 bc14ba88 Vangelis Koukis
            warn_timeout = fail_timeout
574 bc14ba88 Vangelis Koukis
        self._try_until_timeout_expires(warn_timeout, fail_timeout,
575 bc14ba88 Vangelis Koukis
                                        msg, self._verify_server_status,
576 bc14ba88 Vangelis Koukis
                                        current_status, new_status)
577 21bbbc9b Vangelis Koukis
        # Ensure the status is actually the expected one
578 21bbbc9b Vangelis Koukis
        server = self.client.get_server_details(self.serverid)
579 21bbbc9b Vangelis Koukis
        self.assertEquals(server["status"], new_status)
580 bc14ba88 Vangelis Koukis
581 bc14ba88 Vangelis Koukis
    def _insist_on_ssh_hostname(self, hostip, username, password):
582 4fdd25ab Vangelis Koukis
        msg = "SSH to %s, as %s/%s" % (hostip, username, password)
583 bc14ba88 Vangelis Koukis
        hostname = self._try_until_timeout_expires(
584 6e168615 Ilias Tsitsimpis
            self.action_timeout, self.action_timeout,
585 6e168615 Ilias Tsitsimpis
            msg, self._get_hostname_over_ssh,
586 6e168615 Ilias Tsitsimpis
            hostip, username, password)
587 bc14ba88 Vangelis Koukis
588 bc14ba88 Vangelis Koukis
        # The hostname must be of the form 'prefix-id'
589 bc14ba88 Vangelis Koukis
        self.assertTrue(hostname.endswith("-%d\n" % self.serverid))
590 5a140b23 Vangelis Koukis
591 8252d64f John Giannelos
    def _check_file_through_ssh(self, hostip, username, password,
592 8252d64f John Giannelos
                                remotepath, content):
593 8252d64f John Giannelos
        msg = "Trying file injection through SSH to %s, as %s/%s" % \
594 8252d64f John Giannelos
            (hostip, username, password)
595 f97dce4d John Giannelos
        log.info(msg)
596 77054bf5 John Giannelos
        try:
597 77054bf5 John Giannelos
            ssh = paramiko.SSHClient()
598 77054bf5 John Giannelos
            ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
599 77054bf5 John Giannelos
            ssh.connect(hostip, username=username, password=password)
600 2a410f76 Ilias Tsitsimpis
            ssh.close()
601 77054bf5 John Giannelos
        except socket.error:
602 77054bf5 John Giannelos
            raise AssertionError
603 9659e075 John Giannelos
604 2bcfb712 John Giannelos
        transport = paramiko.Transport((hostip, 22))
605 2bcfb712 John Giannelos
        transport.connect(username=username, password=password)
606 2bcfb712 John Giannelos
607 2bcfb712 John Giannelos
        localpath = '/tmp/' + SNF_TEST_PREFIX + 'injection'
608 77054bf5 John Giannelos
        sftp = paramiko.SFTPClient.from_transport(transport)
609 8252d64f John Giannelos
        sftp.get(remotepath, localpath)
610 77054bf5 John Giannelos
        sftp.close()
611 77054bf5 John Giannelos
        transport.close()
612 77054bf5 John Giannelos
613 9659e075 John Giannelos
        f = open(localpath)
614 9659e075 John Giannelos
        remote_content = b64encode(f.read())
615 9659e075 John Giannelos
616 77054bf5 John Giannelos
        # Check if files are the same
617 65462ca9 John Giannelos
        return (remote_content == content)
618 77054bf5 John Giannelos
619 5a140b23 Vangelis Koukis
    def _skipIf(self, condition, msg):
620 5a140b23 Vangelis Koukis
        if condition:
621 5a140b23 Vangelis Koukis
            self.skipTest(msg)
622 5a140b23 Vangelis Koukis
623 5a140b23 Vangelis Koukis
    def test_001_submit_create_server(self):
624 5a140b23 Vangelis Koukis
        """Test submit create server request"""
625 f89d0238 John Giannelos
626 f89d0238 John Giannelos
        log.info("Submit new server request")
627 5a140b23 Vangelis Koukis
        server = self.client.create_server(self.servername, self.flavorid,
628 5a140b23 Vangelis Koukis
                                           self.imageid, self.personality)
629 9659e075 John Giannelos
630 81e8cbf6 John Giannelos
        log.info("Server id: " + str(server["id"]))
631 81e8cbf6 John Giannelos
        log.info("Server password: " + server["adminPass"])
632 5a140b23 Vangelis Koukis
        self.assertEqual(server["name"], self.servername)
633 5a140b23 Vangelis Koukis
        self.assertEqual(server["flavorRef"], self.flavorid)
634 5a140b23 Vangelis Koukis
        self.assertEqual(server["imageRef"], self.imageid)
635 5a140b23 Vangelis Koukis
        self.assertEqual(server["status"], "BUILD")
636 5a140b23 Vangelis Koukis
637 5a140b23 Vangelis Koukis
        # Update class attributes to reflect data on building server
638 5a140b23 Vangelis Koukis
        cls = type(self)
639 5a140b23 Vangelis Koukis
        cls.serverid = server["id"]
640 bc14ba88 Vangelis Koukis
        cls.username = None
641 5a140b23 Vangelis Koukis
        cls.passwd = server["adminPass"]
642 5a140b23 Vangelis Koukis
643 66eba2cf John Giannelos
        self.result_dict["Server ID"] = str(server["id"])
644 66eba2cf John Giannelos
        self.result_dict["Password"] = str(server["adminPass"])
645 66eba2cf John Giannelos
646 5a140b23 Vangelis Koukis
    def test_002a_server_is_building_in_list(self):
647 5a140b23 Vangelis Koukis
        """Test server is in BUILD state, in server list"""
648 f89d0238 John Giannelos
        log.info("Server in BUILD state in server list")
649 f89d0238 John Giannelos
650 66eba2cf John Giannelos
        self.result_dict.clear()
651 66eba2cf John Giannelos
652 5a140b23 Vangelis Koukis
        servers = self.client.list_servers(detail=True)
653 5a140b23 Vangelis Koukis
        servers = filter(lambda x: x["name"] == self.servername, servers)
654 2aaa1336 John Giannelos
655 5a140b23 Vangelis Koukis
        server = servers[0]
656 5a140b23 Vangelis Koukis
        self.assertEqual(server["name"], self.servername)
657 5a140b23 Vangelis Koukis
        self.assertEqual(server["flavorRef"], self.flavorid)
658 5a140b23 Vangelis Koukis
        self.assertEqual(server["imageRef"], self.imageid)
659 5a140b23 Vangelis Koukis
        self.assertEqual(server["status"], "BUILD")
660 5a140b23 Vangelis Koukis
661 5a140b23 Vangelis Koukis
    def test_002b_server_is_building_in_details(self):
662 5a140b23 Vangelis Koukis
        """Test server is in BUILD state, in details"""
663 f89d0238 John Giannelos
664 f89d0238 John Giannelos
        log.info("Server in BUILD state in details")
665 f89d0238 John Giannelos
666 5a140b23 Vangelis Koukis
        server = self.client.get_server_details(self.serverid)
667 5a140b23 Vangelis Koukis
        self.assertEqual(server["name"], self.servername)
668 5a140b23 Vangelis Koukis
        self.assertEqual(server["flavorRef"], self.flavorid)
669 5a140b23 Vangelis Koukis
        self.assertEqual(server["imageRef"], self.imageid)
670 5a140b23 Vangelis Koukis
        self.assertEqual(server["status"], "BUILD")
671 5a140b23 Vangelis Koukis
672 5a140b23 Vangelis Koukis
    def test_002c_set_server_metadata(self):
673 f89d0238 John Giannelos
674 f89d0238 John Giannelos
        log.info("Creating server metadata")
675 f89d0238 John Giannelos
676 5a140b23 Vangelis Koukis
        image = self.client.get_image_details(self.imageid)
677 6e168615 Ilias Tsitsimpis
        os_value = image["metadata"]["values"]["os"]
678 e49bdb7c John Giannelos
        users = image["metadata"]["values"].get("users", None)
679 6e168615 Ilias Tsitsimpis
        self.client.update_server_metadata(self.serverid, OS=os_value)
680 746540cd John Giannelos
681 e49bdb7c John Giannelos
        userlist = users.split()
682 81e8cbf6 John Giannelos
683 bc14ba88 Vangelis Koukis
        # Determine the username to use for future connections
684 bc14ba88 Vangelis Koukis
        # to this host
685 bc14ba88 Vangelis Koukis
        cls = type(self)
686 81e8cbf6 John Giannelos
687 81e8cbf6 John Giannelos
        if "root" in userlist:
688 81e8cbf6 John Giannelos
            cls.username = "root"
689 6e168615 Ilias Tsitsimpis
        elif users is None:
690 6e168615 Ilias Tsitsimpis
            cls.username = self._connect_loginname(os_value)
691 81e8cbf6 John Giannelos
        else:
692 81e8cbf6 John Giannelos
            cls.username = choice(userlist)
693 81e8cbf6 John Giannelos
694 bc14ba88 Vangelis Koukis
        self.assertIsNotNone(cls.username)
695 5a140b23 Vangelis Koukis
696 5a140b23 Vangelis Koukis
    def test_002d_verify_server_metadata(self):
697 5a140b23 Vangelis Koukis
        """Test server metadata keys are set based on image metadata"""
698 f89d0238 John Giannelos
699 f89d0238 John Giannelos
        log.info("Verifying image metadata")
700 f89d0238 John Giannelos
701 5a140b23 Vangelis Koukis
        servermeta = self.client.get_server_metadata(self.serverid)
702 5a140b23 Vangelis Koukis
        imagemeta = self.client.get_image_metadata(self.imageid)
703 81e8cbf6 John Giannelos
704 99d41650 John Giannelos
        self.assertEqual(servermeta["OS"], imagemeta["os"])
705 5a140b23 Vangelis Koukis
706 5a140b23 Vangelis Koukis
    def test_003_server_becomes_active(self):
707 5a140b23 Vangelis Koukis
        """Test server becomes ACTIVE"""
708 f89d0238 John Giannelos
709 f89d0238 John Giannelos
        log.info("Waiting for server to become ACTIVE")
710 f89d0238 John Giannelos
711 6e168615 Ilias Tsitsimpis
        self._insist_on_status_transition(
712 6e168615 Ilias Tsitsimpis
            "BUILD", "ACTIVE", self.build_fail, self.build_warning)
713 5a140b23 Vangelis Koukis
714 f752215c John Giannelos
    def test_003a_get_server_oob_console(self):
715 f752215c John Giannelos
        """Test getting OOB server console over VNC
716 bc14ba88 Vangelis Koukis

717 f752215c John Giannelos
        Implementation of RFB protocol follows
718 f752215c John Giannelos
        http://www.realvnc.com/docs/rfbproto.pdf.
719 bc14ba88 Vangelis Koukis

720 f752215c John Giannelos
        """
721 f752215c John Giannelos
        console = self.cyclades.get_server_console(self.serverid)
722 f752215c John Giannelos
        self.assertEquals(console['type'], "vnc")
723 6e168615 Ilias Tsitsimpis
        sock = self._insist_on_tcp_connection(
724 6e168615 Ilias Tsitsimpis
            socket.AF_INET, console["host"], console["port"])
725 f752215c John Giannelos
726 f752215c John Giannelos
        # Step 1. ProtocolVersion message (par. 6.1.1)
727 f752215c John Giannelos
        version = sock.recv(1024)
728 f752215c John Giannelos
        self.assertEquals(version, 'RFB 003.008\n')
729 f752215c John Giannelos
        sock.send(version)
730 f752215c John Giannelos
731 f752215c John Giannelos
        # Step 2. Security (par 6.1.2): Only VNC Authentication supported
732 f752215c John Giannelos
        sec = sock.recv(1024)
733 f752215c John Giannelos
        self.assertEquals(list(sec), ['\x01', '\x02'])
734 f752215c John Giannelos
735 f752215c John Giannelos
        # Step 3. Request VNC Authentication (par 6.1.2)
736 f752215c John Giannelos
        sock.send('\x02')
737 f752215c John Giannelos
738 f752215c John Giannelos
        # Step 4. Receive Challenge (par 6.2.2)
739 f752215c John Giannelos
        challenge = sock.recv(1024)
740 f752215c John Giannelos
        self.assertEquals(len(challenge), 16)
741 f752215c John Giannelos
742 f752215c John Giannelos
        # Step 5. DES-Encrypt challenge, use password as key (par 6.2.2)
743 f752215c John Giannelos
        response = d3des_generate_response(
744 f752215c John Giannelos
            (console["password"] + '\0' * 8)[:8], challenge)
745 f752215c John Giannelos
        sock.send(response)
746 f752215c John Giannelos
747 f752215c John Giannelos
        # Step 6. SecurityResult (par 6.1.3)
748 f752215c John Giannelos
        result = sock.recv(4)
749 f752215c John Giannelos
        self.assertEquals(list(result), ['\x00', '\x00', '\x00', '\x00'])
750 f752215c John Giannelos
        sock.close()
751 8252d64f John Giannelos
752 5a140b23 Vangelis Koukis
    def test_004_server_has_ipv4(self):
753 5a140b23 Vangelis Koukis
        """Test active server has a valid IPv4 address"""
754 f89d0238 John Giannelos
755 81e8cbf6 John Giannelos
        log.info("Validate server's IPv4")
756 f89d0238 John Giannelos
757 5a140b23 Vangelis Koukis
        server = self.client.get_server_details(self.serverid)
758 5a140b23 Vangelis Koukis
        ipv4 = self._get_ipv4(server)
759 66eba2cf John Giannelos
760 66eba2cf John Giannelos
        self.result_dict.clear()
761 66eba2cf John Giannelos
        self.result_dict["IPv4"] = str(ipv4)
762 66eba2cf John Giannelos
763 5a140b23 Vangelis Koukis
        self.assertEquals(IP(ipv4).version(), 4)
764 5a140b23 Vangelis Koukis
765 65462ca9 John Giannelos
    def test_005_server_has_ipv6(self):
766 65462ca9 John Giannelos
        """Test active server has a valid IPv6 address"""
767 946da8b6 John Giannelos
        self._skipIf(NO_IPV6, "--no-ipv6 flag enabled")
768 f89d0238 John Giannelos
769 81e8cbf6 John Giannelos
        log.info("Validate server's IPv6")
770 f89d0238 John Giannelos
771 65462ca9 John Giannelos
        server = self.client.get_server_details(self.serverid)
772 65462ca9 John Giannelos
        ipv6 = self._get_ipv6(server)
773 66eba2cf John Giannelos
774 66eba2cf John Giannelos
        self.result_dict.clear()
775 66eba2cf John Giannelos
        self.result_dict["IPv6"] = str(ipv6)
776 66eba2cf John Giannelos
777 65462ca9 John Giannelos
        self.assertEquals(IP(ipv6).version(), 6)
778 5a140b23 Vangelis Koukis
779 daac4017 John Giannelos
    def test_006_server_responds_to_ping_IPv4(self):
780 daac4017 John Giannelos
        """Test server responds to ping on IPv4 address"""
781 daac4017 John Giannelos
782 daac4017 John Giannelos
        log.info("Testing if server responds to pings in IPv4")
783 66eba2cf John Giannelos
        self.result_dict.clear()
784 daac4017 John Giannelos
785 daac4017 John Giannelos
        server = self.client.get_server_details(self.serverid)
786 daac4017 John Giannelos
        ip = self._get_ipv4(server)
787 daac4017 John Giannelos
        self._try_until_timeout_expires(self.action_timeout,
788 daac4017 John Giannelos
                                        self.action_timeout,
789 daac4017 John Giannelos
                                        "PING IPv4 to %s" % ip,
790 daac4017 John Giannelos
                                        self._ping_once,
791 daac4017 John Giannelos
                                        False, ip)
792 daac4017 John Giannelos
793 daac4017 John Giannelos
    def test_007_server_responds_to_ping_IPv6(self):
794 daac4017 John Giannelos
        """Test server responds to ping on IPv6 address"""
795 daac4017 John Giannelos
        self._skipIf(NO_IPV6, "--no-ipv6 flag enabled")
796 daac4017 John Giannelos
        log.info("Testing if server responds to pings in IPv6")
797 daac4017 John Giannelos
798 daac4017 John Giannelos
        server = self.client.get_server_details(self.serverid)
799 daac4017 John Giannelos
        ip = self._get_ipv6(server)
800 daac4017 John Giannelos
        self._try_until_timeout_expires(self.action_timeout,
801 daac4017 John Giannelos
                                        self.action_timeout,
802 daac4017 John Giannelos
                                        "PING IPv6 to %s" % ip,
803 daac4017 John Giannelos
                                        self._ping_once,
804 daac4017 John Giannelos
                                        True, ip)
805 5a140b23 Vangelis Koukis
806 5a140b23 Vangelis Koukis
    def test_008_submit_shutdown_request(self):
807 5a140b23 Vangelis Koukis
        """Test submit request to shutdown server"""
808 f89d0238 John Giannelos
809 f89d0238 John Giannelos
        log.info("Shutting down server")
810 f89d0238 John Giannelos
811 74193008 John Giannelos
        self.cyclades.shutdown_server(self.serverid)
812 5a140b23 Vangelis Koukis
813 5a140b23 Vangelis Koukis
    def test_009_server_becomes_stopped(self):
814 5a140b23 Vangelis Koukis
        """Test server becomes STOPPED"""
815 f89d0238 John Giannelos
816 f89d0238 John Giannelos
        log.info("Waiting until server becomes STOPPED")
817 6e168615 Ilias Tsitsimpis
        self._insist_on_status_transition(
818 6e168615 Ilias Tsitsimpis
            "ACTIVE", "STOPPED", self.action_timeout, self.action_timeout)
819 5a140b23 Vangelis Koukis
820 5a140b23 Vangelis Koukis
    def test_010_submit_start_request(self):
821 5a140b23 Vangelis Koukis
        """Test submit start server request"""
822 f89d0238 John Giannelos
823 f89d0238 John Giannelos
        log.info("Starting server")
824 f89d0238 John Giannelos
825 74193008 John Giannelos
        self.cyclades.start_server(self.serverid)
826 5a140b23 Vangelis Koukis
827 5a140b23 Vangelis Koukis
    def test_011_server_becomes_active(self):
828 5a140b23 Vangelis Koukis
        """Test server becomes ACTIVE again"""
829 f89d0238 John Giannelos
830 f89d0238 John Giannelos
        log.info("Waiting until server becomes ACTIVE")
831 6e168615 Ilias Tsitsimpis
        self._insist_on_status_transition(
832 6e168615 Ilias Tsitsimpis
            "STOPPED", "ACTIVE", self.action_timeout, self.action_timeout)
833 5a140b23 Vangelis Koukis
834 daac4017 John Giannelos
    def test_011a_server_responds_to_ping_IPv4(self):
835 daac4017 John Giannelos
        """Test server OS is actually up and running again"""
836 f89d0238 John Giannelos
837 daac4017 John Giannelos
        log.info("Testing if server is actually up and running")
838 f89d0238 John Giannelos
839 daac4017 John Giannelos
        self.test_006_server_responds_to_ping_IPv4()
840 5a140b23 Vangelis Koukis
841 daac4017 John Giannelos
    def test_012_ssh_to_server_IPv4(self):
842 daac4017 John Giannelos
        """Test SSH to server public IPv4 works, verify hostname"""
843 f89d0238 John Giannelos
844 daac4017 John Giannelos
        self._skipIf(self.is_windows, "only valid for Linux servers")
845 daac4017 John Giannelos
        server = self.client.get_server_details(self.serverid)
846 daac4017 John Giannelos
        self._insist_on_ssh_hostname(self._get_ipv4(server),
847 daac4017 John Giannelos
                                     self.username, self.passwd)
848 5a140b23 Vangelis Koukis
849 daac4017 John Giannelos
    def test_013_ssh_to_server_IPv6(self):
850 daac4017 John Giannelos
        """Test SSH to server public IPv6 works, verify hostname"""
851 daac4017 John Giannelos
        self._skipIf(self.is_windows, "only valid for Linux servers")
852 daac4017 John Giannelos
        self._skipIf(NO_IPV6, "--no-ipv6 flag enabled")
853 946da8b6 John Giannelos
854 daac4017 John Giannelos
        server = self.client.get_server_details(self.serverid)
855 daac4017 John Giannelos
        self._insist_on_ssh_hostname(self._get_ipv6(server),
856 daac4017 John Giannelos
                                     self.username, self.passwd)
857 5a140b23 Vangelis Koukis
858 daac4017 John Giannelos
    def test_014_rdp_to_server_IPv4(self):
859 daac4017 John Giannelos
        "Test RDP connection to server public IPv4 works"""
860 daac4017 John Giannelos
        self._skipIf(not self.is_windows, "only valid for Windows servers")
861 daac4017 John Giannelos
        server = self.client.get_server_details(self.serverid)
862 daac4017 John Giannelos
        ipv4 = self._get_ipv4(server)
863 6e168615 Ilias Tsitsimpis
        sock = self._insist_on_tcp_connection(socket.AF_INET, ipv4, 3389)
864 5a140b23 Vangelis Koukis
865 daac4017 John Giannelos
        # No actual RDP processing done. We assume the RDP server is there
866 daac4017 John Giannelos
        # if the connection to the RDP port is successful.
867 daac4017 John Giannelos
        # FIXME: Use rdesktop, analyze exit code? see manpage [costasd]
868 daac4017 John Giannelos
        sock.close()
869 5a140b23 Vangelis Koukis
870 daac4017 John Giannelos
    def test_015_rdp_to_server_IPv6(self):
871 daac4017 John Giannelos
        "Test RDP connection to server public IPv6 works"""
872 daac4017 John Giannelos
        self._skipIf(not self.is_windows, "only valid for Windows servers")
873 daac4017 John Giannelos
        self._skipIf(NO_IPV6, "--no-ipv6 flag enabled")
874 946da8b6 John Giannelos
875 daac4017 John Giannelos
        server = self.client.get_server_details(self.serverid)
876 daac4017 John Giannelos
        ipv6 = self._get_ipv6(server)
877 6e168615 Ilias Tsitsimpis
        sock = self._get_tcp_connection(socket.AF_INET6, ipv6, 3389)
878 5a140b23 Vangelis Koukis
879 daac4017 John Giannelos
        # No actual RDP processing done. We assume the RDP server is there
880 daac4017 John Giannelos
        # if the connection to the RDP port is successful.
881 daac4017 John Giannelos
        sock.close()
882 5a140b23 Vangelis Koukis
883 daac4017 John Giannelos
    def test_016_personality_is_enforced(self):
884 daac4017 John Giannelos
        """Test file injection for personality enforcement"""
885 daac4017 John Giannelos
        self._skipIf(self.is_windows, "only implemented for Linux servers")
886 6e168615 Ilias Tsitsimpis
        self._skipIf(self.personality is None, "No personality file selected")
887 f89d0238 John Giannelos
888 daac4017 John Giannelos
        log.info("Trying to inject file for personality enforcement")
889 f89d0238 John Giannelos
890 daac4017 John Giannelos
        server = self.client.get_server_details(self.serverid)
891 77054bf5 John Giannelos
892 daac4017 John Giannelos
        for inj_file in self.personality:
893 daac4017 John Giannelos
            equal_files = self._check_file_through_ssh(self._get_ipv4(server),
894 daac4017 John Giannelos
                                                       inj_file['owner'],
895 daac4017 John Giannelos
                                                       self.passwd,
896 daac4017 John Giannelos
                                                       inj_file['path'],
897 daac4017 John Giannelos
                                                       inj_file['contents'])
898 daac4017 John Giannelos
            self.assertTrue(equal_files)
899 8252d64f John Giannelos
900 4fdd25ab Vangelis Koukis
    def test_017_submit_delete_request(self):
901 4fdd25ab Vangelis Koukis
        """Test submit request to delete server"""
902 f89d0238 John Giannelos
903 f89d0238 John Giannelos
        log.info("Deleting server")
904 f89d0238 John Giannelos
905 4fdd25ab Vangelis Koukis
        self.client.delete_server(self.serverid)
906 4fdd25ab Vangelis Koukis
907 4fdd25ab Vangelis Koukis
    def test_018_server_becomes_deleted(self):
908 4fdd25ab Vangelis Koukis
        """Test server becomes DELETED"""
909 f89d0238 John Giannelos
910 f89d0238 John Giannelos
        log.info("Testing if server becomes DELETED")
911 f89d0238 John Giannelos
912 6e168615 Ilias Tsitsimpis
        self._insist_on_status_transition(
913 6e168615 Ilias Tsitsimpis
            "ACTIVE", "DELETED", self.action_timeout, self.action_timeout)
914 4fdd25ab Vangelis Koukis
915 4fdd25ab Vangelis Koukis
    def test_019_server_no_longer_in_server_list(self):
916 4fdd25ab Vangelis Koukis
        """Test server is no longer in server list"""
917 f89d0238 John Giannelos
918 f89d0238 John Giannelos
        log.info("Test if server is no longer listed")
919 f89d0238 John Giannelos
920 4fdd25ab Vangelis Koukis
        servers = self.client.list_servers()
921 21bbbc9b Vangelis Koukis
        self.assertNotIn(self.serverid, [s["id"] for s in servers])
922 21bbbc9b Vangelis Koukis
923 21bbbc9b Vangelis Koukis
924 9e4682b5 John Giannelos
class NetworkTestCase(unittest.TestCase):
925 e94a9d8c John Giannelos
    """ Testing networking in cyclades """
926 8252d64f John Giannelos
927 9e4682b5 John Giannelos
    @classmethod
928 e94a9d8c John Giannelos
    def setUpClass(cls):
929 e94a9d8c John Giannelos
        "Initialize kamaki, get list of current networks"
930 567ffb85 John Giannelos
931 567ffb85 John Giannelos
        cls.client = CycladesClient(API, TOKEN)
932 567ffb85 John Giannelos
        cls.compute = ComputeClient(API, TOKEN)
933 9e4682b5 John Giannelos
934 8252d64f John Giannelos
        cls.servername = "%s%s for %s" % (SNF_TEST_PREFIX,
935 8252d64f John Giannelos
                                          TEST_RUN_ID,
936 8252d64f John Giannelos
                                          cls.imagename)
937 91de9b55 John Giannelos
938 91de9b55 John Giannelos
        #Dictionary initialization for the vms credentials
939 91de9b55 John Giannelos
        cls.serverid = dict()
940 91de9b55 John Giannelos
        cls.username = dict()
941 91de9b55 John Giannelos
        cls.password = dict()
942 846980fe John Giannelos
        cls.is_windows = cls.imagename.lower().find("windows") >= 0
943 e49bdb7c John Giannelos
944 66eba2cf John Giannelos
        cls.result_dict = dict()
945 66eba2cf John Giannelos
946 e49bdb7c John Giannelos
    def _skipIf(self, condition, msg):
947 e49bdb7c John Giannelos
        if condition:
948 e49bdb7c John Giannelos
            self.skipTest(msg)
949 91de9b55 John Giannelos
950 1b40b5e3 John Giannelos
    def _get_ipv4(self, server):
951 1b40b5e3 John Giannelos
        """Get the public IPv4 of a server from the detailed server info"""
952 1b40b5e3 John Giannelos
953 e50133da John Giannelos
        nics = server["attachments"]["values"]
954 2aaa1336 John Giannelos
955 e50133da John Giannelos
        for nic in nics:
956 e50133da John Giannelos
            net_id = nic["network_id"]
957 6e168615 Ilias Tsitsimpis
            if self.client.get_network_details(net_id)["public"]:
958 e50133da John Giannelos
                public_addrs = nic["ipv4"]
959 2aaa1336 John Giannelos
960 6e168615 Ilias Tsitsimpis
        self.assertTrue(public_addrs is not None)
961 2aaa1336 John Giannelos
962 6e168615 Ilias Tsitsimpis
        return public_addrs
963 8252d64f John Giannelos
964 6e168615 Ilias Tsitsimpis
    def _connect_loginname(self, os_value):
965 1b40b5e3 John Giannelos
        """Return the login name for connections based on the server OS"""
966 6e168615 Ilias Tsitsimpis
        if os_value in ("Ubuntu", "Kubuntu", "Fedora"):
967 1b40b5e3 John Giannelos
            return "user"
968 6e168615 Ilias Tsitsimpis
        elif os_value in ("windows", "windows_alpha1"):
969 1b40b5e3 John Giannelos
            return "Administrator"
970 1b40b5e3 John Giannelos
        else:
971 1b40b5e3 John Giannelos
            return "root"
972 1b40b5e3 John Giannelos
973 88736f65 John Giannelos
    def _ping_once(self, ip):
974 8252d64f John Giannelos
975 88736f65 John Giannelos
        """Test server responds to a single IPv4 or IPv6 ping"""
976 88736f65 John Giannelos
        cmd = "ping -c 2 -w 3 %s" % (ip)
977 88736f65 John Giannelos
        ping = subprocess.Popen(cmd, shell=True,
978 88736f65 John Giannelos
                                stdout=subprocess.PIPE, stderr=subprocess.PIPE)
979 88736f65 John Giannelos
        (stdout, stderr) = ping.communicate()
980 88736f65 John Giannelos
        ret = ping.wait()
981 8252d64f John Giannelos
982 88736f65 John Giannelos
        return (ret == 0)
983 88736f65 John Giannelos
984 740a5649 John Giannelos
    def test_00001a_submit_create_server_A(self):
985 91de9b55 John Giannelos
        """Test submit create server request"""
986 f89d0238 John Giannelos
987 f89d0238 John Giannelos
        log.info("Creating test server A")
988 f89d0238 John Giannelos
989 91de9b55 John Giannelos
        serverA = self.client.create_server(self.servername, self.flavorid,
990 ae139e8a John Giannelos
                                            self.imageid, personality=None)
991 91de9b55 John Giannelos
992 c54e3d4c John Giannelos
        self.assertEqual(serverA["name"], self.servername)
993 c54e3d4c John Giannelos
        self.assertEqual(serverA["flavorRef"], self.flavorid)
994 c54e3d4c John Giannelos
        self.assertEqual(serverA["imageRef"], self.imageid)
995 c54e3d4c John Giannelos
        self.assertEqual(serverA["status"], "BUILD")
996 91de9b55 John Giannelos
997 91de9b55 John Giannelos
        # Update class attributes to reflect data on building server
998 08748d73 John Giannelos
        self.serverid['A'] = serverA["id"]
999 08748d73 John Giannelos
        self.username['A'] = None
1000 08748d73 John Giannelos
        self.password['A'] = serverA["adminPass"]
1001 91de9b55 John Giannelos
1002 81e8cbf6 John Giannelos
        log.info("Server A id:" + str(serverA["id"]))
1003 81e8cbf6 John Giannelos
        log.info("Server password " + (self.password['A']))
1004 8252d64f John Giannelos
1005 66eba2cf John Giannelos
        self.result_dict["Server A ID"] = str(serverA["id"])
1006 66eba2cf John Giannelos
        self.result_dict["Server A password"] = serverA["adminPass"]
1007 6e168615 Ilias Tsitsimpis
1008 740a5649 John Giannelos
    def test_00001b_serverA_becomes_active(self):
1009 91de9b55 John Giannelos
        """Test server becomes ACTIVE"""
1010 8252d64f John Giannelos
1011 f89d0238 John Giannelos
        log.info("Waiting until test server A becomes ACTIVE")
1012 66eba2cf John Giannelos
        self.result_dict.clear()
1013 91de9b55 John Giannelos
1014 2bcfb712 John Giannelos
        fail_tmout = time.time() + self.action_timeout
1015 91de9b55 John Giannelos
        while True:
1016 91de9b55 John Giannelos
            d = self.client.get_server_details(self.serverid['A'])
1017 91de9b55 John Giannelos
            status = d['status']
1018 91de9b55 John Giannelos
            if status == 'ACTIVE':
1019 91de9b55 John Giannelos
                active = True
1020 91de9b55 John Giannelos
                break
1021 91de9b55 John Giannelos
            elif time.time() > fail_tmout:
1022 91de9b55 John Giannelos
                self.assertLess(time.time(), fail_tmout)
1023 91de9b55 John Giannelos
            else:
1024 91de9b55 John Giannelos
                time.sleep(self.query_interval)
1025 91de9b55 John Giannelos
1026 91de9b55 John Giannelos
        self.assertTrue(active)
1027 91de9b55 John Giannelos
1028 740a5649 John Giannelos
    def test_00002a_submit_create_server_B(self):
1029 fade8dab John Giannelos
        """Test submit create server request"""
1030 8252d64f John Giannelos
1031 f89d0238 John Giannelos
        log.info("Creating test server B")
1032 6e168615 Ilias Tsitsimpis
1033 fade8dab John Giannelos
        serverB = self.client.create_server(self.servername, self.flavorid,
1034 ae139e8a John Giannelos
                                            self.imageid, personality=None)
1035 ae139e8a John Giannelos
1036 fade8dab John Giannelos
        self.assertEqual(serverB["name"], self.servername)
1037 fade8dab John Giannelos
        self.assertEqual(serverB["flavorRef"], self.flavorid)
1038 fade8dab John Giannelos
        self.assertEqual(serverB["imageRef"], self.imageid)
1039 fade8dab John Giannelos
        self.assertEqual(serverB["status"], "BUILD")
1040 fade8dab John Giannelos
1041 fade8dab John Giannelos
        # Update class attributes to reflect data on building server
1042 fade8dab John Giannelos
        self.serverid['B'] = serverB["id"]
1043 fade8dab John Giannelos
        self.username['B'] = None
1044 fade8dab John Giannelos
        self.password['B'] = serverB["adminPass"]
1045 fade8dab John Giannelos
1046 81e8cbf6 John Giannelos
        log.info("Server B id: " + str(serverB["id"]))
1047 81e8cbf6 John Giannelos
        log.info("Password " + (self.password['B']))
1048 ae139e8a John Giannelos
1049 66eba2cf John Giannelos
        self.result_dict.clear()
1050 66eba2cf John Giannelos
        self.result_dict["Server B ID"] = str(serverB["id"])
1051 66eba2cf John Giannelos
        self.result_dict["Server B password"] = serverB["adminPass"]
1052 66eba2cf John Giannelos
1053 740a5649 John Giannelos
    def test_00002b_serverB_becomes_active(self):
1054 91de9b55 John Giannelos
        """Test server becomes ACTIVE"""
1055 91de9b55 John Giannelos
1056 f89d0238 John Giannelos
        log.info("Waiting until test server B becomes ACTIVE")
1057 66eba2cf John Giannelos
        self.result_dict.clear()
1058 f89d0238 John Giannelos
1059 2bcfb712 John Giannelos
        fail_tmout = time.time() + self.action_timeout
1060 91de9b55 John Giannelos
        while True:
1061 91de9b55 John Giannelos
            d = self.client.get_server_details(self.serverid['B'])
1062 91de9b55 John Giannelos
            status = d['status']
1063 91de9b55 John Giannelos
            if status == 'ACTIVE':
1064 91de9b55 John Giannelos
                active = True
1065 91de9b55 John Giannelos
                break
1066 91de9b55 John Giannelos
            elif time.time() > fail_tmout:
1067 91de9b55 John Giannelos
                self.assertLess(time.time(), fail_tmout)
1068 91de9b55 John Giannelos
            else:
1069 91de9b55 John Giannelos
                time.sleep(self.query_interval)
1070 91de9b55 John Giannelos
1071 91de9b55 John Giannelos
        self.assertTrue(active)
1072 567ffb85 John Giannelos
1073 9e4682b5 John Giannelos
    def test_001_create_network(self):
1074 e94a9d8c John Giannelos
        """Test submit create network request"""
1075 f89d0238 John Giannelos
1076 f89d0238 John Giannelos
        log.info("Submit new network request")
1077 66eba2cf John Giannelos
        self.result_dict.clear()
1078 6e168615 Ilias Tsitsimpis
1079 2bcfb712 John Giannelos
        name = SNF_TEST_PREFIX + TEST_RUN_ID
1080 6e168615 Ilias Tsitsimpis
        #previous_num = len(self.client.list_networks())
1081 6e168615 Ilias Tsitsimpis
        network = self.client.create_network(name, cidr='10.0.0.1/28')
1082 8252d64f John Giannelos
1083 9e4682b5 John Giannelos
        #Test if right name is assigned
1084 e94a9d8c John Giannelos
        self.assertEqual(network['name'], name)
1085 8252d64f John Giannelos
1086 9e4682b5 John Giannelos
        # Update class attributes
1087 e94a9d8c John Giannelos
        cls = type(self)
1088 e94a9d8c John Giannelos
        cls.networkid = network['id']
1089 6e168615 Ilias Tsitsimpis
        #networks = self.client.list_networks()
1090 9e4682b5 John Giannelos
1091 2aaa1336 John Giannelos
        fail_tmout = time.time() + self.action_timeout
1092 2aaa1336 John Giannelos
1093 9e4682b5 John Giannelos
        #Test if new network is created
1094 2aaa1336 John Giannelos
        while True:
1095 2aaa1336 John Giannelos
            d = self.client.get_network_details(network['id'])
1096 2aaa1336 John Giannelos
            if d['status'] == 'ACTIVE':
1097 2aaa1336 John Giannelos
                connected = True
1098 2aaa1336 John Giannelos
                break
1099 2aaa1336 John Giannelos
            elif time.time() > fail_tmout:
1100 2aaa1336 John Giannelos
                self.assertLess(time.time(), fail_tmout)
1101 2aaa1336 John Giannelos
            else:
1102 2aaa1336 John Giannelos
                log.info("Waiting for network to become ACTIVE")
1103 2aaa1336 John Giannelos
                time.sleep(self.query_interval)
1104 2aaa1336 John Giannelos
1105 2aaa1336 John Giannelos
        self.assertTrue(connected)
1106 8252d64f John Giannelos
1107 66eba2cf John Giannelos
        self.result_dict["Private network ID"] = str(network['id'])
1108 66eba2cf John Giannelos
1109 9e4682b5 John Giannelos
    def test_002_connect_to_network(self):
1110 4573ea07 John Giannelos
        """Test connect VMs to network"""
1111 9e4682b5 John Giannelos
1112 f89d0238 John Giannelos
        log.info("Connect VMs to private network")
1113 66eba2cf John Giannelos
        self.result_dict.clear()
1114 f89d0238 John Giannelos
1115 91de9b55 John Giannelos
        self.client.connect_server(self.serverid['A'], self.networkid)
1116 91de9b55 John Giannelos
        self.client.connect_server(self.serverid['B'], self.networkid)
1117 8252d64f John Giannelos
1118 65462ca9 John Giannelos
        #Insist on connecting until action timeout
1119 2bcfb712 John Giannelos
        fail_tmout = time.time() + self.action_timeout
1120 9e4682b5 John Giannelos
1121 65462ca9 John Giannelos
        while True:
1122 2aaa1336 John Giannelos
1123 6e168615 Ilias Tsitsimpis
            netsA = [x['network_id']
1124 6e168615 Ilias Tsitsimpis
                     for x in self.client.get_server_details(
1125 6e168615 Ilias Tsitsimpis
                         self.serverid['A'])['attachments']['values']]
1126 6e168615 Ilias Tsitsimpis
            netsB = [x['network_id']
1127 6e168615 Ilias Tsitsimpis
                     for x in self.client.get_server_details(
1128 6e168615 Ilias Tsitsimpis
                         self.serverid['B'])['attachments']['values']]
1129 2aaa1336 John Giannelos
1130 2aaa1336 John Giannelos
            if (self.networkid in netsA) and (self.networkid in netsB):
1131 65462ca9 John Giannelos
                conn_exists = True
1132 de2461ec John Giannelos
                break
1133 de2461ec John Giannelos
            elif time.time() > fail_tmout:
1134 65462ca9 John Giannelos
                self.assertLess(time.time(), fail_tmout)
1135 65462ca9 John Giannelos
            else:
1136 65462ca9 John Giannelos
                time.sleep(self.query_interval)
1137 6e168615 Ilias Tsitsimpis
1138 daac4017 John Giannelos
        #Adding private IPs to class attributes
1139 daac4017 John Giannelos
        cls = type(self)
1140 daac4017 John Giannelos
        cls.priv_ip = dict()
1141 daac4017 John Giannelos
1142 6e168615 Ilias Tsitsimpis
        nicsA = self.client.get_server_details(
1143 6e168615 Ilias Tsitsimpis
            self.serverid['A'])['attachments']['values']
1144 6e168615 Ilias Tsitsimpis
        nicsB = self.client.get_server_details(
1145 6e168615 Ilias Tsitsimpis
            self.serverid['B'])['attachments']['values']
1146 daac4017 John Giannelos
1147 daac4017 John Giannelos
        if conn_exists:
1148 daac4017 John Giannelos
            for nic in nicsA:
1149 daac4017 John Giannelos
                if nic["network_id"] == self.networkid:
1150 daac4017 John Giannelos
                    cls.priv_ip["A"] = nic["ipv4"]
1151 daac4017 John Giannelos
1152 daac4017 John Giannelos
            for nic in nicsB:
1153 daac4017 John Giannelos
                if nic["network_id"] == self.networkid:
1154 daac4017 John Giannelos
                    cls.priv_ip["B"] = nic["ipv4"]
1155 65462ca9 John Giannelos
1156 65462ca9 John Giannelos
        self.assertTrue(conn_exists)
1157 9e4682b5 John Giannelos
1158 88736f65 John Giannelos
    def test_002a_reboot(self):
1159 f89d0238 John Giannelos
        """Rebooting server A"""
1160 f89d0238 John Giannelos
1161 f89d0238 John Giannelos
        log.info("Rebooting server A")
1162 f89d0238 John Giannelos
1163 8252d64f John Giannelos
        self.client.shutdown_server(self.serverid['A'])
1164 8252d64f John Giannelos
1165 2bcfb712 John Giannelos
        fail_tmout = time.time() + self.action_timeout
1166 4573ea07 John Giannelos
        while True:
1167 4573ea07 John Giannelos
            d = self.client.get_server_details(self.serverid['A'])
1168 4573ea07 John Giannelos
            status = d['status']
1169 81e8cbf6 John Giannelos
            if status == 'STOPPED':
1170 81e8cbf6 John Giannelos
                break
1171 81e8cbf6 John Giannelos
            elif time.time() > fail_tmout:
1172 81e8cbf6 John Giannelos
                self.assertLess(time.time(), fail_tmout)
1173 81e8cbf6 John Giannelos
            else:
1174 81e8cbf6 John Giannelos
                time.sleep(self.query_interval)
1175 81e8cbf6 John Giannelos
1176 81e8cbf6 John Giannelos
        self.client.start_server(self.serverid['A'])
1177 81e8cbf6 John Giannelos
1178 81e8cbf6 John Giannelos
        while True:
1179 81e8cbf6 John Giannelos
            d = self.client.get_server_details(self.serverid['A'])
1180 81e8cbf6 John Giannelos
            status = d['status']
1181 4573ea07 John Giannelos
            if status == 'ACTIVE':
1182 4573ea07 John Giannelos
                active = True
1183 4573ea07 John Giannelos
                break
1184 4573ea07 John Giannelos
            elif time.time() > fail_tmout:
1185 4573ea07 John Giannelos
                self.assertLess(time.time(), fail_tmout)
1186 4573ea07 John Giannelos
            else:
1187 4573ea07 John Giannelos
                time.sleep(self.query_interval)
1188 8252d64f John Giannelos
1189 4573ea07 John Giannelos
        self.assertTrue(active)
1190 88736f65 John Giannelos
1191 daac4017 John Giannelos
    def test_002b_ping_server_A(self):
1192 daac4017 John Giannelos
        "Test if server A responds to IPv4 pings"
1193 4573ea07 John Giannelos
1194 daac4017 John Giannelos
        log.info("Testing if server A responds to IPv4 pings ")
1195 66eba2cf John Giannelos
        self.result_dict.clear()
1196 f89d0238 John Giannelos
1197 daac4017 John Giannelos
        server = self.client.get_server_details(self.serverid['A'])
1198 daac4017 John Giannelos
        ip = self._get_ipv4(server)
1199 8252d64f John Giannelos
1200 daac4017 John Giannelos
        fail_tmout = time.time() + self.action_timeout
1201 8252d64f John Giannelos
1202 daac4017 John Giannelos
        s = False
1203 6e168615 Ilias Tsitsimpis
1204 66eba2cf John Giannelos
        self.result_dict["Server A public IP"] = str(ip)
1205 88736f65 John Giannelos
1206 daac4017 John Giannelos
        while True:
1207 88736f65 John Giannelos
1208 daac4017 John Giannelos
            if self._ping_once(ip):
1209 daac4017 John Giannelos
                s = True
1210 daac4017 John Giannelos
                break
1211 88736f65 John Giannelos
1212 daac4017 John Giannelos
            elif time.time() > fail_tmout:
1213 daac4017 John Giannelos
                self.assertLess(time.time(), fail_tmout)
1214 88736f65 John Giannelos
1215 daac4017 John Giannelos
            else:
1216 daac4017 John Giannelos
                time.sleep(self.query_interval)
1217 88736f65 John Giannelos
1218 daac4017 John Giannelos
        self.assertTrue(s)
1219 4573ea07 John Giannelos
1220 4573ea07 John Giannelos
    def test_002c_reboot(self):
1221 f89d0238 John Giannelos
        """Reboot server B"""
1222 f89d0238 John Giannelos
1223 f89d0238 John Giannelos
        log.info("Rebooting server B")
1224 66eba2cf John Giannelos
        self.result_dict.clear()
1225 f89d0238 John Giannelos
1226 8252d64f John Giannelos
        self.client.shutdown_server(self.serverid['B'])
1227 8252d64f John Giannelos
1228 2bcfb712 John Giannelos
        fail_tmout = time.time() + self.action_timeout
1229 4573ea07 John Giannelos
        while True:
1230 4573ea07 John Giannelos
            d = self.client.get_server_details(self.serverid['B'])
1231 4573ea07 John Giannelos
            status = d['status']
1232 81e8cbf6 John Giannelos
            if status == 'STOPPED':
1233 81e8cbf6 John Giannelos
                break
1234 81e8cbf6 John Giannelos
            elif time.time() > fail_tmout:
1235 81e8cbf6 John Giannelos
                self.assertLess(time.time(), fail_tmout)
1236 81e8cbf6 John Giannelos
            else:
1237 81e8cbf6 John Giannelos
                time.sleep(self.query_interval)
1238 81e8cbf6 John Giannelos
1239 81e8cbf6 John Giannelos
        self.client.start_server(self.serverid['B'])
1240 81e8cbf6 John Giannelos
1241 81e8cbf6 John Giannelos
        while True:
1242 81e8cbf6 John Giannelos
            d = self.client.get_server_details(self.serverid['B'])
1243 81e8cbf6 John Giannelos
            status = d['status']
1244 4573ea07 John Giannelos
            if status == 'ACTIVE':
1245 4573ea07 John Giannelos
                active = True
1246 4573ea07 John Giannelos
                break
1247 4573ea07 John Giannelos
            elif time.time() > fail_tmout:
1248 4573ea07 John Giannelos
                self.assertLess(time.time(), fail_tmout)
1249 4573ea07 John Giannelos
            else:
1250 4573ea07 John Giannelos
                time.sleep(self.query_interval)
1251 8252d64f John Giannelos
1252 4573ea07 John Giannelos
        self.assertTrue(active)
1253 8252d64f John Giannelos
1254 daac4017 John Giannelos
    def test_002d_ping_server_B(self):
1255 daac4017 John Giannelos
        """Test if server B responds to IPv4 pings"""
1256 4573ea07 John Giannelos
1257 daac4017 John Giannelos
        log.info("Testing if server B responds to IPv4 pings")
1258 66eba2cf John Giannelos
        self.result_dict.clear()
1259 6e168615 Ilias Tsitsimpis
1260 daac4017 John Giannelos
        server = self.client.get_server_details(self.serverid['B'])
1261 daac4017 John Giannelos
        ip = self._get_ipv4(server)
1262 8252d64f John Giannelos
1263 daac4017 John Giannelos
        fail_tmout = time.time() + self.action_timeout
1264 8252d64f John Giannelos
1265 daac4017 John Giannelos
        s = False
1266 88736f65 John Giannelos
1267 66eba2cf John Giannelos
        self.result_dict["Server B public IP"] = str(ip)
1268 66eba2cf John Giannelos
1269 daac4017 John Giannelos
        while True:
1270 daac4017 John Giannelos
            if self._ping_once(ip):
1271 daac4017 John Giannelos
                s = True
1272 daac4017 John Giannelos
                break
1273 88736f65 John Giannelos
1274 daac4017 John Giannelos
            elif time.time() > fail_tmout:
1275 daac4017 John Giannelos
                self.assertLess(time.time(), fail_tmout)
1276 88736f65 John Giannelos
1277 daac4017 John Giannelos
            else:
1278 daac4017 John Giannelos
                time.sleep(self.query_interval)
1279 88736f65 John Giannelos
1280 daac4017 John Giannelos
        self.assertTrue(s)
1281 88736f65 John Giannelos
1282 daac4017 John Giannelos
    def test_003a_setup_interface_A(self):
1283 daac4017 John Giannelos
        """Set up eth1 for server A"""
1284 f89d0238 John Giannelos
1285 daac4017 John Giannelos
        self._skipIf(self.is_windows, "only valid for Linux servers")
1286 e49bdb7c John Giannelos
1287 daac4017 John Giannelos
        log.info("Setting up interface eth1 for server A")
1288 66eba2cf John Giannelos
        self.result_dict.clear()
1289 ae139e8a John Giannelos
1290 daac4017 John Giannelos
        server = self.client.get_server_details(self.serverid['A'])
1291 daac4017 John Giannelos
        image = self.client.get_image_details(self.imageid)
1292 6e168615 Ilias Tsitsimpis
        os_value = image['metadata']['values']['os']
1293 8252d64f John Giannelos
1294 daac4017 John Giannelos
        users = image["metadata"]["values"].get("users", None)
1295 daac4017 John Giannelos
        userlist = users.split()
1296 d5cc50b3 John Giannelos
1297 daac4017 John Giannelos
        if "root" in userlist:
1298 daac4017 John Giannelos
            loginname = "root"
1299 6e168615 Ilias Tsitsimpis
        elif users is None:
1300 6e168615 Ilias Tsitsimpis
            loginname = self._connect_loginname(os_value)
1301 daac4017 John Giannelos
        else:
1302 daac4017 John Giannelos
            loginname = choice(userlist)
1303 1b40b5e3 John Giannelos
1304 daac4017 John Giannelos
        hostip = self._get_ipv4(server)
1305 daac4017 John Giannelos
        myPass = self.password['A']
1306 8252d64f John Giannelos
1307 daac4017 John Giannelos
        log.info("SSH in server A as %s/%s" % (loginname, myPass))
1308 2a410f76 Ilias Tsitsimpis
        command = "ifconfig eth1 %s" % self.priv_ip["A"]
1309 2a410f76 Ilias Tsitsimpis
        output, status = _ssh_execute(
1310 2a410f76 Ilias Tsitsimpis
            hostip, loginname, myPass, command)
1311 8252d64f John Giannelos
1312 2a410f76 Ilias Tsitsimpis
        self.assertEquals(status, 0)
1313 1b40b5e3 John Giannelos
1314 daac4017 John Giannelos
    def test_003b_setup_interface_B(self):
1315 daac4017 John Giannelos
        """Setup eth1 for server B"""
1316 1b40b5e3 John Giannelos
1317 daac4017 John Giannelos
        self._skipIf(self.is_windows, "only valid for Linux servers")
1318 e49bdb7c John Giannelos
1319 daac4017 John Giannelos
        log.info("Setting up interface eth1 for server B")
1320 ae139e8a John Giannelos
1321 daac4017 John Giannelos
        server = self.client.get_server_details(self.serverid['B'])
1322 daac4017 John Giannelos
        image = self.client.get_image_details(self.imageid)
1323 6e168615 Ilias Tsitsimpis
        os_value = image['metadata']['values']['os']
1324 8252d64f John Giannelos
1325 daac4017 John Giannelos
        users = image["metadata"]["values"].get("users", None)
1326 daac4017 John Giannelos
        userlist = users.split()
1327 d5cc50b3 John Giannelos
1328 daac4017 John Giannelos
        if "root" in userlist:
1329 daac4017 John Giannelos
            loginname = "root"
1330 6e168615 Ilias Tsitsimpis
        elif users is None:
1331 6e168615 Ilias Tsitsimpis
            loginname = self._connect_loginname(os_value)
1332 daac4017 John Giannelos
        else:
1333 daac4017 John Giannelos
            loginname = choice(userlist)
1334 d5cc50b3 John Giannelos
1335 daac4017 John Giannelos
        hostip = self._get_ipv4(server)
1336 daac4017 John Giannelos
        myPass = self.password['B']
1337 740a5649 John Giannelos
1338 daac4017 John Giannelos
        log.info("SSH in server B as %s/%s" % (loginname, myPass))
1339 2a410f76 Ilias Tsitsimpis
        command = "ifconfig eth1 %s" % self.priv_ip["B"]
1340 2a410f76 Ilias Tsitsimpis
        output, status = _ssh_execute(
1341 2a410f76 Ilias Tsitsimpis
            hostip, loginname, myPass, command)
1342 1b40b5e3 John Giannelos
1343 2a410f76 Ilias Tsitsimpis
        self.assertEquals(status, 0)
1344 ae139e8a John Giannelos
1345 daac4017 John Giannelos
    def test_003c_test_connection_exists(self):
1346 daac4017 John Giannelos
        """Ping server B from server A to test if connection exists"""
1347 1b40b5e3 John Giannelos
1348 daac4017 John Giannelos
        self._skipIf(self.is_windows, "only valid for Linux servers")
1349 e49bdb7c John Giannelos
1350 daac4017 John Giannelos
        log.info("Testing if server A is actually connected to server B")
1351 f89d0238 John Giannelos
1352 daac4017 John Giannelos
        server = self.client.get_server_details(self.serverid['A'])
1353 daac4017 John Giannelos
        image = self.client.get_image_details(self.imageid)
1354 6e168615 Ilias Tsitsimpis
        os_value = image['metadata']['values']['os']
1355 daac4017 John Giannelos
        hostip = self._get_ipv4(server)
1356 d5cc50b3 John Giannelos
1357 daac4017 John Giannelos
        users = image["metadata"]["values"].get("users", None)
1358 daac4017 John Giannelos
        userlist = users.split()
1359 d5cc50b3 John Giannelos
1360 daac4017 John Giannelos
        if "root" in userlist:
1361 daac4017 John Giannelos
            loginname = "root"
1362 6e168615 Ilias Tsitsimpis
        elif users is None:
1363 6e168615 Ilias Tsitsimpis
            loginname = self._connect_loginname(os_value)
1364 daac4017 John Giannelos
        else:
1365 daac4017 John Giannelos
            loginname = choice(userlist)
1366 1b40b5e3 John Giannelos
1367 daac4017 John Giannelos
        myPass = self.password['A']
1368 88736f65 John Giannelos
1369 daac4017 John Giannelos
        cmd = "if ping -c 2 -w 3 %s >/dev/null; \
1370 daac4017 John Giannelos
               then echo \'True\'; fi;" % self.priv_ip["B"]
1371 2a410f76 Ilias Tsitsimpis
        lines, status = _ssh_execute(
1372 2a410f76 Ilias Tsitsimpis
            hostip, loginname, myPass, cmd)
1373 1b40b5e3 John Giannelos
1374 daac4017 John Giannelos
        exists = False
1375 4573ea07 John Giannelos
1376 daac4017 John Giannelos
        if 'True\n' in lines:
1377 daac4017 John Giannelos
            exists = True
1378 1b40b5e3 John Giannelos
1379 daac4017 John Giannelos
        self.assertTrue(exists)
1380 1b40b5e3 John Giannelos
1381 88736f65 John Giannelos
    def test_004_disconnect_from_network(self):
1382 4573ea07 John Giannelos
        "Disconnecting server A and B from network"
1383 4573ea07 John Giannelos
1384 f89d0238 John Giannelos
        log.info("Disconnecting servers from private network")
1385 f89d0238 John Giannelos
1386 f97dce4d John Giannelos
        prev_state = self.client.get_network_details(self.networkid)
1387 2aaa1336 John Giannelos
        prev_nics = prev_state['attachments']['values']
1388 6e168615 Ilias Tsitsimpis
        #prev_conn = len(prev_nics)
1389 2aaa1336 John Giannelos
1390 6e168615 Ilias Tsitsimpis
        nicsA = [x['id']
1391 6e168615 Ilias Tsitsimpis
                 for x in self.client.get_server_details(
1392 6e168615 Ilias Tsitsimpis
                     self.serverid['A'])['attachments']['values']]
1393 6e168615 Ilias Tsitsimpis
        nicsB = [x['id']
1394 6e168615 Ilias Tsitsimpis
                 for x in self.client.get_server_details(
1395 6e168615 Ilias Tsitsimpis
                     self.serverid['B'])['attachments']['values']]
1396 2aaa1336 John Giannelos
1397 2aaa1336 John Giannelos
        for nic in prev_nics:
1398 2aaa1336 John Giannelos
            if nic in nicsA:
1399 2aaa1336 John Giannelos
                self.client.disconnect_server(self.serverid['A'], nic)
1400 2aaa1336 John Giannelos
            if nic in nicsB:
1401 2aaa1336 John Giannelos
                self.client.disconnect_server(self.serverid['B'], nic)
1402 e94a9d8c John Giannelos
1403 65462ca9 John Giannelos
        #Insist on deleting until action timeout
1404 2bcfb712 John Giannelos
        fail_tmout = time.time() + self.action_timeout
1405 9e4682b5 John Giannelos
1406 65462ca9 John Giannelos
        while True:
1407 6e168615 Ilias Tsitsimpis
            netsA = [x['network_id']
1408 6e168615 Ilias Tsitsimpis
                     for x in self.client.get_server_details(
1409 6e168615 Ilias Tsitsimpis
                         self.serverid['A'])['attachments']['values']]
1410 6e168615 Ilias Tsitsimpis
            netsB = [x['network_id']
1411 6e168615 Ilias Tsitsimpis
                     for x in self.client.get_server_details(
1412 6e168615 Ilias Tsitsimpis
                         self.serverid['B'])['attachments']['values']]
1413 6e168615 Ilias Tsitsimpis
1414 6e168615 Ilias Tsitsimpis
            #connected = (self.client.get_network_details(self.networkid))
1415 6e168615 Ilias Tsitsimpis
            #connections = connected['attachments']['values']
1416 2aaa1336 John Giannelos
            if (self.networkid not in netsA) and (self.networkid not in netsB):
1417 65462ca9 John Giannelos
                conn_exists = False
1418 de2461ec John Giannelos
                break
1419 de2461ec John Giannelos
            elif time.time() > fail_tmout:
1420 65462ca9 John Giannelos
                self.assertLess(time.time(), fail_tmout)
1421 65462ca9 John Giannelos
            else:
1422 65462ca9 John Giannelos
                time.sleep(self.query_interval)
1423 65462ca9 John Giannelos
1424 65462ca9 John Giannelos
        self.assertFalse(conn_exists)
1425 9e4682b5 John Giannelos
1426 88736f65 John Giannelos
    def test_005_destroy_network(self):
1427 e94a9d8c John Giannelos
        """Test submit delete network request"""
1428 f89d0238 John Giannelos
1429 f89d0238 John Giannelos
        log.info("Submitting delete network request")
1430 f89d0238 John Giannelos
1431 8252d64f John Giannelos
        self.client.delete_network(self.networkid)
1432 e50133da John Giannelos
1433 2aaa1336 John Giannelos
        fail_tmout = time.time() + self.action_timeout
1434 2aaa1336 John Giannelos
1435 2aaa1336 John Giannelos
        while True:
1436 e94a9d8c John Giannelos
1437 2aaa1336 John Giannelos
            curr_net = []
1438 2aaa1336 John Giannelos
            networks = self.client.list_networks()
1439 2aaa1336 John Giannelos
1440 2aaa1336 John Giannelos
            for net in networks:
1441 2aaa1336 John Giannelos
                curr_net.append(net['id'])
1442 2aaa1336 John Giannelos
1443 2aaa1336 John Giannelos
            if self.networkid not in curr_net:
1444 2aaa1336 John Giannelos
                self.assertTrue(self.networkid not in curr_net)
1445 2aaa1336 John Giannelos
                break
1446 65462ca9 John Giannelos
1447 2aaa1336 John Giannelos
            elif time.time() > fail_tmout:
1448 2aaa1336 John Giannelos
                self.assertLess(time.time(), fail_tmout)
1449 2aaa1336 John Giannelos
1450 2aaa1336 John Giannelos
            else:
1451 2aaa1336 John Giannelos
                time.sleep(self.query_interval)
1452 2aaa1336 John Giannelos
1453 88736f65 John Giannelos
    def test_006_cleanup_servers(self):
1454 65462ca9 John Giannelos
        """Cleanup servers created for this test"""
1455 f89d0238 John Giannelos
1456 f89d0238 John Giannelos
        log.info("Delete servers created for this test")
1457 f89d0238 John Giannelos
1458 91de9b55 John Giannelos
        self.compute.delete_server(self.serverid['A'])
1459 91de9b55 John Giannelos
        self.compute.delete_server(self.serverid['B'])
1460 91de9b55 John Giannelos
1461 2bcfb712 John Giannelos
        fail_tmout = time.time() + self.action_timeout
1462 65462ca9 John Giannelos
1463 65462ca9 John Giannelos
        #Ensure server gets deleted
1464 8252d64f John Giannelos
        status = dict()
1465 91de9b55 John Giannelos
1466 65462ca9 John Giannelos
        while True:
1467 91de9b55 John Giannelos
            details = self.compute.get_server_details(self.serverid['A'])
1468 91de9b55 John Giannelos
            status['A'] = details['status']
1469 91de9b55 John Giannelos
            details = self.compute.get_server_details(self.serverid['B'])
1470 91de9b55 John Giannelos
            status['B'] = details['status']
1471 91de9b55 John Giannelos
            if (status['A'] == 'DELETED') and (status['B'] == 'DELETED'):
1472 65462ca9 John Giannelos
                deleted = True
1473 de2461ec John Giannelos
                break
1474 8252d64f John Giannelos
            elif time.time() > fail_tmout:
1475 65462ca9 John Giannelos
                self.assertLess(time.time(), fail_tmout)
1476 65462ca9 John Giannelos
            else:
1477 65462ca9 John Giannelos
                time.sleep(self.query_interval)
1478 8252d64f John Giannelos
1479 65462ca9 John Giannelos
        self.assertTrue(deleted)
1480 e94a9d8c John Giannelos
1481 4573ea07 John Giannelos
1482 21bbbc9b Vangelis Koukis
class TestRunnerProcess(Process):
1483 21bbbc9b Vangelis Koukis
    """A distinct process used to execute part of the tests in parallel"""
1484 21bbbc9b Vangelis Koukis
    def __init__(self, **kw):
1485 21bbbc9b Vangelis Koukis
        Process.__init__(self, **kw)
1486 96da37c8 John Giannelos
        kwargs = kw["kwargs"]
1487 21bbbc9b Vangelis Koukis
        self.testq = kwargs["testq"]
1488 2aaa1336 John Giannelos
        self.worker_folder = kwargs["worker_folder"]
1489 21bbbc9b Vangelis Koukis
1490 21bbbc9b Vangelis Koukis
    def run(self):
1491 21bbbc9b Vangelis Koukis
        # Make sure this test runner process dies with the parent
1492 21bbbc9b Vangelis Koukis
        # and is not left behind.
1493 21bbbc9b Vangelis Koukis
        #
1494 21bbbc9b Vangelis Koukis
        # WARNING: This uses the prctl(2) call and is
1495 21bbbc9b Vangelis Koukis
        # Linux-specific.
1496 2aaa1336 John Giannelos
1497 21bbbc9b Vangelis Koukis
        prctl.set_pdeathsig(signal.SIGHUP)
1498 21bbbc9b Vangelis Koukis
1499 2aaa1336 John Giannelos
        multi = logging.getLogger("multiprocess")
1500 2aaa1336 John Giannelos
1501 21bbbc9b Vangelis Koukis
        while True:
1502 2aaa1336 John Giannelos
            multi.debug("I am process %d, GETting from queue is %s" %
1503 6e168615 Ilias Tsitsimpis
                        (os.getpid(), self.testq))
1504 21bbbc9b Vangelis Koukis
            msg = self.testq.get()
1505 2aaa1336 John Giannelos
1506 2aaa1336 John Giannelos
            multi.debug("Dequeued msg: %s" % msg)
1507 21bbbc9b Vangelis Koukis
1508 21bbbc9b Vangelis Koukis
            if msg == "TEST_RUNNER_TERMINATE":
1509 21bbbc9b Vangelis Koukis
                raise SystemExit
1510 2aaa1336 John Giannelos
1511 21bbbc9b Vangelis Koukis
            elif issubclass(msg, unittest.TestCase):
1512 21bbbc9b Vangelis Koukis
                # Assemble a TestSuite, and run it
1513 2aaa1336 John Giannelos
1514 2aaa1336 John Giannelos
                log_file = os.path.join(self.worker_folder, 'details_' +
1515 2aaa1336 John Giannelos
                                        (msg.__name__) + "_" +
1516 2aaa1336 John Giannelos
                                        TEST_RUN_ID + '.log')
1517 e50133da John Giannelos
1518 2aaa1336 John Giannelos
                fail_file = os.path.join(self.worker_folder, 'failed_' +
1519 2aaa1336 John Giannelos
                                         (msg.__name__) + "_" +
1520 2aaa1336 John Giannelos
                                         TEST_RUN_ID + '.log')
1521 2aaa1336 John Giannelos
                error_file = os.path.join(self.worker_folder, 'error_' +
1522 2aaa1336 John Giannelos
                                          (msg.__name__) + "_" +
1523 2aaa1336 John Giannelos
                                          TEST_RUN_ID + '.log')
1524 2aaa1336 John Giannelos
1525 2aaa1336 John Giannelos
                f = open(log_file, 'w')
1526 6e168615 Ilias Tsitsimpis
                fail = open(fail_file, 'w')
1527 2aaa1336 John Giannelos
                error = open(error_file, 'w')
1528 2aaa1336 John Giannelos
1529 2aaa1336 John Giannelos
                log.info(yellow + '* Starting testcase: %s' % msg + normal)
1530 2aaa1336 John Giannelos
1531 6e168615 Ilias Tsitsimpis
                runner = unittest.TextTestRunner(
1532 6e168615 Ilias Tsitsimpis
                    f, verbosity=2, failfast=True,
1533 6e168615 Ilias Tsitsimpis
                    resultclass=BurninTestResult)
1534 21bbbc9b Vangelis Koukis
                suite = unittest.TestLoader().loadTestsFromTestCase(msg)
1535 2aaa1336 John Giannelos
                result = runner.run(suite)
1536 2aaa1336 John Giannelos
1537 2aaa1336 John Giannelos
                for res in result.errors:
1538 6e168615 Ilias Tsitsimpis
                    log.error("snf-burnin encountered an error in "
1539 6e168615 Ilias Tsitsimpis
                              "testcase: %s" % msg)
1540 2aaa1336 John Giannelos
                    log.error("See log for details")
1541 2aaa1336 John Giannelos
                    error.write(str(res[0]) + '\n')
1542 2aaa1336 John Giannelos
                    error.write(str(res[0].shortDescription()) + '\n')
1543 2aaa1336 John Giannelos
                    error.write('\n')
1544 2aaa1336 John Giannelos
1545 2aaa1336 John Giannelos
                for res in result.failures:
1546 6e168615 Ilias Tsitsimpis
                    log.error("snf-burnin failed in testcase: %s" % msg)
1547 2aaa1336 John Giannelos
                    log.error("See log for details")
1548 2aaa1336 John Giannelos
                    fail.write(str(res[0]) + '\n')
1549 2aaa1336 John Giannelos
                    fail.write(str(res[0].shortDescription()) + '\n')
1550 2aaa1336 John Giannelos
                    fail.write('\n')
1551 6e168615 Ilias Tsitsimpis
                    if not NOFAILFAST:
1552 2aaa1336 John Giannelos
                        sys.exit()
1553 2aaa1336 John Giannelos
1554 2aaa1336 John Giannelos
                if (len(result.failures) == 0) and (len(result.errors) == 0):
1555 6e168615 Ilias Tsitsimpis
                    log.debug("Passed testcase: %s" % msg)
1556 2aaa1336 John Giannelos
1557 2aaa1336 John Giannelos
                f.close()
1558 2aaa1336 John Giannelos
                fail.close()
1559 2aaa1336 John Giannelos
                error.close()
1560 2aaa1336 John Giannelos
1561 21bbbc9b Vangelis Koukis
            else:
1562 21bbbc9b Vangelis Koukis
                raise Exception("Cannot handle msg: %s" % msg)
1563 21bbbc9b Vangelis Koukis
1564 6e168615 Ilias Tsitsimpis
1565 6e168615 Ilias Tsitsimpis
def _run_cases_in_series(cases, image_folder):
1566 3e4c5c32 John Giannelos
    """Run instances of TestCase in series"""
1567 3e4c5c32 John Giannelos
1568 3e4c5c32 John Giannelos
    for case in cases:
1569 3e4c5c32 John Giannelos
1570 3e4c5c32 John Giannelos
        test = case.__name__
1571 3e4c5c32 John Giannelos
1572 6e168615 Ilias Tsitsimpis
        log.info(yellow + '* Starting testcase: %s' % test + normal)
1573 3e4c5c32 John Giannelos
        log_file = os.path.join(image_folder, 'details_' +
1574 3e4c5c32 John Giannelos
                                (case.__name__) + "_" +
1575 3e4c5c32 John Giannelos
                                TEST_RUN_ID + '.log')
1576 3e4c5c32 John Giannelos
        fail_file = os.path.join(image_folder, 'failed_' +
1577 3e4c5c32 John Giannelos
                                 (case.__name__) + "_" +
1578 3e4c5c32 John Giannelos
                                 TEST_RUN_ID + '.log')
1579 3e4c5c32 John Giannelos
        error_file = os.path.join(image_folder, 'error_' +
1580 3e4c5c32 John Giannelos
                                  (case.__name__) + "_" +
1581 3e4c5c32 John Giannelos
                                  TEST_RUN_ID + '.log')
1582 3e4c5c32 John Giannelos
1583 3e4c5c32 John Giannelos
        f = open(log_file, "w")
1584 3e4c5c32 John Giannelos
        fail = open(fail_file, "w")
1585 3e4c5c32 John Giannelos
        error = open(error_file, "w")
1586 3e4c5c32 John Giannelos
1587 3e4c5c32 John Giannelos
        suite = unittest.TestLoader().loadTestsFromTestCase(case)
1588 6e168615 Ilias Tsitsimpis
        runner = unittest.TextTestRunner(
1589 6e168615 Ilias Tsitsimpis
            f, verbosity=2, failfast=True,
1590 6e168615 Ilias Tsitsimpis
            resultclass=BurninTestResult)
1591 3e4c5c32 John Giannelos
        result = runner.run(suite)
1592 3e4c5c32 John Giannelos
1593 3e4c5c32 John Giannelos
        for res in result.errors:
1594 6e168615 Ilias Tsitsimpis
            log.error("snf-burnin encountered an error in "
1595 6e168615 Ilias Tsitsimpis
                      "testcase: %s" % test)
1596 3e4c5c32 John Giannelos
            log.error("See log for details")
1597 3e4c5c32 John Giannelos
            error.write(str(res[0]) + '\n')
1598 3e4c5c32 John Giannelos
            error.write(str(res[0].shortDescription()) + '\n')
1599 3e4c5c32 John Giannelos
            error.write('\n')
1600 3e4c5c32 John Giannelos
1601 3e4c5c32 John Giannelos
        for res in result.failures:
1602 6e168615 Ilias Tsitsimpis
            log.error("snf-burnin failed in testcase: %s" % test)
1603 3e4c5c32 John Giannelos
            log.error("See log for details")
1604 3e4c5c32 John Giannelos
            fail.write(str(res[0]) + '\n')
1605 3e4c5c32 John Giannelos
            fail.write(str(res[0].shortDescription()) + '\n')
1606 3e4c5c32 John Giannelos
            fail.write('\n')
1607 6e168615 Ilias Tsitsimpis
            if not NOFAILFAST:
1608 3e4c5c32 John Giannelos
                sys.exit()
1609 3e4c5c32 John Giannelos
1610 3e4c5c32 John Giannelos
        if (len(result.failures) == 0) and (len(result.errors) == 0):
1611 6e168615 Ilias Tsitsimpis
            log.debug("Passed testcase: %s" % test)
1612 3e4c5c32 John Giannelos
1613 21bbbc9b Vangelis Koukis
1614 2aaa1336 John Giannelos
def _run_cases_in_parallel(cases, fanout, image_folder):
1615 21bbbc9b Vangelis Koukis
    """Run instances of TestCase in parallel, in a number of distinct processes
1616 21bbbc9b Vangelis Koukis

1617 21bbbc9b Vangelis Koukis
    The cases iterable specifies the TestCases to be executed in parallel,
1618 21bbbc9b Vangelis Koukis
    by test runners running in distinct processes.
1619 21bbbc9b Vangelis Koukis
    The fanout parameter specifies the number of processes to spawn,
1620 21bbbc9b Vangelis Koukis
    and defaults to 1.
1621 21bbbc9b Vangelis Koukis
    The runner argument specifies the test runner class to use inside each
1622 21bbbc9b Vangelis Koukis
    runner process.
1623 21bbbc9b Vangelis Koukis

1624 21bbbc9b Vangelis Koukis
    """
1625 e50133da John Giannelos
1626 2aaa1336 John Giannelos
    multi = logging.getLogger("multiprocess")
1627 2aaa1336 John Giannelos
    handler = logging.StreamHandler()
1628 2aaa1336 John Giannelos
    multi.addHandler(handler)
1629 21bbbc9b Vangelis Koukis
1630 2aaa1336 John Giannelos
    if VERBOSE:
1631 2aaa1336 John Giannelos
        multi.setLevel(logging.DEBUG)
1632 2aaa1336 John Giannelos
    else:
1633 2aaa1336 John Giannelos
        multi.setLevel(logging.INFO)
1634 2aaa1336 John Giannelos
1635 2aaa1336 John Giannelos
    testq = []
1636 2aaa1336 John Giannelos
    worker_folder = []
1637 21bbbc9b Vangelis Koukis
    runners = []
1638 2aaa1336 John Giannelos
1639 6e168615 Ilias Tsitsimpis
    for i in xrange(0, fanout):
1640 2aaa1336 John Giannelos
        testq.append(Queue())
1641 2aaa1336 John Giannelos
        worker_folder.append(os.path.join(image_folder, 'process'+str(i)))
1642 2aaa1336 John Giannelos
        os.mkdir(worker_folder[i])
1643 2aaa1336 John Giannelos
1644 21bbbc9b Vangelis Koukis
    for i in xrange(0, fanout):
1645 2aaa1336 John Giannelos
        kwargs = dict(testq=testq[i], worker_folder=worker_folder[i])
1646 21bbbc9b Vangelis Koukis
        runners.append(TestRunnerProcess(kwargs=kwargs))
1647 21bbbc9b Vangelis Koukis
1648 6e168615 Ilias Tsitsimpis
    multi.debug("Spawning %d test runner processes" % len(runners))
1649 2aaa1336 John Giannelos
1650 21bbbc9b Vangelis Koukis
    for p in runners:
1651 21bbbc9b Vangelis Koukis
        p.start()
1652 21bbbc9b Vangelis Koukis
1653 21bbbc9b Vangelis Koukis
    # Enqueue test cases
1654 2aaa1336 John Giannelos
    for i in xrange(0, fanout):
1655 2aaa1336 John Giannelos
        map(testq[i].put, cases)
1656 2aaa1336 John Giannelos
        testq[i].put("TEST_RUNNER_TERMINATE")
1657 2aaa1336 John Giannelos
1658 2aaa1336 John Giannelos
    multi.debug("Spawned %d test runners, PIDs are %s" %
1659 6e168615 Ilias Tsitsimpis
                (len(runners), [p.pid for p in runners]))
1660 21bbbc9b Vangelis Koukis
1661 2aaa1336 John Giannelos
    multi.debug("Joining %d processes" % len(runners))
1662 e50133da John Giannelos
1663 21bbbc9b Vangelis Koukis
    for p in runners:
1664 21bbbc9b Vangelis Koukis
        p.join()
1665 2aaa1336 John Giannelos
1666 2aaa1336 John Giannelos
    multi.debug("Done joining %d processes" % len(runners))
1667 4fdd25ab Vangelis Koukis
1668 5a140b23 Vangelis Koukis
1669 95a87099 Ilias Tsitsimpis
def _images_test_case(**kwargs):
1670 95a87099 Ilias Tsitsimpis
    """Construct a new unit test case class from ImagesTestCase"""
1671 95a87099 Ilias Tsitsimpis
    name = "ImagesTestCase_%s" % kwargs["imageid"]
1672 95a87099 Ilias Tsitsimpis
    cls = type(name, (ImagesTestCase,), kwargs)
1673 95a87099 Ilias Tsitsimpis
1674 95a87099 Ilias Tsitsimpis
    #Patch extra parameters into test names by manipulating method docstrings
1675 95a87099 Ilias Tsitsimpis
    for (mname, m) in \
1676 95a87099 Ilias Tsitsimpis
            inspect.getmembers(cls, lambda x: inspect.ismethod(x)):
1677 95a87099 Ilias Tsitsimpis
        if hasattr(m, __doc__):
1678 95a87099 Ilias Tsitsimpis
            m.__func__.__doc__ = "[%s] %s" % (cls.imagename, m.__doc__)
1679 95a87099 Ilias Tsitsimpis
1680 95a87099 Ilias Tsitsimpis
    # Make sure the class can be pickled, by listing it among
1681 95a87099 Ilias Tsitsimpis
    # the attributes of __main__. A PicklingError is raised otherwise.
1682 95a87099 Ilias Tsitsimpis
    thismodule = sys.modules[__name__]
1683 95a87099 Ilias Tsitsimpis
    setattr(thismodule, name, cls)
1684 95a87099 Ilias Tsitsimpis
    return cls
1685 95a87099 Ilias Tsitsimpis
1686 95a87099 Ilias Tsitsimpis
1687 5a140b23 Vangelis Koukis
def _spawn_server_test_case(**kwargs):
1688 5a140b23 Vangelis Koukis
    """Construct a new unit test case class from SpawnServerTestCase"""
1689 5a140b23 Vangelis Koukis
1690 c1d11f96 John Giannelos
    name = "SpawnServerTestCase_%s" % kwargs["imageid"]
1691 5a140b23 Vangelis Koukis
    cls = type(name, (SpawnServerTestCase,), kwargs)
1692 5a140b23 Vangelis Koukis
1693 5a140b23 Vangelis Koukis
    # Patch extra parameters into test names by manipulating method docstrings
1694 5a140b23 Vangelis Koukis
    for (mname, m) in \
1695 6e168615 Ilias Tsitsimpis
            inspect.getmembers(cls, lambda x: inspect.ismethod(x)):
1696 74ec726f John Giannelos
        if hasattr(m, __doc__):
1697 6e168615 Ilias Tsitsimpis
            m.__func__.__doc__ = "[%s] %s" % (cls.imagename, m.__doc__)
1698 e72bcf60 Vangelis Koukis
1699 e72bcf60 Vangelis Koukis
    # Make sure the class can be pickled, by listing it among
1700 e72bcf60 Vangelis Koukis
    # the attributes of __main__. A PicklingError is raised otherwise.
1701 2aaa1336 John Giannelos
1702 2aaa1336 John Giannelos
    thismodule = sys.modules[__name__]
1703 2aaa1336 John Giannelos
    setattr(thismodule, name, cls)
1704 8252d64f John Giannelos
    return cls
1705 65462ca9 John Giannelos
1706 2bcfb712 John Giannelos
1707 65462ca9 John Giannelos
def _spawn_network_test_case(**kwargs):
1708 65462ca9 John Giannelos
    """Construct a new unit test case class from NetworkTestCase"""
1709 65462ca9 John Giannelos
1710 2bcfb712 John Giannelos
    name = "NetworkTestCase" + TEST_RUN_ID
1711 65462ca9 John Giannelos
    cls = type(name, (NetworkTestCase,), kwargs)
1712 65462ca9 John Giannelos
1713 65462ca9 John Giannelos
    # Make sure the class can be pickled, by listing it among
1714 65462ca9 John Giannelos
    # the attributes of __main__. A PicklingError is raised otherwise.
1715 e50133da John Giannelos
1716 2aaa1336 John Giannelos
    thismodule = sys.modules[__name__]
1717 2aaa1336 John Giannelos
    setattr(thismodule, name, cls)
1718 8252d64f John Giannelos
    return cls
1719 5a140b23 Vangelis Koukis
1720 5a140b23 Vangelis Koukis
1721 8792bb97 Ilias Tsitsimpis
# --------------------------------------------------------------------
1722 8792bb97 Ilias Tsitsimpis
# Clean up servers/networks functions
1723 c0448f4f John Giannelos
def cleanup_servers(timeout, query_interval, delete_stale=False):
1724 74193008 John Giannelos
1725 567ffb85 John Giannelos
    c = ComputeClient(API, TOKEN)
1726 74193008 John Giannelos
1727 5a140b23 Vangelis Koukis
    servers = c.list_servers()
1728 5a140b23 Vangelis Koukis
    stale = [s for s in servers if s["name"].startswith(SNF_TEST_PREFIX)]
1729 5a140b23 Vangelis Koukis
1730 4fdd25ab Vangelis Koukis
    if len(stale) == 0:
1731 4fdd25ab Vangelis Koukis
        return
1732 4fdd25ab Vangelis Koukis
1733 8792bb97 Ilias Tsitsimpis
    # Show staled servers
1734 8792bb97 Ilias Tsitsimpis
    print >>sys.stderr, yellow + \
1735 6e168615 Ilias Tsitsimpis
        "Found these stale servers from previous runs:" + \
1736 6e168615 Ilias Tsitsimpis
        normal
1737 8792bb97 Ilias Tsitsimpis
    print >>sys.stderr, "    " + \
1738 6e168615 Ilias Tsitsimpis
        "\n    ".join(["%d: %s" % (s["id"], s["name"]) for s in stale])
1739 5a140b23 Vangelis Koukis
1740 8792bb97 Ilias Tsitsimpis
    # Delete staled servers
1741 5a140b23 Vangelis Koukis
    if delete_stale:
1742 5a140b23 Vangelis Koukis
        print >> sys.stderr, "Deleting %d stale servers:" % len(stale)
1743 c0448f4f John Giannelos
        fail_tmout = time.time() + timeout
1744 c0448f4f John Giannelos
        for s in stale:
1745 c0448f4f John Giannelos
            c.delete_server(s["id"])
1746 8792bb97 Ilias Tsitsimpis
        # Wait for all servers to be deleted
1747 c0448f4f John Giannelos
        while True:
1748 c0448f4f John Giannelos
            servers = c.list_servers()
1749 6e168615 Ilias Tsitsimpis
            stale = [s for s in servers
1750 6e168615 Ilias Tsitsimpis
                     if s["name"].startswith(SNF_TEST_PREFIX)]
1751 6e168615 Ilias Tsitsimpis
            if len(stale) == 0:
1752 c0448f4f John Giannelos
                print >> sys.stderr, green + "    ...done" + normal
1753 c0448f4f John Giannelos
                break
1754 c0448f4f John Giannelos
            elif time.time() > fail_tmout:
1755 8792bb97 Ilias Tsitsimpis
                print >> sys.stderr, red + \
1756 6e168615 Ilias Tsitsimpis
                    "Not all stale servers deleted. Action timed out." + \
1757 6e168615 Ilias Tsitsimpis
                    normal
1758 6e168615 Ilias Tsitsimpis
                sys.exit(1)
1759 c0448f4f John Giannelos
            else:
1760 c0448f4f John Giannelos
                time.sleep(query_interval)
1761 5a140b23 Vangelis Koukis
    else:
1762 5a140b23 Vangelis Koukis
        print >> sys.stderr, "Use --delete-stale to delete them."
1763 5a140b23 Vangelis Koukis
1764 2bcfb712 John Giannelos
1765 f752215c John Giannelos
def cleanup_networks(action_timeout, query_interval, delete_stale=False):
1766 74ec726f John Giannelos
1767 74ec726f John Giannelos
    c = CycladesClient(API, TOKEN)
1768 e50133da John Giannelos
1769 74ec726f John Giannelos
    networks = c.list_networks()
1770 74ec726f John Giannelos
    stale = [n for n in networks if n["name"].startswith(SNF_TEST_PREFIX)]
1771 74ec726f John Giannelos
1772 74ec726f John Giannelos
    if len(stale) == 0:
1773 74ec726f John Giannelos
        return
1774 e50133da John Giannelos
1775 8792bb97 Ilias Tsitsimpis
    # Show staled networks
1776 8792bb97 Ilias Tsitsimpis
    print >> sys.stderr, yellow + \
1777 6e168615 Ilias Tsitsimpis
        "Found these stale networks from previous runs:" + \
1778 6e168615 Ilias Tsitsimpis
        normal
1779 74ec726f John Giannelos
    print "    " + \
1780 6e168615 Ilias Tsitsimpis
        "\n    ".join(["%s: %s" % (str(n["id"]), n["name"]) for n in stale])
1781 74ec726f John Giannelos
1782 8792bb97 Ilias Tsitsimpis
    # Delete staled networks
1783 74ec726f John Giannelos
    if delete_stale:
1784 74ec726f John Giannelos
        print >> sys.stderr, "Deleting %d stale networks:" % len(stale)
1785 f752215c John Giannelos
        fail_tmout = time.time() + action_timeout
1786 c0448f4f John Giannelos
        for n in stale:
1787 c0448f4f John Giannelos
            c.delete_network(n["id"])
1788 8792bb97 Ilias Tsitsimpis
        # Wait for all networks to be deleted
1789 c0448f4f John Giannelos
        while True:
1790 c0448f4f John Giannelos
            networks = c.list_networks()
1791 6e168615 Ilias Tsitsimpis
            stale = [n for n in networks
1792 6e168615 Ilias Tsitsimpis
                     if n["name"].startswith(SNF_TEST_PREFIX)]
1793 6e168615 Ilias Tsitsimpis
            if len(stale) == 0:
1794 c0448f4f John Giannelos
                print >> sys.stderr, green + "    ...done" + normal
1795 c0448f4f John Giannelos
                break
1796 c0448f4f John Giannelos
            elif time.time() > fail_tmout:
1797 8792bb97 Ilias Tsitsimpis
                print >> sys.stderr, red + \
1798 6e168615 Ilias Tsitsimpis
                    "Not all stale networks deleted. Action timed out." + \
1799 6e168615 Ilias Tsitsimpis
                    normal
1800 6e168615 Ilias Tsitsimpis
                sys.exit(1)
1801 c0448f4f John Giannelos
            else:
1802 c0448f4f John Giannelos
                time.sleep(query_interval)
1803 74ec726f John Giannelos
    else:
1804 74ec726f John Giannelos
        print >> sys.stderr, "Use --delete-stale to delete them."
1805 74ec726f John Giannelos
1806 746540cd John Giannelos
1807 8792bb97 Ilias Tsitsimpis
# --------------------------------------------------------------------
1808 8792bb97 Ilias Tsitsimpis
# Parse arguments functions
1809 22efe1fe John Giannelos
def parse_comma(option, opt, value, parser):
1810 746540cd John Giannelos
    tests = set(['all', 'auth', 'images', 'flavors',
1811 11779b6c Ilias Tsitsimpis
                 'pithos', 'servers', 'server_spawn',
1812 11779b6c Ilias Tsitsimpis
                 'network_spawn'])
1813 22efe1fe John Giannelos
    parse_input = value.split(',')
1814 22efe1fe John Giannelos
1815 22efe1fe John Giannelos
    if not (set(parse_input)).issubset(tests):
1816 22efe1fe John Giannelos
        raise OptionValueError("The selected set of tests is invalid")
1817 22efe1fe John Giannelos
1818 22efe1fe John Giannelos
    setattr(parser.values, option.dest, value.split(','))
1819 22efe1fe John Giannelos
1820 74ec726f John Giannelos
1821 5a140b23 Vangelis Koukis
def parse_arguments(args):
1822 5a140b23 Vangelis Koukis
1823 5a140b23 Vangelis Koukis
    kw = {}
1824 5a140b23 Vangelis Koukis
    kw["usage"] = "%prog [options]"
1825 5a140b23 Vangelis Koukis
    kw["description"] = \
1826 5a140b23 Vangelis Koukis
        "%prog runs a number of test scenarios on a " \
1827 5a140b23 Vangelis Koukis
        "Synnefo deployment."
1828 5a140b23 Vangelis Koukis
1829 5a140b23 Vangelis Koukis
    parser = OptionParser(**kw)
1830 5a140b23 Vangelis Koukis
    parser.disable_interspersed_args()
1831 22efe1fe John Giannelos
1832 21bbbc9b Vangelis Koukis
    parser.add_option("--api",
1833 21bbbc9b Vangelis Koukis
                      action="store", type="string", dest="api",
1834 21bbbc9b Vangelis Koukis
                      help="The API URI to use to reach the Synnefo API",
1835 11779b6c Ilias Tsitsimpis
                      default=None)
1836 946da8b6 John Giannelos
    parser.add_option("--plankton",
1837 946da8b6 John Giannelos
                      action="store", type="string", dest="plankton",
1838 946da8b6 John Giannelos
                      help="The API URI to use to reach the Plankton API",
1839 11779b6c Ilias Tsitsimpis
                      default=None)
1840 946da8b6 John Giannelos
    parser.add_option("--plankton-user",
1841 946da8b6 John Giannelos
                      action="store", type="string", dest="plankton_user",
1842 946da8b6 John Giannelos
                      help="Owner of system images",
1843 946da8b6 John Giannelos
                      default=DEFAULT_PLANKTON_USER)
1844 11779b6c Ilias Tsitsimpis
    parser.add_option("--pithos",
1845 11779b6c Ilias Tsitsimpis
                      action="store", type="string", dest="pithos",
1846 11779b6c Ilias Tsitsimpis
                      help="The API URI to use to reach the Pithos API",
1847 11779b6c Ilias Tsitsimpis
                      default=None)
1848 11779b6c Ilias Tsitsimpis
    parser.add_option("--pithos_user",
1849 11779b6c Ilias Tsitsimpis
                      action="store", type="string", dest="pithos_user",
1850 11779b6c Ilias Tsitsimpis
                      help="Owner of the pithos account",
1851 11779b6c Ilias Tsitsimpis
                      default=None)
1852 21bbbc9b Vangelis Koukis
    parser.add_option("--token",
1853 21bbbc9b Vangelis Koukis
                      action="store", type="string", dest="token",
1854 38d247df Kostas Papadimitriou
                      help="The token to use for authentication to the API")
1855 00f87624 Vangelis Koukis
    parser.add_option("--nofailfast",
1856 00f87624 Vangelis Koukis
                      action="store_true", dest="nofailfast",
1857 6e168615 Ilias Tsitsimpis
                      help="Do not fail immediately if one of the tests "
1858 00f87624 Vangelis Koukis
                           "fails (EXPERIMENTAL)",
1859 bc14ba88 Vangelis Koukis
                      default=False)
1860 946da8b6 John Giannelos
    parser.add_option("--no-ipv6",
1861 946da8b6 John Giannelos
                      action="store_true", dest="no_ipv6",
1862 946da8b6 John Giannelos
                      help="Disables ipv6 related tests",
1863 946da8b6 John Giannelos
                      default=False)
1864 5a140b23 Vangelis Koukis
    parser.add_option("--action-timeout",
1865 5a140b23 Vangelis Koukis
                      action="store", type="int", dest="action_timeout",
1866 5a140b23 Vangelis Koukis
                      metavar="TIMEOUT",
1867 6e168615 Ilias Tsitsimpis
                      help="Wait SECONDS seconds for a server action to "
1868 5a140b23 Vangelis Koukis
                           "complete, then the test is considered failed",
1869 9e4682b5 John Giannelos
                      default=100)
1870 5a140b23 Vangelis Koukis
    parser.add_option("--build-warning",
1871 5a140b23 Vangelis Koukis
                      action="store", type="int", dest="build_warning",
1872 5a140b23 Vangelis Koukis
                      metavar="TIMEOUT",
1873 6e168615 Ilias Tsitsimpis
                      help="Warn if TIMEOUT seconds have passed and a "
1874 5a140b23 Vangelis Koukis
                           "build operation is still pending",
1875 5a140b23 Vangelis Koukis
                      default=600)
1876 5a140b23 Vangelis Koukis
    parser.add_option("--build-fail",
1877 5a140b23 Vangelis Koukis
                      action="store", type="int", dest="build_fail",
1878 5a140b23 Vangelis Koukis
                      metavar="BUILD_TIMEOUT",
1879 6e168615 Ilias Tsitsimpis
                      help="Fail the test if TIMEOUT seconds have passed "
1880 5a140b23 Vangelis Koukis
                           "and a build operation is still incomplete",
1881 5a140b23 Vangelis Koukis
                      default=900)
1882 5a140b23 Vangelis Koukis
    parser.add_option("--query-interval",
1883 5a140b23 Vangelis Koukis
                      action="store", type="int", dest="query_interval",
1884 5a140b23 Vangelis Koukis
                      metavar="INTERVAL",
1885 6e168615 Ilias Tsitsimpis
                      help="Query server status when requests are pending "
1886 5a140b23 Vangelis Koukis
                           "every INTERVAL seconds",
1887 5a140b23 Vangelis Koukis
                      default=3)
1888 21bbbc9b Vangelis Koukis
    parser.add_option("--fanout",
1889 21bbbc9b Vangelis Koukis
                      action="store", type="int", dest="fanout",
1890 5a140b23 Vangelis Koukis
                      metavar="COUNT",
1891 6e168615 Ilias Tsitsimpis
                      help="Spawn up to COUNT child processes to execute "
1892 6e168615 Ilias Tsitsimpis
                           "in parallel, essentially have up to COUNT "
1893 00f87624 Vangelis Koukis
                           "server build requests outstanding (EXPERIMENTAL)",
1894 5a140b23 Vangelis Koukis
                      default=1)
1895 5a140b23 Vangelis Koukis
    parser.add_option("--force-flavor",
1896 5a140b23 Vangelis Koukis
                      action="store", type="int", dest="force_flavorid",
1897 5a140b23 Vangelis Koukis
                      metavar="FLAVOR ID",
1898 6e168615 Ilias Tsitsimpis
                      help="Force all server creations to use the specified "
1899 6e168615 Ilias Tsitsimpis
                           "FLAVOR ID instead of a randomly chosen one, "
1900 5a140b23 Vangelis Koukis
                           "useful if disk space is scarce",
1901 00f87624 Vangelis Koukis
                      default=None)
1902 7f62a0b5 Vangelis Koukis
    parser.add_option("--image-id",
1903 7f62a0b5 Vangelis Koukis
                      action="store", type="string", dest="force_imageid",
1904 00f87624 Vangelis Koukis
                      metavar="IMAGE ID",
1905 6e168615 Ilias Tsitsimpis
                      help="Test the specified image id, use 'all' to test "
1906 7f62a0b5 Vangelis Koukis
                           "all available images (mandatory argument)",
1907 00f87624 Vangelis Koukis
                      default=None)
1908 5a140b23 Vangelis Koukis
    parser.add_option("--show-stale",
1909 5a140b23 Vangelis Koukis
                      action="store_true", dest="show_stale",
1910 6e168615 Ilias Tsitsimpis
                      help="Show stale servers from previous runs, whose "
1911 21bbbc9b Vangelis Koukis
                           "name starts with `%s'" % SNF_TEST_PREFIX,
1912 5a140b23 Vangelis Koukis
                      default=False)
1913 5a140b23 Vangelis Koukis
    parser.add_option("--delete-stale",
1914 5a140b23 Vangelis Koukis
                      action="store_true", dest="delete_stale",
1915 6e168615 Ilias Tsitsimpis
                      help="Delete stale servers from previous runs, whose "
1916 21bbbc9b Vangelis Koukis
                           "name starts with `%s'" % SNF_TEST_PREFIX,
1917 5a140b23 Vangelis Koukis
                      default=False)
1918 9659e075 John Giannelos
    parser.add_option("--force-personality",
1919 65462ca9 John Giannelos
                      action="store", type="string", dest="personality_path",
1920 8252d64f John Giannelos
                      help="Force a personality file injection.\
1921 8252d64f John Giannelos
                            File path required. ",
1922 9659e075 John Giannelos
                      default=None)
1923 74ec726f John Giannelos
    parser.add_option("--log-folder",
1924 74ec726f John Giannelos
                      action="store", type="string", dest="log_folder",
1925 8252d64f John Giannelos
                      help="Define the absolute path where the output \
1926 8252d64f John Giannelos
                            log is stored. ",
1927 2bcfb712 John Giannelos
                      default="/var/log/burnin/")
1928 2aaa1336 John Giannelos
    parser.add_option("--verbose", "-V",
1929 2aaa1336 John Giannelos
                      action="store_true", dest="verbose",
1930 6e168615 Ilias Tsitsimpis
                      help="Print detailed output about multiple "
1931 8792bb97 Ilias Tsitsimpis
                           "processes spawning",
1932 2aaa1336 John Giannelos
                      default=False)
1933 22efe1fe John Giannelos
    parser.add_option("--set-tests",
1934 22efe1fe John Giannelos
                      action="callback",
1935 746540cd John Giannelos
                      dest="tests",
1936 22efe1fe John Giannelos
                      type="string",
1937 22efe1fe John Giannelos
                      help='Set comma seperated tests for this run. \
1938 22efe1fe John Giannelos
                            Available tests: auth, images, flavors, \
1939 746540cd John Giannelos
                                             servers, server_spawn, \
1940 11779b6c Ilias Tsitsimpis
                                             network_spawn, pithos. \
1941 22efe1fe John Giannelos
                            Default = all',
1942 22efe1fe John Giannelos
                      default='all',
1943 22efe1fe John Giannelos
                      callback=parse_comma)
1944 22efe1fe John Giannelos
1945 5a140b23 Vangelis Koukis
    (opts, args) = parser.parse_args(args)
1946 5a140b23 Vangelis Koukis
1947 8792bb97 Ilias Tsitsimpis
    # -----------------------
1948 5a140b23 Vangelis Koukis
    # Verify arguments
1949 8792bb97 Ilias Tsitsimpis
1950 8792bb97 Ilias Tsitsimpis
    # `delete_stale' implies `show_stale'
1951 5a140b23 Vangelis Koukis
    if opts.delete_stale:
1952 5a140b23 Vangelis Koukis
        opts.show_stale = True
1953 5a140b23 Vangelis Koukis
1954 11779b6c Ilias Tsitsimpis
    # `token' is mandatory
1955 11779b6c Ilias Tsitsimpis
    _mandatory_argument(opts.token, "--token")
1956 11779b6c Ilias Tsitsimpis
    # `api' is mandatory
1957 11779b6c Ilias Tsitsimpis
    _mandatory_argument(opts.api, "--api")
1958 11779b6c Ilias Tsitsimpis
1959 7f62a0b5 Vangelis Koukis
    if not opts.show_stale:
1960 11779b6c Ilias Tsitsimpis
        # `image-id' is mandatory
1961 11779b6c Ilias Tsitsimpis
        _mandatory_argument(opts.force_imageid, "--image_id")
1962 7f62a0b5 Vangelis Koukis
        if opts.force_imageid != 'all':
1963 7f62a0b5 Vangelis Koukis
            try:
1964 99d41650 John Giannelos
                opts.force_imageid = str(opts.force_imageid)
1965 7f62a0b5 Vangelis Koukis
            except ValueError:
1966 8792bb97 Ilias Tsitsimpis
                print >>sys.stderr, red + \
1967 6e168615 Ilias Tsitsimpis
                    "Invalid value specified for" + \
1968 6e168615 Ilias Tsitsimpis
                    "--image-id. Use a valid id, or `all'." + \
1969 6e168615 Ilias Tsitsimpis
                    normal
1970 7f62a0b5 Vangelis Koukis
                sys.exit(1)
1971 11779b6c Ilias Tsitsimpis
        # `pithos' is mandatory
1972 11779b6c Ilias Tsitsimpis
        _mandatory_argument(opts.pithos, "--pithos")
1973 11779b6c Ilias Tsitsimpis
        # `pithos_user' is mandatory
1974 11779b6c Ilias Tsitsimpis
        _mandatory_argument(opts.pithos_user, "--pithos_user")
1975 11779b6c Ilias Tsitsimpis
        # `plankton' is mandatory
1976 11779b6c Ilias Tsitsimpis
        _mandatory_argument(opts.plankton, "--plankton")
1977 7f62a0b5 Vangelis Koukis
1978 11779b6c Ilias Tsitsimpis
    return (opts, args)
1979 11779b6c Ilias Tsitsimpis
1980 11779b6c Ilias Tsitsimpis
1981 11779b6c Ilias Tsitsimpis
def _mandatory_argument(Arg, Str):
1982 11779b6c Ilias Tsitsimpis
    if not Arg:
1983 8792bb97 Ilias Tsitsimpis
        print >>sys.stderr, red + \
1984 11779b6c Ilias Tsitsimpis
            "The " + Str + " argument is mandatory.\n" + \
1985 6e168615 Ilias Tsitsimpis
            normal
1986 8792bb97 Ilias Tsitsimpis
        sys.exit(1)
1987 8792bb97 Ilias Tsitsimpis
1988 5a140b23 Vangelis Koukis
1989 8792bb97 Ilias Tsitsimpis
# --------------------------------------------------------------------
1990 8792bb97 Ilias Tsitsimpis
# Burnin main function
1991 5a140b23 Vangelis Koukis
def main():
1992 5a140b23 Vangelis Koukis
    """Assemble test cases into a test suite, and run it
1993 5a140b23 Vangelis Koukis

1994 5a140b23 Vangelis Koukis
    IMPORTANT: Tests have dependencies and have to be run in the specified
1995 5a140b23 Vangelis Koukis
    order inside a single test case. They communicate through attributes of the
1996 21bbbc9b Vangelis Koukis
    corresponding TestCase class (shared fixtures). Distinct subclasses of
1997 21bbbc9b Vangelis Koukis
    TestCase MAY SHARE NO DATA, since they are run in parallel, in distinct
1998 21bbbc9b Vangelis Koukis
    test runner processes.
1999 5a140b23 Vangelis Koukis

2000 5a140b23 Vangelis Koukis
    """
2001 ae139e8a John Giannelos
2002 8792bb97 Ilias Tsitsimpis
    # Parse arguments using `optparse'
2003 5a140b23 Vangelis Koukis
    (opts, args) = parse_arguments(sys.argv[1:])
2004 5a140b23 Vangelis Koukis
2005 8792bb97 Ilias Tsitsimpis
    # Some global variables
2006 11779b6c Ilias Tsitsimpis
    global API, TOKEN, PLANKTON, PLANKTON_USER
2007 11779b6c Ilias Tsitsimpis
    global PITHOS, PITHOS_USER, NO_IPV6, VERBOSE, NOFAILFAST
2008 21bbbc9b Vangelis Koukis
    API = opts.api
2009 21bbbc9b Vangelis Koukis
    TOKEN = opts.token
2010 946da8b6 John Giannelos
    PLANKTON = opts.plankton
2011 946da8b6 John Giannelos
    PLANKTON_USER = opts.plankton_user
2012 11779b6c Ilias Tsitsimpis
    PITHOS = opts.pithos
2013 11779b6c Ilias Tsitsimpis
    PITHOS_USER = opts.pithos_user
2014 946da8b6 John Giannelos
    NO_IPV6 = opts.no_ipv6
2015 2aaa1336 John Giannelos
    VERBOSE = opts.verbose
2016 2aaa1336 John Giannelos
    NOFAILFAST = opts.nofailfast
2017 21bbbc9b Vangelis Koukis
2018 8792bb97 Ilias Tsitsimpis
    # If `show_stale', cleanup stale servers
2019 8792bb97 Ilias Tsitsimpis
    # from previous runs and exit
2020 5a140b23 Vangelis Koukis
    if opts.show_stale:
2021 8792bb97 Ilias Tsitsimpis
        # We must clean the servers first
2022 8792bb97 Ilias Tsitsimpis
        cleanup_servers(opts.action_timeout, opts.query_interval,
2023 8792bb97 Ilias Tsitsimpis
                        delete_stale=opts.delete_stale)
2024 8792bb97 Ilias Tsitsimpis
        cleanup_networks(opts.action_timeout, opts.query_interval,
2025 8792bb97 Ilias Tsitsimpis
                         delete_stale=opts.delete_stale)
2026 74ec726f John Giannelos
        return 0
2027 5a140b23 Vangelis Koukis
2028 5a140b23 Vangelis Koukis
    # Initialize a kamaki instance, get flavors, images
2029 96da37c8 John Giannelos
    c = ComputeClient(API, TOKEN)
2030 5a140b23 Vangelis Koukis
    DIMAGES = c.list_images(detail=True)
2031 5a140b23 Vangelis Koukis
    DFLAVORS = c.list_flavors(detail=True)
2032 5a140b23 Vangelis Koukis
2033 21bbbc9b Vangelis Koukis
    # FIXME: logging, log, LOG PID, TEST_RUN_ID, arguments
2034 5a140b23 Vangelis Koukis
    # Run them: FIXME: In parallel, FAILEARLY, catchbreak?
2035 5a140b23 Vangelis Koukis
    #unittest.main(verbosity=2, catchbreak=True)
2036 5a140b23 Vangelis Koukis
2037 6e168615 Ilias Tsitsimpis
    # Get a list of images we are going to test
2038 e94a9d8c John Giannelos
    if opts.force_imageid == 'all':
2039 e94a9d8c John Giannelos
        test_images = DIMAGES
2040 e94a9d8c John Giannelos
    else:
2041 e94a9d8c John Giannelos
        test_images = filter(lambda x: x["id"] == opts.force_imageid, DIMAGES)
2042 e94a9d8c John Giannelos
2043 6e168615 Ilias Tsitsimpis
    # Create output (logging) folder
2044 74ec726f John Giannelos
    if not os.path.exists(opts.log_folder):
2045 74ec726f John Giannelos
        os.mkdir(opts.log_folder)
2046 2bcfb712 John Giannelos
    test_folder = os.path.join(opts.log_folder, TEST_RUN_ID)
2047 74ec726f John Giannelos
    os.mkdir(test_folder)
2048 81e8cbf6 John Giannelos
2049 00f87624 Vangelis Koukis
    for image in test_images:
2050 99d41650 John Giannelos
        imageid = str(image["id"])
2051 6e168615 Ilias Tsitsimpis
        imagename = image["name"]
2052 6e168615 Ilias Tsitsimpis
        # Choose a flavor (given from user or random)
2053 81e8cbf6 John Giannelos
        if opts.force_flavorid:
2054 81e8cbf6 John Giannelos
            flavorid = opts.force_flavorid
2055 81e8cbf6 John Giannelos
        else:
2056 81e8cbf6 John Giannelos
            flavorid = choice([f["id"] for f in DFLAVORS if f["disk"] >= 20])
2057 6e168615 Ilias Tsitsimpis
        # Personality dictionary for file injection test
2058 6e168615 Ilias Tsitsimpis
        if opts.personality_path is not None:
2059 9659e075 John Giannelos
            f = open(opts.personality_path)
2060 9659e075 John Giannelos
            content = b64encode(f.read())
2061 9659e075 John Giannelos
            personality = []
2062 9659e075 John Giannelos
            st = os.stat(opts.personality_path)
2063 9659e075 John Giannelos
            personality.append({
2064 6e168615 Ilias Tsitsimpis
                'path': '/root/test_inj_file',
2065 6e168615 Ilias Tsitsimpis
                'owner': 'root',
2066 6e168615 Ilias Tsitsimpis
                'group': 'root',
2067 6e168615 Ilias Tsitsimpis
                'mode': 0x7777 & st.st_mode,
2068 6e168615 Ilias Tsitsimpis
                'contents': content})
2069 9659e075 John Giannelos
        else:
2070 9659e075 John Giannelos
            personality = None
2071 6e168615 Ilias Tsitsimpis
        # Give a name to our test servers
2072 21bbbc9b Vangelis Koukis
        servername = "%s%s for %s" % (SNF_TEST_PREFIX, TEST_RUN_ID, imagename)
2073 21bbbc9b Vangelis Koukis
        is_windows = imagename.lower().find("windows") >= 0
2074 8252d64f John Giannelos
2075 6e168615 Ilias Tsitsimpis
        # Create Server TestCases
2076 8252d64f John Giannelos
        ServerTestCase = _spawn_server_test_case(
2077 8252d64f John Giannelos
            imageid=imageid,
2078 8252d64f John Giannelos
            flavorid=flavorid,
2079 8252d64f John Giannelos
            imagename=imagename,
2080 8252d64f John Giannelos
            personality=personality,
2081 8252d64f John Giannelos
            servername=servername,
2082 8252d64f John Giannelos
            is_windows=is_windows,
2083 8252d64f John Giannelos
            action_timeout=opts.action_timeout,
2084 8252d64f John Giannelos
            build_warning=opts.build_warning,
2085 8252d64f John Giannelos
            build_fail=opts.build_fail,
2086 6e168615 Ilias Tsitsimpis
            query_interval=opts.query_interval)
2087 6e168615 Ilias Tsitsimpis
        # Create Network TestCases
2088 8252d64f John Giannelos
        NetworkTestCase = _spawn_network_test_case(
2089 8252d64f John Giannelos
            action_timeout=opts.action_timeout,
2090 8252d64f John Giannelos
            imageid=imageid,
2091 8252d64f John Giannelos
            flavorid=flavorid,
2092 8252d64f John Giannelos
            imagename=imagename,
2093 6e168615 Ilias Tsitsimpis
            query_interval=opts.query_interval)
2094 95a87099 Ilias Tsitsimpis
        # Create Images TestCase
2095 95a87099 Ilias Tsitsimpis
        CImagesTestCase = _images_test_case(
2096 95a87099 Ilias Tsitsimpis
            action_timeout=opts.action_timeout,
2097 95a87099 Ilias Tsitsimpis
            imageid=imageid,
2098 95a87099 Ilias Tsitsimpis
            flavorid=flavorid,
2099 95a87099 Ilias Tsitsimpis
            imagename=imagename,
2100 95a87099 Ilias Tsitsimpis
            query_interval=opts.query_interval)
2101 8252d64f John Giannelos
2102 6e168615 Ilias Tsitsimpis
        # Choose the tests we are going to run
2103 746540cd John Giannelos
        test_dict = {'auth': UnauthorizedTestCase,
2104 95a87099 Ilias Tsitsimpis
                     'images': CImagesTestCase,
2105 746540cd John Giannelos
                     'flavors': FlavorsTestCase,
2106 746540cd John Giannelos
                     'servers': ServersTestCase,
2107 11779b6c Ilias Tsitsimpis
                     'pithos': PithosTestCase,
2108 746540cd John Giannelos
                     'server_spawn': ServerTestCase,
2109 746540cd John Giannelos
                     'network_spawn': NetworkTestCase}
2110 22efe1fe John Giannelos
        seq_cases = []
2111 22efe1fe John Giannelos
        if 'all' in opts.tests:
2112 11779b6c Ilias Tsitsimpis
            seq_cases = [UnauthorizedTestCase, ImagesTestCase,
2113 11779b6c Ilias Tsitsimpis
                         FlavorsTestCase, ServersTestCase,
2114 11779b6c Ilias Tsitsimpis
                         PithosTestCase, ServerTestCase,
2115 11779b6c Ilias Tsitsimpis
                         NetworkTestCase]
2116 22efe1fe John Giannelos
        else:
2117 22efe1fe John Giannelos
            for test in opts.tests:
2118 22efe1fe John Giannelos
                seq_cases.append(test_dict[test])
2119 22efe1fe John Giannelos
2120 6e168615 Ilias Tsitsimpis
        # Folder for each image
2121 2bcfb712 John Giannelos
        image_folder = os.path.join(test_folder, imageid)
2122 81e8cbf6 John Giannelos
        os.mkdir(image_folder)
2123 81e8cbf6 John Giannelos
2124 6e168615 Ilias Tsitsimpis
        # Run each test
2125 6e168615 Ilias Tsitsimpis
        if opts.fanout > 1:
2126 3e4c5c32 John Giannelos
            _run_cases_in_parallel(seq_cases, opts.fanout, image_folder)
2127 3e4c5c32 John Giannelos
        else:
2128 6e168615 Ilias Tsitsimpis
            _run_cases_in_series(seq_cases, image_folder)
2129 6e168615 Ilias Tsitsimpis
2130 746540cd John Giannelos
2131 6e168615 Ilias Tsitsimpis
# --------------------------------------------------------------------
2132 6e168615 Ilias Tsitsimpis
# Call main
2133 5a140b23 Vangelis Koukis
if __name__ == "__main__":
2134 5a140b23 Vangelis Koukis
    sys.exit(main())