diff --git a/README.md b/README.md index 027f202..d725826 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,7 @@ This kind of test is the ultimate set of verifications to run for a project, lon - [Syntax Reference](#syntax-reference) - [Counting Resources](#counting-resources) - [Verifying Property Values](#verifying-property-values) + - [Using Regular Expressions](#using-regular-expressions) - [Property Names](#property-names) - [Errors](#errors) - [Error Codes](#error-codes) @@ -167,6 +168,11 @@ try "at most 5 times every 30s " \ try at most 5 times every 30s \ to get svc named "'nginx'" \ and verify that "'.spec.ports[*].targetPort'" is "'8484'" + +# Regular expressions can also be used +try at most 5 times every 30s \ + to get svc named 'nginx' \ + and verify that '.spec.ports[*].targetPort' matches '[[:digit:]]+' ``` If you work with OpenShift and would prefer to use **oc** instead of **kubectl**... @@ -304,9 +310,7 @@ try "at most times every s \ For services, you may directly use the simple count assertions. This is a checking loop. -It breaks the loop if as soon as the assertion is verified. If it reaches the end of the loop -without having been verified, an error is thrown. Please, refer to [this section](#property-names) for details -about the property names. +It breaks the loop if as soon as the assertion is verified. If it reaches the end of the loop without having been verified, an error is thrown. Please, refer to [this section](#property-names) for details about the property names. ### Verifying Property Values @@ -334,6 +338,65 @@ about the property names. But unlike the assertion type to [count resources](#counting-resources), you do not verify _how many instances_ have this value. Notice however that **if it finds 0 item verifying the property, the assertion fails**. +### Using Regular Expressions + +It is also possible to verify property values against a regular expression. +This can be used, as an example, to verify values in a JSON array. + +```bash +# Verifying a property +verify "'' matches '' for named ''" + +# Finding elements with a matching property +try "at most times every s \ + to get named '' \ + and verify that '' matches ''" + +# Counting elements with a matching property +try "at most times every s \ + to find named '' \ + with '' matching ''" +``` + +The regular expression used for property values relies on +[BASH regexp](https://en.wikibooks.org/wiki/Regular_Expressions/POSIX-Extended_Regular_Expressions). +More exactly, it uses extended regular expressions (EREs). You can simulate the result of such an assertion +with `grep`, as it is the command used internally. Hence, you can use `echo your-value | grep -E your-regex` +to prepare your assertions. + +> Unlike the assertions with the verb « to be », those with the verb « to match » are case-sensitive. + +All the assertions using the verb « to be » make case-insensitive comparison. +It means writing `is 'running'` or `is 'Running'` does not change anything. +If you want case-sensitive equality, then use a regular expression, i.e. write +`matches '^Running$'`. + +If for some reasons, one needs case-insensitive matches, you can set the DETIK_CASE_INSENSITIVE_PROPERTIES +property to `true` in your test. All the retrieved values by the DETIK_CLIENT will be lower-cased. It means +you can write a pattern that only considers lower-case characters. The following sample illustrates this situation: + +```bash +# Assuming the status of the POD is "Running"... +# ... then the following assertion will fail. +verify "'status' matches 'running' for pods named 'nginx'" + +# Same for... +verify "'status' matches '^running$' for pods named 'nginx'" + +# This is because the value returned by the client starts with an upper-case letter. +# For case-insensivity operations with a regular expression, just use... +DETIK_CASE_INSENSITIVE_PROPERTIES="true" +verify "'status' matches 'running' for pods named 'nginx'" + +# The assertion will now be verified. +# Just make sure the pattern ONLY INCLUDES lower-case characters. + +# If you set DETIK_CASE_INSENSITIVE_PROPERTIES directly in a "@test" function, +# there is no need to reset it for the other tests. Its scope is limited to the +# function that defines it. It is recommended to NOT make this variable a global one. +``` + + ### Property Names In all assertions, *property-name* is one of the column names supported by K8s. @@ -428,9 +491,9 @@ DEBUG_DETIK="" ### Linting -Because Bash is not a compiled language, it is easy to make mistakes. -Even if the library was designed to be simple. This is why a linter was created, to help to -locate syntax errors when writing DETIK assertions. You can use it with BATS in your tests. +Despite the efforts to make the DETIK syntax as simple as possible, BASH remains a non-compiled +language and mistakes happen. To prevent them, a linter was created to help locating +syntax errors when writing DETIK assertions. You can use it with BATS in your tests. ```bash #!/usr/bin/env bats diff --git a/lib/detik.bash b/lib/detik.bash index d1dfbf6..8e26f47 100644 --- a/lib/detik.bash +++ b/lib/detik.bash @@ -38,8 +38,9 @@ try() { property="" expected_value="" expected_count="" + verify_strict_equality="true" - if [[ "$exp" =~ $try_regex_verify ]]; then + if [[ "$exp" =~ $try_regex_verify_is ]]; then # Extract parameters times="${BASH_REMATCH[1]}" @@ -47,9 +48,20 @@ try() { resource=$(to_lower_case "${BASH_REMATCH[3]}") name="${BASH_REMATCH[4]}" property="${BASH_REMATCH[5]}" - expected_value=$(to_lower_case "${BASH_REMATCH[6]}") + expected_value="${BASH_REMATCH[6]}" - elif [[ "$exp" =~ $try_regex_find ]]; then + elif [[ "$exp" =~ $try_regex_verify_matches ]]; then + + # Extract parameters + times="${BASH_REMATCH[1]}" + delay="${BASH_REMATCH[2]}" + resource=$(to_lower_case "${BASH_REMATCH[3]}") + name="${BASH_REMATCH[4]}" + property="${BASH_REMATCH[5]}" + expected_value="${BASH_REMATCH[6]}" + verify_strict_equality="false" + + elif [[ "$exp" =~ $try_regex_find_being ]]; then # Extract parameters times="${BASH_REMATCH[1]}" @@ -58,7 +70,19 @@ try() { resource=$(to_lower_case "${BASH_REMATCH[4]}") name="${BASH_REMATCH[5]}" property="${BASH_REMATCH[6]}" - expected_value=$(to_lower_case "${BASH_REMATCH[7]}") + expected_value="${BASH_REMATCH[7]}" + + elif [[ "$exp" =~ $try_regex_find_matching ]]; then + + # Extract parameters + times="${BASH_REMATCH[1]}" + delay="${BASH_REMATCH[2]}" + expected_count="${BASH_REMATCH[3]}" + resource=$(to_lower_case "${BASH_REMATCH[4]}") + name="${BASH_REMATCH[5]}" + property="${BASH_REMATCH[6]}" + expected_value="${BASH_REMATCH[7]}" + verify_strict_equality="false" fi # Do we have something? @@ -73,7 +97,7 @@ try() { for ((i=1; i<=times; i++)); do # Verify the value - verify_value "$property" "$expected_value" "$resource" "$name" "$expected_count" && code=$? || code=$? + verify_value "$verify_strict_equality" "$property" "$expected_value" "$resource" "$name" "$expected_count" && code=$? || code=$? # Break the loop prematurely? if [[ "$code" == "0" ]]; then @@ -158,7 +182,20 @@ verify() { name="${BASH_REMATCH[4]}" echo "Valid expression. Verification in progress..." - verify_value "$property" "$expected_value" "$resource" "$name" + verify_value true "$property" "$expected_value" "$resource" "$name" + + if [[ "$?" != "0" ]]; then + return 3 + fi + + elif [[ "$exp" =~ $verify_regex_property_matches ]]; then + property="${BASH_REMATCH[1]}" + expected_value="${BASH_REMATCH[2]}" + resource=$(to_lower_case "${BASH_REMATCH[3]}") + name="${BASH_REMATCH[4]}" + + echo "Valid expression. Verification in progress..." + verify_value false "$property" "$expected_value" "$resource" "$name" if [[ "$?" != "0" ]]; then return 3 @@ -172,6 +209,7 @@ verify() { # Verifies the value of a column for a set of elements. +# @param {boolean} true to verify equality, false to match a regex # @param {string} A K8s column or one of the supported aliases. # @param {string} The expected value. # @param {string} The resouce type (e.g. pod). @@ -183,11 +221,12 @@ verify() { verify_value() { # Make the parameters readable - property="$1" - expected_value=$(to_lower_case "$2") - resource="$3" - name="$4" - expected_count="$5" + verify_strict_equality=$(to_lower_case "$1") + property="$2" + expected_value="$3" + resource="$4" + name="$5" + expected_count="$6" # List the items and remove the first line (the one that contains the column names) query=$(build_k8s_request "$property") @@ -224,22 +263,47 @@ verify_value() { for line in $result; do # Keep the second column (property to verify) - # and put it in lower case - value=$(to_lower_case "$line" | awk '{ print $2 }') + value=$(echo "$line" | awk '{ print $2 }') element=$(echo "$line" | awk '{ print $1 }') - if [[ "$value" != "$expected_value" ]]; then - echo "Current value for $element is $value..." - invalid=$((invalid + 1)) + + # Compare with an exact value (case insensitive) + if [[ "$verify_strict_equality" == "true" ]]; then + value=$(to_lower_case "$value") + expected_value=$(to_lower_case "$expected_value") + if [[ "$value" != "$expected_value" ]]; then + echo "Current value for $element is $value..." + invalid=$((invalid + 1)) + else + echo "$element has the right value ($value)." + valid=$((valid + 1)) + fi + + # Verify a regex (we preserve the case) else - echo "$element has the right value ($value)." - valid=$((valid + 1)) + # We do not want another syntax for case-insensitivity + if [ "$DETIK_REGEX_CASE_INSENSITIVE_PROPERTIES" = "true" ]; then + value=$(to_lower_case "$value") + fi + + reg=$(echo "$value" | grep -E "$expected_value") + if [[ "$?" -ne 0 ]]; then + echo "Current value for $element is $value..." + invalid=$((invalid + 1)) + else + echo "$element matches the regular expression (found $reg)." + valid=$((valid + 1)) + fi fi done # Do we have the right number of elements? if [[ "$expected_count" != "" ]]; then if [[ "$valid" != "$expected_count" ]]; then - echo "Expected $expected_count $resource named $name to have this value ($expected_value). Found $valid." + if [[ "$verify_strict_equality" == "true" ]]; then + echo "Expected $expected_count $resource named $name to have this value ($expected_value). Found $valid." + else + echo "Expected $expected_count $resource named $name to match this pattern ($expected_value). Found $valid." + fi invalid=101 else invalid=0 @@ -279,7 +343,7 @@ build_k8s_client_with_options() { client_with_options="$DETIK_CLIENT_NAME" if [[ -n "$DETIK_CLIENT_NAMESPACE" ]]; then - # eval does not like '-n' + # eval does not "like" the '-n' syntax client_with_options="$DETIK_CLIENT_NAME --namespace=$DETIK_CLIENT_NAMESPACE" fi diff --git a/lib/linter.bash b/lib/linter.bash index c9dc6ba..c51b62d 100644 --- a/lib/linter.bash +++ b/lib/linter.bash @@ -132,15 +132,24 @@ check_line() { part=$(clean_regex_part "${BASH_REMATCH[2]}") context="$context\nRegex part: $part" - verify_against_pattern "$part" "$try_regex_verify" - p_verify="$?" + verify_against_pattern "$part" "$try_regex_verify_is" + p_verify_is="$?" - verify_against_pattern "$part" "$try_regex_find" - p_find="$?" + verify_against_pattern "$part" "$try_regex_verify_matches" + p_verify_matches="$?" + + verify_against_pattern "$part" "$try_regex_find_being" + p_find_being="$?" + + verify_against_pattern "$part" "$try_regex_find_matching" + p_find_matching="$?" # detik_debug "p_verify=$p_verify, p_find=$p_find, part=$part" - if [[ "$p_verify" != "0" ]] && [[ "$p_find" != "0" ]]; then - handle_error "Invalid TRY statement at line $line_number." "$context" + if [[ "$p_verify_is" != "0" ]] && \ + [[ "$p_verify_matches" != "0" ]] && \ + [[ "$p_find_being" != "0" ]] && \ + [[ "$p_find_matching" != "0" ]]; then + handle_error "Invalid TRY statement at line $line_number." "$context" fi # We have "verify" or "run verify" followed by something @@ -159,9 +168,15 @@ check_line() { verify_against_pattern "$part" "$verify_regex_property_is" p_prop="$?" + verify_against_pattern "$part" "$verify_regex_property_matches" + p_matches="$?" + # detik_debug "p_is=$p_is, p_are=$p_are, p_prop=$p_prop, part=$part" - if [[ "$p_is" != "0" ]] && [[ "$p_are" != "0" ]] && [[ "$p_prop" != "0" ]] ; then - handle_error "Invalid VERIFY statement at line $line_number." "$context" + if [[ "$p_is" != "0" ]] && \ + [[ "$p_are" != "0" ]] && \ + [[ "$p_prop" != "0" ]] && \ + [[ "$p_matches" != "0" ]] ; then + handle_error "Invalid VERIFY statement at line $line_number." "$context" fi fi } diff --git a/lib/utils.bash b/lib/utils.bash index 8cfb91e..7af2738 100644 --- a/lib/utils.bash +++ b/lib/utils.bash @@ -2,14 +2,16 @@ # The regex for the "try" key word -try_regex_verify="^at +most +([0-9]+) +times +every +([0-9]+)s +to +get +([a-z]+) +named +'([^']+)' +and +verify +that +'([^']+)' +is +'([^']+)'$" -try_regex_find="^at +most +([0-9]+) +times +every +([0-9]+)s +to +find +([0-9]+) +([a-z]+) +named +'([^']+)' +with +'([^']+)' +being +'([^']+)'$" +try_regex_verify_is="^at +most +([0-9]+) +times +every +([0-9]+)s +to +get +([a-z]+) +named +'([^']+)' +and +verify +that +'([^']+)' +is +'([^']+)'$" +try_regex_verify_matches="^at +most +([0-9]+) +times +every +([0-9]+)s +to +get +([a-z]+) +named +'([^']+)' +and +verify +that +'([^']+)' +matches +'([^']+)'$" +try_regex_find_being="^at +most +([0-9]+) +times +every +([0-9]+)s +to +find +([0-9]+) +([a-z]+) +named +'([^']+)' +with +'([^']+)' +being +'([^']+)'$" +try_regex_find_matching="^at +most +([0-9]+) +times +every +([0-9]+)s +to +find +([0-9]+) +([a-z]+) +named +'([^']+)' +with +'([^']+)' +matching +'([^']+)'$" # The regex for the "verify" key word verify_regex_count_is="^there +is +(0|1) +([a-z]+) +named +'([^']+)'$" verify_regex_count_are="^there +are +([0-9]+) +([a-z]+) +named +'([^']+)'$" verify_regex_property_is="^'([^']+)' +is +'([^']+)' +for +([a-z]+) +named +'([^']+)'$" - +verify_regex_property_matches="^'([^']+)' +matches +'([^']+)' +for +([a-z]+) +named +'([^']+)'$" # Prints a string in lower case. @@ -73,3 +75,12 @@ reset_detik_debug() { reset_debug fi } + + +# Dumps the argument and return the previous error code. +# @return the previous error code +ddump() { + res="$?" + echo "$1" + return $res +} diff --git a/tests/resources/with_lint_errors_try_to_find.no.run.txt b/tests/resources/with_lint_errors_try_to_find.no.run.txt index f626322..550a650 100644 --- a/tests/resources/with_lint_errors_try_to_find.no.run.txt +++ b/tests/resources/with_lint_errors_try_to_find.no.run.txt @@ -20,7 +20,7 @@ try "at most 5 times every 5s to find 2 pods named 'nginx' with '.status.phase' # Error: missing quote before nginx try "at most 5 times eVery 5s to find 2 pods named nginx' with 'status' being 'RUNNING'" -# Error: the "most" keyword being missing +# Error: the "every" keyword being missing try "at most 5 times VERY 5hours to find 2 pods named 'nginx' with 'status' being 'RUNNING'" # Error: missing time unit @@ -45,3 +45,34 @@ try " at most 5 times every 5s to find 2 pods " try at most 11 times every 5s to find 2 pods \ named "'nginx'" \ with "'status'" being "'running'" + +# Property patterns +# Error: missing double quote at the end +try "at most 5 times every 5s to find 2 pods named 'nginx' with 'status' matching '^running$' +try "at most 5 times every 5s to find 2 pods named 'nginx' with '.status.phase' matching '^running$'" + +# Error: missing quote before nginx +try "at most 5 times eVery 5s to find 2 pods named nginx' with 'status' matching 'RUN.+'" + +# Error: the "every" keyword matching missing +try "at most 5 times VERY 5hours to find 2 pods named 'nginx' with 'status' matching 'R.NN.NG'" + +# Error: missing time unit +try "at most 5 times every 5 to find 2 pods named 'nginx' with 'status' matching running" + +try "at most 1 times every 1s to find 2 pods named 'nginx' with 'status' matching '^initializing'" +try "at most 2 times every 1s to find 2 pods named 'nginx' with 'status' matching '^initializing'" +try "at most 3 times every 1s to find 2 pods named 'nginx' with 'status' matching '^initializing'" + +try "at most 1 times every 1s to find 2 pods named 'nginx-something' with 'status' matching '^running$'" +try "at most 1 times every 1s to find 2 pods named 'ngin.*' with 'status' matching '^running$'" +try "at most 1 times every 1s to find 2 pods named 'ngin.+x' with 'status' matching '^running$'" + +# Error: missing backslash at the end of the line +try " at most 5 times every 5s to find 2 pods " + " named 'nginx' " \ + " with 'status' matching '[[:alnum:]]+' " + +try at most 11 times every 5s to find 2 pods \ + named "'nginx'" \ + with "'status'" matching "'[[:alnum:]]+'" diff --git a/tests/resources/with_lint_errors_try_to_find.run.txt b/tests/resources/with_lint_errors_try_to_find.run.txt index 282afea..2fd7f58 100644 --- a/tests/resources/with_lint_errors_try_to_find.run.txt +++ b/tests/resources/with_lint_errors_try_to_find.run.txt @@ -20,7 +20,7 @@ run try "at most 5 times every 5s to find 2 pods named 'nginx' with '.status.pha # Error: missing quote before nginx run try "at most 5 times eVery 5s to find 2 pods named nginx' with 'status' being 'RUNNING'" -# Error: the "most" keyword being missing +# Error: the "every" keyword being missing run try "at most 5 times VERY 5hours to find 2 pods named 'nginx' with 'status' being 'RUNNING'" # Error: missing time unit @@ -45,3 +45,34 @@ run try " at most 5 times every 5s to find 2 pods " run try at most 11 times every 5s to find 2 pods \ named "'nginx'" \ with "'status'" being "'running'" + +# Property patterns +# Error: missing double quote at the end +run try "at most 5 times every 5s to find 2 pods named 'nginx' with 'status' matching '^running$' +run try "at most 5 times every 5s to find 2 pods named 'nginx' with '.status.phase' matching '^running$'" + +# Error: missing quote before nginx +run try "at most 5 times eVery 5s to find 2 pods named nginx' with 'status' matching 'RUN.+'" + +# Error: the "every" keyword matching missing +run try "at most 5 times VERY 5hours to find 2 pods named 'nginx' with 'status' matching 'R.NN.NG'" + +# Error: missing time unit +run try "at most 5 times every 5 to find 2 pods named 'nginx' with 'status' matching running" + +run try "at most 1 times every 1s to find 2 pods named 'nginx' with 'status' matching '^initializing'" +run try "at most 2 times every 1s to find 2 pods named 'nginx' with 'status' matching '^initializing'" +run try "at most 3 times every 1s to find 2 pods named 'nginx' with 'status' matching '^initializing'" + +run try "at most 1 times every 1s to find 2 pods named 'nginx-something' with 'status' matching '^running$'" +run try "at most 1 times every 1s to find 2 pods named 'ngin.*' with 'status' matching '^running$'" +run try "at most 1 times every 1s to find 2 pods named 'ngin.+x' with 'status' matching '^running$'" + +# Error: missing backslash at the end of the line +run try " at most 5 times every 5s to find 2 pods " + " named 'nginx' " \ + " with 'status' matching '[[:alnum:]]+' " + +run try at most 11 times every 5s to find 2 pods \ + named "'nginx'" \ + with "'status'" matching "'[[:alnum:]]+'" diff --git a/tests/resources/with_lint_errors_try_to_verify.no.run.txt b/tests/resources/with_lint_errors_try_to_verify.no.run.txt index d8ebb81..bb6455f 100644 --- a/tests/resources/with_lint_errors_try_to_verify.no.run.txt +++ b/tests/resources/with_lint_errors_try_to_verify.no.run.txt @@ -20,7 +20,7 @@ try "at most 5 times every 5s to get pods named 'nginx' and verify that '.status # Error: missing quote before nginx try "at most 5 times eVery 5s to GET pods named nginx' and verify that 'status' is 'RUNNING'" -# Error: the "most" keyword is missing +# Error: the "every" keyword is missing try "at most 5 times VERY 5hours to GET pods named 'nginx' and verify that 'status' is 'RUNNING'" # Error: missing time unit @@ -45,3 +45,34 @@ try " at most 5 times every 5s to get pods " try at most 11 times every 5s to get pods \ named "'nginx'" and \ verify that "'status'" is "'running'" + +# Property patterns +# Error: missing double quote at the end +try "at most 5 times every 5s to get pods named 'nginx' and verify that 'status' matches '^running$' +try "at most 5 times every 5s to get pods named 'nginx' and verify that '.status.phase' matches 'run.*'" + +# Error: missing quote before nginx +try "at most 5 times eVery 5s to GET pods named nginx' and verify that 'status' matches 'R.NN.NG'" + +# Error: the "every" keyword is missing +try "at most 5 times VERY 5hours to GET pods named 'nginx' and verify that 'status' matches 'RUNNING'" + +# Error: missing time unit +try "at most 5 times every 5 to get pods named 'nginx' and verify that 'status' matches running" + +try "at most 1 times every 1s to get pods named 'nginx' and verify that 'status' matches '^initializing'" +try "at most 2 times every 1s to get pods named 'nginx' and verify that 'status' matches '^initializing'" +try "at most 3 times every 1s to get pods named 'nginx' and verify that 'status' matches '^initializing'" + +try "at most 1 times every 1s to get pods named 'nginx-something' and verify that 'status' matches 'running'" +try "at most 1 times every 1s to get pods named 'ngin.*' and verify that 'status' matches 'running'" +try "at most 1 times every 1s to get pods named 'ngin.+x' and verify that 'status' matches 'running'" + +# Error: missing backslash at the end of the line +try " at most 5 times every 5s to get pods " + " named 'nginx' and " \ + " verify that 'status' matches '[[:alnum:]]+' " + +try at most 11 times every 5s to get pods \ + named "'nginx'" and \ + verify that "'status'" matches "'[[:alnum:]]+'" diff --git a/tests/resources/with_lint_errors_try_to_verify.run.txt b/tests/resources/with_lint_errors_try_to_verify.run.txt index fa2ef30..8ab48a0 100644 --- a/tests/resources/with_lint_errors_try_to_verify.run.txt +++ b/tests/resources/with_lint_errors_try_to_verify.run.txt @@ -20,7 +20,7 @@ run try "at most 5 times every 5s to get pods named 'nginx' and verify that '.st # Error: missing quote before nginx run try "at most 5 times eVery 5s to GET pods named nginx' and verify that 'status' is 'RUNNING'" -# Error: the "most" keyword is missing +# Error: the "every" keyword is missing run try "at most 5 times VERY 5hours to GET pods named 'nginx' and verify that 'status' is 'RUNNING'" # Error: missing time unit @@ -45,3 +45,34 @@ run try " at most 5 times every 5s to get pods " run try at most 11 times every 5s to get pods \ named "'nginx'" and \ verify that "'status'" is "'running'" + +# Property patterns +# Error: missing double quote at the end +run try "at most 5 times every 5s to get pods named 'nginx' and verify that 'status' matches '^running$' +run try "at most 5 times every 5s to get pods named 'nginx' and verify that '.status.phase' matches 'run.*'" + +# Error: missing quote before nginx +run try "at most 5 times eVery 5s to GET pods named nginx' and verify that 'status' matches 'R.NN.NG'" + +# Error: the "every" keyword is missing +run try "at most 5 times VERY 5hours to GET pods named 'nginx' and verify that 'status' matches 'RUNNING'" + +# Error: missing time unit +run try "at most 5 times every 5 to get pods named 'nginx' and verify that 'status' matches running" + +run try "at most 1 times every 1s to get pods named 'nginx' and verify that 'status' matches '^initializing'" +run try "at most 2 times every 1s to get pods named 'nginx' and verify that 'status' matches '^initializing'" +run try "at most 3 times every 1s to get pods named 'nginx' and verify that 'status' matches '^initializing'" + +run try "at most 1 times every 1s to get pods named 'nginx-something' and verify that 'status' matches 'running'" +run try "at most 1 times every 1s to get pods named 'ngin.*' and verify that 'status' matches 'running'" +run try "at most 1 times every 1s to get pods named 'ngin.+x' and verify that 'status' matches 'running'" + +# Error: missing backslash at the end of the line +run try " at most 5 times every 5s to get pods " + " named 'nginx' and " \ + " verify that 'status' matches '[[:alnum:]]+' " + +run try at most 11 times every 5s to get pods \ + named "'nginx'" and \ + verify that "'status'" matches "'[[:alnum:]]+'" diff --git a/tests/resources/with_lint_errors_verify.no.run.txt b/tests/resources/with_lint_errors_verify.no.run.txt index 6f849ee..0c1a910 100644 --- a/tests/resources/with_lint_errors_verify.no.run.txt +++ b/tests/resources/with_lint_errors_verify.no.run.txt @@ -64,3 +64,27 @@ verify " 'status' is 'running' for " verify "'status'" is "'running'" for \ pods named "'nginx'" + +# Property patterns +verify "'status' matches 'running' for pods named 'nginx'" +verify "'.status.phase' matches 'running' for pods named 'nginx'" +verify "'status' matches 'RUNNING' For pods named 'nginx'" + +# Error: missing double quote at the end +verify "'status' matches 'running' for all the pods named 'nginx' + +# Error: missing single quote at the end +verify "status matches 'running' for pods named nginx'" +verify "'status' matches 'initializing' for pods named 'nginx'" +verify "'status' matches 'running' for pods named 'nginx-something'" + +# Error: missing single quote in the middle +verify "'status' matches 'running for pods named 'ngin.*'" +verify "'status' matches 'running' for pods named 'ngin.+x'" + +# Error: missing backslash at the end +verify " 'status' matches 'running' for " + " pods named 'nginx' " + +verify "'status'" matches "'running'" for \ + pods named "'nginx'" diff --git a/tests/resources/with_lint_errors_verify.run.txt b/tests/resources/with_lint_errors_verify.run.txt index 2e6003a..888a7f4 100644 --- a/tests/resources/with_lint_errors_verify.run.txt +++ b/tests/resources/with_lint_errors_verify.run.txt @@ -64,3 +64,27 @@ run verify " 'status' is 'running' for " run verify "'status'" is "'running'" for \ pods named "'nginx'" + +# Property patterns +run verify "'status' matches 'running' for pods named 'nginx'" +run verify "'.status.phase' matches 'running' for pods named 'nginx'" +run verify "'status' matches 'RUNNING' For pods named 'nginx'" + +# Error: missing double quote at the end +run verify "'status' matches 'running' for all the pods named 'nginx' + +# Error: missing single quote at the end +run verify "status matches 'running' for pods named nginx'" +run verify "'status' matches 'initializing' for pods named 'nginx'" +run verify "'status' matches 'running' for pods named 'nginx-something'" + +# Error: missing single quote in the middle +run verify "'status' matches 'running for pods named 'ngin.*'" +run verify "'status' matches 'running' for pods named 'ngin.+x'" + +# Error: missing backslash at the end +run verify " 'status' matches 'running' for " + " pods named 'nginx' " + +run verify "'status'" matches "'running'" for \ + pods named "'nginx'" diff --git a/tests/resources/without_lint_errors.no.run.txt b/tests/resources/without_lint_errors.no.run.txt index a999d20..bed0d46 100644 --- a/tests/resources/without_lint_errors.no.run.txt +++ b/tests/resources/without_lint_errors.no.run.txt @@ -55,6 +55,31 @@ verify "'.spec.ports[*].targetPort' is '8484' for services named 'nginx'" verify "'.spec.ports[*].targetPort'" is "'8484'" for services named "'nginx'" +######################################### +# Verifying properties (patterns) +######################################### + +# Basic example +verify "'status' matches '^running$' for pods named 'nginx'" + verify "'status' matches '^running$' for pods named 'nginx'" + +# The same thing (it is case insensitive) +verify "'status' matches '^RUN.+' for pods naMed 'nginx'" + +# Use short names for resources ('po' instead of 'pods') +# See https://kubernetes.io/docs/reference/kubectl/overview/#resource-types +verify "'status' matches '^r.*g' for po named 'nginx'" + +# Use a regular expression for the name +verify "'status' matches 'r.nn.ng' for pods named 'nginx.*'" + +# You can also use column names +# Use kubectl get -o custom-columns=ALL:* to find column names. +verify "'.status.phase' matches 'running' for pods named 'nginx'" +verify "'.spec.ports[*].targetPort' matches '8484' for services named 'nginx'" +verify "'.spec.ports[*].targetPort'" matches "'[[:digit:]]+'" for services named "'nginx'" + + ######################################### # Verifying properties (with retries) ######################################### @@ -78,6 +103,29 @@ try "at most 2 times every 30s to get po named 'nginx' and verify that '.status. try "at most 2 times every 30s to get svc named 'nginx' and verify that '.spec.ports[*].targetPort' is '8484'" +######################################### +# Verifying properties (with retries and patterns) +######################################### + +# Basic example +try "at most 5 times every 5s to get pods named 'nginx' and verify that 'status' matches '^running$'" + +# The same thing (it is case insensitive) +try "at most 5 times every 15s to GET pods named 'nginx' and verify that 'status' matches '^RUNNING'" + +# Use short names for resources ('po' instead of 'pods') +# See https://kubernetes.io/docs/reference/kubectl/overview/#resource-types +try "at most 5 times every 5s to get po named 'nginx' and verify that 'status' matches 'r.nn.ng'" + +# Use a regular expression for the name +try "at most 2 times every 30s to get po named '^ng.*nx' and verify that 'status' matches 'run.+g'" + +# You can also use column names +# Use kubectl get -o custom-columns=ALL:* to find column names. +try "at most 2 times every 30s to get po named 'nginx' and verify that '.status.phase' matches 'running'" +try "at most 2 times every 30s to get svc named 'nginx' and verify that '.spec.ports[*].targetPort' matches '[[:digit:]]+'" + + ######################################### # Counting objects (with retries and properties) ######################################### @@ -101,6 +149,29 @@ try "at most 2 times every 30s to find 4 po named 'nginx' with '.status.phase' b try "at most 2 times every 30s to find 1 svc named 'nginx' with '.spec.ports[*].targetPort' being '8484'" +######################################### +# Counting objects (with retries, patterns and properties) +######################################### + +# Basic example +try "at most 5 times every 5s to find 2 pods named 'nginx' with 'status' matching '^running$'" + +# The same thing (it is case insensitive) +try "at most 5 times every 15s to FIND 2 pods named 'nginx' with 'status' matching 'RUN.+'" + +# Use short names for resources ('po' instead of 'pods') +# See https://kubernetes.io/docs/reference/kubectl/overview/#resource-types +try "at most 5 times every 5s to find 0 po named 'nginx' with 'status' matching 'r.nn.ng'" + +# Use a regular expression for the name +try "at most 2 times every 30s to find 1 po named '^ng.*nx' with 'status' matching '^r.*g'" + +# You can also use column names +# Use kubectl get -o custom-columns=ALL:* to find column names. +try "at most 2 times every 30s to find 4 po named 'nginx' with '.status.phase' matching '^running$'" +try "at most 2 times every 30s to find 1 svc named 'nginx' with '.spec.ports[*].targetPort' matching '[[:digit:]]+'" + + ######################################### # Formatting ######################################### @@ -115,7 +186,15 @@ try "at most 2 times every 30s "\ try at most 2 times every 30s \ to get svc named "'nginx'" and \ verify that "'.spec.ports[*].targetPort'" is "'8484'" - + +try at most 2 times every 30s \ + to get svc named "'nginx'" and \ + verify that "'.spec.ports[*].targetPort'" matches "'[[:digit:]]+'" + try "at most 2 times every 30s "\ "to find 1 svc named 'nginx' "\ "with '.spec.ports[*].targetPort' being '8484'" + +try "at most 2 times every 30s "\ + "to find 1 svc named 'nginx' "\ + "with '.spec.ports[*].targetPort' matching '[[:digit:]]+'" diff --git a/tests/resources/without_lint_errors.run.txt b/tests/resources/without_lint_errors.run.txt index 248dc28..6e45b63 100644 --- a/tests/resources/without_lint_errors.run.txt +++ b/tests/resources/without_lint_errors.run.txt @@ -55,6 +55,31 @@ run verify "'.spec.ports[*].targetPort' is '8484' for services named 'nginx'" run verify "'.spec.ports[*].targetPort'" is "'8484'" for services named "'nginx'" +######################################### +# Verifying properties (patterns) +######################################### + +# Basic example +run verify "'status' matches '^running$' for pods named 'nginx'" + run verify "'status' matches '^running$' for pods named 'nginx'" + +# The same thing (it is case insensitive) +run verify "'status' matches '^RUN.+' for pods naMed 'nginx'" + +# Use short names for resources ('po' instead of 'pods') +# See https://kubernetes.io/docs/reference/kubectl/overview/#resource-types +run verify "'status' matches '^r.*g' for po named 'nginx'" + +# Use a regular expression for the name +run verify "'status' matches 'r.nn.ng' for pods named 'nginx.*'" + +# You can also use column names +# Use kubectl get -o custom-columns=ALL:* to find column names. +run verify "'.status.phase' matches 'running' for pods named 'nginx'" +run verify "'.spec.ports[*].targetPort' matches '8484' for services named 'nginx'" +run verify "'.spec.ports[*].targetPort'" matches "'[[:digit:]]+'" for services named "'nginx'" + + ######################################### # Verifying properties (with retries) ######################################### @@ -78,6 +103,29 @@ run try "at most 2 times every 30s to get po named 'nginx' and verify that '.sta run try "at most 2 times every 30s to get svc named 'nginx' and verify that '.spec.ports[*].targetPort' is '8484'" +######################################### +# Verifying properties (with retries and patterns) +######################################### + +# Basic example +run try "at most 5 times every 5s to get pods named 'nginx' and verify that 'status' matches '^running$'" + +# The same thing (it is case insensitive) +run try "at most 5 times every 15s to GET pods named 'nginx' and verify that 'status' matches '^RUNNING'" + +# Use short names for resources ('po' instead of 'pods') +# See https://kubernetes.io/docs/reference/kubectl/overview/#resource-types +run try "at most 5 times every 5s to get po named 'nginx' and verify that 'status' matches 'r.nn.ng'" + +# Use a regular expression for the name +run try "at most 2 times every 30s to get po named '^ng.*nx' and verify that 'status' matches 'run.+g'" + +# You can also use column names +# Use kubectl get -o custom-columns=ALL:* to find column names. +run try "at most 2 times every 30s to get po named 'nginx' and verify that '.status.phase' matches 'running'" +run try "at most 2 times every 30s to get svc named 'nginx' and verify that '.spec.ports[*].targetPort' matches '[[:digit:]]+'" + + ######################################### # Counting objects (with retries and properties) ######################################### @@ -101,6 +149,29 @@ run try "at most 2 times every 30s to find 4 po named 'nginx' with '.status.phas run try "at most 2 times every 30s to find 1 svc named 'nginx' with '.spec.ports[*].targetPort' being '8484'" +######################################### +# Counting objects (with retries, patterns and properties) +######################################### + +# Basic example +run try "at most 5 times every 5s to find 2 pods named 'nginx' with 'status' matching '^running$'" + +# The same thing (it is case insensitive) +run try "at most 5 times every 15s to FIND 2 pods named 'nginx' with 'status' matching 'RUN.+'" + +# Use short names for resources ('po' instead of 'pods') +# See https://kubernetes.io/docs/reference/kubectl/overview/#resource-types +run try "at most 5 times every 5s to find 0 po named 'nginx' with 'status' matching 'r.nn.ng'" + +# Use a regular expression for the name +run try "at most 2 times every 30s to find 1 po named '^ng.*nx' with 'status' matching '^r.*g'" + +# You can also use column names +# Use kubectl get -o custom-columns=ALL:* to find column names. +run try "at most 2 times every 30s to find 4 po named 'nginx' with '.status.phase' matching '^running$'" +run try "at most 2 times every 30s to find 1 svc named 'nginx' with '.spec.ports[*].targetPort' matching '[[:digit:]]+'" + + ######################################### # Formatting ######################################### @@ -115,7 +186,15 @@ run try "at most 2 times every 30s "\ run try at most 2 times every 30s \ to get svc named "'nginx'" and \ verify that "'.spec.ports[*].targetPort'" is "'8484'" - + +run try at most 2 times every 30s \ + to get svc named "'nginx'" and \ + verify that "'.spec.ports[*].targetPort'" matches "'[[:digit:]]+'" + run try "at most 2 times every 30s "\ "to find 1 svc named 'nginx' "\ "with '.spec.ports[*].targetPort' being '8484'" + +run try "at most 2 times every 30s "\ + "to find 1 svc named 'nginx' "\ + "with '.spec.ports[*].targetPort' matching '[[:digit:]]+'" diff --git a/tests/test.detik.try.to.find.bats b/tests/test.detik.try.to.find.being.bats similarity index 100% rename from tests/test.detik.try.to.find.bats rename to tests/test.detik.try.to.find.being.bats diff --git a/tests/test.detik.try.to.find.matching.bats b/tests/test.detik.try.to.find.matching.bats new file mode 100755 index 0000000..c73e1ae --- /dev/null +++ b/tests/test.detik.try.to.find.matching.bats @@ -0,0 +1,416 @@ +#!/usr/bin/env bats + +load "../lib/detik" + +DETIK_CLIENT_NAME="mytest" +DETIK_CLIENT_NAMESPACE="" + +mytest() { + # The namespace should not appear (it is set in 1st position) + [[ "$1" != "--namespace=test_ns" ]] || return 1 + + # Return the result + echo -e "NAME PROP\nnginx-deployment-75675f5897-6dg9r Running\nnginx-deployment-75675f5897-gstkw Running" +} + +mytest_with_namespace() { + # A namespace is expected as the first argument + [[ "$1" == "--namespace=test_ns" ]] || return 1 + + # Return the result + echo -e "NAME PROP\nnginx-deployment-75675f5897-6dg9r Running\nnginx-deployment-75675f5897-gstkw Running" +} + + +@test "trying to find 1 POD with the lower-case syntax and a simple match" { + run try "at most 1 times every 5s to find 1 pod named 'nginx' with 'status' matching 'Running'" + [ "$status" -eq 3 ] + [ ${#lines[@]} -eq 4 ] + [ "${lines[0]}" = "Valid expression. Verification in progress..." ] + [ "${lines[1]}" = "nginx-deployment-75675f5897-6dg9r matches the regular expression (found Running)." ] + [ "${lines[2]}" = "nginx-deployment-75675f5897-gstkw matches the regular expression (found Running)." ] + [ "${lines[3]}" = "Expected 1 pod named nginx to match this pattern (Running). Found 2." ] +} + + +@test "trying to find 1 POD with the exact syntax and a simple match with different case" { + run try "at most 1 times every 2s to find 1 pod named 'nginx' with 'status' matching 'running'" + [ "$status" -eq 3 ] + [ ${#lines[@]} -eq 4 ] + [ "${lines[0]}" = "Valid expression. Verification in progress..." ] + [ "${lines[1]}" = "Current value for nginx-deployment-75675f5897-6dg9r is Running..." ] + [ "${lines[2]}" = "Current value for nginx-deployment-75675f5897-gstkw is Running..." ] + [ "${lines[3]}" = "Expected 1 pod named nginx to match this pattern (running). Found 0." ] +} + + +@test "trying to find 1 POD with the lower-case syntax and a simple match with case-insensitivy" { + DETIK_REGEX_CASE_INSENSITIVE_PROPERTIES="true" + run try "at most 1 times every 5s to find 1 pod named 'nginx' with 'status' matching 'running'" + [ "$status" -eq 3 ] + [ ${#lines[@]} -eq 4 ] + [ "${lines[0]}" = "Valid expression. Verification in progress..." ] + [ "${lines[1]}" = "nginx-deployment-75675f5897-6dg9r matches the regular expression (found running)." ] + [ "${lines[2]}" = "nginx-deployment-75675f5897-gstkw matches the regular expression (found running)." ] + [ "${lines[3]}" = "Expected 1 pod named nginx to match this pattern (running). Found 2." ] +} + + +@test "trying to find 1 POD with the exact syntax and a simple match with an upper-case pattern" { + run try "at most 1 times every 2s to find 1 pod named 'nginx' with 'status' matching '[A-Z]+$'" + [ "$status" -eq 3 ] + [ ${#lines[@]} -eq 4 ] + [ "${lines[0]}" = "Valid expression. Verification in progress..." ] + [ "${lines[1]}" = "Current value for nginx-deployment-75675f5897-6dg9r is Running..." ] + [ "${lines[2]}" = "Current value for nginx-deployment-75675f5897-gstkw is Running..." ] + [ "${lines[3]}" = "Expected 1 pod named nginx to match this pattern ([A-Z]+$). Found 0." ] +} + + +@test "trying to find 1 POD with the exact syntax and a simple match with a lower-case pattern" { + run try "at most 1 times every 2s to find 1 pod named 'nginx' with 'status' matching '[A-Z][a-z]+'" + [ "$status" -eq 3 ] + [ ${#lines[@]} -eq 4 ] + [ "${lines[0]}" = "Valid expression. Verification in progress..." ] + [ "${lines[1]}" = "nginx-deployment-75675f5897-6dg9r matches the regular expression (found Running)." ] + [ "${lines[2]}" = "nginx-deployment-75675f5897-gstkw matches the regular expression (found Running)." ] + [ "${lines[3]}" = "Expected 1 pod named nginx to match this pattern ([A-Z][a-z]+). Found 2." ] +} + + +@test "trying to find 1 POD with the lower-case syntax and an exact match" { + run try "at most 1 times every 2s to find 1 pod named 'nginx' with 'status' matching '^Running$'" + [ "$status" -eq 3 ] + [ ${#lines[@]} -eq 4 ] + [ "${lines[0]}" = "Valid expression. Verification in progress..." ] + [ "${lines[1]}" = "nginx-deployment-75675f5897-6dg9r matches the regular expression (found Running)." ] + [ "${lines[2]}" = "nginx-deployment-75675f5897-gstkw matches the regular expression (found Running)." ] + [ "${lines[3]}" = "Expected 1 pod named nginx to match this pattern (^Running$). Found 2." ] +} + + +@test "trying to find 2 PODs with the lower-case syntax and a partial match" { + run try "at most 1 times every 5s to find 2 pods named 'nginx' with 'status' matching 'Run.*'" + [ "$status" -eq 0 ] + [ ${#lines[@]} -eq 3 ] + [ "${lines[0]}" = "Valid expression. Verification in progress..." ] + [ "${lines[1]}" = "nginx-deployment-75675f5897-6dg9r matches the regular expression (found Running)." ] + [ "${lines[2]}" = "nginx-deployment-75675f5897-gstkw matches the regular expression (found Running)." ] +} + + +@test "trying to find 2 PODs with the lower-case syntax (with a partial match and a different K8s namespace)" { + DETIK_CLIENT_NAME="mytest_with_namespace" + DETIK_CLIENT_NAMESPACE="test_ns" + DEBUG_DETIK="true" + + run try "at most 1 times every 5s to find 2 pods named 'nginx' with 'status' matching '.*ing'" + [ "$status" -eq 0 ] + [ ${#lines[@]} -eq 3 ] + [ "${lines[0]}" = "Valid expression. Verification in progress..." ] + [ "${lines[1]}" = "nginx-deployment-75675f5897-6dg9r matches the regular expression (found Running)." ] + [ "${lines[2]}" = "nginx-deployment-75675f5897-gstkw matches the regular expression (found Running)." ] + + # Running the same request with the invalid client will throw an error + # (the namespace is not expected in this function) + DETIK_CLIENT_NAME="mytest" + run try "at most 1 times every 5s to find 2 pods named 'nginx' with 'status' matching 'Running'" + [ "$status" -eq 3 ] +} + + +@test "trying to find 3 PODs with the lower-case syntax and a partial match" { + run try "at most 1 times every 5s to find 3 pods named 'nginx' with 'status' matching 'Ru.+ng'" + [ "$status" -eq 3 ] + [ ${#lines[@]} -eq 4 ] + [ "${lines[0]}" = "Valid expression. Verification in progress..." ] + [ "${lines[1]}" = "nginx-deployment-75675f5897-6dg9r matches the regular expression (found Running)." ] + [ "${lines[2]}" = "nginx-deployment-75675f5897-gstkw matches the regular expression (found Running)." ] + [ "${lines[3]}" = "Expected 3 pods named nginx to match this pattern (Ru.+ng). Found 2." ] +} + + +@test "trying to find 0 POD with the lower-case syntax and a pattern match" { + run try "at most 1 times every 5s to find 0 pod named 'nginx' with 'status' matching '^drinking'" + [ "$status" -eq 0 ] + [ ${#lines[@]} -eq 3 ] + [ "${lines[0]}" = "Valid expression. Verification in progress..." ] + [ "${lines[1]}" = "Current value for nginx-deployment-75675f5897-6dg9r is Running..." ] + [ "${lines[2]}" = "Current value for nginx-deployment-75675f5897-gstkw is Running..." ] +} + + +@test "trying to find 1 POD with a complex property and a pattern match" { + run try "at most 1 times every 5s to find 1 pod named 'nginx' with '.status.phase' matching 'R.nn.ng'" + [ "$status" -eq 3 ] + [ ${#lines[@]} -eq 4 ] + [ "${lines[0]}" = "Valid expression. Verification in progress..." ] + [ "${lines[1]}" = "nginx-deployment-75675f5897-6dg9r matches the regular expression (found Running)." ] + [ "${lines[2]}" = "nginx-deployment-75675f5897-gstkw matches the regular expression (found Running)." ] + [ "${lines[3]}" = "Expected 1 pod named nginx to match this pattern (R.nn.ng). Found 2." ] +} + + +@test "trying to find 2 PODs with a complex property and a pattern match" { + run try "at most 1 times every 5s to find 2 pods named 'nginx' with '.status.phase' matching 'Run{2}ing'" + [ "$status" -eq 0 ] + [ ${#lines[@]} -eq 3 ] + [ "${lines[0]}" = "Valid expression. Verification in progress..." ] + [ "${lines[1]}" = "nginx-deployment-75675f5897-6dg9r matches the regular expression (found Running)." ] + [ "${lines[2]}" = "nginx-deployment-75675f5897-gstkw matches the regular expression (found Running)." ] +} + + +@test "trying to verify the syntax check (invalid wording, with a pattern match)" { + run try "at most 5 times VERY 5hours to find 1 pod named 'nginx' with 'status' matching '^RUNNING'" + [ "$status" -eq 2 ] + [ ${#lines[@]} -eq 1 ] + [ "${lines[0]}" = "Invalid expression: it does not respect the expected syntax." ] +} + + +@test "trying to verify the find syntax check (missing quotes, with a pattern match)" { + run try "at most 5 times every 5s to find 2 pods named 'nginx' with 'status' matching Running" + [ "$status" -eq 2 ] + [ ${#lines[@]} -eq 1 ] + [ "${lines[0]}" = "Invalid expression: it does not respect the expected syntax." ] +} + + +@test "trying to find of a POD with the wrong value and a match (1 attempt)" { + run try "at most 1 times every 1s to find 1 pod named 'nginx' with 'status' matching 'initializing'" + [ "$status" -eq 3 ] + [ ${#lines[@]} -eq 4 ] + [ "${lines[0]}" = "Valid expression. Verification in progress..." ] + [ "${lines[1]}" = "Current value for nginx-deployment-75675f5897-6dg9r is Running..." ] + [ "${lines[2]}" = "Current value for nginx-deployment-75675f5897-gstkw is Running..." ] + [ "${lines[3]}" = "Expected 1 pod named nginx to match this pattern (initializing). Found 0." ] +} + + +@test "trying to find of a POD with the wrong value and a match (2 attempts)" { + run try "at most 2 times every 1s to find 1 pod named 'nginx' with 'status' matching 'initializing'" + [ "$status" -eq 3 ] + [ ${#lines[@]} -eq 7 ] + [ "${lines[0]}" = "Valid expression. Verification in progress..." ] + [ "${lines[1]}" = "Current value for nginx-deployment-75675f5897-6dg9r is Running..." ] + [ "${lines[2]}" = "Current value for nginx-deployment-75675f5897-gstkw is Running..." ] + [ "${lines[3]}" = "Expected 1 pod named nginx to match this pattern (initializing). Found 0." ] + [ "${lines[4]}" = "Current value for nginx-deployment-75675f5897-6dg9r is Running..." ] + [ "${lines[5]}" = "Current value for nginx-deployment-75675f5897-gstkw is Running..." ] + [ "${lines[6]}" = "Expected 1 pod named nginx to match this pattern (initializing). Found 0." ] +} + + +@test "trying to find of a POD with the wrong value and a match (3 attempts)" { + run try "at most 3 times every 1s to find 1 pod named 'nginx' with 'status' matching 'initializing'" + [ "$status" -eq 3 ] + [ ${#lines[@]} -eq 10 ] + [ "${lines[0]}" = "Valid expression. Verification in progress..." ] + [ "${lines[1]}" = "Current value for nginx-deployment-75675f5897-6dg9r is Running..." ] + [ "${lines[2]}" = "Current value for nginx-deployment-75675f5897-gstkw is Running..." ] + [ "${lines[3]}" = "Expected 1 pod named nginx to match this pattern (initializing). Found 0." ] + [ "${lines[4]}" = "Current value for nginx-deployment-75675f5897-6dg9r is Running..." ] + [ "${lines[5]}" = "Current value for nginx-deployment-75675f5897-gstkw is Running..." ] + [ "${lines[6]}" = "Expected 1 pod named nginx to match this pattern (initializing). Found 0." ] + [ "${lines[7]}" = "Current value for nginx-deployment-75675f5897-6dg9r is Running..." ] + [ "${lines[8]}" = "Current value for nginx-deployment-75675f5897-gstkw is Running..." ] + [ "${lines[9]}" = "Expected 1 pod named nginx to match this pattern (initializing). Found 0." ] +} + + +@test "trying to find of a POD with an invalid name and a pattern match" { + run try "at most 1 times every 1s to find 2 pods named 'nginx-something' with 'status' matching 'R.*g'" + [ "$status" -eq 3 ] + [ ${#lines[@]} -eq 3 ] + [ "${lines[0]}" = "Valid expression. Verification in progress..." ] + [ "${lines[1]}" = "No resource of type 'pods' was found with the name 'nginx-something'." ] + [ "${lines[2]}" = "Expected 2 pods named nginx-something to match this pattern (R.*g). Found 0." ] +} + + +@test "trying to find of a POD with a pattern name and pattern match" { + run try "at most 1 times every 1s to find 2 pods named 'ngin.*' with 'status' matching 'Run.+'" + [ "$status" -eq 0 ] + [ ${#lines[@]} -eq 3 ] + [ "${lines[0]}" = "Valid expression. Verification in progress..." ] + [ "${lines[1]}" = "nginx-deployment-75675f5897-6dg9r matches the regular expression (found Running)." ] + [ "${lines[2]}" = "nginx-deployment-75675f5897-gstkw matches the regular expression (found Running)." ] +} + + +@test "trying to find of a POD with an invalid pattern name and a pattern match" { + run try "at most 1 times every 1s to find 2 pods named 'ngin.+x' with 'status' matching 'Running'" + [ "$status" -eq 3 ] + [ ${#lines[@]} -eq 3 ] + [ "${lines[0]}" = "Valid expression. Verification in progress..." ] + [ "${lines[1]}" = "No resource of type 'pods' was found with the name 'ngin.+x'." ] + [ "${lines[2]}" = "Expected 2 pods named ngin.+x to match this pattern (Running). Found 0." ] +} + + +@test "trying to find of a POD with the lower-case syntax (multi-lines and pattern matching)" { + run try " at most 5 times every 5s to find 2 pods " \ + " named 'nginx' " \ + " with 'status' matching '^Running$' " + + [ "$status" -eq 0 ] + [ ${#lines[@]} -eq 3 ] + [ "${lines[0]}" = "Valid expression. Verification in progress..." ] + [ "${lines[1]}" = "nginx-deployment-75675f5897-6dg9r matches the regular expression (found Running)." ] + [ "${lines[2]}" = "nginx-deployment-75675f5897-gstkw matches the regular expression (found Running)." ] +} + + +@test "trying to find of a POD with the lower-case syntax (multi-lines and pattern matching, without quotes)" { + run try at most 11 times every 5s to find 2 pods \ + named "'nginx'" \ + with "'status'" matching "'^Running$'" + + [ "$status" -eq 0 ] + [ ${#lines[@]} -eq 3 ] + [ "${lines[0]}" = "Valid expression. Verification in progress..." ] + [ "${lines[1]}" = "nginx-deployment-75675f5897-6dg9r matches the regular expression (found Running)." ] + [ "${lines[2]}" = "nginx-deployment-75675f5897-gstkw matches the regular expression (found Running)." ] +} + + +@test "trying to find of a POD with the lower-case syntax (debug matching)" { + + debug_filename=$(basename -- "$BATS_TEST_FILENAME") + path="/tmp/detik/$debug_filename.debug" + [ -f "$path" ] && mv "$path" "$path.backup" + [ ! -f "$path" ] + + # Enable the debug flag + DEBUG_DETIK="true" + run try "at most 5 times every 5s to find 2 pods named 'nginx' with 'status' matching '^[[:alnum:]]+$'" + + # Reset the debug flag + DEBUG_DETIK="" + + # Verify basic assertions + [ "$status" -eq 0 ] + [ ${#lines[@]} -eq 3 ] + [ "${lines[0]}" = "Valid expression. Verification in progress..." ] + [ "${lines[1]}" = "nginx-deployment-75675f5897-6dg9r matches the regular expression (found Running)." ] + [ "${lines[2]}" = "nginx-deployment-75675f5897-gstkw matches the regular expression (found Running)." ] + + # Verify the debug file + [ -f "$path" ] + + rm -rf "$path.cmp" + exec 7<> "$path.cmp" + + echo "-----DETIK:begin-----" >&7 + echo "$BATS_TEST_FILENAME" >&7 + echo "trying to find of a POD with the lower-case syntax (debug matching)" >&7 + echo "" >&7 + echo "Client query:" >&7 + echo "mytest get pods -o custom-columns=NAME:.metadata.name,PROP:.status.phase" >&7 + echo "" >&7 + echo "Result:" >&7 + echo "nginx-deployment-75675f5897-6dg9r Running" >&7 + echo "nginx-deployment-75675f5897-gstkw Running" >&7 + echo "" >&7 + echo "Expected count: 2" >&7 + echo "-----DETIK:end-----" >&7 + echo "" >&7 + + exec 7>&- + run diff -q "$path" "$path.cmp" + [ "$status" -eq 0 ] + [ "$output" = "" ] + + [ -f "$path.backup" ] && mv "$path.backup" "$path" + rm -rf "$path.cmp" +} + + +@test "trying to find of a POD with the lower-case syntax (debug matching and a different K8s namespace)" { + DETIK_CLIENT_NAME="mytest_with_namespace" + DETIK_CLIENT_NAMESPACE="test_ns" + + debug_filename=$(basename -- "$BATS_TEST_FILENAME") + path="/tmp/detik/$debug_filename.debug" + [ -f "$path" ] && mv "$path" "$path.backup" + [ ! -f "$path" ] + + # Enable the debug flag + DEBUG_DETIK="true" + run try "at most 5 times every 5s to find 2 pods named 'nginx' with 'status' matching '^[[:alnum:]]+$'" + + # Reset the debug flag + DEBUG_DETIK="" + + # Verify basic assertions + [ "$status" -eq 0 ] + [ ${#lines[@]} -eq 3 ] + [ "${lines[0]}" = "Valid expression. Verification in progress..." ] + [ "${lines[1]}" = "nginx-deployment-75675f5897-6dg9r matches the regular expression (found Running)." ] + [ "${lines[2]}" = "nginx-deployment-75675f5897-gstkw matches the regular expression (found Running)." ] + + # Verify the debug file + [ -f "$path" ] + + rm -rf "$path.cmp" + exec 7<> "$path.cmp" + + echo "-----DETIK:begin-----" >&7 + echo "$BATS_TEST_FILENAME" >&7 + echo "trying to find of a POD with the lower-case syntax (debug matching and a different K8s namespace)" >&7 + echo "" >&7 + echo "Client query:" >&7 + echo "mytest_with_namespace --namespace=test_ns get pods -o custom-columns=NAME:.metadata.name,PROP:.status.phase" >&7 + echo "" >&7 + echo "Result:" >&7 + echo "nginx-deployment-75675f5897-6dg9r Running" >&7 + echo "nginx-deployment-75675f5897-gstkw Running" >&7 + echo "" >&7 + echo "Expected count: 2" >&7 + echo "-----DETIK:end-----" >&7 + echo "" >&7 + + exec 7>&- + run diff -q "$path" "$path.cmp" + [ "$status" -eq 0 ] + [ "$output" = "" ] + + [ -f "$path.backup" ] && mv "$path.backup" "$path" + rm -rf "$path.cmp" +} + + +my_consul_test() { + + consul_cpt=0 + if [[ -f /tmp/my-consul-test.txt ]]; then + consul_cpt=$(cat /tmp/my-consul-test.txt) + fi + + if [[ "$consul_cpt" == "2" ]]; then + echo -e "NAME PROP\nconsul-for-vault-0 Running\nconsul-for-vault-1 Running\nconsul-for-vault-2 Running" + fi + + consul_cpt=$((consul_cpt + 1)) + echo "$consul_cpt" > /tmp/my-consul-test.txt +} + + +@test "trying to find Consul PODs with a match" { + + DETIK_CLIENT_NAME="my_consul_test" + rm -rf /tmp/my-consul-test.txt + + run try "at most 5 times every 1s to find 3 pods named 'consul-for-vault' with 'status' matching 'R.nn.ng'" + [ "$status" -eq 0 ] + [ ${#lines[@]} -eq 8 ] + [ "${lines[0]}" = "Valid expression. Verification in progress..." ] + [ "${lines[1]}" = "No resource of type 'pods' was found with the name 'consul-for-vault'." ] + [ "${lines[2]}" = "Expected 3 pods named consul-for-vault to match this pattern (R.nn.ng). Found 0." ] + [ "${lines[3]}" = "No resource of type 'pods' was found with the name 'consul-for-vault'." ] + [ "${lines[4]}" = "Expected 3 pods named consul-for-vault to match this pattern (R.nn.ng). Found 0." ] + [ "${lines[5]}" = "consul-for-vault-0 matches the regular expression (found Running)." ] + [ "${lines[6]}" = "consul-for-vault-1 matches the regular expression (found Running)." ] + [ "${lines[7]}" = "consul-for-vault-2 matches the regular expression (found Running)." ] +} diff --git a/tests/test.detik.try.to.verify.bats b/tests/test.detik.try.to.verify.is.bats similarity index 99% rename from tests/test.detik.try.to.verify.bats rename to tests/test.detik.try.to.verify.is.bats index 1d6ecd3..1531883 100755 --- a/tests/test.detik.try.to.verify.bats +++ b/tests/test.detik.try.to.verify.is.bats @@ -163,12 +163,12 @@ mytest() { @test "trying to verify the status of a POD with the lower-case syntax (debug)" { - + debug_filename=$(basename -- "$BATS_TEST_FILENAME") path="/tmp/detik/$debug_filename.debug" [[ -f "$path" ]] && mv "$path" "$path.backup" [ ! -f "$path" ] - + # Enable the debug flag DEBUG_DETIK="true" run try "at most 5 times every 5s to get pods named 'nginx' and verify that 'status' is 'running'" @@ -182,10 +182,10 @@ mytest() { [ "${lines[0]}" = "Valid expression. Verification in progress..." ] [ "${lines[1]}" = "nginx-deployment-75675f5897-6dg9r has the right value (running)." ] [ "${lines[2]}" = "nginx-deployment-75675f5897-gstkw has the right value (running)." ] - + # Verify the debug file [ -f "$path" ] - + rm -rf "$path.cmp" exec 7<> "$path.cmp" @@ -206,7 +206,7 @@ mytest() { run diff -q "$path" "$path.cmp" [ "$status" -eq 0 ] [ "$output" = "" ] - + [[ -f "$path.backup" ]] && mv "$path.backup" "$path" rm -rf "$path.cmp" } diff --git a/tests/test.detik.try.to.verify.matches.bats b/tests/test.detik.try.to.verify.matches.bats new file mode 100755 index 0000000..cfbfa54 --- /dev/null +++ b/tests/test.detik.try.to.verify.matches.bats @@ -0,0 +1,255 @@ +#!/usr/bin/env bats + +load "../lib/detik" + + +DETIK_CLIENT_NAME="mytest" +mytest() { + echo -e "NAME PROP\nnginx-deployment-75675f5897-6dg9r Running\nnginx-deployment-75675f5897-gstkw Running" +} + + +@test "trying to verify the status of a POD with the lower-case syntax and a simple match" { + run try "at most 1 times every 1s to get pods named 'nginx' and verify that 'status' matches 'Running'" + [ "$status" -eq 0 ] + [ ${#lines[@]} -eq 3 ] + [ "${lines[0]}" = "Valid expression. Verification in progress..." ] + [ "${lines[1]}" = "nginx-deployment-75675f5897-6dg9r matches the regular expression (found Running)." ] + [ "${lines[2]}" = "nginx-deployment-75675f5897-gstkw matches the regular expression (found Running)." ] +} + + +@test "trying to verify the status of a POD with the lower-case syntax and a simple match with different case" { + run try "at most 1 times every 1s to get pods named 'nginx' and verify that 'status' matches 'running'" + [ "$status" -eq 3 ] + [ ${#lines[@]} -eq 3 ] + [ "${lines[0]}" = "Valid expression. Verification in progress..." ] + [ "${lines[1]}" = "Current value for nginx-deployment-75675f5897-6dg9r is Running..." ] + [ "${lines[2]}" = "Current value for nginx-deployment-75675f5897-gstkw is Running..." ] +} + + +@test "trying to verify the status of a POD with the lower-case syntax and a simple match with case-insensitivy" { + DETIK_REGEX_CASE_INSENSITIVE_PROPERTIES="true" + run try "at most 1 times every 1s to get pods named 'nginx' and verify that 'status' matches 'running'" + [ "$status" -eq 0 ] + [ ${#lines[@]} -eq 3 ] + [ "${lines[0]}" = "Valid expression. Verification in progress..." ] + [ "${lines[1]}" = "nginx-deployment-75675f5897-6dg9r matches the regular expression (found running)." ] + [ "${lines[2]}" = "nginx-deployment-75675f5897-gstkw matches the regular expression (found running)." ] +} + + +@test "trying to verify the status of a POD with the lower-case syntax and a simple match with an upper-case pattern" { + run try "at most 1 times every 1s to get pods named 'nginx' and verify that 'status' matches '[A-Z]+$'" + [ "$status" -eq 3 ] + [ ${#lines[@]} -eq 3 ] + [ "${lines[0]}" = "Valid expression. Verification in progress..." ] + [ "${lines[1]}" = "Current value for nginx-deployment-75675f5897-6dg9r is Running..." ] + [ "${lines[2]}" = "Current value for nginx-deployment-75675f5897-gstkw is Running..." ] +} + + +@test "trying to verify the status of a POD with the lower-case syntax and a simple match with a lower-case pattern" { + run try "at most 5 times every 5s to get pods named 'nginx' and verify that 'status' matches '[A-Z][a-z]+'" + [ "$status" -eq 0 ] + [ ${#lines[@]} -eq 3 ] + [ "${lines[0]}" = "Valid expression. Verification in progress..." ] + [ "${lines[1]}" = "nginx-deployment-75675f5897-6dg9r matches the regular expression (found Running)." ] + [ "${lines[2]}" = "nginx-deployment-75675f5897-gstkw matches the regular expression (found Running)." ] +} + + +@test "trying to verify the status of a POD with the lower-case syntax and an exact match" { + run try "at most 5 times every 5s to get pods named 'nginx' and verify that 'status' matches '^Running$'" + [ "$status" -eq 0 ] + [ ${#lines[@]} -eq 3 ] + [ "${lines[0]}" = "Valid expression. Verification in progress..." ] + [ "${lines[1]}" = "nginx-deployment-75675f5897-6dg9r matches the regular expression (found Running)." ] + [ "${lines[2]}" = "nginx-deployment-75675f5897-gstkw matches the regular expression (found Running)." ] +} + + +@test "trying to verify the status of a POD with a complex property and a partial match" { + run try "at most 5 times every 5s to get pods named 'nginx' and verify that '.status.phase' matches '^Run.*'" + [ "$status" -eq 0 ] + [ ${#lines[@]} -eq 3 ] + [ "${lines[0]}" = "Valid expression. Verification in progress..." ] + [ "${lines[1]}" = "nginx-deployment-75675f5897-6dg9r matches the regular expression (found Running)." ] + [ "${lines[2]}" = "nginx-deployment-75675f5897-gstkw matches the regular expression (found Running)." ] +} + +@test "trying to verify the containerStatus of a POD with a complex json property and a partial match" { + run try "at most 5 times every 5s to get pods named 'nginx' and verify that '.status.containerStatuses[?(@.name==\"nginx\")].ready' matches '.*ning'" + [ "$status" -eq 0 ] + [ ${#lines[@]} -eq 3 ] + [ "${lines[0]}" = "Valid expression. Verification in progress..." ] + [ "${lines[1]}" = "nginx-deployment-75675f5897-6dg9r matches the regular expression (found Running)." ] + [ "${lines[2]}" = "nginx-deployment-75675f5897-gstkw matches the regular expression (found Running)." ] +} + + +@test "trying to verify the status of a POD with upper-case letters and a pattern match" { + run try "at most 5 times eVery 5s to GET pods named 'nginx' and verify that 'status' matches '^Running$'" + [ "$status" -eq 0 ] + [ ${#lines[@]} -eq 3 ] + [ "${lines[0]}" = "Valid expression. Verification in progress..." ] + [ "${lines[1]}" = "nginx-deployment-75675f5897-6dg9r matches the regular expression (found Running)." ] + [ "${lines[2]}" = "nginx-deployment-75675f5897-gstkw matches the regular expression (found Running)." ] +} + + +@test "trying to verify the syntax check (invalid wording, with a pattern match)" { + run try "at most 5 times VERY 5hours to GET pods named 'nginx' and verify that 'status' matches 'RUNNING'" + [ "$status" -eq 2 ] + [ ${#lines[@]} -eq 1 ] + [ "${lines[0]}" = "Invalid expression: it does not respect the expected syntax." ] +} + + +@test "trying to verify the syntax check (missing quotes, with a pattern match)" { + run try "at most 5 times every 5s to get pods named 'nginx' and verify that 'status' matches Running" + [ "$status" -eq 2 ] + [ ${#lines[@]} -eq 1 ] + [ "${lines[0]}" = "Invalid expression: it does not respect the expected syntax." ] +} + + +@test "trying to verify the status of a POD with the wrong value and a match (1 attempt)" { + run try "at most 1 times every 1s to get pods named 'nginx' and verify that 'status' matches 'initializing'" + [ "$status" -eq 3 ] + [ ${#lines[@]} -eq 3 ] + [ "${lines[0]}" = "Valid expression. Verification in progress..." ] + [ "${lines[1]}" = "Current value for nginx-deployment-75675f5897-6dg9r is Running..." ] + [ "${lines[2]}" = "Current value for nginx-deployment-75675f5897-gstkw is Running..." ] +} + + +@test "trying to verify the status of a POD with the wrong value and a match (2 attempts)" { + run try "at most 2 times every 1s to get pods named 'nginx' and verify that 'status' matches 'initializing'" + [ "$status" -eq 3 ] + [ ${#lines[@]} -eq 5 ] + [ "${lines[0]}" = "Valid expression. Verification in progress..." ] + [ "${lines[1]}" = "Current value for nginx-deployment-75675f5897-6dg9r is Running..." ] + [ "${lines[2]}" = "Current value for nginx-deployment-75675f5897-gstkw is Running..." ] + [ "${lines[3]}" = "Current value for nginx-deployment-75675f5897-6dg9r is Running..." ] + [ "${lines[4]}" = "Current value for nginx-deployment-75675f5897-gstkw is Running..." ] +} + + +@test "trying to verify the status of a POD with the wrong value and a match (3 attempts)" { + run try "at most 3 times every 1s to get pods named 'nginx' and verify that 'status' matches 'initializing'" + [ "$status" -eq 3 ] + [ ${#lines[@]} -eq 7 ] + [ "${lines[0]}" = "Valid expression. Verification in progress..." ] + [ "${lines[1]}" = "Current value for nginx-deployment-75675f5897-6dg9r is Running..." ] + [ "${lines[2]}" = "Current value for nginx-deployment-75675f5897-gstkw is Running..." ] + [ "${lines[3]}" = "Current value for nginx-deployment-75675f5897-6dg9r is Running..." ] + [ "${lines[4]}" = "Current value for nginx-deployment-75675f5897-gstkw is Running..." ] + [ "${lines[5]}" = "Current value for nginx-deployment-75675f5897-6dg9r is Running..." ] + [ "${lines[6]}" = "Current value for nginx-deployment-75675f5897-gstkw is Running..." ] +} + + +@test "trying to verify the status of a POD with an invalid name and a pattern match" { + run try "at most 1 times every 1s to get pods named 'nginx-something' and verify that 'status' matches 'Running'" + [ "$status" -eq 3 ] + [ ${#lines[@]} -eq 2 ] + [ "${lines[0]}" = "Valid expression. Verification in progress..." ] + [ "${lines[1]}" = "No resource of type 'pods' was found with the name 'nginx-something'." ] +} + + +@test "trying to verify the status of a POD with a pattern name and a partial match" { + run try "at most 1 times every 1s to get pods named 'ngin.*' and verify that 'status' matches 'R.*g'" + [ "$status" -eq 0 ] + [ ${#lines[@]} -eq 3 ] + [ "${lines[0]}" = "Valid expression. Verification in progress..." ] + [ "${lines[1]}" = "nginx-deployment-75675f5897-6dg9r matches the regular expression (found Running)." ] + [ "${lines[2]}" = "nginx-deployment-75675f5897-gstkw matches the regular expression (found Running)." ] +} + + +@test "trying to verify the status of a POD with an invalid pattern name and a partial match" { + run try "at most 1 times every 1s to get pods named 'ngin.+x' and verify that 'status' matches 'Running'" + [ "$status" -eq 3 ] + [ ${#lines[@]} -eq 2 ] + [ "${lines[0]}" = "Valid expression. Verification in progress..." ] + [ "${lines[1]}" = "No resource of type 'pods' was found with the name 'ngin.+x'." ] +} + + +@test "trying to verify the status of a POD with the lower-case syntax (multi-lines and pattern matching)" { + run try " at most 5 times every 5s to get pods " \ + " named 'nginx' and " \ + " verify that 'status' matches '^Running$' " + + [ "$status" -eq 0 ] + [ ${#lines[@]} -eq 3 ] + [ "${lines[0]}" = "Valid expression. Verification in progress..." ] + [ "${lines[1]}" = "nginx-deployment-75675f5897-6dg9r matches the regular expression (found Running)." ] + [ "${lines[2]}" = "nginx-deployment-75675f5897-gstkw matches the regular expression (found Running)." ] +} + + +@test "trying to verify the status of a POD with the lower-case syntax (multi-lines and pattern matching, without quotes)" { + run try at most 11 times every 5s to get pods \ + named "'nginx'" and \ + verify that "'status'" matches "'^Running$'" + + [ "$status" -eq 0 ] + [ ${#lines[@]} -eq 3 ] + [ "${lines[0]}" = "Valid expression. Verification in progress..." ] + [ "${lines[1]}" = "nginx-deployment-75675f5897-6dg9r matches the regular expression (found Running)." ] + [ "${lines[2]}" = "nginx-deployment-75675f5897-gstkw matches the regular expression (found Running)." ] +} + + +@test "trying to verify the status of a POD with the lower-case syntax (debug matching)" { + + debug_filename=$(basename -- "$BATS_TEST_FILENAME") + path="/tmp/detik/$debug_filename.debug" + [[ -f "$path" ]] && mv "$path" "$path.backup" + [ ! -f "$path" ] + + # Enable the debug flag + DEBUG_DETIK="true" + run try "at most 5 times every 5s to get pods named 'nginx' and verify that 'status' matches '^[[:alnum:]]+$'" + + # Reset the debug flag + DEBUG_DETIK="" + + # Verify basic assertions + [ "$status" -eq 0 ] + [ ${#lines[@]} -eq 3 ] + [ "${lines[0]}" = "Valid expression. Verification in progress..." ] + [ "${lines[1]}" = "nginx-deployment-75675f5897-6dg9r matches the regular expression (found Running)." ] + [ "${lines[2]}" = "nginx-deployment-75675f5897-gstkw matches the regular expression (found Running)." ] + + # Verify the debug file + [ -f "$path" ] + + rm -rf "$path.cmp" + exec 7<> "$path.cmp" + + echo "-----DETIK:begin-----" >&7 + echo "$BATS_TEST_FILENAME" >&7 + echo "trying to verify the status of a POD with the lower-case syntax (debug matching)" >&7 + echo "" >&7 + echo "Client query:" >&7 + echo "mytest get pods -o custom-columns=NAME:.metadata.name,PROP:.status.phase" >&7 + echo "" >&7 + echo "Result:" >&7 + echo "nginx-deployment-75675f5897-6dg9r Running" >&7 + echo "nginx-deployment-75675f5897-gstkw Running" >&7 + echo "-----DETIK:end-----" >&7 + echo "" >&7 + + exec 7>&- + run diff -q "$path" "$path.cmp" + [ "$status" -eq 0 ] + [ "$output" = "" ] + + [[ -f "$path.backup" ]] && mv "$path.backup" "$path" + rm -rf "$path.cmp" +} diff --git a/tests/test.detik.verify.bats b/tests/test.detik.verify.bats index 3946f66..4a65d68 100755 --- a/tests/test.detik.verify.bats +++ b/tests/test.detik.verify.bats @@ -2,9 +2,9 @@ load "../lib/detik" - DETIK_CLIENT_NAME="mytest" DETIK_CLIENT_NAMESPACE="" + mytest() { # The namespace should not appear (it is set in 1st position) [[ "$1" != "--namespace=test_ns" ]] || return 1 @@ -422,3 +422,202 @@ mytest_with_namespace() { rm -rf "$path.cmp" [ -f "$path.backup" ] && mv "$path.backup" "$path" } + + +@test "verifying the status of a POD with the lower-case syntax and a simple match" { + run verify "'status' matches 'Running' for pods named 'nginx'" + [ "$status" -eq 0 ] + [ ${#lines[@]} -eq 3 ] + [ "${lines[0]}" = "Valid expression. Verification in progress..." ] + [ "${lines[1]}" = "nginx-deployment-75675f5897-6dg9r matches the regular expression (found Running)." ] + [ "${lines[2]}" = "nginx-deployment-75675f5897-gstkw matches the regular expression (found Running)." ] +} + + +@test "verifying the status of a POD with the lower-case syntax and a simple match with different case" { + run verify "'status' matches 'running' for pods named 'nginx'" + [ "$status" -eq 3 ] + [ ${#lines[@]} -eq 3 ] + [ "${lines[0]}" = "Valid expression. Verification in progress..." ] + [ "${lines[1]}" = "Current value for nginx-deployment-75675f5897-6dg9r is Running..." ] + [ "${lines[2]}" = "Current value for nginx-deployment-75675f5897-gstkw is Running..." ] +} + + +@test "verifying the status of a POD with the lower-case syntax and a simple match with case-insensitivy" { + DETIK_REGEX_CASE_INSENSITIVE_PROPERTIES="true" + run verify "'status' matches 'running' for pods named 'nginx'" + [ "$status" -eq 0 ] + [ ${#lines[@]} -eq 3 ] + [ "${lines[0]}" = "Valid expression. Verification in progress..." ] + [ "${lines[1]}" = "nginx-deployment-75675f5897-6dg9r matches the regular expression (found running)." ] + [ "${lines[2]}" = "nginx-deployment-75675f5897-gstkw matches the regular expression (found running)." ] +} + + +@test "verifying the status of a POD with the lower-case syntax and a simple match with an upper-case pattern" { + run verify "'status' matches '[A-Z]+$' for pods named 'nginx'" + [ "$status" -eq 3 ] + [ ${#lines[@]} -eq 3 ] + [ "${lines[0]}" = "Valid expression. Verification in progress..." ] + [ "${lines[1]}" = "Current value for nginx-deployment-75675f5897-6dg9r is Running..." ] + [ "${lines[2]}" = "Current value for nginx-deployment-75675f5897-gstkw is Running..." ] +} + + +@test "verifying the status of a POD with the lower-case syntax and a simple match with a lower-case pattern" { + run verify "'status' matches '[a-z]+' for pods named 'nginx'" + [ "$status" -eq 0 ] + [ ${#lines[@]} -eq 3 ] + [ "${lines[0]}" = "Valid expression. Verification in progress..." ] + [ "${lines[1]}" = "nginx-deployment-75675f5897-6dg9r matches the regular expression (found Running)." ] + [ "${lines[2]}" = "nginx-deployment-75675f5897-gstkw matches the regular expression (found Running)." ] +} + + +@test "verifying the status of a POD with the lower-case syntax and an exact match" { + run verify "'status' matches '^Running$' for pods named 'nginx'" + [ "$status" -eq 0 ] + [ ${#lines[@]} -eq 3 ] + [ "${lines[0]}" = "Valid expression. Verification in progress..." ] + [ "${lines[1]}" = "nginx-deployment-75675f5897-6dg9r matches the regular expression (found Running)." ] + [ "${lines[2]}" = "nginx-deployment-75675f5897-gstkw matches the regular expression (found Running)." ] +} + + +@test "verifying the status of a POD with a complex property and a partial match" { + run verify "'.status.phase' matches 'Run.*' for pods named 'nginx'" + [ "$status" -eq 0 ] + [ ${#lines[@]} -eq 3 ] + [ "${lines[0]}" = "Valid expression. Verification in progress..." ] + [ "${lines[1]}" = "nginx-deployment-75675f5897-6dg9r matches the regular expression (found Running)." ] + [ "${lines[2]}" = "nginx-deployment-75675f5897-gstkw matches the regular expression (found Running)." ] +} + + +@test "verifying the syntax check (invalid wording, with a pattern match)" { + run verify "'status' matches 'running' for all the pods named 'nginx'" + [ "$status" -eq 2 ] + [ ${#lines[@]} -eq 1 ] + [ "${lines[0]}" = "Invalid expression: it does not respect the expected syntax." ] +} + + +@test "verifying the syntax check (missing quotes, with a pattern match)" { + run verify "status matches 'running' for pods named 'nginx'" + [ "$status" -eq 2 ] + [ ${#lines[@]} -eq 1 ] + [ "${lines[0]}" = "Invalid expression: it does not respect the expected syntax." ] +} + + +@test "verifying the status of a POD with the wrong value and a pattern match" { + run verify "'status' matches 'initializing' for pods named 'nginx'" + [ "$status" -eq 3 ] + [ ${#lines[@]} -eq 3 ] + [ "${lines[0]}" = "Valid expression. Verification in progress..." ] + [ "${lines[1]}" = "Current value for nginx-deployment-75675f5897-6dg9r is Running..." ] + [ "${lines[2]}" = "Current value for nginx-deployment-75675f5897-gstkw is Running..." ] +} + + +@test "verifying the status of a POD with an invalid name and a pattern match" { + run verify "'status' matches 'Running' for pods named 'nginx-something'" + [ "$status" -eq 3 ] + [ ${#lines[@]} -eq 2 ] + [ "${lines[0]}" = "Valid expression. Verification in progress..." ] + [ "${lines[1]}" = "No resource of type 'pods' was found with the name 'nginx-something'." ] +} + + +@test "verifying the status of a POD with a pattern name and a pattern match" { + run verify "'status' matches 'R.nn.ng' for pods named 'ngin.*'" + [ "$status" -eq 0 ] + [ ${#lines[@]} -eq 3 ] + [ "${lines[0]}" = "Valid expression. Verification in progress..." ] + [ "${lines[1]}" = "nginx-deployment-75675f5897-6dg9r matches the regular expression (found Running)." ] + [ "${lines[2]}" = "nginx-deployment-75675f5897-gstkw matches the regular expression (found Running)." ] +} + + +@test "verifying the status of a POD with an invalid pattern name and a pattern match" { + run verify "'status' matches 'Running' for pods named 'ngin.+x'" + [ "$status" -eq 3 ] + [ ${#lines[@]} -eq 2 ] + [ "${lines[0]}" = "Valid expression. Verification in progress..." ] + [ "${lines[1]}" = "No resource of type 'pods' was found with the name 'ngin.+x'." ] +} + + +@test "verifying the status of a POD with the lower-case syntax (multi-lines and pattern matching)" { + run verify " 'status' matches 'R.+g' for " \ + " pods named 'nginx' " + + [ "$status" -eq 0 ] + [ ${#lines[@]} -eq 3 ] + [ "${lines[0]}" = "Valid expression. Verification in progress..." ] + [ "${lines[1]}" = "nginx-deployment-75675f5897-6dg9r matches the regular expression (found Running)." ] + [ "${lines[2]}" = "nginx-deployment-75675f5897-gstkw matches the regular expression (found Running)." ] +} + + +@test "verifying the status of a POD with the lower-case syntax (multi-lines and pattern matching, without quotes)" { + run verify "'status'" matches "'R.+g'" for \ + pods named "'nginx'" + + [ "$status" -eq 0 ] + [ ${#lines[@]} -eq 3 ] + [ "${lines[0]}" = "Valid expression. Verification in progress..." ] + [ "${lines[1]}" = "nginx-deployment-75675f5897-6dg9r matches the regular expression (found Running)." ] + [ "${lines[2]}" = "nginx-deployment-75675f5897-gstkw matches the regular expression (found Running)." ] +} + + +@test "verifying the status of a POD with the lower-case syntax (debug matching)" { + + debug_filename=$(basename -- "$BATS_TEST_FILENAME") + path="/tmp/detik/$debug_filename.debug" + [ -f "$path" ] && mv "$path" "$path.backup" + [ ! -f "$path" ] + + # Enable the debug flag + DEBUG_DETIK="true" + run verify "'status' matches 'Running' for pods named 'nginx'" + + # Reset the debug flag + DEBUG_DETIK="" + + # Verify basic assertions + [ "$status" -eq 0 ] + [ ${#lines[@]} -eq 3 ] + [ "${lines[0]}" = "Valid expression. Verification in progress..." ] + [ "${lines[1]}" = "nginx-deployment-75675f5897-6dg9r matches the regular expression (found Running)." ] + [ "${lines[2]}" = "nginx-deployment-75675f5897-gstkw matches the regular expression (found Running)." ] + + # Verify the debug file + [ -f "$path" ] + + rm -rf "$path.cmp" + exec 7<> "$path.cmp" + + echo "-----DETIK:begin-----" >&7 + echo "$BATS_TEST_FILENAME" >&7 + echo "verifying the status of a POD with the lower-case syntax (debug matching)" >&7 + echo "" >&7 + echo "Client query:" >&7 + echo "mytest get pods -o custom-columns=NAME:.metadata.name,PROP:.status.phase" >&7 + echo "" >&7 + echo "Result:" >&7 + echo "nginx-deployment-75675f5897-6dg9r Running" >&7 + echo "nginx-deployment-75675f5897-gstkw Running" >&7 + echo "-----DETIK:end-----" >&7 + echo "" >&7 + + exec 7>&- + run diff -q "$path" "$path.cmp" + [ "$status" -eq 0 ] + [ "$output" = "" ] + + rm -rf "$path.cmp" + [ -f "$path.backup" ] && mv "$path.backup" "$path" +} diff --git a/tests/test.linter.bats b/tests/test.linter.bats index 138f256..c819339 100755 --- a/tests/test.linter.bats +++ b/tests/test.linter.bats @@ -23,22 +23,22 @@ setup() { run remove_surrounding_quotes "" [ "$status" -eq 0 ] [ "$output" = "" ] - + run remove_surrounding_quotes "\"toto\"" [ "$status" -eq 0 ] [ "$output" = "toto" ] - + run remove_surrounding_quotes "\"toto is sleeping\"" [ "$status" -eq 0 ] [ "$output" = "toto is sleeping" ] - + run remove_surrounding_quotes "\"toto is \"still\" sleeping\"" [ "$status" -eq 0 ] [ "$output" = "toto is \"still\" sleeping" ] - + run remove_surrounding_quotes "\"toto is \"still\" sleeping" [ "$status" -eq 0 ] - + run remove_surrounding_quotes "toto is \"still\" sleeping\"" [ "$status" -eq 0 ] } @@ -48,23 +48,29 @@ setup() { run verify_against_pattern "toto" "toto" [ "$status" -eq 0 ] - + run verify_against_pattern "toto" "^toto$" [ "$status" -eq 0 ] - + run verify_against_pattern "\"toto\"" "^toto$" [ "$status" -eq 1 ] - + run verify_against_pattern "'toto'" "'toto'" [ "$status" -eq 0 ] - + run verify_against_pattern "\"'toto'\"" "'toto'" [ "$status" -eq 0 ] - - run verify_against_pattern "at most 5 times eVery 5s to GET pods named 'nginx' and verify that 'status' is 'RUNNING'" "$try_regex_verify" + + run verify_against_pattern "at most 5 times eVery 5s to GET pods named 'nginx' and verify that 'status' is 'RUNNING'" "$try_regex_verify_is" + [ "$status" -eq 0 ] + + run verify_against_pattern "at most 5 times eVery 5s to GET pods named nginx' and verify that 'status' is 'RUNNING'" "$try_regex_verify_is" + [ "$status" -eq 1 ] + + run verify_against_pattern "at most 5 times eVery 5s to GET pods named 'nginx' and verify that 'status' matches '^RUNNING$'" "$try_regex_verify_matches" [ "$status" -eq 0 ] - - run verify_against_pattern "at most 5 times eVery 5s to GET pods named nginx' and verify that 'status' is 'RUNNING'" "$try_regex_verify" + + run verify_against_pattern "at most 5 times eVery 5s to GET pods named nginx' and verify that 'status' matches '^RUNNING$'" "$try_regex_verify_matches" [ "$status" -eq 1 ] } @@ -74,7 +80,7 @@ setup() { run lint "/tmp/does-not-exist" [ "$status" -eq 1 ] [ "$output" = "'/tmp/does-not-exist' does not exist or is not a regular file." ] - + run lint "/tmp/" [ "$status" -eq 1 ] [ "$output" = "'/tmp/' does not exist or is not a regular file." ] @@ -85,7 +91,7 @@ setup() { run lint "$BATS_TEST_DIRNAME/resources/without_lint_errors.run.txt" [ ${#lines[@]} -eq 2 ] - [ "${lines[0]}" = "29 DETIK queries were verified." ] + [ "${lines[0]}" = "51 DETIK queries were verified." ] [ "${lines[1]}" = "0 DETIK queries were found to be invalid or malformed." ] [ "$status" -eq 0 ] } @@ -95,80 +101,100 @@ setup() { run lint "$BATS_TEST_DIRNAME/resources/without_lint_errors.no.run.txt" [ ${#lines[@]} -eq 2 ] - [ "${lines[0]}" = "29 DETIK queries were verified." ] + [ "${lines[0]}" = "51 DETIK queries were verified." ] [ "${lines[1]}" = "0 DETIK queries were found to be invalid or malformed." ] [ "$status" -eq 0 ] } -@test "checking the linter with a file with lint errors on TRY to VERIFY (with RUN)" { +@test "checking the linter with a file with lint errors on TRY to VERIFY (without RUN)" { - run lint "$BATS_TEST_DIRNAME/resources/with_lint_errors_try_to_verify.run.txt" - [ ${#lines[@]} -eq 8 ] + run lint "$BATS_TEST_DIRNAME/resources/with_lint_errors_try_to_verify.no.run.txt" + [ ${#lines[@]} -eq 13 ] [ "${lines[0]}" = "Invalid TRY statement at line 17." ] [ "${lines[1]}" = "Invalid TRY statement at line 21." ] [ "${lines[2]}" = "Invalid TRY statement at line 24." ] [ "${lines[3]}" = "Invalid TRY statement at line 27." ] [ "${lines[4]}" = "Empty statement at line 30." ] [ "${lines[5]}" = "Invalid TRY statement at line 41." ] - [ "${lines[6]}" = "14 DETIK queries were verified." ] - [ "${lines[7]}" = "6 DETIK queries were found to be invalid or malformed." ] - [ "$status" -eq 6 ] + [ "${lines[6]}" = "Invalid TRY statement at line 51." ] + [ "${lines[7]}" = "Invalid TRY statement at line 55." ] + [ "${lines[8]}" = "Invalid TRY statement at line 58." ] + [ "${lines[9]}" = "Invalid TRY statement at line 61." ] + [ "${lines[10]}" = "Invalid TRY statement at line 72." ] + [ "${lines[11]}" = "27 DETIK queries were verified." ] + [ "${lines[12]}" = "11 DETIK queries were found to be invalid or malformed." ] + [ "$status" -eq 11 ] } -@test "checking the linter with a file with lint errors on TRY to FIND (without RUN)" { +@test "checking the linter with a file with lint errors on TRY to VERIFY (with RUN)" { - run lint "$BATS_TEST_DIRNAME/resources/with_lint_errors_try_to_find.no.run.txt" - [ ${#lines[@]} -eq 8 ] + run lint "$BATS_TEST_DIRNAME/resources/with_lint_errors_try_to_verify.run.txt" + [ ${#lines[@]} -eq 13 ] [ "${lines[0]}" = "Invalid TRY statement at line 17." ] [ "${lines[1]}" = "Invalid TRY statement at line 21." ] [ "${lines[2]}" = "Invalid TRY statement at line 24." ] [ "${lines[3]}" = "Invalid TRY statement at line 27." ] [ "${lines[4]}" = "Empty statement at line 30." ] [ "${lines[5]}" = "Invalid TRY statement at line 41." ] - [ "${lines[6]}" = "14 DETIK queries were verified." ] - [ "${lines[7]}" = "6 DETIK queries were found to be invalid or malformed." ] - [ "$status" -eq 6 ] + [ "${lines[6]}" = "Invalid TRY statement at line 51." ] + [ "${lines[7]}" = "Invalid TRY statement at line 55." ] + [ "${lines[8]}" = "Invalid TRY statement at line 58." ] + [ "${lines[9]}" = "Invalid TRY statement at line 61." ] + [ "${lines[10]}" = "Invalid TRY statement at line 72." ] + [ "${lines[11]}" = "27 DETIK queries were verified." ] + [ "${lines[12]}" = "11 DETIK queries were found to be invalid or malformed." ] + [ "$status" -eq 11 ] } -@test "checking the linter with a file with lint errors on TRY to FIND (with RUN)" { +@test "checking the linter with a file with lint errors on TRY to FIND (without RUN)" { - run lint "$BATS_TEST_DIRNAME/resources/with_lint_errors_try_to_find.run.txt" - [ ${#lines[@]} -eq 8 ] + run lint "$BATS_TEST_DIRNAME/resources/with_lint_errors_try_to_find.no.run.txt" + [ ${#lines[@]} -eq 13 ] [ "${lines[0]}" = "Invalid TRY statement at line 17." ] [ "${lines[1]}" = "Invalid TRY statement at line 21." ] [ "${lines[2]}" = "Invalid TRY statement at line 24." ] [ "${lines[3]}" = "Invalid TRY statement at line 27." ] [ "${lines[4]}" = "Empty statement at line 30." ] [ "${lines[5]}" = "Invalid TRY statement at line 41." ] - [ "${lines[6]}" = "14 DETIK queries were verified." ] - [ "${lines[7]}" = "6 DETIK queries were found to be invalid or malformed." ] - [ "$status" -eq 6 ] + [ "${lines[6]}" = "Invalid TRY statement at line 51." ] + [ "${lines[7]}" = "Invalid TRY statement at line 55." ] + [ "${lines[8]}" = "Invalid TRY statement at line 58." ] + [ "${lines[9]}" = "Invalid TRY statement at line 61." ] + [ "${lines[10]}" = "Invalid TRY statement at line 72." ] + [ "${lines[11]}" = "27 DETIK queries were verified." ] + [ "${lines[12]}" = "11 DETIK queries were found to be invalid or malformed." ] + [ "$status" -eq 11 ] } -@test "checking the linter with a file with lint errors on TRY to VERIFY (without RUN)" { +@test "checking the linter with a file with lint errors on TRY to FIND (with RUN)" { - run lint "$BATS_TEST_DIRNAME/resources/with_lint_errors_try_to_verify.no.run.txt" - [ ${#lines[@]} -eq 8 ] + run lint "$BATS_TEST_DIRNAME/resources/with_lint_errors_try_to_find.run.txt" + [ ${#lines[@]} -eq 13 ] [ "${lines[0]}" = "Invalid TRY statement at line 17." ] [ "${lines[1]}" = "Invalid TRY statement at line 21." ] [ "${lines[2]}" = "Invalid TRY statement at line 24." ] [ "${lines[3]}" = "Invalid TRY statement at line 27." ] [ "${lines[4]}" = "Empty statement at line 30." ] [ "${lines[5]}" = "Invalid TRY statement at line 41." ] - [ "${lines[6]}" = "14 DETIK queries were verified." ] - [ "${lines[7]}" = "6 DETIK queries were found to be invalid or malformed." ] - [ "$status" -eq 6 ] + [ "${lines[6]}" = "Invalid TRY statement at line 51." ] + [ "${lines[7]}" = "Invalid TRY statement at line 55." ] + [ "${lines[8]}" = "Invalid TRY statement at line 58." ] + [ "${lines[9]}" = "Invalid TRY statement at line 61." ] + [ "${lines[10]}" = "Invalid TRY statement at line 72." ] + [ "${lines[11]}" = "27 DETIK queries were verified." ] + [ "${lines[12]}" = "11 DETIK queries were found to be invalid or malformed." ] + [ "$status" -eq 11 ] } @test "checking the linter with a file with lint errors on VERIFY (with RUN)" { run lint "$BATS_TEST_DIRNAME/resources/with_lint_errors_verify.run.txt" - [ ${#lines[@]} -eq 12 ] + [ ${#lines[@]} -eq 16 ] [ "${lines[0]}" = "Invalid VERIFY statement at line 20." ] [ "${lines[1]}" = "Invalid VERIFY statement at line 25." ] [ "${lines[2]}" = "Invalid VERIFY statement at line 28." ] @@ -179,16 +205,20 @@ setup() { [ "${lines[7]}" = "Invalid VERIFY statement at line 52." ] [ "${lines[8]}" = "Invalid VERIFY statement at line 57." ] [ "${lines[9]}" = "Invalid VERIFY statement at line 62." ] - [ "${lines[10]}" = "25 DETIK queries were verified." ] - [ "${lines[11]}" = "10 DETIK queries were found to be invalid or malformed." ] - [ "$status" -eq 10 ] + [ "${lines[10]}" = "Invalid VERIFY statement at line 74." ] + [ "${lines[11]}" = "Invalid VERIFY statement at line 77." ] + [ "${lines[12]}" = "Invalid VERIFY statement at line 82." ] + [ "${lines[13]}" = "Invalid VERIFY statement at line 86." ] + [ "${lines[14]}" = "36 DETIK queries were verified." ] + [ "${lines[15]}" = "14 DETIK queries were found to be invalid or malformed." ] + [ "$status" -eq 14 ] } @test "checking the linter with a file with lint errors on VERIFY (without RUN)" { run lint "$BATS_TEST_DIRNAME/resources/with_lint_errors_verify.no.run.txt" - [ ${#lines[@]} -eq 12 ] + [ ${#lines[@]} -eq 16 ] [ "${lines[0]}" = "Invalid VERIFY statement at line 20." ] [ "${lines[1]}" = "Invalid VERIFY statement at line 25." ] [ "${lines[2]}" = "Invalid VERIFY statement at line 28." ] @@ -199,7 +229,11 @@ setup() { [ "${lines[7]}" = "Invalid VERIFY statement at line 52." ] [ "${lines[8]}" = "Invalid VERIFY statement at line 57." ] [ "${lines[9]}" = "Invalid VERIFY statement at line 62." ] - [ "${lines[10]}" = "25 DETIK queries were verified." ] - [ "${lines[11]}" = "10 DETIK queries were found to be invalid or malformed." ] - [ "$status" -eq 10 ] + [ "${lines[10]}" = "Invalid VERIFY statement at line 74." ] + [ "${lines[11]}" = "Invalid VERIFY statement at line 77." ] + [ "${lines[12]}" = "Invalid VERIFY statement at line 82." ] + [ "${lines[13]}" = "Invalid VERIFY statement at line 86." ] + [ "${lines[14]}" = "36 DETIK queries were verified." ] + [ "${lines[15]}" = "14 DETIK queries were found to be invalid or malformed." ] + [ "$status" -eq 14 ] }