Skip to content

#46 Fix regexp support for resource names #47

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,14 @@ The syntax is quite simple and may be easily adapted for other solutions, such a

## Syntax Reference

For all the available sentences, both a resource name and a resource type are expected.
The resource name can be a simple string (e.g. `nginx`) or a regular expression
(e.g. `^nginx-[a-z0-9]{9,10}-[a-z0-9]{5}\$`), while the resource type is one of
the K8s ones (e.g. `pods`, `po`, `services`, `svc`...) or a CRD. See
[https://kubernetes.io/docs/reference/kubectl/overview/#resource-types](https://kubernetes.io/docs/reference/kubectl/overview/#resource-types) for a complete reference of the official resources. The available custom resources (e.g.
`settings.management.cattle.io`) will depend on your cluster setup.


### Counting Resources

Verify there are N resources of this type with this name pattern.
Expand All @@ -297,15 +305,11 @@ verify "there are more than <number> <resource-type> named '<regular-expression>
verify "there are less than <number> <resource-type> named '<regular-expression>'"
```

*resource-type* is one of the K8s ones (e.g. `pods`, `po`, `services`, `svc`...).
See [https://kubernetes.io/docs/reference/kubectl/overview/#resource-types](https://kubernetes.io/docs/reference/kubectl/overview/#resource-types) for a complete reference.


> :warning: This simple assertion may fail sometimes.
>
> As an example, if you count the number of PODs, run your test and then kill the POD, they will still be listed, with the `TERMINATING` state.
>
> So, most of the time, you will want to verify the number of instances with a given property value. Example: count the number of PODs with a given name pattern and having the `started` status.
> So, most of the time, you will want to verify the number of instances with a given property value. Example: count the number of PODs with a given name pattern and having the `running` status.

Hence this additional syntax (using [next section](#verifying-property-values) documentation to verify additionnal properties):

Expand Down
32 changes: 28 additions & 4 deletions lib/detik.bash
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,11 @@ verify() {
echo "Valid expression. Verification in progress..."
query=$(build_k8s_request "")
client_with_options=$(build_k8s_client_with_options)
result=$(eval $client_with_options get $resource $query | grep $name | tail -n +1 | wc -l | tr -d '[:space:]')
result=$(eval $client_with_options get $resource $query \
| tail -n +2 \
| filter_by_resource_name "$name" \
| wc -l \
| tr -d '[:space:]')

# Debug?
detik_debug "-----DETIK:begin-----"
Expand All @@ -173,7 +177,7 @@ verify() {
echo "Found $result $resource named $name (less than $card as expected)."
else
echo "Found $result $resource named $name (instead of less than $card expected)."
return 3
return 3
fi
elif [[ "$exp" =~ "more than" ]]; then
if [[ "$result" -gt "$card" ]]; then
Expand Down Expand Up @@ -243,10 +247,12 @@ verify_value() {
expected_count="$6"
exp="$7"

# List the items and remove the first line (the one that contains the column names)
# 1. Query / list the items
# 2. Remove the first line (the one that contains the column names)
# 3. Filter by resource name
query=$(build_k8s_request "$property")
client_with_options=$(build_k8s_client_with_options)
result=$(eval $client_with_options get $resource $query | grep $name | tail -n +1)
result=$(eval $client_with_options get $resource $query | tail -n +2 | filter_by_resource_name "$name")

# Debug?
detik_debug "-----DETIK:begin-----"
Expand Down Expand Up @@ -380,3 +386,21 @@ build_k8s_client_with_options() {

echo "$client_with_options"
}


# Filters results by resource name (or name pattern).
# The results are directly read, they are not passed as variables.
#
# @param $1 the resource name or name pattern
# @return 0
filter_by_resource_name() {

# For all the output lines...
while IFS= read -r line; do
# ... extract the resource name (first column)
# and only keep the lines where the resource name matches
if echo "$line" | cut -d ' ' -f1 | grep -qE "$1"; then
echo "$line"
fi
done
}
20 changes: 20 additions & 0 deletions tests/test.detik.try.to.verify.is.bats
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,16 @@ mytest_deployment(){
}


@test "trying to find of a POD with an extended pattern name" {
run try "at most 1 times every 5s to get pod named '^nginx-deployment-[a-z0-9]{9,10}-[a-z0-9]{5}\$' and verify that 'status' is 'running'"
[ "$status" -eq 0 ]
[ ${#lines[@]} -eq 3 ]
[ "${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)." ]
}


@test "trying to verify the status of a POD with an invalid pattern name" {
run try "at most 1 times every 1s to get pods named 'ngin.+x' and verify that 'status' is 'running'"
[ "$status" -eq 3 ]
Expand All @@ -154,6 +164,16 @@ mytest_deployment(){
}


@test "trying to find of a POD with an invalid extended pattern name" {
run try "at most 1 times every 1s to find 2 pods named '^nginx-deployment-[a-z0-9]{9,10}-[a-z0-9]{4}\$' with 'status' being '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 '^nginx-deployment-[a-z0-9]{9,10}-[a-z0-9]{4}\$'." ]
[ "${lines[2]}" = "Expected 2 pods named ^nginx-deployment-[a-z0-9]{9,10}-[a-z0-9]{4}\$ to have this value (running). Found 0." ]
}


@test "trying to verify the status of a POD with the lower-case syntax (multi-lines)" {
run try " at most 5 times every 5s to get pods " \
" named 'nginx' and " \
Expand Down
9 changes: 9 additions & 0 deletions tests/test.detik.verify.bats
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,15 @@ mytest_with_namespace() {
}


@test "verifying the number of PODs with an extended pattern syntax (exact number, 0 as singular)" {
run verify "There are 2 PODS named '^nginx-deployment-[a-z0-9]{9,10}-[a-z0-9]{5}\$'"
[ "$status" -eq 0 ]
[ ${#lines[@]} -eq 2 ]
[ "${lines[0]}" = "Valid expression. Verification in progress..." ]
[ "${lines[1]}" = "Found 2 pods named ^nginx-deployment-[a-z0-9]{9,10}-[a-z0-9]{5}\$ (as expected)." ]
}


@test "verifying the number of resources with their type including dots" {
# The value is not important. We want to make sure resource
# types with dots is supported.
Expand Down
3 changes: 3 additions & 0 deletions tests/test.linter.bats
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ setup() {

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 ]

run verify_against_pattern "at most 5 times eVery 5s to GET pods named '^nginx-deployment-[a-z0-9]{9,10}-[a-z0-9]{4}\$' and verify that 'status' matches '^RUNNING$'" "$try_regex_verify_matches"
[ "$status" -eq 0 ]
}


Expand Down
Loading