eb889886e2
There are two things that call the conductor task API's build_instances method: 1. nova-api when using cellsv1 2. nova-compute when rescheduling during a build failure Since we want to eventually replace the filter_properties usage in the compute service with the request_spec, this allows passing the request_spec from the compute service during a reschedule. For now we have to continue munging that RequestSpec a bit using the filter_properties for retries and the next chosen host from the scheduler, but that can eventually go away. With this, the computes can start to at least pull scheduler_hints out of the request_spec rather than the filter_properties, which is one more step in removing the compute's dependency on filter_properties. Note that we don't pass the request_spec from nova-api for cells v1, simply because cells v1 is deprecated. Part of blueprint request-spec-use-by-compute Change-Id: Ie5233bd481013413f12e55201588d37a9688ae78
80 lines
3.7 KiB
Python
80 lines
3.7 KiB
Python
# 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))
|
|
self.conductor = self.start_service('conductor')
|
|
self.start_service('scheduler')
|
|
self.compute = self.start_service('compute')
|
|
self.context = context.RequestContext('fake', 'fake')
|
|
fake_server_actions.stub_out_action_events(self)
|
|
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(max_attempts=3, group='scheduler')
|
|
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()
|
|
|
|
# Amongst others, mock the resource tracker, otherwise it will
|
|
# not have been sufficiently initialized and will raise a KeyError
|
|
# on the self.compute_nodes dict after the TestingException.
|
|
@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, '_get_resource_tracker')
|
|
@mock.patch.object(self.compute.manager.driver, 'spawn')
|
|
def _test(mock_spawn, mock_grt, 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}}
|
|
request_spec = objects.RequestSpec.from_primitives(
|
|
self.context, {}, filter_properties)
|
|
self.compute.manager.build_and_run_instance(
|
|
self.context, instance, {}, request_spec,
|
|
filter_properties, block_device_mapping=[])
|
|
_test()
|
|
self.assertIn('Preserve this', instance.fault.message)
|