Details
- Reviewers
kparal tflink mkrizek jskladan - Maniphest Tasks
- T95: Make task output in the runner more readable
- Commits
- rLTRNd4de0b2847ec: Make sure python directive returns a string
$ python runtask.py -i xchat-2.8.8-21.fc20 -t koji_build -a x86_64 ../task-rpmlint/rpmlint.yml
$ python runtask.py -i tigervnc-1.3.0-14.fc20 -t koji_build -a x86_64 ../task-examplebodhi/examplebodhi.yml
Diff Detail
- Repository
- rLTRN libtaskotron
- Lint
Lint Skipped - Unit
Unit Tests Skipped
I'm not sure I understand the reason for enforcing the return of a single string from the python directive other than making sure it's consistent.
Can you elaborate a bit on why enforcing a single string return is the best solution here when other directives return non-strings?
Tim, thanks for the comment. I thought about it and I realized several important things.
My initial motivation was to make check output consistent and my reasoning was like this:
- Checks are expected to return TAP.
- TAP is a string. It can't be a list, it doesn't make much sense. If it were a list, should we simply join it by newlines? Or would it be a list of individual TAP results, so that we would have to join them in a proper TAP manner (delimiters and such) and then generate the TAP header? It's too complicated, too much to explain, too much to document, without any clear benefit. Therefore TAP is a string. Simple, expected.
- Checks are run through the python directive.
- Outcome: The python directive must return a string and we should enforce it.
However, I realized:
a) We currently have no documentation at all regarding directive output. Different directives can return a range variety of data, and there's no way to knowing what data unless you read the source code. We should put return data documentation into the directive docstring in the very least.
b) The check doesn't have to be executed by the python directive. That is not true at the moment, but can/should easily become true in the future (bash checks, for example).
c) The python directives doesn't have to execute checks. It can be some other code, for example some environment preparation scripts (and then, in another python directive can the actual check be run).
d) We currently print to stdout anything that we find in Runner.working_data and assume they are check results. That's a bit shortsighted, because working_data should be used for arbitrary data transfer, not just check results. We will need to change that as well and find a better way to distinguishing check results from other data.
This is just a food for thought at the moment, we won't solve all of that here, we will need to file individual tickets for these issue. Here, I think we could start with the basics:
- This patch should be modified to allow str and None values as python directive output. That covers the most basic needs (TAP output and not-a-check python script).
- The python directive's docstring should be adjusted to reflect that.
If you agree with the core problems mentioned, I would create individual tickets for them. This patch might get reverted once we solve them, but in the mean time, it would ensure consistent and valid check output. What do you think?
TAP is a string. It can't be a list, it doesn't make much sense. If it were a list, should we simply join it by newlines? Or would it be a list of individual TAP results, so that we would have to join them in a proper TAP manner (delimiters and such) and then generate the TAP header? It's too complicated, too much to explain, too much to document, without any clear benefit. Therefore TAP is a string. Simple, expected.
Checks are run through the python directive.
Outcome: The python directive must return a string and we should enforce it.
OK, that makes sense for the time being, at least. Are our reporting directives capable of understanding multiple TAP results concatenated together? Do we currently have any checks that output multiple TAP streams? I can't think of any off the top of my head.
a) We currently have no documentation at all regarding directive output. Different directives can return a range variety of data, and there's no way to knowing what data unless you read the source code. We should put return data documentation into the directive docstring in the very least.
Yeah, that's a problem. I think that it's partially covered by T183 and T142 but there's a lot of stuff not covered by those two tickets.
b) The check doesn't have to be executed by the python directive. That is not true at the moment, but can/should easily become true in the future (bash checks, for example).
c) The python directives doesn't have to execute checks. It can be some other code, for example some environment preparation scripts (and then, in another python directive can the actual check be run).
d) We currently print to stdout anything that we find in Runner.working_data and assume they are check results. That's a bit shortsighted, because working_data should be used for arbitrary data transfer, not just check results. We will need to change that as well and find a better way to distinguishing check results from other data.
These are good points. Thanks for bringing them up.
This is just a food for thought at the moment, we won't solve all of that here, we will need to file individual tickets for these issue. Here, I think we could start with the basics:
Yeah, I think that we need to spend some time making sure that our internals are at least reasonably consistent and documented. I suspect that the directive docs will go a ways toward making this better but that's getting a bit off topic for a code review :)
This patch should be modified to allow str and None values as python directive output. That covers the most basic needs (TAP output and not-a-check python script). The python directive's docstring should be adjusted to reflect that.
Agreed. @lbrabec, would ypu update the revision to do this?
If you agree with the core problems mentioned, I would create individual tickets for them. This patch might get reverted once we solve them, but in the mean time, it would ensure consistent and valid check output. What do you think?
Sounds like a plan to me.
Are all of those test_python_directive.py changes still necessary when we allowed None to be returned?
Can you please add a new unit tests that verifies that TaskotronDirectiveError gets raised when you try to return something else than None and basestring? (Be sure to also test corner cases like an empty string, or an empty list). Thanks.
libtaskotron/directives/python_directive.py | ||
---|---|---|
69 | You should use if output is not None. Otherwise an empty list (for example) would not get checked. | |
70–73 | This could easily fit on two lines, but I don't want to talk too much into your code structuring habits :-) What interests me, though, are the redundant str() calls I see lately. If there was just "%s" % output and output could be anything, then yes, if output was a tuple, then it could break the formatting. But since you already call type() on it and you know what gets returned (a type), you no longer need to manually cast it to string, that's what %s does for you. Just a nitpick. | |
libtaskotron/runner.py | ||
200–203 | It seems your formatting is somehow broken (no whitespace between variable name and value?). I'd suggest a bit more readable approach (not tested): log.info('Check execution finished. Showing stored variables:') for name, value in task_runner.working_data.items(): log.info("%${s}:\n%s" % (name, value)) |
libtaskotron/runner.py | ||
---|---|---|
203 | Thanks for correcting my typo :-) |
You should use if output is not None. Otherwise an empty list (for example) would not get checked.