diff --git a/ci-operator/config/stolostron/policy-collection/stolostron-policy-collection-main__ocp4.22.yaml b/ci-operator/config/stolostron/policy-collection/stolostron-policy-collection-main__ocp4.22.yaml index 7c648df07abcf..c24a4aab33455 100644 --- a/ci-operator/config/stolostron/policy-collection/stolostron-policy-collection-main__ocp4.22.yaml +++ b/ci-operator/config/stolostron/policy-collection/stolostron-policy-collection-main__ocp4.22.yaml @@ -23,10 +23,6 @@ base_images: name: "2.17" namespace: acm-qe tag: multicluster-observability-operator-opp - ocs-ci-tests: - name: ocs-ci-container - namespace: ci - tag: stable tests-private: name: tests-private namespace: ci @@ -90,8 +86,6 @@ tests: FIREWATCH_DEFAULT_JIRA_PROJECT: LPINTEROP FIREWATCH_FAIL_WITH_TEST_FAILURES: "true" IGNORE_SECONDARY_POLICIES: "true" - MAP_TESTS: "true" - ODF_VERSION_MAJOR_MINOR: "4.21" OPERATORS: | [ {"name": "advanced-cluster-management", "source": "redhat-operators", "channel": "release-2.16", "install_namespace": "ocm", "target_namespaces": "ocm", "operator_group": "acm-operator-group"} @@ -125,7 +119,7 @@ tests: - ref: acm-tests-clc-create - ref: acm-fetch-managed-clusters - ref: acm-opp-app - - ref: interop-tests-ocs-tests + - ref: interop-opp-odf-health - ref: quay-tests-quay-interop-test - ref: acm-tests-observability - ref: acm-tests-grc @@ -150,8 +144,6 @@ tests: cluster_profile: vsphere-connected-2 env: COMPUTE_NODE_REPLICAS: "6" - DISABLE_ENVIRONMENT_CHECKER: "true" - DR__RP__CR_COMP_NAME: lp-interop--OPP FIREWATCH_CONFIG_FILE_PATH: https://raw.githubusercontent.com/CSPI-QE/cspi-utils/refs/heads/main/firewatch-base-configs/opp/lp-interop-vsphere.json FIREWATCH_DEFAULT_JIRA_ADDITIONAL_LABELS: '["4.22-lp","opp-vsphere-lp","opp-lp"]' FIREWATCH_DEFAULT_JIRA_ASSIGNEE: ftan@redhat.com @@ -159,8 +151,6 @@ tests: FIREWATCH_DEFAULT_JIRA_PROJECT: LPINTEROP FIREWATCH_FAIL_WITH_TEST_FAILURES: "true" IGNORE_SECONDARY_POLICIES: "true" - MAP_TESTS: "true" - ODF_VERSION_MAJOR_MINOR: "4.21" OPENSHIFT_REQUIRED_CORES: "72" OPENSHIFT_REQUIRED_MEMORY: "288" OPERATORS: | @@ -184,7 +174,7 @@ tests: - ref: acm-policies-openshift-plus-setup - ref: acm-policies-openshift-plus - chain: cucushift-installer-check-cluster-health - - ref: interop-tests-ocs-tests + - ref: interop-opp-odf-health - ref: acm-tests-observability - ref: acm-opp-app - ref: openshift-extended-test diff --git a/ci-operator/config/stolostron/policy-collection/stolostron-policy-collection-main__ocp5.0.yaml b/ci-operator/config/stolostron/policy-collection/stolostron-policy-collection-main__ocp5.0.yaml index 2efc0cc8ee622..610fc395e85fb 100644 --- a/ci-operator/config/stolostron/policy-collection/stolostron-policy-collection-main__ocp5.0.yaml +++ b/ci-operator/config/stolostron/policy-collection/stolostron-policy-collection-main__ocp5.0.yaml @@ -23,10 +23,6 @@ base_images: name: "2.17" namespace: acm-qe tag: multicluster-observability-operator-opp - ocs-ci-tests: - name: ocs-ci-container - namespace: ci - tag: stable tests-private: name: tests-private namespace: ci @@ -89,8 +85,6 @@ tests: FIREWATCH_DEFAULT_JIRA_EPIC: INTEROP-9323 FIREWATCH_DEFAULT_JIRA_PROJECT: LPINTEROP FIREWATCH_FAIL_WITH_TEST_FAILURES: "true" - MAP_TESTS: "true" - ODF_VERSION_MAJOR_MINOR: "5.0" OPERATORS: | [ {"name": "advanced-cluster-management", "source": "redhat-operators", "channel": "release-2.17", "install_namespace": "ocm", "target_namespaces": "ocm", "operator_group": "acm-operator-group"} @@ -123,7 +117,7 @@ tests: - ref: acm-tests-clc-create - ref: acm-fetch-managed-clusters - ref: acm-opp-app - - ref: interop-tests-ocs-tests + - ref: interop-opp-odf-health - ref: quay-tests-quay-interop-test - ref: acm-tests-observability - ref: acm-tests-grc @@ -148,16 +142,12 @@ tests: cluster_profile: vsphere-connected-2 env: COMPUTE_NODE_REPLICAS: "6" - DISABLE_ENVIRONMENT_CHECKER: "true" - DR__RP__CR_COMP_NAME: lp-interop--OPP FIREWATCH_CONFIG_FILE_PATH: https://raw.githubusercontent.com/CSPI-QE/cspi-utils/refs/heads/main/firewatch-base-configs/opp/lp-interop-vsphere.json FIREWATCH_DEFAULT_JIRA_ADDITIONAL_LABELS: '["5.0-lp","opp-vsphere-lp","opp-lp"]' FIREWATCH_DEFAULT_JIRA_ASSIGNEE: mpruitt@redhat.com FIREWATCH_DEFAULT_JIRA_EPIC: INTEROP-9323 FIREWATCH_DEFAULT_JIRA_PROJECT: LPINTEROP FIREWATCH_FAIL_WITH_TEST_FAILURES: "true" - MAP_TESTS: "true" - ODF_VERSION_MAJOR_MINOR: "5.0" OPENSHIFT_REQUIRED_CORES: "72" OPENSHIFT_REQUIRED_MEMORY: "288" OPERATORS: | @@ -180,7 +170,7 @@ tests: - ref: acm-policies-openshift-plus-setup - ref: acm-policies-openshift-plus - chain: cucushift-installer-check-cluster-health - - ref: interop-tests-ocs-tests + - ref: interop-opp-odf-health - ref: acm-tests-observability - ref: acm-opp-app - ref: openshift-extended-test diff --git a/ci-operator/step-registry/interop/opp/odf-health/OWNERS b/ci-operator/step-registry/interop/opp/odf-health/OWNERS new file mode 100644 index 0000000000000..41d144d3728a2 --- /dev/null +++ b/ci-operator/step-registry/interop/opp/odf-health/OWNERS @@ -0,0 +1,3 @@ +approvers: &owners +- cspi-qe-ocp-lp +reviewers: *owners diff --git a/ci-operator/step-registry/interop/opp/odf-health/interop-opp-odf-health-commands.sh b/ci-operator/step-registry/interop/opp/odf-health/interop-opp-odf-health-commands.sh new file mode 100755 index 0000000000000..156a7f9b28caa --- /dev/null +++ b/ci-operator/step-registry/interop/opp/odf-health/interop-opp-odf-health-commands.sh @@ -0,0 +1,525 @@ +#!/bin/bash +set -euo pipefail +shopt -s inherit_errexit + +# --------------------------------------------------------------------------- +# ODF Health Check (7-point gate) +# +# Validates that ODF is healthy and functional in the OPP interop cluster. +# Replaces the former interop-tests-ocs-tests step which ran single-product +# ODF acceptance tests unrelated to cross-product interop. +# +# Produces JUnit XML consumed by Prow / Sippy / TestGrid. +# --------------------------------------------------------------------------- + +ODF_NAMESPACE="${ODF_NAMESPACE:-openshift-storage}" +NOOBAA_S3_TIMEOUT="${NOOBAA_S3_TIMEOUT:-30}" + +typeset junitFile="${ARTIFACT_DIR}/junit_odf_health.xml" + +typeset -a tcNamesArr=() +typeset -a tcResultsArr=() +typeset -a tcMessagesArr=() + +# --------------------------------------------------------------------------- +# Helpers +# --------------------------------------------------------------------------- + +function AddResult () { + typeset name="${1:-}"; (($#)) && shift + typeset result="${1:-}"; (($#)) && shift + typeset message="${1:-}"; (($#)) && shift + tcNamesArr+=("${name}") + tcResultsArr+=("${result}") + tcMessagesArr+=("${message}") + true +} + +function XmlEscape () { + typeset text="${1:-}"; (($#)) && shift + text="${text//&/&}" + text="${text///>}" + text="${text//\"/"}" + text="${text//\'/'}" + printf '%s' "${text}" + true +} + +function WriteJunit () { + typeset -i total=${#tcNamesArr[@]} + typeset -i failCount=0 + typeset -i skipCount=0 + typeset r="" + for r in "${tcResultsArr[@]}"; do + if [[ "${r}" == "fail" ]]; then + (( failCount++ )) || true + elif [[ "${r}" == "skip" ]]; then + (( skipCount++ )) || true + fi + done + + { + echo '' + echo "" + typeset -i i=0 + for i in "${!tcNamesArr[@]}"; do + typeset name="" + name="$(XmlEscape "${tcNamesArr[$i]}")" + echo " " + if [[ "${tcResultsArr[$i]}" == "fail" ]]; then + typeset msg="" + msg="$(XmlEscape "${tcMessagesArr[$i]}")" + echo " " + elif [[ "${tcResultsArr[$i]}" == "skip" ]]; then + typeset msg="" + msg="$(XmlEscape "${tcMessagesArr[$i]}")" + echo " " + fi + echo " " + done + echo "" + } > "${junitFile}" + : "JUnit XML written to ${junitFile}" +} + +# shellcheck disable=SC2317 +function CollectExitArtifacts () { + : "Collecting ODF diagnostics..." + oc get csv -n "${ODF_NAMESPACE}" -o yaml > "${ARTIFACT_DIR}/odf-csvs.yaml" || true + oc get storagecluster -n "${ODF_NAMESPACE}" -o yaml > "${ARTIFACT_DIR}/storagecluster.yaml" || true + oc get cephcluster -n "${ODF_NAMESPACE}" -o yaml > "${ARTIFACT_DIR}/cephcluster.yaml" || true + oc get noobaa -n "${ODF_NAMESPACE}" -o yaml > "${ARTIFACT_DIR}/noobaa.yaml" || true + oc get sc -o yaml > "${ARTIFACT_DIR}/storageclasses.yaml" || true +} + +trap CollectExitArtifacts EXIT + +# --------------------------------------------------------------------------- +# Check 1: ODF Operator CSV in Succeeded phase +# --------------------------------------------------------------------------- + +function CheckOdfCsv () { + : "=== Check 1: ODF Operator CSV ===" + + typeset csvPhase="" + if ! csvPhase="$(oc get csv -n "${ODF_NAMESPACE}" -o json | python3 -c " +import sys,json,re; d=json.load(sys.stdin) +m=[i for i in d.get('items',[]) if re.match(r'^(odf-|ocs-)operator',i['metadata']['name'])] +print((m[0].get('status',{}).get('phase','NotFound')) if m else 'NotFound') +")"; then + AddResult "odf-csv-phase" "fail" "Failed to query ODF CSVs in ${ODF_NAMESPACE}" + return + fi + + if [[ "${csvPhase}" == "Succeeded" ]]; then + : "PASS: ODF CSV phase=Succeeded" + AddResult "odf-csv-phase" "pass" + elif [[ "${csvPhase}" == "NotFound" ]]; then + AddResult "odf-csv-phase" "fail" "No ODF/OCS operator CSV found in ${ODF_NAMESPACE}" + else + AddResult "odf-csv-phase" "fail" "ODF CSV phase=${csvPhase} (expected Succeeded)" + fi + true +} + +# --------------------------------------------------------------------------- +# Check 2: StorageCluster phase == Ready +# --------------------------------------------------------------------------- + +function CheckStorageCluster () { + : "=== Check 2: StorageCluster Ready ===" + + typeset scPhase="" + if ! scPhase="$(oc get storagecluster -n "${ODF_NAMESPACE}" -o json | python3 -c " +import sys,json; d=json.load(sys.stdin) +print(d['items'][0]['status'].get('phase','NotFound') if d.get('items') else 'NotFound') +")"; then + AddResult "storagecluster-ready" "fail" "Failed to query StorageCluster" + return + fi + + if [[ "${scPhase}" == "Ready" ]]; then + : "PASS: StorageCluster phase=Ready" + AddResult "storagecluster-ready" "pass" + elif [[ "${scPhase}" == "NotFound" ]]; then + AddResult "storagecluster-ready" "fail" "No StorageCluster found in ${ODF_NAMESPACE}" + else + AddResult "storagecluster-ready" "fail" "StorageCluster phase=${scPhase} (expected Ready)" + fi + true +} + +# --------------------------------------------------------------------------- +# Check 3: CephCluster health == HEALTH_OK or HEALTH_WARN +# --------------------------------------------------------------------------- + +function CheckCephCluster () { + : "=== Check 3: CephCluster health ===" + + typeset cephHealth="" + if ! cephHealth="$(oc get cephcluster -n "${ODF_NAMESPACE}" -o json | python3 -c " +import sys,json; d=json.load(sys.stdin) +print(d['items'][0].get('status',{}).get('ceph',{}).get('health','NotFound') if d.get('items') else 'NotFound') +")"; then + AddResult "cephcluster-health" "fail" "Failed to query CephCluster" + return + fi + + if [[ "${cephHealth}" == "HEALTH_OK" || "${cephHealth}" == "HEALTH_WARN" ]]; then + : "PASS: CephCluster health=${cephHealth}" + AddResult "cephcluster-health" "pass" + elif [[ "${cephHealth}" == "NotFound" ]]; then + AddResult "cephcluster-health" "fail" "No CephCluster found in ${ODF_NAMESPACE}" + else + AddResult "cephcluster-health" "fail" "CephCluster health=${cephHealth} (expected HEALTH_OK or HEALTH_WARN)" + fi + true +} + +# --------------------------------------------------------------------------- +# Check 4: Default StorageClasses available (ceph-rbd, cephfs) +# --------------------------------------------------------------------------- + +function CheckStorageClasses () { + : "=== Check 4: StorageClasses ===" + typeset failMsg="" + typeset scName="" + + for scName in ocs-storagecluster-ceph-rbd ocs-storagecluster-cephfs; do + if ! oc get sc "${scName}" -o name 2>/dev/null; then + if [[ -n "${failMsg}" ]]; then + failMsg="${failMsg}; StorageClass ${scName} not found" + else + failMsg="StorageClass ${scName} not found" + fi + else + : "PASS: StorageClass ${scName} exists" + fi + done + + if [[ -z "${failMsg}" ]]; then + AddResult "storageclasses-available" "pass" + else + AddResult "storageclasses-available" "fail" "${failMsg}" + fi + true +} + +# --------------------------------------------------------------------------- +# Check 5: PVC provisionable (create, bind, delete) +# --------------------------------------------------------------------------- + +function CheckPvcProvision () { + : "=== Check 5: PVC provisioning (RBD + CephFS) ===" + + typeset -a scTests=("ocs-storagecluster-ceph-rbd" "ocs-storagecluster-cephfs") + typeset -a scModes=("ReadWriteOnce" "ReadWriteMany") + typeset -i idx=0 + + for idx in "${!scTests[@]}"; do + typeset scName="${scTests[$idx]}" + typeset accessMode="${scModes[$idx]}" + typeset testId="pvc-provision-${scName##*-}" + typeset pvcName="odf-health-${scName##*-}-${RANDOM}" + typeset pvcYaml + pvcYaml=$(cat </dev/null || echo "")" + if [[ "${phase}" == "Bound" ]]; then + break + fi + sleep 5 + (( elapsed += 5 )) || true + done + + oc delete pvc "${pvcName}" -n "${ODF_NAMESPACE}" --wait=false 2>/dev/null || true + + if [[ "${phase}" == "Bound" ]]; then + : "PASS: ${scName} PVC bound in ${elapsed}s" + AddResult "${testId}" "pass" + else + AddResult "${testId}" "fail" "${scName} PVC did not bind within ${maxWait}s (phase=${phase:-unknown})" + fi + done + true +} + +# --------------------------------------------------------------------------- +# Check 6: NooBaa system Ready + S3 put/get/delete functional check +# --------------------------------------------------------------------------- + +function CheckNoobaa () { + : "=== Check 6: NooBaa S3 functional ===" + + typeset nbPhase="" + if ! nbPhase="$(oc get noobaa -n "${ODF_NAMESPACE}" -o json | python3 -c " +import sys,json; d=json.load(sys.stdin) +print(d['items'][0]['status'].get('phase','NotFound') if d.get('items') else 'NotFound') +")"; then + AddResult "noobaa-s3-functional" "fail" "Failed to query NooBaa" + return + fi + + if [[ "${nbPhase}" == "NotFound" ]]; then + AddResult "noobaa-s3-functional" "fail" "No NooBaa system found in ${ODF_NAMESPACE}" + return + fi + + if [[ "${nbPhase}" != "Ready" ]]; then + AddResult "noobaa-s3-functional" "fail" "NooBaa phase=${nbPhase} (expected Ready)" + return + fi + + : "NooBaa phase=Ready, creating OBC for S3 functional check..." + + typeset obcName="odf-health-obc-${RANDOM}" + typeset obcYaml + obcYaml=$(cat </dev/null || echo "")" + if [[ "${obcPhase}" == "Bound" ]]; then + break + fi + sleep 5 + (( elapsed += 5 )) || true + done + + if [[ "${obcPhase}" != "Bound" ]]; then + oc delete obc "${obcName}" -n "${ODF_NAMESPACE}" --ignore-not-found=true --wait=false 2>/dev/null || true + AddResult "noobaa-s3-functional" "fail" "OBC did not bind within ${maxWait}s (phase=${obcPhase:-unknown})" + return + fi + + typeset bucketName="" + bucketName="$(oc get obc "${obcName}" -n "${ODF_NAMESPACE}" -o jsonpath='{.spec.bucketName}' 2>/dev/null)" || true + if [[ -z "${bucketName}" ]]; then + oc delete obc "${obcName}" -n "${ODF_NAMESPACE}" --ignore-not-found=true --wait=false 2>/dev/null || true + AddResult "noobaa-s3-functional" "fail" "OBC bound but bucket name is empty" + return + fi + typeset secretRef="" + secretRef="$(oc get obc "${obcName}" -n "${ODF_NAMESPACE}" -o jsonpath='{.spec.secretName}' 2>/dev/null)" + if [[ -z "${secretRef}" ]]; then + secretRef="${obcName}" + fi + + typeset s3Endpoint="" + s3Endpoint="$(oc get noobaa -n "${ODF_NAMESPACE}" -o json | python3 -c " +import sys,json; d=json.load(sys.stdin) +v=d['items'][0].get('status',{}).get('services',{}).get('serviceS3',{}).get('internalDNS',[]) +print(v[0] if v else '') +")" || true + if [[ -z "${s3Endpoint}" ]]; then + s3Endpoint="https://s3.${ODF_NAMESPACE}.svc:443" + fi + + typeset testKey="health-check-${RANDOM}" + typeset testData="" + testData="odf-health-$(date +%s)" + + typeset podName="odf-health-s3-check-${RANDOM}" + typeset podManifest="" + podManifest=$(cat </dev/null && \ + RETRIEVED=\$(aws --endpoint-url "\${S3_ENDPOINT}" --no-verify-ssl s3 cp "s3://\${BUCKET_NAME}/\${TEST_KEY}" - 2>/dev/null) && \ + aws --endpoint-url "\${S3_ENDPOINT}" --no-verify-ssl s3 rm "s3://\${BUCKET_NAME}/\${TEST_KEY}" 2>/dev/null && \ + if [ "\${RETRIEVED}" = "\${TEST_DATA}" ]; then echo "S3_CHECK_PASS"; else echo "S3_CHECK_FAIL: data mismatch"; fi + activeDeadlineSeconds: ${NOOBAA_S3_TIMEOUT} +EOF +) + + typeset s3Result="" + typeset -i podWait=$(( NOOBAA_S3_TIMEOUT + 60 )) + if echo "${podManifest}" | oc apply -f -; then + if ! oc wait pod "${podName}" -n "${ODF_NAMESPACE}" \ + --for=jsonpath='{.status.phase}'=Succeeded \ + --timeout="${podWait}s" 2>/dev/null; then + : "Pod did not succeed within ${podWait}s, checking logs anyway" + fi + s3Result="$(oc logs "${podName}" -n "${ODF_NAMESPACE}" 2>/dev/null || echo "")" + fi + + oc delete pod "${podName}" -n "${ODF_NAMESPACE}" --ignore-not-found=true --wait=false 2>/dev/null || true + oc delete obc "${obcName}" -n "${ODF_NAMESPACE}" --ignore-not-found=true --wait=false 2>/dev/null || true + + if echo "${s3Result}" | grep -q "S3_CHECK_PASS"; then + : "PASS: NooBaa S3 put/get/delete cycle succeeded" + AddResult "noobaa-s3-functional" "pass" + else + typeset s3Msg="NooBaa S3 functional check failed" + if echo "${s3Result}" | grep -q "S3_CHECK_FAIL"; then + s3Msg="NooBaa S3: $(echo "${s3Result}" | grep "S3_CHECK_FAIL")" + fi + AddResult "noobaa-s3-functional" "fail" "${s3Msg}" + fi + true +} + +# --------------------------------------------------------------------------- +# Check 7: Ceph overall health (via toolbox or CephCluster status) +# --------------------------------------------------------------------------- + +function CheckCephHealth () { + : "=== Check 7: Ceph health detail ===" + + typeset cephDetail="" + if ! cephDetail="$(oc get cephcluster -n "${ODF_NAMESPACE}" -o json | python3 -c " +import sys,json; d=json.load(sys.stdin) +details=d['items'][0].get('status',{}).get('ceph',{}).get('details',{}) if d.get('items') else {} +for k,v in details.items(): + if v.get('severity')!='HEALTH_OK': print(f\"{k}: {v.get('message','unknown')}\") +")"; then + AddResult "ceph-health-detail" "fail" "Failed to query CephCluster details" + return + fi + + typeset cephHealth="" + cephHealth="$(oc get cephcluster -n "${ODF_NAMESPACE}" -o json | python3 -c " +import sys,json; d=json.load(sys.stdin) +print(d['items'][0].get('status',{}).get('ceph',{}).get('health','unknown') if d.get('items') else 'unknown') +")" || true + + if [[ "${cephHealth}" == "HEALTH_OK" ]]; then + : "PASS: Ceph health=HEALTH_OK" + AddResult "ceph-health-detail" "pass" + elif [[ "${cephHealth}" == "HEALTH_WARN" ]]; then + : "PASS (warn): Ceph health=HEALTH_WARN: ${cephDetail}" + AddResult "ceph-health-detail" "pass" + else + AddResult "ceph-health-detail" "fail" "Ceph health=${cephHealth}: ${cephDetail}" + fi + true +} + +# --------------------------------------------------------------------------- +# Main +# --------------------------------------------------------------------------- + +function Main () { + if [[ -f "${SHARED_DIR}/kubeconfig" ]]; then + export KUBECONFIG="${SHARED_DIR}/kubeconfig" + fi + + : "ODF Health Check (7-point gate) starting" + : "Namespace: ${ODF_NAMESPACE}" + : "Artifacts dir: ${ARTIFACT_DIR}" + + CheckOdfCsv || true + CheckStorageCluster || true + CheckCephCluster || true + CheckStorageClasses || true + CheckPvcProvision || true + CheckNoobaa || true + CheckCephHealth || true + + WriteJunit + + typeset -i hasAnyFail=0 + typeset r="" + for r in "${tcResultsArr[@]}"; do + if [[ "${r}" == "fail" ]]; then + hasAnyFail=1 + break + fi + done + + if (( hasAnyFail )); then + : "ODF Health Check: SOME CHECKS FAILED" + exit 1 + fi + + : "ODF Health Check: ALL PASSED" + exit 0 +} + +Main "$@" diff --git a/ci-operator/step-registry/interop/opp/odf-health/interop-opp-odf-health-ref.metadata.json b/ci-operator/step-registry/interop/opp/odf-health/interop-opp-odf-health-ref.metadata.json new file mode 100644 index 0000000000000..4db42591de65c --- /dev/null +++ b/ci-operator/step-registry/interop/opp/odf-health/interop-opp-odf-health-ref.metadata.json @@ -0,0 +1,11 @@ +{ + "path": "interop/opp/odf-health/interop-opp-odf-health-ref.yaml", + "owners": { + "approvers": [ + "cspi-qe-ocp-lp" + ], + "reviewers": [ + "cspi-qe-ocp-lp" + ] + } +} \ No newline at end of file diff --git a/ci-operator/step-registry/interop/opp/odf-health/interop-opp-odf-health-ref.yaml b/ci-operator/step-registry/interop/opp/odf-health/interop-opp-odf-health-ref.yaml new file mode 100644 index 0000000000000..9f8c8a5523239 --- /dev/null +++ b/ci-operator/step-registry/interop/opp/odf-health/interop-opp-odf-health-ref.yaml @@ -0,0 +1,25 @@ +ref: + as: interop-opp-odf-health + from: cli + grace_period: 30s + commands: interop-opp-odf-health-commands.sh + timeout: 8m + env: + - name: ODF_NAMESPACE + default: "openshift-storage" + documentation: Namespace where ODF is installed + - name: NOOBAA_S3_TIMEOUT + default: "30" + documentation: Timeout in seconds for the NooBaa S3 functional check pod + resources: + requests: + cpu: 100m + memory: 200Mi + documentation: |- + Validates ODF health in the OPP interop cluster via a 7-point gate: + ODF Operator CSV phase, StorageCluster readiness, CephCluster health, + default StorageClass availability, PVC provisioning, NooBaa system + readiness with S3 functional check, and Ceph overall health. + Replaces the former interop-tests-ocs-tests step which ran 28 + single-product acceptance tests with a 3h timeout. + Produces JUnit XML for Prow / Sippy / TestGrid consumption.