224 lines
9.3 KiB
Python
224 lines
9.3 KiB
Python
# Copyright 2016 Huawei Technologies Co.,LTD.
|
|
# All Rights Reserved.
|
|
#
|
|
# 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.
|
|
|
|
"""Test class for Mogan ManagerService."""
|
|
|
|
import mock
|
|
from oslo_config import cfg
|
|
|
|
from mogan.common import exception
|
|
from mogan.engine.baremetal import ironic
|
|
from mogan.engine.baremetal import ironic_states
|
|
from mogan.engine import manager
|
|
from mogan.network import api as network_api
|
|
from mogan.tests.unit.db import base as tests_db_base
|
|
from mogan.tests.unit.engine import mgr_utils
|
|
from mogan.tests.unit.objects import utils as obj_utils
|
|
|
|
CONF = cfg.CONF
|
|
|
|
|
|
@mock.patch.object(manager.EngineManager, '_refresh_cache')
|
|
class ManageInstanceTestCase(mgr_utils.ServiceSetUpMixin,
|
|
tests_db_base.DbTestCase):
|
|
|
|
@mock.patch.object(ironic, 'unplug_vif')
|
|
@mock.patch.object(ironic, 'get_ports_from_node')
|
|
@mock.patch.object(network_api.API, 'delete_port')
|
|
def test_destroy_networks(self, delete_port_mock,
|
|
get_ports_mock, unplug_vif_mock,
|
|
refresh_cache_mock):
|
|
instance = obj_utils.create_test_instance(self.context)
|
|
delete_port_mock.side_effect = None
|
|
port = mock.MagicMock()
|
|
port.extra = {'vif_port_id': 'fake-vif'}
|
|
port.uuid = 'fake-uuid'
|
|
get_ports_mock.return_value = [port]
|
|
unplug_vif_mock.side_effect = None
|
|
refresh_cache_mock.side_effect = None
|
|
self._start_service()
|
|
|
|
self.service.destroy_networks(self.context, instance)
|
|
self._stop_service()
|
|
|
|
delete_port_mock.assert_called_once_with(
|
|
self.context, '2ea04c3d-6dc9-4285-836f-3b355008c84e',
|
|
instance.uuid)
|
|
get_ports_mock.assert_called_once_with(
|
|
mock.ANY, instance.node_uuid, detail=True)
|
|
unplug_vif_mock.assert_called_once_with(mock.ANY, 'fake-uuid')
|
|
|
|
@mock.patch.object(ironic, 'get_node_by_instance')
|
|
@mock.patch.object(ironic, 'destroy_node')
|
|
def _test__destroy_instance(self, destroy_node_mock,
|
|
get_node_mock, refresh_cache_mock,
|
|
state=None):
|
|
fake_node = mock.MagicMock()
|
|
fake_node.provision_state = state
|
|
get_node_mock.return_value = fake_node
|
|
instance = obj_utils.create_test_instance(self.context)
|
|
destroy_node_mock.side_effect = None
|
|
refresh_cache_mock.side_effect = None
|
|
self._start_service()
|
|
|
|
self.service._destroy_instance(self.context, instance)
|
|
self._stop_service()
|
|
|
|
get_node_mock.assert_called_once_with(mock.ANY, instance.uuid)
|
|
destroy_node_mock.assert_called_once_with(mock.ANY, instance.node_uuid)
|
|
|
|
def test__destroy_instance_cleaning(self, refresh_cache_mock):
|
|
self._test__destroy_instance(state=ironic_states.CLEANING,
|
|
refresh_cache_mock=refresh_cache_mock)
|
|
|
|
def test__destroy_instance_cleanwait(self, refresh_cache_mock):
|
|
self._test__destroy_instance(state=ironic_states.CLEANWAIT,
|
|
refresh_cache_mock=refresh_cache_mock)
|
|
|
|
@mock.patch.object(ironic, 'get_node_by_instance')
|
|
@mock.patch.object(ironic, 'destroy_node')
|
|
def test__destroy_instance_fail_max_retries(self, destroy_node_mock,
|
|
get_node_mock,
|
|
refresh_cache_mock):
|
|
CONF.set_default('api_max_retries', default=2, group='ironic')
|
|
fake_node = mock.MagicMock()
|
|
fake_node.provision_state = ironic_states.ACTIVE
|
|
get_node_mock.return_value = fake_node
|
|
instance = obj_utils.create_test_instance(self.context)
|
|
destroy_node_mock.side_effect = None
|
|
refresh_cache_mock.side_effect = None
|
|
self._start_service()
|
|
|
|
self.assertRaises(exception.MoganException,
|
|
self.service._destroy_instance,
|
|
self.context, instance)
|
|
self._stop_service()
|
|
|
|
self.assertTrue(get_node_mock.called)
|
|
destroy_node_mock.assert_called_once_with(mock.ANY, instance.node_uuid)
|
|
|
|
@mock.patch.object(ironic, 'get_node_by_instance')
|
|
@mock.patch.object(manager.EngineManager, '_destroy_instance')
|
|
@mock.patch.object(manager.EngineManager, 'destroy_networks')
|
|
def test_delete_instance(self, destroy_net_mock,
|
|
destroy_inst_mock, get_node_mock,
|
|
refresh_cache_mock):
|
|
fake_node = mock.MagicMock()
|
|
fake_node.provision_state = ironic_states.ACTIVE
|
|
instance = obj_utils.create_test_instance(self.context)
|
|
destroy_net_mock.side_effect = None
|
|
destroy_inst_mock.side_effect = None
|
|
refresh_cache_mock.side_effect = None
|
|
get_node_mock.return_value = fake_node
|
|
self._start_service()
|
|
|
|
self.service.delete_instance(self.context, instance)
|
|
self._stop_service()
|
|
|
|
destroy_net_mock.assert_called_once_with(mock.ANY, instance)
|
|
destroy_inst_mock.assert_called_once_with(mock.ANY, instance)
|
|
get_node_mock.assert_called_once_with(mock.ANY, instance.uuid)
|
|
|
|
@mock.patch.object(ironic, 'get_node_by_instance')
|
|
@mock.patch.object(manager.EngineManager, '_destroy_instance')
|
|
def test_delete_instance_without_node_destroy(
|
|
self, destroy_inst_mock, get_node_mock, refresh_cache_mock):
|
|
fake_node = mock.MagicMock()
|
|
fake_node.provision_state = 'foo'
|
|
instance = obj_utils.create_test_instance(self.context)
|
|
destroy_inst_mock.side_effect = None
|
|
refresh_cache_mock.side_effect = None
|
|
get_node_mock.return_value = fake_node
|
|
self._start_service()
|
|
|
|
self.service.delete_instance(self.context, instance)
|
|
self._stop_service()
|
|
|
|
self.assertFalse(destroy_inst_mock.called)
|
|
|
|
@mock.patch.object(ironic, 'get_node_by_instance')
|
|
@mock.patch.object(ironic, 'set_power_state')
|
|
def test_change_instance_power_state(
|
|
self, set_power_mock, get_node_mock, refresh_cache_mock):
|
|
instance = obj_utils.create_test_instance(self.context)
|
|
fake_node = mock.MagicMock()
|
|
fake_node.target_power_state = ironic_states.NOSTATE
|
|
get_node_mock.return_value = fake_node
|
|
refresh_cache_mock.side_effect = None
|
|
self._start_service()
|
|
|
|
self.service.set_power_state(self.context, instance,
|
|
ironic_states.POWER_ON)
|
|
self._stop_service()
|
|
|
|
set_power_mock.assert_called_once_with(mock.ANY, instance.node_uuid,
|
|
ironic_states.POWER_ON)
|
|
get_node_mock.assert_called_once_with(mock.ANY, instance.uuid)
|
|
|
|
@mock.patch.object(ironic, 'get_node_states')
|
|
def test_get_instance_states(self, get_states_mock, refresh_cache_mock):
|
|
instance = obj_utils.create_test_instance(self.context)
|
|
get_states_mock.return_value = mock.MagicMock()
|
|
refresh_cache_mock.side_effect = None
|
|
self._start_service()
|
|
|
|
self.service.instance_states(self.context, instance)
|
|
self._stop_service()
|
|
|
|
get_states_mock.assert_called_once_with(mock.ANY, instance.node_uuid)
|
|
|
|
@mock.patch.object(ironic, 'get_node_by_instance')
|
|
def test_get_ironic_node(self, get_node_mock, refresh_cache_mock):
|
|
instance = obj_utils.create_test_instance(self.context)
|
|
get_node_mock.return_value = mock.MagicMock()
|
|
refresh_cache_mock.side_effect = None
|
|
self._start_service()
|
|
|
|
self.service.get_ironic_node(self.context, instance.uuid, [])
|
|
self._stop_service()
|
|
|
|
get_node_mock.assert_called_once_with(mock.ANY, instance.uuid, [])
|
|
|
|
@mock.patch.object(ironic, 'get_node_list')
|
|
def test_get_ironic_node_list(self, get_node_list_mock,
|
|
refresh_cache_mock):
|
|
get_node_list_mock.return_value = mock.MagicMock()
|
|
refresh_cache_mock.side_effect = None
|
|
self._start_service()
|
|
|
|
self.service.get_ironic_node_list(self.context, [])
|
|
self._stop_service()
|
|
|
|
get_node_list_mock.assert_called_once_with(mock.ANY, associated=True,
|
|
limit=0, fields=[])
|
|
|
|
def test_list_availability_zone(self, refresh_cache_mock):
|
|
refresh_cache_mock.side_effect = None
|
|
node1 = mock.MagicMock()
|
|
node2 = mock.MagicMock()
|
|
node3 = mock.MagicMock()
|
|
node1.properties = {'availability_zone': 'az1'}
|
|
node2.properties = {'availability_zone': 'az2'}
|
|
node3.properties = {'availability_zone': 'az1'}
|
|
|
|
self._start_service()
|
|
self.service.node_cache = {'node1_id': node1,
|
|
'node2_id': node2,
|
|
'node3_id': node3}
|
|
azs = self.service.list_availability_zones(self.context)
|
|
self._stop_service()
|
|
|
|
self.assertItemsEqual(['az1', 'az2'], azs['availability_zones'])
|