Merge "Func test for qos live migration reschedule"

This commit is contained in:
Zuul
2019-12-23 16:50:52 +00:00
committed by Gerrit Code Review
4 changed files with 137 additions and 6 deletions

View File

@@ -7604,7 +7604,7 @@ class ComputeManager(manager.Manager):
src_compute_info = obj_base.obj_to_primitive(
self._get_compute_info(ctxt, instance.host))
dst_compute_info = obj_base.obj_to_primitive(
self._get_compute_info(ctxt, CONF.host))
self._get_compute_info(ctxt, self.host))
dest_check_data = self.driver.check_can_live_migrate_destination(ctxt,
instance, src_compute_info, dst_compute_info,
block_migration, disk_over_commit)

View File

@@ -9,6 +9,7 @@
# 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 copy
from oslo_log import log as logging
import oslo_messaging as messaging
@@ -67,6 +68,7 @@ class LiveMigrationTask(base.TaskBase):
self._source_cn = None
self._held_allocations = None
self.network_api = network.API()
self.instance_pci_request = None
def _execute(self):
self._check_instance_is_active()
@@ -82,6 +84,11 @@ class LiveMigrationTask(base.TaskBase):
self.instance,
self.migration))
# NOTE(gibi): migrating with qos SRIOV ports will update the PCI
# request so we saving the request here so that we can roll that change
# back if the migration fails.
self.instance_pci_request = copy.deepcopy(self.instance.pci_requests)
if not self.destination:
# Either no host was specified in the API request and the user
# wants the scheduler to pick a destination host, or a host was
@@ -151,6 +158,9 @@ class LiveMigrationTask(base.TaskBase):
self._source_cn,
self.instance,
self.migration)
if self.instance_pci_request:
self.instance.pci_requests = self.instance_pci_request
self.instance.save()
def _check_instance_is_active(self):
if self.instance.power_state not in (power_state.RUNNING,

View File

@@ -7249,7 +7249,7 @@ class ServerMoveWithPortResourceRequestTest(
self.addCleanup(patcher.stop)
patcher.start()
def test_live_migrate_with_qos_port(self):
def test_live_migrate_with_qos_port(self, host=None):
# TODO(gibi): remove this when live migration is fully supported and
# therefore the check is removed from the api
self._turn_off_api_check()
@@ -7270,7 +7270,7 @@ class ServerMoveWithPortResourceRequestTest(
server['id'],
{
'os-migrateLive': {
'host': None,
'host': host,
'block_migration': 'auto'
}
}
@@ -7288,10 +7288,130 @@ class ServerMoveWithPortResourceRequestTest(
self._delete_server_and_check_allocations(
server, qos_normal_port, qos_sriov_port)
def test_live_migrate_with_qos_port_with_target_host(self):
self.test_live_migrate_with_qos_port(host='host2')
def test_live_migrate_with_qos_port_reschedule_success(self):
# TODO(gibi): remove this when live migration is fully supported and
# therefore the check is removed from the api
self._turn_off_api_check()
self._start_compute('host3')
compute3_rp_uuid = self._get_provider_uuid_by_host('host3')
self._create_networking_rp_tree('host3', compute3_rp_uuid)
non_qos_normal_port = self.neutron.port_1
qos_normal_port = self.neutron.port_with_resource_request
qos_sriov_port = self.neutron.port_with_sriov_resource_request
server = self._create_server_with_ports(
non_qos_normal_port, qos_normal_port, qos_sriov_port)
# check that the server allocates from the current host properly
self._check_allocation(
server, self.compute1_rp_uuid, non_qos_normal_port,
qos_normal_port, qos_sriov_port, self.flavor_with_group_policy)
orig_check = nova.virt.fake.FakeDriver.\
check_can_live_migrate_destination
def fake_check_can_live_migrate_destination(
context, instance, src_compute_info, dst_compute_info,
block_migration=False, disk_over_commit=False):
if dst_compute_info['host'] == 'host2':
raise exception.MigrationPreCheckError(
reason='test_live_migrate_pre_check_fails')
else:
return orig_check(
context, instance, src_compute_info, dst_compute_info,
block_migration, disk_over_commit)
with mock.patch('nova.virt.fake.FakeDriver.'
'check_can_live_migrate_destination',
side_effect=fake_check_can_live_migrate_destination):
self.api.post_server_action(
server['id'],
{
'os-migrateLive': {
'host': None,
'block_migration': 'auto'
}
}
)
# The first migration attempt was to host2. So we expect that the
# instance lands on host3.
self._wait_for_server_parameter(
server,
{'OS-EXT-SRV-ATTR:host': 'host3',
'status': 'ACTIVE'})
self._check_allocation(
server, compute3_rp_uuid, non_qos_normal_port,
qos_normal_port, qos_sriov_port, self.flavor_with_group_policy)
self._delete_server_and_check_allocations(
server, qos_normal_port, qos_sriov_port)
def test_live_migrate_with_qos_port_reschedule_fails(self):
# TODO(gibi): remove this when live migration is fully supported and
# therefore the check is removed from the api
self._turn_off_api_check()
non_qos_normal_port = self.neutron.port_1
qos_normal_port = self.neutron.port_with_resource_request
qos_sriov_port = self.neutron.port_with_sriov_resource_request
server = self._create_server_with_ports(
non_qos_normal_port, qos_normal_port, qos_sriov_port)
# check that the server allocates from the current host properly
self._check_allocation(
server, self.compute1_rp_uuid, non_qos_normal_port,
qos_normal_port, qos_sriov_port, self.flavor_with_group_policy)
with mock.patch(
'nova.virt.fake.FakeDriver.check_can_live_migrate_destination',
side_effect=exception.MigrationPreCheckError(
reason='test_live_migrate_pre_check_fails')):
self.api.post_server_action(
server['id'],
{
'os-migrateLive': {
'host': None,
'block_migration': 'auto'
}
}
)
# The every migration target host will fail the pre check so
# the conductor will run out of target host and the migration will
# fail
self._wait_for_migration_status(server, ['error'])
# the server will remain on host1
self._wait_for_server_parameter(
server,
{'OS-EXT-SRV-ATTR:host': 'host1',
'status': 'ACTIVE'})
self._check_allocation(
server, self.compute1_rp_uuid, non_qos_normal_port,
qos_normal_port, qos_sriov_port, self.flavor_with_group_policy)
# Assert that the InstancePCIRequests also rolled back to point to
# host1
ctxt = context.get_admin_context()
pci_requests = objects.InstancePCIRequests.get_by_instance_uuid(
ctxt, server['id'])
self.assertEqual(1, len(pci_requests.requests))
self.assertEqual(1, len(pci_requests.requests[0].spec))
self.assertEqual(
'host1-ens2',
pci_requests.requests[0].spec[0]['parent_ifname'])
self._delete_server_and_check_allocations(
server, qos_normal_port, qos_sriov_port)
# TODO(gibi): add tests for live migration cases:
# * with target host
# * re-schedule success
# * re-schedule fail -> pci request cleanup?
# * abort / cancel -> dest / pci request cleanup?

View File

@@ -60,6 +60,7 @@ class LiveMigrationTaskTestCase(test.NoDBTestCase):
self.context, objects.Instance(), db_instance)
self.instance.system_metadata = {'image_hw_disk_bus': 'scsi'}
self.instance.numa_topology = None
self.instance.pci_requests = None
self.destination = "destination"
self.block_migration = "bm"
self.disk_over_commit = "doc"