251 lines
9.2 KiB
Python
251 lines
9.2 KiB
Python
# Copyright 2015 Red Hat, Inc.
|
|
#
|
|
# 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 uuid import uuid4
|
|
|
|
from osc_lib.tests import utils
|
|
|
|
from tripleoclient.tests.v1.overcloud_deploy import fakes
|
|
from tripleoclient.v1 import overcloud_deploy
|
|
|
|
|
|
class TestDeployValidators(fakes.TestDeployOvercloud):
|
|
def setUp(self):
|
|
super(TestDeployValidators, self).setUp()
|
|
|
|
# Get the command object to test
|
|
self.cmd = overcloud_deploy.DeployOvercloud(self.app, None)
|
|
|
|
@mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.'
|
|
'_check_node_boot_configuration')
|
|
def test_ironic_boot_checks(self, mock_node_boot_check):
|
|
class FakeNode(object):
|
|
uuid = None
|
|
|
|
def __init__(self, uuid):
|
|
self.uuid = uuid
|
|
|
|
bm_client = self.app.client_manager.baremetal
|
|
mock_node = mock.Mock()
|
|
bm_client.attach_mock(mock_node, 'node')
|
|
|
|
fake_nodes = [FakeNode(uuid) for uuid in (
|
|
'97dd6459-cf2d-4eea-865e-84fee3bf5e6d',
|
|
'1867d71b-d0a5-44c6-b83e-ada8b16de556'
|
|
)]
|
|
# return a list of FakeNodes, replaces bm_client.node.list
|
|
mock_maint_nodes = mock.Mock(return_value=fake_nodes)
|
|
mock_node.attach_mock(mock_maint_nodes, 'list')
|
|
|
|
# get a FakeNode by its UUID, replaces bm_client.node.get
|
|
|
|
self.cmd.baremetal_client = bm_client
|
|
self.cmd._check_ironic_boot_configuration()
|
|
|
|
mock_maint_nodes.assert_called_once_with(detail=True,
|
|
maintenance=False)
|
|
|
|
def test_image_ids(self):
|
|
image_client = self.app.client_manager.image
|
|
image_client.images = {}
|
|
image_ids = self.cmd._image_ids()
|
|
|
|
image_client.images = {
|
|
'bm-deploy-kernel':
|
|
mock.Mock(id='fb7a98fb-acb9-43ec-9b93-525d1286f9d8'),
|
|
'bm-deploy-ramdisk':
|
|
mock.Mock(id='8558de2e-1b72-4654-8ba9-cceb89e9194e'),
|
|
}
|
|
|
|
image_ids = self.cmd._image_ids()
|
|
self.assertEqual(image_ids, ('fb7a98fb-acb9-43ec-9b93-525d1286f9d8',
|
|
'8558de2e-1b72-4654-8ba9-cceb89e9194e'))
|
|
|
|
@mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.'
|
|
'_image_ids',
|
|
return_value=('fb7a98fb-acb9-43ec-9b93-525d1286f9d8',
|
|
'8558de2e-1b72-4654-8ba9-cceb89e9194e'))
|
|
def test_node_boot_checks(self, mock_image_ids):
|
|
class FakeNode(object):
|
|
uuid = 'fake-node-123'
|
|
driver_info = None
|
|
properties = None
|
|
|
|
node = FakeNode()
|
|
node.driver_info = {
|
|
'deploy_kernel': 'fb7a98fb-acb9-43ec-9b93-525d1286f9d8',
|
|
'deploy_ramdisk': '8558de2e-1b72-4654-8ba9-cceb89e9194e',
|
|
}
|
|
node.properties = {
|
|
'capabilities': 'boot_option:local,profile:foobar'
|
|
}
|
|
self.cmd._check_node_boot_configuration(node)
|
|
self.assertEqual(self.cmd.predeploy_errors, 0)
|
|
self.assertEqual(self.cmd.predeploy_warnings, 0)
|
|
|
|
node.properties['capabilities'] = 'profile:foobar'
|
|
self.cmd._check_node_boot_configuration(node)
|
|
self.assertEqual(self.cmd.predeploy_errors, 0)
|
|
self.assertEqual(self.cmd.predeploy_warnings, 1)
|
|
|
|
node.properties['capabilities'] = 'profile:foobar,boot_option:local'
|
|
node.driver_info.pop('deploy_kernel')
|
|
self.cmd._check_node_boot_configuration(node)
|
|
self.assertEqual(self.cmd.predeploy_errors, 1)
|
|
self.assertEqual(self.cmd.predeploy_warnings, 1)
|
|
|
|
@mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.'
|
|
'_image_ids',
|
|
return_value=('fb7a98fb-acb9-43ec-9b93-525d1286f9d8',
|
|
'8558de2e-1b72-4654-8ba9-cceb89e9194e'))
|
|
def test_boot_image_checks(self, mock_image_ids):
|
|
self.cmd._check_boot_images()
|
|
self.assertEqual(self.cmd.predeploy_errors, 0)
|
|
self.assertEqual(self.cmd.predeploy_warnings, 0)
|
|
|
|
mock_image_ids.return_value = (
|
|
None, '8558de2e-1b72-4654-8ba9-cceb89e9194e')
|
|
self.cmd._check_boot_images()
|
|
self.assertEqual(self.cmd.predeploy_errors, 1)
|
|
self.assertEqual(self.cmd.predeploy_warnings, 0)
|
|
|
|
mock_image_ids.return_value = (
|
|
'8558de2e-1b72-4654-8ba9-cceb89e9194e', None)
|
|
self.cmd._check_boot_images()
|
|
self.assertEqual(self.cmd.predeploy_errors, 2)
|
|
self.assertEqual(self.cmd.predeploy_warnings, 0)
|
|
|
|
|
|
class FakeFlavor(object):
|
|
name = ''
|
|
uuid = ''
|
|
|
|
def __init__(self, name):
|
|
self.uuid = uuid4()
|
|
self.name = name
|
|
|
|
def get_keys(self):
|
|
return {'capabilities:boot_option': 'local'}
|
|
|
|
|
|
class TestCollectFlavors(fakes.TestDeployOvercloud):
|
|
def setUp(self):
|
|
super(TestCollectFlavors, self).setUp()
|
|
self.cmd = overcloud_deploy.DeployOvercloud(self.app, None)
|
|
self.arglist = [
|
|
'--block-storage-flavor', 'block',
|
|
'--block-storage-scale', '3',
|
|
'--ceph-storage-flavor', 'ceph',
|
|
'--ceph-storage-scale', '0',
|
|
'--compute-flavor', 'compute',
|
|
'--compute-scale', '3',
|
|
'--control-flavor', 'control',
|
|
'--control-scale', '1',
|
|
'--swift-storage-flavor', 'swift',
|
|
'--swift-storage-scale', '2',
|
|
'--templates'
|
|
]
|
|
self.verifylist = [
|
|
('templates', '/usr/share/openstack-tripleo-heat-templates/'),
|
|
]
|
|
|
|
self.mock_flavors = mock.Mock()
|
|
self.app.client_manager.compute.attach_mock(self.mock_flavors,
|
|
'flavors')
|
|
|
|
def test_ok(self):
|
|
parsed_args = self.check_parser(self.cmd, self.arglist,
|
|
self.verifylist)
|
|
|
|
expected_result = {
|
|
'block': (FakeFlavor('block'), 3),
|
|
'compute': (FakeFlavor('compute'), 3),
|
|
'control': (FakeFlavor('control'), 1),
|
|
'swift': (FakeFlavor('swift'), 2)
|
|
}
|
|
mock_flavor_list = mock.Mock(
|
|
return_value=[
|
|
flavor for flavor, scale in expected_result.values()
|
|
]
|
|
)
|
|
self.mock_flavors.attach_mock(mock_flavor_list, 'list')
|
|
|
|
result = self.cmd._collect_flavors(parsed_args)
|
|
self.assertEqual(self.cmd.predeploy_errors, 0)
|
|
self.assertEqual(self.cmd.predeploy_warnings, 0)
|
|
self.assertEqual(expected_result, result)
|
|
|
|
def test_flavor_not_found(self):
|
|
parsed_args = self.check_parser(self.cmd, self.arglist,
|
|
self.verifylist)
|
|
|
|
expected_result = {
|
|
'block': (FakeFlavor('block'), 3),
|
|
'compute': (FakeFlavor('compute'), 3),
|
|
'control': (FakeFlavor('control'), 1),
|
|
}
|
|
mock_flavor_list = mock.Mock(
|
|
return_value=[
|
|
flavor for flavor, scale in expected_result.values()
|
|
]
|
|
)
|
|
self.mock_flavors.attach_mock(mock_flavor_list, 'list')
|
|
result = self.cmd._collect_flavors(parsed_args)
|
|
self.assertEqual(self.cmd.predeploy_errors, 1)
|
|
self.assertEqual(self.cmd.predeploy_warnings, 0)
|
|
self.assertEqual(expected_result, result)
|
|
|
|
def test_same_flavor(self):
|
|
self.arglist = [
|
|
'--compute-flavor', 'baremetal',
|
|
'--compute-scale', '3',
|
|
'--control-flavor', 'baremetal',
|
|
'--control-scale', '1',
|
|
'--templates'
|
|
]
|
|
parsed_args = self.check_parser(self.cmd, self.arglist,
|
|
self.verifylist)
|
|
|
|
expected_result = {
|
|
'baremetal': (FakeFlavor('baremetal'), 4),
|
|
}
|
|
mock_flavor_list = mock.Mock(
|
|
return_value=[
|
|
flavor for flavor, scale in expected_result.values()
|
|
]
|
|
)
|
|
self.mock_flavors.attach_mock(mock_flavor_list, 'list')
|
|
|
|
result = self.cmd._collect_flavors(parsed_args)
|
|
self.assertEqual(self.cmd.predeploy_errors, 0)
|
|
self.assertEqual(self.cmd.predeploy_warnings, 0)
|
|
self.assertEqual(expected_result, result)
|
|
|
|
def test_error_default(self):
|
|
self.check_parser(self.cmd, ['--templates'],
|
|
[('validation_errors_fatal', True)])
|
|
|
|
def test_error_nonfatal(self):
|
|
self.check_parser(self.cmd,
|
|
['--templates', '--validation-errors-nonfatal'],
|
|
[('validation_errors_fatal', False)])
|
|
|
|
def test_error_exclusive(self):
|
|
self.assertRaises(utils.ParserException,
|
|
self.check_parser, self.cmd,
|
|
['--templates', '--validation-errors-nonfatal',
|
|
'--validation-errors-fatal'], [])
|