Statistics
| Branch: | Tag: | Revision:

root / snf-tools / synnefo_tools / burnin / server_tests.py @ 3e5bbd85

History | View | Annotate | Download (14 kB)

1 6c78720b Ilias Tsitsimpis
# Copyright 2013 GRNET S.A. All rights reserved.
2 6c78720b Ilias Tsitsimpis
#
3 6c78720b Ilias Tsitsimpis
# Redistribution and use in source and binary forms, with or
4 6c78720b Ilias Tsitsimpis
# without modification, are permitted provided that the following
5 6c78720b Ilias Tsitsimpis
# conditions are met:
6 6c78720b Ilias Tsitsimpis
#
7 6c78720b Ilias Tsitsimpis
#   1. Redistributions of source code must retain the above
8 6c78720b Ilias Tsitsimpis
#      copyright notice, this list of conditions and the following
9 6c78720b Ilias Tsitsimpis
#      disclaimer.
10 6c78720b Ilias Tsitsimpis
#
11 6c78720b Ilias Tsitsimpis
#   2. Redistributions in binary form must reproduce the above
12 6c78720b Ilias Tsitsimpis
#      copyright notice, this list of conditions and the following
13 6c78720b Ilias Tsitsimpis
#      disclaimer in the documentation and/or other materials
14 6c78720b Ilias Tsitsimpis
#      provided with the distribution.
15 6c78720b Ilias Tsitsimpis
#
16 6c78720b Ilias Tsitsimpis
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 6c78720b Ilias Tsitsimpis
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 6c78720b Ilias Tsitsimpis
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 6c78720b Ilias Tsitsimpis
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 6c78720b Ilias Tsitsimpis
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 6c78720b Ilias Tsitsimpis
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 6c78720b Ilias Tsitsimpis
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 6c78720b Ilias Tsitsimpis
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 6c78720b Ilias Tsitsimpis
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 6c78720b Ilias Tsitsimpis
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 6c78720b Ilias Tsitsimpis
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 6c78720b Ilias Tsitsimpis
# POSSIBILITY OF SUCH DAMAGE.
28 6c78720b Ilias Tsitsimpis
#
29 6c78720b Ilias Tsitsimpis
# The views and conclusions contained in the software and
30 6c78720b Ilias Tsitsimpis
# documentation are those of the authors and should not be
31 6c78720b Ilias Tsitsimpis
# interpreted as representing official policies, either expressed
32 6c78720b Ilias Tsitsimpis
# or implied, of GRNET S.A.
33 6c78720b Ilias Tsitsimpis
34 6c78720b Ilias Tsitsimpis
"""
35 6c78720b Ilias Tsitsimpis
This is the burnin class that tests the Servers' functionality
36 6c78720b Ilias Tsitsimpis

37 6c78720b Ilias Tsitsimpis
"""
38 6c78720b Ilias Tsitsimpis
39 6c78720b Ilias Tsitsimpis
import sys
40 6c78720b Ilias Tsitsimpis
import IPy
41 cee3ee9b Ilias Tsitsimpis
import stat
42 cee3ee9b Ilias Tsitsimpis
import base64
43 6c78720b Ilias Tsitsimpis
import random
44 6c78720b Ilias Tsitsimpis
import socket
45 6c78720b Ilias Tsitsimpis
46 6c78720b Ilias Tsitsimpis
from vncauthproxy.d3des import generate_response as d3des_generate_response
47 6c78720b Ilias Tsitsimpis
48 6c78720b Ilias Tsitsimpis
from synnefo_tools.burnin.common import BurninTests, Proper, run_test
49 d246be88 Ilias Tsitsimpis
from synnefo_tools.burnin.cyclades_common import CycladesTests
50 6c78720b Ilias Tsitsimpis
51 6c78720b Ilias Tsitsimpis
52 6c78720b Ilias Tsitsimpis
# Too many public methods. pylint: disable-msg=R0904
53 6c78720b Ilias Tsitsimpis
# This class gets replicated into actual TestCases dynamically
54 d246be88 Ilias Tsitsimpis
class GeneratedServerTestSuite(CycladesTests):
55 6c78720b Ilias Tsitsimpis
    """Test Spawning Serverfunctionality"""
56 6c78720b Ilias Tsitsimpis
    use_image = Proper(value=None)
57 cee3ee9b Ilias Tsitsimpis
    personality = Proper(value=None)
58 6c78720b Ilias Tsitsimpis
    avail_flavors = Proper(value=None)
59 6c78720b Ilias Tsitsimpis
    use_flavor = Proper(value=None)
60 6c78720b Ilias Tsitsimpis
    server = Proper(value=None)
61 6c78720b Ilias Tsitsimpis
    ipv4 = Proper(value=None)
62 6c78720b Ilias Tsitsimpis
    ipv6 = Proper(value=None)
63 cee3ee9b Ilias Tsitsimpis
    username = Proper(value=None)
64 cee3ee9b Ilias Tsitsimpis
    password = Proper(value=None)
65 6c78720b Ilias Tsitsimpis
66 6c78720b Ilias Tsitsimpis
    def test_001_submit_create_server(self):
67 6c78720b Ilias Tsitsimpis
        """Submit a create server request"""
68 cee3ee9b Ilias Tsitsimpis
        if self._image_is(self.use_image, "linux"):
69 cee3ee9b Ilias Tsitsimpis
            # Enforce personality test
70 cee3ee9b Ilias Tsitsimpis
            self.info("Creating personality content to be used")
71 cee3ee9b Ilias Tsitsimpis
            self.personality = [{
72 cee3ee9b Ilias Tsitsimpis
                'path': "/root/test_inj_file",
73 cee3ee9b Ilias Tsitsimpis
                'owner': "root",
74 cee3ee9b Ilias Tsitsimpis
                'group': "root",
75 cee3ee9b Ilias Tsitsimpis
                'mode': stat.S_IRUSR | stat.S_IWUSR,
76 cee3ee9b Ilias Tsitsimpis
                'contents': base64.b64encode("This is a personality file")
77 cee3ee9b Ilias Tsitsimpis
            }]
78 6c78720b Ilias Tsitsimpis
        self.use_flavor = random.choice(self.avail_flavors)
79 6c78720b Ilias Tsitsimpis
80 6c78720b Ilias Tsitsimpis
        self.server = self._create_server(
81 3eaf0ec5 Ilias Tsitsimpis
            self.use_image, self.use_flavor, self.personality)
82 cee3ee9b Ilias Tsitsimpis
        self.username = self._get_connection_username(self.server)
83 cee3ee9b Ilias Tsitsimpis
        self.password = self.server['adminPass']
84 6c78720b Ilias Tsitsimpis
85 6c78720b Ilias Tsitsimpis
    def test_002_server_build_list(self):
86 6c78720b Ilias Tsitsimpis
        """Test server is in BUILD state, in server list"""
87 6c78720b Ilias Tsitsimpis
        servers = self._get_list_of_servers(detail=True)
88 6c78720b Ilias Tsitsimpis
        servers = [s for s in servers if s['id'] == self.server['id']]
89 6c78720b Ilias Tsitsimpis
90 6c78720b Ilias Tsitsimpis
        self.assertEqual(len(servers), 1)
91 6c78720b Ilias Tsitsimpis
        server = servers[0]
92 6c78720b Ilias Tsitsimpis
        self.assertEqual(server['name'], self.server['name'])
93 6c78720b Ilias Tsitsimpis
        self.assertEqual(server['flavor']['id'], self.use_flavor['id'])
94 6c78720b Ilias Tsitsimpis
        self.assertEqual(server['image']['id'], self.use_image['id'])
95 6c78720b Ilias Tsitsimpis
        self.assertEqual(server['status'], "BUILD")
96 6c78720b Ilias Tsitsimpis
97 6c78720b Ilias Tsitsimpis
    def test_003_server_build_details(self):
98 6c78720b Ilias Tsitsimpis
        """Test server is in BUILD state, in details"""
99 6c78720b Ilias Tsitsimpis
        server = self._get_server_details(self.server)
100 6c78720b Ilias Tsitsimpis
        self.assertEqual(server['name'], self.server['name'])
101 6c78720b Ilias Tsitsimpis
        self.assertEqual(server['flavor']['id'], self.use_flavor['id'])
102 6c78720b Ilias Tsitsimpis
        self.assertEqual(server['image']['id'], self.use_image['id'])
103 6c78720b Ilias Tsitsimpis
        self.assertEqual(server['status'], "BUILD")
104 6c78720b Ilias Tsitsimpis
105 6c78720b Ilias Tsitsimpis
    def test_004_set_server_metadata(self):
106 6c78720b Ilias Tsitsimpis
        """Test setting some of the server's metadata"""
107 6c78720b Ilias Tsitsimpis
        image = self.clients.cyclades.get_image_details(self.use_image['id'])
108 6c78720b Ilias Tsitsimpis
        os_value = image['metadata']['os']
109 6c78720b Ilias Tsitsimpis
        self.clients.cyclades.update_server_metadata(
110 6c78720b Ilias Tsitsimpis
            self.server['id'], OS=os_value)
111 6c78720b Ilias Tsitsimpis
112 6c78720b Ilias Tsitsimpis
        servermeta = \
113 6c78720b Ilias Tsitsimpis
            self.clients.cyclades.get_server_metadata(self.server['id'])
114 6c78720b Ilias Tsitsimpis
        imagemeta = \
115 6c78720b Ilias Tsitsimpis
            self.clients.cyclades.get_image_metadata(self.use_image['id'])
116 6c78720b Ilias Tsitsimpis
        self.assertEqual(servermeta['OS'], imagemeta['os'])
117 6c78720b Ilias Tsitsimpis
118 6c78720b Ilias Tsitsimpis
    def test_005_server_becomes_active(self):
119 6c78720b Ilias Tsitsimpis
        """Test server becomes ACTIVE"""
120 3eaf0ec5 Ilias Tsitsimpis
        self._insist_on_server_transition(self.server, ["BUILD"], "ACTIVE")
121 6c78720b Ilias Tsitsimpis
122 6c78720b Ilias Tsitsimpis
    def test_006_get_server_oob_console(self):
123 6c78720b Ilias Tsitsimpis
        """Test getting OOB server console over VNC
124 6c78720b Ilias Tsitsimpis

125 6c78720b Ilias Tsitsimpis
        Implementation of RFB protocol follows
126 6c78720b Ilias Tsitsimpis
        http://www.realvnc.com/docs/rfbproto.pdf.
127 6c78720b Ilias Tsitsimpis

128 6c78720b Ilias Tsitsimpis
        """
129 6c78720b Ilias Tsitsimpis
        console = self.clients.cyclades.get_server_console(self.server['id'])
130 6c78720b Ilias Tsitsimpis
        self.assertEquals(console['type'], "vnc")
131 6c78720b Ilias Tsitsimpis
        sock = self._insist_on_tcp_connection(
132 6c78720b Ilias Tsitsimpis
            socket.AF_INET, console['host'], console['port'])
133 6c78720b Ilias Tsitsimpis
134 6c78720b Ilias Tsitsimpis
        # Step 1. ProtocolVersion message (par. 6.1.1)
135 6c78720b Ilias Tsitsimpis
        version = sock.recv(1024)
136 6c78720b Ilias Tsitsimpis
        self.assertEquals(version, 'RFB 003.008\n')
137 6c78720b Ilias Tsitsimpis
        sock.send(version)
138 6c78720b Ilias Tsitsimpis
139 6c78720b Ilias Tsitsimpis
        # Step 2. Security (par 6.1.2): Only VNC Authentication supported
140 6c78720b Ilias Tsitsimpis
        sec = sock.recv(1024)
141 6c78720b Ilias Tsitsimpis
        self.assertEquals(list(sec), ['\x01', '\x02'])
142 6c78720b Ilias Tsitsimpis
143 6c78720b Ilias Tsitsimpis
        # Step 3. Request VNC Authentication (par 6.1.2)
144 6c78720b Ilias Tsitsimpis
        sock.send('\x02')
145 6c78720b Ilias Tsitsimpis
146 6c78720b Ilias Tsitsimpis
        # Step 4. Receive Challenge (par 6.2.2)
147 6c78720b Ilias Tsitsimpis
        challenge = sock.recv(1024)
148 6c78720b Ilias Tsitsimpis
        self.assertEquals(len(challenge), 16)
149 6c78720b Ilias Tsitsimpis
150 6c78720b Ilias Tsitsimpis
        # Step 5. DES-Encrypt challenge, use password as key (par 6.2.2)
151 6c78720b Ilias Tsitsimpis
        response = d3des_generate_response(
152 6c78720b Ilias Tsitsimpis
            (console["password"] + '\0' * 8)[:8], challenge)
153 6c78720b Ilias Tsitsimpis
        sock.send(response)
154 6c78720b Ilias Tsitsimpis
155 6c78720b Ilias Tsitsimpis
        # Step 6. SecurityResult (par 6.1.3)
156 6c78720b Ilias Tsitsimpis
        result = sock.recv(4)
157 6c78720b Ilias Tsitsimpis
        self.assertEquals(list(result), ['\x00', '\x00', '\x00', '\x00'])
158 6c78720b Ilias Tsitsimpis
        sock.close()
159 6c78720b Ilias Tsitsimpis
160 6c78720b Ilias Tsitsimpis
    def test_007_server_has_ipv4(self):
161 6c78720b Ilias Tsitsimpis
        """Test active server has a valid IPv4 address"""
162 6c78720b Ilias Tsitsimpis
        server = self.clients.cyclades.get_server_details(self.server['id'])
163 6c78720b Ilias Tsitsimpis
        # Update the server attribute
164 6c78720b Ilias Tsitsimpis
        self.server = server
165 6c78720b Ilias Tsitsimpis
166 cee3ee9b Ilias Tsitsimpis
        self.ipv4 = self._get_ip(server, version=4)
167 6c78720b Ilias Tsitsimpis
        self.assertEquals(IPy.IP(self.ipv4).version(), 4)
168 6c78720b Ilias Tsitsimpis
169 6c78720b Ilias Tsitsimpis
    def test_008_server_has_ipv6(self):
170 6c78720b Ilias Tsitsimpis
        """Test active server has a valid IPv6 address"""
171 6c78720b Ilias Tsitsimpis
        self._skip_if(not self.use_ipv6, "--no-ipv6 flag enabled")
172 6c78720b Ilias Tsitsimpis
173 cee3ee9b Ilias Tsitsimpis
        self.ipv6 = self._get_ip(self.server, version=6)
174 6c78720b Ilias Tsitsimpis
        self.assertEquals(IPy.IP(self.ipv6).version(), 6)
175 6c78720b Ilias Tsitsimpis
176 6c78720b Ilias Tsitsimpis
    def test_009_server_ping_ipv4(self):
177 6c78720b Ilias Tsitsimpis
        """Test server responds to ping on IPv4 address"""
178 cee3ee9b Ilias Tsitsimpis
        self._insist_on_ping(self.ipv4, version=4)
179 6c78720b Ilias Tsitsimpis
180 6c78720b Ilias Tsitsimpis
    def test_010_server_ping_ipv6(self):
181 6c78720b Ilias Tsitsimpis
        """Test server responds to ping on IPv6 address"""
182 6c78720b Ilias Tsitsimpis
        self._skip_if(not self.use_ipv6, "--no-ipv6 flag enabled")
183 cee3ee9b Ilias Tsitsimpis
        self._insist_on_ping(self.ipv6, version=6)
184 6c78720b Ilias Tsitsimpis
185 6c78720b Ilias Tsitsimpis
    def test_011_submit_shutdown(self):
186 6c78720b Ilias Tsitsimpis
        """Test submit request to shutdown server"""
187 6c78720b Ilias Tsitsimpis
        self.clients.cyclades.shutdown_server(self.server['id'])
188 6c78720b Ilias Tsitsimpis
189 6c78720b Ilias Tsitsimpis
    def test_012_server_becomes_stopped(self):
190 6c78720b Ilias Tsitsimpis
        """Test server becomes STOPPED"""
191 3eaf0ec5 Ilias Tsitsimpis
        self._insist_on_server_transition(self.server, ["ACTIVE"], "STOPPED")
192 6c78720b Ilias Tsitsimpis
193 6c78720b Ilias Tsitsimpis
    def test_013_submit_start(self):
194 6c78720b Ilias Tsitsimpis
        """Test submit start server request"""
195 6c78720b Ilias Tsitsimpis
        self.clients.cyclades.start_server(self.server['id'])
196 6c78720b Ilias Tsitsimpis
197 6c78720b Ilias Tsitsimpis
    def test_014_server_becomes_active(self):
198 6c78720b Ilias Tsitsimpis
        """Test server becomes ACTIVE again"""
199 3eaf0ec5 Ilias Tsitsimpis
        self._insist_on_server_transition(self.server, ["STOPPED"], "ACTIVE")
200 6c78720b Ilias Tsitsimpis
201 6c78720b Ilias Tsitsimpis
    def test_015_server_ping_ipv4(self):
202 6c78720b Ilias Tsitsimpis
        """Test server OS is actually up and running again"""
203 6c78720b Ilias Tsitsimpis
        self.test_009_server_ping_ipv4()
204 6c78720b Ilias Tsitsimpis
205 cee3ee9b Ilias Tsitsimpis
    def test_016_ssh_to_server_ipv4(self):
206 cee3ee9b Ilias Tsitsimpis
        """Test SSH to server public IPv4 works, verify hostname"""
207 cee3ee9b Ilias Tsitsimpis
        self._skip_if(not self._image_is(self.use_image, "linux"),
208 cee3ee9b Ilias Tsitsimpis
                      "only valid for Linux servers")
209 cee3ee9b Ilias Tsitsimpis
        hostname = self._insist_get_hostname_over_ssh(
210 cee3ee9b Ilias Tsitsimpis
            self.ipv4, self.username, self.password)
211 cee3ee9b Ilias Tsitsimpis
        # The hostname must be of the form 'prefix-id'
212 cee3ee9b Ilias Tsitsimpis
        self.assertTrue(hostname.endswith("-%d" % self.server['id']))
213 cee3ee9b Ilias Tsitsimpis
214 cee3ee9b Ilias Tsitsimpis
    def test_017_ssh_to_server_ipv6(self):
215 cee3ee9b Ilias Tsitsimpis
        """Test SSH to server public IPv6 works, verify hostname"""
216 cee3ee9b Ilias Tsitsimpis
        self._skip_if(not self._image_is(self.use_image, "linux"),
217 cee3ee9b Ilias Tsitsimpis
                      "only valid for Linux servers")
218 cee3ee9b Ilias Tsitsimpis
        self._skip_if(not self.use_ipv6, "--no-ipv6 flag enabled")
219 cee3ee9b Ilias Tsitsimpis
        hostname = self._insist_get_hostname_over_ssh(
220 cee3ee9b Ilias Tsitsimpis
            self.ipv6, self.username, self.password)
221 cee3ee9b Ilias Tsitsimpis
        # The hostname must be of the form 'prefix-id'
222 cee3ee9b Ilias Tsitsimpis
        self.assertTrue(hostname.endswith("-%d" % self.server['id']))
223 cee3ee9b Ilias Tsitsimpis
224 cee3ee9b Ilias Tsitsimpis
    def test_018_rdp_to_server_ipv4(self):
225 cee3ee9b Ilias Tsitsimpis
        """Test RDP connection to server public IPv4 works"""
226 cee3ee9b Ilias Tsitsimpis
        self._skip_if(not self._image_is(self.use_image, "windows"),
227 cee3ee9b Ilias Tsitsimpis
                      "only valid for Windows servers")
228 cee3ee9b Ilias Tsitsimpis
        sock = self._insist_on_tcp_connection(socket.AF_INET, self.ipv4, 3389)
229 cee3ee9b Ilias Tsitsimpis
        # No actual RDP processing done. We assume the RDP server is there
230 cee3ee9b Ilias Tsitsimpis
        # if the connection to the RDP port is successful.
231 cee3ee9b Ilias Tsitsimpis
        # pylint: disable-msg=W0511
232 cee3ee9b Ilias Tsitsimpis
        # FIXME: Use rdesktop, analyze exit code? see manpage
233 cee3ee9b Ilias Tsitsimpis
        sock.close()
234 cee3ee9b Ilias Tsitsimpis
235 cee3ee9b Ilias Tsitsimpis
    def test_019_rdp_to_server_ipv6(self):
236 cee3ee9b Ilias Tsitsimpis
        """Test RDP connection to server public IPv6 works"""
237 cee3ee9b Ilias Tsitsimpis
        self._skip_if(not self._image_is(self.use_image, "windows"),
238 cee3ee9b Ilias Tsitsimpis
                      "only valid for Windows servers")
239 cee3ee9b Ilias Tsitsimpis
        self._skip_if(not self.use_ipv6, "--no-ipv6 flag enabled")
240 cee3ee9b Ilias Tsitsimpis
        sock = self._insist_on_tcp_connection(socket.AF_INET, self.ipv6, 3389)
241 cee3ee9b Ilias Tsitsimpis
        # No actual RDP processing done. We assume the RDP server is there
242 cee3ee9b Ilias Tsitsimpis
        # if the connection to the RDP port is successful.
243 cee3ee9b Ilias Tsitsimpis
        # pylint: disable-msg=W0511
244 cee3ee9b Ilias Tsitsimpis
        # FIXME: Use rdesktop, analyze exit code? see manpage
245 cee3ee9b Ilias Tsitsimpis
        sock.close()
246 cee3ee9b Ilias Tsitsimpis
247 cee3ee9b Ilias Tsitsimpis
    def test_020_personality(self):
248 cee3ee9b Ilias Tsitsimpis
        """Test file injection for personality enforcement"""
249 cee3ee9b Ilias Tsitsimpis
        self._skip_if(not self._image_is(self.use_image, "linux"),
250 cee3ee9b Ilias Tsitsimpis
                      "only implemented for linux servers")
251 cee3ee9b Ilias Tsitsimpis
        assert self.personality is not None, "No personality used"
252 cee3ee9b Ilias Tsitsimpis
253 cee3ee9b Ilias Tsitsimpis
        for inj_file in self.personality:
254 cee3ee9b Ilias Tsitsimpis
            self._check_file_through_ssh(
255 cee3ee9b Ilias Tsitsimpis
                self.ipv4, inj_file['owner'], self.password,
256 cee3ee9b Ilias Tsitsimpis
                inj_file['path'], inj_file['contents'])
257 cee3ee9b Ilias Tsitsimpis
258 cee3ee9b Ilias Tsitsimpis
    def test_021_submit_delete_request(self):
259 cee3ee9b Ilias Tsitsimpis
        """Test submit request to delete server"""
260 cee3ee9b Ilias Tsitsimpis
        self.clients.cyclades.delete_server(self.server['id'])
261 cee3ee9b Ilias Tsitsimpis
262 cee3ee9b Ilias Tsitsimpis
    def test_022_server_becomes_deleted(self):
263 cee3ee9b Ilias Tsitsimpis
        """Test server becomes DELETED"""
264 3eaf0ec5 Ilias Tsitsimpis
        self._insist_on_server_transition(self.server, ["ACTIVE"], "DELETED")
265 3e5bbd85 Ilias Tsitsimpis
        # Verify quotas
266 3e5bbd85 Ilias Tsitsimpis
        self._verify_quotas_deleted([self.use_flavor])
267 cee3ee9b Ilias Tsitsimpis
268 cee3ee9b Ilias Tsitsimpis
    def test_023_server_no_longer(self):
269 cee3ee9b Ilias Tsitsimpis
        """Test server is no longer in server list"""
270 cee3ee9b Ilias Tsitsimpis
        servers = self._get_list_of_servers()
271 cee3ee9b Ilias Tsitsimpis
        self.assertNotIn(self.server['id'], [s['id'] for s in servers])
272 cee3ee9b Ilias Tsitsimpis
273 6c78720b Ilias Tsitsimpis
274 6c78720b Ilias Tsitsimpis
# --------------------------------------------------------------------
275 6c78720b Ilias Tsitsimpis
# The actuall test class. We use this class to dynamically create
276 6c78720b Ilias Tsitsimpis
# tests from the GeneratedServerTestSuite class. Each of these classes
277 6c78720b Ilias Tsitsimpis
# will run the same tests using different images and or flavors.
278 6c78720b Ilias Tsitsimpis
# The creation and running of our GeneratedServerTestSuite class will
279 6c78720b Ilias Tsitsimpis
# happen as a testsuite itself (everything here is a test!).
280 6c78720b Ilias Tsitsimpis
class ServerTestSuite(BurninTests):
281 6c78720b Ilias Tsitsimpis
    """Generate and run the GeneratedServerTestSuite
282 6c78720b Ilias Tsitsimpis

283 6c78720b Ilias Tsitsimpis
    We will generate as many testsuites as the number of images given.
284 6c78720b Ilias Tsitsimpis
    Each of these testsuites will use the given flavors at will (random).
285 6c78720b Ilias Tsitsimpis

286 6c78720b Ilias Tsitsimpis
    """
287 6c78720b Ilias Tsitsimpis
    avail_images = Proper(value=None)
288 6c78720b Ilias Tsitsimpis
    avail_flavors = Proper(value=None)
289 6c78720b Ilias Tsitsimpis
    gen_classes = Proper(value=None)
290 6c78720b Ilias Tsitsimpis
291 6c78720b Ilias Tsitsimpis
    def test_001_images_to_use(self):
292 6c78720b Ilias Tsitsimpis
        """Find images to be used by GeneratedServerTestSuite"""
293 6c78720b Ilias Tsitsimpis
        if self.images is None:
294 6c78720b Ilias Tsitsimpis
            self.info("No --images given. Will use the default %s",
295 6c78720b Ilias Tsitsimpis
                      "^Debian Base$")
296 6c78720b Ilias Tsitsimpis
            filters = ["name:^Debian Base$"]
297 6c78720b Ilias Tsitsimpis
        else:
298 6c78720b Ilias Tsitsimpis
            filters = self.images
299 6c78720b Ilias Tsitsimpis
300 6c78720b Ilias Tsitsimpis
        self.avail_images = self._find_images(filters)
301 6c78720b Ilias Tsitsimpis
        self.info("Found %s images. Let's create an equal number of tests",
302 6c78720b Ilias Tsitsimpis
                  len(self.avail_images))
303 6c78720b Ilias Tsitsimpis
304 6c78720b Ilias Tsitsimpis
    def test_002_flavors_to_use(self):
305 6c78720b Ilias Tsitsimpis
        """Find flavors to be used by GeneratedServerTestSuite"""
306 6c78720b Ilias Tsitsimpis
        flavors = self._get_list_of_flavors(detail=True)
307 6c78720b Ilias Tsitsimpis
308 6c78720b Ilias Tsitsimpis
        if self.flavors is None:
309 6c78720b Ilias Tsitsimpis
            self.info("No --flavors given. Will use all of them")
310 6c78720b Ilias Tsitsimpis
            self.avail_flavors = flavors
311 6c78720b Ilias Tsitsimpis
        else:
312 6c78720b Ilias Tsitsimpis
            self.avail_flavors = self._find_flavors(
313 3eaf0ec5 Ilias Tsitsimpis
                self.flavors, flavors=flavors)
314 6c78720b Ilias Tsitsimpis
        self.info("Found %s flavors to choose from", len(self.avail_flavors))
315 6c78720b Ilias Tsitsimpis
316 6c78720b Ilias Tsitsimpis
    def test_003_create_testsuites(self):
317 6c78720b Ilias Tsitsimpis
        """Generate the GeneratedServerTestSuite tests"""
318 6c78720b Ilias Tsitsimpis
        gen_classes = []
319 6c78720b Ilias Tsitsimpis
        for img in self.avail_images:
320 6c78720b Ilias Tsitsimpis
            name = (str("GeneratedServerTestSuite_(%s)" %
321 6c78720b Ilias Tsitsimpis
                    img['name']).replace(" ", "_"))
322 6c78720b Ilias Tsitsimpis
            self.info("Constructing class %s", name)
323 6c78720b Ilias Tsitsimpis
            class_dict = {
324 6c78720b Ilias Tsitsimpis
                'use_image': Proper(value=img),
325 6c78720b Ilias Tsitsimpis
                'avail_flavors': Proper(value=self.avail_flavors)
326 6c78720b Ilias Tsitsimpis
            }
327 6c78720b Ilias Tsitsimpis
            cls = type(name, (GeneratedServerTestSuite,), class_dict)
328 6c78720b Ilias Tsitsimpis
            # Make sure the class can be pickled, by listing it among
329 6c78720b Ilias Tsitsimpis
            # the attributes of __main__. A PicklingError is raised otherwise.
330 6c78720b Ilias Tsitsimpis
            thismodule = sys.modules[__name__]
331 6c78720b Ilias Tsitsimpis
            setattr(thismodule, name, cls)
332 6c78720b Ilias Tsitsimpis
            # Append the generated class
333 6c78720b Ilias Tsitsimpis
            gen_classes.append(cls)
334 6c78720b Ilias Tsitsimpis
335 6c78720b Ilias Tsitsimpis
        self.gen_classes = gen_classes
336 6c78720b Ilias Tsitsimpis
337 6c78720b Ilias Tsitsimpis
    def test_004_run_testsuites(self):
338 6c78720b Ilias Tsitsimpis
        """Run the generated tests"""
339 6c78720b Ilias Tsitsimpis
        for gen_cls in self.gen_classes:
340 6c78720b Ilias Tsitsimpis
            self.info("Running testsuite %s", gen_cls.__name__)
341 6c78720b Ilias Tsitsimpis
            run_test(gen_cls)