diff --git a/nova/cmd/manage.py b/nova/cmd/manage.py index c6482e2b980c..f23b52cff584 100644 --- a/nova/cmd/manage.py +++ b/nova/cmd/manage.py @@ -38,6 +38,7 @@ from oslo_config import cfg from oslo_db import exception as db_exc from oslo_log import log as logging import oslo_messaging as messaging +from oslo_serialization import jsonutils from oslo_utils import encodeutils from oslo_utils import importutils from oslo_utils import uuidutils @@ -2168,16 +2169,19 @@ class PlacementCommands(object): if need_healing: if dry_run: + # json dump the allocation dict as it contains nested default + # dicts that is pretty hard to read in the verbose output + alloc = jsonutils.dumps(allocations) if need_healing == _CREATE: output(_('[dry-run] Create allocations for instance ' '%(instance)s: %(allocations)s') % {'instance': instance.uuid, - 'allocations': allocations}) + 'allocations': alloc}) elif need_healing == _UPDATE: output(_('[dry-run] Update allocations for instance ' '%(instance)s: %(allocations)s') % {'instance': instance.uuid, - 'allocations': allocations}) + 'allocations': alloc}) else: # First update ports in neutron. If any of those operations # fail, then roll back the successful part of it and fail the diff --git a/nova/tests/functional/test_nova_manage.py b/nova/tests/functional/test_nova_manage.py index d913c180ce70..2bdf3884ab3e 100644 --- a/nova/tests/functional/test_nova_manage.py +++ b/nova/tests/functional/test_nova_manage.py @@ -880,6 +880,25 @@ class TestNovaManagePlacementHealPortAllocations( self.output.getvalue()) self.assertEqual(0, result) + def test_heal_port_allocation_dry_run(self): + server, ports = self._create_server_with_missing_port_alloc( + [self.neutron.port_1]) + + # let's trigger a heal + result = self.cli.heal_allocations( + verbose=True, max_count=2, dry_run=True) + + self._assert_placement_not_updated(server) + self._assert_ports_not_updated(ports) + + self.assertIn( + '[dry-run] Update allocations for instance', + self.output.getvalue()) + # Note that we had a issues by printing defaultdicts directly to the + # user in the past. So let's assert it does not happen any more. + self.assertNotIn('defaultdict', self.output.getvalue()) + self.assertEqual(4, result) + def test_no_healing_is_needed(self): """Test that the instance has a port that has allocations so nothing to be healed.