
This patch set changes Pegleg in two similar ways: 1) Ignore certain types of files altogether: - those located in hidden folders - those prefixed with "." (files like .zuul.yaml) 2) Only read Deckhand-formatted documents for lint/collect/etc. commands as Pegleg need not consider other types of documents (it separately reads the site-definition.yaml for internal processing still). The tools/ subfolder is also ignored as it can contain .yaml files which are not Deckhand-formatted documents, so need not be processed by pegleg.engine. Change-Id: I8996b5d430cf893122af648ef8e5805b36c1bfd9
220 lines
7.8 KiB
Python
220 lines
7.8 KiB
Python
# Copyright 2018 AT&T Intellectual Property. All other 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.
|
|
|
|
import mock
|
|
|
|
from pegleg.engine import lint
|
|
from pegleg.engine.errorcodes import DECKHAND_DUPLICATE_SCHEMA
|
|
from pegleg.engine.errorcodes import DECKHAND_RENDER_EXCEPTION
|
|
from pegleg.engine.util import deckhand
|
|
from pegleg.engine.util import files
|
|
from tests.unit.fixtures import create_tmp_deployment_files
|
|
|
|
|
|
def test_verify_deckhand_render_site_documents_separately(
|
|
create_tmp_deployment_files):
|
|
expected_documents = {
|
|
'cicd': [
|
|
'global-common', 'global-v1.0', 'cicd-type-common',
|
|
'cicd-type-v1.0', 'cicd-chart', 'cicd-passphrase'
|
|
],
|
|
'lab': [
|
|
'global-common', 'global-v1.0', 'lab-type-common', 'lab-type-v1.0',
|
|
'lab-chart', 'lab-passphrase'
|
|
],
|
|
}
|
|
|
|
with mock.patch(
|
|
'pegleg.engine.util.deckhand.deckhand_render',
|
|
autospec=True) as mock_render:
|
|
mock_render.return_value = (None, [])
|
|
|
|
result = lint._verify_deckhand_render()
|
|
assert result == []
|
|
|
|
expected_sitenames = ['cicd', 'lab']
|
|
sites = files.list_sites()
|
|
|
|
# Verify that both expected site types are listed.
|
|
assert sorted(sites) == expected_sitenames
|
|
# Verify that Deckhand called render twice, once for each site.
|
|
assert mock_render.call_count == 2
|
|
|
|
expected_documents = []
|
|
for sitename in expected_sitenames:
|
|
documents = [{
|
|
'data': 'global-common-password',
|
|
'metadata': {
|
|
'layeringDefinition': {
|
|
'abstract': False,
|
|
'layer': 'global'
|
|
},
|
|
'name': 'global-common',
|
|
'schema': 'metadata/Document/v1',
|
|
'storagePolicy': 'cleartext'
|
|
},
|
|
'schema': 'deckhand/Passphrase/v1'
|
|
}, {
|
|
'data': 'global-v1.0-password',
|
|
'metadata': {
|
|
'layeringDefinition': {
|
|
'abstract': False,
|
|
'layer': 'global'
|
|
},
|
|
'name': 'global-v1.0',
|
|
'schema': 'metadata/Document/v1',
|
|
'storagePolicy': 'cleartext'
|
|
},
|
|
'schema': 'deckhand/Passphrase/v1'
|
|
}, {
|
|
'data': '%s-type-common-password' % sitename,
|
|
'metadata': {
|
|
'layeringDefinition': {
|
|
'abstract': False,
|
|
'layer': 'type'
|
|
},
|
|
'name': '%s-type-common' % sitename,
|
|
'schema': 'metadata/Document/v1',
|
|
'storagePolicy': 'cleartext'
|
|
},
|
|
'schema': 'deckhand/Passphrase/v1'
|
|
}, {
|
|
'data': '%s-type-v1.0-password' % sitename,
|
|
'metadata': {
|
|
'layeringDefinition': {
|
|
'abstract': False,
|
|
'layer': 'type'
|
|
},
|
|
'name': '%s-type-v1.0' % sitename,
|
|
'schema': 'metadata/Document/v1',
|
|
'storagePolicy': 'cleartext'
|
|
},
|
|
'schema': 'deckhand/Passphrase/v1'
|
|
}, {
|
|
'data': '%s-chart-password' % sitename,
|
|
'metadata': {
|
|
'layeringDefinition': {
|
|
'abstract': False,
|
|
'layer': 'site'
|
|
},
|
|
'name': '%s-chart' % sitename,
|
|
'schema': 'metadata/Document/v1',
|
|
'storagePolicy': 'cleartext'
|
|
},
|
|
'schema': 'deckhand/Passphrase/v1'
|
|
}, {
|
|
'data': '%s-passphrase-password' % sitename,
|
|
'metadata': {
|
|
'layeringDefinition': {
|
|
'abstract': False,
|
|
'layer': 'site'
|
|
},
|
|
'name': '%s-passphrase' % sitename,
|
|
'schema': 'metadata/Document/v1',
|
|
'storagePolicy': 'cleartext'
|
|
},
|
|
'schema': 'deckhand/Passphrase/v1'
|
|
}]
|
|
expected_documents.extend(documents)
|
|
|
|
mock_calls = list(mock_render.mock_calls)
|
|
actual_documents = []
|
|
for mock_call in mock_calls:
|
|
documents = mock_call[2]['documents']
|
|
actual_documents.extend(documents)
|
|
|
|
sort_func = lambda x: x['metadata']['name']
|
|
assert sorted(
|
|
expected_documents, key=sort_func) == sorted(
|
|
actual_documents, key=sort_func)
|
|
|
|
|
|
@mock.patch('pegleg.engine.util.deckhand.deckhand_render')
|
|
def test_verify_deckhand_render_error_handling(mock_render):
|
|
"""
|
|
Verifying deckhand render error handling.
|
|
|
|
Parameters:
|
|
mock_render: Mock render object.
|
|
"""
|
|
exp_dict = {
|
|
'exp1':
|
|
DECKHAND_DUPLICATE_SCHEMA + ": Duplicate schema specified.\n",
|
|
'exp2':
|
|
DECKHAND_RENDER_EXCEPTION +
|
|
": An unknown Deckhand exception occurred while trying to render documents\n",
|
|
'exp3':
|
|
"Generic Error\n"
|
|
}
|
|
# No exception raised
|
|
mock_render.return_value = _return_deckhand_render_errors()
|
|
errors = deckhand.deckhand_render()
|
|
assert errors == []
|
|
# check errors object type
|
|
mock_render.return_value = _return_deckhand_render_errors(1)
|
|
errors = deckhand.deckhand_render()
|
|
assert isinstance(errors, list)
|
|
# check single exception handling
|
|
assert _deckhand_render_exception_msg(errors) == exp_dict['exp1']
|
|
# check multiple exception with tuple type
|
|
mock_render.return_value = _return_deckhand_render_errors(2)
|
|
errors = deckhand.deckhand_render()
|
|
assert _deckhand_render_exception_msg(
|
|
errors) == exp_dict['exp1'] + exp_dict['exp2']
|
|
# check multiple exception with mixed type
|
|
mock_render.return_value = _return_deckhand_render_errors(3)
|
|
errors = deckhand.deckhand_render()
|
|
assert _deckhand_render_exception_msg(
|
|
errors) == exp_dict['exp1'] + exp_dict['exp2'] + exp_dict['exp3']
|
|
|
|
|
|
def _deckhand_render_exception_msg(errors):
|
|
"""
|
|
Helper function to create deckhand render exception msg.
|
|
|
|
Parameters:
|
|
errors: List of errors provided by deckhand render.
|
|
Returns:
|
|
string: formulated error message.
|
|
"""
|
|
err_msg = ''
|
|
for err in errors:
|
|
if isinstance(err, tuple) and len(err) > 1:
|
|
err_msg += ': '.join(err) + '\n'
|
|
else:
|
|
err_msg += str(err) + '\n'
|
|
return err_msg
|
|
|
|
|
|
def _return_deckhand_render_errors(error_count=0):
|
|
"""
|
|
Helper function to mock deckhand render errors.
|
|
|
|
Parameters:
|
|
error_count: Number of mock errors to return.
|
|
Returns:
|
|
List: List of mock errors as per error_count.
|
|
"""
|
|
errors = []
|
|
if error_count >= 1:
|
|
errors.append((DECKHAND_DUPLICATE_SCHEMA,
|
|
'Duplicate schema specified.'))
|
|
if error_count >= 2:
|
|
errors.append((DECKHAND_RENDER_EXCEPTION,
|
|
'An unknown Deckhand exception occurred while '
|
|
'trying to render documents'))
|
|
if error_count >= 3:
|
|
errors.append(('Generic Error'))
|
|
return errors
|