diff options
author | Balazs Gibizer <balazs.gibizer@est.tech> | 2020-02-10 15:23:02 +0100 |
---|---|---|
committer | Balazs Gibizer <balazs.gibizer@est.tech> | 2020-07-13 13:39:47 +0200 |
commit | 618dd9bdc24b3a1de6a5581d4e7201efdf1f86bd (patch) | |
tree | 5c6adbe87f67b34aaac3507ebb6b1b927008e4a4 | |
parent | 33d5b585f24f66c2533a65e026904d1c919ee7bb (diff) | |
download | nova-618dd9bdc24b3a1de6a5581d4e7201efdf1f86bd.tar.gz |
Reproduce bug 1862633
If port update fails during unshelve of an offloaded server then
placement allocation on the target host is leaked.
Changes in test_bug_1862633.py due to:
* the NeutronFixture improvement done in
Id8d2c48c9c864554a917596e377d30515465fec1 is missing from stable/pike
therefore the fault injection mock needed to be moved to a higher
level function.
* the Ie4676eed0039c927b35af7573f0b57fd762adbaa refactor is also missing
and causing the name change of wait_for_versioned_notification
Change-Id: I7be32e4fc2e69f805535e0a437931516f491e5cb
Related-Bug: #1862633
(cherry picked from commit c33ebdafbd633578a0a4b6f1b118c756510acea6)
(cherry picked from commit bd1bfc13d7e2c418afc409871ab56da454a1334d)
(cherry picked from commit f960d1751d752d559ea18604bfd1fcaf1a3283cd)
(cherry picked from commit 5e452f8eb743c226af4f4998835ece8dd142a011)
(cherry picked from commit eb4f0a5aa93feb2dc7730987207f052a04bc33db)
-rw-r--r-- | nova/tests/functional/regressions/test_bug_1862633.py | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/nova/tests/functional/regressions/test_bug_1862633.py b/nova/tests/functional/regressions/test_bug_1862633.py new file mode 100644 index 0000000000..e35e391417 --- /dev/null +++ b/nova/tests/functional/regressions/test_bug_1862633.py @@ -0,0 +1,100 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +import mock +from neutronclient.common import exceptions as neutron_exception + +from nova import test +from nova.tests import fixtures as nova_fixtures +from nova.tests.functional import integrated_helpers +from nova.tests.unit import fake_notifier +from nova.tests.unit.image import fake as fake_image +from nova.virt import fake + + +class UnshelveNeutronErrorTest( + test.TestCase, integrated_helpers.InstanceHelperMixin): + def setUp(self): + super(UnshelveNeutronErrorTest, self).setUp() + # Start standard fixtures. + placement = nova_fixtures.PlacementFixture() + self.useFixture(placement) + self.placement_api = placement.api + self.neutron = nova_fixtures.NeutronFixture(self) + self.useFixture(self.neutron) + fake_image.stub_out_image_service(self) + self.addCleanup(fake_image.FakeImageService_reset) + # Start nova services. + self.api = self.useFixture(nova_fixtures.OSAPIFixture( + api_version='v2.1')).admin_api + self.api.microversion = 'latest' + fake_notifier.stub_notifier(self) + self.addCleanup(fake_notifier.reset) + + self.start_service('conductor') + self.start_service('scheduler') + self.addCleanup(fake.restore_nodes) + fake.set_nodes(['host1']) + self.start_service('compute', host='host1') + fake.set_nodes(['host2']) + self.start_service('compute', host='host2') + + def test_unshelve_offloaded_fails_due_to_neutron(self): + server_req = self._build_minimal_create_server_request( + self.api, name='unshelve-error-vm', + image_uuid='155d900f-4e14-4e4c-a73d-069cbf4541e6', + networks=[{'port': self.neutron.port_1['id']}], az='nova:host1') + created_server = self.api.post_server({'server': server_req}) + server = self._wait_for_state_change( + self.api, created_server, 'ACTIVE') + + # with default config shelve means immediate offload as well + req = { + 'shelve': {} + } + self.api.post_server_action(server['id'], req) + self._wait_for_server_parameter( + self.api, server, {'status': 'SHELVED_OFFLOADED'}) + allocations = self.placement_api.get( + '/allocations/%s' % server['id']).body['allocations'] + self.assertEqual(0, len(allocations)) + + # disable the original host of the instance to force a port update + # during unshelve + source_service_id = self.api.get_services( + host='host1', binary='nova-compute')[0]['id'] + self.api.put_service(source_service_id, {"status": "disabled"}) + + # Simulate that port update fails during unshelve due to neutron is + # unavailable + with mock.patch( + 'nova.network.neutronv2.api.API.' + 'setup_instance_network_on_host', + side_effect=neutron_exception.ConnectionFailed(reason='test')): + req = {'unshelve': None} + self.api.post_server_action(server['id'], req) + fake_notifier.wait_for_versioned_notification( + 'instance.unshelve.start') + self._wait_for_server_parameter( + self.api, + server, + {'status': 'SHELVED_OFFLOADED', + 'OS-EXT-STS:task_state': None}) + + # As the instance went back to offloaded state we expect no allocation + # allocations = self.placement_api.get( + # '/allocations/%s' % server['id']).body['allocations'] + # self.assertEqual(0, len(allocations)) + # + # but the allocation is leaked this is bug 1862633 + allocations = self.placement_api.get( + '/allocations/%s' % server['id']).body['allocations'] + self.assertEqual(1, len(allocations)) |