diff options
author | Zuul <zuul@review.opendev.org> | 2020-03-30 12:01:33 +0000 |
---|---|---|
committer | Gerrit Code Review <review@openstack.org> | 2020-03-30 12:01:33 +0000 |
commit | fe66c28dac64e467c3c75aa37401366bfbb3db4e (patch) | |
tree | bfeb0ccece0d083d454819f852953edc96847f67 /nova/tests/unit/cmd/test_manage.py | |
parent | 54973653863adefdb730fcb087685a09913874dc (diff) | |
parent | c03716be1f3e9fd5a5e9adf95860c7ce4bfe211f (diff) | |
download | nova-fe66c28dac64e467c3c75aa37401366bfbb3db4e.tar.gz |
Merge "Add a placement audit command"
Diffstat (limited to 'nova/tests/unit/cmd/test_manage.py')
-rw-r--r-- | nova/tests/unit/cmd/test_manage.py | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/nova/tests/unit/cmd/test_manage.py b/nova/tests/unit/cmd/test_manage.py index 8f70352d4b..87d901f5e9 100644 --- a/nova/tests/unit/cmd/test_manage.py +++ b/nova/tests/unit/cmd/test_manage.py @@ -34,6 +34,7 @@ from nova.db import migration from nova.db.sqlalchemy import migration as sqla_migration from nova import exception from nova import objects +from nova.scheduler.client import report from nova import test from nova.tests import fixtures as nova_fixtures from nova.tests.unit import fake_requests @@ -2860,6 +2861,142 @@ class TestNovaManagePlacement(test.NoDBTestCase): neutron.update_port.assert_called_once_with( uuidsentinel.port_id, body=expected_update_body) + def test_audit_with_wrong_provider_uuid(self): + with mock.patch.object( + self.cli, '_get_resource_provider', + side_effect=exception.ResourceProviderNotFound( + name_or_uuid=uuidsentinel.fake_uuid)): + ret = self.cli.audit( + provider_uuid=uuidsentinel.fake_uuid) + self.assertEqual(127, ret) + output = self.output.getvalue() + self.assertIn( + 'Resource provider with UUID %s' % uuidsentinel.fake_uuid, + output) + + @mock.patch.object(manage.PlacementCommands, + '_check_orphaned_allocations_for_provider') + @mock.patch('nova.scheduler.client.report.SchedulerReportClient.get') + def _test_audit(self, get_resource_providers, check_orphaned_allocs, + verbose=False, delete=False, errors=False, found=False): + rps = [ + {"generation": 1, + "uuid": uuidsentinel.rp1, + "links": None, + "name": "rp1", + "parent_provider_uuid": None, + "root_provider_uuid": uuidsentinel.rp1}, + {"generation": 1, + "uuid": uuidsentinel.rp2, + "links": None, + "name": "rp2", + "parent_provider_uuid": None, + "root_provider_uuid": uuidsentinel.rp2}, + ] + get_resource_providers.return_value = fake_requests.FakeResponse( + 200, content=jsonutils.dumps({"resource_providers": rps})) + + if errors: + # We found one orphaned allocation per RP but RP1 got a fault + check_orphaned_allocs.side_effect = ((1, 1), (1, 0)) + elif found: + # we found one orphaned allocation per RP and we had no faults + check_orphaned_allocs.side_effect = ((1, 0), (1, 0)) + else: + # No orphaned allocations are found for all the RPs + check_orphaned_allocs.side_effect = ((0, 0), (0, 0)) + + ret = self.cli.audit(verbose=verbose, delete=delete) + if errors: + # Any fault stops the audit and provides a return code equals to 1 + expected_ret = 1 + elif found and delete: + # We found orphaned allocations and deleted them + expected_ret = 4 + elif found and not delete: + # We found orphaned allocations but we left them + expected_ret = 3 + else: + # Nothing was found + expected_ret = 0 + self.assertEqual(expected_ret, ret) + + call1 = mock.call(mock.ANY, mock.ANY, mock.ANY, rps[0], delete) + call2 = mock.call(mock.ANY, mock.ANY, mock.ANY, rps[1], delete) + if errors: + # We stop checking other RPs once we got a fault + check_orphaned_allocs.assert_has_calls([call1]) + else: + # All the RPs are checked + check_orphaned_allocs.assert_has_calls([call1, call2]) + + if verbose and found: + output = self.output.getvalue() + self.assertIn('Processed 2 allocations', output) + if errors: + output = self.output.getvalue() + self.assertIn( + 'The Resource Provider %s had problems' % rps[0]["uuid"], + output) + + def test_audit_not_found_orphaned_allocs(self): + self._test_audit(found=False) + + def test_audit_found_orphaned_allocs_not_verbose(self): + self._test_audit(found=True) + + def test_audit_found_orphaned_allocs_verbose(self): + self._test_audit(found=True, verbose=True) + + def test_audit_found_orphaned_allocs_and_deleted_them(self): + self._test_audit(found=True, delete=True) + + def test_audit_found_orphaned_allocs_but_got_errors(self): + self._test_audit(errors=True) + + @mock.patch.object(manage.PlacementCommands, + '_delete_allocations_from_consumer') + @mock.patch('nova.scheduler.client.report.SchedulerReportClient.' + 'get_allocations_for_resource_provider') + @mock.patch.object(manage.PlacementCommands, + '_get_instances_and_current_migrations') + def test_check_orphaned_allocations_for_provider(self, + get_insts_and_migs, + get_allocs_for_rp, + delete_allocs): + provider = {"generation": 1, + "uuid": uuidsentinel.rp1, + "links": None, + "name": "rp1", + "parent_provider_uuid": None, + "root_provider_uuid": uuidsentinel.rp1} + compute_resources = {'VCPU': 1, 'MEMORY_MB': 2048, 'DISK_GB': 20} + allocations = { + # Some orphaned compute allocation + uuidsentinel.orphaned_alloc1: {'resources': compute_resources}, + # Some existing instance allocation + uuidsentinel.inst1: {'resources': compute_resources}, + # Some existing migration allocation + uuidsentinel.mig1: {'resources': compute_resources}, + # Some other allocation not related to Nova + uuidsentinel.other_alloc1: {'resources': {'CUSTOM_GOO'}}, + } + + get_insts_and_migs.return_value = ( + [uuidsentinel.inst1], + [uuidsentinel.mig1]) + get_allocs_for_rp.return_value = report.ProviderAllocInfo(allocations) + + ctxt = context.RequestContext() + placement = report.SchedulerReportClient() + ret = self.cli._check_orphaned_allocations_for_provider( + ctxt, placement, lambda x: x, provider, True) + get_allocs_for_rp.assert_called_once_with(ctxt, uuidsentinel.rp1) + delete_allocs.assert_called_once_with(ctxt, placement, provider, + uuidsentinel.orphaned_alloc1, + 'instance') + self.assertEqual((1, 0), ret) + class TestNovaManageMain(test.NoDBTestCase): """Tests the nova-manage:main() setup code.""" |