new_contents: #    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 mock
  from oslo_config import cfg
  
  from nova import context
  from nova import objects
  from nova import test
  from nova.tests import fixtures
  from nova.tests.unit import cast_as_call
  from nova.tests.unit import fake_network
  from nova.tests.unit import fake_server_actions
  
  
  CONF = cfg.CONF
  
  
  class ComputeManagerTestCase(test.TestCase):
      def setUp(self):
          super(ComputeManagerTestCase, self).setUp()
          self.useFixture(fixtures.SpawnIsSynchronousFixture())
          self.useFixture(cast_as_call.CastAsCall(self.stubs))
          self.conductor = self.start_service('conductor',
                                              manager=CONF.conductor.manager)
          self.start_service('scheduler')
          self.compute = self.start_service('compute')
          self.context = context.RequestContext('fake', 'fake')
          fake_server_actions.stub_out_action_events(self.stubs)
          fake_network.set_stub_network_methods(self)
  
      def test_instance_fault_message_no_traceback_with_retry(self):
          """This test simulates a spawn failure on the last retry attempt.
  
          If driver spawn raises an exception on the last retry attempt, the
          instance fault message should not contain a traceback for the
          last exception. The fault message field is limited in size and a long
          message with a traceback displaces the original error message.
          """
          self.flags(scheduler_max_attempts=3)
          flavor = objects.Flavor(
                  id=1, name='flavor1', memory_mb=256, vcpus=1, root_gb=1,
                  ephemeral_gb=1, flavorid='1', swap=0, rxtx_factor=1.0,
                  vcpu_weight=1, disabled=False, is_public=True, extra_specs={},
                  projects=[])
          instance = objects.Instance(self.context, flavor=flavor, vcpus=1,
                                      memory_mb=256, root_gb=0, ephemeral_gb=0,
                                      project_id='fake')
          instance.create()
  
          @mock.patch.object(self.conductor.manager.compute_task_mgr,
                             '_cleanup_allocated_networks')
          @mock.patch.object(self.compute.manager.network_api,
                             'cleanup_instance_network_on_host')
          @mock.patch('nova.compute.utils.notify_about_instance_usage')
          @mock.patch.object(self.compute.manager.driver, 'spawn')
          def _test(mock_spawn, mock_notify, mock_cinoh, mock_can):
              mock_spawn.side_effect = test.TestingException('Preserve this')
              # Simulate that we're on the last retry attempt
              filter_properties = {'retry': {'num_attempts': 3}}
              self.compute.manager.build_and_run_instance(
                      self.context, instance, {}, {}, filter_properties,
                      block_device_mapping=[])
          _test()
          self.assertIn('Preserve this', instance.fault.message)
  
subject: Add a functional test for instance fault message with retry