diff --git a/tests/common/gen-bats.bash b/tests/common/gen-bats.bash index 4cad963bf..fa5c54b00 100755 --- a/tests/common/gen-bats.bash +++ b/tests/common/gen-bats.bash @@ -19,13 +19,14 @@ render_args() { return fi - for arg in $(yq4 -oy '.[]' <<< "${args}"); do - if [[ "${arg}" =~ ^\. ]]; then + readarray -t args_arr <<< "$(jq -c '.[]' <<< "${args}")" + for arg in "${args_arr[@]}"; do + if [[ "${arg}" =~ ^\"\. ]]; then # reference argument - echo -n "\"\$(yq_dig \"${cluster}\" \"${arg}\")\"" + echo -n " \"\$(yq_dig \"${cluster}\" ${arg})\"" else # plain argument - echo -n "\"${arg}\"" + echo -n " ${arg}" fi done } @@ -42,8 +43,9 @@ render_conditions() { return fi - for condition in $(yq4 -oy '.[]' <<< "${conditions}"); do - echo " continue_on \"${cluster}\" \"${condition}\"" + readarray -t conditions_arr <<< "$(jq -c '.[]' <<< "${conditions}")" + for condition in "${conditions_arr[@]}"; do + echo " continue_on ${cluster} ${condition}" done echo "" } @@ -67,15 +69,22 @@ render_test() { log_fatal "render test: missing target" fi - for cluster in $(yq4 -oy '.[]' <<< "${clusters}"); do - for namespace in $(yq4 -oy '.[]' <<< "${namespaces}"); do + readarray -t clusters_arr <<< "$(jq -c '.[]' <<< "${clusters}")" + for cluster in "${clusters_arr[@]}"; do + readarray -t namespaces_arr <<< "$(jq -c '.[]' <<< "${namespaces}")" + for namespace in "${namespaces_arr[@]}"; do echo "" - echo "@test \"${name} - ${function/_/ } - ${cluster} / ${namespace} / ${target}\" {" + # TODO: Set with flag + if [ "${foreach:-[]}" != "[]" ]; then + echo "@test \"${name} - ${function//_/ } - ${cluster//\"/} / ${namespace//\"/} / ${target} - $(jq -r .[0] <<< "${args}")\" {" + else + echo "@test \"${name} - ${function//_/ } - ${cluster//\"/} / ${namespace//\"/} / ${target}\" {" + fi render_conditions "${cluster}" "${conditions}" - echo " with_kubeconfig \"${cluster}\"" - echo " with_namespace \"${namespace}\"" + echo " with_kubeconfig ${cluster}" + echo " with_namespace ${namespace}" echo "" - echo " ${function} \"${target}\" $(render_args "${cluster}" "${args}")" + echo " ${function} \"${target}\"$(render_args "${cluster}" "${args}")" echo "}" done done @@ -88,12 +97,12 @@ render_tests() { for test in "$@"; do # Intentionally creating subprocesses to ensure variables are reset after traversal ( - stage="$(yq4 '.clusters // []' <<< "${test}")" + stage="$(jq -c '.clusters // []' <<< "${test}")" if [[ "${stage}" != "[]" ]]; then clusters="${stage}" fi - stage="$(yq4 '.namespaces // []' <<< "${test}")" + stage="$(jq -c '.namespaces // []' <<< "${test}")" if [[ "${stage}" != "[]" ]]; then namespaces="${stage}" fi @@ -112,12 +121,25 @@ render_tests() { function="${stage}" fi + stage="$(jq -c '.foreach // []' <<< "${test}")" + if [[ "${stage}" != "[]" ]]; then + foreach="${stage}" + fi + stage="$(yq4 '.target // ""' <<< "${test}")" - readarray -t tests <<< "$(yq4 -oj -I0 '.tests[] // []' <<< "${test}")" + readarray -t tests <<< "$(jq -c '(.tests // []) | .[]' <<< "${test}")" if [[ "${stage}" != "" ]]; then - render_test "${clusters:-[]}" "${namespaces:-[]}" "[${conditions:-}]" "${function:-}" "${stage}" "$(yq4 -oj -I0 '.args // []' <<< "${test}")" - elif [[ "${tests[*]}" != "[]" ]]; then + # With foreach set emit tests for each as first argument with regular args after + if [[ "${foreach:-[]}" != "[]" ]]; then + for args in $(jq .[] <<< "${foreach}"); do + render_test "${clusters:-[]}" "${namespaces:-[]}" "[${conditions:-}]" "${function:-}" "${stage}" "$(jq -c "[${args}] + (.args // [])" <<< "${test}")" + done + # Without foreach set emit test with regular args + else + render_test "${clusters:-[]}" "${namespaces:-[]}" "[${conditions:-}]" "${function:-}" "${stage}" "$(jq -c '.args // []' <<< "${test}")" + fi + elif [[ "${tests[*]}" != "" ]]; then render_tests "${tests[@]}" fi ) diff --git a/tests/common/lib.bash b/tests/common/lib.bash index 37dfab06d..a159a1630 100644 --- a/tests/common/lib.bash +++ b/tests/common/lib.bash @@ -164,6 +164,7 @@ with_kubeconfig() { with_namespace() { if [[ -n "${1:-}" ]]; then export DETIK_CLIENT_NAMESPACE="$1" + export NAMESPACE="$1" else fail "missing namespace argument" fi @@ -213,3 +214,13 @@ test_statefulset() { fail "missing statefulset name argument" fi } + +# note: expects with_kubeconfig and with_namespace to be set +# usage: test_logs_contains ... +test_logs_contains() { + run kubectl -n "${NAMESPACE}" logs "${1}" grafana-sc-dashboard + + for arg in "${@:2}"; do + assert_line --regexp "${arg}" + done +} diff --git a/tests/end-to-end/grafana-dashboard-discovery.bats b/tests/end-to-end/grafana-dashboard-discovery.bats new file mode 100644 index 000000000..59f7d451f --- /dev/null +++ b/tests/end-to-end/grafana-dashboard-discovery.bats @@ -0,0 +1,52 @@ +#!/usr/bin/env bats + +setup() { + load "../common/lib" + + common_setup +} + +grafana_sc_dashboard_logs() { + kubectl -n monitoring logs "deployment/${1}" grafana-sc-dashboard | sed -rn 's#\{"time": ".+", "msg": "Writing /tmp/dashboards/(.+) \(ascii\)", "level": "INFO"\}#- \1#p' | sort -u +} + +grafana_logs() { + kubectl -n monitoring logs "deployment/${1}" grafana | grep 'level=error' | sed -rn 's#.*dashboards/(.+) error="(.+)"#error: \1: \2#p' | sort -u +} + +@test "grafana admin dashboard discovery" { + with_kubeconfig "sc" + + run grafana_sc_dashboard_logs ops-grafana + + while read -r line; do + assert_line "${line}" + done < "${ROOT}/tests/end-to-end/grafana-dashboards-admin.yaml" +} + +@test "grafana dev dashboard discovery" { + with_kubeconfig "sc" + + run grafana_sc_dashboard_logs user-grafana + + while read -r line; do + assert_line "${line}" + done < "${ROOT}/tests/end-to-end/grafana-dashboards-dev.yaml" +} + +@test "grafana admin dashboard load without error" { + with_kubeconfig "sc" + + run grafana_logs ops-grafana + + refute_output +} + + +@test "grafana dev dashboard load without error" { + with_kubeconfig "sc" + + run grafana_logs user-grafana + + refute_output +} diff --git a/tests/end-to-end/grafana-dashboards-admin.yaml b/tests/end-to-end/grafana-dashboards-admin.yaml new file mode 100644 index 000000000..01937ab28 --- /dev/null +++ b/tests/end-to-end/grafana-dashboards-admin.yaml @@ -0,0 +1,54 @@ +- alertmanager-overview-dashboard.json +- apiserver-dashboard.json +- backup-dashboard.json +- calicofelix-dashboard.json +- ciskubernetesbenchmark-dashboard.json +- cluster-api-dashboard.json +- cluster-total-dashboard.json +- clustercompliancereport-dashboard.json +- daily-dashboard.json +- etcd-dashboard.json +- falco-dashboard.json +- fluentd-dashboard.json +- gatekeeper-dashboard.json +- grafana-overview-dashboard.json +- harbor-dashboard.json +- hnc-dashboard.json +- k8s-coredns-dashboard.json +- k8s-resources-cluster-dashboard.json +- k8s-resources-namespace-dashboard.json +- k8s-resources-node-dashboard.json +- k8s-resources-pod-dashboard.json +- k8s-resources-workload-dashboard.json +- k8s-resources-workloads-namespace-dashboard.json +- kubelet-dashboard.json +- kubernetesstatus-dashboard.json +- namespace-by-pod-dashboard.json +- namespace-by-workload-dashboard.json +- networkpolicy-dashboard.json +- nginx-dashboard.json +- node-cluster-rsrc-use-dashboard.json +- node-exporter-full-dashboard.json +- node-local-dns-dashboard.json +- node-rsrc-use-dashboard.json +- node-spread-dashboard.json +- nodes-dashboard.json +- opensearch-dashboard.json +- persistentvolumesusage-dashboard.json +- pod-total-dashboard.json +- prometheus-blackbox-exporter-dashboard.json +- prometheus-dashboard.json +- prometheus-timeseries-dashboard.json +- proxy-dashboard.json +- thanos-compact-dashboard.json +- thanos-overview-dashboard.json +- thanos-query-dashboard.json +- thanos-query-frontend-dashboard.json +- thanos-receive-dashboard.json +- thanos-rule-dashboard.json +- thanos-store-dashboard.json +- trivy-operator-dashboard.json +- uptime-dashboard.json +- velero-dashboard.json +- welcome-dashboard.json +- workload-total-dashboard.json diff --git a/tests/end-to-end/grafana-dashboards-dev.yaml b/tests/end-to-end/grafana-dashboards-dev.yaml new file mode 100644 index 000000000..b08722d59 --- /dev/null +++ b/tests/end-to-end/grafana-dashboards-dev.yaml @@ -0,0 +1,48 @@ +- alertmanager-overview-dashboard.json +- apiserver-dashboard.json +- backup-dashboard.json +- ciskubernetesbenchmark-dashboard.json +- cluster-total-dashboard.json +- clustercompliancereport-dashboard.json +- etcd-dashboard.json +- falco-dashboard.json +- fluentd-dashboard.json +- gatekeeper-dashboard.json +- grafana-overview-dashboard.json +- harbor-dashboard.json +- k8s-coredns-dashboard.json +- k8s-resources-cluster-dashboard.json +- k8s-resources-namespace-dashboard.json +- k8s-resources-node-dashboard.json +- k8s-resources-pod-dashboard.json +- k8s-resources-workload-dashboard.json +- k8s-resources-workloads-namespace-dashboard.json +- kubelet-dashboard.json +- kubernetesstatus-dashboard.json +- namespace-by-pod-dashboard.json +- namespace-by-workload-dashboard.json +- networkpolicy-dashboard.json +- nginx-dashboard.json +- node-cluster-rsrc-use-dashboard.json +- node-exporter-full-dashboard.json +- node-local-dns-dashboard.json +- node-rsrc-use-dashboard.json +- node-spread-dashboard.json +- nodes-dashboard.json +- opensearch-dashboard.json +- persistentvolumesusage-dashboard.json +- pod-total-dashboard.json +- prometheus-blackbox-exporter-dashboard.json +- prometheus-dashboard.json +- proxy-dashboard.json +- thanos-compact-dashboard.json +- thanos-overview-dashboard.json +- thanos-query-dashboard.json +- thanos-query-frontend-dashboard.json +- thanos-receive-dashboard.json +- thanos-rule-dashboard.json +- thanos-store-dashboard.json +- trivy-operator-dashboard.json +- uptime-dashboard.json +- welcome-dashboard.json +- workload-total-dashboard.json