Statistics
| Branch: | Tag: | Revision:

root / kamaki / clients / tests / cyclades.py @ db77d79e

History | View | Annotate | Download (17 kB)

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

    
34
import time
35

    
36
from kamaki.clients import tests, ClientError
37
from kamaki.clients.cyclades import CycladesClient
38

    
39

    
40
class Cyclades(tests.Generic):
41
    """Set up a Cyclades thorough test"""
42
    def setUp(self):
43
        print
44
        with open(self['image', 'details']) as f:
45
            self.img_details = eval(f.read())
46
        self.img = self.img_details['id']
47
        with open(self['flavor', 'details']) as f:
48
            self._flavor_details = eval(f.read())
49
        self.PROFILES = ('ENABLED', 'DISABLED', 'PROTECTED')
50

    
51
        self.servers = {}
52
        self.now = time.mktime(time.gmtime())
53
        self.servname1 = 'serv' + unicode(self.now)
54
        self.servname2 = self.servname1 + '_v2'
55
        self.servname1 += '_v1'
56
        self.flavorid = 1
57
        #servers have to be created at the begining...
58
        self.networks = {}
59
        self.netname1 = 'net' + unicode(self.now)
60
        self.netname2 = 'net' + unicode(self.now) + '_v2'
61

    
62
        self.client = CycladesClient(self['compute', 'url'], self['token'])
63

    
64
    def tearDown(self):
65
        """Destoy servers used in testing"""
66
        self.do_with_progress_bar(
67
            self._delete_network,
68
            'Delete %s networks' % len(self.networks),
69
            self.networks.keys())
70
        for server in self.servers.values():
71
            self._delete_server(server['id'])
72
            print('DEL VM %s (%s)' % (server['id'], server['name']))
73

    
74
    def test_000(self):
75
        "Prepare a full Cyclades test scenario"
76
        self.server1 = self._create_server(self.servname1,
77
            self.flavorid,
78
            self.img)
79
        self.server2 = self._create_server(self.servname2,
80
            self.flavorid + 2,
81
            self.img)
82
        super(self.__class__, self).test_000()
83

    
84
    def _create_server(self, servername, flavorid, imageid, personality=None):
85
        server = self.client.create_server(servername,
86
            flavorid,
87
            imageid,
88
            personality)
89
        print('CREATE VM %s (%s)' % (server['id'], server['name']))
90
        self.servers[servername] = server
91
        return server
92

    
93
    def _delete_server(self, servid):
94
        try:
95
            current_state = self.client.get_server_details(servid)
96
            current_state = current_state['status']
97
            if current_state == 'DELETED':
98
                return
99
            self.client.delete_server(servid)
100
            self._wait_for_status(servid, current_state)
101
            self.client.delete_server(servid)
102
        except:
103
            return
104

    
105
    def _create_network(self, netname, **kwargs):
106
        net = self.client.create_network(netname, **kwargs)
107
        self.networks[net['id']] = net
108
        return net
109

    
110
    def _delete_network(self, netid):
111
        print('Disconnect nics of network %s' % netid)
112
        self.client.disconnect_network_nics(netid)
113

    
114
        def netwait(self, wait):
115
            try:
116
                self.client.delete_network(netid)
117
            except ClientError:
118
                time.sleep(wait)
119
        self.do_with_progress_bar(
120
            netwait,
121
            'Delete network %s' % netid,
122
            self._waits[:5])
123

    
124
    def _wait_for_network(self, netid, status):
125

    
126
        def netwait(self, wait):
127
            r = self.client.get_network_details(netid)
128
            if r['status'] == status:
129
                return
130
            time.sleep(wait)
131
        self.do_with_progress_bar(
132
            netwait,
133
            'Wait network %s to reach status %s' % (netid, status),
134
            self._waits[:5])
135

    
136
    def _wait_for_nic(self, netid, servid, in_creation=True):
137
        self._wait_for_network(netid, 'ACTIVE')
138

    
139
        def nicwait(self, wait):
140
            nics = self.client.list_server_nics(servid)
141
            for net in nics:
142
                found_nic = net['network_id'] == netid
143
                if (in_creation and found_nic)\
144
                or not (in_creation or found_nic):
145
                    return
146
            time.sleep(wait)
147
        self.do_with_progress_bar(
148
            nicwait,
149
            'Wait nic-%s-%s to %sconnect' % (
150
                netid,
151
                servid,
152
                '' if in_creation else 'dis'),
153
            self._waits[:5])
154

    
155
    def _has_status(self, servid, status):
156
        r = self.client.get_server_details(servid)
157
        return r['status'] == status
158

    
159
    def _wait_for_status(self, servid, status):
160
        (wait_bar, wait_cb) = self._safe_progress_bar(
161
            'Server %s in %s' % (servid, status))
162
        self.client.wait_server(servid, status, wait_cb=wait_cb)
163
        self._safe_progress_bar_finish(wait_bar)
164

    
165
    def test_parallel_creation(self):
166
        """test create with multiple threads
167
        Do not use this in regular tests
168
        """
169
        from kamaki.clients import SilentEvent
170
        c1 = SilentEvent(self._create_server,
171
            self.servname1,
172
            self.flavorid,
173
            self.img)
174
        c2 = SilentEvent(self._create_server,
175
            self.servname2,
176
            self.flavorid + 2,
177
            self.img)
178
        c3 = SilentEvent(self._create_server,
179
            self.servname1,
180
            self.flavorid,
181
            self.img)
182
        c4 = SilentEvent(self._create_server,
183
            self.servname2,
184
            self.flavorid + 2,
185
            self.img)
186
        c5 = SilentEvent(self._create_server,
187
            self.servname1,
188
            self.flavorid,
189
            self.img)
190
        c6 = SilentEvent(self._create_server,
191
            self.servname2,
192
            self.flavorid + 2,
193
            self.img)
194
        c7 = SilentEvent(self._create_server,
195
            self.servname1,
196
            self.flavorid,
197
            self.img)
198
        c8 = SilentEvent(self._create_server,
199
            self.servname2,
200
            self.flavorid + 2,
201
            self.img)
202
        c1.start()
203
        c2.start()
204
        c3.start()
205
        c4.start()
206
        c5.start()
207
        c6.start()
208
        c7.start()
209
        c8.start()
210

    
211
    def test_create_server(self):
212
        """Test create_server"""
213
        self.server1 = self._create_server(self.servname1,
214
            self.flavorid,
215
            self.img)
216
        self._wait_for_status(self.server1['id'], 'BUILD')
217
        self._test_0010_create_server()
218

    
219
    def _test_0010_create_server(self):
220
        self.assertEqual(self.server1["name"], self.servname1)
221
        self.assertEqual(self.server1["flavorRef"], self.flavorid)
222
        self.assertEqual(self.server1["imageRef"], self.img)
223
        self.assertEqual(self.server1["status"], "BUILD")
224

    
225
    def test_list_servers(self):
226
        """Test list servers"""
227
        self.server1 = self._create_server(
228
            self.servname1,
229
            self.flavorid,
230
            self.img)
231
        self.server2 = self._create_server(
232
            self.servname2,
233
            self.flavorid + 2,
234
            self.img)
235
        self._test_0020_list_servers()
236

    
237
    def _test_0020_list_servers(self):
238
        servers = self.client.list_servers()
239
        dservers = self.client.list_servers(detail=True)
240

    
241
        """detailed and simple are same size"""
242
        self.assertEqual(len(dservers), len(servers))
243
        for i in range(len(servers)):
244
            for field in (
245
                'created',
246
                'flavorRef',
247
                'hostId',
248
                'imageRef',
249
                'progress',
250
                'status',
251
                'updated'):
252
                self.assertFalse(field in servers[i])
253
                self.assertTrue(field in dservers[i])
254

    
255
        """detailed and simple contain same names"""
256
        names = sorted(map(lambda x: x["name"], servers))
257
        dnames = sorted(map(lambda x: x["name"], dservers))
258
        self.assertEqual(names, dnames)
259

    
260
    def _test_0030_wait_test_servers_to_build(self):
261
        """Pseudo-test to wait for VMs to load"""
262
        from sys import stdout
263
        stdout.write('')
264
        stdout.flush()
265
        self._wait_for_status(self.server1['id'], 'BUILD')
266
        self._wait_for_status(self.server2['id'], 'BUILD')
267

    
268
    def test_get_server_details(self):
269
        """Test get_server_details"""
270
        self.server1 = self._create_server(self.servname1,
271
            self.flavorid,
272
            self.img)
273
        self._wait_for_status(self.server1['id'], 'BUILD')
274
        self._test_0040_get_server_details()
275

    
276
    def _test_0040_get_server_details(self):
277
        r = self.client.get_server_details(self.server1['id'])
278
        self.assertEqual(r["name"], self.servname1)
279
        self.assertEqual(r["flavorRef"], self.flavorid)
280
        self.assertEqual(r["imageRef"], self.img)
281
        self.assertEqual(r["status"], "ACTIVE")
282

    
283
    def test_update_server_name(self):
284
        """Test update_server_name"""
285
        self.server1 = self._create_server(self.servname1,
286
            self.flavorid,
287
            self.img)
288
        self._test_0050_update_server_name()
289

    
290
    def _test_0050_update_server_name(self):
291
        new_name = self.servname1 + '_new_name'
292
        self.client.update_server_name(self.server1['id'], new_name)
293
        r = self.client.get_server_details(self.server1['id'],
294
         success=(200, 400))
295
        self.assertEqual(r['name'], new_name)
296
        changed = self.servers.pop(self.servname1)
297
        changed['name'] = new_name
298
        self.servers[new_name] = changed
299

    
300
    def test_reboot_server(self):
301
        """Test reboot server"""
302
        self.server1 = self._create_server(self.servname1,
303
            self.flavorid,
304
            self.img)
305
        self._wait_for_status(self.server1['id'], 'BUILD')
306
        self.server2 = self._create_server(self.servname2,
307
            self.flavorid + 1,
308
            self.img)
309
        self._wait_for_status(self.server2['id'], 'BUILD')
310
        self._test_0060_reboot_server()
311
        self._wait_for_status(self.server1['id'], 'REBOOT')
312
        self._wait_for_status(self.server2['id'], 'REBOOT')
313

    
314
    def _test_0060_reboot_server(self):
315
        self.client.reboot_server(self.server1['id'])
316
        self.assertTrue(self._has_status(self.server1['id'], 'REBOOT'))
317
        self.client.reboot_server(self.server2['id'], hard=True)
318
        self.assertTrue(self._has_status(self.server2['id'], 'REBOOT'))
319

    
320
    def _test_0070_wait_test_servers_to_reboot(self):
321
        """Pseudo-test to wait for VMs to load"""
322
        from sys import stdout
323
        stdout.write('')
324
        stdout.flush()
325
        self._wait_for_status(self.server1['id'], 'REBOOT')
326
        self._wait_for_status(self.server2['id'], 'REBOOT')
327

    
328
    def test_create_server_metadata(self):
329
        """Test create_server_metadata"""
330
        self.server1 = self._create_server(self.servname1,
331
            self.flavorid,
332
            self.img)
333
        self._test_0080_create_server_metadata()
334

    
335
    def _test_0080_create_server_metadata(self):
336
        r1 = self.client.create_server_metadata(self.server1['id'],
337
            'mymeta',
338
            'mymeta val')
339
        self.assertTrue('mymeta' in r1)
340
        r2 = self.client.get_server_metadata(self.server1['id'], 'mymeta')
341
        self.assert_dicts_are_deeply_equal(r1, r2)
342

    
343
    def test_get_server_metadata(self):
344
        """Test get server_metadata"""
345
        self.server1 = self._create_server(self.servname1,
346
            self.flavorid,
347
            self.img)
348
        self._test_0090_get_server_metadata()
349

    
350
    def _test_0090_get_server_metadata(self):
351
        self.client.create_server_metadata(self.server1['id'],
352
            'mymeta_0',
353
            'val_0')
354
        r = self.client.get_server_metadata(self.server1['id'], 'mymeta_0')
355
        self.assertEqual(r['mymeta_0'], 'val_0')
356

    
357
    def test_update_server_metadata(self):
358
        """Test update_server_metadata"""
359
        self.server1 = self._create_server(self.servname1,
360
            self.flavorid,
361
            self.img)
362
        self._test_0100_update_server_metadata()
363

    
364
    def _test_0100_update_server_metadata(self):
365
        r1 = self.client.create_server_metadata(self.server1['id'],
366
            'mymeta3',
367
            'val2')
368
        self.assertTrue('mymeta3'in r1)
369
        r2 = self.client.update_server_metadata(self.server1['id'],
370
            mymeta3='val3')
371
        self.assertTrue(r2['mymeta3'], 'val3')
372

    
373
    def test_delete_server_metadata(self):
374
        """Test delete_server_metadata"""
375
        self.server1 = self._create_server(self.servname1,
376
            self.flavorid,
377
            self.img)
378
        self._test_0110_delete_server_metadata()
379

    
380
    def _test_0110_delete_server_metadata(self):
381
        r1 = self.client.create_server_metadata(self.server1['id'],
382
            'mymeta',
383
            'val')
384
        self.assertTrue('mymeta' in r1)
385
        self.client.delete_server_metadata(self.server1['id'], 'mymeta')
386
        try:
387
            self.client.get_server_metadata(self.server1['id'], 'mymeta')
388
            raise ClientError('Wrong Error', status=100)
389
        except ClientError as err:
390
            self.assertEqual(err.status, 404)
391

    
392
    def test_list_flavors(self):
393
        """Test flavors_get"""
394
        self._test_0120_list_flavors()
395

    
396
    def _test_0120_list_flavors(self):
397
        r = self.client.list_flavors()
398
        self.assertTrue(len(r) > 1)
399
        r = self.client.list_flavors(detail=True)
400
        self.assertTrue('SNF:disk_template' in r[0])
401

    
402
    def test_get_flavor_details(self):
403
        """Test test_get_flavor_details"""
404
        self._test_0130_get_flavor_details()
405

    
406
    def _test_0130_get_flavor_details(self):
407
        r = self.client.get_flavor_details(self.flavorid)
408
        self.assert_dicts_are_deeply_equal(self._flavor_details, r)
409

    
410
    def test_list_images(self):
411
        """Test list_images"""
412
        self._test_0140_list_images()
413

    
414
    def _test_0140_list_images(self):
415
        r = self.client.list_images()
416
        self.assertTrue(len(r) > 1)
417
        r = self.client.list_images(detail=True)
418
        for detailed_img in r:
419
            if detailed_img['id'] == self.img:
420
                break
421
        self.assert_dicts_are_deeply_equal(detailed_img, self.img_details)
422

    
423
    def test_get_image_details(self):
424
        """Test image_details"""
425
        self._test_0150_get_image_details()
426

    
427
    def _test_0150_get_image_details(self):
428
        r = self.client.get_image_details(self.img)
429
        r.pop('updated')
430
        self.assert_dicts_are_deeply_equal(r, self.img_details)
431

    
432
    def test_get_image_metadata(self):
433
        """Test get_image_metadata"""
434
        self._test_0160_get_image_metadata()
435

    
436
    def _test_0160_get_image_metadata(self):
437
        r = self.client.get_image_metadata(self.img)
438
        self.assert_dicts_are_deeply_equal(
439
            self.img_details['metadata']['values'], r)
440
        for key, val in self.img_details['metadata']['values'].items():
441
            r = self.client.get_image_metadata(self.img, key)
442
            self.assertEqual(r[key], val)
443

    
444
    def test_shutdown_server(self):
445
        """Test shutdown_server"""
446
        self.server1 = self._create_server(self.servname1,
447
            self.flavorid,
448
            self.img)
449
        self._wait_for_status(self.server1['id'], 'BUILD')
450
        self._test_0170_shutdown_server()
451

    
452
    def _test_0170_shutdown_server(self):
453
        self.client.shutdown_server(self.server1['id'])
454
        self._wait_for_status(self.server1['id'], 'ACTIVE')
455
        r = self.client.get_server_details(self.server1['id'])
456
        self.assertEqual(r['status'], 'STOPPED')
457

    
458
    def test_start_server(self):
459
        """Test start_server"""
460
        self.server1 = self._create_server(self.servname1,
461
            self.flavorid,
462
            self.img)
463
        self._wait_for_status(self.server1['id'], 'BUILD')
464
        self.client.shutdown_server(self.server1['id'])
465
        self._wait_for_status(self.server1['id'], 'ACTIVE')
466
        self._test_0180_start_server()
467

    
468
    def _test_0180_start_server(self):
469
        self.client.start_server(self.server1['id'])
470
        self._wait_for_status(self.server1['id'], 'STOPPED')
471
        r = self.client.get_server_details(self.server1['id'])
472
        self.assertEqual(r['status'], 'ACTIVE')