exitcode directive
ClosedPublic

Authored by lbrabec on Jul 16 2015, 8:33 AM.

Details

Summary

After discussion in T450, new exitcode directive is introduced.
It accepts two mutually exclusive keys tap_last and tap_worst
that extract last or worst outcome from TAP.

Test Plan

used this task formula

name: tasktest
desc: blah blah
maintainer: lbrabec

actions:
    - name: print hello world
      python:
          file: hw.py
          callable: run
      export: tap

    - name: return exitcode
      exitcode:
          tap_last: ${tap}

Diff Detail

Repository
rLTRN libtaskotron
Lint
Automatic diff as part of commit; lint not applicable.
Unit
Automatic diff as part of commit; unit tests not applicable.
lbrabec retitled this revision from to exitcode directive.Jul 16 2015, 8:33 AM
lbrabec updated this object.
lbrabec edited the test plan for this revision. (Show Details)
lbrabec added reviewers: kparal, jskladan, mkrizek.
jskladan requested changes to this revision.Jul 16 2015, 9:58 AM

Looks good overall, but please add unittests for the ExitcodeDirective.

libtaskotron/runner.py
134

Please document why this is necessary instead of isinstance()

This revision now requires changes to proceed.Jul 16 2015, 9:58 AM
kparal requested changes to this revision.Jul 16 2015, 10:30 AM

I guess this is just a preliminary review, since there are no unit tests yet. Some quick comments below.

libtaskotron/directives/exitcode_directive.py
12

The docs fail to build.

14

maybe "set runtask exit code" instead of "generate exitcode"

30

Let's document the return type as well, and the values (since they are hard-coded).

32–36

This seems to be part of the returns section, while it should be probably in description.

38–39

"exactly one of keys ..." would be probably more precise

40

Current libtaskotron version is 0.3.17. You should make sure it is not the same as the last publicly released version, and if it is, bump it to 0.3.18 (I guess) and adjust the spec file as well.

58–59

Ditto.

63

Would this be a bit more readable?

if ['tap_worst' in input_data, 'tap_last' in input_data].count(True) != 1:

Or, alternatively, why do you have not and != together? Would this work?

if ('tap_worst' in input_data) == ('tap_last' in input_data):
64–65

Ditto.

76
assert 'tap_last' in input_data

above this line would add some extra error checking. Just an idea.

78

This is probably not intended here. But a log.debug statement before every return statement in this directive would be nice.

libtaskotron/runner.py
39

Can you please document (using a standard Sphinx syntax, so that it's visible in the generated docs) what this is for (that's rather obvious) and what values this can have? Number, string, boolean,... and what None means?

135

It would be great to add a comment here documenting the intended intention (i.e. failure should not be overridden with later success).

136

Let's add a log.info here, it's an important change.

278–279

I'd add another log.info here, saying that we're exiting with exit status $number because something failed and this beahavior was requested.

jskladan added inline comments.Jul 16 2015, 11:32 AM
libtaskotron/directives/exitcode_directive.py
63

Or, alternatively, why do you have not and != together? Would this work?

The truth is, that the code is flawed - it is supposed to behave like XOR, but is not. The XOR-like behaviour is actually this piece of code:

if ('tap_worst' in input_data) != ('tap_last' in input_data):

Which corresponds to the ...count() example of yours, but IMHO is quite a bit more readable.

lbrabec added inline comments.Jul 16 2015, 12:05 PM
libtaskotron/directives/exitcode_directive.py
63

Well, it should behave like NXOR, which is actually equivalence, wonder how i missed that, @kparal 's solution with == should be fine.

lbrabec updated this revision to Diff 1188.Jul 16 2015, 1:13 PM
  • code polishing
lbrabec updated this revision to Diff 1190.Jul 16 2015, 1:48 PM
  • exitcode unit tests
kparal requested changes to this revision.Jul 16 2015, 2:14 PM

Thanks, can you please add unit tests?

libtaskotron/directives/exitcode_directive.py
20–22

Please also mention what happens when the TAP is empty (no results).

39

I'm mildly confused by input data, it looks like a variable input_data, but without the underscore - but the user doesn't know anything about that variable. It's probably better to say

* :class:`.TaskotronDirectiveError`: when there's not exactly one of parameters ``tap_last`` or ``tap_last`` present
45–58

I'd probably include even the python directive step so that it's more obvious. What about:

Run a check returning multiple results and make ``runtask`` fail if any of the results is failed::

  - name: run my check and return TAP
    python:
        file: my_check.py
        callable: run
    export: tap

  - name: set runtask exit code according to the worst result in TAP
    exitcode:
        tap_worst: ${tap}

Run a check that returns multiple results and one "overall" result (at the end) which is computed according check's internal logic. Then make ``runtask`` fail if the overall result failed::

  - name: run my check and return TAP
    python:
        file: my_check.py
        callable: run
    export: tap

  - name: set runtask exit code according to the last (overall) result in TAP
    exitcode:
        tap_last: ${tap}
60–61

Please move this into the description instead of examples, thanks.

84

I'm confused. Shouldn't this be == after all?

98

The idea of the proposed assert was that you try to catch a error that should never occur (defensive programming). So with your latest change, it would look like this:

if 'tap_worst' in input_data: 
  # do something
elif 'tap_last' in input_data:
  # do something
else:
  assert False, "This should never occur"

This protects you against future changes (renaming one of the arguments and forgetting adjusting the code here).

This revision now requires changes to proceed.Jul 16 2015, 2:14 PM

You were quicker than me :) Unit tests look good, a few more use cases would be great to have covered, comments below.

libtaskotron/runner.py
137–139

Can you please write a short unit test for this as well? That it was saved correctly the first time, and that it can be overridden with worse but not better result.

testing/test_exitcode_directive.py
13

Please also test an empty TAP (no results), and imparseable TAP (that should probably also be documented to throw an error). Otherwise it looks good.

lbrabec updated this revision to Diff 1193.Jul 16 2015, 3:04 PM
lbrabec marked 7 inline comments as done.
  • code polishing, more tests
kparal accepted this revision.Jul 17 2015, 7:23 AM

Thanks, looks good. Sorry for so many concerns.
Before committing, please add that one missing line of documentation.

libtaskotron/directives/exitcode_directive.py
92

Please also add this to the main directive documentation.

Closed by commit rLTRN6d0d0cfa52a4: exitcode directive (authored by Lukas Brabec <lbrabec@redhat.com>, committed by Lukas Sparrow <lukas.sparrow@gmail.com>). · Explain WhyJul 17 2015, 7:34 AM
This revision was automatically updated to reflect the committed changes.