Make validation process failures more obvious
Adds better info to the error returne when retreiving the validations from another Airship component. Adds tests to cover the success and failure flows of this same logic Change-Id: Id7fb389a3905f3e0659d4a7eec0e0658e00f3f28
This commit is contained in:
parent
16cc15f856
commit
bd2a686dbf
@ -791,25 +791,25 @@ def _get_validations_for_component(url, design_reference, response,
|
|||||||
CONF.requests_config.validation_connect_timeout,
|
CONF.requests_config.validation_connect_timeout,
|
||||||
CONF.requests_config.validation_read_timeout))
|
CONF.requests_config.validation_read_timeout))
|
||||||
# 400 response is "valid" failure to validate. > 400 is a problem.
|
# 400 response is "valid" failure to validate. > 400 is a problem.
|
||||||
|
LOG.debug("%s responded with status code %s", thread_name,
|
||||||
|
http_resp.status_code)
|
||||||
if http_resp.status_code > 400:
|
if http_resp.status_code > 400:
|
||||||
http_resp.raise_for_status()
|
http_resp.raise_for_status()
|
||||||
response_dict = http_resp.json()
|
response['response'] = http_resp.json()
|
||||||
response['response'] = response_dict
|
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
# catch anything exceptional as a failure to run validations
|
# catch anything exceptional as a failure to run validations
|
||||||
unable_str = '{} unable to validate configdocs'.format(thread_name)
|
unable_str = ('{} unable to validate configdocs or an invalid response'
|
||||||
LOG.error("%s. Exception follows.", unable_str)
|
' has been returned').format(thread_name)
|
||||||
LOG.error(str(ex))
|
LOG.exception(unable_str)
|
||||||
response['response'] = {
|
response['response'] = {
|
||||||
'details': {
|
'details': {
|
||||||
'messageList': [{
|
'messageList': [{
|
||||||
'message': unable_str,
|
'message': unable_str,
|
||||||
'kind': 'SimpleMessage',
|
'kind': 'ValidationMessage',
|
||||||
'error': True
|
'error': True,
|
||||||
}, {
|
'level': "Error",
|
||||||
'message': str(ex),
|
'diagnostic': '{}: {}'.format(
|
||||||
'kind': 'SimpleMessage',
|
ex.__class__.__name__, str(ex))
|
||||||
'error': True
|
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@ from unittest.mock import patch
|
|||||||
import yaml
|
import yaml
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
import responses
|
||||||
|
|
||||||
from .fake_response import FakeResponse
|
from .fake_response import FakeResponse
|
||||||
from shipyard_airflow.control.base import ShipyardRequestContext
|
from shipyard_airflow.control.base import ShipyardRequestContext
|
||||||
@ -906,3 +907,117 @@ def test_get_revision_dict_last_site_action_and_successful_site_action():
|
|||||||
last_site_action = rev_dict.get(configdocs_helper.LAST_SITE_ACTION)
|
last_site_action = rev_dict.get(configdocs_helper.LAST_SITE_ACTION)
|
||||||
assert successful_site_action.get('id') == 1
|
assert successful_site_action.get('id') == 1
|
||||||
assert last_site_action.get('id') == 2
|
assert last_site_action.get('id') == 2
|
||||||
|
|
||||||
|
|
||||||
|
@responses.activate
|
||||||
|
@mock.patch("shipyard_airflow.control.helpers.configdocs_helper.get_token",
|
||||||
|
return_value="1")
|
||||||
|
def test_get_validations_for_component_200_null_body(*args):
|
||||||
|
"""Tests the function used to call the remote validators
|
||||||
|
|
||||||
|
This is an error case - a 200 should include a response body per spec
|
||||||
|
"""
|
||||||
|
url = 'http://shiptest/validate_empty'
|
||||||
|
design_reference = {}
|
||||||
|
response = {}
|
||||||
|
exception = {}
|
||||||
|
context_marker = "testing"
|
||||||
|
thread_name = "unittest"
|
||||||
|
|
||||||
|
responses.add(responses.POST,
|
||||||
|
url,
|
||||||
|
body=None,
|
||||||
|
status=200)
|
||||||
|
configdocs_helper._get_validations_for_component(
|
||||||
|
url, design_reference, response, exception, context_marker,
|
||||||
|
thread_name)
|
||||||
|
|
||||||
|
ex_unable = ('unittest unable to validate configdocs or an invalid '
|
||||||
|
'response has been returned')
|
||||||
|
|
||||||
|
assert response['response'] == {
|
||||||
|
'details': {
|
||||||
|
'messageList': [{
|
||||||
|
'message': ex_unable,
|
||||||
|
'kind': 'ValidationMessage',
|
||||||
|
'error': True,
|
||||||
|
'level': "Error",
|
||||||
|
'diagnostic': ('JSONDecodeError: Expecting value: line 1 '
|
||||||
|
'column 1 (char 0)')
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert exception['exception'].__class__.__name__ == "JSONDecodeError"
|
||||||
|
|
||||||
|
|
||||||
|
def _exercise_get_validations_for_component_valid(resp_code, *args):
|
||||||
|
"""Tests the function used to call the remote validators"""
|
||||||
|
url = 'http://shiptest/validate_{}'.format(resp_code)
|
||||||
|
design_reference = {}
|
||||||
|
response = {}
|
||||||
|
exception = {}
|
||||||
|
context_marker = "testing"
|
||||||
|
thread_name = "unittest"
|
||||||
|
|
||||||
|
valid_response = '{"response": "something"}'
|
||||||
|
responses.add(responses.POST,
|
||||||
|
url,
|
||||||
|
body=valid_response,
|
||||||
|
status=resp_code)
|
||||||
|
configdocs_helper._get_validations_for_component(
|
||||||
|
url, design_reference, response, exception, context_marker,
|
||||||
|
thread_name)
|
||||||
|
|
||||||
|
assert response['response'] == {'response': 'something'}
|
||||||
|
assert exception == {}
|
||||||
|
|
||||||
|
|
||||||
|
@responses.activate
|
||||||
|
@mock.patch("shipyard_airflow.control.helpers.configdocs_helper.get_token",
|
||||||
|
return_value="1")
|
||||||
|
def test_get_validations_for_component_valid_status_codes(*args):
|
||||||
|
""" test a 200 and 400 response code, as valid """
|
||||||
|
for sc in [200, 400]:
|
||||||
|
_exercise_get_validations_for_component_valid(sc, *args)
|
||||||
|
|
||||||
|
|
||||||
|
@responses.activate
|
||||||
|
@mock.patch("shipyard_airflow.control.helpers.configdocs_helper.get_token",
|
||||||
|
return_value="1")
|
||||||
|
def test_get_validations_for_component_bad_status_404(*args):
|
||||||
|
"""Tests the function used to call the remote validators
|
||||||
|
|
||||||
|
This is an error case - a 404 should not occur for the validate endpoint
|
||||||
|
"""
|
||||||
|
url = 'http://shiptest/validate_404'
|
||||||
|
design_reference = {}
|
||||||
|
response = {}
|
||||||
|
exception = {}
|
||||||
|
context_marker = "testing"
|
||||||
|
thread_name = "unittest"
|
||||||
|
|
||||||
|
responses.add(responses.POST,
|
||||||
|
url,
|
||||||
|
body="Some string",
|
||||||
|
status=404)
|
||||||
|
configdocs_helper._get_validations_for_component(
|
||||||
|
url, design_reference, response, exception, context_marker,
|
||||||
|
thread_name)
|
||||||
|
|
||||||
|
ex_unable = ('unittest unable to validate configdocs or an invalid '
|
||||||
|
'response has been returned')
|
||||||
|
|
||||||
|
assert response['response'] == {
|
||||||
|
'details': {
|
||||||
|
'messageList': [{
|
||||||
|
'message': ex_unable,
|
||||||
|
'kind': 'ValidationMessage',
|
||||||
|
'error': True,
|
||||||
|
'level': "Error",
|
||||||
|
'diagnostic': ('HTTPError: 404 Client Error: Not Found for '
|
||||||
|
'url: http://shiptest/validate_404')
|
||||||
|
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert exception['exception'].__class__.__name__ == "HTTPError"
|
||||||
|
Loading…
Reference in New Issue
Block a user