-
Notifications
You must be signed in to change notification settings - Fork 117
New style checks #264
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
New style checks #264
Conversation
- No more `ResourcesManager` - A global runtime (`RuntimeContext`) is introduced, which holds all the information about the system the framework is currently running. This information includes the current host system and its configuration, the associated modules system and the resources of the framework (ex `ResourcesManager`). Anybody who wants to access any of this information, he may do so by calling `runtime()` to retrieve the `RuntimeContext` instance. - Unit tests are considerably refactored to match this redesign. The `test_reframe.py` initialises a runtime (either a user-specified one or the `generic` one from some predefined unit-test-specific settings. Also, functionality to temporarily switch to a different runtime (not possible normally) is offered to the unit tests for special test cases. Job scheduler unit tests became a bit more generic allowing easier testing of new backends.
- With Python 3.5 - On systems without Tmod
Both for unit tests and the normal ReFrame invocations.
…into feature/new-style-checks
|
@jenkins-cscs retry all |
omlins
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM so far (I found only 2 little things)
reframe/core/runtime.py
Outdated
|
|
||
| @property | ||
| def partitions(self): | ||
| """Get all the partitions of this system. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In agreement with the way you did the comments for name, descr and resourcesdir, I would note here instead:
"""All the partitions of this system.
or
"""The partitions of this system.
unittests/fixtures.py
Outdated
| def partition_with_scheduler(name, skip_partitions=['kesch:pn']): | ||
| """Retrieve a partition from the current system whose registered name is | ||
| def partition_with_scheduler(name=None, skip_partitions=['kesch:pn']): | ||
| """Retrieve a natice system partition whose scheduler is registered with |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
natice -> native
- The boilerplate code for calling the `RegressionTest` constructor is no more required; the base constructor may now be called without any arguments. - The `_get_checks()` method is no more required. The test are registered with class decorators. - The basic classes and decorators are now exported at the top-level `reframe` module for convenience. Other improvement and fixes brought by this commit: - Use our module load mechanism only if an absolute path is passed. Otherwise use `importlib.import_module`, which also takes care of the PEP420 namespace packages. - To decouple the frontend code from the CLI further, a new `SystemAutodetectionError` is raised in cases of system autodetection failure. - All the ReFrame test files used for unit tests are now moved under a new directory named `checks/` in `unittests/resources`. This was done to allow to have separate directories for unlisted tests, i.e., that need not to be listed and counted by the loader's and policies' unit tests.
victorusu
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is definitely a long change.
I took forever reviewing it today.
I am excited with the use of the visitor pattern for the RegressionCheckValidator.
I can see it being used for other things too.
The new syntax is awesome!
Great job!
reframe/frontend/cli.py
Outdated
| # Load configuration | ||
| try: | ||
| settings = config.load_from_file(options.config_file) | ||
| settings = config.load_settings(options.config_file) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let me a bit picky...
Can we stick with the load_from_file? Or have it load_settings_from_file? Or just settings_from_file or from_file?
I think it is important to stick to the "from file" part. It makes easier to understand the code
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't want to use the load_from_file, cos this makes more sense as a method of class. Nonetheless, I will change it to settings_from_file() or load_settings_from_file().
| if not s: | ||
| return '' | ||
|
|
||
| return re.sub(r'([a-z])([A-Z])', r'\1_\2', s).lower() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it enough to just call s.lower()?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you mean?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@victorusu What do you mean here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We finally don't use this function. I have kept it though, because it's a perhaps useful utility.
omlins
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the automatic generation of test.name needs to be revised.
unittests/test_pipeline.py
Outdated
| super().__init__(1, 2) | ||
|
|
||
| test = MyTest() | ||
| self.assertEqual('my_test', test.name) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As we enforce since version 2.12 that the names of the loaded tests must be unique (https://eth-cscs.github.io/reframe/running.html?highlight=unique#discovery-of-regression-tests), I have the following doubt. Don't we get non-unique names e.g. in the following scenario?
class BaseMatrixVectorTest(RegressionTest):
def __init__(self):
...
...
class SerialTest(BaseMatrixVectorTest):
def __init__(self):
...
...
...and (in another file):
class BaseStencilTest(RegressionTest):
def __init__(self):
...
...
class SerialTest(BaseStencilTest):
def __init__(self):
...
...
We get in both cases test.name equal to serial_test, right? If I am not overseeing something and it is like that, then I think this must be avoided, because it is not an unlikely scenario. One solution could be to prefix the generated names additionally with the name(s) of the super class(es).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Personally, I can't see this as a blocking issue for this PR. The class name is a guess and a convenience; the users may always set their own name if a conflict occurs or if they don't trust the auto-generation mechanism. Whichever heuristic we had with the name, there would always be a case to fool it. In your scenario, it could be easily fooled if the same class names were also present at another file. Then, we end up having to include the name of the file. Oops, this is not enough either! Because, we might have two files with the same class structure in different directories and so on an so forth. We would end with too long, unusable test names, forcing the users to use their own... After all, the conflict detection mechanism is still valid, since it checks the names during loading the test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I totally agree that the test name generation does not need to be bullet proof; it only needs to catch the common scenarios (as we have discussed already some days ago off-line). Now, how common the above scenario is depends very much on the programming habits of the users.
Besides the uniqueness issue, the test name should be most meaningful but not too long as you pointed out. One could maybe use somehow the name of the direct superclass (if it is defined by the user) to make the test names more meaningful. However, this could already make the name too long...
In any case this issues are certainly not blocking as you say. You may merge it as is and we may see later if the automatic test name generation can still be improved...
I think it would be good to explain in the documentation how the names are generated such that the users may make good usage of it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To fix this, I'm gonna use the fully qualified name of the class from the __qualname__ attribute.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@omlins Prefixing with the module name (or anything derived from the filesystem) is not a good idea. The __qualname__ does not do that deliberately. Have a look here. I suggest getting along with just the qualified name (which covers also nested classes compared to __name__) and if a conflict occurs, then the user may define its own name.
|
@omlins Can you review again and possibly approve this PR? |
|
@jenkins-cscs retry all |
|
Raised the priority of this PR. We need to merge asap, cos it's blocking everything else in the sprint. |
|
@omlins Thanks for approving. I am still not entirely sure whether it's better to prefix the the automatically generated test name with the module name or not, but let's leave it open for discussion internally. |
This PR provides two things:
Host resources and unit tests refactoring
The refactoring of the resources code is based on the following concept:
RuntimeContext. This information includes the current host system, the current modules system and the directory resources management (exResourcesManager).systemandresourcesarguments that used to be passed through to theRegressionTests are removed. This information is now accessible inside theRegressionTestby the runtime. This change is transparent to the current regression tests.reframe.core.runtime.runtime()function, which returns aRuntimeContextobject, from which access to the host system, modules system and the resources manager is given.test_reframe.py, initialises the framework's runtime based on a special settings fileunittests/resources/settings.py. This file defines agenericsystem to allow the unit tests to run on any machine and fake one (exTEST_SITE_CONFIGin fixtures) for testing the framework's behaviour with site-specific settings.test_reframe.pydriver adds an option,--rfm-user-config, for specifying a custom user configuration file. Contrary to the past, these settings DO NOT replace globally the ReFrame configuration during the unit tests. Instead, only the unit tests that need a specific user configuration (e.g., SLURM tests) temporarily change to the user configuration using the@fixtures.switch_to_user_runtime. These tests then do the necessary setup and check if they can continue or be skipped.Other changes brought by this PR (related to unit tests and host resources):
init_modules_system()andget_modules_system()methods are removed. Instead a modules system is created by calling theModulesSystem.create()method. To retrieve the current modules system, one has to first retrieve the runtime and then access it from there.settingsare not stored in the framework internally. It would now only be needed for retrieving the logging settings, but this is not the case, so for simplicity, only theload_settings()(exload_from_file()) method is retained. Accessing anything related to the global configuration may only be done through the globalRuntimeContext.SiteConfigurationclass were moved inside itsload_from_dict()method to avoid cyclic dependencies at import time. Since the this class creates several core components of the framework it needs to be as independent as possible at the import time. This is called by the runtime to set itself up, but other basic components of the framework may need the runtime services to fulfil their operations.SiteConfigurationclass moved to the core.RegressionTest._setup_paths()is now replaced by setting up the appropriate validation of the corresponding attributes in the respective classes. To achieve this anExtendedAlphanumericFieldwas added that accepts-as valid characters apart from those typically accepted by an alphanumeric field.Systemclass is now immutable. All the user-supplied directory prefixes are set in theHostResources. This class uses properties to compute dynamically the actual prefixes (e.g., using or not timestamps)generate_test_configof the unit tests is now removed. Log files and other resources pertaining to the unit tests ReFrame configuration have a specialrfm_prefix.force_remove_file()function moved toutility.os_ext.SiteConfigurationare added again, after accidentally being removed in a previous PR.New-style checks
RegressionTestconstructor is no more required; the base constructor may now be called without any arguments._get_checks()method is no more required. The test are registered with class decorators.reframemodule for convenience.Other improvement and fixes brought by this PR:
importlib.import_module, which also takes care of the PEP420 namespace packages.SystemAutodetectionErroris raised in cases of system autodetection failure.checks/inunittests/resources. This was done to allow to have separate directories for unlisted tests, i.e., that need not to be listed and counted by the loader's and policies' unit tests.ModulesSystemclass is now exposed to and documented for the users.Still in progress
Thereframe.core.decoratorsis a bit obsolete now.The new style checks are still to come, but it should now be easy to be implemented.CI script needs to be adapted to use the--rfm-user-configoption.A bit of code cleanup.Update documentation.Fixes #51.
Fixes #70.