5edb14b238
Originally these functions were include in tripleoclient but as they can be useful for CI and other places (mistral, etc), this change moves the role validation and generation code into tripleo-common. Change-Id: If47bc113f66f57eb1d66f581e42de15d3ad80cb4 Related-Blueprint: example-custom-role-environments
122 lines
4.8 KiB
Python
122 lines
4.8 KiB
Python
# Copyright 2017 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
|
|
import yaml
|
|
|
|
from tripleo_common.exception import NotFound
|
|
from tripleo_common.exception import RoleMetadataError
|
|
from tripleo_common.tests import base
|
|
from tripleo_common.utils import roles as rolesutils
|
|
|
|
SAMPLE_ROLE = """
|
|
###############################################################################
|
|
# Role: sample #
|
|
###############################################################################
|
|
- name: sample
|
|
description: |
|
|
Sample!
|
|
networks:
|
|
- InternalApi
|
|
HostnameFormatDefault: '%stackname%-sample-%index%'
|
|
ServicesDefault:
|
|
- OS::TripleO::Services::Ntp
|
|
"""
|
|
SAMPLE_ROLE_OBJ = {
|
|
'HostnameFormatDefault': '%stackname%-sample-%index%',
|
|
'ServicesDefault': ['OS::TripleO::Services::Ntp'],
|
|
'description': 'Sample!\n',
|
|
'name': 'sample',
|
|
'networks': ['InternalApi']
|
|
}
|
|
|
|
|
|
class TestRolesUtils(base.TestCase):
|
|
@mock.patch('os.listdir')
|
|
@mock.patch('os.path.exists')
|
|
def test_get_roles_from_directory(self, exists_mock, listdir_mock):
|
|
exists_mock.return_value = True
|
|
listdir_mock.return_value = ['b.yaml', 'a.yaml']
|
|
self.assertEqual(rolesutils.get_roles_list_from_directory('/foo'),
|
|
['a', 'b'])
|
|
|
|
@mock.patch('os.listdir')
|
|
@mock.patch('os.path.exists')
|
|
def test_get_roles_from_directory_failure(self, exists_mock, listdir_mock):
|
|
exists_mock.return_value = False
|
|
self.assertRaises(ValueError, rolesutils.get_roles_list_from_directory,
|
|
['/foo'])
|
|
|
|
def test_validate_roles(self):
|
|
available_roles = ['a', 'b', 'c']
|
|
requested_roles = ['b', 'c']
|
|
try:
|
|
rolesutils.check_role_exists(available_roles, requested_roles)
|
|
except Exception:
|
|
self.fail('Exception raised')
|
|
|
|
def test_validate_roles_with_invalid_role(self):
|
|
available_roles = ['a', 'b', 'c']
|
|
requested_roles = ['b', 'd']
|
|
self.assertRaises(NotFound, rolesutils.check_role_exists,
|
|
available_roles, requested_roles)
|
|
|
|
@mock.patch('tripleo_common.utils.roles.check_role_exists')
|
|
@mock.patch('tripleo_common.utils.roles.get_roles_list_from_directory')
|
|
def test_generate_roles_data_from_directory(self, get_roles_mock,
|
|
check_mock):
|
|
get_roles_mock.return_value = ['foo', 'bar', 'baz']
|
|
m = mock.mock_open(read_data=SAMPLE_ROLE)
|
|
with mock.patch('tripleo_common.utils.roles.open', m) as open_mock:
|
|
r = rolesutils.generate_roles_data_from_directory('/foo',
|
|
['foo', 'bar'])
|
|
open_mock.assert_any_call('/foo/foo.yaml', 'r')
|
|
open_mock.assert_any_call('/foo/bar.yaml', 'r')
|
|
|
|
header = '\n'.join(["#" * 79,
|
|
"# File generated by TripleO",
|
|
"#" * 79,
|
|
""])
|
|
expected = header + SAMPLE_ROLE * 2
|
|
self.assertEqual(expected, r)
|
|
get_roles_mock.assert_called_with('/foo')
|
|
check_mock.assert_called_with(['foo', 'bar', 'baz'], ['foo', 'bar'])
|
|
|
|
def test_validate_role_yaml(self):
|
|
role = rolesutils.validate_role_yaml(SAMPLE_ROLE)
|
|
self.assertEqual(SAMPLE_ROLE_OBJ, role)
|
|
|
|
def test_validate_role_yaml_with_file(self):
|
|
m = mock.mock_open(read_data=SAMPLE_ROLE)
|
|
with mock.patch('tripleo_common.utils.roles.open', m):
|
|
r = rolesutils.validate_role_yaml(role_path='/foo.yaml')
|
|
self.assertEqual(SAMPLE_ROLE_OBJ, r)
|
|
|
|
def test_validate_role_yaml_invalid_params(self):
|
|
self.assertRaises(ValueError, rolesutils.validate_role_yaml, 'foo',
|
|
'bar')
|
|
|
|
def test_validate_role_yaml_missing_name(self):
|
|
role = yaml.safe_load(SAMPLE_ROLE)
|
|
del role[0]['name']
|
|
self.assertRaises(RoleMetadataError, rolesutils.validate_role_yaml,
|
|
yaml.dump(role))
|
|
|
|
def test_validate_role_yaml_invalid_type(self):
|
|
role = yaml.safe_load(SAMPLE_ROLE)
|
|
role[0]['CountDefault'] = 'should not be a string'
|
|
self.assertRaises(RoleMetadataError, rolesutils.validate_role_yaml,
|
|
yaml.dump(role))
|