Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 17 additions & 7 deletions docs/migration_2_to_3.rst
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,14 @@ Updating Your Tests
-------------------


ReFrame 3.0 deprecates particular test syntax as well as certain test attributes.
Some more esoteric features have also changed which may cause tests that make use of them to break.
In this section we summarize all these changes and how to make these tests compatible with ReFrame 3.0


Pipeline methods and hooks
==========================

ReFrame 2.20 introduced a new powerful mechanism for attaching arbitrary functions hooks at the different pipeline stages.
This mechanism provides an easy way to configure and extend the functionality of a test, eliminating essentially the need to override pipeline stages for this purpose.
ReFrame 3.0 deprecates the old practice of overriding pipeline stage methods in favor of using pipeline hooks.
Expand Down Expand Up @@ -108,8 +116,9 @@ You could equally attach this function to run after the "setup" phase with ``@rf
However, you can't attach this function *before* the "setup" phase, because the ``current_environ`` will not be available and it will be still ``None``.


--------------------------------
Force override a pipeline method
================================
--------------------------------

Although pipeline hooks should be able to cover almost all the cases for writing tests in ReFrame, there might be corner cases that you need to override one of the pipeline methods, e.g., because you want to implement a stage differently.
In this case, all you have to do is mark your test class as "special", and ReFrame will not issue any deprecation warning if you override pipeline stage methods:
Expand All @@ -125,12 +134,6 @@ In this case, all you have to do is mark your test class as "special", and ReFra
If you try to override the ``setup()`` method in any of the subclasses of ``MyExtendedTest``, you will still get a deprecation warning, which a desired behavior since the subclasses should be normal tests.


Suppressing deprecation warnings
================================

Although not recommended, you can suppress any deprecation warning issued by ReFrame by passing the ``--no-deprecation-warnings`` flag.


Getting schedulers and launchers by name
========================================

Expand Down Expand Up @@ -163,6 +166,13 @@ Now you have to simply replace the import statement with the following:
Similarly for schedulers, the ``reframe.core.schedulers.registry`` module must be replaced with ``reframe.core.backends``.


Suppressing deprecation warnings
================================

Although not recommended, you can suppress any deprecation warning issued by ReFrame by passing the ``--no-deprecation-warnings`` flag.



Other Changes
-------------

Expand Down
65 changes: 65 additions & 0 deletions docs/regression_test_api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -128,3 +128,68 @@ Container Platforms
:members:
:exclude-members: ContainerPlatformField
:show-inheritance:


The ``reframe`` module
----------------------

The :py:mod:`reframe` module offers direct access to the basic test classes, constants and decorators.


.. py:class:: reframe.CompileOnlyRegressionTest

See :class:`reframe.core.pipeline.CompileOnlyRegressionTest`.


.. py:class:: reframe.RegressionTest

See :class:`reframe.core.pipeline.RegressionTest`.


.. py:class:: reframe.RunOnlyRegressionTest

See :class:`reframe.core.pipeline.RunOnlyRegressionTest`.

.. py:attribute:: reframe.DEPEND_BY_ENV

See :attr:`reframe.core.pipeline.DEPEND_BY_ENV`.


.. py:attribute:: reframe.DEPEND_EXACT

See :attr:`reframe.core.pipeline.DEPEND_EXACT`.


.. py:attribute:: reframe.DEPEND_FULLY

See :attr:`reframe.core.pipeline.DEPEND_FULLY`.


.. py:decorator:: reframe.parameterized_test

See :func:`@reframe.core.decorators.parameterized_test <reframe.core.decorators.parameterized_test>`.


.. py:decorator:: reframe.require_deps

See :func:`@reframe.core.decorators.require_deps <reframe.core.decorators.require_deps>`.


.. py:decorator:: reframe.required_version

See :func:`@reframe.core.decorators.required_version <reframe.core.decorators.required_version>`.


.. py:decorator:: reframe.run_after

See :func:`@reframe.core.decorators.run_after <reframe.core.decorators.run_after>`.


.. py:decorator:: reframe.run_before

See :func:`@reframe.core.decorators.run_before <reframe.core.decorators.run_before>`.


.. py:decorator:: reframe.simple_test

See :func:`@reframe.core.decorators.simple_test <reframe.core.decorators.simple_test>`.
11 changes: 2 additions & 9 deletions reframe/core/decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@ def simple_test(cls):
available directly under the :mod:`reframe` module.

.. versionadded:: 2.13

'''

_validate_test(cls)
Expand All @@ -102,10 +101,8 @@ def parameterized_test(*inst):
.. versionadded:: 2.13

.. note::

This decorator does not instantiate any test. It only registers them.
The actual instantiation happens during the loading phase of the test.

'''
def _do_register(cls):
_validate_test(cls)
Expand All @@ -124,6 +121,8 @@ def required_version(*versions):
If the test is not compatible with the current ReFrame version it will be
skipped.

.. versionadded:: 2.13

:arg versions: A list of ReFrame version specifications that this test is
allowed to run. A version specification string can have one of the
following formats:
Expand All @@ -140,9 +139,6 @@ def required_version(*versions):
``@required_version('2.13', '>=2.16')``, in which case the test will be
selected if *any* of the versions is satisfied, even if the versions
specifications are conflicting.

.. versionadded:: 2.13

'''
if not versions:
raise ValueError('no versions specified')
Expand Down Expand Up @@ -200,7 +196,6 @@ def run_before(stage):
``'run'``, ``'sanity'``, ``'performance'`` or ``'cleanup'``.

.. versionadded:: 2.20

'''
return _runx('pre_' + stage)

Expand All @@ -212,7 +207,6 @@ def run_after(stage):
:py:attr:`reframe.core.decorators.run_before`.

.. versionadded:: 2.20

'''
return _runx('post_' + stage)

Expand All @@ -236,7 +230,6 @@ def require_deps(func):
This decorator is also directly available under the :mod:`reframe` module.

.. versionadded:: 2.21

'''
tests = inspect.getfullargspec(func).args[1:]
func._rfm_resolve_deps = True
Expand Down
37 changes: 18 additions & 19 deletions reframe/core/pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@
# Basic functionality for regression tests
#

__all__ = ['final', 'RegressionTest',
'RunOnlyRegressionTest', 'CompileOnlyRegressionTest',
'DEPEND_EXACT', 'DEPEND_BY_ENV', 'DEPEND_FULLY']
__all__ = [
'CompileOnlyRegressionTest', 'RegressionTest', 'RunOnlyRegressionTest',
'DEPEND_BY_ENV', 'DEPEND_EXACT', 'DEPEND_FULLY', 'final'
]


import functools
Expand Down Expand Up @@ -214,6 +215,8 @@ class RegressionTest(metaclass=RegressionTestMeta):
#: :class:`None`.
sourcesdir = fields.TypedField('sourcesdir', str, type(None))

#: .. versionadded:: 2.14
#:
#: The build system to be used for this test.
#: If not specified, the framework will try to figure it out automatically
#: based on the value of :attr:`sourcepath`.
Expand All @@ -227,8 +230,6 @@ class RegressionTest(metaclass=RegressionTestMeta):
#:
#: :type: :class:`str` or :class:`reframe.core.buildsystems.BuildSystem`.
#: :default: :class:`None`.
#:
#: .. versionadded:: 2.14
build_system = BuildSystemField('build_system', type(None))

#: List of shell commands to be executed before compiling.
Expand Down Expand Up @@ -263,6 +264,8 @@ class RegressionTest(metaclass=RegressionTestMeta):
#: :default: ``[]``
executable_opts = fields.TypedField('executable_opts', typ.List[str])

#: .. versionadded:: 2.20
#:
#: The container platform to be used for launching this test.
#:
#: If this field is set, the test will run inside a container using the
Expand All @@ -283,11 +286,11 @@ class RegressionTest(metaclass=RegressionTestMeta):
#: :type: :class:`str` or
#: :class:`reframe.core.containers.ContainerPlatform`.
#: :default: :class:`None`.
#:
#: .. versionadded:: 2.20
container_platform = ContainerPlatformField('container_platform',
type(None))

#: .. versionadded:: 2.10
#:
#: List of shell commands to execute before launching this job.
#:
#: These commands do not execute in the context of ReFrame.
Expand All @@ -296,20 +299,16 @@ class RegressionTest(metaclass=RegressionTestMeta):
#:
#: :type: :class:`List[str]`
#: :default: ``[]``
#:
#: .. note::
#: .. versionadded:: 2.10
pre_run = fields.TypedField('pre_run', typ.List[str])

#: .. versionadded:: 2.10
#:
#: List of shell commands to execute after launching this job.
#:
#: See :attr:`pre_run` for a more detailed description of the semantics.
#:
#: :type: :class:`List[str]`
#: :default: ``[]``
#:
#: .. note::
#: .. versionadded:: 2.10
post_run = fields.TypedField('post_run', typ.List[str])

#: List of files to be kept after the test finishes.
Expand Down Expand Up @@ -440,15 +439,14 @@ class RegressionTest(metaclass=RegressionTestMeta):
use_multithreading = fields.TypedField('use_multithreading',
bool, type(None))

#: .. versionadded:: 3.0
#:
#: The maximum time a job can be pending before starting running.
#:
#: Time duration is specified as of the :attr:`time_limit` attribute.
#:
#: :type: :class:`str` or :class:`datetime.timedelta`
#: :default: :class:`None`
#:
#: .. versionadded:: 3.0
#:
max_pending_time = fields.TimerField('max_pending_time', type(None))

#: Specify whether this test needs exclusive access to nodes.
Expand Down Expand Up @@ -577,6 +575,8 @@ class RegressionTest(metaclass=RegressionTestMeta):
#: The old syntax using a ``(h, m, s)`` tuple is deprecated.
time_limit = fields.TimerField('time_limit', type(None))

#: .. versionadded:: 2.8
#:
#: Extra resources for this test.
#:
#: This field is for specifying custom resources needed by this test. These
Expand Down Expand Up @@ -638,7 +638,6 @@ class RegressionTest(metaclass=RegressionTestMeta):
#: :default: ``{}``
#:
#: .. note::
#: .. versionadded:: 2.8
#: .. versionchanged:: 2.9
#: A new more powerful syntax was introduced
#: that allows also custom job script directive prefixes.
Expand Down Expand Up @@ -908,11 +907,11 @@ def info(self):
partition and the current programming environment that the test is
currently executing on.

.. versionadded:: 2.10

:returns: a string with an informational message about this test

.. note ::
.. versionadded:: 2.10

When overriding this method, you should pay extra attention on how
you use the :class:`RegressionTest`'s attributes, because this
method may be called at any point of the test's lifetime.
Expand Down
9 changes: 3 additions & 6 deletions reframe/core/runtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,7 @@ class RuntimeContext:

There is a single instance of this class globally in the framework.

.. note::
.. versionadded:: 2.13

.. versionadded:: 2.13
'''

def __init__(self, site_config):
Expand Down Expand Up @@ -175,10 +173,9 @@ def init_runtime(site_config):
def runtime():
'''Get the runtime context of the framework.

:returns: A :class:`reframe.core.runtime.RuntimeContext` object.
.. versionadded:: 2.13

.. note::
.. versionadded:: 2.13
:returns: A :class:`reframe.core.runtime.RuntimeContext` object.
'''
if _runtime_context is None:
raise ReframeFatalError('no runtime context is configured')
Expand Down
20 changes: 8 additions & 12 deletions reframe/core/schedulers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,34 +144,33 @@ class Job:
launcher = fields.TypedField('launcher', JobLauncher)
scheduler = fields.TypedField('scheduler', JobScheduler)

#: .. versionadded:: 2.21
#:
#: The ID of the current job.
#:
#: :type: :class:`int` or :class:`None`.
#:
#: .. versionadded:: 2.21
#:
jobid = fields.TypedField('jobid', int, type(None))

#: .. versionadded:: 2.21
#:
#: The exit code of the job.
#:
#: This may or may not be set depending on the scheduler backend.
#:
#: :type: :class:`int` or :class:`None`.
#:
#: .. versionadded:: 2.21
#:
exitcode = fields.TypedField('exitcode', int, type(None))

#: .. versionadded:: 2.21
#:
#: The state of the job.
#:
#: The value of this field is scheduler-specific.
#:
#: :type: :class:`str` or :class:`None`.
#:
#: .. versionadded:: 2.21
#:
state = fields.TypedField('state', str, type(None))

#: .. versionadded:: 2.17
#:
#: The list of node names assigned to this job.
#:
#: This attribute is :class:`None` if no nodes are assigned to the job
Expand All @@ -189,9 +188,6 @@ class Job:
#: |--flex-alloc-nodes|_ command-line option
#:
#: This attribute is *not* supported by the ``pbs`` scheduler backend.
#:
#: .. versionadded:: 2.17
#:
nodelist = fields.TypedField('nodelist', typ.List[str], type(None))

# The sched_* arguments are exposed also to the frontend
Expand Down
Loading