~ubuntu-branches/ubuntu/saucy/heat/saucy

« back to all changes in this revision

Viewing changes to heat/tests/test_server.py

  • Committer: Package Import Robot
  • Author(s): Chuck Short, Chuck Short, Adam Gandelman
  • Date: 2013-09-08 21:51:19 UTC
  • mfrom: (1.1.4)
  • Revision ID: package-import@ubuntu.com-20130908215119-r939tu4aumqgdrkx
Tags: 2013.2~b3-0ubuntu1
[ Chuck Short ]
* New upstream release.
* debian/control: Add python-netaddr as build-dep.
* debian/heat-common.install: Remove heat-boto and associated man-page
* debian/heat-common.install: Remove heat-cfn and associated man-page
* debian/heat-common.install: Remove heat-watch and associated man-page
* debian/patches/fix-sqlalchemy-0.8.patch: Dropped

[ Adam Gandelman ]
* debian/patches/default-kombu.patch: Dropped.
* debian/patches/default-sqlite.patch: Refreshed.
* debian/*.install, rules: Install heat.conf.sample as common
  config file in heat-common. Drop other per-package configs, they
  are no longer used.
* debian/rules: Clean pbr .egg from build dir if it exists.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# vim: tabstop=4 shiftwidth=4 softtabstop=4
 
2
 
 
3
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
 
4
#    not use this file except in compliance with the License. You may obtain
 
5
#    a copy of the License at
 
6
#
 
7
#         http://www.apache.org/licenses/LICENSE-2.0
 
8
#
 
9
#    Unless required by applicable law or agreed to in writing, software
 
10
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 
11
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 
12
#    License for the specific language governing permissions and limitations
 
13
#    under the License.
 
14
 
 
15
import copy
 
16
 
 
17
import mox
 
18
 
 
19
from heat.engine import environment
 
20
from heat.tests.v1_1 import fakes
 
21
from heat.common import exception
 
22
from heat.common import template_format
 
23
from heat.engine import parser
 
24
from heat.engine import resource
 
25
from heat.engine import scheduler
 
26
from heat.engine.resources import server as servers
 
27
from heat.openstack.common import uuidutils
 
28
from heat.tests.common import HeatTestCase
 
29
from heat.tests import utils
 
30
 
 
31
 
 
32
wp_template = '''
 
33
{
 
34
  "AWSTemplateFormatVersion" : "2010-09-09",
 
35
  "Description" : "WordPress",
 
36
  "Parameters" : {
 
37
    "key_name" : {
 
38
      "Description" : "key_name",
 
39
      "Type" : "String",
 
40
      "Default" : "test"
 
41
    }
 
42
  },
 
43
  "Resources" : {
 
44
    "WebServer": {
 
45
      "Type": "OS::Nova::Server",
 
46
      "Properties": {
 
47
        "image" : "F17-x86_64-gold",
 
48
        "flavor"   : "m1.large",
 
49
        "key_name"        : "test",
 
50
        "user_data"       : "wordpress"
 
51
      }
 
52
    }
 
53
  }
 
54
}
 
55
'''
 
56
 
 
57
 
 
58
class ServersTest(HeatTestCase):
 
59
    def setUp(self):
 
60
        super(ServersTest, self).setUp()
 
61
        self.fc = fakes.FakeClient()
 
62
        utils.setup_dummy_db()
 
63
 
 
64
    def _setup_test_stack(self, stack_name):
 
65
        t = template_format.parse(wp_template)
 
66
        template = parser.Template(t)
 
67
        stack = parser.Stack(utils.dummy_context(), stack_name, template,
 
68
                             environment.Environment({'key_name': 'test'}),
 
69
                             stack_id=uuidutils.generate_uuid())
 
70
        return (t, stack)
 
71
 
 
72
    def _setup_test_server(self, return_server, name, image_id=None):
 
73
        stack_name = '%s_stack' % name
 
74
        (t, stack) = self._setup_test_stack(stack_name)
 
75
 
 
76
        t['Resources']['WebServer']['Properties']['image'] = \
 
77
            image_id or 'CentOS 5.2'
 
78
        t['Resources']['WebServer']['Properties']['flavor'] = \
 
79
            '256 MB Server'
 
80
        server = servers.Server('%s_name' % name,
 
81
                                t['Resources']['WebServer'], stack)
 
82
 
 
83
        self.m.StubOutWithMock(server, 'nova')
 
84
        server.nova().MultipleTimes().AndReturn(self.fc)
 
85
 
 
86
        server.t = server.stack.resolve_runtime_data(server.t)
 
87
 
 
88
        # need to resolve the template functions
 
89
        #server_userdata = nova_utils.build_userdata(
 
90
        #    server,
 
91
        #    server.t['Properties']['user_data'])
 
92
        #server.mime_string = server_userdata
 
93
        self.m.StubOutWithMock(self.fc.servers, 'create')
 
94
        self.fc.servers.create(
 
95
            image=1, flavor=1, key_name='test',
 
96
            name=utils.PhysName(stack_name, server.name),
 
97
            security_groups=None,
 
98
            userdata=mox.IgnoreArg(), scheduler_hints=None,
 
99
            meta=None, nics=None, availability_zone=None,
 
100
            block_device_mapping=None, config_drive=None,
 
101
            disk_config=None, reservation_id=None).AndReturn(
 
102
                return_server)
 
103
 
 
104
        return server
 
105
 
 
106
    def _create_test_server(self, return_server, name):
 
107
        server = self._setup_test_server(return_server, name)
 
108
        self.m.ReplayAll()
 
109
        scheduler.TaskRunner(server.create)()
 
110
        return server
 
111
 
 
112
    def test_server_create(self):
 
113
        return_server = self.fc.servers.list()[1]
 
114
        server = self._create_test_server(return_server,
 
115
                                          'test_server_create')
 
116
        # this makes sure the auto increment worked on server creation
 
117
        self.assertTrue(server.id > 0)
 
118
 
 
119
        public_ip = return_server.networks['public'][0]
 
120
        self.assertEqual(
 
121
            server.FnGetAtt('addresses')['public'][0]['addr'], public_ip)
 
122
        self.assertEqual(
 
123
            server.FnGetAtt('networks')['public'][0], public_ip)
 
124
        self.assertEqual(
 
125
            server.FnGetAtt('first_public_address'), public_ip)
 
126
 
 
127
        private_ip = return_server.networks['private'][0]
 
128
        self.assertEqual(
 
129
            server.FnGetAtt('addresses')['private'][0]['addr'], private_ip)
 
130
        self.assertEqual(
 
131
            server.FnGetAtt('networks')['private'][0], private_ip)
 
132
        self.assertEqual(
 
133
            server.FnGetAtt('first_private_address'), private_ip)
 
134
 
 
135
        self.assertEqual(return_server._info, server.FnGetAtt('show'))
 
136
        self.assertEqual('sample-server2', server.FnGetAtt('instance_name'))
 
137
        self.assertEqual('192.0.2.0', server.FnGetAtt('accessIPv4'))
 
138
        self.assertEqual('::babe:4317:0A83', server.FnGetAtt('accessIPv6'))
 
139
        self.m.VerifyAll()
 
140
 
 
141
    def test_server_create_with_image_id(self):
 
142
        return_server = self.fc.servers.list()[1]
 
143
        server = self._setup_test_server(return_server,
 
144
                                         'test_server_create_image_id',
 
145
                                         image_id='1')
 
146
        self.m.StubOutWithMock(uuidutils, "is_uuid_like")
 
147
        uuidutils.is_uuid_like('1').AndReturn(True)
 
148
 
 
149
        self.m.ReplayAll()
 
150
        scheduler.TaskRunner(server.create)()
 
151
 
 
152
        # this makes sure the auto increment worked on server creation
 
153
        self.assertTrue(server.id > 0)
 
154
 
 
155
        public_ip = return_server.networks['public'][0]
 
156
        self.assertEqual(
 
157
            server.FnGetAtt('addresses')['public'][0]['addr'], public_ip)
 
158
        self.assertEqual(
 
159
            server.FnGetAtt('networks')['public'][0], public_ip)
 
160
        self.assertEqual(
 
161
            server.FnGetAtt('first_public_address'), public_ip)
 
162
 
 
163
        private_ip = return_server.networks['private'][0]
 
164
        self.assertEqual(
 
165
            server.FnGetAtt('addresses')['private'][0]['addr'], private_ip)
 
166
        self.assertEqual(
 
167
            server.FnGetAtt('networks')['private'][0], private_ip)
 
168
        self.assertEqual(
 
169
            server.FnGetAtt('first_private_address'), private_ip)
 
170
 
 
171
        self.m.VerifyAll()
 
172
 
 
173
    def test_server_create_image_name_err(self):
 
174
        stack_name = 'test_server_create_image_name_err_stack'
 
175
        (t, stack) = self._setup_test_stack(stack_name)
 
176
 
 
177
        # create an server with non exist image name
 
178
        t['Resources']['WebServer']['Properties']['image'] = 'Slackware'
 
179
        server = servers.Server('server_create_image_err',
 
180
                                t['Resources']['WebServer'], stack)
 
181
 
 
182
        self.m.StubOutWithMock(server, 'nova')
 
183
        server.nova().MultipleTimes().AndReturn(self.fc)
 
184
        self.m.ReplayAll()
 
185
 
 
186
        self.assertRaises(exception.ImageNotFound, server.handle_create)
 
187
 
 
188
        self.m.VerifyAll()
 
189
 
 
190
    def test_server_create_duplicate_image_name_err(self):
 
191
        stack_name = 'test_server_create_image_name_err_stack'
 
192
        (t, stack) = self._setup_test_stack(stack_name)
 
193
 
 
194
        # create an server with a non unique image name
 
195
        t['Resources']['WebServer']['Properties']['image'] = 'CentOS 5.2'
 
196
        server = servers.Server('server_create_image_err',
 
197
                                t['Resources']['WebServer'], stack)
 
198
 
 
199
        self.m.StubOutWithMock(server, 'nova')
 
200
        server.nova().MultipleTimes().AndReturn(self.fc)
 
201
        self.m.StubOutWithMock(self.fc.client, "get_images_detail")
 
202
        self.fc.client.get_images_detail().AndReturn((
 
203
            200, {'images': [{'id': 1, 'name': 'CentOS 5.2'},
 
204
                             {'id': 4, 'name': 'CentOS 5.2'}]}))
 
205
        self.m.ReplayAll()
 
206
 
 
207
        self.assertRaises(exception.NoUniqueImageFound, server.handle_create)
 
208
 
 
209
        self.m.VerifyAll()
 
210
 
 
211
    def test_server_create_image_id_err(self):
 
212
        stack_name = 'test_server_create_image_id_err_stack'
 
213
        (t, stack) = self._setup_test_stack(stack_name)
 
214
 
 
215
        # create an server with non exist image Id
 
216
        t['Resources']['WebServer']['Properties']['image'] = '1'
 
217
        server = servers.Server('server_create_image_err',
 
218
                                t['Resources']['WebServer'], stack)
 
219
 
 
220
        self.m.StubOutWithMock(server, 'nova')
 
221
        server.nova().MultipleTimes().AndReturn(self.fc)
 
222
        self.m.StubOutWithMock(uuidutils, "is_uuid_like")
 
223
        uuidutils.is_uuid_like('1').AndReturn(True)
 
224
        self.m.StubOutWithMock(self.fc.client, "get_images_1")
 
225
        self.fc.client.get_images_1().AndRaise(
 
226
            servers.clients.novaclient.exceptions.NotFound(404))
 
227
        self.m.ReplayAll()
 
228
 
 
229
        self.assertRaises(exception.ImageNotFound, server.handle_create)
 
230
 
 
231
        self.m.VerifyAll()
 
232
 
 
233
    def test_server_create_unexpected_status(self):
 
234
        return_server = self.fc.servers.list()[1]
 
235
        server = self._create_test_server(return_server,
 
236
                                          'test_server_create')
 
237
        return_server.get = lambda: None
 
238
        return_server.status = 'BOGUS'
 
239
        self.assertRaises(exception.Error,
 
240
                          server.check_create_complete,
 
241
                          return_server)
 
242
 
 
243
    def test_server_create_error_status(self):
 
244
        return_server = self.fc.servers.list()[1]
 
245
        server = self._create_test_server(return_server,
 
246
                                          'test_server_create')
 
247
        return_server.status = 'ERROR'
 
248
        return_server.fault = {
 
249
            'message': 'NoValidHost',
 
250
            'code': 500,
 
251
            'created': '2013-08-14T03:12:10Z'
 
252
        }
 
253
        self.m.StubOutWithMock(return_server, 'get')
 
254
        return_server.get()
 
255
        self.m.ReplayAll()
 
256
 
 
257
        self.assertRaises(exception.Error,
 
258
                          server.check_create_complete,
 
259
                          return_server)
 
260
 
 
261
        self.m.VerifyAll()
 
262
 
 
263
    def test_server_validate(self):
 
264
        stack_name = 'test_server_validate_stack'
 
265
        (t, stack) = self._setup_test_stack(stack_name)
 
266
 
 
267
        # create an server with non exist image Id
 
268
        t['Resources']['WebServer']['Properties']['image'] = '1'
 
269
        server = servers.Server('server_create_image_err',
 
270
                                t['Resources']['WebServer'], stack)
 
271
 
 
272
        self.m.StubOutWithMock(server, 'nova')
 
273
        server.nova().MultipleTimes().AndReturn(self.fc)
 
274
 
 
275
        self.m.StubOutWithMock(uuidutils, "is_uuid_like")
 
276
        uuidutils.is_uuid_like('1').AndReturn(True)
 
277
        self.m.ReplayAll()
 
278
 
 
279
        self.assertEqual(server.validate(), None)
 
280
 
 
281
        self.m.VerifyAll()
 
282
 
 
283
    def test_server_validate_delete_policy(self):
 
284
        stack_name = 'test_server_validate_stack'
 
285
        (t, stack) = self._setup_test_stack(stack_name)
 
286
 
 
287
        # create an server with non exist image Id
 
288
        t['Resources']['WebServer']['DeletionPolicy'] = 'SelfDestruct'
 
289
        server = servers.Server('server_create_image_err',
 
290
                                t['Resources']['WebServer'], stack)
 
291
 
 
292
        self.m.ReplayAll()
 
293
 
 
294
        ex = self.assertRaises(exception.StackValidationFailed,
 
295
                               server.validate)
 
296
        self.assertEqual('Invalid DeletionPolicy SelfDestruct',
 
297
                         str(ex))
 
298
 
 
299
        self.m.VerifyAll()
 
300
 
 
301
    def test_server_delete(self):
 
302
        return_server = self.fc.servers.list()[1]
 
303
        server = self._create_test_server(return_server,
 
304
                                          'test_server_create_delete')
 
305
        server.resource_id = 1234
 
306
 
 
307
        # this makes sure the auto increment worked on server creation
 
308
        self.assertTrue(server.id > 0)
 
309
 
 
310
        server_get = self.fc.client.get_servers_1234()
 
311
        self.m.StubOutWithMock(self.fc.client, 'get_servers_1234')
 
312
        get = self.fc.client.get_servers_1234
 
313
        get().AndReturn(server_get)
 
314
        get().AndRaise(servers.clients.novaclient.exceptions.NotFound(404))
 
315
        mox.Replay(get)
 
316
        self.m.ReplayAll()
 
317
 
 
318
        scheduler.TaskRunner(server.delete)()
 
319
        self.assertTrue(server.resource_id is None)
 
320
        self.assertEqual(server.state, (server.DELETE, server.COMPLETE))
 
321
        self.m.VerifyAll()
 
322
 
 
323
    def test_server_delete_notfound(self):
 
324
        return_server = self.fc.servers.list()[1]
 
325
        server = self._create_test_server(return_server,
 
326
                                          'test_server_create_delete')
 
327
        server.resource_id = 1234
 
328
 
 
329
        # this makes sure the auto increment worked on server creation
 
330
        self.assertTrue(server.id > 0)
 
331
 
 
332
        self.m.StubOutWithMock(self.fc.client, 'get_servers_1234')
 
333
        get = self.fc.client.get_servers_1234
 
334
        get().AndRaise(servers.clients.novaclient.exceptions.NotFound(404))
 
335
        mox.Replay(get)
 
336
 
 
337
        scheduler.TaskRunner(server.delete)()
 
338
        self.assertTrue(server.resource_id is None)
 
339
        self.assertEqual(server.state, (server.DELETE, server.COMPLETE))
 
340
        self.m.VerifyAll()
 
341
 
 
342
        server.state_set(server.CREATE, server.COMPLETE, 'to delete again')
 
343
        scheduler.TaskRunner(server.delete)()
 
344
        self.assertEqual(server.state, (server.DELETE, server.COMPLETE))
 
345
        self.m.VerifyAll()
 
346
 
 
347
    def test_server_update_metadata(self):
 
348
        return_server = self.fc.servers.list()[1]
 
349
        server = self._create_test_server(return_server,
 
350
                                          'test_server_update')
 
351
 
 
352
        update_template = copy.deepcopy(server.t)
 
353
        update_template['Metadata'] = {'test': 123}
 
354
        scheduler.TaskRunner(server.update, update_template)()
 
355
        self.assertEqual(server.metadata, {'test': 123})
 
356
 
 
357
        server.t['Metadata'] = {'test': 456}
 
358
        server.metadata_update()
 
359
        self.assertEqual(server.metadata, {'test': 456})
 
360
 
 
361
    def test_server_update_server_flavor(self):
 
362
        """
 
363
        Server.handle_update supports changing the flavor, and makes
 
364
        the change making a resize API call against Nova.
 
365
        """
 
366
        return_server = self.fc.servers.list()[1]
 
367
        return_server.id = 1234
 
368
        server = self._create_test_server(return_server,
 
369
                                          'test_server_update')
 
370
 
 
371
        update_template = copy.deepcopy(server.t)
 
372
        update_template['Properties']['flavor'] = 'm1.small'
 
373
 
 
374
        self.m.StubOutWithMock(self.fc.servers, 'get')
 
375
        self.fc.servers.get(1234).AndReturn(return_server)
 
376
 
 
377
        def activate_status(server):
 
378
            server.status = 'VERIFY_RESIZE'
 
379
        return_server.get = activate_status.__get__(return_server)
 
380
 
 
381
        self.m.StubOutWithMock(self.fc.client, 'post_servers_1234_action')
 
382
        self.fc.client.post_servers_1234_action(
 
383
            body={'resize': {'flavorRef': 2}}).AndReturn((202, None))
 
384
        self.fc.client.post_servers_1234_action(
 
385
            body={'confirmResize': None}).AndReturn((202, None))
 
386
        self.m.ReplayAll()
 
387
 
 
388
        scheduler.TaskRunner(server.update, update_template)()
 
389
        self.assertEqual(server.state, (server.UPDATE, server.COMPLETE))
 
390
        self.m.VerifyAll()
 
391
 
 
392
    def test_server_update_server_flavor_failed(self):
 
393
        """
 
394
        If the status after a resize is not VERIFY_RESIZE, it means the resize
 
395
        call failed, so we raise an explicit error.
 
396
        """
 
397
        return_server = self.fc.servers.list()[1]
 
398
        return_server.id = 1234
 
399
        server = self._create_test_server(return_server,
 
400
                                          'test_server_update')
 
401
 
 
402
        update_template = copy.deepcopy(server.t)
 
403
        update_template['Properties']['flavor'] = 'm1.small'
 
404
 
 
405
        self.m.StubOutWithMock(self.fc.servers, 'get')
 
406
        self.fc.servers.get(1234).AndReturn(return_server)
 
407
 
 
408
        def activate_status(server):
 
409
            server.status = 'ACTIVE'
 
410
        return_server.get = activate_status.__get__(return_server)
 
411
 
 
412
        self.m.StubOutWithMock(self.fc.client, 'post_servers_1234_action')
 
413
        self.fc.client.post_servers_1234_action(
 
414
            body={'resize': {'flavorRef': 2}}).AndReturn((202, None))
 
415
        self.m.ReplayAll()
 
416
 
 
417
        updater = scheduler.TaskRunner(server.update, update_template)
 
418
        error = self.assertRaises(exception.ResourceFailure, updater)
 
419
        self.assertEqual(
 
420
            "Error: Resizing to 'm1.small' failed, status 'ACTIVE'",
 
421
            str(error))
 
422
        self.assertEqual(server.state, (server.UPDATE, server.FAILED))
 
423
        self.m.VerifyAll()
 
424
 
 
425
    def test_server_update_server_flavor_replace(self):
 
426
        stack_name = 'test_server_update_flavor_replace'
 
427
        (t, stack) = self._setup_test_stack(stack_name)
 
428
 
 
429
        t['Resources']['WebServer']['Properties'][
 
430
            'flavor_update_policy'] = 'REPLACE'
 
431
        server = servers.Server('server_server_update_flavor_replace',
 
432
                                t['Resources']['WebServer'], stack)
 
433
 
 
434
        update_template = copy.deepcopy(server.t)
 
435
        update_template['Properties']['flavor'] = 'm1.smigish'
 
436
        updater = scheduler.TaskRunner(server.update, update_template)
 
437
        self.assertRaises(resource.UpdateReplace, updater)
 
438
 
 
439
    def test_server_update_server_flavor_policy_update(self):
 
440
        stack_name = 'test_server_update_flavor_replace'
 
441
        (t, stack) = self._setup_test_stack(stack_name)
 
442
 
 
443
        server = servers.Server('server_server_update_flavor_replace',
 
444
                                t['Resources']['WebServer'], stack)
 
445
 
 
446
        update_template = copy.deepcopy(server.t)
 
447
        # confirm that when flavor_update_policy is changed during
 
448
        # the update then the updated policy is followed for a flavor
 
449
        # update
 
450
        update_template['Properties']['flavor_update_policy'] = 'REPLACE'
 
451
        update_template['Properties']['flavor'] = 'm1.smigish'
 
452
        updater = scheduler.TaskRunner(server.update, update_template)
 
453
        self.assertRaises(resource.UpdateReplace, updater)
 
454
 
 
455
    def test_server_update_replace(self):
 
456
        return_server = self.fc.servers.list()[1]
 
457
        server = self._create_test_server(return_server,
 
458
                                          'test_server_update')
 
459
 
 
460
        update_template = copy.deepcopy(server.t)
 
461
        update_template['Notallowed'] = {'test': 123}
 
462
        updater = scheduler.TaskRunner(server.update, update_template)
 
463
        self.assertRaises(resource.UpdateReplace, updater)
 
464
 
 
465
    def test_server_update_properties(self):
 
466
        return_server = self.fc.servers.list()[1]
 
467
        server = self._create_test_server(return_server,
 
468
                                          'test_server_update')
 
469
 
 
470
        update_template = copy.deepcopy(server.t)
 
471
        update_template['Properties']['key_name'] = 'mustreplace'
 
472
        updater = scheduler.TaskRunner(server.update, update_template)
 
473
        self.assertRaises(resource.UpdateReplace, updater)
 
474
 
 
475
    def test_server_status_build(self):
 
476
        return_server = self.fc.servers.list()[0]
 
477
        server = self._setup_test_server(return_server,
 
478
                                         'test_server_status_build')
 
479
        server.resource_id = 1234
 
480
 
 
481
        # Bind fake get method which Server.check_create_complete will call
 
482
        def activate_status(server):
 
483
            server.status = 'ACTIVE'
 
484
        return_server.get = activate_status.__get__(return_server)
 
485
        self.m.ReplayAll()
 
486
 
 
487
        scheduler.TaskRunner(server.create)()
 
488
        self.assertEqual(server.state, (server.CREATE, server.COMPLETE))
 
489
 
 
490
    def test_server_status_suspend_no_resource_id(self):
 
491
        return_server = self.fc.servers.list()[1]
 
492
        server = self._create_test_server(return_server,
 
493
                                          'test_server_suspend')
 
494
 
 
495
        server.resource_id = None
 
496
        self.m.ReplayAll()
 
497
 
 
498
        ex = self.assertRaises(exception.ResourceFailure,
 
499
                               scheduler.TaskRunner(server.suspend))
 
500
        self.assertEqual('Error: Cannot suspend test_server_suspend_name, '
 
501
                         'resource_id not set',
 
502
                         str(ex))
 
503
        self.assertEqual(server.state, (server.SUSPEND, server.FAILED))
 
504
 
 
505
        self.m.VerifyAll()
 
506
 
 
507
    def test_server_status_suspend_not_found(self):
 
508
        return_server = self.fc.servers.list()[1]
 
509
        server = self._create_test_server(return_server,
 
510
                                          'test_server_suspend')
 
511
 
 
512
        server.resource_id = 1234
 
513
        self.m.StubOutWithMock(self.fc.client, 'get_servers_1234')
 
514
        get = self.fc.client.get_servers_1234
 
515
        get().AndRaise(servers.clients.novaclient.exceptions.NotFound(404))
 
516
        mox.Replay(get)
 
517
        self.m.ReplayAll()
 
518
 
 
519
        ex = self.assertRaises(exception.ResourceFailure,
 
520
                               scheduler.TaskRunner(server.suspend))
 
521
        self.assertEqual('NotFound: Failed to find server 1234',
 
522
                         str(ex))
 
523
        self.assertEqual(server.state, (server.SUSPEND, server.FAILED))
 
524
 
 
525
        self.m.VerifyAll()
 
526
 
 
527
    def test_server_status_suspend_immediate(self):
 
528
        return_server = self.fc.servers.list()[1]
 
529
        server = self._create_test_server(return_server,
 
530
                                          'test_server_suspend')
 
531
 
 
532
        server.resource_id = 1234
 
533
        self.m.ReplayAll()
 
534
 
 
535
        # Override the get_servers_1234 handler status to SUSPENDED
 
536
        d = {'server': self.fc.client.get_servers_detail()[1]['servers'][0]}
 
537
        d['server']['status'] = 'SUSPENDED'
 
538
        self.m.StubOutWithMock(self.fc.client, 'get_servers_1234')
 
539
        get = self.fc.client.get_servers_1234
 
540
        get().AndReturn((200, d))
 
541
        mox.Replay(get)
 
542
 
 
543
        scheduler.TaskRunner(server.suspend)()
 
544
        self.assertEqual(server.state, (server.SUSPEND, server.COMPLETE))
 
545
 
 
546
        self.m.VerifyAll()
 
547
 
 
548
    def test_server_status_resume_immediate(self):
 
549
        return_server = self.fc.servers.list()[1]
 
550
        server = self._create_test_server(return_server,
 
551
                                          'test_server_resume')
 
552
 
 
553
        server.resource_id = 1234
 
554
        self.m.ReplayAll()
 
555
 
 
556
        # Override the get_servers_1234 handler status to SUSPENDED
 
557
        d = {'server': self.fc.client.get_servers_detail()[1]['servers'][0]}
 
558
        d['server']['status'] = 'ACTIVE'
 
559
        self.m.StubOutWithMock(self.fc.client, 'get_servers_1234')
 
560
        get = self.fc.client.get_servers_1234
 
561
        get().AndReturn((200, d))
 
562
        mox.Replay(get)
 
563
        server.state_set(server.SUSPEND, server.COMPLETE)
 
564
 
 
565
        scheduler.TaskRunner(server.resume)()
 
566
        self.assertEqual(server.state, (server.RESUME, server.COMPLETE))
 
567
 
 
568
        self.m.VerifyAll()
 
569
 
 
570
    def test_server_status_suspend_wait(self):
 
571
        return_server = self.fc.servers.list()[1]
 
572
        server = self._create_test_server(return_server,
 
573
                                          'test_server_suspend')
 
574
 
 
575
        server.resource_id = 1234
 
576
        self.m.ReplayAll()
 
577
 
 
578
        # Override the get_servers_1234 handler status to SUSPENDED, but
 
579
        # return the ACTIVE state first (twice, so we sleep)
 
580
        d1 = {'server': self.fc.client.get_servers_detail()[1]['servers'][0]}
 
581
        d2 = copy.deepcopy(d1)
 
582
        d1['server']['status'] = 'ACTIVE'
 
583
        d2['server']['status'] = 'SUSPENDED'
 
584
        self.m.StubOutWithMock(self.fc.client, 'get_servers_1234')
 
585
        get = self.fc.client.get_servers_1234
 
586
        get().AndReturn((200, d1))
 
587
        get().AndReturn((200, d1))
 
588
        get().AndReturn((200, d2))
 
589
        self.m.ReplayAll()
 
590
 
 
591
        scheduler.TaskRunner(server.suspend)()
 
592
        self.assertEqual(server.state, (server.SUSPEND, server.COMPLETE))
 
593
 
 
594
        self.m.VerifyAll()
 
595
 
 
596
    def test_server_status_suspend_unknown_status(self):
 
597
        return_server = self.fc.servers.list()[1]
 
598
        server = self._create_test_server(return_server,
 
599
                                          'test_server_suspend')
 
600
 
 
601
        server.resource_id = 1234
 
602
        self.m.ReplayAll()
 
603
 
 
604
        # Override the get_servers_1234 handler status to SUSPENDED, but
 
605
        # return the ACTIVE state first (twice, so we sleep)
 
606
        d1 = {'server': self.fc.client.get_servers_detail()[1]['servers'][0]}
 
607
        d2 = copy.deepcopy(d1)
 
608
        d1['server']['status'] = 'ACTIVE'
 
609
        d2['server']['status'] = 'TRANSMOGRIFIED'
 
610
        self.m.StubOutWithMock(self.fc.client, 'get_servers_1234')
 
611
        get = self.fc.client.get_servers_1234
 
612
        get().AndReturn((200, d1))
 
613
        get().AndReturn((200, d1))
 
614
        get().AndReturn((200, d2))
 
615
        self.m.ReplayAll()
 
616
 
 
617
        ex = self.assertRaises(exception.ResourceFailure,
 
618
                               scheduler.TaskRunner(server.suspend))
 
619
        self.assertEqual('Error: Suspend of server sample-server failed '
 
620
                         'with unknown status: TRANSMOGRIFIED',
 
621
                         str(ex))
 
622
        self.assertEqual(server.state, (server.SUSPEND, server.FAILED))
 
623
 
 
624
        self.m.VerifyAll()
 
625
 
 
626
    def test_server_status_resume_wait(self):
 
627
        return_server = self.fc.servers.list()[1]
 
628
        server = self._create_test_server(return_server,
 
629
                                          'test_server_resume')
 
630
 
 
631
        server.resource_id = 1234
 
632
        self.m.ReplayAll()
 
633
 
 
634
        # Override the get_servers_1234 handler status to ACTIVE, but
 
635
        # return the SUSPENDED state first (twice, so we sleep)
 
636
        d1 = {'server': self.fc.client.get_servers_detail()[1]['servers'][0]}
 
637
        d2 = copy.deepcopy(d1)
 
638
        d1['server']['status'] = 'SUSPENDED'
 
639
        d2['server']['status'] = 'ACTIVE'
 
640
        self.m.StubOutWithMock(self.fc.client, 'get_servers_1234')
 
641
        get = self.fc.client.get_servers_1234
 
642
        get().AndReturn((200, d1))
 
643
        get().AndReturn((200, d1))
 
644
        get().AndReturn((200, d2))
 
645
        self.m.ReplayAll()
 
646
 
 
647
        server.state_set(server.SUSPEND, server.COMPLETE)
 
648
 
 
649
        scheduler.TaskRunner(server.resume)()
 
650
        self.assertEqual(server.state, (server.RESUME, server.COMPLETE))
 
651
 
 
652
        self.m.VerifyAll()
 
653
 
 
654
    def test_server_status_resume_no_resource_id(self):
 
655
        return_server = self.fc.servers.list()[1]
 
656
        server = self._create_test_server(return_server,
 
657
                                          'test_server_suspend')
 
658
 
 
659
        server.resource_id = None
 
660
        self.m.ReplayAll()
 
661
 
 
662
        server.state_set(server.SUSPEND, server.COMPLETE)
 
663
        ex = self.assertRaises(exception.ResourceFailure,
 
664
                               scheduler.TaskRunner(server.resume))
 
665
        self.assertEqual('Error: Cannot resume test_server_suspend_name, '
 
666
                         'resource_id not set',
 
667
                         str(ex))
 
668
        self.assertEqual(server.state, (server.RESUME, server.FAILED))
 
669
 
 
670
        self.m.VerifyAll()
 
671
 
 
672
    def test_server_status_resume_not_found(self):
 
673
        return_server = self.fc.servers.list()[1]
 
674
        server = self._create_test_server(return_server,
 
675
                                          'test_server_resume')
 
676
 
 
677
        server.resource_id = 1234
 
678
        self.m.ReplayAll()
 
679
 
 
680
        # Override the get_servers_1234 handler status to ACTIVE, but
 
681
        # return the SUSPENDED state first (twice, so we sleep)
 
682
        self.m.StubOutWithMock(self.fc.client, 'get_servers_1234')
 
683
        get = self.fc.client.get_servers_1234
 
684
        get().AndRaise(servers.clients.novaclient.exceptions.NotFound(404))
 
685
        self.m.ReplayAll()
 
686
 
 
687
        server.state_set(server.SUSPEND, server.COMPLETE)
 
688
 
 
689
        ex = self.assertRaises(exception.ResourceFailure,
 
690
                               scheduler.TaskRunner(server.resume))
 
691
        self.assertEqual('NotFound: Failed to find server 1234',
 
692
                         str(ex))
 
693
        self.assertEqual(server.state, (server.RESUME, server.FAILED))
 
694
 
 
695
        self.m.VerifyAll()
 
696
 
 
697
    def test_server_status_build_spawning(self):
 
698
        self._test_server_status_not_build_active('BUILD(SPAWNING)')
 
699
 
 
700
    def test_server_status_hard_reboot(self):
 
701
        self._test_server_status_not_build_active('HARD_REBOOT')
 
702
 
 
703
    def test_server_status_password(self):
 
704
        self._test_server_status_not_build_active('PASSWORD')
 
705
 
 
706
    def test_server_status_reboot(self):
 
707
        self._test_server_status_not_build_active('REBOOT')
 
708
 
 
709
    def test_server_status_rescue(self):
 
710
        self._test_server_status_not_build_active('RESCUE')
 
711
 
 
712
    def test_server_status_resize(self):
 
713
        self._test_server_status_not_build_active('RESIZE')
 
714
 
 
715
    def test_server_status_revert_resize(self):
 
716
        self._test_server_status_not_build_active('REVERT_RESIZE')
 
717
 
 
718
    def test_server_status_shutoff(self):
 
719
        self._test_server_status_not_build_active('SHUTOFF')
 
720
 
 
721
    def test_server_status_suspended(self):
 
722
        self._test_server_status_not_build_active('SUSPENDED')
 
723
 
 
724
    def test_server_status_verify_resize(self):
 
725
        self._test_server_status_not_build_active('VERIFY_RESIZE')
 
726
 
 
727
    def _test_server_status_not_build_active(self, uncommon_status):
 
728
        return_server = self.fc.servers.list()[0]
 
729
        server = self._setup_test_server(return_server,
 
730
                                         'test_server_status_build')
 
731
        server.resource_id = 1234
 
732
 
 
733
        check_iterations = [0]
 
734
 
 
735
        # Bind fake get method which Server.check_create_complete will call
 
736
        def activate_status(server):
 
737
            check_iterations[0] += 1
 
738
            if check_iterations[0] == 1:
 
739
                server.status = uncommon_status
 
740
            if check_iterations[0] > 2:
 
741
                server.status = 'ACTIVE'
 
742
        return_server.get = activate_status.__get__(return_server)
 
743
        self.m.ReplayAll()
 
744
 
 
745
        scheduler.TaskRunner(server.create)()
 
746
        self.assertEqual(server.state, (server.CREATE, server.COMPLETE))
 
747
 
 
748
        self.m.VerifyAll()
 
749
 
 
750
    def test_build_nics(self):
 
751
        self.assertEqual(None, servers.Server._build_nics([]))
 
752
        self.assertEqual(None, servers.Server._build_nics(None))
 
753
        self.assertEqual([
 
754
            {'net-id': '1234abcd'},
 
755
            {'v4-fixed-ip': '192.0.2.0'},
 
756
            {'port-id': 'aaaabbbb'}
 
757
        ], servers.Server._build_nics([
 
758
            {'uuid': '1234abcd'},
 
759
            {'fixed_ip': '192.0.2.0'},
 
760
            {'port': 'aaaabbbb'}
 
761
        ]))
 
762
 
 
763
    def test_server_without_ip_address(self):
 
764
        return_server = self.fc.servers.list()[3]
 
765
        server = self._create_test_server(return_server,
 
766
                                          'test_without_ip_address')
 
767
 
 
768
        self.assertEqual(server.FnGetAtt('addresses'), {'empty_net': []})
 
769
        self.assertEqual(server.FnGetAtt('networks'), {'empty_net': []})
 
770
        self.assertEqual(server.FnGetAtt('first_private_address'), '')
 
771
        self.assertEqual(server.FnGetAtt('first_public_address'), '')
 
772
 
 
773
    def test_build_block_device_mapping(self):
 
774
        self.assertEqual(
 
775
            None, servers.Server._build_block_device_mapping([]))
 
776
        self.assertEqual(
 
777
            None, servers.Server._build_block_device_mapping(None))
 
778
 
 
779
        self.assertEqual({
 
780
            'vda': ['1234', ''],
 
781
            'vdb': ['1234', 'snap'],
 
782
        }, servers.Server._build_block_device_mapping([
 
783
            {'device_name': 'vda', 'volume_id': '1234'},
 
784
            {'device_name': 'vdb', 'snapshot_id': '1234'},
 
785
        ]))
 
786
 
 
787
        self.assertEqual({
 
788
            'vdc': ['1234', '', 10],
 
789
            'vdd': ['1234', 'snap', 0, True]
 
790
        }, servers.Server._build_block_device_mapping([
 
791
            {
 
792
                'device_name': 'vdc',
 
793
                'volume_id': '1234',
 
794
                'volume_size': 10
 
795
            },
 
796
            {
 
797
                'device_name': 'vdd',
 
798
                'snapshot_id': '1234',
 
799
                'delete_on_termination': True
 
800
            }
 
801
        ]))