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

« back to all changes in this revision

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

  • Committer: Package Import Robot
  • Author(s): James Page, Chuck Short, James Page
  • Date: 2013-08-08 15:23:59 UTC
  • mfrom: (1.1.3)
  • Revision ID: package-import@ubuntu.com-20130808152359-9jgqjp23kssvc3x9
Tags: 2013.2~b2.a186.g2b4b248-0ubuntu1
[ Chuck Short ]
* debian/patches/rename-quantumclient.patch: Dropped no longer needed. 
* debian/control: Add python-oslo.sphinx

[ James Page ]
* New upstream snapshot.
* d/watch: Updated to track releases on launchpad.
* d/control: Drop BD in pep8, no longer required.
* d/control,rules: Drop use of openstack-pkg-tools, revert use of xz
  compression for debs.
* d/control,*.config,*.templates,po: Drop use of debconf/dbconfig-common
  to configure heat.
* d/*.upstart: Add upstart configurations for Ubuntu.
* d/p/default-kombu.patch: Switch default messaging from qpid to
  kombu.
* d/p/default-sqlite.patch: Use sqlite as default database option.
* d/control: Add python-ceilometerclient to BD's.
* d/rules: Fail package build for unit test failures.
* d/*.install: Directly install configuration files to /etc/heat.
* d/control: Update VCS locations to ubuntu-server-dev branches.
* d/heat-common.{install,manpages}: Include new binaries and associated
  manpages.

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
 
 
16
 
from testtools import skipIf
17
 
 
18
 
from heat.common import exception
19
 
from heat.common import template_format
20
 
from heat.engine import properties
21
 
from heat.engine import resource
22
 
from heat.engine import scheduler
23
 
from heat.engine.resources.quantum import net
24
 
from heat.engine.resources.quantum import subnet
25
 
from heat.engine.resources.quantum import router
26
 
from heat.engine.resources.quantum.quantum import QuantumResource as qr
27
 
from heat.openstack.common.importutils import try_import
28
 
from heat.tests.common import HeatTestCase
29
 
from heat.tests import utils
30
 
from heat.tests.utils import setup_dummy_db
31
 
from heat.tests.utils import parse_stack
32
 
 
33
 
quantumclient = try_import('quantumclient.v2_0.client')
34
 
qe = try_import('quantumclient.common.exceptions')
35
 
 
36
 
quantum_template = '''
37
 
{
38
 
  "AWSTemplateFormatVersion" : "2010-09-09",
39
 
  "Description" : "Template to test Quantum resources",
40
 
  "Parameters" : {},
41
 
  "Resources" : {
42
 
    "network": {
43
 
      "Type": "OS::Quantum::Net",
44
 
      "Properties": {
45
 
        "name": "the_network"
46
 
      }
47
 
    },
48
 
    "unnamed_network": {
49
 
      "Type": "OS::Quantum::Net"
50
 
    },
51
 
    "admin_down_network": {
52
 
      "Type": "OS::Quantum::Net",
53
 
      "Properties": {
54
 
        "admin_state_up": false
55
 
      }
56
 
    },
57
 
    "subnet": {
58
 
      "Type": "OS::Quantum::Subnet",
59
 
      "Properties": {
60
 
        "network_id": { "Ref" : "network" },
61
 
        "ip_version": 4,
62
 
        "cidr": "10.0.3.0/24",
63
 
        "allocation_pools": [{"start": "10.0.3.20", "end": "10.0.3.150"}],
64
 
        "dns_nameservers": ["8.8.8.8"]
65
 
      }
66
 
    },
67
 
    "port": {
68
 
      "Type": "OS::Quantum::Port",
69
 
      "Properties": {
70
 
        "device_id": "d6b4d3a5-c700-476f-b609-1493dd9dadc0",
71
 
        "name": "port1",
72
 
        "network_id": { "Ref" : "network" },
73
 
        "fixed_ips": [{
74
 
          "subnet_id": { "Ref" : "subnet" },
75
 
          "ip_address": "10.0.3.21"
76
 
        }]
77
 
      }
78
 
    },
79
 
    "port2": {
80
 
      "Type": "OS::Quantum::Port",
81
 
      "Properties": {
82
 
        "name": "port2",
83
 
        "network_id": { "Ref" : "network" }
84
 
      }
85
 
    },
86
 
    "router": {
87
 
      "Type": "OS::Quantum::Router"
88
 
    },
89
 
    "router_interface": {
90
 
      "Type": "OS::Quantum::RouterInterface",
91
 
      "Properties": {
92
 
        "router_id": { "Ref" : "router" },
93
 
        "subnet_id": { "Ref" : "subnet" }
94
 
      }
95
 
    },
96
 
    "gateway": {
97
 
      "Type": "OS::Quantum::RouterGateway",
98
 
      "Properties": {
99
 
        "router_id": { "Ref" : "router" },
100
 
        "network_id": { "Ref" : "network" }
101
 
      }
102
 
    }
103
 
  }
104
 
}
105
 
'''
106
 
 
107
 
quantum_floating_template = '''
108
 
{
109
 
  "AWSTemplateFormatVersion" : "2010-09-09",
110
 
  "Description" : "Template to test Quantum resources",
111
 
  "Parameters" : {},
112
 
  "Resources" : {
113
 
    "port_floating": {
114
 
      "Type": "OS::Quantum::Port",
115
 
      "Properties": {
116
 
        "network_id": "xyz1234",
117
 
        "fixed_ips": [{
118
 
          "subnet_id": "12.12.12.0",
119
 
          "ip_address": "10.0.0.10"
120
 
        }]
121
 
      }
122
 
    },
123
 
    "floating_ip": {
124
 
      "Type": "OS::Quantum::FloatingIP",
125
 
      "Properties": {
126
 
        "floating_network_id": "abcd1234",
127
 
      }
128
 
    },
129
 
    "floating_ip_assoc": {
130
 
      "Type": "OS::Quantum::FloatingIPAssociation",
131
 
      "Properties": {
132
 
        "floatingip_id": { "Ref" : "floating_ip" },
133
 
        "port_id": { "Ref" : "port_floating" }
134
 
      }
135
 
    },
136
 
    "router": {
137
 
      "Type": "OS::Quantum::Router"
138
 
    },
139
 
    "gateway": {
140
 
      "Type": "OS::Quantum::RouterGateway",
141
 
      "Properties": {
142
 
        "router_id": { "Ref" : "router" },
143
 
        "network_id": "abcd1234"
144
 
      }
145
 
    }
146
 
  }
147
 
}
148
 
'''
149
 
 
150
 
 
151
 
class QuantumTest(HeatTestCase):
152
 
 
153
 
    def test_validate_properties(self):
154
 
        vs = {'router:external': True}
155
 
        data = {'admin_state_up': False,
156
 
                'value_specs': vs}
157
 
        p = properties.Properties(net.Net.properties_schema, data)
158
 
        self.assertEqual(None, qr.validate_properties(p))
159
 
 
160
 
        vs['shared'] = True
161
 
        self.assertEqual('shared not allowed in value_specs',
162
 
                         qr.validate_properties(p))
163
 
        vs.pop('shared')
164
 
 
165
 
        vs['name'] = 'foo'
166
 
        self.assertEqual('name not allowed in value_specs',
167
 
                         qr.validate_properties(p))
168
 
        vs.pop('name')
169
 
 
170
 
        vs['tenant_id'] = '1234'
171
 
        self.assertEqual('tenant_id not allowed in value_specs',
172
 
                         qr.validate_properties(p))
173
 
        vs.pop('tenant_id')
174
 
 
175
 
        vs['foo'] = '1234'
176
 
        self.assertEqual(None, qr.validate_properties(p))
177
 
 
178
 
    def test_prepare_properties(self):
179
 
        data = {'admin_state_up': False,
180
 
                'value_specs': {'router:external': True}}
181
 
        p = properties.Properties(net.Net.properties_schema, data)
182
 
        props = qr.prepare_properties(p, 'resource_name')
183
 
        self.assertEqual({'name': 'resource_name',
184
 
                          'router:external': True,
185
 
                          'admin_state_up': False}, props)
186
 
 
187
 
    def test_is_built(self):
188
 
        self.assertTrue(qr.is_built({
189
 
            'name': 'the_net',
190
 
            'status': 'ACTIVE'
191
 
        }))
192
 
        self.assertTrue(qr.is_built({
193
 
            'name': 'the_net',
194
 
            'status': 'DOWN'
195
 
        }))
196
 
        self.assertFalse(qr.is_built({
197
 
            'name': 'the_net',
198
 
            'status': 'BUILD'
199
 
        }))
200
 
        self.assertRaises(exception.Error, qr.is_built, {
201
 
            'name': 'the_net',
202
 
            'status': 'FROBULATING'
203
 
        })
204
 
 
205
 
 
206
 
@skipIf(quantumclient is None, 'quantumclient unavailable')
207
 
class QuantumNetTest(HeatTestCase):
208
 
 
209
 
    def setUp(self):
210
 
        super(QuantumNetTest, self).setUp()
211
 
        self.m.StubOutWithMock(quantumclient.Client, 'create_network')
212
 
        self.m.StubOutWithMock(quantumclient.Client, 'delete_network')
213
 
        self.m.StubOutWithMock(quantumclient.Client, 'show_network')
214
 
        setup_dummy_db()
215
 
 
216
 
    def create_net(self, t, stack, resource_name):
217
 
        rsrc = net.Net('test_net', t['Resources'][resource_name], stack)
218
 
        scheduler.TaskRunner(rsrc.create)()
219
 
        self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
220
 
        return rsrc
221
 
 
222
 
    def test_net(self):
223
 
        quantumclient.Client.create_network({
224
 
            'network': {'name': u'the_network', 'admin_state_up': True}
225
 
        }).AndReturn({"network": {
226
 
            "status": "BUILD",
227
 
            "subnets": [],
228
 
            "name": "name",
229
 
            "admin_state_up": False,
230
 
            "shared": False,
231
 
            "tenant_id": "c1210485b2424d48804aad5d39c61b8f",
232
 
            "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
233
 
        }})
234
 
 
235
 
        quantumclient.Client.show_network(
236
 
            'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
237
 
        ).AndReturn({"network": {
238
 
            "status": "BUILD",
239
 
            "subnets": [],
240
 
            "name": "name",
241
 
            "admin_state_up": False,
242
 
            "shared": False,
243
 
            "tenant_id": "c1210485b2424d48804aad5d39c61b8f",
244
 
            "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
245
 
        }})
246
 
 
247
 
        quantumclient.Client.show_network(
248
 
            'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
249
 
        ).AndReturn({"network": {
250
 
            "status": "ACTIVE",
251
 
            "subnets": [],
252
 
            "name": "name",
253
 
            "admin_state_up": False,
254
 
            "shared": False,
255
 
            "tenant_id": "c1210485b2424d48804aad5d39c61b8f",
256
 
            "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
257
 
        }})
258
 
 
259
 
        quantumclient.Client.show_network(
260
 
            'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
261
 
        ).AndRaise(qe.QuantumClientException(status_code=404))
262
 
 
263
 
        quantumclient.Client.show_network(
264
 
            'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
265
 
        ).AndReturn({"network": {
266
 
            "status": "ACTIVE",
267
 
            "subnets": [],
268
 
            "name": "name",
269
 
            "admin_state_up": False,
270
 
            "shared": False,
271
 
            "tenant_id": "c1210485b2424d48804aad5d39c61b8f",
272
 
            "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
273
 
        }})
274
 
 
275
 
        quantumclient.Client.show_network(
276
 
            'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
277
 
        ).AndReturn({"network": {
278
 
            "status": "ACTIVE",
279
 
            "subnets": [],
280
 
            "name": "name",
281
 
            "admin_state_up": False,
282
 
            "shared": False,
283
 
            "tenant_id": "c1210485b2424d48804aad5d39c61b8f",
284
 
            "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
285
 
        }})
286
 
 
287
 
        quantumclient.Client.delete_network(
288
 
            'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
289
 
        ).AndReturn(None)
290
 
 
291
 
        quantumclient.Client.show_network(
292
 
            'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
293
 
        ).AndRaise(qe.QuantumClientException(status_code=404))
294
 
 
295
 
        quantumclient.Client.delete_network(
296
 
            'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
297
 
        ).AndRaise(qe.QuantumClientException(status_code=404))
298
 
 
299
 
        self.m.ReplayAll()
300
 
        t = template_format.parse(quantum_template)
301
 
        stack = parse_stack(t)
302
 
        rsrc = self.create_net(t, stack, 'network')
303
 
 
304
 
        # assert the implicit dependency between the gateway and the interface
305
 
        deps = stack.dependencies[stack['router_interface']]
306
 
        self.assertIn(stack['gateway'], deps)
307
 
 
308
 
        # assert the implicit dependency between the gateway and the subnet
309
 
        deps = stack.dependencies[stack['subnet']]
310
 
        self.assertIn(stack['gateway'], deps)
311
 
 
312
 
        rsrc.validate()
313
 
 
314
 
        ref_id = rsrc.FnGetRefId()
315
 
        self.assertEqual('fc68ea2c-b60b-4b4f-bd82-94ec81110766', ref_id)
316
 
 
317
 
        self.assertEqual(None, rsrc.FnGetAtt('status'))
318
 
        self.assertEqual('ACTIVE', rsrc.FnGetAtt('status'))
319
 
        try:
320
 
            rsrc.FnGetAtt('Foo')
321
 
            raise Exception('Expected InvalidTemplateAttribute')
322
 
        except exception.InvalidTemplateAttribute:
323
 
            pass
324
 
 
325
 
        self.assertEqual('fc68ea2c-b60b-4b4f-bd82-94ec81110766',
326
 
                         rsrc.FnGetAtt('id'))
327
 
 
328
 
        self.assertRaises(resource.UpdateReplace,
329
 
                          rsrc.handle_update, {}, {}, {})
330
 
 
331
 
        scheduler.TaskRunner(rsrc.delete)()
332
 
        rsrc.state_set(rsrc.CREATE, rsrc.COMPLETE, 'to delete again')
333
 
        scheduler.TaskRunner(rsrc.delete)()
334
 
        self.m.VerifyAll()
335
 
 
336
 
 
337
 
@skipIf(quantumclient is None, 'quantumclient unavailable')
338
 
class QuantumSubnetTest(HeatTestCase):
339
 
 
340
 
    def setUp(self):
341
 
        super(QuantumSubnetTest, self).setUp()
342
 
        self.m.StubOutWithMock(quantumclient.Client, 'create_subnet')
343
 
        self.m.StubOutWithMock(quantumclient.Client, 'delete_subnet')
344
 
        self.m.StubOutWithMock(quantumclient.Client, 'show_subnet')
345
 
        setup_dummy_db()
346
 
 
347
 
    def create_subnet(self, t, stack, resource_name):
348
 
        rsrc = subnet.Subnet('test_subnet', t['Resources'][resource_name],
349
 
                             stack)
350
 
        scheduler.TaskRunner(rsrc.create)()
351
 
        self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
352
 
        return rsrc
353
 
 
354
 
    def test_subnet(self):
355
 
 
356
 
        quantumclient.Client.create_subnet({
357
 
            'subnet': {
358
 
                'name': utils.PhysName('test_stack', 'test_subnet'),
359
 
                'network_id': u'None',
360
 
                'dns_nameservers': [u'8.8.8.8'],
361
 
                'allocation_pools': [
362
 
                    {'start': u'10.0.3.20', 'end': u'10.0.3.150'}],
363
 
                'ip_version': 4,
364
 
                'cidr': u'10.0.3.0/24'
365
 
            }
366
 
        }).AndReturn({
367
 
            "subnet": {
368
 
                "allocation_pools": [
369
 
                    {"start": "10.0.3.20", "end": "10.0.3.150"}],
370
 
                "cidr": "10.0.3.0/24",
371
 
                "dns_nameservers": ["8.8.8.8"],
372
 
                "enable_dhcp": True,
373
 
                "gateway_ip": "10.0.3.1",
374
 
                "id": "91e47a57-7508-46fe-afc9-fc454e8580e1",
375
 
                "ip_version": 4,
376
 
                "name": "name",
377
 
                "network_id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766",
378
 
                "tenant_id": "c1210485b2424d48804aad5d39c61b8f"
379
 
            }
380
 
        })
381
 
        quantumclient.Client.show_subnet(
382
 
            '91e47a57-7508-46fe-afc9-fc454e8580e1').AndRaise(
383
 
                qe.QuantumClientException(status_code=404))
384
 
        sn = {
385
 
            "subnet": {
386
 
                "name": "name",
387
 
                "network_id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766",
388
 
                "tenant_id": "c1210485b2424d48804aad5d39c61b8f",
389
 
                "allocation_pools": [
390
 
                    {"start": "10.0.3.20", "end": "10.0.3.150"}],
391
 
                "gateway_ip": "10.0.3.1",
392
 
                "ip_version": 4,
393
 
                "cidr": "10.0.3.0/24",
394
 
                "dns_nameservers": ["8.8.8.8"],
395
 
                "id": "91e47a57-7508-46fe-afc9-fc454e8580e1",
396
 
                "enable_dhcp": True,
397
 
            }
398
 
        }
399
 
        quantumclient.Client.show_subnet(
400
 
            '91e47a57-7508-46fe-afc9-fc454e8580e1').AndReturn(sn)
401
 
        quantumclient.Client.show_subnet(
402
 
            '91e47a57-7508-46fe-afc9-fc454e8580e1').AndReturn(sn)
403
 
        quantumclient.Client.show_subnet(
404
 
            '91e47a57-7508-46fe-afc9-fc454e8580e1').AndReturn(sn)
405
 
 
406
 
        quantumclient.Client.delete_subnet(
407
 
            '91e47a57-7508-46fe-afc9-fc454e8580e1'
408
 
        ).AndReturn(None)
409
 
 
410
 
        quantumclient.Client.show_subnet(
411
 
            '91e47a57-7508-46fe-afc9-fc454e8580e1'
412
 
        ).AndRaise(qe.QuantumClientException(status_code=404))
413
 
 
414
 
        quantumclient.Client.delete_subnet(
415
 
            '91e47a57-7508-46fe-afc9-fc454e8580e1'
416
 
        ).AndRaise(qe.QuantumClientException(status_code=404))
417
 
 
418
 
        self.m.ReplayAll()
419
 
        t = template_format.parse(quantum_template)
420
 
        stack = parse_stack(t)
421
 
        rsrc = self.create_subnet(t, stack, 'subnet')
422
 
 
423
 
        rsrc.validate()
424
 
 
425
 
        ref_id = rsrc.FnGetRefId()
426
 
        self.assertEqual('91e47a57-7508-46fe-afc9-fc454e8580e1', ref_id)
427
 
        self.assertEqual(None,
428
 
                         rsrc.FnGetAtt('network_id'))
429
 
        self.assertEqual('fc68ea2c-b60b-4b4f-bd82-94ec81110766',
430
 
                         rsrc.FnGetAtt('network_id'))
431
 
        self.assertEqual('8.8.8.8', rsrc.FnGetAtt('dns_nameservers')[0])
432
 
        self.assertEqual('91e47a57-7508-46fe-afc9-fc454e8580e1',
433
 
                         rsrc.FnGetAtt('id'))
434
 
 
435
 
        # assert the dependency (implicit or explicit) between the ports
436
 
        # and the subnet
437
 
        self.assertIn(stack['port'], stack.dependencies[stack['subnet']])
438
 
        self.assertIn(stack['port2'], stack.dependencies[stack['subnet']])
439
 
 
440
 
        self.assertRaises(resource.UpdateReplace,
441
 
                          rsrc.handle_update, {}, {}, {})
442
 
 
443
 
        self.assertEqual(scheduler.TaskRunner(rsrc.delete)(), None)
444
 
        rsrc.state_set(rsrc.CREATE, rsrc.COMPLETE, 'to delete again')
445
 
        self.assertEqual(scheduler.TaskRunner(rsrc.delete)(), None)
446
 
        self.m.VerifyAll()
447
 
 
448
 
    def test_subnet_disable_dhcp(self):
449
 
 
450
 
        quantumclient.Client.create_subnet({
451
 
            'subnet': {
452
 
                'name': utils.PhysName('test_stack', 'test_subnet'),
453
 
                'network_id': u'None',
454
 
                'dns_nameservers': [u'8.8.8.8'],
455
 
                'allocation_pools': [
456
 
                    {'start': u'10.0.3.20', 'end': u'10.0.3.150'}],
457
 
                'ip_version': 4,
458
 
                'enable_dhcp': False,
459
 
                'cidr': u'10.0.3.0/24'
460
 
            }
461
 
        }).AndReturn({
462
 
            "subnet": {
463
 
                "allocation_pools": [
464
 
                    {"start": "10.0.3.20", "end": "10.0.3.150"}],
465
 
                "cidr": "10.0.3.0/24",
466
 
                "dns_nameservers": ["8.8.8.8"],
467
 
                "enable_dhcp": False,
468
 
                "gateway_ip": "10.0.3.1",
469
 
                "id": "91e47a57-7508-46fe-afc9-fc454e8580e1",
470
 
                "ip_version": 4,
471
 
                "name": "name",
472
 
                "network_id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766",
473
 
                "tenant_id": "c1210485b2424d48804aad5d39c61b8f"
474
 
            }
475
 
        })
476
 
 
477
 
        quantumclient.Client.show_subnet(
478
 
            '91e47a57-7508-46fe-afc9-fc454e8580e1').AndReturn({
479
 
                "subnet": {
480
 
                    "name": "name",
481
 
                    "network_id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766",
482
 
                    "tenant_id": "c1210485b2424d48804aad5d39c61b8f",
483
 
                    "allocation_pools": [
484
 
                        {"start": "10.0.3.20", "end": "10.0.3.150"}],
485
 
                    "gateway_ip": "10.0.3.1",
486
 
                    "ip_version": 4,
487
 
                    "cidr": "10.0.3.0/24",
488
 
                    "dns_nameservers": ["8.8.8.8"],
489
 
                    "id": "91e47a57-7508-46fe-afc9-fc454e8580e1",
490
 
                    "enable_dhcp": False,
491
 
                }
492
 
            })
493
 
 
494
 
        quantumclient.Client.delete_subnet(
495
 
            '91e47a57-7508-46fe-afc9-fc454e8580e1'
496
 
        ).AndReturn(None)
497
 
 
498
 
        quantumclient.Client.show_subnet(
499
 
            '91e47a57-7508-46fe-afc9-fc454e8580e1'
500
 
        ).AndRaise(qe.QuantumClientException(status_code=404))
501
 
 
502
 
        self.m.ReplayAll()
503
 
        t = template_format.parse(quantum_template)
504
 
        t['Resources']['subnet']['Properties']['enable_dhcp'] = 'False'
505
 
        stack = parse_stack(t)
506
 
        rsrc = self.create_subnet(t, stack, 'subnet')
507
 
 
508
 
        rsrc.validate()
509
 
 
510
 
        ref_id = rsrc.FnGetRefId()
511
 
        self.assertEqual('91e47a57-7508-46fe-afc9-fc454e8580e1', ref_id)
512
 
        self.assertEqual(False, rsrc.FnGetAtt('enable_dhcp'))
513
 
        self.assertEqual(rsrc.delete(), None)
514
 
        self.m.VerifyAll()
515
 
 
516
 
 
517
 
@skipIf(quantumclient is None, 'quantumclient unavailable')
518
 
class QuantumRouterTest(HeatTestCase):
519
 
    def setUp(self):
520
 
        super(QuantumRouterTest, self).setUp()
521
 
        self.m.StubOutWithMock(quantumclient.Client, 'create_router')
522
 
        self.m.StubOutWithMock(quantumclient.Client, 'delete_router')
523
 
        self.m.StubOutWithMock(quantumclient.Client, 'show_router')
524
 
        self.m.StubOutWithMock(quantumclient.Client, 'add_interface_router')
525
 
        self.m.StubOutWithMock(quantumclient.Client, 'remove_interface_router')
526
 
        self.m.StubOutWithMock(quantumclient.Client, 'add_gateway_router')
527
 
        self.m.StubOutWithMock(quantumclient.Client, 'remove_gateway_router')
528
 
        setup_dummy_db()
529
 
 
530
 
    def create_router(self, t, stack, resource_name):
531
 
        rsrc = router.Router('router', t['Resources'][resource_name], stack)
532
 
        scheduler.TaskRunner(rsrc.create)()
533
 
        self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
534
 
        return rsrc
535
 
 
536
 
    def create_router_interface(self, t, stack, resource_name, properties={}):
537
 
        t['Resources'][resource_name]['Properties'] = properties
538
 
        rsrc = router.RouterInterface(
539
 
            'router_interface',
540
 
            t['Resources'][resource_name],
541
 
            stack)
542
 
        scheduler.TaskRunner(rsrc.create)()
543
 
        self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
544
 
        return rsrc
545
 
 
546
 
    def create_gateway_router(self, t, stack, resource_name, properties={}):
547
 
        t['Resources'][resource_name]['Properties'] = properties
548
 
        rsrc = router.RouterGateway(
549
 
            'gateway',
550
 
            t['Resources'][resource_name],
551
 
            stack)
552
 
        scheduler.TaskRunner(rsrc.create)()
553
 
        self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
554
 
        return rsrc
555
 
 
556
 
    def test_router(self):
557
 
        quantumclient.Client.create_router({
558
 
            'router': {
559
 
                'name': utils.PhysName('test_stack', 'router'),
560
 
                'admin_state_up': True,
561
 
            }
562
 
        }).AndReturn({
563
 
            "router": {
564
 
                "status": "BUILD",
565
 
                "external_gateway_info": None,
566
 
                "name": utils.PhysName('test_stack', 'router'),
567
 
                "admin_state_up": True,
568
 
                "tenant_id": "3e21026f2dc94372b105808c0e721661",
569
 
                "id": "3e46229d-8fce-4733-819a-b5fe630550f8"
570
 
            }
571
 
        })
572
 
        quantumclient.Client.show_router(
573
 
            '3e46229d-8fce-4733-819a-b5fe630550f8').AndReturn({
574
 
                "router": {
575
 
                    "status": "BUILD",
576
 
                    "external_gateway_info": None,
577
 
                    "name": utils.PhysName('test_stack', 'router'),
578
 
                    "admin_state_up": True,
579
 
                    "tenant_id": "3e21026f2dc94372b105808c0e721661",
580
 
                    "routes": [],
581
 
                    "id": "3e46229d-8fce-4733-819a-b5fe630550f8"
582
 
                }
583
 
            })
584
 
        quantumclient.Client.show_router(
585
 
            '3e46229d-8fce-4733-819a-b5fe630550f8').AndReturn({
586
 
                "router": {
587
 
                    "status": "ACTIVE",
588
 
                    "external_gateway_info": None,
589
 
                    "name": utils.PhysName('test_stack', 'router'),
590
 
                    "admin_state_up": True,
591
 
                    "tenant_id": "3e21026f2dc94372b105808c0e721661",
592
 
                    "routes": [],
593
 
                    "id": "3e46229d-8fce-4733-819a-b5fe630550f8"
594
 
                }
595
 
            })
596
 
 
597
 
        quantumclient.Client.show_router(
598
 
            '3e46229d-8fce-4733-819a-b5fe630550f8').AndRaise(
599
 
                qe.QuantumClientException(status_code=404))
600
 
        quantumclient.Client.show_router(
601
 
            '3e46229d-8fce-4733-819a-b5fe630550f8').AndReturn({
602
 
                "router": {
603
 
                    "status": "ACTIVE",
604
 
                    "external_gateway_info": None,
605
 
                    "name": utils.PhysName('test_stack', 'router'),
606
 
                    "admin_state_up": True,
607
 
                    "tenant_id": "3e21026f2dc94372b105808c0e721661",
608
 
                    "routes": [],
609
 
                    "id": "3e46229d-8fce-4733-819a-b5fe630550f8"
610
 
                }
611
 
            })
612
 
        quantumclient.Client.show_router(
613
 
            '3e46229d-8fce-4733-819a-b5fe630550f8').AndReturn({
614
 
                "router": {
615
 
                    "status": "ACTIVE",
616
 
                    "external_gateway_info": None,
617
 
                    "name": utils.PhysName('test_stack', 'router'),
618
 
                    "admin_state_up": True,
619
 
                    "tenant_id": "3e21026f2dc94372b105808c0e721661",
620
 
                    "routes": [],
621
 
                    "id": "3e46229d-8fce-4733-819a-b5fe630550f8"
622
 
                }
623
 
            })
624
 
 
625
 
        quantumclient.Client.delete_router(
626
 
            '3e46229d-8fce-4733-819a-b5fe630550f8'
627
 
        ).AndReturn(None)
628
 
 
629
 
        quantumclient.Client.show_router(
630
 
            '3e46229d-8fce-4733-819a-b5fe630550f8'
631
 
        ).AndRaise(qe.QuantumClientException(status_code=404))
632
 
 
633
 
        quantumclient.Client.delete_router(
634
 
            '3e46229d-8fce-4733-819a-b5fe630550f8'
635
 
        ).AndRaise(qe.QuantumClientException(status_code=404))
636
 
 
637
 
        self.m.ReplayAll()
638
 
        t = template_format.parse(quantum_template)
639
 
        stack = parse_stack(t)
640
 
        rsrc = self.create_router(t, stack, 'router')
641
 
 
642
 
        rsrc.validate()
643
 
 
644
 
        ref_id = rsrc.FnGetRefId()
645
 
        self.assertEqual('3e46229d-8fce-4733-819a-b5fe630550f8', ref_id)
646
 
        self.assertEqual(None,
647
 
                         rsrc.FnGetAtt('tenant_id'))
648
 
        self.assertEqual('3e21026f2dc94372b105808c0e721661',
649
 
                         rsrc.FnGetAtt('tenant_id'))
650
 
        self.assertEqual('3e46229d-8fce-4733-819a-b5fe630550f8',
651
 
                         rsrc.FnGetAtt('id'))
652
 
 
653
 
        self.assertRaises(resource.UpdateReplace,
654
 
                          rsrc.handle_update, {}, {}, {})
655
 
 
656
 
        self.assertEqual(scheduler.TaskRunner(rsrc.delete)(), None)
657
 
        rsrc.state_set(rsrc.CREATE, rsrc.COMPLETE, 'to delete again')
658
 
        self.assertEqual(scheduler.TaskRunner(rsrc.delete)(), None)
659
 
        self.m.VerifyAll()
660
 
 
661
 
    def test_router_interface(self):
662
 
        quantumclient.Client.add_interface_router(
663
 
            '3e46229d-8fce-4733-819a-b5fe630550f8',
664
 
            {'subnet_id': '91e47a57-7508-46fe-afc9-fc454e8580e1'}
665
 
        ).AndReturn(None)
666
 
        quantumclient.Client.remove_interface_router(
667
 
            '3e46229d-8fce-4733-819a-b5fe630550f8',
668
 
            {'subnet_id': '91e47a57-7508-46fe-afc9-fc454e8580e1'}
669
 
        ).AndReturn(None)
670
 
        quantumclient.Client.remove_interface_router(
671
 
            '3e46229d-8fce-4733-819a-b5fe630550f8',
672
 
            {'subnet_id': '91e47a57-7508-46fe-afc9-fc454e8580e1'}
673
 
        ).AndRaise(qe.QuantumClientException(status_code=404))
674
 
        self.m.ReplayAll()
675
 
        t = template_format.parse(quantum_template)
676
 
        stack = parse_stack(t)
677
 
 
678
 
        rsrc = self.create_router_interface(
679
 
            t, stack, 'router_interface', properties={
680
 
                'router_id': '3e46229d-8fce-4733-819a-b5fe630550f8',
681
 
                'subnet_id': '91e47a57-7508-46fe-afc9-fc454e8580e1'
682
 
            })
683
 
 
684
 
        self.assertEqual(rsrc.delete(), None)
685
 
        rsrc.state_set(rsrc.CREATE, rsrc.COMPLETE, 'to delete again')
686
 
        self.assertEqual(rsrc.delete(), None)
687
 
        self.m.VerifyAll()
688
 
 
689
 
    def test_gateway_router(self):
690
 
        quantumclient.Client.add_gateway_router(
691
 
            '3e46229d-8fce-4733-819a-b5fe630550f8',
692
 
            {'network_id': 'fc68ea2c-b60b-4b4f-bd82-94ec81110766'}
693
 
        ).AndReturn(None)
694
 
        quantumclient.Client.remove_gateway_router(
695
 
            '3e46229d-8fce-4733-819a-b5fe630550f8'
696
 
        ).AndReturn(None)
697
 
        quantumclient.Client.remove_gateway_router(
698
 
            '3e46229d-8fce-4733-819a-b5fe630550f8'
699
 
        ).AndRaise(qe.QuantumClientException(status_code=404))
700
 
        self.m.ReplayAll()
701
 
        t = template_format.parse(quantum_template)
702
 
        stack = parse_stack(t)
703
 
 
704
 
        rsrc = self.create_gateway_router(
705
 
            t, stack, 'gateway', properties={
706
 
                'router_id': '3e46229d-8fce-4733-819a-b5fe630550f8',
707
 
                'network_id': 'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
708
 
            })
709
 
 
710
 
        self.assertEqual(rsrc.delete(), None)
711
 
        rsrc.state_set(rsrc.CREATE, rsrc.COMPLETE, 'to delete again')
712
 
        self.assertEqual(rsrc.delete(), None)
713
 
        self.m.VerifyAll()
714
 
 
715
 
 
716
 
@skipIf(quantumclient is None, 'quantumclient unavailable')
717
 
class QuantumFloatingIPTest(HeatTestCase):
718
 
    @skipIf(net.clients.quantumclient is None, "Missing Quantum Client")
719
 
    def setUp(self):
720
 
        super(QuantumFloatingIPTest, self).setUp()
721
 
        self.m.StubOutWithMock(quantumclient.Client, 'create_floatingip')
722
 
        self.m.StubOutWithMock(quantumclient.Client, 'delete_floatingip')
723
 
        self.m.StubOutWithMock(quantumclient.Client, 'show_floatingip')
724
 
        self.m.StubOutWithMock(quantumclient.Client, 'update_floatingip')
725
 
        self.m.StubOutWithMock(quantumclient.Client, 'create_port')
726
 
        self.m.StubOutWithMock(quantumclient.Client, 'delete_port')
727
 
        self.m.StubOutWithMock(quantumclient.Client, 'show_port')
728
 
        setup_dummy_db()
729
 
 
730
 
    def test_floating_ip(self):
731
 
 
732
 
        quantumclient.Client.create_floatingip({
733
 
            'floatingip': {'floating_network_id': u'abcd1234'}
734
 
        }).AndReturn({'floatingip': {
735
 
            "status": "ACTIVE",
736
 
            "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
737
 
        }})
738
 
 
739
 
        quantumclient.Client.show_floatingip(
740
 
            'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
741
 
        ).AndRaise(qe.QuantumClientException(status_code=404))
742
 
        quantumclient.Client.show_floatingip(
743
 
            'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
744
 
        ).MultipleTimes().AndReturn({'floatingip': {
745
 
            "status": "ACTIVE",
746
 
            "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
747
 
        }})
748
 
 
749
 
        quantumclient.Client.delete_floatingip(
750
 
            'fc68ea2c-b60b-4b4f-bd82-94ec81110766').AndReturn(None)
751
 
        quantumclient.Client.delete_floatingip(
752
 
            'fc68ea2c-b60b-4b4f-bd82-94ec81110766').AndRaise(
753
 
                qe.QuantumClientException(status_code=404))
754
 
        self.m.ReplayAll()
755
 
 
756
 
        t = template_format.parse(quantum_floating_template)
757
 
        stack = parse_stack(t)
758
 
 
759
 
        # assert the implicit dependency between the floating_ip
760
 
        # and the gateway
761
 
        deps = stack.dependencies[stack['gateway']]
762
 
        self.assertIn(stack['floating_ip'], deps)
763
 
 
764
 
        fip = stack['floating_ip']
765
 
        scheduler.TaskRunner(fip.create)()
766
 
        self.assertEqual((fip.CREATE, fip.COMPLETE), fip.state)
767
 
        fip.validate()
768
 
 
769
 
        fip_id = fip.FnGetRefId()
770
 
        self.assertEqual('fc68ea2c-b60b-4b4f-bd82-94ec81110766', fip_id)
771
 
 
772
 
        self.assertEqual(None, fip.FnGetAtt('status'))
773
 
        self.assertEqual('ACTIVE', fip.FnGetAtt('status'))
774
 
        try:
775
 
            fip.FnGetAtt('Foo')
776
 
            raise Exception('Expected InvalidTemplateAttribute')
777
 
        except exception.InvalidTemplateAttribute:
778
 
            pass
779
 
 
780
 
        self.assertEqual('fc68ea2c-b60b-4b4f-bd82-94ec81110766',
781
 
                         fip.FnGetAtt('id'))
782
 
        self.assertRaises(resource.UpdateReplace,
783
 
                          fip.handle_update, {}, {}, {})
784
 
        self.assertEqual(fip.delete(), None)
785
 
        fip.state_set(fip.CREATE, fip.COMPLETE, 'to delete again')
786
 
        self.assertEqual(fip.delete(), None)
787
 
 
788
 
        self.m.VerifyAll()
789
 
 
790
 
    def test_port(self):
791
 
 
792
 
        quantumclient.Client.create_port({'port': {
793
 
            'network_id': u'xyz1234',
794
 
            'fixed_ips': [
795
 
                {'subnet_id': u'12.12.12.0', 'ip_address': u'10.0.0.10'}
796
 
            ],
797
 
            'name': utils.PhysName('test_stack', 'port_floating'),
798
 
            'admin_state_up': True}}
799
 
        ).AndReturn({'port': {
800
 
            "status": "BUILD",
801
 
            "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
802
 
        }})
803
 
        quantumclient.Client.show_port(
804
 
            'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
805
 
        ).AndReturn({'port': {
806
 
            "status": "BUILD",
807
 
            "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
808
 
        }})
809
 
        quantumclient.Client.show_port(
810
 
            'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
811
 
        ).AndReturn({'port': {
812
 
            "status": "ACTIVE",
813
 
            "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
814
 
        }})
815
 
        quantumclient.Client.show_port(
816
 
            'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
817
 
        ).AndRaise(qe.QuantumClientException(status_code=404))
818
 
        quantumclient.Client.show_port(
819
 
            'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
820
 
        ).MultipleTimes().AndReturn({'port': {
821
 
            "status": "ACTIVE",
822
 
            "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
823
 
        }})
824
 
 
825
 
        self.m.ReplayAll()
826
 
 
827
 
        t = template_format.parse(quantum_floating_template)
828
 
        stack = parse_stack(t)
829
 
 
830
 
        p = stack['port_floating']
831
 
        scheduler.TaskRunner(p.create)()
832
 
        self.assertEqual((p.CREATE, p.COMPLETE), p.state)
833
 
        p.validate()
834
 
 
835
 
        port_id = p.FnGetRefId()
836
 
        self.assertEqual('fc68ea2c-b60b-4b4f-bd82-94ec81110766', port_id)
837
 
 
838
 
        self.assertEqual(None, p.FnGetAtt('status'))
839
 
        self.assertEqual('ACTIVE', p.FnGetAtt('status'))
840
 
        try:
841
 
            p.FnGetAtt('Foo')
842
 
            raise Exception('Expected InvalidTemplateAttribute')
843
 
        except exception.InvalidTemplateAttribute:
844
 
            pass
845
 
 
846
 
        self.assertEqual('fc68ea2c-b60b-4b4f-bd82-94ec81110766',
847
 
                         p.FnGetAtt('id'))
848
 
 
849
 
        self.assertRaises(resource.UpdateReplace,
850
 
                          p.handle_update, {}, {}, {})
851
 
 
852
 
        self.m.VerifyAll()
853
 
 
854
 
    def test_floatip_port(self):
855
 
 
856
 
        quantumclient.Client.create_floatingip({
857
 
            'floatingip': {'floating_network_id': u'abcd1234'}
858
 
        }).AndReturn({'floatingip': {
859
 
            "status": "ACTIVE",
860
 
            "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
861
 
        }})
862
 
 
863
 
        quantumclient.Client.create_port({'port': {
864
 
            'network_id': u'xyz1234',
865
 
            'fixed_ips': [
866
 
                {'subnet_id': u'12.12.12.0', 'ip_address': u'10.0.0.10'}
867
 
            ],
868
 
            'name': utils.PhysName('test_stack', 'port_floating'),
869
 
            'admin_state_up': True}}
870
 
        ).AndReturn({'port': {
871
 
            "status": "BUILD",
872
 
            "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
873
 
        }})
874
 
        quantumclient.Client.show_port(
875
 
            'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
876
 
        ).AndReturn({'port': {
877
 
            "status": "ACTIVE",
878
 
            "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
879
 
        }})
880
 
        quantumclient.Client.update_floatingip(
881
 
            'fc68ea2c-b60b-4b4f-bd82-94ec81110766',
882
 
            {
883
 
                'floatingip': {
884
 
                    'port_id': u'fc68ea2c-b60b-4b4f-bd82-94ec81110766'}}
885
 
        ).AndReturn({'floatingip': {
886
 
            "status": "ACTIVE",
887
 
            "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
888
 
        }})
889
 
 
890
 
        quantumclient.Client.update_floatingip(
891
 
            'fc68ea2c-b60b-4b4f-bd82-94ec81110766',
892
 
            {'floatingip': {
893
 
                'port_id': None
894
 
            }}).AndReturn(None)
895
 
 
896
 
        quantumclient.Client.delete_port(
897
 
            'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
898
 
        ).AndReturn(None)
899
 
 
900
 
        quantumclient.Client.show_port(
901
 
            'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
902
 
        ).AndRaise(qe.QuantumClientException(status_code=404))
903
 
 
904
 
        quantumclient.Client.delete_floatingip(
905
 
            'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
906
 
        ).AndReturn(None)
907
 
 
908
 
        quantumclient.Client.update_floatingip(
909
 
            'fc68ea2c-b60b-4b4f-bd82-94ec81110766',
910
 
            {'floatingip': {
911
 
                'port_id': None
912
 
            }}).AndRaise(qe.QuantumClientException(status_code=404))
913
 
 
914
 
        quantumclient.Client.delete_port(
915
 
            'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
916
 
        ).AndRaise(qe.QuantumClientException(status_code=404))
917
 
 
918
 
        quantumclient.Client.delete_floatingip(
919
 
            'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
920
 
        ).AndRaise(qe.QuantumClientException(status_code=404))
921
 
 
922
 
        self.m.ReplayAll()
923
 
 
924
 
        t = template_format.parse(quantum_floating_template)
925
 
        stack = parse_stack(t)
926
 
 
927
 
        fip = stack['floating_ip']
928
 
        scheduler.TaskRunner(fip.create)()
929
 
        self.assertEqual((fip.CREATE, fip.COMPLETE), fip.state)
930
 
 
931
 
        p = stack['port_floating']
932
 
        scheduler.TaskRunner(p.create)()
933
 
        self.assertEqual((p.CREATE, p.COMPLETE), p.state)
934
 
 
935
 
        fipa = stack['floating_ip_assoc']
936
 
        scheduler.TaskRunner(fipa.create)()
937
 
        self.assertEqual((fipa.CREATE, fipa.COMPLETE), fipa.state)
938
 
 
939
 
        fipa.validate()
940
 
 
941
 
        fipa_id = fipa.FnGetRefId()
942
 
        fip_id = fip.FnGetRefId()
943
 
        port_id = p.FnGetRefId()
944
 
        self.assertEqual('%s:%s' % (fip_id, port_id), fipa_id)
945
 
        self.assertRaises(resource.UpdateReplace,
946
 
                          fipa.handle_update, {}, {}, {})
947
 
 
948
 
        self.assertEqual(fipa.delete(), None)
949
 
        self.assertEqual(scheduler.TaskRunner(p.delete)(), None)
950
 
        self.assertEqual(fip.delete(), None)
951
 
 
952
 
        fipa.state_set(fipa.CREATE, fipa.COMPLETE, 'to delete again')
953
 
        fip.state_set(fip.CREATE, fip.COMPLETE, 'to delete again')
954
 
        p.state_set(p.CREATE, p.COMPLETE, 'to delete again')
955
 
 
956
 
        self.assertEqual(fipa.delete(), None)
957
 
        self.assertEqual(scheduler.TaskRunner(p.delete)(), None)
958
 
        self.assertEqual(fip.delete(), None)
959
 
 
960
 
        self.m.VerifyAll()