Skip to content

Commit 9374a38

Browse files
committed
Rename RegressionMixin to RegressionTestPlugin
1 parent fd7068d commit 9374a38

File tree

8 files changed

+121
-70
lines changed

8 files changed

+121
-70
lines changed

reframe/core/builtins.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ def sanity_function(fn):
109109
'''Decorate a test member function to mark it as a sanity check.
110110
111111
This decorator will convert the given function into a
112-
:func:`~RegressionMixin.deferrable` and mark it to be executed during the
112+
:func:`~RegressionTestPlugin.deferrable` and mark it to be executed during the
113113
test's sanity stage. When this decorator is used, manually assigning a
114114
value to :attr:`~RegressionTest.sanity_patterns` in the test is not
115115
allowed.
@@ -118,7 +118,7 @@ def sanity_function(fn):
118118
classes may also decorate a different method as the test's sanity
119119
function. Decorating multiple member functions in the same class is not
120120
allowed. However, a :class:`RegressionTest` may inherit from multiple
121-
:class:`RegressionMixin` classes with their own sanity functions. In this
121+
:class:`RegressionTestPlugin` classes with their own sanity functions. In this
122122
case, the derived class will follow Python's `MRO
123123
<https://docs.python.org/3/library/stdtypes.html#class.__mro__>`_ to find
124124
a suitable sanity function.

reframe/core/fixtures.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -496,7 +496,7 @@ def access_fixture_resources(self):
496496
that these classes can use the same built-in functionalities as in regular
497497
tests decorated with
498498
:func:`@rfm.simple_test<reframe.core.decorators.simple_test>`. This
499-
includes the :func:`~reframe.core.pipeline.RegressionMixin.parameter`
499+
includes the :func:`~reframe.core.pipeline.RegressionTestPlugin.parameter`
500500
built-in, where fixtures may have more than one
501501
:ref:`variant<test-variants>`. When this occurs, a parent test may select
502502
to either treat a parameterized fixture as a test parameter, or instead,
@@ -595,7 +595,7 @@ class TestE(rfm.RegressionTest):
595595
A parent test may also specify the value of different variables in the
596596
fixture class to be set before its instantiation. Each variable must have
597597
been declared in the fixture class with the
598-
:func:`~reframe.core.pipeline.RegressionMixin.variable` built-in,
598+
:func:`~reframe.core.pipeline.RegressionTestPlugin.variable` built-in,
599599
otherwise it is silently ignored. This variable specification is
600600
equivalent to deriving a new class from the fixture class, and setting
601601
these variable values in the class body of a newly derived class.

reframe/core/pipeline.py

Lines changed: 54 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
#
99

1010
__all__ = [
11-
'CompileOnlyRegressionTest', 'RegressionTest', 'RunOnlyRegressionTest',
12-
'RegressionMixin'
11+
'CompileOnlyRegressionTest', 'RegressionMixin',
12+
'RegressionTest', 'RunOnlyRegressionTest', 'RegressionTestPlugin'
1313
]
1414

1515

@@ -47,6 +47,7 @@
4747
ReframeError)
4848
from reframe.core.meta import RegressionTestMeta
4949
from reframe.core.schedulers import Job
50+
from reframe.core.warnings import user_deprecation_warning
5051

5152

5253
class _NoRuntime(ContainerPlatform):
@@ -103,23 +104,67 @@ def launch_command(self, stagedir):
103104
_RFM_TEST_KIND_RUN = 2
104105

105106

106-
class RegressionMixin(metaclass=RegressionTestMeta):
107+
class RegressionTestPlugin(metaclass=RegressionTestMeta):
108+
'''A reusable test plugin.
109+
110+
This is a non-test base class that other tests can inherit from in order
111+
to augment their behaviour. A plugin can define variables, parameters,
112+
hooks etc. The following example shows a plugin that defines a variable
113+
and adds a specific job option for every test that uses it.
114+
115+
.. code-block:: python
116+
117+
class MyPlugin(RegressionTestPlugin):
118+
foo = variable(int, value=0)
119+
120+
@run_before('run', always_last=True)
121+
def add_foo_opt(self):
122+
if self.foo:
123+
self.job.options = [f'--foo={self.foo}']
124+
125+
126+
@simple_test
127+
class MyTestA(RegressionTest, MyPlugin):
128+
"""A test using the plugin"""
129+
130+
@simple_test
131+
class MyTestB(RegressionTest, MyPlugin):
132+
"""Another test using the plugin"""
133+
134+
135+
This class is equivalent to the deprecated :class:`RegressionMixin`.
136+
137+
.. versionadded:: 4.9
138+
'''
139+
_rfm_regression_class_kind = _RFM_TEST_KIND_MIXIN
140+
141+
142+
class RegressionMixin(RegressionTestPlugin):
107143
'''Base mixin class for regression tests.
108144
109-
Multiple inheritance from more than one
110-
:class:`RegressionTest` class is not allowed in ReFrame. Hence, mixin
111-
classes provide the flexibility to bundle reusable test add-ons, leveraging
112-
the metaclass magic implemented in
145+
Multiple inheritance from more than one :class:`RegressionTest` class is
146+
not allowed. Hence, mixin classes provide the flexibility to bundle
147+
reusable test add-ons, leveraging the metaclass magic implemented in
113148
:class:`RegressionTestMeta`. Using this metaclass allows mixin classes to
114149
use powerful ReFrame features, such as hooks, parameters or variables.
115150
116151
.. versionadded:: 3.4.2
152+
153+
.. deprecated:: 4.9
154+
155+
Use :class:`RegressionTestPlugin` instead.
117156
'''
118157

119-
_rfm_regression_class_kind = _RFM_TEST_KIND_MIXIN
158+
@classmethod
159+
def __init_subclass__(cls, **kwargs):
160+
super().__init_subclass__(**kwargs)
161+
user_deprecation_warning(
162+
'`RegressionMixin` is deprecated; '
163+
'please inherit from `RegresssionTestPlugin` instead'
164+
)
120165

121166

122-
class RegressionTest(RegressionMixin, jsonext.JSONSerializable):
167+
class RegressionTest(RegressionTestPlugin, jsonext.JSONSerializable):
123168
'''Base class for regression tests.
124169
125170
All regression tests must eventually inherit from this class.

reframe/utility/typecheck.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,8 @@ class ConvertibleType(abc.ABCMeta):
114114
For example, a class whose constructor accepts and :class:`int` may need
115115
to support a cast-from-string conversion. This is particular useful if you
116116
want a custom-typed test
117-
:attr:`~reframe.core.pipeline.RegressionMixin.variable` to be able to be
118-
set from the command line using the :option:`-S` option.
117+
:attr:`~reframe.core.pipeline.RegressionTestPlugin.variable` to be able to
118+
be set from the command line using the :option:`-S` option.
119119
120120
In order to support such conversions, a class must use this metaclass and
121121
define a class method, named as :obj:`__rfm_cast_<type>__`, for each of

unittests/test_fixtures.py

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -20,48 +20,48 @@ class Foo:
2020
# Wrong fixture classes
2121

2222
with pytest.raises(ValueError):
23-
class MyTest(rfm.RegressionMixin):
23+
class MyTest(rfm.RegressionTestPlugin):
2424
f = fixture(Foo)
2525

2626
with pytest.raises(ValueError):
27-
class MyTest(rfm.RegressionMixin):
28-
f = fixture(rfm.RegressionMixin)
27+
class MyTest(rfm.RegressionTestPlugin):
28+
f = fixture(rfm.RegressionTestPlugin)
2929

3030
# Session and partition scopes must be run-only.
3131

3232
with pytest.raises(ValueError):
33-
class MyTest(rfm.RegressionMixin):
33+
class MyTest(rfm.RegressionTestPlugin):
3434
f = fixture(rfm.RegressionTest, scope='session')
3535

3636
with pytest.raises(ValueError):
37-
class MyTest(rfm.RegressionMixin):
37+
class MyTest(rfm.RegressionTestPlugin):
3838
f = fixture(rfm.RegressionTest, scope='partition')
3939

4040
with pytest.raises(ValueError):
41-
class MyTest(rfm.RegressionMixin):
41+
class MyTest(rfm.RegressionTestPlugin):
4242
f = fixture(rfm.CompileOnlyRegressionTest, scope='session')
4343

4444
with pytest.raises(ValueError):
45-
class MyTest(rfm.RegressionMixin):
45+
class MyTest(rfm.RegressionTestPlugin):
4646
f = fixture(rfm.CompileOnlyRegressionTest, scope='partition')
4747

4848

4949
def test_fixture_args():
5050
'''Test invalid fixture arguments.'''
5151
with pytest.raises(ValueError):
52-
class MyTest(rfm.RegressionMixin):
52+
class MyTest(rfm.RegressionTestPlugin):
5353
f = fixture(rfm.RegressionTest, scope='other')
5454

5555
with pytest.raises(ValueError):
56-
class MyTest(rfm.RegressionMixin):
56+
class MyTest(rfm.RegressionTestPlugin):
5757
f = fixture(rfm.RegressionTest, action='other')
5858

5959
with pytest.raises(ValueError):
60-
class MyTest(rfm.RegressionMixin):
60+
class MyTest(rfm.RegressionTestPlugin):
6161
f = fixture(rfm.RegressionTest, variants='other')
6262

6363
with pytest.raises(TypeError):
64-
class MyTest(rfm.RegressionMixin):
64+
class MyTest(rfm.RegressionTestPlugin):
6565
f = fixture(rfm.RegressionTest, variables='other')
6666

6767

@@ -72,7 +72,7 @@ class Foo(rfm.RegressionTest):
7272
p = parameter()
7373

7474
with pytest.raises(ValueError):
75-
class MyTest(rfm.RegressionMixin):
75+
class MyTest(rfm.RegressionTestPlugin):
7676
f = fixture(Foo)
7777

7878

@@ -83,15 +83,15 @@ class Foo(rfm.RegressionTest):
8383
p = parameter(range(4))
8484

8585
with pytest.raises(ValueError):
86-
class MyTest(rfm.RegressionMixin):
86+
class MyTest(rfm.RegressionTestPlugin):
8787
f = fixture(Foo, variants={'p': lambda x: x > 10})
8888

8989
with pytest.raises(ValueError):
90-
class MyTest(rfm.RegressionMixin):
90+
class MyTest(rfm.RegressionTestPlugin):
9191
f = fixture(Foo, variants=())
9292

9393
# Test default variants argument 'all'
94-
class MyTest(rfm.RegressionMixin):
94+
class MyTest(rfm.RegressionTestPlugin):
9595
f = fixture(Foo, variants='all')
9696

9797
assert MyTest.fixture_space['f'].variants == (0, 1, 2, 3,)
@@ -103,7 +103,7 @@ def test_fork_join_variants():
103103
class Foo(rfm.RegressionTest):
104104
p = parameter(range(4))
105105

106-
class MyTest(rfm.RegressionMixin):
106+
class MyTest(rfm.RegressionTestPlugin):
107107
f0 = fixture(Foo, action='fork')
108108
f1 = fixture(Foo, action='join')
109109

@@ -119,7 +119,7 @@ class MyTest(rfm.RegressionMixin):
119119

120120

121121
def test_default_args():
122-
class Foo(rfm.RegressionMixin):
122+
class Foo(rfm.RegressionTestPlugin):
123123
f = fixture(rfm.RegressionTest)
124124

125125
assert Foo.fixture_space['f'].variables == {}
@@ -132,10 +132,10 @@ def test_fixture_inheritance():
132132
class Fix(rfm.RunOnlyRegressionTest):
133133
pass
134134

135-
class Foo(rfm.RegressionMixin):
135+
class Foo(rfm.RegressionTestPlugin):
136136
f0 = fixture(Fix, scope='test')
137137

138-
class Bar(rfm.RegressionMixin):
138+
class Bar(rfm.RegressionTestPlugin):
139139
f1 = fixture(Fix, scope='environment')
140140
f2 = fixture(Fix, scope='partition')
141141

@@ -151,10 +151,10 @@ class Baz(Foo, Bar):
151151
def test_fixture_inheritance_clash():
152152
'''Fixture name clash is not permitted.'''
153153

154-
class Foo(rfm.RegressionMixin):
154+
class Foo(rfm.RegressionTestPlugin):
155155
f0 = fixture(rfm.RegressionTest)
156156

157-
class Bar(rfm.RegressionMixin):
157+
class Bar(rfm.RegressionTestPlugin):
158158
f0 = fixture(rfm.RegressionTest)
159159

160160
# Multiple inheritance clash
@@ -166,7 +166,7 @@ class Baz(Foo, Bar):
166166
def test_fixture_override():
167167
'''A child class may only redefine a fixture with the fixture builtin.'''
168168

169-
class Foo(rfm.RegressionMixin):
169+
class Foo(rfm.RegressionTestPlugin):
170170
f0 = fixture(rfm.RegressionTest)
171171

172172
class Bar(Foo):
@@ -180,14 +180,14 @@ class Baz(Foo):
180180
Bar.f0 = 4
181181

182182
with pytest.raises(ReframeSyntaxError):
183-
class Baz(rfm.RegressionMixin):
183+
class Baz(rfm.RegressionTestPlugin):
184184
f0 = fixture(rfm.RegressionTest)
185185
f0 = 4
186186

187187

188188
def test_fixture_access_in_class_body():
189189
with pytest.raises(ReframeSyntaxError):
190-
class Foo(rfm.RegressionMixin):
190+
class Foo(rfm.RegressionTestPlugin):
191191
f0 = fixture(rfm.RegressionTest)
192192
print(f0)
193193

@@ -218,7 +218,7 @@ def test_fixture_space_access():
218218
class P0(rfm.RunOnlyRegressionTest):
219219
p0 = parameter(range(2))
220220

221-
class Foo(rfm.RegressionMixin):
221+
class Foo(rfm.RegressionTestPlugin):
222222
f0 = fixture(P0, scope='test', action='fork')
223223
f1 = fixture(P0, scope='environment', action='join')
224224
f2 = fixture(P0, scope='partition', action='fork')

unittests/test_parameters.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -199,10 +199,10 @@ class MyTest(ExtendParams):
199199

200200

201201
def test_param_space_clash():
202-
class Spam(rfm.RegressionMixin):
202+
class Spam(rfm.RegressionTestPlugin):
203203
P0 = parameter([1])
204204

205-
class Ham(rfm.RegressionMixin):
205+
class Ham(rfm.RegressionTestPlugin):
206206
P0 = parameter([2])
207207

208208
with pytest.raises(ReframeSyntaxError):
@@ -211,10 +211,10 @@ class Eggs(Spam, Ham):
211211

212212

213213
def test_multiple_inheritance():
214-
class Spam(rfm.RegressionMixin):
214+
class Spam(rfm.RegressionTestPlugin):
215215
P0 = parameter()
216216

217-
class Ham(rfm.RegressionMixin):
217+
class Ham(rfm.RegressionTestPlugin):
218218
P0 = parameter([2])
219219

220220
class Eggs(Spam, Ham):
@@ -276,7 +276,7 @@ class Foo(rfm.RegressionTest):
276276

277277

278278
def test_param_space_read_only():
279-
class Foo(rfm.RegressionMixin):
279+
class Foo(rfm.RegressionTestPlugin):
280280
pass
281281

282282
with pytest.raises(ValueError):

unittests/test_pipeline.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1065,7 +1065,7 @@ class BaseTest(HelloTest):
10651065
def x(self):
10661066
self.var += 1
10671067

1068-
class C(rfm.RegressionMixin):
1068+
class C(rfm.RegressionTestPlugin):
10691069
@run_before('run')
10701070
def y(self):
10711071
self.foo = 1
@@ -1099,7 +1099,7 @@ def weird_mro_test(HelloTest):
10991099
# See example in https://www.python.org/download/releases/2.3/mro/
11001100
#
11011101
# The MRO of A is ABECDFX, which means that E is more specialized than C!
1102-
class X(rfm.RegressionMixin):
1102+
class X(rfm.RegressionTestPlugin):
11031103
pass
11041104

11051105
class D(X):

0 commit comments

Comments
 (0)