-
Notifications
You must be signed in to change notification settings - Fork 117
Filter out tests with no programming environments #319
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
* Create the corresponding unit test.
Codecov Report
@@ Coverage Diff @@
## master #319 +/- ##
==========================================
+ Coverage 91.18% 91.26% +0.08%
==========================================
Files 67 67
Lines 7941 8005 +64
==========================================
+ Hits 7241 7306 +65
+ Misses 700 699 -1
Continue to review full report at Codecov.
|
reframe/frontend/cli.py
Outdated
| for e in options.prgenv) else None, | ||
| lambda c: c if (c.valid_prog_environs | ||
| and all(c.supports_environ(e) | ||
| for e in options.prgenv)) else None, |
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 lambda gets a bit too complicated. Since this operation is quite useful, I suggest writing a function in utility doing that thing:
def allx(iterable):
# we should check here specifically if `iterable` is actually an iterable, as real all() does
if not iterable:
return False
return all(iterable)Would it also make sense to provide a deferrable version of this function in this PR, too?
* Create `allx` function in `reframe/utility/__init__.py`. * Create the corresponding deferrable version of `allx`. * Create the unit tests for the above functions. * Use raw strings in some regular expressions to avoid warnings.
reframe/utility/sanity.py
Outdated
|
|
||
| @deferrable | ||
| def allx(iterable): | ||
| """Replacement for the :func:`allx() <reframe.utility.allx>` function. |
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.
The documentation of reframe.utility is not public, so you may not refer to it here.
reframe/utility/__init__.py
Outdated
|
|
||
| def allx(iterable): | ||
| """Return ``True`` if all elements of the `iterable` are true. If | ||
| iterable is empty or ``None`` return ``False``. |
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 would phrase this different to stress the connection with the builtin
all(): Same as the built-inall, except that it returnsFalseifiterableis empty. - This function must be fully equivalent with the built-in
all()ifiterableis not empty, which means, we should raiseTypeErrorif the argument isNone. Pay attention to have fully compatible behaviour. - There are several documentation formatting issues here:
- Double backquotes must be used for citing function arguments, here
iterable. None,TrueandFalsemust be formatted as:class:`None`,:class:`True`etc.
- Double backquotes must be used for citing function arguments, here
| first_item = next(iterable) | ||
| return all(itertools.chain([first_item], iterable)) | ||
| except StopIteration: | ||
| return False |
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 can't understand all this fuss here. Why a check of iterable against collections.abc.Iterable wouldn't just work?
>>> import collections
>>> isinstance(range(0), collections.abc.Iterable)
True
>>>
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.
Because we do not want to accept empty generators. Is there any other way to check that a generator is empty?
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 by "empty generator"? A generator is a generator, i.e., an iterable, even if it doesn't produce any values. Your unit tests should pass fine using my proposal.
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 mean a generator like (i for i in []) if it is passed to allx how can I check that there are no elements and return False?
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.
Now, I get what you are trying to do. The comment above the code is really misleading... Please change it with sth more precise!
reframe/utility/__init__.py
Outdated
| except StopIteration: | ||
| return False | ||
|
|
||
| if not iterable: |
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 not enough. If iterable is None, we should raise a TypeError as all() does.
unittests/test_sanity_functions.py
Outdated
| self.assertFalse(expr3) | ||
| self.assertFalse(expr4) | ||
| self.assertFalse(expr5) | ||
| self.assertTrue(expr6) |
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.
You can combine these assertions with the expressions above.
unittests/test_sanity_functions.py
Outdated
| expr3 = sn.allx([]) | ||
| expr4 = sn.allx(None) | ||
| expr5 = sn.allx(i for i in []) | ||
| expr6 = sn.allx(i for i in [1]) |
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 would use ranges here.
reframe/utility/__init__.py
Outdated
| if isinstance(iterable, types.GeneratorType): | ||
| try: | ||
| first_item = next(iterable) | ||
| return all(itertools.chain([first_item], iterable)) |
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.
Better put this in the else block of the try/except. Also rename first_item to first or head.
- Rationale on special treatment of generators in allx. - Document the sanity function correctly. - Correct line splits.
…-fixes Code organisation fixes
|
@jenkins-cscs retry all |
vkarak
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.
@teojgo @victorusu I think there is a fundamental problem with this PR:
On master, this
./reframe.py -C config/cscs.py -c cscs-checks/ -R -l
gives a whole listing of the tests, whereas here it gives nothing!
|
@victorusu what should be the expected behavior when a check has an empty prgenv list and we also do not specify any particular prgenv to ReFrame? |
|
@teojgo @victorusu The logical thing to do would be to print the test if it supports any programming environment, i.e., |
reframe/frontend/cli.py
Outdated
| # Here we also check that the valid_prog_environs of the check | ||
| # is an iterable and not empty | ||
| filter_func = lambda c: c if util.allx( | ||
| c.valid_prog_environs) else None |
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 suggest replacing the lambdas altogether here in favour of a closure:
def filter_prgenv(c):
if options.prgenv:
return util.allx(c.supports_environ(e) for e in options.prgenv)
else:
return bool(c.valid_prog_environs)
Fixes #244