Source code for valjean.gavroche.eval_test_task

# Copyright French Alternative Energies and Atomic Energy Commission
# Contributors: valjean developers
# valjean-support@cea.fr
#
# This software is a computer program whose purpose is to analyze and
# post-process numerical simulation results.
#
# This software is governed by the CeCILL license under French law and abiding
# by the rules of distribution of free software. You can use, modify and/ or
# redistribute the software under the terms of the CeCILL license as circulated
# by CEA, CNRS and INRIA at the following URL: http://www.cecill.info.
#
# As a counterpart to the access to the source code and rights to copy, modify
# and redistribute granted by the license, users are provided only with a
# limited warranty and the software's author, the holder of the economic
# rights, and the successive licensors have only limited liability.
#
# In this respect, the user's attention is drawn to the risks associated with
# loading, using, modifying and/or developing or reproducing the software by
# the user in light of its specific status of free software, that may mean that
# it is complicated to manipulate, and that also therefore means that it is
# reserved for developers and experienced professionals having in-depth
# computer knowledge. Users are therefore encouraged to load and test the
# software's suitability as regards their requirements in conditions enabling
# the security of their systems and/or data to be ensured and, more generally,
# to use and operate it in the same conditions as regards security.
#
# The fact that you are presently reading this means that you have had
# knowledge of the CeCILL license and that you accept its terms.

'''The purpose of this module is to define the :class:`EvalTestTask` class, a
task that evaluates a collection of :class:`~.gavroche.test.Test` objects and
transforms them into :class:`~.gavroche.test.TestResult` objects, which can be
subsequently processed for inclusion in a test report.
'''

import logging
from pathlib import Path

from ..path import ensure, sanitize_filename
from ..cosette.task import TaskStatus
from ..cosette.use import from_env
from ..cosette.pythontask import PythonTask
from ..gavroche.test import Test, TestResultFailed


LOGGER = logging.getLogger(__name__)


[docs] def actually_eval_test(test): '''Actually perform test evaluation. :returns: the result of test evaluation. :rtype: TestResult :raises TestResultFailed: if the underlying test raises any exception. ''' try: res = test.evaluate() except Exception as ex: # pylint: disable=broad-except LOGGER.error('The test failed with error: \n%s', ex) return TestResultFailed(test, ex) return res
[docs] class EvalTestTask(PythonTask): '''Class that evaluates a list of tests and stores the resulting :class:`~.TestResult` objects in the environment.'''
[docs] @classmethod def from_test_task(cls, test_task, name=None): '''This method instantiates an :class:`EvalTestTask` that will evaluate all the tests generated by a given task. :param Task test_task: a task that is expected to generate a list of tests as a result. ''' test_task_name = test_task.name if name is None: eval_task_name = test_task_name + '.eval' else: eval_task_name = name return cls(eval_task_name, test_task_name, deps=[test_task])
[docs] def __init__(self, name, test_task_name, *, deps=None, soft_deps=None): '''Direct instantiation of an :class:`EvalTestTask`. :param str name: the name of this task. :param str test_task_name: the name of the task that generated the tests. :param deps: the list of dependencies for this task. :type deps: list(Task) or None :param soft_deps: the list of soft dependencies for this task. :type soft_deps: list(Task) or None ''' def evaluate(*, env, config): tests = from_env(env=env, task_name=test_task_name, key='result') if not isinstance(tests, list): raise TypeError('Expected a list of tests in EvalTestTask ' f'{self.name!r}; got a {type(tests)} instead') for test in tests: if not isinstance(test, Test): raise TypeError('Expected a list of tests in EvalTestTask ' f'{self.name!r}, but one of the list ' 'elements is a {type(test)}') results = [actually_eval_test(test) for test in tests] output_dir = Path(config.query('path', 'output-root'), sanitize_filename(self.name)) ensure(output_dir, is_dir=True) env_up = {self.name: {'result': results, 'output_dir': str(output_dir)}} status = TaskStatus.DONE return env_up, status super().__init__(name, evaluate, deps=deps, soft_deps=soft_deps, env_kwarg='env', config_kwarg='config')
[docs] def evaluate_tests(test_fn, name=None): '''Create an :class:`EvalTestTask` objects for the given test. :param test_fn: a function that produces tests, wrapped in a :class:`~valjean.cosette.use.Use` decorator. :type test_fn: valjean.cosette.use.Use :param str name: the name of the :class:`EvalTestTask` object. :returns: the task that evaluates your tests. :rtype: EvalTestTask ''' return EvalTestTask.from_test_task(test_fn.get_task(), name=name)