Exceptions for Validations Framework
Introduces two new exceptions for Validation Framework to be raised within appropriate context. ValidationRunException - signifying incorrect behavior of the Run action code ValidationShowException - signifying incorrect behavior of the Show actions code Signed-off-by: Jiri Podivin <jpodivin@redhat.com> Change-Id: I87f315e7bb2e28a8572982a71fbe2be4432ff2c0
This commit is contained in:
@@ -22,6 +22,7 @@ from validations_libs.validation_actions import ValidationActions
|
|||||||
from validations_libs.cli import common
|
from validations_libs.cli import common
|
||||||
from validations_libs.cli.base import BaseCommand
|
from validations_libs.cli.base import BaseCommand
|
||||||
from validations_libs.cli.parseractions import CommaListAction, KeyValueAction
|
from validations_libs.cli.parseractions import CommaListAction, KeyValueAction
|
||||||
|
from validations_libs.exceptions import ValidationRunException
|
||||||
|
|
||||||
|
|
||||||
class Run(BaseCommand):
|
class Run(BaseCommand):
|
||||||
@@ -197,7 +198,7 @@ class Run(BaseCommand):
|
|||||||
if parsed_args.skip_list:
|
if parsed_args.skip_list:
|
||||||
skip_list = common.read_cli_data_file(parsed_args.skip_list)
|
skip_list = common.read_cli_data_file(parsed_args.skip_list)
|
||||||
if not isinstance(skip_list, dict):
|
if not isinstance(skip_list, dict):
|
||||||
raise RuntimeError("Wrong format for the skiplist.")
|
raise ValidationRunException("Wrong format for the skiplist.")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
results = v_actions.run_validations(
|
results = v_actions.run_validations(
|
||||||
@@ -216,8 +217,8 @@ class Run(BaseCommand):
|
|||||||
ssh_user=parsed_args.ssh_user,
|
ssh_user=parsed_args.ssh_user,
|
||||||
validation_config=config,
|
validation_config=config,
|
||||||
skip_list=skip_list)
|
skip_list=skip_list)
|
||||||
except RuntimeError as e:
|
except (RuntimeError, ValidationRunException) as e:
|
||||||
raise RuntimeError(e)
|
raise ValidationRunException(e)
|
||||||
|
|
||||||
if results:
|
if results:
|
||||||
failed_rc = any([r for r in results if r['Status'] == 'FAILED'])
|
failed_rc = any([r for r in results if r['Status'] == 'FAILED'])
|
||||||
@@ -227,8 +228,8 @@ class Run(BaseCommand):
|
|||||||
common.write_junitxml(parsed_args.junitxml, results)
|
common.write_junitxml(parsed_args.junitxml, results)
|
||||||
common.print_dict(results)
|
common.print_dict(results)
|
||||||
if failed_rc:
|
if failed_rc:
|
||||||
raise RuntimeError("One or more validations have failed.")
|
raise ValidationRunException("One or more validations have failed.")
|
||||||
else:
|
else:
|
||||||
msg = ("No validation has been run, please check "
|
msg = ("No validation has been run, please check "
|
||||||
"log in the Ansible working directory.")
|
"log in the Ansible working directory.")
|
||||||
raise RuntimeError(msg)
|
raise ValidationRunException(msg)
|
||||||
|
41
validations_libs/exceptions.py
Normal file
41
validations_libs/exceptions.py
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
# Copyright 2022 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.
|
||||||
|
#
|
||||||
|
|
||||||
|
"""This module contains Validation Framework specific exceptions,
|
||||||
|
to be raised by Validation Framework runtime.
|
||||||
|
|
||||||
|
The exceptions are meant to cover the most common of the possible
|
||||||
|
fail states the framework can encounter, with the rest evoking one
|
||||||
|
of the built in exceptions, such as 'RuntimeError'.
|
||||||
|
Use of these exceptions should be limited to cases when cause is known
|
||||||
|
and within the context of the framework itself.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class ValidationRunException(Exception):
|
||||||
|
"""ValidationRunException is to be raised when actions
|
||||||
|
initiated by the CLI 'run' subcommand or `run_validations` method
|
||||||
|
of the `ValidationsActions` class, cause unacceptable behavior
|
||||||
|
from which it is impossible to recover.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class ValidationShowException(Exception):
|
||||||
|
"""ValidationShowException is to be raised when actions
|
||||||
|
initiated by the CLI 'show' subcommands or `show_history`,
|
||||||
|
`show_validations` or `show_validations_parameters` methods
|
||||||
|
of the `ValidationsActions` class, cause unacceptable behavior
|
||||||
|
from which it is impossible to recover.
|
||||||
|
"""
|
@@ -20,6 +20,7 @@ except ImportError:
|
|||||||
import mock
|
import mock
|
||||||
|
|
||||||
from validations_libs.cli import run
|
from validations_libs.cli import run
|
||||||
|
from validations_libs.exceptions import ValidationRunException
|
||||||
from validations_libs.tests import fakes
|
from validations_libs.tests import fakes
|
||||||
from validations_libs.tests.cli.fakes import BaseCommand
|
from validations_libs.tests.cli.fakes import BaseCommand
|
||||||
|
|
||||||
@@ -39,7 +40,7 @@ class TestRun(BaseCommand):
|
|||||||
verifylist = [('validation_name', ['foo'])]
|
verifylist = [('validation_name', ['foo'])]
|
||||||
|
|
||||||
parsed_args = self.check_parser(self.cmd, args, verifylist)
|
parsed_args = self.check_parser(self.cmd, args, verifylist)
|
||||||
self.assertRaises(RuntimeError, self.cmd.take_action, parsed_args)
|
self.assertRaises(ValidationRunException, self.cmd.take_action, parsed_args)
|
||||||
|
|
||||||
@mock.patch('validations_libs.cli.common.open')
|
@mock.patch('validations_libs.cli.common.open')
|
||||||
@mock.patch('validations_libs.validation_actions.ValidationActions.'
|
@mock.patch('validations_libs.validation_actions.ValidationActions.'
|
||||||
@@ -414,7 +415,7 @@ class TestRun(BaseCommand):
|
|||||||
|
|
||||||
self._set_args(arglist)
|
self._set_args(arglist)
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
self.assertRaises(RuntimeError, self.cmd.take_action, parsed_args)
|
self.assertRaises(ValidationRunException, self.cmd.take_action, parsed_args)
|
||||||
call_args = mock_run.mock_calls[0][2]
|
call_args = mock_run.mock_calls[0][2]
|
||||||
|
|
||||||
self.assertDictEqual(call_args, run_called_args)
|
self.assertDictEqual(call_args, run_called_args)
|
||||||
@@ -456,7 +457,7 @@ class TestRun(BaseCommand):
|
|||||||
|
|
||||||
self._set_args(arglist)
|
self._set_args(arglist)
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
self.assertRaises(RuntimeError, self.cmd.take_action, parsed_args)
|
self.assertRaises(ValidationRunException, self.cmd.take_action, parsed_args)
|
||||||
|
|
||||||
@mock.patch('validations_libs.constants.VALIDATIONS_LOG_BASEDIR')
|
@mock.patch('validations_libs.constants.VALIDATIONS_LOG_BASEDIR')
|
||||||
@mock.patch('getpass.getuser',
|
@mock.patch('getpass.getuser',
|
||||||
@@ -589,4 +590,4 @@ class TestRun(BaseCommand):
|
|||||||
('skip_list', '/foo/skip.yaml')]
|
('skip_list', '/foo/skip.yaml')]
|
||||||
self._set_args(arglist)
|
self._set_args(arglist)
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
self.assertRaises(RuntimeError, self.cmd.take_action, parsed_args)
|
self.assertRaises(ValidationRunException, self.cmd.take_action, parsed_args)
|
||||||
|
@@ -24,6 +24,7 @@ from unittest import TestCase
|
|||||||
|
|
||||||
from validations_libs.tests import fakes
|
from validations_libs.tests import fakes
|
||||||
from validations_libs.validation_actions import ValidationActions
|
from validations_libs.validation_actions import ValidationActions
|
||||||
|
from validations_libs.exceptions import ValidationRunException, ValidationShowException
|
||||||
|
|
||||||
|
|
||||||
class TestValidationActions(TestCase):
|
class TestValidationActions(TestCase):
|
||||||
@@ -250,7 +251,7 @@ class TestValidationActions(TestCase):
|
|||||||
mock_validation_play.return_value = []
|
mock_validation_play.return_value = []
|
||||||
|
|
||||||
run = ValidationActions()
|
run = ValidationActions()
|
||||||
self.assertRaises(RuntimeError, run.run_validations,
|
self.assertRaises(ValidationRunException, run.run_validations,
|
||||||
validation_name=['fake'],
|
validation_name=['fake'],
|
||||||
validations_dir='/tmp/foo')
|
validations_dir='/tmp/foo')
|
||||||
|
|
||||||
@@ -263,10 +264,10 @@ class TestValidationActions(TestCase):
|
|||||||
run.run_validations(
|
run.run_validations(
|
||||||
validation_name=['fake', 'foo'],
|
validation_name=['fake', 'foo'],
|
||||||
validations_dir='/tmp/foo')
|
validations_dir='/tmp/foo')
|
||||||
except RuntimeError as runtime_error:
|
except ValidationRunException as run_exception:
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
"Following validations were not found in '/tmp/foo': foo",
|
"Following validations were not found in '/tmp/foo': foo",
|
||||||
str(runtime_error))
|
str(run_exception))
|
||||||
else:
|
else:
|
||||||
self.fail("Runtime error exception should have been raised")
|
self.fail("Runtime error exception should have been raised")
|
||||||
|
|
||||||
@@ -275,7 +276,7 @@ class TestValidationActions(TestCase):
|
|||||||
mock_validation_play.return_value = []
|
mock_validation_play.return_value = []
|
||||||
|
|
||||||
run = ValidationActions()
|
run = ValidationActions()
|
||||||
self.assertRaises(RuntimeError, run.run_validations,
|
self.assertRaises(ValidationRunException, run.run_validations,
|
||||||
validations_dir='/tmp/foo'
|
validations_dir='/tmp/foo'
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -386,7 +387,7 @@ class TestValidationActions(TestCase):
|
|||||||
inventory = 'tmp/inventory.yaml'
|
inventory = 'tmp/inventory.yaml'
|
||||||
|
|
||||||
run = ValidationActions()
|
run = ValidationActions()
|
||||||
self.assertRaises(RuntimeError, run.run_validations, playbook,
|
self.assertRaises(ValidationRunException, run.run_validations, playbook,
|
||||||
inventory)
|
inventory)
|
||||||
|
|
||||||
@mock.patch('validations_libs.utils.parse_all_validations_on_disk',
|
@mock.patch('validations_libs.utils.parse_all_validations_on_disk',
|
||||||
@@ -418,7 +419,7 @@ class TestValidationActions(TestCase):
|
|||||||
def test_validation_show_not_found(self, mock_exists):
|
def test_validation_show_not_found(self, mock_exists):
|
||||||
validations_show = ValidationActions()
|
validations_show = ValidationActions()
|
||||||
self.assertRaises(
|
self.assertRaises(
|
||||||
RuntimeError,
|
ValidationShowException,
|
||||||
validations_show.show_validations,
|
validations_show.show_validations,
|
||||||
'512e'
|
'512e'
|
||||||
)
|
)
|
||||||
@@ -480,7 +481,7 @@ class TestValidationActions(TestCase):
|
|||||||
@mock.patch('six.moves.builtins.open')
|
@mock.patch('six.moves.builtins.open')
|
||||||
def test_show_validations_parameters_non_supported_format(self, mock_open):
|
def test_show_validations_parameters_non_supported_format(self, mock_open):
|
||||||
v_actions = ValidationActions()
|
v_actions = ValidationActions()
|
||||||
self.assertRaises(RuntimeError,
|
self.assertRaises(ValidationShowException,
|
||||||
v_actions.show_validations_parameters,
|
v_actions.show_validations_parameters,
|
||||||
validations=['foo'], output_format='bar')
|
validations=['foo'], output_format='bar')
|
||||||
|
|
||||||
|
@@ -24,6 +24,7 @@ from validations_libs.cli.common import Spinner
|
|||||||
from validations_libs.validation_logs import ValidationLogs, ValidationLog
|
from validations_libs.validation_logs import ValidationLogs, ValidationLog
|
||||||
from validations_libs import constants
|
from validations_libs import constants
|
||||||
from validations_libs import utils as v_utils
|
from validations_libs import utils as v_utils
|
||||||
|
from validations_libs.exceptions import ValidationRunException, ValidationShowException
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__ + ".validation_actions")
|
LOG = logging.getLogger(__name__ + ".validation_actions")
|
||||||
|
|
||||||
@@ -162,6 +163,8 @@ class ValidationActions(object):
|
|||||||
:return: The detailed information for a validation
|
:return: The detailed information for a validation
|
||||||
:rtype: `dict`
|
:rtype: `dict`
|
||||||
|
|
||||||
|
:raises: ValidationShowException
|
||||||
|
|
||||||
:example:
|
:example:
|
||||||
|
|
||||||
>>> path = "/foo/bar"
|
>>> path = "/foo/bar"
|
||||||
@@ -202,7 +205,8 @@ class ValidationActions(object):
|
|||||||
validation,
|
validation,
|
||||||
self.validation_path,
|
self.validation_path,
|
||||||
extra_msg)
|
extra_msg)
|
||||||
raise RuntimeError(msg)
|
raise ValidationShowException(msg)
|
||||||
|
|
||||||
logfiles = vlog.get_logfile_content_by_validation(validation)
|
logfiles = vlog.get_logfile_content_by_validation(validation)
|
||||||
data_format = vlog.get_validations_stats(logfiles)
|
data_format = vlog.get_validations_stats(logfiles)
|
||||||
data.update(data_format)
|
data.update(data_format)
|
||||||
@@ -406,6 +410,7 @@ class ValidationActions(object):
|
|||||||
Status, Status_by_Host, UUID and Unreachable_Hosts)
|
Status, Status_by_Host, UUID and Unreachable_Hosts)
|
||||||
:rtype: ``list``
|
:rtype: ``list``
|
||||||
|
|
||||||
|
:raises: ValidationRunException
|
||||||
:example:
|
:example:
|
||||||
|
|
||||||
>>> path = "/u/s/a"
|
>>> path = "/u/s/a"
|
||||||
@@ -471,9 +476,9 @@ class ValidationActions(object):
|
|||||||
"Following validations were not found in '{}': {}"
|
"Following validations were not found in '{}': {}"
|
||||||
).format(validations_dir, ', '.join(unknown_validations))
|
).format(validations_dir, ', '.join(unknown_validations))
|
||||||
|
|
||||||
raise RuntimeError(msg)
|
raise ValidationRunException(msg)
|
||||||
else:
|
else:
|
||||||
raise RuntimeError("No validations found")
|
raise ValidationRunException("No validations found")
|
||||||
if log_path:
|
if log_path:
|
||||||
self.log.warning((
|
self.log.warning((
|
||||||
"The 'log_path' argument is deprecated and"
|
"The 'log_path' argument is deprecated and"
|
||||||
@@ -664,6 +669,9 @@ class ValidationActions(object):
|
|||||||
:return: A JSON or a YAML dump (By default, JSON).
|
:return: A JSON or a YAML dump (By default, JSON).
|
||||||
if `download_file` is used, a file containing only the
|
if `download_file` is used, a file containing only the
|
||||||
parameters will be created in the file system.
|
parameters will be created in the file system.
|
||||||
|
|
||||||
|
:raises: ValidationShowException
|
||||||
|
|
||||||
:example:
|
:example:
|
||||||
|
|
||||||
>>> validations = ['check-cpu', 'check-ram']
|
>>> validations = ['check-cpu', 'check-ram']
|
||||||
@@ -691,7 +699,7 @@ class ValidationActions(object):
|
|||||||
supported_format = ['json', 'yaml']
|
supported_format = ['json', 'yaml']
|
||||||
|
|
||||||
if output_format not in supported_format:
|
if output_format not in supported_format:
|
||||||
raise RuntimeError("{} output format not supported".format(output_format))
|
raise ValidationShowException("{} output format not supported".format(output_format))
|
||||||
|
|
||||||
validation_playbooks = v_utils.get_validations_playbook(
|
validation_playbooks = v_utils.get_validations_playbook(
|
||||||
path=self.validation_path,
|
path=self.validation_path,
|
||||||
|
Reference in New Issue
Block a user