Merge "Add functional test for AggregateMultiTenancyIsolation + migrate"

This commit is contained in:
Zuul
2019-08-30 11:27:40 +00:00
committed by Gerrit Code Review
+120
View File
@@ -551,3 +551,123 @@ class TestAggregateMultiTenancyIsolationFilter(
server = user_api.post_server(server_req)
self._wait_for_state_change(user_api, server, 'ACTIVE')
self.assertEqual(2, len(self.filtered_hosts))
class AggregateMultiTenancyIsolationColdMigrateTest(
test.TestCase, integrated_helpers.InstanceHelperMixin):
@staticmethod
def _create_aggregate(admin_api, name):
return admin_api.api_post(
'/os-aggregates', {'aggregate': {'name': name}}).body['aggregate']
@staticmethod
def _add_host_to_aggregate(admin_api, aggregate, host):
add_host_req_body = {
"add_host": {
"host": host
}
}
admin_api.api_post(
'/os-aggregates/%s/action' % aggregate['id'], add_host_req_body)
@staticmethod
def _isolate_aggregate(admin_api, aggregate, tenant_id):
set_meta_req_body = {
"set_metadata": {
"metadata": {
"filter_tenant_id": tenant_id
}
}
}
admin_api.api_post(
'/os-aggregates/%s/action' % aggregate['id'], set_meta_req_body)
def setUp(self):
super(AggregateMultiTenancyIsolationColdMigrateTest, self).setUp()
self.useFixture(policy_fixture.RealPolicyFixture())
self.useFixture(nova_fixtures.NeutronFixture(self))
self.useFixture(func_fixtures.PlacementFixture())
# Intentionally keep these separate since we want to create the
# server with the non-admin user in a different project.
admin_api_fixture = self.useFixture(nova_fixtures.OSAPIFixture(
api_version='v2.1', project_id=uuids.admin_project))
self.admin_api = admin_api_fixture.admin_api
self.admin_api.microversion = 'latest'
user_api_fixture = self.useFixture(nova_fixtures.OSAPIFixture(
api_version='v2.1', project_id=uuids.user_project))
self.api = user_api_fixture.api
self.api.microversion = 'latest'
# the image fake backend needed for image discovery
nova.tests.unit.image.fake.stub_out_image_service(self)
self.addCleanup(nova.tests.unit.image.fake.FakeImageService_reset)
self.start_service('conductor')
# Enable the AggregateMultiTenancyIsolation filter before starting the
# scheduler service.
enabled_filters = CONF.filter_scheduler.enabled_filters
if 'AggregateMultiTenancyIsolation' not in enabled_filters:
enabled_filters.append('AggregateMultiTenancyIsolation')
self.flags(
enabled_filters=enabled_filters, group='filter_scheduler')
# Add a custom weigher which will weigh host1, which will be in the
# admin project aggregate, higher than the other hosts which are in
# the non-admin project aggregate.
self.flags(weight_classes=[__name__ + '.HostNameWeigher'],
group='filter_scheduler')
self.start_service('scheduler')
for host in ('host1', 'host2', 'host3'):
self.start_service('compute', host=host)
# Create an admin-only aggregate for the admin project. This is needed
# because if host1 is not in an aggregate with the filter_tenant_id
# metadata key, the filter will accept that host even for the non-admin
# project.
admin_aggregate = self._create_aggregate(
self.admin_api, 'admin-aggregate')
self._add_host_to_aggregate(self.admin_api, admin_aggregate, 'host1')
# Restrict the admin project to the admin aggregate.
self._isolate_aggregate(
self.admin_api, admin_aggregate, uuids.admin_project)
# Create the tenant aggregate for the non-admin project.
tenant_aggregate = self._create_aggregate(
self.admin_api, 'tenant-aggregate')
# Add two compute hosts to the tenant aggregate. We exclude host1
# since that is weighed higher in HostNameWeigher and we want to
# ensure the scheduler properly filters out host1 before we even get
# to weighing the selected hosts.
for host in ('host2', 'host3'):
self._add_host_to_aggregate(self.admin_api, tenant_aggregate, host)
# Restrict the non-admin project to the tenant aggregate.
self._isolate_aggregate(
self.admin_api, tenant_aggregate, uuids.user_project)
def test_cold_migrate_server(self):
"""Creates a server using the non-admin project, then cold migrates
the server and asserts the server goes to the other host in the
isolated host aggregate via the AggregateMultiTenancyIsolation filter.
"""
img = nova.tests.unit.image.fake.AUTO_DISK_CONFIG_ENABLED_IMAGE_UUID
server_req_body = self._build_minimal_create_server_request(
self.api, 'test_cold_migrate_server', image_uuid=img,
networks='none')
server = self.api.post_server({'server': server_req_body})
server = self._wait_for_state_change(self.admin_api, server, 'ACTIVE')
# Ensure the server ended up in host2 or host3
original_host = server['OS-EXT-SRV-ATTR:host']
self.assertNotEqual('host1', original_host)
# Now cold migrate the server and it should end up in the other host
# in the same tenant-isolated aggregate.
self.admin_api.api_post(
'/servers/%s/action' % server['id'], {'migrate': None})
server = self._wait_for_state_change(
self.admin_api, server, 'VERIFY_RESIZE')
# Ensure the server is on the other host in the same aggregate.
expected_host = 'host3' if original_host == 'host2' else 'host2'
self.assertEqual(expected_host, server['OS-EXT-SRV-ATTR:host'])