Skip to content

feat: add test resource collector utility for debugging test failures - #1034

Open
fabikova wants to merge 3 commits into
Kuadrant:mainfrom
fabikova:feature/861-test-resources-utility
Open

feat: add test resource collector utility for debugging test failures#1034
fabikova wants to merge 3 commits into
Kuadrant:mainfrom
fabikova:feature/861-test-resources-utility

Conversation

@fabikova

@fabikova fabikova commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Add a utility to collect and save Kubernetes resources created during test runs for debugging purposes. When enabled via --collect-resources flag, the collector captures all test-related resources and saves them to debug-resources/ as clean YAML files.

Features:

  • Automatic collection via --collect-resources flag
  • Two output files per test: apply-able spec and full debugging context
  • Multicluster support: separate files per cluster (cluster1/cluster2/cluster3)
  • Each parametrized test variant gets its own self-contained files
  • Readable filenames with module, test name, and parameters
  • Resources can be recreated with oc apply -f file.yaml

Enabled via pytest flag:
poetry run pytest --collect-resources

Apply file (spec-only):

  • No status, no server-assigned metadata (uid, resourceVersion, clusterIP, nodePort)
  • No Pods or ReplicaSets (controller-managed)
  • Reproducible: oc apply -f file.yaml works on any clean namespace

Full file (debugging):

  • Everything: status, all metadata, Pods, cluster-assigned fields
  • Shows actual state as it was during the test

Verification:

Singlecluster test:

poetry run pytest testsuite/tests/singlecluster/gateway/authpolicy/test_authpolicy_section_targeting_gateway.py --collect-resources
→ Two files created (-apply.yaml and -full.yaml)

Parametrized tests:

poetry run pytest testsuite/tests/singlecluster/authorino/identity/api_key/test_auth_credentials.py --collect-resources
→ 16 parameter variants × 2 files = 32 files created (each with different AuthPolicy)

Design:

  • Per-test collection: Dedup by nodeid - reruns reuse first capture
  • Per-parameter variant: Parametrized tests get separate files (each is self-contained)
  • Metadata strategy: Strip managedFields only; keep uid/resourceVersion/generation for state reconstruction
  • Filter by ownerReferences: Exclude resources managed by controllers (Pods, ReplicaSets, ServiceAccounts created by Deployments/Gateways) - they're recreated automatically when you apply the parent resource

Future Work

Phase 2: Automated collection for CI failures
Implement automated collection and Report Portal integration:

  1. testsuite

    • Add --collect-resources-on-failure flag (collect only failed tests)
    • Output to $WORKSPACE/debug-resources/ (Tekton shared workspace)
  2. testsuite-rptool

    • Add rptool attach --dir debug-resources/ after write step
    • Matches failed tests in Report Portal, uploads YAML as attachments
  3. testsuite-pipelines

    • Integrate both in nightly job (run-tests + rptool-upload tasks)

Result: Failed test in RP → Logs tab → downloadable YAML

Uses Tekton workspace (like JUnit XML already does) — YAML persists on shared PVC between tasks.

This addresses issue #861 by providing an automated way to collect test resources without manually stopping tests and copying resources.

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The test suite adds optional Kubernetes resource collection. A pytest option enables the feature, and an autouse fixture invokes collection after each test. Matching resources are discovered, filtered, sanitised, and written as YAML.

Changes

Resource collection

Layer / File(s) Summary
Kubernetes resource collector
testsuite/utils/resource_collector.py
Adds optional resource discovery, module-level deduplication, resource matching, metadata removal, YAML output, and failure handling.
Pytest collection integration
testsuite/tests/conftest.py
Adds the --collect-resources option and an autouse fixture that invokes collection.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Pytest
  participant collect_resources
  participant KubernetesAPI
  participant DebugResources
  Pytest->>collect_resources: invoke after each test
  collect_resources->>KubernetesAPI: discover and retrieve resources
  collect_resources->>DebugResources: write matching resources as YAML
Loading

Suggested reviewers: averevki, azgabur

Poem

I hop through tests with a careful sweep,
Find cluster traces the modules keep.
YAML bundles land in a tidy row,
While noisy metadata fades below.
“Collect resources!” the rabbit sings,
And bounds away on debugging springs.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title uses the required Conventional Commits format and clearly describes the main change: adding a test resource collector utility for debugging failures.
Description check ✅ Passed The description explains the purpose, lists the main features, documents usage, and provides verification commands and results. It does not use the exact template headings for Description and Changes,…
Full details: Description check

Explanation

The description explains the purpose, lists the main features, documents usage, and provides verification commands and results. It does not use the exact template headings for Description and Changes, but it contains the required information and is sufficiently complete.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@fabikova
fabikova requested review from averevki and azgabur August 5, 2026 14:59
@fabikova
fabikova force-pushed the feature/861-test-resources-utility branch from d23c7d6 to 68b7dfe Compare August 6, 2026 08:16

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
testsuite/tests/conftest.py (1)

462-466: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Align the fixture docstring with the actual behaviour.

The fixture is function-scoped, so it runs after each test, not after all tests in the module. The collector then skips repeated calls. State this in the docstring so the scope choice stays clear to maintainers.

♻️ Proposed docstring change
 `@pytest.fixture`(scope="function", autouse=True)
 def collect_test_resources(request, module_label):
-    """Collect module resources after all tests in the module finish."""
+    """Collect module resources after each test.
+
+    The scope is function so that teardown runs before module-scoped fixtures
+    delete the resources. The collector skips repeated collection per module.
+    """
     yield
     collect_resources(request.node, module_label)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@testsuite/tests/conftest.py` around lines 462 - 466, Update the docstring of
collect_test_resources to state that it collects module resources after each
test, with repeated calls skipped by the collector.
testsuite/utils/resource_collector.py (1)

129-140: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Log the failure when the get call does not succeed.

If result.status() is not 0, the code writes a file that states "No matching resources found". A user cannot distinguish an empty result from a failed query. The single get with all discovered types is also likely to fail on large clusters, because one unknown or forbidden type makes the whole call fail.

Log the non-zero status and the stderr output.

♻️ Proposed change to report query failures
     result = invoke("get", [",".join(resource_types), "--ignore-not-found", "-n", project, "-o", "yaml"])
 
-    if result.status() == 0 and result.out().strip():
+    if result.status() != 0:
+        logger.warning("Resource query failed with status %s: %s", result.status(), result.err())
+    elif result.out().strip():
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@testsuite/utils/resource_collector.py` around lines 129 - 140, Update the
resource query handling around invoke and result.status() to log non-zero query
failures, including the status code and result.err() output, before continuing
to write the no-matching-resources result. Preserve the existing successful YAML
parsing and matching behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@testsuite/utils/resource_collector.py`:
- Around line 74-75: Sanitize both file-name components used to construct
base_filename in the resource collection helper, especially item.name, replacing
path separators and other unsafe characters with a safe substitute before
building the debug-resources path. Preserve readable uniqueness for parametrized
test IDs and ensure the resulting path can be opened without triggering the
warning-handling path.
- Around line 46-57: Update the de-duplication logic in the resource collection
function to check and store the full module_label in _collected_modules. Keep
base_pattern calculation for resource metadata matching, but pass base_pattern
only to _save_matching_resources (or the equivalent resource-matching helper),
not as the collected-module key.

---

Nitpick comments:
In `@testsuite/tests/conftest.py`:
- Around line 462-466: Update the docstring of collect_test_resources to state
that it collects module resources after each test, with repeated calls skipped
by the collector.

In `@testsuite/utils/resource_collector.py`:
- Around line 129-140: Update the resource query handling around invoke and
result.status() to log non-zero query failures, including the status code and
result.err() output, before continuing to write the no-matching-resources
result. Preserve the existing successful YAML parsing and matching behavior.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 59ee4655-8c50-4338-afe5-0466da9562ab

📥 Commits

Reviewing files that changed from the base of the PR and between f9f0a17 and 68b7dfe.

📒 Files selected for processing (2)
  • testsuite/tests/conftest.py
  • testsuite/utils/resource_collector.py

Comment thread testsuite/utils/resource_collector.py Outdated
Comment thread testsuite/utils/resource_collector.py Outdated
@fabikova fabikova added the enhancement Improvement to the testsuite or the existing test label Aug 6, 2026
@github-project-automation github-project-automation Bot moved this to 🆕 New in Kuadrant QE Aug 6, 2026
@fabikova fabikova self-assigned this Aug 6, 2026
@fabikova
fabikova marked this pull request as draft August 6, 2026 09:17
@fabikova fabikova moved this to Ready For Review in Kuadrant Aug 6, 2026
@fabikova fabikova added this to Kuadrant Aug 6, 2026
@fabikova fabikova removed this from Kuadrant Aug 6, 2026
@fabikova fabikova moved this from 🆕 New to 🏗 In progress in Kuadrant QE Aug 6, 2026
@fabikova
fabikova force-pushed the feature/861-test-resources-utility branch 3 times, most recently from b6f832f to b0846ae Compare August 6, 2026 10:20
@fabikova
fabikova marked this pull request as ready for review August 6, 2026 10:22
@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@testsuite/utils/resource_collector.py`:
- Around line 54-58: Update collect_resources() and _save_resources() so
_save_resources() returns an explicit success result and propagates Kubernetes
query, yaml.YAMLError, and file-writing failures without writing the no-match
marker. Record module_label in _collected_modules only after _save_resources()
successfully completes discovery, querying, parsing, and output writing;
preserve the no-match marker only for successful queries with no matching
resources.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 0e0db25f-bb24-4c3f-b529-6ff22c006063

📥 Commits

Reviewing files that changed from the base of the PR and between d5e0d81 and b0846ae.

📒 Files selected for processing (2)
  • testsuite/tests/conftest.py
  • testsuite/utils/resource_collector.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • testsuite/tests/conftest.py

Comment thread testsuite/utils/resource_collector.py Outdated
@fabikova
fabikova force-pushed the feature/861-test-resources-utility branch from b0846ae to 602022b Compare August 6, 2026 12:32
@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
testsuite/utils/resource_collector.py (1)

95-97: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Narrow the pylint suppression at the collection boundary.

except Exception maps configuration, Kubernetes, YAML, and filesystem failures to one warning. Catch expected failures at the smallest scope. Retain a final broad catch only if the optional collector must never fail the test run, and document that boundary.

As per coding guidelines, always look for a more correct solution before disabling a pylint warning.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@testsuite/utils/resource_collector.py` around lines 95 - 97, Refine the
exception handling in the resource collection function around the broad `except
Exception`: catch expected configuration, Kubernetes, YAML, and filesystem
exceptions at their smallest applicable scopes, removing the broad pylint
suppression. Retain a final broad catch only if the optional collector must not
fail tests, and document that boundary clearly.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@testsuite/utils/resource_collector.py`:
- Around line 61-66: The _discover_resource_types and _save_resources flow must
avoid combining forbidden resource types into one list request. Check list
permission for each discovered type before constructing the combined query, or
invoke each type independently, while preserving successful collection for
permitted types and ensuring denied types do not prevent the resource file from
being saved.

---

Nitpick comments:
In `@testsuite/utils/resource_collector.py`:
- Around line 95-97: Refine the exception handling in the resource collection
function around the broad `except Exception`: catch expected configuration,
Kubernetes, YAML, and filesystem exceptions at their smallest applicable scopes,
removing the broad pylint suppression. Retain a final broad catch only if the
optional collector must not fail tests, and document that boundary clearly.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: cbf38e81-0aad-4376-9dfa-daf224681be9

📥 Commits

Reviewing files that changed from the base of the PR and between d5e0d81 and 602022b.

📒 Files selected for processing (2)
  • testsuite/tests/conftest.py
  • testsuite/utils/resource_collector.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • testsuite/tests/conftest.py

Comment thread testsuite/utils/resource_collector.py Outdated
Signed-off-by: Martina Fabikova <mfabikov@redhat.com>
@fabikova
fabikova force-pushed the feature/861-test-resources-utility branch from 602022b to 0761264 Compare August 6, 2026 14:01
@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

Signed-off-by: Martina Fabikova <mfabikov@redhat.com>
Signed-off-by: Martina Fabikova <mfabikov@redhat.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement Improvement to the testsuite or the existing test

Projects

Status: 🏗 In progress

Development

Successfully merging this pull request may close these issues.

1 participant