-
Notifications
You must be signed in to change notification settings - Fork 117
Description
As we move more towards reusable tests, I think that adding support for stacking multiple sanity functions in the same test would greatly enhance test reusability.
Problem Example
Say we have a base class in a library with a general and basic sanity checking.
class BaseTest(rfm.RegressionTest, pin_prefix=True):
...
@rfm.run_before('sanity'):
def set_sanity_patterns(self):
self.sanity_patterns = some_basic_sanity_checkingand a derived class that extends the tests and requires of some other additional sanity checking.
from library.... import BaseTest
@rfm.simple_test
class MyTest(BaseTest):
...
@rfm.run_before('sanity')
def set_sanity_patterns(self):
self.sanity_patterns = some_more_advanced_sanity_checkingHere we would be overriding the sanity checking from the BaseTest class, and, assuming that we can't change the library's sources, the sanity checking from BaseTest is just impossible to reuse. This means that the derived class would have to rewrite code from BaseTest into MyTest to do the same sanity checking that was already implemented in BaseTest. Not ideal.
Problem solution
A new decorator that makes a function a deferred expression and flags the function as a sanity function would solve this problem. For example, if we call this decorator @sanity_function, the above can be rewritten as follows:
# The test library file
class BaseTest(rfm.RegressionTest, pin_prefix=True):
...
@sanity_function
def basic_sanity(self):
return some_basic_sanity_checking
# The file with the derived test
from library.... import BaseTest
@rfm.simple_test
class MyTest(BaseTest):
...
@sanity_function
def my_derived_sanity(self):
return some_more_advanced_sanity_checkingAnd this would make reframe run both basic_sanity and my_derived_sanity in the sanity pipeline stage. This removes the need of explicitly setting the sanity_patterns variable every time, since the decorator would just take care of that.