-
Notifications
You must be signed in to change notification settings - Fork 117
Description
We need to support the notion of fixtures for a ReFrame test. A fixture is different from a test dependency and different from a test parameter. The will execute where ReFrame runs and perform operations such as cloning a repo, connecting to a resource that a test needs etc.
Test dependencies in ReFrame differ from fixtures in that they have to deal with the individual test cases (where a test can run and with which programming environments). A fixture will run regardless and will run on the same node that ReFrame itself executes.
Test parameters as discussed in #1567 differ again to fixtures in that the parameterization space is attached to a test we want it to be inherited by its children. Having parameters as fixtures, would require the children to redefine the whole parameter space everytime. We also want parameter attributes to be set.
A typical fixture example, is when you want a test to clone a repo and you don't want to do that for each test case. The current solution is by using test dependencies: have a test to run on a single partition and programming environment and the test doing the actual work depend fully on that one. The problem with this is that you can end up with unresolved dependencies if you run ReFrame with --system=x:part where x:part is not the partition that the test that clones the source is meant to run. This is in fact a restriction that should not exist. You want to clone the repo regardless of where the test executes. That's why we need to introduce the concept of fixtures. Here is an example that shows potential syntax (inspired by pytest fixtures):
import reframe as rfm
@rfm.fixture
def tmp_path():
yield a_dir_under_stage_prefix()
@rfm.fixture
def clone_repo(tmp_path):
def _clone_repo(repo):
return git_clone_repo()
return clone_repo
class MyTest(rfm.RegressionTest):
use_fixture('repo', clone_repo('url'))
def __init__(self):
self.valid_systems = ['dom:gpu', 'dom:mc']
self.valid_prog_environs = ['gnu', 'cray']
self.sourcesdir = self.repo
...Fixtures can be quite intelligent so as not to clone the same repo again and do some reference counting before deleting paths.
In this example, MyTest will clone the test once for all the test cases of MyTest without having to rely on dependencies for this sort of task.