~ubuntu-branches/ubuntu/trusty/heat/trusty

« back to all changes in this revision

Viewing changes to .pc/rename-quantumclient.patch/heat/tests/test_vpc.py

  • Committer: Package Import Robot
  • Author(s): Chuck Short, Chuck Short
  • Date: 2013-08-08 01:08:42 UTC
  • Revision ID: package-import@ubuntu.com-20130808010842-77cni2v4vlib7rus
Tags: 2013.2~b2-0ubuntu4
[ Chuck Short ]
* debian/rules: Enable testsuite during builds.
* debian/patches/fix-sqlalchemy-0.8.patch: Build against sqlalchemy 0.8.
* debian/patches/rename-quantumclient.patch: quantumclient -> neutronclient.

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
from testtools import skipIf
 
16
 
 
17
from heat.common import context
 
18
from heat.common import exception
 
19
from heat.common import template_format
 
20
from heat.engine import parser
 
21
from heat.engine import resource
 
22
from heat.tests.common import HeatTestCase
 
23
from heat.tests import utils
 
24
from heat.tests.utils import setup_dummy_db
 
25
 
 
26
try:
 
27
    from quantumclient.common.exceptions import QuantumClientException
 
28
    from quantumclient.v2_0 import client as quantumclient
 
29
except ImportError:
 
30
    quantumclient = None
 
31
 
 
32
 
 
33
class VPCTestBase(HeatTestCase):
 
34
 
 
35
    @skipIf(quantumclient is None, 'quantumclient unavaialble')
 
36
    def setUp(self):
 
37
        super(VPCTestBase, self).setUp()
 
38
        setup_dummy_db()
 
39
        self.m.StubOutWithMock(quantumclient.Client, 'add_interface_router')
 
40
        self.m.StubOutWithMock(quantumclient.Client, 'add_gateway_router')
 
41
        self.m.StubOutWithMock(quantumclient.Client, 'create_network')
 
42
        self.m.StubOutWithMock(quantumclient.Client, 'create_port')
 
43
        self.m.StubOutWithMock(quantumclient.Client, 'create_router')
 
44
        self.m.StubOutWithMock(quantumclient.Client, 'create_subnet')
 
45
        self.m.StubOutWithMock(quantumclient.Client, 'delete_network')
 
46
        self.m.StubOutWithMock(quantumclient.Client, 'delete_port')
 
47
        self.m.StubOutWithMock(quantumclient.Client, 'delete_router')
 
48
        self.m.StubOutWithMock(quantumclient.Client, 'delete_subnet')
 
49
        self.m.StubOutWithMock(quantumclient.Client, 'list_networks')
 
50
        self.m.StubOutWithMock(quantumclient.Client, 'list_routers')
 
51
        self.m.StubOutWithMock(quantumclient.Client, 'remove_gateway_router')
 
52
        self.m.StubOutWithMock(quantumclient.Client, 'remove_interface_router')
 
53
        self.m.StubOutWithMock(quantumclient.Client, 'show_subnet')
 
54
        self.m.StubOutWithMock(quantumclient.Client, 'show_network')
 
55
        self.m.StubOutWithMock(quantumclient.Client, 'show_router')
 
56
        self.m.StubOutWithMock(quantumclient.Client, 'create_security_group')
 
57
        self.m.StubOutWithMock(quantumclient.Client, 'show_security_group')
 
58
        self.m.StubOutWithMock(quantumclient.Client, 'delete_security_group')
 
59
        self.m.StubOutWithMock(
 
60
            quantumclient.Client, 'create_security_group_rule')
 
61
        self.m.StubOutWithMock(
 
62
            quantumclient.Client, 'delete_security_group_rule')
 
63
 
 
64
    def create_stack(self, template):
 
65
        t = template_format.parse(template)
 
66
        stack = self.parse_stack(t)
 
67
        self.assertEqual(None, stack.create())
 
68
        return stack
 
69
 
 
70
    def parse_stack(self, t):
 
71
        ctx = context.RequestContext.from_dict({
 
72
            'tenant': 'test_tenant',
 
73
            'username': 'test_username',
 
74
            'password': 'password',
 
75
            'auth_url': 'http://localhost:5000/v2.0'})
 
76
        stack_name = 'test_stack'
 
77
        tmpl = parser.Template(t)
 
78
        stack = parser.Stack(ctx, stack_name, tmpl)
 
79
        stack.store()
 
80
        return stack
 
81
 
 
82
    def mock_create_network(self):
 
83
        self.vpc_name = utils.PhysName('test_stack', 'the_vpc')
 
84
        quantumclient.Client.create_network(
 
85
            {
 
86
                'network': {'name': self.vpc_name}
 
87
            }).AndReturn({'network': {
 
88
                'status': 'BUILD',
 
89
                'subnets': [],
 
90
                'name': 'name',
 
91
                'admin_state_up': True,
 
92
                'shared': False,
 
93
                'tenant_id': 'c1210485b2424d48804aad5d39c61b8f',
 
94
                'id': 'aaaa'
 
95
            }})
 
96
        quantumclient.Client.show_network(
 
97
            'aaaa'
 
98
        ).AndReturn({"network": {
 
99
            "status": "BUILD",
 
100
            "subnets": [],
 
101
            "name": self.vpc_name,
 
102
            "admin_state_up": False,
 
103
            "shared": False,
 
104
            "tenant_id": "c1210485b2424d48804aad5d39c61b8f",
 
105
            "id": "aaaa"
 
106
        }})
 
107
 
 
108
        quantumclient.Client.show_network(
 
109
            'aaaa'
 
110
        ).MultipleTimes().AndReturn({"network": {
 
111
            "status": "ACTIVE",
 
112
            "subnets": [],
 
113
            "name": self.vpc_name,
 
114
            "admin_state_up": False,
 
115
            "shared": False,
 
116
            "tenant_id": "c1210485b2424d48804aad5d39c61b8f",
 
117
            "id": "aaaa"
 
118
        }})
 
119
        quantumclient.Client.create_router(
 
120
            {'router': {'name': self.vpc_name}}).AndReturn({
 
121
                'router': {
 
122
                    'status': 'BUILD',
 
123
                    'name': self.vpc_name,
 
124
                    'admin_state_up': True,
 
125
                    'tenant_id': 'c1210485b2424d48804aad5d39c61b8f',
 
126
                    'id': 'bbbb'
 
127
                }})
 
128
        quantumclient.Client.list_routers(name=self.vpc_name).AndReturn({
 
129
            "routers": [{
 
130
                "status": "BUILD",
 
131
                "external_gateway_info": None,
 
132
                "name": self.vpc_name,
 
133
                "admin_state_up": True,
 
134
                "tenant_id": "3e21026f2dc94372b105808c0e721661",
 
135
                "routes": [],
 
136
                "id": "bbbb"
 
137
            }]
 
138
        })
 
139
        self.mock_router_for_vpc()
 
140
 
 
141
    def mock_create_subnet(self):
 
142
        self.subnet_name = utils.PhysName('test_stack', 'the_subnet')
 
143
        quantumclient.Client.create_subnet(
 
144
            {'subnet': {
 
145
                'network_id': u'aaaa',
 
146
                'cidr': u'10.0.0.0/24',
 
147
                'ip_version': 4,
 
148
                'name': self.subnet_name}}).AndReturn({
 
149
                    'subnet': {
 
150
                        'status': 'ACTIVE',
 
151
                        'name': self.subnet_name,
 
152
                        'admin_state_up': True,
 
153
                        'tenant_id': 'c1210485b2424d48804aad5d39c61b8f',
 
154
                        'id': 'cccc'}})
 
155
        self.mock_router_for_vpc()
 
156
        quantumclient.Client.add_interface_router(
 
157
            u'bbbb',
 
158
            {'subnet_id': 'cccc'}).AndReturn(None)
 
159
 
 
160
    def mock_show_subnet(self):
 
161
        quantumclient.Client.show_subnet('cccc').AndReturn({
 
162
            'subnet': {
 
163
                'name': self.subnet_name,
 
164
                'network_id': 'aaaa',
 
165
                'tenant_id': 'c1210485b2424d48804aad5d39c61b8f',
 
166
                'allocation_pools': [{'start': '10.0.0.2',
 
167
                                      'end': '10.0.0.254'}],
 
168
                'gateway_ip': '10.0.0.1',
 
169
                'ip_version': 4,
 
170
                'cidr': '10.0.0.0/24',
 
171
                'id': 'cccc',
 
172
                'enable_dhcp': False,
 
173
            }})
 
174
 
 
175
    def mock_create_security_group(self):
 
176
        self.sg_name = utils.PhysName('test_stack', 'the_sg')
 
177
        quantumclient.Client.create_security_group({
 
178
            'security_group': {
 
179
                'name': self.sg_name,
 
180
                'description': 'SSH access'
 
181
            }
 
182
        }).AndReturn({
 
183
            'security_group': {
 
184
                'tenant_id': 'c1210485b2424d48804aad5d39c61b8f',
 
185
                'name': self.sg_name,
 
186
                'description': 'SSH access',
 
187
                'security_group_rules': [],
 
188
                'id': 'eeee'
 
189
            }
 
190
        })
 
191
 
 
192
        quantumclient.Client.create_security_group_rule({
 
193
            'security_group_rule': {
 
194
                'direction': 'ingress',
 
195
                'remote_ip_prefix': '0.0.0.0/0',
 
196
                'port_range_min': 22,
 
197
                'ethertype': 'IPv4',
 
198
                'port_range_max': 22,
 
199
                'protocol': 'tcp',
 
200
                'security_group_id': 'eeee'
 
201
            }
 
202
        }).AndReturn({
 
203
            'security_group_rule': {
 
204
                'direction': 'ingress',
 
205
                'remote_ip_prefix': '0.0.0.0/0',
 
206
                'port_range_min': 22,
 
207
                'ethertype': 'IPv4',
 
208
                'port_range_max': 22,
 
209
                'protocol': 'tcp',
 
210
                'security_group_id': 'eeee',
 
211
                'id': 'bbbb'
 
212
            }
 
213
        })
 
214
 
 
215
    def mock_delete_security_group(self):
 
216
        sg_name = utils.PhysName('test_stack', 'the_sg')
 
217
        quantumclient.Client.show_security_group('eeee').AndReturn({
 
218
            'security_group': {
 
219
                'tenant_id': 'c1210485b2424d48804aad5d39c61b8f',
 
220
                'name': sg_name,
 
221
                'description': '',
 
222
                'security_group_rules': [{
 
223
                    'direction': 'ingress',
 
224
                    'protocol': 'tcp',
 
225
                    'port_range_max': 22,
 
226
                    'id': 'bbbb',
 
227
                    'ethertype': 'IPv4',
 
228
                    'security_group_id': 'eeee',
 
229
                    'remote_ip_prefix': '0.0.0.0/0',
 
230
                    'tenant_id': 'c1210485b2424d48804aad5d39c61b8f',
 
231
                    'port_range_min': 22
 
232
                }],
 
233
                'id': 'eeee'}})
 
234
        quantumclient.Client.delete_security_group_rule('bbbb').AndReturn(None)
 
235
        quantumclient.Client.delete_security_group('eeee').AndReturn(None)
 
236
 
 
237
    def mock_router_for_vpc(self):
 
238
        quantumclient.Client.list_routers(name=self.vpc_name).AndReturn({
 
239
            "routers": [{
 
240
                "status": "ACTIVE",
 
241
                "external_gateway_info": {
 
242
                    "network_id": "zzzz",
 
243
                    "enable_snat": True},
 
244
                "name": self.vpc_name,
 
245
                "admin_state_up": True,
 
246
                "tenant_id": "3e21026f2dc94372b105808c0e721661",
 
247
                "routes": [],
 
248
                "id": "bbbb"
 
249
            }]
 
250
        })
 
251
 
 
252
    def mock_delete_network(self):
 
253
        self.mock_router_for_vpc()
 
254
        quantumclient.Client.delete_router('bbbb').AndReturn(None)
 
255
        quantumclient.Client.delete_network('aaaa').AndReturn(None)
 
256
 
 
257
    def mock_delete_subnet(self):
 
258
        self.mock_router_for_vpc()
 
259
        quantumclient.Client.remove_interface_router(
 
260
            u'bbbb',
 
261
            {'subnet_id': 'cccc'}).AndReturn(None)
 
262
        quantumclient.Client.delete_subnet('cccc').AndReturn(None)
 
263
 
 
264
    def mock_create_route_table(self):
 
265
        self.rt_name = utils.PhysName('test_stack', 'the_route_table')
 
266
        quantumclient.Client.create_router({
 
267
            'router': {'name': self.rt_name}}).AndReturn({
 
268
                'router': {
 
269
                    'status': 'BUILD',
 
270
                    'name': self.rt_name,
 
271
                    'admin_state_up': True,
 
272
                    'tenant_id': 'c1210485b2424d48804aad5d39c61b8f',
 
273
                    'id': 'ffff'
 
274
                }
 
275
            })
 
276
        quantumclient.Client.show_router('ffff').AndReturn({
 
277
            'router': {
 
278
                'status': 'BUILD',
 
279
                'name': self.rt_name,
 
280
                'admin_state_up': True,
 
281
                'tenant_id': 'c1210485b2424d48804aad5d39c61b8f',
 
282
                'id': 'ffff'
 
283
            }
 
284
        })
 
285
        quantumclient.Client.show_router('ffff').AndReturn({
 
286
            'router': {
 
287
                'status': 'ACTIVE',
 
288
                'name': self.rt_name,
 
289
                'admin_state_up': True,
 
290
                'tenant_id': 'c1210485b2424d48804aad5d39c61b8f',
 
291
                'id': 'ffff'
 
292
            }
 
293
        })
 
294
        self.mock_router_for_vpc()
 
295
        quantumclient.Client.add_gateway_router(
 
296
            'ffff', {'network_id': 'zzzz'}).AndReturn(None)
 
297
 
 
298
    def mock_create_association(self):
 
299
        self.mock_show_subnet()
 
300
        self.mock_router_for_vpc()
 
301
        quantumclient.Client.remove_interface_router(
 
302
            'bbbb',
 
303
            {'subnet_id': u'cccc'}).AndReturn(None)
 
304
        quantumclient.Client.add_interface_router(
 
305
            u'ffff',
 
306
            {'subnet_id': 'cccc'}).AndReturn(None)
 
307
 
 
308
    def mock_delete_association(self):
 
309
        self.mock_show_subnet()
 
310
        self.mock_router_for_vpc()
 
311
        quantumclient.Client.remove_interface_router(
 
312
            'ffff',
 
313
            {'subnet_id': u'cccc'}).AndReturn(None)
 
314
        quantumclient.Client.add_interface_router(
 
315
            u'bbbb',
 
316
            {'subnet_id': 'cccc'}).AndReturn(None)
 
317
 
 
318
    def mock_delete_route_table(self):
 
319
        quantumclient.Client.delete_router('ffff').AndReturn(None)
 
320
        quantumclient.Client.remove_gateway_router('ffff').AndReturn(None)
 
321
 
 
322
    def assertResourceState(self, resource, ref_id):
 
323
        self.assertEqual(None, resource.validate())
 
324
        self.assertEqual((resource.CREATE, resource.COMPLETE), resource.state)
 
325
        self.assertEqual(ref_id, resource.FnGetRefId())
 
326
 
 
327
 
 
328
class VPCTest(VPCTestBase):
 
329
 
 
330
    test_template = '''
 
331
HeatTemplateFormatVersion: '2012-12-12'
 
332
Resources:
 
333
  the_vpc:
 
334
    Type: AWS::EC2::VPC
 
335
    Properties: {CidrBlock: '10.0.0.0/16'}
 
336
'''
 
337
 
 
338
    def test_vpc(self):
 
339
        self.mock_create_network()
 
340
        self.mock_delete_network()
 
341
        self.m.ReplayAll()
 
342
 
 
343
        stack = self.create_stack(self.test_template)
 
344
        vpc = stack['the_vpc']
 
345
        self.assertResourceState(vpc, 'aaaa')
 
346
        self.assertRaises(resource.UpdateReplace,
 
347
                          vpc.handle_update, {}, {}, {})
 
348
 
 
349
        self.assertEqual(None, vpc.delete())
 
350
        self.m.VerifyAll()
 
351
 
 
352
 
 
353
class SubnetTest(VPCTestBase):
 
354
 
 
355
    test_template = '''
 
356
HeatTemplateFormatVersion: '2012-12-12'
 
357
Resources:
 
358
  the_vpc:
 
359
    Type: AWS::EC2::VPC
 
360
    Properties: {CidrBlock: '10.0.0.0/16'}
 
361
  the_subnet:
 
362
    Type: AWS::EC2::Subnet
 
363
    Properties:
 
364
      CidrBlock: 10.0.0.0/24
 
365
      VpcId: {Ref: the_vpc}
 
366
      AvailabilityZone: moon
 
367
'''
 
368
 
 
369
    def test_subnet(self):
 
370
        self.mock_create_network()
 
371
        self.mock_create_subnet()
 
372
        self.mock_delete_subnet()
 
373
        self.mock_delete_network()
 
374
 
 
375
        # mock delete subnet which is already deleted
 
376
        self.mock_router_for_vpc()
 
377
        quantumclient.Client.remove_interface_router(
 
378
            u'bbbb',
 
379
            {'subnet_id': 'cccc'}).AndRaise(
 
380
                QuantumClientException(status_code=404))
 
381
        quantumclient.Client.delete_subnet('cccc').AndRaise(
 
382
            QuantumClientException(status_code=404))
 
383
 
 
384
        self.m.ReplayAll()
 
385
        stack = self.create_stack(self.test_template)
 
386
 
 
387
        subnet = stack['the_subnet']
 
388
        self.assertResourceState(subnet, 'cccc')
 
389
 
 
390
        self.assertRaises(resource.UpdateReplace,
 
391
                          subnet.handle_update, {}, {}, {})
 
392
        self.assertRaises(
 
393
            exception.InvalidTemplateAttribute,
 
394
            subnet.FnGetAtt,
 
395
            'Foo')
 
396
 
 
397
        self.assertEqual('moon', subnet.FnGetAtt('AvailabilityZone'))
 
398
 
 
399
        self.assertEqual(None, subnet.delete())
 
400
        subnet.state_set(subnet.CREATE, subnet.COMPLETE, 'to delete again')
 
401
        self.assertEqual(None, subnet.delete())
 
402
        self.assertEqual(None, stack['the_vpc'].delete())
 
403
        self.m.VerifyAll()
 
404
 
 
405
 
 
406
class NetworkInterfaceTest(VPCTestBase):
 
407
 
 
408
    test_template = '''
 
409
HeatTemplateFormatVersion: '2012-12-12'
 
410
Resources:
 
411
  the_sg:
 
412
    Type: AWS::EC2::SecurityGroup
 
413
    Properties:
 
414
      VpcId: {Ref: the_vpc}
 
415
      GroupDescription: SSH access
 
416
      SecurityGroupIngress:
 
417
        - IpProtocol: tcp
 
418
          FromPort: 22
 
419
          ToPort: 22
 
420
          CidrIp: 0.0.0.0/0
 
421
  the_vpc:
 
422
    Type: AWS::EC2::VPC
 
423
    Properties: {CidrBlock: '10.0.0.0/16'}
 
424
  the_subnet:
 
425
    Type: AWS::EC2::Subnet
 
426
    Properties:
 
427
      CidrBlock: 10.0.0.0/24
 
428
      VpcId: {Ref: the_vpc}
 
429
      AvailabilityZone: moon
 
430
  the_nic:
 
431
    Type: AWS::EC2::NetworkInterface
 
432
    Properties:
 
433
      PrivateIpAddress: 10.0.0.100
 
434
      SubnetId: {Ref: the_subnet}
 
435
      GroupSet:
 
436
      - Ref: the_sg
 
437
'''
 
438
 
 
439
    test_template_no_groupset = '''
 
440
HeatTemplateFormatVersion: '2012-12-12'
 
441
Resources:
 
442
  the_vpc:
 
443
    Type: AWS::EC2::VPC
 
444
    Properties: {CidrBlock: '10.0.0.0/16'}
 
445
  the_subnet:
 
446
    Type: AWS::EC2::Subnet
 
447
    Properties:
 
448
      CidrBlock: 10.0.0.0/24
 
449
      VpcId: {Ref: the_vpc}
 
450
      AvailabilityZone: moon
 
451
  the_nic:
 
452
    Type: AWS::EC2::NetworkInterface
 
453
    Properties:
 
454
      PrivateIpAddress: 10.0.0.100
 
455
      SubnetId: {Ref: the_subnet}
 
456
'''
 
457
 
 
458
    test_template_error = '''
 
459
HeatTemplateFormatVersion: '2012-12-12'
 
460
Resources:
 
461
  the_sg:
 
462
    Type: AWS::EC2::SecurityGroup
 
463
    Properties:
 
464
      VpcId: {Ref: the_vpc}
 
465
      GroupDescription: SSH access
 
466
      SecurityGroupIngress:
 
467
        - IpProtocol: tcp
 
468
          FromPort: 22
 
469
          ToPort: 22
 
470
          CidrIp: 0.0.0.0/0
 
471
  the_vpc:
 
472
    Type: AWS::EC2::VPC
 
473
    Properties: {CidrBlock: '10.0.0.0/16'}
 
474
  the_subnet:
 
475
    Type: AWS::EC2::Subnet
 
476
    Properties:
 
477
      CidrBlock: 10.0.0.0/24
 
478
      VpcId: {Ref: the_vpc}
 
479
      AvailabilityZone: moon
 
480
  the_nic:
 
481
    Type: AWS::EC2::NetworkInterface
 
482
    Properties:
 
483
      PrivateIpAddress: 10.0.0.100
 
484
      SubnetId: {Ref: the_subnet}
 
485
      GroupSet:
 
486
      - Ref: INVALID-REF-IN-TEMPLATE
 
487
'''
 
488
 
 
489
    test_template_error_no_ref = '''
 
490
HeatTemplateFormatVersion: '2012-12-12'
 
491
Resources:
 
492
  the_vpc:
 
493
    Type: AWS::EC2::VPC
 
494
    Properties: {CidrBlock: '10.0.0.0/16'}
 
495
  the_subnet:
 
496
    Type: AWS::EC2::Subnet
 
497
    Properties:
 
498
      CidrBlock: 10.0.0.0/24
 
499
      VpcId: {Ref: the_vpc}
 
500
      AvailabilityZone: moon
 
501
  the_nic:
 
502
    Type: AWS::EC2::NetworkInterface
 
503
    Properties:
 
504
      PrivateIpAddress: 10.0.0.100
 
505
      SubnetId: {Ref: the_subnet}
 
506
      GroupSet:
 
507
      - INVALID-NO-REF
 
508
'''
 
509
 
 
510
    def mock_create_network_interface(self, security_groups=['eeee']):
 
511
        self.nic_name = utils.PhysName('test_stack', 'the_nic')
 
512
        port = {'network_id': 'aaaa',
 
513
                'fixed_ips': [{
 
514
                    'subnet_id': u'cccc',
 
515
                    'ip_address': u'10.0.0.100'
 
516
                }],
 
517
                'name': self.nic_name,
 
518
                'admin_state_up': True}
 
519
        if security_groups:
 
520
                port['security_groups'] = security_groups
 
521
 
 
522
        quantumclient.Client.create_port({'port': port}).AndReturn({
 
523
            'port': {
 
524
                'admin_state_up': True,
 
525
                'device_id': '',
 
526
                'device_owner': '',
 
527
                'fixed_ips': [
 
528
                    {
 
529
                        'ip_address': '10.0.0.100',
 
530
                        'subnet_id': 'cccc'
 
531
                    }
 
532
                ],
 
533
                'id': 'dddd',
 
534
                'mac_address': 'fa:16:3e:25:32:5d',
 
535
                'name': self.nic_name,
 
536
                'network_id': 'aaaa',
 
537
                'status': 'ACTIVE',
 
538
                'tenant_id': 'c1210485b2424d48804aad5d39c61b8f'
 
539
            }
 
540
        })
 
541
 
 
542
    def mock_delete_network_interface(self):
 
543
        quantumclient.Client.delete_port('dddd').AndReturn(None)
 
544
 
 
545
    def test_network_interface(self):
 
546
        self.mock_create_security_group()
 
547
        self.mock_create_network()
 
548
        self.mock_create_subnet()
 
549
        self.mock_show_subnet()
 
550
        self.mock_create_network_interface()
 
551
        self.mock_delete_network_interface()
 
552
        self.mock_delete_subnet()
 
553
        self.mock_delete_network()
 
554
        self.mock_delete_security_group()
 
555
 
 
556
        self.m.ReplayAll()
 
557
 
 
558
        stack = self.create_stack(self.test_template)
 
559
        try:
 
560
            self.assertEqual((stack.CREATE, stack.COMPLETE), stack.state)
 
561
            rsrc = stack['the_nic']
 
562
            self.assertResourceState(rsrc, 'dddd')
 
563
 
 
564
            self.assertRaises(resource.UpdateReplace,
 
565
                              rsrc.handle_update, {}, {}, {})
 
566
 
 
567
        finally:
 
568
            stack.delete()
 
569
 
 
570
        self.m.VerifyAll()
 
571
 
 
572
    def test_network_interface_no_groupset(self):
 
573
        self.mock_create_network()
 
574
        self.mock_create_subnet()
 
575
        self.mock_show_subnet()
 
576
        self.mock_create_network_interface(security_groups=None)
 
577
        self.mock_delete_network_interface()
 
578
        self.mock_delete_subnet()
 
579
        self.mock_delete_network()
 
580
 
 
581
        self.m.ReplayAll()
 
582
 
 
583
        stack = self.create_stack(self.test_template_no_groupset)
 
584
        stack.delete()
 
585
 
 
586
        self.m.VerifyAll()
 
587
 
 
588
    def test_network_interface_error(self):
 
589
        real_exception = self.assertRaises(
 
590
            exception.InvalidTemplateReference,
 
591
            self.create_stack,
 
592
            self.test_template_error)
 
593
        expected_exception = exception.InvalidTemplateReference(
 
594
            resource='INVALID-REF-IN-TEMPLATE',
 
595
            key='GroupSet')
 
596
 
 
597
        self.assertEquals(str(expected_exception), str(real_exception))
 
598
 
 
599
    def test_network_interface_error_no_ref(self):
 
600
        self.mock_create_network()
 
601
        self.mock_create_subnet()
 
602
        self.mock_show_subnet()
 
603
        self.mock_delete_subnet()
 
604
        self.mock_delete_network()
 
605
 
 
606
        self.m.ReplayAll()
 
607
 
 
608
        stack = self.create_stack(self.test_template_error_no_ref)
 
609
        try:
 
610
            self.assertEqual((stack.CREATE, stack.FAILED), stack.state)
 
611
            rsrc = stack['the_nic']
 
612
            self.assertEqual((rsrc.CREATE, rsrc.FAILED), rsrc.state)
 
613
            reason = rsrc.status_reason
 
614
            self.assertTrue(reason.startswith('InvalidTemplateAttribute:'))
 
615
        finally:
 
616
            stack.delete()
 
617
 
 
618
        self.m.VerifyAll()
 
619
 
 
620
 
 
621
class InternetGatewayTest(VPCTestBase):
 
622
 
 
623
    test_template = '''
 
624
HeatTemplateFormatVersion: '2012-12-12'
 
625
Resources:
 
626
  the_gateway:
 
627
    Type: AWS::EC2::InternetGateway
 
628
  the_vpc:
 
629
    Type: AWS::EC2::VPC
 
630
    Properties:
 
631
      CidrBlock: '10.0.0.0/16'
 
632
  the_subnet:
 
633
    Type: AWS::EC2::Subnet
 
634
    Properties:
 
635
      CidrBlock: 10.0.0.0/24
 
636
      VpcId: {Ref: the_vpc}
 
637
      AvailabilityZone: moon
 
638
  the_attachment:
 
639
    Type: AWS::EC2::VPCGatewayAttachment
 
640
    Properties:
 
641
      VpcId: {Ref: the_vpc}
 
642
      InternetGatewayId: {Ref: the_gateway}
 
643
  the_route_table:
 
644
    Type: AWS::EC2::RouteTable
 
645
    Properties:
 
646
      VpcId: {Ref: the_vpc}
 
647
  the_association:
 
648
    Type: AWS::EC2::SubnetRouteTableAssocation
 
649
    Properties:
 
650
      RouteTableId: {Ref: the_route_table}
 
651
      SubnetId: {Ref: the_subnet}
 
652
'''
 
653
 
 
654
    def mock_create_internet_gateway(self):
 
655
        quantumclient.Client.list_networks(
 
656
            **{'router:external': True}).AndReturn({'networks': [{
 
657
                'status': 'ACTIVE',
 
658
                'subnets': [],
 
659
                'name': 'nova',
 
660
                'router:external': True,
 
661
                'tenant_id': 'c1210485b2424d48804aad5d39c61b8f',
 
662
                'admin_state_up': True,
 
663
                'shared': True,
 
664
                'id': 'eeee'
 
665
            }]})
 
666
 
 
667
    def mock_create_gateway_attachment(self):
 
668
        quantumclient.Client.add_gateway_router(
 
669
            'ffff', {'network_id': 'eeee'}).AndReturn(None)
 
670
 
 
671
    def mock_delete_gateway_attachment(self):
 
672
        quantumclient.Client.remove_gateway_router('ffff').AndReturn(None)
 
673
 
 
674
    def test_internet_gateway(self):
 
675
        self.mock_create_internet_gateway()
 
676
        self.mock_create_network()
 
677
        self.mock_create_subnet()
 
678
        self.mock_create_route_table()
 
679
        self.mock_create_association()
 
680
        self.mock_create_gateway_attachment()
 
681
        self.mock_delete_gateway_attachment()
 
682
        self.mock_delete_association()
 
683
        self.mock_delete_route_table()
 
684
        self.mock_delete_subnet()
 
685
        self.mock_delete_network()
 
686
 
 
687
        self.m.ReplayAll()
 
688
 
 
689
        stack = self.create_stack(self.test_template)
 
690
 
 
691
        gateway = stack['the_gateway']
 
692
        self.assertResourceState(gateway, gateway.physical_resource_name())
 
693
        self.assertRaises(resource.UpdateReplace, gateway.handle_update,
 
694
                          {}, {}, {})
 
695
 
 
696
        attachment = stack['the_attachment']
 
697
        self.assertResourceState(attachment, 'the_attachment')
 
698
        self.assertRaises(resource.UpdateReplace,
 
699
                          attachment.handle_update, {}, {}, {})
 
700
 
 
701
        route_table = stack['the_route_table']
 
702
        self.assertEqual([route_table], list(attachment._vpc_route_tables()))
 
703
 
 
704
        stack.delete()
 
705
        self.m.VerifyAll()
 
706
 
 
707
 
 
708
class RouteTableTest(VPCTestBase):
 
709
 
 
710
    test_template = '''
 
711
HeatTemplateFormatVersion: '2012-12-12'
 
712
Resources:
 
713
  the_vpc:
 
714
    Type: AWS::EC2::VPC
 
715
    Properties:
 
716
      CidrBlock: '10.0.0.0/16'
 
717
  the_subnet:
 
718
    Type: AWS::EC2::Subnet
 
719
    Properties:
 
720
      CidrBlock: 10.0.0.0/24
 
721
      VpcId: {Ref: the_vpc}
 
722
      AvailabilityZone: moon
 
723
  the_route_table:
 
724
    Type: AWS::EC2::RouteTable
 
725
    Properties:
 
726
      VpcId: {Ref: the_vpc}
 
727
  the_association:
 
728
    Type: AWS::EC2::SubnetRouteTableAssocation
 
729
    Properties:
 
730
      RouteTableId: {Ref: the_route_table}
 
731
      SubnetId: {Ref: the_subnet}
 
732
'''
 
733
 
 
734
    def test_route_table(self):
 
735
        self.mock_create_network()
 
736
        self.mock_create_subnet()
 
737
        self.mock_create_route_table()
 
738
        self.mock_create_association()
 
739
        self.mock_delete_association()
 
740
        self.mock_delete_route_table()
 
741
        self.mock_delete_subnet()
 
742
        self.mock_delete_network()
 
743
 
 
744
        self.m.ReplayAll()
 
745
 
 
746
        stack = self.create_stack(self.test_template)
 
747
 
 
748
        route_table = stack['the_route_table']
 
749
        self.assertResourceState(route_table, 'ffff')
 
750
        self.assertRaises(
 
751
            resource.UpdateReplace,
 
752
            route_table.handle_update, {}, {}, {})
 
753
 
 
754
        association = stack['the_association']
 
755
        self.assertResourceState(association, 'the_association')
 
756
        self.assertRaises(
 
757
            resource.UpdateReplace,
 
758
            association.handle_update, {}, {}, {})
 
759
 
 
760
        association.delete()
 
761
        route_table.delete()
 
762
 
 
763
        stack.delete()
 
764
        self.m.VerifyAll()