blob: db4751be442b751611c7f5822d0606d22e65520f [file] [log] [blame]
Lajos Katonac87a06b2019-01-04 13:21:48 +01001# Copyright (c) 2019 Ericsson
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
elajkat064a3402019-10-17 13:18:10 +020015import testtools
Lajos Katonac87a06b2019-01-04 13:21:48 +010016
17from tempest.common import utils
18from tempest.common import waiters
19from tempest import config
20from tempest.lib.common.utils import data_utils
21from tempest.lib.common.utils import test_utils
22from tempest.lib import decorators
elajkat8b90b262020-07-15 16:11:56 +020023from tempest.lib import exceptions as lib_exc
Lajos Katonac87a06b2019-01-04 13:21:48 +010024from tempest.scenario import manager
25
26
Lajos Katonac87a06b2019-01-04 13:21:48 +010027CONF = config.CONF
28
29
Balazs Gibizerbc0257c2021-08-26 16:41:51 +020030class NetworkQoSPlacementTestBase(manager.NetworkScenarioTest):
31 """Base class for Network QoS testing
32
33 Base class for testing Network QoS scenarios involving placement
34 resource allocations.
35 """
Lajos Katonac87a06b2019-01-04 13:21:48 +010036 credentials = ['primary', 'admin']
Lajos Katonac87a06b2019-01-04 13:21:48 +010037 # The feature QoS minimum bandwidth allocation in Placement API depends on
38 # Granular resource requests to GET /allocation_candidates and Support
39 # allocation candidates with nested resource providers features in
40 # Placement (see: https://specs.openstack.org/openstack/nova-specs/specs/
41 # stein/approved/bandwidth-resource-provider.html#rest-api-impact) and this
42 # means that the minimum placement microversion is 1.29
43 placement_min_microversion = '1.29'
44 placement_max_microversion = 'latest'
45
46 # Nova rejects to boot VM with port which has resource_request field, below
47 # microversion 2.72
48 compute_min_microversion = '2.72'
49 compute_max_microversion = 'latest'
50
Lajos Katonac87a06b2019-01-04 13:21:48 +010051 INGRESS_DIRECTION = 'ingress'
Balazs Gibizerbc0257c2021-08-26 16:41:51 +020052 BW_RESOURCE_CLASS = "NET_BW_IGR_KILOBIT_PER_SEC"
Lajos Katonac87a06b2019-01-04 13:21:48 +010053
Lajos Katonac87a06b2019-01-04 13:21:48 +010054 # For any realistic inventory value (that is inventory != MAX_INT) an
55 # allocation candidate request of MAX_INT is expected to be rejected, see:
56 # https://github.com/openstack/placement/blob/master/placement/
57 # db/constants.py#L16
58 PLACEMENT_MAX_INT = 0x7FFFFFFF
59
60 @classmethod
61 def setup_clients(cls):
Balazs Gibizerbc0257c2021-08-26 16:41:51 +020062 super().setup_clients()
Lajos Katonac87a06b2019-01-04 13:21:48 +010063 cls.placement_client = cls.os_admin.placement_client
64 cls.networks_client = cls.os_admin.networks_client
65 cls.subnets_client = cls.os_admin.subnets_client
elajkat8b90b262020-07-15 16:11:56 +020066 cls.ports_client = cls.os_primary.ports_client
Lajos Katonac87a06b2019-01-04 13:21:48 +010067 cls.routers_client = cls.os_adm.routers_client
68 cls.qos_client = cls.os_admin.qos_client
69 cls.qos_min_bw_client = cls.os_admin.qos_min_bw_client
elajkat064a3402019-10-17 13:18:10 +020070 cls.flavors_client = cls.os_adm.flavors_client
Balazs Gibizer18accde2021-09-29 16:10:49 +020071 cls.servers_client = cls.os_primary.servers_client
Lajos Katonac87a06b2019-01-04 13:21:48 +010072
Balazs Gibizerbc0257c2021-08-26 16:41:51 +020073 def _create_flavor_to_resize_to(self):
74 old_flavor = self.flavors_client.show_flavor(
75 CONF.compute.flavor_ref)['flavor']
76 new_flavor = self.flavors_client.create_flavor(**{
77 'ram': old_flavor['ram'],
78 'vcpus': old_flavor['vcpus'],
79 'name': old_flavor['name'] + 'extra',
80 'disk': old_flavor['disk'] + 1
81 })['flavor']
82 self.addCleanup(test_utils.call_and_ignore_notfound_exc,
83 self.flavors_client.delete_flavor, new_flavor['id'])
84 return new_flavor
85
86
87class MinBwAllocationPlacementTest(NetworkQoSPlacementTestBase):
88
89 required_extensions = ['port-resource-request',
90 'qos',
91 'qos-bw-minimum-ingress']
92
93 SMALLEST_POSSIBLE_BW = 1
94 BANDWIDTH_1 = 1000
95 BANDWIDTH_2 = 2000
96
Lajos Katonac87a06b2019-01-04 13:21:48 +010097 @classmethod
98 def skip_checks(cls):
99 super(MinBwAllocationPlacementTest, cls).skip_checks()
100 if not CONF.network_feature_enabled.qos_placement_physnet:
101 msg = "Skipped as no physnet is available in config for " \
102 "placement based QoS allocation."
103 raise cls.skipException(msg)
104
elajkat064a3402019-10-17 13:18:10 +0200105 def setUp(self):
106 super(MinBwAllocationPlacementTest, self).setUp()
107 self._check_if_allocation_is_possible()
elajkat064a3402019-10-17 13:18:10 +0200108
Lajos Katonac87a06b2019-01-04 13:21:48 +0100109 def _create_policy_and_min_bw_rule(self, name_prefix, min_kbps):
110 policy = self.qos_client.create_qos_policy(
111 name=data_utils.rand_name(name_prefix),
112 shared=True)['policy']
113 self.addCleanup(test_utils.call_and_ignore_notfound_exc,
114 self.qos_client.delete_qos_policy, policy['id'])
115 rule = self.qos_min_bw_client.create_minimum_bandwidth_rule(
116 policy['id'],
117 **{
118 'min_kbps': min_kbps,
119 'direction': self.INGRESS_DIRECTION
120 })['minimum_bandwidth_rule']
121 self.addCleanup(
122 test_utils.call_and_ignore_notfound_exc,
123 self.qos_min_bw_client.delete_minimum_bandwidth_rule, policy['id'],
124 rule['id'])
125
126 return policy
127
elajkat8b90b262020-07-15 16:11:56 +0200128 def _create_qos_basic_policies(self):
Lajos Katonac87a06b2019-01-04 13:21:48 +0100129 self.qos_policy_valid = self._create_policy_and_min_bw_rule(
130 name_prefix='test_policy_valid',
131 min_kbps=self.SMALLEST_POSSIBLE_BW)
132 self.qos_policy_not_valid = self._create_policy_and_min_bw_rule(
133 name_prefix='test_policy_not_valid',
134 min_kbps=self.PLACEMENT_MAX_INT)
135
elajkat8b90b262020-07-15 16:11:56 +0200136 def _create_qos_policies_from_life(self):
137 # For tempest-slow the max bandwidth configured is 1000000,
138 # https://opendev.org/openstack/tempest/src/branch/master/
139 # .zuul.yaml#L416-L420
140 self.qos_policy_1 = self._create_policy_and_min_bw_rule(
141 name_prefix='test_policy_1',
142 min_kbps=self.BANDWIDTH_1
143 )
144 self.qos_policy_2 = self._create_policy_and_min_bw_rule(
145 name_prefix='test_policy_2',
146 min_kbps=self.BANDWIDTH_2
147 )
148
149 def _create_network_and_qos_policies(self, policy_method):
Lajos Katonac87a06b2019-01-04 13:21:48 +0100150 physnet_name = CONF.network_feature_enabled.qos_placement_physnet
151 base_segm = \
152 CONF.network_feature_enabled.provider_net_base_segmentation_id
153
Ghanshyam Mann071d1542021-03-24 19:10:47 -0500154 self.prov_network, _, _ = self.setup_network_subnet_with_router(
Lajos Katonac87a06b2019-01-04 13:21:48 +0100155 networks_client=self.networks_client,
156 routers_client=self.routers_client,
157 subnets_client=self.subnets_client,
158 **{
159 'shared': True,
160 'provider:network_type': 'vlan',
161 'provider:physical_network': physnet_name,
162 'provider:segmentation_id': base_segm
163 })
164
elajkat8b90b262020-07-15 16:11:56 +0200165 policy_method()
Lajos Katonac87a06b2019-01-04 13:21:48 +0100166
167 def _check_if_allocation_is_possible(self):
168 alloc_candidates = self.placement_client.list_allocation_candidates(
Balazs Gibizerbc0257c2021-08-26 16:41:51 +0200169 resources1='%s:%s' % (self.BW_RESOURCE_CLASS,
Lajos Katonac87a06b2019-01-04 13:21:48 +0100170 self.SMALLEST_POSSIBLE_BW))
171 if len(alloc_candidates['provider_summaries']) == 0:
Balazs Gibizera5f523b2021-08-26 13:38:19 +0200172 self.fail('No allocation candidates are available for %s:%s' %
Balazs Gibizerbc0257c2021-08-26 16:41:51 +0200173 (self.BW_RESOURCE_CLASS, self.SMALLEST_POSSIBLE_BW))
Lajos Katonac87a06b2019-01-04 13:21:48 +0100174
175 # Just to be sure check with impossible high (placement max_int),
176 # allocation
177 alloc_candidates = self.placement_client.list_allocation_candidates(
Balazs Gibizerbc0257c2021-08-26 16:41:51 +0200178 resources1='%s:%s' % (self.BW_RESOURCE_CLASS,
Lajos Katonac87a06b2019-01-04 13:21:48 +0100179 self.PLACEMENT_MAX_INT))
180 if len(alloc_candidates['provider_summaries']) != 0:
181 self.fail('For %s:%s there should be no available candidate!' %
Balazs Gibizerbc0257c2021-08-26 16:41:51 +0200182 (self.BW_RESOURCE_CLASS, self.PLACEMENT_MAX_INT))
Lajos Katonac87a06b2019-01-04 13:21:48 +0100183
elajkat064a3402019-10-17 13:18:10 +0200184 def _boot_vm_with_min_bw(self, qos_policy_id, status='ACTIVE'):
185 wait_until = (None if status == 'ERROR' else status)
186 port = self.create_port(
187 self.prov_network['id'], qos_policy_id=qos_policy_id)
188
189 server = self.create_server(networks=[{'port': port['id']}],
190 wait_until=wait_until)
191 waiters.wait_for_server_status(
Balazs Gibizer18accde2021-09-29 16:10:49 +0200192 client=self.servers_client, server_id=server['id'],
elajkat064a3402019-10-17 13:18:10 +0200193 status=status, ready_wait=False, raise_on_error=False)
194 return server, port
195
elajkat8b90b262020-07-15 16:11:56 +0200196 def _assert_allocation_is_as_expected(self, consumer, port_ids,
197 min_kbps=SMALLEST_POSSIBLE_BW):
198 allocations = self.placement_client.list_allocations(
199 consumer)['allocations']
200 self.assertGreater(len(allocations), 0)
elajkat064a3402019-10-17 13:18:10 +0200201 bw_resource_in_alloc = False
Balazs Gibizer20514ef2021-09-15 12:00:20 +0200202 allocation_rp = None
elajkat8b90b262020-07-15 16:11:56 +0200203 for rp, resources in allocations.items():
Balazs Gibizerbc0257c2021-08-26 16:41:51 +0200204 if self.BW_RESOURCE_CLASS in resources['resources']:
elajkat8b90b262020-07-15 16:11:56 +0200205 self.assertEqual(
206 min_kbps,
Balazs Gibizerbc0257c2021-08-26 16:41:51 +0200207 resources['resources'][self.BW_RESOURCE_CLASS])
elajkat064a3402019-10-17 13:18:10 +0200208 bw_resource_in_alloc = True
209 allocation_rp = rp
elajkat8b90b262020-07-15 16:11:56 +0200210 if min_kbps:
211 self.assertTrue(bw_resource_in_alloc)
elajkat064a3402019-10-17 13:18:10 +0200212
elajkat8b90b262020-07-15 16:11:56 +0200213 # Check binding_profile of the port is not empty and equals with
214 # the rp uuid
215 for port_id in port_ids:
216 port = self.os_admin.ports_client.show_port(port_id)
Balazs Gibizer20514ef2021-09-15 12:00:20 +0200217 port_binding_alloc = port['port']['binding:profile'][
218 'allocation']
219 # NOTE(gibi): the format of the allocation key depends on the
220 # existence of port-resource-request-groups API extension.
221 # TODO(gibi): drop the else branch once tempest does not need
222 # to support Xena release any more.
223 if utils.is_extension_enabled(
224 'port-resource-request-groups', 'network'):
225 self.assertEqual(
226 {allocation_rp},
227 set(port_binding_alloc.values()))
228 else:
229 self.assertEqual(allocation_rp, port_binding_alloc)
elajkat064a3402019-10-17 13:18:10 +0200230
Lajos Katonac87a06b2019-01-04 13:21:48 +0100231 @decorators.idempotent_id('78625d92-212c-400e-8695-dd51706858b8')
Lajos Katonac87a06b2019-01-04 13:21:48 +0100232 @utils.services('compute', 'network')
233 def test_qos_min_bw_allocation_basic(self):
234 """"Basic scenario with QoS min bw allocation in placement.
235
236 Steps:
237 * Create prerequisites:
238 ** VLAN type provider network with subnet.
239 ** valid QoS policy with minimum bandwidth rule with min_kbps=1
240 (This is a simplification to skip the checks in placement for
241 detecting the resource provider tree and inventories, as if
242 bandwidth resource is available 1 kbs will be available).
243 ** invalid QoS policy with minimum bandwidth rule with
244 min_kbs=max integer from placement (this is a simplification again
245 to avoid detection of RP tress and inventories, as placement will
246 reject such big allocation).
247 * Create port with valid QoS policy, and boot VM with that, it should
248 pass.
249 * Create port with invalid QoS policy, and try to boot VM with that,
250 it should fail.
251 """
elajkat8b90b262020-07-15 16:11:56 +0200252 self._create_network_and_qos_policies(self._create_qos_basic_policies)
elajkat064a3402019-10-17 13:18:10 +0200253 server1, valid_port = self._boot_vm_with_min_bw(
254 qos_policy_id=self.qos_policy_valid['id'])
elajkat8b90b262020-07-15 16:11:56 +0200255 self._assert_allocation_is_as_expected(server1['id'],
256 [valid_port['id']])
Lajos Katonac87a06b2019-01-04 13:21:48 +0100257
elajkat064a3402019-10-17 13:18:10 +0200258 server2, not_valid_port = self._boot_vm_with_min_bw(
259 self.qos_policy_not_valid['id'], status='ERROR')
Lajos Katonac87a06b2019-01-04 13:21:48 +0100260 allocations = self.placement_client.list_allocations(server2['id'])
261
262 self.assertEqual(0, len(allocations['allocations']))
263 server2 = self.servers_client.show_server(server2['id'])
264 self.assertIn('fault', server2['server'])
265 self.assertIn('No valid host', server2['server']['fault']['message'])
elajkate4f28202019-10-24 12:56:42 +0200266 # Check that binding_profile of the port is empty
267 port = self.os_admin.ports_client.show_port(not_valid_port['id'])
268 self.assertEqual(0, len(port['port']['binding:profile']))
elajkat064a3402019-10-17 13:18:10 +0200269
270 @decorators.idempotent_id('8a98150c-a506-49a5-96c6-73a5e7b04ada')
271 @testtools.skipUnless(CONF.compute_feature_enabled.cold_migration,
272 'Cold migration is not available.')
273 @testtools.skipUnless(CONF.compute.min_compute_nodes > 1,
274 'Less than 2 compute nodes, skipping multinode '
275 'tests.')
276 @utils.services('compute', 'network')
277 def test_migrate_with_qos_min_bw_allocation(self):
278 """Scenario to migrate VM with QoS min bw allocation in placement
279
280 Boot a VM like in test_qos_min_bw_allocation_basic, do the same
281 checks, and
282 * migrate the server
283 * confirm the resize, if the VM state is VERIFY_RESIZE
284 * If the VM goes to ACTIVE state check that allocations are as
285 expected.
286 """
elajkat8b90b262020-07-15 16:11:56 +0200287 self._create_network_and_qos_policies(self._create_qos_basic_policies)
elajkat064a3402019-10-17 13:18:10 +0200288 server, valid_port = self._boot_vm_with_min_bw(
289 qos_policy_id=self.qos_policy_valid['id'])
elajkat8b90b262020-07-15 16:11:56 +0200290 self._assert_allocation_is_as_expected(server['id'],
291 [valid_port['id']])
elajkat064a3402019-10-17 13:18:10 +0200292
Balazs Gibizer18accde2021-09-29 16:10:49 +0200293 self.os_adm.servers_client.migrate_server(server_id=server['id'])
elajkat064a3402019-10-17 13:18:10 +0200294 waiters.wait_for_server_status(
Balazs Gibizer18accde2021-09-29 16:10:49 +0200295 client=self.servers_client, server_id=server['id'],
elajkat064a3402019-10-17 13:18:10 +0200296 status='VERIFY_RESIZE', ready_wait=False, raise_on_error=False)
elajkat064a3402019-10-17 13:18:10 +0200297
298 # TODO(lajoskatona): Check that the allocations are ok for the
299 # migration?
elajkat8b90b262020-07-15 16:11:56 +0200300 self._assert_allocation_is_as_expected(server['id'],
301 [valid_port['id']])
elajkat064a3402019-10-17 13:18:10 +0200302
Balazs Gibizer18accde2021-09-29 16:10:49 +0200303 self.os_adm.servers_client.confirm_resize_server(
304 server_id=server['id'])
elajkat064a3402019-10-17 13:18:10 +0200305 waiters.wait_for_server_status(
Balazs Gibizer18accde2021-09-29 16:10:49 +0200306 client=self.servers_client, server_id=server['id'],
elajkat064a3402019-10-17 13:18:10 +0200307 status='ACTIVE', ready_wait=False, raise_on_error=True)
elajkat8b90b262020-07-15 16:11:56 +0200308 self._assert_allocation_is_as_expected(server['id'],
309 [valid_port['id']])
elajkat064a3402019-10-17 13:18:10 +0200310
311 @decorators.idempotent_id('c29e7fd3-035d-4993-880f-70819847683f')
312 @testtools.skipUnless(CONF.compute_feature_enabled.resize,
313 'Resize not available.')
314 @utils.services('compute', 'network')
315 def test_resize_with_qos_min_bw_allocation(self):
316 """Scenario to resize VM with QoS min bw allocation in placement.
317
318 Boot a VM like in test_qos_min_bw_allocation_basic, do the same
319 checks, and
320 * resize the server with new flavor
321 * confirm the resize, if the VM state is VERIFY_RESIZE
322 * If the VM goes to ACTIVE state check that allocations are as
323 expected.
324 """
elajkat8b90b262020-07-15 16:11:56 +0200325 self._create_network_and_qos_policies(self._create_qos_basic_policies)
elajkat064a3402019-10-17 13:18:10 +0200326 server, valid_port = self._boot_vm_with_min_bw(
327 qos_policy_id=self.qos_policy_valid['id'])
elajkat8b90b262020-07-15 16:11:56 +0200328 self._assert_allocation_is_as_expected(server['id'],
329 [valid_port['id']])
elajkat064a3402019-10-17 13:18:10 +0200330
Balazs Gibizerbc0257c2021-08-26 16:41:51 +0200331 new_flavor = self._create_flavor_to_resize_to()
elajkat064a3402019-10-17 13:18:10 +0200332
333 self.servers_client.resize_server(
334 server_id=server['id'], flavor_ref=new_flavor['id'])
335 waiters.wait_for_server_status(
Balazs Gibizer18accde2021-09-29 16:10:49 +0200336 client=self.servers_client, server_id=server['id'],
elajkat064a3402019-10-17 13:18:10 +0200337 status='VERIFY_RESIZE', ready_wait=False, raise_on_error=False)
elajkat064a3402019-10-17 13:18:10 +0200338
339 # TODO(lajoskatona): Check that the allocations are ok for the
340 # migration?
elajkat8b90b262020-07-15 16:11:56 +0200341 self._assert_allocation_is_as_expected(server['id'],
342 [valid_port['id']])
elajkat064a3402019-10-17 13:18:10 +0200343
344 self.servers_client.confirm_resize_server(server_id=server['id'])
345 waiters.wait_for_server_status(
Balazs Gibizer18accde2021-09-29 16:10:49 +0200346 client=self.servers_client, server_id=server['id'],
elajkat064a3402019-10-17 13:18:10 +0200347 status='ACTIVE', ready_wait=False, raise_on_error=True)
elajkat8b90b262020-07-15 16:11:56 +0200348 self._assert_allocation_is_as_expected(server['id'],
349 [valid_port['id']])
350
351 @decorators.idempotent_id('79fdaa1c-df62-4738-a0f0-1cff9dc415f6')
352 @utils.services('compute', 'network')
353 def test_qos_min_bw_allocation_update_policy(self):
354 """Test the update of QoS policy on bound port
355
356 Related RFE in neutron: #1882804
357 The scenario is the following:
358 * Have a port with QoS policy and minimum bandwidth rule.
359 * Boot a VM with the port.
360 * Update the port with a new policy with different minimum bandwidth
361 values.
362 * The allocation on placement side should be according to the new
363 rules.
364 """
365 if not utils.is_network_feature_enabled('update_port_qos'):
366 raise self.skipException("update_port_qos feature is not enabled")
367
368 self._create_network_and_qos_policies(
369 self._create_qos_policies_from_life)
370
371 port = self.create_port(
372 self.prov_network['id'], qos_policy_id=self.qos_policy_1['id'])
373
374 server1 = self.create_server(
375 networks=[{'port': port['id']}])
376
377 self._assert_allocation_is_as_expected(server1['id'], [port['id']],
378 self.BANDWIDTH_1)
379
380 self.ports_client.update_port(
381 port['id'],
382 **{'qos_policy_id': self.qos_policy_2['id']})
383 self._assert_allocation_is_as_expected(server1['id'], [port['id']],
384 self.BANDWIDTH_2)
385
386 # I changed my mind
387 self.ports_client.update_port(
388 port['id'],
389 **{'qos_policy_id': self.qos_policy_1['id']})
390 self._assert_allocation_is_as_expected(server1['id'], [port['id']],
391 self.BANDWIDTH_1)
392
393 # bad request....
394 self.qos_policy_not_valid = self._create_policy_and_min_bw_rule(
395 name_prefix='test_policy_not_valid',
396 min_kbps=self.PLACEMENT_MAX_INT)
397 port_orig = self.ports_client.show_port(port['id'])['port']
398 self.assertRaises(
399 lib_exc.Conflict,
400 self.ports_client.update_port,
401 port['id'], **{'qos_policy_id': self.qos_policy_not_valid['id']})
402 self._assert_allocation_is_as_expected(server1['id'], [port['id']],
403 self.BANDWIDTH_1)
404
405 port_upd = self.ports_client.show_port(port['id'])['port']
406 self.assertEqual(port_orig['qos_policy_id'],
407 port_upd['qos_policy_id'])
408 self.assertEqual(self.qos_policy_1['id'], port_upd['qos_policy_id'])
409
410 @decorators.idempotent_id('9cfc3bb8-f433-4c91-87b6-747cadc8958a')
411 @utils.services('compute', 'network')
412 def test_qos_min_bw_allocation_update_policy_from_zero(self):
413 """Test port without QoS policy to have QoS policy
414
415 This scenario checks if updating a port without QoS policy to
416 have QoS policy with minimum_bandwidth rule succeeds only on
417 controlplane, but placement allocation remains 0.
418 """
419 if not utils.is_network_feature_enabled('update_port_qos'):
420 raise self.skipException("update_port_qos feature is not enabled")
421
422 self._create_network_and_qos_policies(
423 self._create_qos_policies_from_life)
424
425 port = self.create_port(self.prov_network['id'])
426
427 server1 = self.create_server(
428 networks=[{'port': port['id']}])
429
430 self._assert_allocation_is_as_expected(server1['id'], [port['id']], 0)
431
432 self.ports_client.update_port(
433 port['id'], **{'qos_policy_id': self.qos_policy_2['id']})
434 self._assert_allocation_is_as_expected(server1['id'], [port['id']], 0)
435
436 @decorators.idempotent_id('a9725a70-1d28-4e3b-ae0e-450abc235962')
437 @utils.services('compute', 'network')
438 def test_qos_min_bw_allocation_update_policy_to_zero(self):
439 """Test port with QoS policy to remove QoS policy
440
441 In this scenario port with QoS minimum_bandwidth rule update to
442 remove QoS policy results in 0 placement allocation.
443 """
444 if not utils.is_network_feature_enabled('update_port_qos'):
445 raise self.skipException("update_port_qos feature is not enabled")
446
447 self._create_network_and_qos_policies(
448 self._create_qos_policies_from_life)
449
450 port = self.create_port(
451 self.prov_network['id'], qos_policy_id=self.qos_policy_1['id'])
452
453 server1 = self.create_server(
454 networks=[{'port': port['id']}])
455 self._assert_allocation_is_as_expected(server1['id'], [port['id']],
456 self.BANDWIDTH_1)
457
458 self.ports_client.update_port(
459 port['id'],
460 **{'qos_policy_id': None})
461 self._assert_allocation_is_as_expected(server1['id'], [port['id']], 0)
462
463 @decorators.idempotent_id('756ced7f-6f1a-43e7-a851-2fcfc16f3dd7')
464 @utils.services('compute', 'network')
465 def test_qos_min_bw_allocation_update_with_multiple_ports(self):
466 if not utils.is_network_feature_enabled('update_port_qos'):
467 raise self.skipException("update_port_qos feature is not enabled")
468
469 self._create_network_and_qos_policies(
470 self._create_qos_policies_from_life)
471
472 port1 = self.create_port(
473 self.prov_network['id'], qos_policy_id=self.qos_policy_1['id'])
474 port2 = self.create_port(
475 self.prov_network['id'], qos_policy_id=self.qos_policy_2['id'])
476
477 server1 = self.create_server(
478 networks=[{'port': port1['id']}, {'port': port2['id']}])
479 self._assert_allocation_is_as_expected(
480 server1['id'], [port1['id'], port2['id']],
481 self.BANDWIDTH_1 + self.BANDWIDTH_2)
482
483 self.ports_client.update_port(
484 port1['id'],
485 **{'qos_policy_id': self.qos_policy_2['id']})
486 self._assert_allocation_is_as_expected(
487 server1['id'], [port1['id'], port2['id']],
488 2 * self.BANDWIDTH_2)
489
490 @decorators.idempotent_id('0805779e-e03c-44fb-900f-ce97a790653b')
491 @utils.services('compute', 'network')
492 def test_empty_update(self):
493 if not utils.is_network_feature_enabled('update_port_qos'):
494 raise self.skipException("update_port_qos feature is not enabled")
495
496 self._create_network_and_qos_policies(
497 self._create_qos_policies_from_life)
498
499 port = self.create_port(
500 self.prov_network['id'], qos_policy_id=self.qos_policy_1['id'])
501
502 server1 = self.create_server(
503 networks=[{'port': port['id']}])
504 self._assert_allocation_is_as_expected(server1['id'], [port['id']],
505 self.BANDWIDTH_1)
506 self.ports_client.update_port(
507 port['id'],
508 **{'description': 'foo'})
509 self._assert_allocation_is_as_expected(server1['id'], [port['id']],
510 self.BANDWIDTH_1)