-
Notifications
You must be signed in to change notification settings - Fork 117
[feat] Re-implement pipeline hook mechanism and add a post-init hook #1865
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
Conversation
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.
lgtm. I just wonder if it makes sense to tell the difference between the run_before('setup'), compared to run_after('init'). Or in other words, what is the init hook meant to be used for.
I find very very confusing that a standard Python method can magically override a reframe hook. I'm struggling to see what the advantage is of having this |
Basically, yes. It is just syntactic sugar. Generally, everything can go into hooks, but there is one case that you can't use hooks: it's when you have to deal with test filtering. There are tests that we change the tags or the |
|
I will postpone this PR to the next sprint, since I would like to improve also the current hook mechanism to follow the same pattern as with what we have discussed with |
Pipeline hooks are now implemented in the metaclass. The logic is very similar to that of the variables and parameters. As the class hierarchy is built, a `HookRegistry` is maintained containing all the hooks. When the test object is created for the first time, all of its pipeline methods are wrapped with the corresponding pipeline hooks. Moving the implementation to the metaclasses brings a set of advantages: - Inheritance is handled by Python and there is no need to manually ascend the class hierarchy when the hook is applied. - For storing the hooks of each phase, we use an ordered set and we make sure that firstly the hooks of the class that is being currently created are inserted and then those of its parents. This way we ensure that hooks are properly overriden. - By using metaclasses, hooks are more consistent and are automatically applied correctly to any method overrides.
jjotero
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 like the idea of the HookRegistry, but I'm not convinced by the new way the pipeline stages are dynamically decorated to pick up the hooks. I see no reason to do that and I feel that it makes more sense to have the pipeline stages decorated in the pipeline itself. See comments below.
The "problem" is that we need to handle disabled hooks. Users can disable hooks on-demand and this happens after the test has been created. Regardless if the |
Co-authored-by: Javier Otero <71280927+jjotero@users.noreply.github.com>
|
Hello @vkarak, Thank you for updating! Cheers! There are no PEP8 issues in this Pull Request!Do see the ReFrame Coding Style Guide Comment last updated at 2021-04-06 18:59:34 UTC |
Pipeline hooks are no more applied to the pipeline functions with the decorator. This has the following advantages: a. Hooks will be automatically applied to any pipeline function that is overriden by a subclass. b. The hooks will wrap the leaf function and not the call to `super().pipeline_fn()` c. The hooks will be applied only once in all cases even if a test and its child classes are instantiated multiple times.
Codecov Report
@@ Coverage Diff @@
## master #1865 +/- ##
=======================================
Coverage 87.90% 87.91%
=======================================
Files 49 50 +1
Lines 8451 8491 +40
=======================================
+ Hits 7429 7465 +36
- Misses 1022 1026 +4
Continue to review full report at Codecov.
|
jjotero
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
Overload `__getattribute__` in the pipeline
fcbe878 to
5840403
Compare
And apply the fix in all tests in `test_policies.py`.
fce97f9 to
59e9f57
Compare
|
I fixed the unit tests in |
|
@jenkins-cscs retry all |
With the new syntax of variable definition we can almost get rid of
__init__(). Currently, functions likedepends_on()must still be called during initialisation, but this will be addressed by #1864. However, there will still be cases that something must be executed during the initialisation and this is when you want to have dynamic tags, for example, change the tags based on a test parameter. In order for the frontend to be able to select tests by tags, the tags must be finalised after the initialisation, so you can't practically set them in any other pipeline stage.The post-init hook introduced here is fairly simple it can substitute the constructor. The following:
is equivalent to
Of course, the example with
init_a()andinit_b()is a bit silly, but it gets more sense if you imagine test hierarchies.If a test defines__init__(), any init hooks will be ignored.Finally, there are no pre-init hooks, although it's trivial to implement. I'm not introducing them here, unless there is a need.
Fixes #1863.
Implementation details
The pipeline mechanism is re-implemented from scratch. Pipeline hooks are no more applied to the pipeline functions with the decorator. This has a number of advantages:
a. Hooks will be automatically applied to any pipeline function that is overriden by a subclass.
b. The hooks will wrap the leaf function and not the call to
super().pipeline_fn()c. The hooks will be applied only once in all cases even if a test and its child classes are instantiated multiple times.
Specific implementation tricks and intricacies are explained with comments in the code.