shipyard/src/bin/shipyard_airflow/tests/unit/control/test_action_validators.py

177 lines
7.0 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.
"""Tests for the action validators run when an action is created"""
import mock
from mock import MagicMock
import yaml
import pytest
from shipyard_airflow.control.action.action_validators import (
validate_site_action
)
from shipyard_airflow.errors import ApiError
from tests.unit.common.deployment_group.node_lookup_stubs import node_lookup
import tests.unit.common.deployment_group.test_deployment_group_manager as tdgm
def get_doc_returner(style, ds_name):
strategy = MagicMock()
if style == 'cycle':
strategy.data = {"groups": yaml.safe_load(tdgm._CYCLE_GROUPS_YAML)}
elif style == 'clean':
strategy.data = {"groups": yaml.safe_load(tdgm._GROUPS_YAML)}
def doc_returner(revision_id, rendered, **filters):
if not revision_id == 99:
doc = filters['metadata.name']
if doc == 'deployment-configuration':
dc = MagicMock()
dc.data = {
"physical_provisioner": {
"deployment_strategy": ds_name
},
"armada": {
"manifest": "full-site"
}
}
# if passed a name of 'defaulted' clear the section
if ds_name == 'defaulted':
dc.data["physical_provisioner"] = None
print(dc.__dict__)
return [dc]
elif doc == 'dep-strat':
return [strategy]
return []
return doc_returner
def fake_dh_doc_client(style, ds_name='dep-strat'):
dhc = MagicMock()
dhc.revisions.documents = get_doc_returner(style, ds_name)
return dhc
class TestActionValidator:
@mock.patch("shipyard_airflow.control.service_clients.deckhand_client",
return_value=fake_dh_doc_client('clean'))
@mock.patch("shipyard_airflow.control.validators."
"validate_deployment_strategy._get_node_lookup",
return_value=node_lookup)
def test_validate_site_action(self, *args):
"""Test the function that runs the validator class"""
try:
validate_site_action({
'id': '123',
'name': 'deploy_site',
'committed_rev_id': 1
})
except Exception as ex:
# any exception is a failure
assert False, str(ex)
@mock.patch("shipyard_airflow.control.service_clients.deckhand_client",
return_value=fake_dh_doc_client('cycle'))
@mock.patch("shipyard_airflow.control.validators."
"validate_deployment_strategy._get_node_lookup",
return_value=node_lookup)
def test_validate_site_action_cycle(self, *args):
"""Test the function that runs the validator class with a
deployment strategy that has a cycle in the groups
"""
with pytest.raises(ApiError) as apie:
validate_site_action({
'id': '123',
'name': 'deploy_site',
'committed_rev_id': 1
})
assert apie.value.description == 'InvalidConfigurationDocuments'
assert (
'The following are involved in a circular dependency:'
) in apie.value.error_list[0]['diagnostic']
@mock.patch("shipyard_airflow.control.service_clients.deckhand_client",
return_value=fake_dh_doc_client('clean', ds_name='not-there'))
@mock.patch("shipyard_airflow.control.validators."
"validate_deployment_strategy._get_node_lookup",
return_value=node_lookup)
def test_validate_site_action_missing_dep_strat(self, *args):
"""Test the function that runs the validator class with a missing
deployment strategy - specified, but not present
"""
with pytest.raises(ApiError) as apie:
validate_site_action({
'id': '123',
'name': 'deploy_site',
'committed_rev_id': 1
})
assert apie.value.description == 'InvalidConfigurationDocuments'
assert apie.value.error_list[0]['name'] == 'DocumentNotFoundError'
@mock.patch("shipyard_airflow.control.service_clients.deckhand_client",
return_value=fake_dh_doc_client('clean'), ds_name='defaulted')
@mock.patch("shipyard_airflow.control.validators."
"validate_deployment_strategy._get_node_lookup",
return_value=node_lookup)
def test_validate_site_action_default_dep_strat(self, *args):
"""Test the function that runs the validator class with a defaulted
deployment strategy (not specified)
"""
try:
validate_site_action({
'id': '123',
'name': 'deploy_site',
'committed_rev_id': 1
})
except:
# any exception is a failure
assert False
@mock.patch("shipyard_airflow.control.service_clients.deckhand_client",
return_value=fake_dh_doc_client('clean'), ds_name='defaulted')
@mock.patch("shipyard_airflow.control.validators."
"validate_deployment_strategy._get_node_lookup",
return_value=node_lookup)
def test_validate_site_missing_rev(self, *args):
"""Test the function that runs the validator class with a
deployment strategy that has a cycle in the groups
"""
with pytest.raises(ApiError) as apie:
validate_site_action({
'id': '123',
'name': 'deploy_site'
})
assert apie.value.description == 'InvalidDocumentRevision'
@mock.patch("shipyard_airflow.control.service_clients.deckhand_client",
return_value=fake_dh_doc_client('clean', ds_name='not-there'))
@mock.patch("shipyard_airflow.control.validators."
"validate_deployment_strategy._get_node_lookup",
return_value=node_lookup)
def test_validate_site_action_continue_failure(self, *args):
"""Test the function that runs the validator class with a defaulted
deployment strategy (not specified)
"""
try:
validate_site_action({
'id': '123',
'name': 'deploy_site',
'committed_rev_id': 1,
'parameters': {'continue-on-fail': 'true'}
})
except:
# any exception is a failure
assert False