~ubuntu-branches/ubuntu/vivid/neutron/vivid-updates

« back to all changes in this revision

Viewing changes to neutron/tests/tempest/api/network/test_dhcp_ipv6.py

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2015-03-30 11:17:19 UTC
  • mfrom: (1.1.21)
  • Revision ID: package-import@ubuntu.com-20150330111719-h0gx7233p4jkkgfh
Tags: 1:2015.1~b3-0ubuntu1
* New upstream milestone release:
  - d/control: Align version requirements with upstream.
  - d/control: Add new dependency on oslo-log.
  - d/p/*: Rebase.
  - d/control,d/neutron-plugin-hyperv*: Dropped, decomposed into
    separate project upstream.
  - d/control,d/neutron-plugin-openflow*: Dropped, decomposed into
    separate project upstream.
  - d/neutron-common.install: Add neutron-rootwrap-daemon and 
    neutron-keepalived-state-change binaries.
  - d/rules: Ignore neutron-hyperv-agent when installing; only for Windows.
  - d/neutron-plugin-cisco.install: Drop neutron-cisco-cfg-agent as
    decomposed into separate project upstream.
  - d/neutron-plugin-vmware.install: Drop neutron-check-nsx-config and
    neutron-nsx-manage as decomposed into separate project upstream.
  - d/control: Add dependency on python-neutron-fwaas to neutron-l3-agent.
* d/pydist-overrides: Add overrides for oslo packages.
* d/control: Fixup type in package description (LP: #1263539).
* d/p/fixup-driver-test-execution.patch: Cherry pick fix from upstream VCS
  to support unit test exection in out-of-tree vendor drivers.
* d/neutron-common.postinst: Allow general access to /etc/neutron but limit
  access to root/neutron to /etc/neutron/neutron.conf to support execution
  of unit tests in decomposed vendor drivers.
* d/control: Add dependency on python-neutron-fwaas to neutron-l3-agent
  package.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright 2014 OpenStack Foundation
 
2
# All Rights Reserved.
 
3
#
 
4
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
 
5
#    not use this file except in compliance with the License. You may obtain
 
6
#    a copy of the License at
 
7
#
 
8
#         http://www.apache.org/licenses/LICENSE-2.0
 
9
#
 
10
#    Unless required by applicable law or agreed to in writing, software
 
11
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 
12
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 
13
#    License for the specific language governing permissions and limitations
 
14
#    under the License.
 
15
 
 
16
import netaddr
 
17
import random
 
18
 
 
19
from tempest_lib.common.utils import data_utils
 
20
from tempest_lib import exceptions as lib_exc
 
21
 
 
22
from neutron.tests.tempest.api.network import base
 
23
from neutron.tests.tempest import config
 
24
from neutron.tests.tempest import test
 
25
 
 
26
CONF = config.CONF
 
27
 
 
28
 
 
29
class NetworksTestDHCPv6(base.BaseNetworkTest):
 
30
    _ip_version = 6
 
31
 
 
32
    """ Test DHCPv6 specific features using SLAAC, stateless and
 
33
    stateful settings for subnets. Also it shall check dual-stack
 
34
    functionality (IPv4 + IPv6 together).
 
35
    The tests include:
 
36
        generating of SLAAC EUI-64 address in subnets with various settings
 
37
        receiving SLAAC addresses in combinations of various subnets
 
38
        receiving stateful IPv6 addresses
 
39
        addressing in subnets with router
 
40
    """
 
41
 
 
42
    @classmethod
 
43
    def skip_checks(cls):
 
44
        msg = None
 
45
        if not CONF.network_feature_enabled.ipv6:
 
46
            msg = "IPv6 is not enabled"
 
47
        elif not CONF.network_feature_enabled.ipv6_subnet_attributes:
 
48
            msg = "DHCPv6 attributes are not enabled."
 
49
        if msg:
 
50
            raise cls.skipException(msg)
 
51
 
 
52
    @classmethod
 
53
    def resource_setup(cls):
 
54
        super(NetworksTestDHCPv6, cls).resource_setup()
 
55
        cls.network = cls.create_network()
 
56
 
 
57
    def _remove_from_list_by_index(self, things_list, elem):
 
58
        for index, i in enumerate(things_list):
 
59
            if i['id'] == elem['id']:
 
60
                break
 
61
        del things_list[index]
 
62
 
 
63
    def _clean_network(self):
 
64
        body = self.client.list_ports()
 
65
        ports = body['ports']
 
66
        for port in ports:
 
67
            if (port['device_owner'].startswith('network:router_interface')
 
68
                and port['device_id'] in [r['id'] for r in self.routers]):
 
69
                self.client.remove_router_interface_with_port_id(
 
70
                    port['device_id'], port['id']
 
71
                )
 
72
            else:
 
73
                if port['id'] in [p['id'] for p in self.ports]:
 
74
                    self.client.delete_port(port['id'])
 
75
                    self._remove_from_list_by_index(self.ports, port)
 
76
        body = self.client.list_subnets()
 
77
        subnets = body['subnets']
 
78
        for subnet in subnets:
 
79
            if subnet['id'] in [s['id'] for s in self.subnets]:
 
80
                self.client.delete_subnet(subnet['id'])
 
81
                self._remove_from_list_by_index(self.subnets, subnet)
 
82
        body = self.client.list_routers()
 
83
        routers = body['routers']
 
84
        for router in routers:
 
85
            if router['id'] in [r['id'] for r in self.routers]:
 
86
                self.client.delete_router(router['id'])
 
87
                self._remove_from_list_by_index(self.routers, router)
 
88
 
 
89
    def _get_ips_from_subnet(self, **kwargs):
 
90
        subnet = self.create_subnet(self.network, **kwargs)
 
91
        port_mac = data_utils.rand_mac_address()
 
92
        port = self.create_port(self.network, mac_address=port_mac)
 
93
        real_ip = next(iter(port['fixed_ips']), None)['ip_address']
 
94
        eui_ip = data_utils.get_ipv6_addr_by_EUI64(subnet['cidr'],
 
95
                                                   port_mac).format()
 
96
        return real_ip, eui_ip
 
97
 
 
98
    @test.idempotent_id('e5517e62-6f16-430d-a672-f80875493d4c')
 
99
    def test_dhcpv6_stateless_eui64(self):
 
100
        """When subnets configured with RAs SLAAC (AOM=100) and DHCP stateless
 
101
        (AOM=110) both for radvd and dnsmasq, port shall receive IP address
 
102
        calculated from its MAC.
 
103
        """
 
104
        for ra_mode, add_mode in (
 
105
                ('slaac', 'slaac'),
 
106
                ('dhcpv6-stateless', 'dhcpv6-stateless'),
 
107
        ):
 
108
            kwargs = {'ipv6_ra_mode': ra_mode,
 
109
                      'ipv6_address_mode': add_mode}
 
110
            real_ip, eui_ip = self._get_ips_from_subnet(**kwargs)
 
111
            self._clean_network()
 
112
            self.assertEqual(eui_ip, real_ip,
 
113
                             ('Real port IP is %s, but shall be %s when '
 
114
                              'ipv6_ra_mode=%s and ipv6_address_mode=%s') % (
 
115
                                 real_ip, eui_ip, ra_mode, add_mode))
 
116
 
 
117
    @test.idempotent_id('ae2f4a5d-03ff-4c42-a3b0-ce2fcb7ea832')
 
118
    def test_dhcpv6_stateless_no_ra(self):
 
119
        """When subnets configured with dnsmasq SLAAC and DHCP stateless
 
120
        and there is no radvd, port shall receive IP address calculated
 
121
        from its MAC and mask of subnet.
 
122
        """
 
123
        for ra_mode, add_mode in (
 
124
                (None, 'slaac'),
 
125
                (None, 'dhcpv6-stateless'),
 
126
        ):
 
127
            kwargs = {'ipv6_ra_mode': ra_mode,
 
128
                      'ipv6_address_mode': add_mode}
 
129
            kwargs = {k: v for k, v in kwargs.iteritems() if v}
 
130
            real_ip, eui_ip = self._get_ips_from_subnet(**kwargs)
 
131
            self._clean_network()
 
132
            self.assertEqual(eui_ip, real_ip,
 
133
                             ('Real port IP %s shall be equal to EUI-64 %s'
 
134
                              'when ipv6_ra_mode=%s,ipv6_address_mode=%s') % (
 
135
                                 real_ip, eui_ip,
 
136
                                 ra_mode if ra_mode else "Off",
 
137
                                 add_mode if add_mode else "Off"))
 
138
 
 
139
    @test.idempotent_id('81f18ef6-95b5-4584-9966-10d480b7496a')
 
140
    def test_dhcpv6_invalid_options(self):
 
141
        """Different configurations for radvd and dnsmasq are not allowed"""
 
142
        for ra_mode, add_mode in (
 
143
                ('dhcpv6-stateless', 'dhcpv6-stateful'),
 
144
                ('dhcpv6-stateless', 'slaac'),
 
145
                ('slaac', 'dhcpv6-stateful'),
 
146
                ('dhcpv6-stateful', 'dhcpv6-stateless'),
 
147
                ('dhcpv6-stateful', 'slaac'),
 
148
                ('slaac', 'dhcpv6-stateless'),
 
149
        ):
 
150
            kwargs = {'ipv6_ra_mode': ra_mode,
 
151
                      'ipv6_address_mode': add_mode}
 
152
            self.assertRaises(lib_exc.BadRequest,
 
153
                              self.create_subnet,
 
154
                              self.network,
 
155
                              **kwargs)
 
156
 
 
157
    @test.idempotent_id('21635b6f-165a-4d42-bf49-7d195e47342f')
 
158
    def test_dhcpv6_stateless_no_ra_no_dhcp(self):
 
159
        """If no radvd option and no dnsmasq option is configured
 
160
        port shall receive IP from fixed IPs list of subnet.
 
161
        """
 
162
        real_ip, eui_ip = self._get_ips_from_subnet()
 
163
        self._clean_network()
 
164
        self.assertNotEqual(eui_ip, real_ip,
 
165
                            ('Real port IP %s equal to EUI-64 %s when '
 
166
                             'ipv6_ra_mode=Off and ipv6_address_mode=Off,'
 
167
                             'but shall be taken from fixed IPs') % (
 
168
                                real_ip, eui_ip))
 
169
 
 
170
    @test.idempotent_id('4544adf7-bb5f-4bdc-b769-b3e77026cef2')
 
171
    def test_dhcpv6_two_subnets(self):
 
172
        """When one IPv6 subnet configured with dnsmasq SLAAC or DHCP stateless
 
173
        and other IPv6 is with DHCP stateful, port shall receive EUI-64 IP
 
174
        addresses from first subnet and DHCP address from second one.
 
175
        Order of subnet creating should be unimportant.
 
176
        """
 
177
        for order in ("slaac_first", "dhcp_first"):
 
178
            for ra_mode, add_mode in (
 
179
                    ('slaac', 'slaac'),
 
180
                    ('dhcpv6-stateless', 'dhcpv6-stateless'),
 
181
            ):
 
182
                kwargs = {'ipv6_ra_mode': ra_mode,
 
183
                          'ipv6_address_mode': add_mode}
 
184
                kwargs_dhcp = {'ipv6_address_mode': 'dhcpv6-stateful'}
 
185
                if order == "slaac_first":
 
186
                    subnet_slaac = self.create_subnet(self.network, **kwargs)
 
187
                    subnet_dhcp = self.create_subnet(
 
188
                        self.network, **kwargs_dhcp)
 
189
                else:
 
190
                    subnet_dhcp = self.create_subnet(
 
191
                        self.network, **kwargs_dhcp)
 
192
                    subnet_slaac = self.create_subnet(self.network, **kwargs)
 
193
                port_mac = data_utils.rand_mac_address()
 
194
                dhcp_ip = subnet_dhcp["allocation_pools"][0]["start"]
 
195
                eui_ip = data_utils.get_ipv6_addr_by_EUI64(
 
196
                    subnet_slaac['cidr'],
 
197
                    port_mac
 
198
                ).format()
 
199
                # TODO(sergsh): remove this when 1219795 is fixed
 
200
                dhcp_ip = [dhcp_ip, (netaddr.IPAddress(dhcp_ip) + 1).format()]
 
201
                port = self.create_port(self.network, mac_address=port_mac)
 
202
                real_ips = dict([(k['subnet_id'], k['ip_address'])
 
203
                                 for k in port['fixed_ips']])
 
204
                real_dhcp_ip, real_eui_ip = [real_ips[sub['id']]
 
205
                                             for sub in subnet_dhcp,
 
206
                                             subnet_slaac]
 
207
                self.client.delete_port(port['id'])
 
208
                self.ports.pop()
 
209
                body = self.client.list_ports()
 
210
                ports_id_list = [i['id'] for i in body['ports']]
 
211
                self.assertNotIn(port['id'], ports_id_list)
 
212
                self._clean_network()
 
213
                self.assertEqual(real_eui_ip,
 
214
                                 eui_ip,
 
215
                                 'Real IP is {0}, but shall be {1}'.format(
 
216
                                     real_eui_ip,
 
217
                                     eui_ip))
 
218
                self.assertIn(
 
219
                    real_dhcp_ip, dhcp_ip,
 
220
                    'Real IP is {0}, but shall be one from {1}'.format(
 
221
                        real_dhcp_ip,
 
222
                        str(dhcp_ip)))
 
223
 
 
224
    @test.idempotent_id('4256c61d-c538-41ea-9147-3c450c36669e')
 
225
    def test_dhcpv6_64_subnets(self):
 
226
        """When one IPv6 subnet configured with dnsmasq SLAAC or DHCP stateless
 
227
        and other IPv4 is with DHCP of IPv4, port shall receive EUI-64 IP
 
228
        addresses from first subnet and IPv4 DHCP address from second one.
 
229
        Order of subnet creating should be unimportant.
 
230
        """
 
231
        for order in ("slaac_first", "dhcp_first"):
 
232
            for ra_mode, add_mode in (
 
233
                    ('slaac', 'slaac'),
 
234
                    ('dhcpv6-stateless', 'dhcpv6-stateless'),
 
235
            ):
 
236
                kwargs = {'ipv6_ra_mode': ra_mode,
 
237
                          'ipv6_address_mode': add_mode}
 
238
                if order == "slaac_first":
 
239
                    subnet_slaac = self.create_subnet(self.network, **kwargs)
 
240
                    subnet_dhcp = self.create_subnet(
 
241
                        self.network, ip_version=4)
 
242
                else:
 
243
                    subnet_dhcp = self.create_subnet(
 
244
                        self.network, ip_version=4)
 
245
                    subnet_slaac = self.create_subnet(self.network, **kwargs)
 
246
                port_mac = data_utils.rand_mac_address()
 
247
                dhcp_ip = subnet_dhcp["allocation_pools"][0]["start"]
 
248
                eui_ip = data_utils.get_ipv6_addr_by_EUI64(
 
249
                    subnet_slaac['cidr'],
 
250
                    port_mac
 
251
                ).format()
 
252
                # TODO(sergsh): remove this when 1219795 is fixed
 
253
                dhcp_ip = [dhcp_ip, (netaddr.IPAddress(dhcp_ip) + 1).format()]
 
254
                port = self.create_port(self.network, mac_address=port_mac)
 
255
                real_ips = dict([(k['subnet_id'], k['ip_address'])
 
256
                                 for k in port['fixed_ips']])
 
257
                real_dhcp_ip, real_eui_ip = [real_ips[sub['id']]
 
258
                                             for sub in subnet_dhcp,
 
259
                                             subnet_slaac]
 
260
                self._clean_network()
 
261
                self.assertTrue({real_eui_ip,
 
262
                                 real_dhcp_ip}.issubset([eui_ip] + dhcp_ip))
 
263
                self.assertEqual(real_eui_ip,
 
264
                                 eui_ip,
 
265
                                 'Real IP is {0}, but shall be {1}'.format(
 
266
                                     real_eui_ip,
 
267
                                     eui_ip))
 
268
                self.assertIn(
 
269
                    real_dhcp_ip, dhcp_ip,
 
270
                    'Real IP is {0}, but shall be one from {1}'.format(
 
271
                        real_dhcp_ip,
 
272
                        str(dhcp_ip)))
 
273
 
 
274
    @test.idempotent_id('4ab211a0-276f-4552-9070-51e27f58fecf')
 
275
    def test_dhcp_stateful(self):
 
276
        """With all options below, DHCPv6 shall allocate first
 
277
        address from subnet pool to port.
 
278
        """
 
279
        for ra_mode, add_mode in (
 
280
                ('dhcpv6-stateful', 'dhcpv6-stateful'),
 
281
                ('dhcpv6-stateful', None),
 
282
                (None, 'dhcpv6-stateful'),
 
283
        ):
 
284
            kwargs = {'ipv6_ra_mode': ra_mode,
 
285
                      'ipv6_address_mode': add_mode}
 
286
            kwargs = {k: v for k, v in kwargs.iteritems() if v}
 
287
            subnet = self.create_subnet(self.network, **kwargs)
 
288
            port = self.create_port(self.network)
 
289
            port_ip = next(iter(port['fixed_ips']), None)['ip_address']
 
290
            dhcp_ip = subnet["allocation_pools"][0]["start"]
 
291
            # TODO(sergsh): remove this when 1219795 is fixed
 
292
            dhcp_ip = [dhcp_ip, (netaddr.IPAddress(dhcp_ip) + 1).format()]
 
293
            self._clean_network()
 
294
            self.assertIn(
 
295
                port_ip, dhcp_ip,
 
296
                'Real IP is {0}, but shall be one from {1}'.format(
 
297
                    port_ip,
 
298
                    str(dhcp_ip)))
 
299
 
 
300
    @test.idempotent_id('51a5e97f-f02e-4e4e-9a17-a69811d300e3')
 
301
    def test_dhcp_stateful_fixedips(self):
 
302
        """With all options below, port shall be able to get
 
303
        requested IP from fixed IP range not depending on
 
304
        DHCP stateful (not SLAAC!) settings configured.
 
305
        """
 
306
        for ra_mode, add_mode in (
 
307
                ('dhcpv6-stateful', 'dhcpv6-stateful'),
 
308
                ('dhcpv6-stateful', None),
 
309
                (None, 'dhcpv6-stateful'),
 
310
        ):
 
311
            kwargs = {'ipv6_ra_mode': ra_mode,
 
312
                      'ipv6_address_mode': add_mode}
 
313
            kwargs = {k: v for k, v in kwargs.iteritems() if v}
 
314
            subnet = self.create_subnet(self.network, **kwargs)
 
315
            ip_range = netaddr.IPRange(subnet["allocation_pools"][0]["start"],
 
316
                                       subnet["allocation_pools"][0]["end"])
 
317
            ip = netaddr.IPAddress(random.randrange(ip_range.first,
 
318
                                                    ip_range.last)).format()
 
319
            port = self.create_port(self.network,
 
320
                                    fixed_ips=[{'subnet_id': subnet['id'],
 
321
                                                'ip_address': ip}])
 
322
            port_ip = next(iter(port['fixed_ips']), None)['ip_address']
 
323
            self._clean_network()
 
324
            self.assertEqual(port_ip, ip,
 
325
                             ("Port IP %s is not as fixed IP from "
 
326
                              "port create request: %s") % (
 
327
                                 port_ip, ip))
 
328
 
 
329
    @test.idempotent_id('98244d88-d990-4570-91d4-6b25d70d08af')
 
330
    def test_dhcp_stateful_fixedips_outrange(self):
 
331
        """When port gets IP address from fixed IP range it
 
332
        shall be checked if it's from subnets range.
 
333
        """
 
334
        kwargs = {'ipv6_ra_mode': 'dhcpv6-stateful',
 
335
                  'ipv6_address_mode': 'dhcpv6-stateful'}
 
336
        subnet = self.create_subnet(self.network, **kwargs)
 
337
        ip_range = netaddr.IPRange(subnet["allocation_pools"][0]["start"],
 
338
                                   subnet["allocation_pools"][0]["end"])
 
339
        ip = netaddr.IPAddress(random.randrange(
 
340
            ip_range.last + 1, ip_range.last + 10)).format()
 
341
        self.assertRaises(lib_exc.BadRequest,
 
342
                          self.create_port,
 
343
                          self.network,
 
344
                          fixed_ips=[{'subnet_id': subnet['id'],
 
345
                                      'ip_address': ip}])
 
346
 
 
347
    @test.idempotent_id('57b8302b-cba9-4fbb-8835-9168df029051')
 
348
    def test_dhcp_stateful_fixedips_duplicate(self):
 
349
        """When port gets IP address from fixed IP range it
 
350
        shall be checked if it's not duplicate.
 
351
        """
 
352
        kwargs = {'ipv6_ra_mode': 'dhcpv6-stateful',
 
353
                  'ipv6_address_mode': 'dhcpv6-stateful'}
 
354
        subnet = self.create_subnet(self.network, **kwargs)
 
355
        ip_range = netaddr.IPRange(subnet["allocation_pools"][0]["start"],
 
356
                                   subnet["allocation_pools"][0]["end"])
 
357
        ip = netaddr.IPAddress(random.randrange(
 
358
            ip_range.first, ip_range.last)).format()
 
359
        self.create_port(self.network,
 
360
                         fixed_ips=[
 
361
                             {'subnet_id': subnet['id'],
 
362
                              'ip_address': ip}])
 
363
        self.assertRaisesRegexp(lib_exc.Conflict,
 
364
                                "object with that identifier already exists",
 
365
                                self.create_port,
 
366
                                self.network,
 
367
                                fixed_ips=[{'subnet_id': subnet['id'],
 
368
                                            'ip_address': ip}])
 
369
 
 
370
    def _create_subnet_router(self, kwargs):
 
371
        subnet = self.create_subnet(self.network, **kwargs)
 
372
        router = self.create_router(
 
373
            router_name=data_utils.rand_name("routerv6-"),
 
374
            admin_state_up=True)
 
375
        port = self.create_router_interface(router['id'],
 
376
                                            subnet['id'])
 
377
        body = self.client.show_port(port['port_id'])
 
378
        return subnet, body['port']
 
379
 
 
380
    @test.idempotent_id('e98f65db-68f4-4330-9fea-abd8c5192d4d')
 
381
    def test_dhcp_stateful_router(self):
 
382
        """With all options below the router interface shall
 
383
        receive DHCPv6 IP address from allocation pool.
 
384
        """
 
385
        for ra_mode, add_mode in (
 
386
                ('dhcpv6-stateful', 'dhcpv6-stateful'),
 
387
                ('dhcpv6-stateful', None),
 
388
        ):
 
389
            kwargs = {'ipv6_ra_mode': ra_mode,
 
390
                      'ipv6_address_mode': add_mode}
 
391
            kwargs = {k: v for k, v in kwargs.iteritems() if v}
 
392
            subnet, port = self._create_subnet_router(kwargs)
 
393
            port_ip = next(iter(port['fixed_ips']), None)['ip_address']
 
394
            self._clean_network()
 
395
            self.assertEqual(port_ip, subnet['gateway_ip'],
 
396
                             ("Port IP %s is not as first IP from "
 
397
                              "subnets allocation pool: %s") % (
 
398
                                 port_ip, subnet['gateway_ip']))
 
399
 
 
400
    def tearDown(self):
 
401
        self._clean_network()
 
402
        super(NetworksTestDHCPv6, self).tearDown()