Functional test for regression bug #1713783
Add functional test for evacuation, when no valid host available. Migration should end up in 'error' state. Change-Id: I1adc20f2a5261e6906a18b9aee5cd2c8ecf0cf4d Related-bug: #1713783
This commit is contained in:
parent
1fb132f2f3
commit
5687c170ea
@ -443,3 +443,6 @@ class TestOpenStackClient(object):
|
||||
def get_active_migrations(self, server_id):
|
||||
return self.api_get('/servers/%s/migrations' %
|
||||
server_id).body['migrations']
|
||||
|
||||
def get_migrations(self):
|
||||
return self.api_get('os-migrations').body['migrations']
|
||||
|
124
nova/tests/functional/regressions/test_bug_1713783.py
Normal file
124
nova/tests/functional/regressions/test_bug_1713783.py
Normal file
@ -0,0 +1,124 @@
|
||||
# Copyright 2017 Ericsson
|
||||
#
|
||||
# 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 time
|
||||
|
||||
from oslo_log import log as logging
|
||||
|
||||
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_network
|
||||
from nova.tests.unit import fake_notifier
|
||||
import nova.tests.unit.image.fake
|
||||
from nova.tests.unit import policy_fixture
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class FailedEvacuateStateTests(test.TestCase,
|
||||
integrated_helpers.InstanceHelperMixin):
|
||||
"""Regression Tests for bug #1713783
|
||||
|
||||
When evacuation fails with NoValidHost, the migration status remains
|
||||
'accepted' instead of 'error'. This causes problem in case the compute
|
||||
service starts up again and looks for migrations with status 'accepted',
|
||||
as it then removes the local instances for those migrations even though
|
||||
the instance never actually migrated to another host.
|
||||
"""
|
||||
|
||||
microversion = 'latest'
|
||||
|
||||
def setUp(self):
|
||||
super(FailedEvacuateStateTests, self).setUp()
|
||||
|
||||
self.useFixture(policy_fixture.RealPolicyFixture())
|
||||
self.useFixture(nova_fixtures.NeutronFixture(self))
|
||||
self.useFixture(nova_fixtures.PlacementFixture())
|
||||
|
||||
api_fixture = self.useFixture(nova_fixtures.OSAPIFixture(
|
||||
api_version='v2.1'))
|
||||
|
||||
self.api = api_fixture.admin_api
|
||||
self.api.microversion = self.microversion
|
||||
|
||||
nova.tests.unit.image.fake.stub_out_image_service(self)
|
||||
|
||||
self.start_service('conductor')
|
||||
self.start_service('scheduler')
|
||||
|
||||
self.addCleanup(nova.tests.unit.image.fake.FakeImageService_reset)
|
||||
|
||||
self.hostname = 'host1'
|
||||
self.compute1 = self.start_service('compute', host=self.hostname)
|
||||
fake_network.set_stub_network_methods(self)
|
||||
|
||||
flavors = self.api.get_flavors()
|
||||
self.flavor1 = flavors[0]
|
||||
|
||||
def _wait_for_notification_event_type(self, event_type, max_retries=10):
|
||||
retry_counter = 0
|
||||
while True:
|
||||
if len(fake_notifier.NOTIFICATIONS) > 0:
|
||||
for notification in fake_notifier.NOTIFICATIONS:
|
||||
if notification.event_type == event_type:
|
||||
return
|
||||
if retry_counter == max_retries:
|
||||
self.fail('Wait for notification event type (%s) failed'
|
||||
% event_type)
|
||||
retry_counter += 1
|
||||
time.sleep(0.5)
|
||||
|
||||
def _boot_a_server(self):
|
||||
server_req = self._build_minimal_create_server_request(
|
||||
self.api, 'some-server', flavor_id=self.flavor1['id'],
|
||||
image_uuid='155d900f-4e14-4e4c-a73d-069cbf4541e6',
|
||||
networks='none')
|
||||
LOG.info('booting on %s', self.hostname)
|
||||
created_server = self.api.post_server({'server': server_req})
|
||||
return self._wait_for_state_change(
|
||||
self.api, created_server, 'ACTIVE')
|
||||
|
||||
def test_evacuate_no_valid_host(self):
|
||||
# Boot a server
|
||||
server = self._boot_a_server()
|
||||
|
||||
# Force source compute down
|
||||
compute_id = self.api.get_services(
|
||||
host=self.hostname, binary='nova-compute')[0]['id']
|
||||
self.api.put_service(compute_id, {'forced_down': 'true'})
|
||||
|
||||
fake_notifier.stub_notifier(self)
|
||||
fake_notifier.reset()
|
||||
|
||||
# Initiate evacuation
|
||||
post = {'evacuate': {}}
|
||||
self.api.post_server_action(server['id'], post)
|
||||
|
||||
self._wait_for_notification_event_type('compute_task.rebuild_server')
|
||||
|
||||
server = self._wait_for_state_change(self.api, server, 'ACTIVE')
|
||||
self.assertEqual(self.hostname, server['OS-EXT-SRV-ATTR:host'])
|
||||
|
||||
# Check migrations
|
||||
migrations = self.api.get_migrations()
|
||||
self.assertEqual(1, len(migrations))
|
||||
self.assertEqual('evacuation', migrations[0]['migration_type'])
|
||||
self.assertEqual(server['id'], migrations[0]['instance_uuid'])
|
||||
self.assertEqual(self.hostname, migrations[0]['source_compute'])
|
||||
self.assertEqual('accepted', migrations[0]['status'])
|
||||
# NOTE(elod.illes): Migration status should be 'error' and not
|
||||
# 'accepted'. Needs to be replaced when bug #1713783 is fixed.
|
||||
# self.assertEqual('error', migrations[0]['status'])
|
Loading…
x
Reference in New Issue
Block a user