-
Notifications
You must be signed in to change notification settings - Fork 59
8. Conditional Test Operators
-
Conditional operators introduced in v1.1:
- AND
- OR
- NOT
-
Following grammar is used by the operators:
exp -> catA-op exp exp | catB-op ETC
catA-op -> AND | OR
catB-op -> NOT | epsilon
ETC: Elementary test condition
-
AND, OR are n-ary operators. NOT is an unary operator. If any deviation is observed, for ex, passing more than one ETC to a unary operator or passing one ETC to a n-ary operator, the parser will simply ignore that logical sub-expression and continue evaluating remaining sub-expressions.
-
If all sub-expressions are skipped then no ETCs are executed. For module version, this means that Operator.result will now be
None
instead of earlierTrue
. -
Refer to Example 2 below. If instead of the top most OR operator you want to use AND operator, there is no need to write it explicitly. The parser will consider AND to be the default operator will evaluating. Thus one can write:
tests: - AND: - is-equal: admin-status, up - is-equal: admin-status, down - OR: - is-equal: oper-status, up - is-equal: oper-status, down
It will be evaluated as
(? AND ?) AND (? OR ?)
-
[IMP] The operators have evaluation shortcut optimization builtin. This means that the evaluation of the subexpression under AND operator will stop when the first
false
is encountered. Remaining subexpressions down the list will be skipped. In case of OR operator when the firsttrue
is encountered, evaluation of that subexpression is stopped. Refer example for in-depth explanation.
- Nothing is removed only new things are added.
- Each test's status is also shown in the final report. Here each test is treated as an expression and the result of evaluation of that expression is reported.
- For module version, one can access the new
Operator.result_dict
dictionary (key => test_name, value=> result[True/False/None])
to access the result of each test. User should ensure that test names in a test suite remain unique. If they repeat, the result of older instance gets overwritten. - One should not confuse the no. of test cases passed or fail reported at the end with the no. of sub-expressions/expressions failed or passed.
tests_include:
- test_interfaces_terse
test_interfaces_terse:
- command: show interfaces terse lo*
- item:
id: ./name
xpath: //physical-interface[normalize-space(name) = "lo0"]
tests:
- AND:
- is-equal: admin-status, down
info: "Test Succeeded !! admin-status is equal to <{{post['admin-status']}}> with oper-status <{{pre['oper-status']}}>"
err: "Test Failed !! admin-status is not equal to down, it is <{{post['admin-status']}}> with oper-status <{{pre['oper-status']}}>"
- is-equal: admin-status, up
info: "Test Succeeded !! admin-status is equal to <{{post['admin-status']}}> with oper-status <{{pre['oper-status']}}>"
err: "Test Failed !! admin-status is not equal to up, it is <{{post['admin-status']}}> with oper-status <{{pre['oper-status']}}>"
-
There were two ETCs namely
- is-equal: admin-status, down
and- is-equal: admin-status, up
. -
As reported in the results the first ETC passed and the second failed.
-
The result of this
AND(pass, fail) = fail
is reported in the final result in the following waytest_interfaces_terse : Failed
i.e.<test_name> : <result of expression evaluation>
-
"Total number of tests" in the final result mean the total number of ETCs
-
Notice that the final result is "Failed".
tests_include:
- test_interfaces_terse
test_interfaces_terse:
- command: show interfaces terse lo*
- item:
id: ./name
xpath: //physical-interface[normalize-space(name) = "lo0"]
tests:
- OR:
- AND:
- is-equal: admin-status, down
info: "Test Succeeded !! admin-status is equal to <{{post['admin-status']}}> with oper-status <{{pre['oper-status']}}>"
err: "Test Failed !! admin-status is not equal to down, it is <{{post['admin-status']}}> with oper-status <{{pre['oper-status']}}>"
- is-equal: admin-status, up
info: "Test Succeeded !! admin-status is equal to <{{post['admin-status']}}> with oper-status <{{pre['oper-status']}}>"
err: "Test Failed !! admin-status is not equal to up, it is <{{post['admin-status']}}> with oper-status <{{pre['oper-status']}}>"
- OR:
- is-equal: oper-status, down
info: "Test Succeeded !! admin-status is equal to <{{post['admin-status']}}> with oper-status <{{pre['oper-status']}}>"
err: "Test Failed !! admin-status is not equal to down, it is <{{post['admin-status']}}> with oper-status <{{pre['oper-status']}}>"
- is-equal: oper-status, up
info: "Test Succeeded !! admin-status is equal to <{{post['admin-status']}}> with oper-status <{{pre['oper-status']}}>"
err: "Test Failed !! admin-status is not equal to up, it is <{{post['admin-status']}}> with oper-status <{{pre['oper-status']}}>"
- There are total of 4 ETCs.
- As one can see, only two ETCs were run.
- In the AND subexpression, the first ETC (i.e.
- is-equal: admin-status, up
) evaluated toFalse
and hence the second ETC (i.e.- is-equal: admin-status, down
) was not evaluated as whatever may be the result, the final result ofFalse AND ?
isFalse
. - In the second OR subexpression, the first ETC evaluated to True and hence the second ETC was not evaluated as
True OR ?
isTrue
. - The final result of the the test came out to be
Passed
as(False AND ?) OR (True OR ?)
isTRUE
.
tests_include:
- test_interfaces_terse
test_interfaces_terse:
- command: show interfaces terse lo*
- item:
id: ./name
xpath: //physical-interface[normalize-space(name) = "lo0"]
tests:
- OR:
- AND:
- NOT:
- is-equal: admin-status, up
info: "Test Succeeded !! admin-status is equal to <{{post['admin-status']}}> with oper-status <{{pre['oper-status']}}>"
err: "Test Failed !! admin-status is not equal to up, it is <{{post['admin-status']}}> with oper-status <{{pre['oper-status']}}>"
- is-equal: admin-status, down
info: "Test Succeeded !! admin-status is equal to <{{post['admin-status']}}> with oper-status <{{pre['oper-status']}}>"
err: "Test Failed !! admin-status is not equal to down, it is <{{post['admin-status']}}> with oper-status <{{pre['oper-status']}}>"
- OR:
- is-equal: oper-status, down
info: "Test Succeeded !! admin-status is equal to <{{post['admin-status']}}> with oper-status <{{pre['oper-status']}}>"
err: "Test Failed !! admin-status is not equal to down, it is <{{post['admin-status']}}> with oper-status <{{pre['oper-status']}}>"
- is-equal: oper-status, up
info: "Test Succeeded !! admin-status is equal to <{{post['admin-status']}}> with oper-status <{{pre['oper-status']}}>"
err: "Test Failed !! admin-status is not equal to up, it is <{{post['admin-status']}}> with oper-status <{{pre['oper-status']}}>"
- Please not that the NOT and AND subexpression is illegal and hence we have an error of malformed subexpression.
- In such scenarios, the parser tries to recover as much as possible.
- In this case, whole of the AND subexpression is skipped and the remaining expression:
is evaluated.
tests: - OR: - OR: - is-equal: oper-status, down info: "Test Succeeded !! admin-status is equal to <{{post['admin-status']}}> with oper-status <{{pre['oper-status']}}>" err: "Test Failed !! admin-status is not equal to down, it is <{{post['admin-status']}}> with oper-status <{{pre['oper-status']}}>" - is-equal: oper-status, up info: "Test Succeeded !! admin-status is equal to <{{post['admin-status']}}> with oper-status <{{pre['oper-status']}}>" err: "Test Failed !! admin-status is not equal to up, it is <{{post['admin-status']}}> with oper-status <{{pre['oper-status']}}>"