Skip to content

Conversation

@rnetser
Copy link
Collaborator

@rnetser rnetser commented Aug 28, 2025

Short description:

In the current implementation, an installed knmstate operator is a requirement.
The knmstate operator is not required:

  • when using cloud-based clusters
  • By any sig besides the network sig

The following changes have been made to drop the dependency on the operator when not needed:

  • As part of cluster_health_check, test_pod_sanity will only verify HCO pods
  • Network network_sanity was updated to check knmstate running pods it the namespace exists.
  • Added some TODO tasks to follow up by network sig
More details:
What this PR does / why we need it:
Which issue(s) this PR fixes:
Special notes for reviewer:
jira-ticket:

Summary by CodeRabbit

  • Tests
    • Pod sanity validation now focuses on HCO namespace verification only
    • Enhanced network sanity checks to include NMState pod readiness verification
    • Improved test flexibility for deployments without NMState namespace support
    • Better namespace handling with graceful fallback when NMState is unavailable

@coderabbitai
Copy link

coderabbitai bot commented Aug 28, 2025

Walkthrough

Refactors NMState namespace handling to be optional rather than required. Removes the nmstate_required fixture, makes the nmstate_namespace fixture gracefully handle missing NMState environments via try/except, narrows pod sanity checks to HCO namespace only, updates network test fixtures to support optional NMState verification, and introduces the OPENSHIFT_NMSTATE constant for namespace configuration.

Changes

Cohort / File(s) Summary
NMState namespace fixture refactoring
tests/conftest.py
Removed nmstate_required fixture; refactored nmstate_namespace signature from (admin_client, nmstate_required) to (admin_client); replaced conditional logic with try/except block to return Namespace or None when NMState is unavailable; added logging for missing namespace.
Pod sanity test narrowing
tests/after_cluster_deploy_sanity/test_after_cluster_deploy_sanity.py
Narrowed test_pod_sanity to check only HCO namespace; removed nmstate_namespace parameter and multi-namespace loop; now calls wait_for_pods_running once per HCO namespace.
Network test fixture updates
tests/network/conftest.py
Extended network_sanity fixture signature to include admin_client and nmstate_namespace parameters; added new internal _verify_nmstate_running_pods() function to validate NMState pod readiness; refactored _verify_multi_nic parameter from request to _request; added imports for TimeoutExpiredError, wait_for_pods_running, and NamespacesNames.
Constants and configuration
utilities/constants.py, conftest.py
Added OPENSHIFT_NMSTATE = "openshift-nmstate" constant to NamespacesNames class; updated root conftest.py to use constant reference instead of string literal in NAMESPACE_COLLECTION; refactored get_inspect_command_namespace_string to avoid mutating global collection; implemented lazy evaluation via walrus assignment in pytest_exception_interact.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Fixture refactoring from conditional to try/except pattern requires verification that graceful None handling is correctly propagated through dependent tests
  • _verify_nmstate_running_pods logic depends on wait_for_pods_running behavior and TimeoutExpiredError handling; confirm timeout semantics align with intent
  • Multiple signature changes across fixtures demand cross-referencing to ensure all call sites are updated consistently
  • Lazy evaluation in pytest_exception_interact changes control flow; verify walrus assignment doesn't mask exceptions or defer side effects unexpectedly

Possibly related PRs

Suggested reviewers

  • EdDev
  • dshchedr
  • RoniKishner
  • yossisegev
  • Anatw
  • vsibirsk
  • geetikakay

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 35.71% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed The pull request title accurately captures the main objectives of the changeset. It specifically identifies that nmstate namespace checks are being moved to network sanity checks and that nodes_active_nics behavior is being adjusted for cloud clusters. The changes in the raw summary align with these stated goals: test_pod_sanity is narrowed to HCO namespace, nmstate_namespace fixture is refactored to handle optional namespaces, network_sanity fixture is extended to accept admin_client and nmstate_namespace parameters, and a new _verify_nmstate_running_pods function is added for conditional nmstate validation. While the title is lengthy, it is clear and specific enough for teammates reviewing the history to understand the primary changes.
Description Check ✅ Passed The pull request description provides substantive content in the "Short description" section, which explains the rationale for removing the knmstate operator dependency (not needed for cloud clusters or non-network SIGs) and lists three specific changes made. This core information addresses what the PR does and why it is needed. However, most template sections including "More details," "What this PR does / why we need it," "Which issue(s) this PR fixes," "Special notes for reviewer," and "jira-ticket" are left empty or unfilled. The provided content in the short description section is sufficient to convey the primary intent, though the description could be more comprehensive across all template sections.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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 and usage tips.

@openshift-virtualization-qe-bot

Report bugs in Issues

Welcome! 🎉

This pull request will be automatically processed with the following features:

🔄 Automatic Actions

  • Reviewer Assignment: Reviewers are automatically assigned based on the OWNERS file in the repository root
  • Size Labeling: PR size labels (XS, S, M, L, XL, XXL) are automatically applied based on changes
  • Issue Creation: A tracking issue is created for this PR and will be closed when the PR is merged or closed
  • Pre-commit Checks: pre-commit runs automatically if .pre-commit-config.yaml exists
  • Branch Labeling: Branch-specific labels are applied to track the target branch
  • Auto-verification: Auto-verified users have their PRs automatically marked as verified

📋 Available Commands

PR Status Management

  • /wip - Mark PR as work in progress (adds WIP: prefix to title)
  • /wip cancel - Remove work in progress status
  • /hold - Block PR merging (approvers only)
  • /hold cancel - Unblock PR merging
  • /verified - Mark PR as verified
  • /verified cancel - Remove verification status

Review & Approval

  • /lgtm - Approve changes (looks good to me)
  • /approve - Approve PR (approvers only)
  • /automerge - Enable automatic merging when all requirements are met (maintainers and approvers only)
  • /assign-reviewers - Assign reviewers based on OWNERS file
  • /assign-reviewer @username - Assign specific reviewer
  • /check-can-merge - Check if PR meets merge requirements

Testing & Validation

  • /retest tox - Run Python test suite with tox
  • /retest build-container - Rebuild and test container image
  • /retest all - Run all available tests

Container Operations

  • /build-and-push-container - Build and push container image (tagged with PR number)
    • Supports additional build arguments: /build-and-push-container --build-arg KEY=value

Cherry-pick Operations

  • /cherry-pick <branch> - Schedule cherry-pick to target branch when PR is merged
    • Multiple branches: /cherry-pick branch1 branch2 branch3

Label Management

  • /<label-name> - Add a label to the PR
  • /<label-name> cancel - Remove a label from the PR

✅ Merge Requirements

This PR will be automatically approved when the following conditions are met:

  1. Approval: /approve from at least one approver
  2. LGTM Count: Minimum 2 /lgtm from reviewers
  3. Status Checks: All required status checks must pass
  4. No Blockers: No WIP, hold, or conflict labels
  5. Verified: PR must be marked as verified (if verification is enabled)

📊 Review Process

Approvers and Reviewers

Approvers:

  • EdDev
  • dshchedr
  • dshchedr
  • myakove
  • rnetser
  • rnetser
  • vsibirsk
  • vsibirsk

Reviewers:

  • Anatw
  • EdDev
  • RoniKishner
  • RoniKishner
  • dshchedr
  • dshchedr
  • geetikakay
  • rnetser
  • rnetser
  • servolkov
  • vsibirsk
  • vsibirsk
  • yossisegev
Available Labels
  • hold
  • verified
  • wip
  • lgtm
  • approve
  • automerge

💡 Tips

  • WIP Status: Use /wip when your PR is not ready for review
  • Verification: The verified label is automatically removed on each new commit
  • Cherry-picking: Cherry-pick labels are processed when the PR is merged
  • Container Builds: Container images are automatically tagged with the PR number
  • Permission Levels: Some commands require approver permissions
  • Auto-verified Users: Certain users have automatic verification and merge privileges

For more information, please refer to the project documentation or contact the maintainers.

@rnetser
Copy link
Collaborator Author

rnetser commented Aug 28, 2025

/build-and-push-container

@codecov
Copy link

codecov bot commented Aug 28, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
⚠️ Please upload report for BASE (main@2f8d7b7). Learn more about missing BASE report.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #1904   +/-   ##
=======================================
  Coverage        ?   93.54%           
=======================================
  Files           ?       16           
  Lines           ?     1347           
  Branches        ?        0           
=======================================
  Hits            ?     1260           
  Misses          ?       87           
  Partials        ?        0           
Flag Coverage Δ
utilities 93.54% <100.00%> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@openshift-virtualization-qe-bot-3
Copy link
Contributor

New container for quay.io/openshift-cnv/openshift-virtualization-tests:pr-1904 published

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
tests/network/conftest.py (1)

221-234: Add missing is_baremetal_or_psi_cluster parameter to gate BM/PSI-specific checks.

The PR objectives state: "network_sanity updated to check multi-NIC and nmstate installation only on Bare Metal (BM) and PSI clusters." However, the fixture signature is missing the is_baremetal_or_psi_cluster parameter needed to implement cluster-type conditional logic.

Apply this diff to add the missing parameter:

 @pytest.fixture(scope="session", autouse=True)
 def network_sanity(
     admin_client,
     hosts_common_available_ports,
     junitxml_plugin,
     request,
     istio_system_namespace,
     cluster_network_mtu,
     network_overhead,
     sriov_workers,
     ipv4_supported_cluster,
     ipv6_supported_cluster,
     conformance_tests,
     nmstate_namespace,
+    is_baremetal_or_psi_cluster,
 ):
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f5d63e8 and 1c0e886.

📒 Files selected for processing (1)
  • tests/network/conftest.py (6 hunks)
🧰 Additional context used
🧠 Learnings (5)
📓 Common learnings
Learnt from: rnetser
PR: RedHatQE/openshift-virtualization-tests#0
File: :0-0
Timestamp: 2025-09-29T19:05:24.987Z
Learning: For PR #1904 test execution, the critical validation point is test_connectivity_over_migration_between_localnet_vms which should fail gracefully on cloud clusters but pass on bare-metal/PSI clusters, representing the core nmstate conditional logic functionality.
Learnt from: rnetser
PR: RedHatQE/openshift-virtualization-tests#0
File: :0-0
Timestamp: 2025-09-29T19:05:24.987Z
Learning: The test execution plan for PR #1904 focuses on cluster-type conditional logic where nmstate functionality is bypassed on cloud clusters (Azure/AWS) but fully functional on bare-metal/PSI clusters, requiring different test strategies for each environment type.
Learnt from: dshchedr
PR: RedHatQE/openshift-virtualization-tests#1840
File: tests/virt/node/workload_density/test_swap.py:88-89
Timestamp: 2025-08-20T23:57:48.380Z
Learning: In the RedHatQE/openshift-virtualization-tests repository, CNV installation and health are verified by sanity tests before other tests run, so hco_namespace is guaranteed to exist in the testing environment. Defensive programming against nil hco_namespace scenarios is not needed in fixtures.
📚 Learning: 2025-09-02T11:18:02.529Z
Learnt from: rnetser
PR: RedHatQE/openshift-virtualization-tests#1904
File: tests/network/conftest.py:319-325
Timestamp: 2025-09-02T11:18:02.529Z
Learning: In tests/network/conftest.py, for the _verify_nmstate_running_pods function, the user rnetser prefers a simple approach of just logging the result from wait_for_pods_running rather than implementing complex logic to distinguish between None and empty list returns.

Applied to files:

  • tests/network/conftest.py
📚 Learning: 2025-09-02T11:16:59.950Z
Learnt from: rnetser
PR: RedHatQE/openshift-virtualization-tests#1904
File: tests/conftest.py:589-593
Timestamp: 2025-09-02T11:16:59.950Z
Learning: In tests/conftest.py, for non-baremetal/PSI clusters in the nodes_active_nics fixture, the user prefers to populate the "occupied" field with actual physical NICs from node_physical_nics rather than leaving it empty, to provide downstream consumers with visibility into physical NIC inventory even when NMState isn't managing them.

Applied to files:

  • tests/network/conftest.py
📚 Learning: 2025-09-29T19:05:24.987Z
Learnt from: rnetser
PR: RedHatQE/openshift-virtualization-tests#0
File: :0-0
Timestamp: 2025-09-29T19:05:24.987Z
Learning: For PR #1904 test execution, the critical validation point is test_connectivity_over_migration_between_localnet_vms which should fail gracefully on cloud clusters but pass on bare-metal/PSI clusters, representing the core nmstate conditional logic functionality.

Applied to files:

  • tests/network/conftest.py
📚 Learning: 2025-09-29T19:05:24.987Z
Learnt from: rnetser
PR: RedHatQE/openshift-virtualization-tests#0
File: :0-0
Timestamp: 2025-09-29T19:05:24.987Z
Learning: The test execution plan for PR #1904 focuses on cluster-type conditional logic where nmstate functionality is bypassed on cloud clusters (Azure/AWS) but fully functional on bare-metal/PSI clusters, requiring different test strategies for each environment type.

Applied to files:

  • tests/network/conftest.py
🧬 Code graph analysis (1)
tests/network/conftest.py (3)
utilities/constants.py (1)
  • NamespacesNames (689-703)
utilities/infra.py (1)
  • wait_for_pods_running (320-365)
tests/conftest.py (3)
  • admin_client (307-311)
  • nmstate_namespace (2864-2870)
  • namespace (665-678)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
  • GitHub Check: can-be-merged
  • GitHub Check: can-be-merged
  • GitHub Check: can-be-merged
  • GitHub Check: can-be-merged
  • GitHub Check: can-be-merged
  • GitHub Check: build-container
  • GitHub Check: tox
  • GitHub Check: can-be-merged
🔇 Additional comments (3)
tests/network/conftest.py (3)

17-17: LGTM: Required imports added correctly.

The new imports (TimeoutExpiredError, NamespacesNames, wait_for_pods_running) are all used in the _verify_nmstate_running_pods function and are correctly sourced.

Also applies to: 29-29, 36-36


363-363: Verify: Should multi-NIC check also be gated by cluster type?

The PR objectives state: "network_sanity updated to check multi-NIC and nmstate installation only on Bare Metal (BM) and PSI clusters." However, _verify_multi_nic is called unconditionally on line 363, while nmstate verification should be cluster-type gated.

The function does have internal marker-based logic (lines 244-256) to skip when single_nic marker is used or for conformance tests, which might make cluster-type gating unnecessary. However, this creates a design inconsistency:

  • Multi-NIC: marker-based gating (internal to function)
  • NMState: cluster-type gating (external, should be added)

Please clarify: Should _verify_multi_nic also be moved inside the is_baremetal_or_psi_cluster conditional block for consistency with the PR objectives, or is the current marker-based approach intentional?


243-243: LGTM: Parameter renamed for clarity.

Renaming the parameter from request to _request helps distinguish it from the outer network_sanity fixture's request parameter, improving code clarity.

@rnetser
Copy link
Collaborator Author

rnetser commented Oct 27, 2025

/build-and-push-container

Copy link
Contributor

@EdDev EdDev left a comment

Choose a reason for hiding this comment

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

Thank you!

/approve

@openshift-virtualization-qe-bot-3
Copy link
Contributor

New container for quay.io/openshift-cnv/openshift-virtualization-tests:pr-1904 published

@rnetser
Copy link
Collaborator Author

rnetser commented Oct 27, 2025

/verified
job 3408 - bm + gating
job 3407 - cloud + "gating and single_nic and not ipv6" without nmstate - all failed on "failed on setup with "NotImplementedError: Couldn't find NodeNetworkState in nmstate.io api group"
(sig network will need to mark nmstate tests with a marker)

@openshift-virtualization-qe-bot-3
Copy link
Contributor

@coderabbitai

Test execution plan request details

As an expert software testing engineer, analyze all modified files in this PR and create a targeted test execution plan.
You will create a change request comment on the 1st line of the 1st file in the pr with the test execution plan.
If you fail to run or post a comment, retry.

Analysis Requirements:

  1. Examine code changes in each modified file
  2. Identify affected code paths, functions, and classes
  3. Analyze pytest-specific elements: fixtures (scope, dependencies), parametrization, markers, conftest changes
  4. Trace test dependencies through imports, shared utilities, and fixture inheritance
  5. Detect new tests introduced in the PR

Your deliverable:
Your change request comment will be based on the following requirements:

Test Execution Plan

  • path/to/test_file.py - When the entire test file needs verification
  • path/to/test_file.py::TestClass::test_method - When specific test(s) needed
  • path/to/test_file.py::test_function - When specific test(s) needed
  • -m marker - When specific marker(s) can be used to cover multiple cases.

Guidelines:

  • Include only tests directly affected by the changes
  • Use a full file path only if ALL tests in that file require verification
  • Use file path + test name if only specific tests are needed
  • If a test marker can cover multiple files/tests, provide the marker
  • Balance coverage vs over-testing - Keep descriptions minimal
  • Do not add a follow-up comment in the PR, only the change request one

@rnetser rnetser dismissed stale reviews from coderabbitai[bot] and myakove October 27, 2025 20:28

test comment

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Test Execution Plan

Directly affected tests:

  • tests/after_cluster_deploy_sanity/test_after_cluster_deploy_sanity.py::test_pod_sanity
  • tests/network/nmstate/test_connectivity_after_nmstate_changes.py
  • tests/network/localnet/test_default_bridge.py
  • tests/network/localnet/test_ovs_bridge.py

Cluster-specific markers:

  • -m "gating and single_nic" - Cloud clusters (Azure/AWS)
  • -m "gating" - Bare-metal/PSI clusters

@dshchedr
Copy link
Collaborator

/approve
/lgtm

coderabbitai[bot]
coderabbitai bot previously requested changes Oct 27, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Test Execution Plan

@coderabbitai
Copy link

coderabbitai bot commented Oct 27, 2025

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Analyze PR #1904 and gather information for test execution plan

echo "=== Step 1: Get modified files in PR #1904 ==="
gh api repos/RedHatQE/openshift-virtualization-tests/pulls/1904/files | jq -r '.[] | "\(.filename) (\(.status)) +\(.additions) -\(.deletions)"'

echo -e "\n=== Step 2: Get first modified file ==="
FIRST_FILE=$(gh api repos/RedHatQE/openshift-virtualization-tests/pulls/1904/files | jq -r '.[0].filename')
echo "First file: $FIRST_FILE"

echo -e "\n=== Step 3: Get commit SHA ==="
COMMIT_SHA=$(gh api repos/RedHatQE/openshift-virtualization-tests/pulls/1904 | jq -r '.head.sha')
echo "Commit SHA: $COMMIT_SHA"

echo -e "\n=== Step 4: Analyze fixture usage ==="
echo "--- Tests using nodes_active_nics ---"
rg -l "nodes_active_nics" tests/ --type=py 2>/dev/null | grep "test_" | head -5

echo -e "\n--- Tests using nmstate_namespace ---"
rg -l "nmstate_namespace" tests/ --type=py 2>/dev/null | grep "test_" | head -5

echo -e "\n--- Tests using network_sanity ---"
rg -l "network_sanity" tests/ --type=py 2>/dev/null | grep "test_" | head -5

echo -e "\n--- test_pod_sanity location ---"
rg -n "def test_pod_sanity" tests/ --type=py 2>/dev/null

echo -e "\n--- Localnet tests ---"
find tests/network/localnet/ -name "test_*.py" 2>/dev/null

echo -e "\n=== Step 5: Get diff for first file ==="
PATCH=$(gh api repos/RedHatQE/openshift-virtualization-tests/commits/$COMMIT_SHA | \
  jq -r ".files[] | select(.filename == \"$FIRST_FILE\") | .patch")

if [ -n "$PATCH" ]; then
  echo "$PATCH" | head -40
  FIRST_CHANGED_LINE=$(echo "$PATCH" | grep "^@@" | head -1 | sed 's/.*+\([0-9]*\),.*/\1/')
  echo -e "\nFirst changed line: $FIRST_CHANGED_LINE"
else
  echo "No patch available"
  FIRST_CHANGED_LINE=""
fi

# Export for next script
echo "$FIRST_FILE" > /tmp/first_file.txt
echo "$COMMIT_SHA" > /tmp/commit_sha.txt
echo "$FIRST_CHANGED_LINE" > /tmp/first_line.txt

echo -e "\n=== Summary ==="
echo "First file: $FIRST_FILE"
echo "Commit: $COMMIT_SHA"
echo "Line: $FIRST_CHANGED_LINE"

Length of output: 1074


🏁 Script executed:

#!/bin/bash
# Post test execution plan as change request review

FIRST_FILE=$(cat /tmp/first_file.txt 2>/dev/null)
COMMIT_SHA=$(cat /tmp/commit_sha.txt 2>/dev/null)
FIRST_CHANGED_LINE=$(cat /tmp/first_line.txt 2>/dev/null)

# Create minimal test execution plan
TEST_PLAN="## Test Execution Plan

**Directly affected tests:**
- \`tests/after_cluster_deploy_sanity/test_after_cluster_deploy_sanity.py::test_pod_sanity\`
- \`tests/network/nmstate/test_connectivity_after_nmstate_changes.py\`
- \`tests/network/localnet/test_default_bridge.py\`
- \`tests/network/localnet/test_ovs_bridge.py\`

**Cluster-specific markers:**
- \`-m \"gating and single_nic\"\` - Cloud clusters (Azure/AWS)
- \`-m \"gating\"\` - Bare-metal/PSI clusters"

echo "=== Test Execution Plan ==="
echo "$TEST_PLAN"
echo ""
echo "File: $FIRST_FILE"
echo "Commit: $COMMIT_SHA"
echo "Line: $FIRST_CHANGED_LINE"

# Try inline comment first
if [ -n "$FIRST_CHANGED_LINE" ] && [ "$FIRST_CHANGED_LINE" != "null" ] && [ "$FIRST_CHANGED_LINE" -gt 0 ] 2>/dev/null; then
  echo -e "\n=== Attempting inline comment on line $FIRST_CHANGED_LINE ==="
  RESULT=$(gh api \
    --method POST \
    -H "Accept: application/vnd.github+json" \
    repos/RedHatQE/openshift-virtualization-tests/pulls/1904/reviews \
    -f body="Test Execution Plan" \
    -f event='REQUEST_CHANGES' \
    -f commit_id="$COMMIT_SHA" \
    -F comments[][path]="$FIRST_FILE" \
    -F comments[][line]="$FIRST_CHANGED_LINE" \
    -f comments[][side]='RIGHT' \
    -f comments[][body]="$TEST_PLAN" 2>&1)
  
  if echo "$RESULT" | jq -e '.id' >/dev/null 2>&1; then
    echo "✓ Inline review posted successfully"
    echo "$RESULT" | jq -r '{review_id: .id, state: .state, submitted_at: .submitted_at}'
    exit 0
  else
    echo "✗ Inline failed: $RESULT"
  fi
fi

# Fallback to general review
echo -e "\n=== Posting as general review ==="
gh api \
  --method POST \
  -H "Accept: application/vnd.github+json" \
  repos/RedHatQE/openshift-virtualization-tests/pulls/1904/reviews \
  -f body="$TEST_PLAN" \
  -f event='REQUEST_CHANGES' \
  -f commit_id="$COMMIT_SHA" | \
  jq -r '{review_id: .id, state: .state, submitted_at: .submitted_at}'

echo -e "\n=== Verification ==="
gh api repos/RedHatQE/openshift-virtualization-tests/pulls/1904/reviews | \
  jq -r '.[-1] | {id: .id, state: .state, user: .user.login, submitted_at: .submitted_at}'

Length of output: 825


@openshift-virtualization-qe-bot-3 Acknowledged. I’ll post a CHANGES_REQUESTED inline comment on the first modified file with the minimal Test Execution Plan now. I leveraged our stored learnings about nmstate gating and the critical localnet migration test to keep coverage tight.


🏁 Script executed:

#!/bin/bash
set -euo pipefail

PR="1904"
REPO="RedHatQE/openshift-virtualization-tests"

# 1) Identify first modified file and get head SHA
FIRST_FILE=$(gh api repos/$REPO/pulls/$PR/files --jq '.[0].filename')
HEAD_SHA=$(gh api repos/$REPO/pulls/$PR --jq '.head.sha')

# 2) Get PR-level patch for the first file and compute first new-line from @@ hunk
PATCH=$(gh api repos/$REPO/pulls/$PR/files --jq ".[] | select(.filename==\"$FIRST_FILE\") | .patch" || true)

if [[ -z "${PATCH:-}" || "${PATCH}" == "null" ]]; then
  # As a fallback, try commit-level patch for the head sha
  PATCH=$(gh api repos/$REPO/commits/$HEAD_SHA --jq ".files[] | select(.filename==\"$FIRST_FILE\") | .patch" || true)
fi

# Compute first new line number to place inline comment on RIGHT side
NEWLINE=""
if [[ -n "${PATCH:-}" && "${PATCH}" != "null" ]]; then
  NEWLINE=$(printf "%s\n" "$PATCH" | grep -m1 -oE '\+\d+(,\d+)?' | sed 's/^\+\([0-9]\+\).*/\1/')
fi

# Build minimal test execution plan (title + bullets only)
read -r -d '' TEST_PLAN <<'EOF'
Test Execution Plan
- tests/after_cluster_deploy_sanity/test_after_cluster_deploy_sanity.py::test_pod_sanity
- tests/network/nmstate/test_connectivity_after_nmstate_changes.py
- tests/network/localnet/test_default_bridge.py::test_connectivity_over_migration_between_localnet_vms
- tests/network/localnet/test_ovs_bridge.py::test_connectivity_after_interface_state_change_in_ovs_bridge_localnet_vms
- -m "gating and single_nic"
- -m "gating"
EOF

# 3) Try posting inline review on first hunk new-line; if missing, default to 1
if [[ -z "${NEWLINE:-}" ]]; then
  NEWLINE="1"
fi

# Primary attempt: inline using line + side RIGHT
POST_RESULT=$(
  gh api \
    --method POST \
    -H "Accept: application/vnd.github+json" \
    repos/$REPO/pulls/$PR/reviews \
    -f body="Test Execution Plan" \
    -f event='REQUEST_CHANGES' \
    -f commit_id="$HEAD_SHA" \
    -F comments[][path]="$FIRST_FILE" \
    -F comments[][line]="$NEWLINE" \
    -f comments[][side]='RIGHT' \
    -f comments[][body]="$TEST_PLAN" 2>&1 \
  || true
)

# Detect failure (non-JSON or missing id); if failed, retry with position=1
if ! printf "%s" "$POST_RESULT" | jq -e '.id' >/dev/null 2>&1; then
  # Retry using position=1 (diff-based position)
  gh api \
    --method POST \
    -H "Accept: application/vnd.github+json" \
    repos/$REPO/pulls/$PR/reviews \
    -f body="Test Execution Plan" \
    -f event='REQUEST_CHANGES' \
    -f commit_id="$HEAD_SHA" \
    -F comments[][path]="$FIRST_FILE" \
    -F comments[][position]=1 \
    -f comments[][body]="$TEST_PLAN" \
    | jq -r '{review_id: .id, state: .state, submitted_at: .submitted_at}'
else
  printf "%s\n" "$POST_RESULT" | jq -r '{review_id: .id, state: .state, submitted_at: .submitted_at}'
fi

Length of output: 0


🏁 Script executed:

#!/bin/bash
set -euo pipefail

PR="1904"
REPO="RedHatQE/openshift-virtualization-tests"

echo "=== Discover first modified file and head SHA ==="
FIRST_FILE=$(gh api repos/$REPO/pulls/$PR/files --jq '.[0].filename')
HEAD_SHA=$(gh api repos/$REPO/pulls/$PR --jq '.head.sha')
echo "First file: $FIRST_FILE"
echo "Head SHA:   $HEAD_SHA"

echo "=== Extract first changed line using unified diff ==="
DIFF=$(gh pr diff $PR --patch --path "$FIRST_FILE" || true)
if [[ -n "${DIFF:-}" ]]; then
  echo "Got diff for $FIRST_FILE"
  echo "$DIFF" | sed -n '1,80p'
  NEWLINE=$(echo "$DIFF" | awk '/^@@ /{ if (match($0, /\+([0-9]+)/, a)) { print a[1]; exit } }')
else
  echo "No diff from gh pr diff; defaulting NEWLINE=1"
  NEWLINE=""
fi

if [[ -z "${NEWLINE:-}" ]]; then
  NEWLINE="1"
fi
echo "First changed new-file line: $NEWLINE"

# Minimal test execution plan (title + bullets)
read -r -d '' TEST_PLAN <<'EOF'
Test Execution Plan
- tests/after_cluster_deploy_sanity/test_after_cluster_deploy_sanity.py::test_pod_sanity
- tests/network/nmstate/test_connectivity_after_nmstate_changes.py
- tests/network/localnet/test_default_bridge.py::test_connectivity_over_migration_between_localnet_vms
- -m "gating and single_nic"
- -m "gating"
EOF

echo "=== Attempt inline CHANGES_REQUESTED review on $FIRST_FILE:$NEWLINE ==="
POST=$(gh api \
  --method POST \
  -H "Accept: application/vnd.github+json" \
  repos/$REPO/pulls/$PR/reviews \
  -f body="Test Execution Plan" \
  -f event='REQUEST_CHANGES' \
  -f commit_id="$HEAD_SHA" \
  -F comments[][path]="$FIRST_FILE" \
  -F comments[][line]="$NEWLINE" \
  -f comments[][side]='RIGHT' \
  -f comments[][body]="$TEST_PLAN" 2>&1) || true

# If inline failed, retry using diff position=1
if ! echo "$POST" | jq -e '.id' >/dev/null 2>&1; then
  echo "Inline by line failed; retry with position=1"
  POST=$(gh api \
    --method POST \
    -H "Accept: application/vnd.github+json" \
    repos/$REPO/pulls/$PR/reviews \
    -f body="Test Execution Plan" \
    -f event='REQUEST_CHANGES' \
    -f commit_id="$HEAD_SHA" \
    -F comments[][path]="$FIRST_FILE" \
    -F comments[][position]=1 \
    -f comments[][body]="$TEST_PLAN" 2>&1) || true
fi

# If still no id, fallback to a general CHANGES_REQUESTED review (last resort)
if ! echo "$POST" | jq -e '.id' >/dev/null 2>&1; then
  echo "Both inline methods failed; posting general REQUEST_CHANGES review"
  POST=$(gh api \
    --method POST \
    -H "Accept: application/vnd.github+json" \
    repos/$REPO/pulls/$PR/reviews \
    -f body="$TEST_PLAN" \
    -f event='REQUEST_CHANGES' \
    -f commit_id="$HEAD_SHA")
fi

echo "$POST" | jq -r '{review_id: .id, state: .state, submitted_at: .submitted_at}'

Length of output: 609


🏁 Script executed:

#!/bin/bash
set -euo pipefail

PR="1904"
REPO="RedHatQE/openshift-virtualization-tests"

echo "=== Identify first modified file and SHAs ==="
FIRST_FILE=$(gh api repos/$REPO/pulls/$PR/files --jq '.[0].filename')
BASE_SHA=$(gh api repos/$REPO/pulls/$PR --jq '.base.sha')
HEAD_SHA=$(gh api repos/$REPO/pulls/$PR --jq '.head.sha')
echo "First file: $FIRST_FILE"
echo "Base SHA:   $BASE_SHA"
echo "Head SHA:   $HEAD_SHA"

echo "=== Fetch patch from compare API and compute first new-file line ==="
PATCH=$(gh api repos/$REPO/compare/$BASE_SHA...$HEAD_SHA --jq ".files[] | select(.filename==\"$FIRST_FILE\") | .patch" || true)
if [[ -z "${PATCH:-}" || "${PATCH}" == "null" ]]; then
  echo "No patch found via compare API for $FIRST_FILE"
  NEWLINE="1"
else
  echo "Patch header (first 40 lines):"
  echo "$PATCH" | sed -n '1,40p'
  # Parse first @@ hunk header to extract +<new-start>
  NEWLINE=$(echo "$PATCH" | awk '/^@@ /{ if (match($0, /\+([0-9]+)/, a)) { print a[1]; exit } }')
  if [[ -z "${NEWLINE:-}" ]]; then
    NEWLINE="1"
  fi
fi
echo "First changed new-file line: $NEWLINE"

# Minimal, strictly formatted plan: title + bullets only
read -r -d '' TEST_PLAN <<'EOF'
Test Execution Plan
- tests/after_cluster_deploy_sanity/test_after_cluster_deploy_sanity.py::test_pod_sanity
- tests/network/nmstate/test_connectivity_after_nmstate_changes.py
- tests/network/localnet/test_default_bridge.py::test_connectivity_over_migration_between_localnet_vms
- -m "gating and single_nic"
- -m "gating"
EOF

echo "=== Attempt inline CHANGES_REQUESTED review on $FIRST_FILE:$NEWLINE ==="
POST=$(gh api \
  --method POST \
  -H "Accept: application/vnd.github+json" \
  repos/$REPO/pulls/$PR/reviews \
  -f body="Test Execution Plan" \
  -f event='REQUEST_CHANGES' \
  -f commit_id="$HEAD_SHA" \
  -F comments[][path]="$FIRST_FILE" \
  -F comments[][line]="$NEWLINE" \
  -f comments[][side]='RIGHT' \
  -f comments[][body]="$TEST_PLAN" 2>&1) || true

if ! echo "$POST" | jq -e '.id' >/dev/null 2>&1; then
  echo "Inline by line failed; retry with diff position=1"
  POST=$(gh api \
    --method POST \
    -H "Accept: application/vnd.github+json" \
    repos/$REPO/pulls/$PR/reviews \
    -f body="Test Execution Plan" \
    -f event='REQUEST_CHANGES' \
    -f commit_id="$HEAD_SHA" \
    -F comments[][path]="$FIRST_FILE" \
    -F comments[][position]=1 \
    -f comments[][body]="$TEST_PLAN" 2>&1) || true
fi

if ! echo "$POST" | jq -e '.id' >/dev/null 2>&1; then
  echo "Both inline methods failed; posting general REQUEST_CHANGES review (last resort)"
  POST=$(gh api \
    --method POST \
    -H "Accept: application/vnd.github+json" \
    repos/$REPO/pulls/$PR/reviews \
    -f body="$TEST_PLAN" \
    -f event='REQUEST_CHANGES' \
    -f commit_id="$HEAD_SHA")
fi

echo "=== Result ==="
echo "$POST" | jq -r '{review_id: .id, state: .state, submitted_at: .submitted_at}'

Length of output: 2248


@openshift-virtualization-qe-bot-3 I’ve attempted to post the required CHANGES_REQUESTED inline comment at the first line (diff position=1) of the first modified file with the minimal Test Execution Plan. If inline placement was not possible due to API constraints, I retried with the first changed line and finally as a general change request to ensure the plan is attached to the PR.


🏁 Script executed:

#!/bin/bash
set -euo pipefail

PR="1904"
REPO="RedHatQE/openshift-virtualization-tests"

echo "=== Prepare context ==="
FIRST_FILE=$(gh api repos/$REPO/pulls/$PR/files --jq '.[0].filename')
BASE_SHA=$(gh api repos/$REPO/pulls/$PR --jq '.base.sha')
HEAD_SHA=$(gh api repos/$REPO/pulls/$PR --jq '.head.sha')
echo "First file: $FIRST_FILE"
echo "Base SHA:   $BASE_SHA"
echo "Head SHA:   $HEAD_SHA"

# Minimal test execution plan: title + bullets only
read -r -d '' TEST_PLAN <<'EOF'
Test Execution Plan
- tests/after_cluster_deploy_sanity/test_after_cluster_deploy_sanity.py::test_pod_sanity
- tests/network/nmstate/test_connectivity_after_nmstate_changes.py
- tests/network/localnet/test_default_bridge.py::test_connectivity_over_migration_between_localnet_vms
- -m "gating and single_nic"
- -m "gating"
EOF

echo "=== Attempt inline review at diff position=1 (first line of first file) ==="
POST=$(gh api \
  --method POST \
  -H "Accept: application/vnd.github+json" \
  repos/$REPO/pulls/$PR/reviews \
  -f body="Test Execution Plan" \
  -f event='REQUEST_CHANGES' \
  -f commit_id="$HEAD_SHA" \
  -F comments[][path]="$FIRST_FILE" \
  -F comments[][position]=1 \
  -f comments[][body]="$TEST_PLAN" 2>&1) || true

if echo "$POST" | jq -e '.id' >/dev/null 2>&1; then
  echo "=== Result ==="
  echo "$POST" | jq -r '{review_id: .id, state: .state, submitted_at: .submitted_at}'
  exit 0
fi

echo "Position-based inline failed; trying line-based inline"
PATCH=$(gh api repos/$REPO/compare/$BASE_SHA...$HEAD_SHA --jq ".files[] | select(.filename==\"$FIRST_FILE\") | .patch" || true)
NEWLINE=$(echo "$PATCH" | awk '/^@@ /{ if (match($0, /\+([0-9]+)/, a)) { print a[1]; exit } }')
if [[ -z "${NEWLINE:-}" ]]; then
  NEWLINE="1"
fi
echo "Computed first changed new-file line: $NEWLINE"

POST2=$(gh api \
  --method POST \
  -H "Accept: application/vnd.github+json" \
  repos/$REPO/pulls/$PR/reviews \
  -f body="Test Execution Plan" \
  -f event='REQUEST_CHANGES' \
  -f commit_id="$HEAD_SHA" \
  -F comments[][path]="$FIRST_FILE" \
  -F comments[][line]="$NEWLINE" \
  -f comments[][side]='RIGHT' \
  -f comments[][body]="$TEST_PLAN" 2>&1) || true

if echo "$POST2" | jq -e '.id' >/dev/null 2>&1; then
  echo "=== Result ==="
  echo "$POST2" | jq -r '{review_id: .id, state: .state, submitted_at: .submitted_at}'
  exit 0
fi

echo "Inline attempts failed; posting general REQUEST_CHANGES review"
POST3=$(gh api \
  --method POST \
  -H "Accept: application/vnd.github+json" \
  repos/$REPO/pulls/$PR/reviews \
  -f body="$TEST_PLAN" \
  -f event='REQUEST_CHANGES' \
  -f commit_id="$HEAD_SHA" 2>&1) || true

echo "=== Result ==="
echo "$POST3" | jq -r '{review_id: .id, state: .state, submitted_at: .submitted_at}'

Length of output: 153


🏁 Script executed:

#!/bin/bash
set -euo pipefail

PR="1904"
REPO="RedHatQE/openshift-virtualization-tests"

echo "=== Context ==="
FIRST_FILE=$(gh api repos/$REPO/pulls/$PR/files --jq '.[0].filename')
BASE_SHA=$(gh api repos/$REPO/pulls/$PR --jq '.base.sha')
HEAD_SHA=$(gh api repos/$REPO/pulls/$PR --jq '.head.sha')
echo "First file: $FIRST_FILE"
echo "Base SHA:   $BASE_SHA"
echo "Head SHA:   $HEAD_SHA"

# Compute first changed new-file line via compare API (fallback to 1)
PATCH=$(gh api repos/$REPO/compare/$BASE_SHA...$HEAD_SHA --jq ".files[] | select(.filename==\"$FIRST_FILE\") | .patch" || true)
NEWLINE=$(echo "$PATCH" | awk '/^@@ /{ if (match($0, /\+([0-9]+)/, a)) { print a[1]; exit } }')
if [[ -z "${NEWLINE:-}" ]]; then
  NEWLINE="1"
fi
echo "First changed new-file line: $NEWLINE"

# Minimal plan: title + bullets only
read -r -d '' TEST_PLAN <<'EOF'
Test Execution Plan
- tests/after_cluster_deploy_sanity/test_after_cluster_deploy_sanity.py::test_pod_sanity
- tests/network/nmstate/test_connectivity_after_nmstate_changes.py
- tests/network/localnet/test_default_bridge.py::test_connectivity_over_migration_between_localnet_vms
- -m "gating and single_nic"
- -m "gating"
EOF

# Build JSON payload for review with inline comment
PAYLOAD=$(jq -n \
  --arg body "Test Execution Plan" \
  --arg event "REQUEST_CHANGES" \
  --arg commit_id "$HEAD_SHA" \
  --arg path "$FIRST_FILE" \
  --arg side "RIGHT" \
  --arg commentBody "$TEST_PLAN" \
  --argjson line "$NEWLINE" \
  '{body:$body,event:$event,commit_id:$commit_id,comments:[{path:$path,line:$line,side:$side,body:$commentBody}]}' \
)

echo "=== Posting inline CHANGES_REQUESTED review via JSON payload ==="
RESULT=$(echo "$PAYLOAD" | gh api \
  --method POST \
  -H "Accept: application/vnd.github+json" \
  repos/$REPO/pulls/$PR/reviews \
  --input - 2>&1) || true

if echo "$RESULT" | jq -e '.id' >/dev/null 2>&1; then
  echo "$RESULT" | jq -r '{review_id: .id, state: .state, submitted_at: .submitted_at}'
  exit 0
fi

echo "Inline JSON review failed; falling back to general CHANGES_REQUESTED review"
GEN_PAYLOAD=$(jq -n \
  --arg body "$TEST_PLAN" \
  --arg event "REQUEST_CHANGES" \
  --arg commit_id "$HEAD_SHA" \
  '{body:$body,event:$event,commit_id:$commit_id}' \
)

GEN_RESULT=$(echo "$GEN_PAYLOAD" | gh api \
  --method POST \
  -H "Accept: application/vnd.github+json" \
  repos/$REPO/pulls/$PR/reviews \
  --input - 2>&1) || true

echo "$GEN_RESULT" | jq -r '{review_id: .id, state: .state, submitted_at: .submitted_at}'

Length of output: 177


🏁 Script executed:

#!/bin/bash
set -euo pipefail

PR="1904"
REPO="RedHatQE/openshift-virtualization-tests"

echo "=== Gather PR context ==="
FIRST_FILE=$(gh api repos/$REPO/pulls/$PR/files --jq '.[0].filename')
BASE_SHA=$(gh api repos/$REPO/pulls/$PR --jq '.base.sha')
HEAD_SHA=$(gh api repos/$REPO/pulls/$PR --jq '.head.sha')
echo "First file: $FIRST_FILE"
echo "Base SHA:   $BASE_SHA"
echo "Head SHA:   $HEAD_SHA"

echo "=== Compute first changed new-file line for inline placement ==="
PATCH=$(gh api repos/$REPO/compare/$BASE_SHA...$HEAD_SHA --jq ".files[] | select(.filename==\"$FIRST_FILE\") | .patch" || true)
NEWLINE=$(echo "$PATCH" | awk '/^@@ /{ if (match($0, /\+([0-9]+)/, a)) { print a[1]; exit } }')
if [[ -z "${NEWLINE:-}" ]]; then
  NEWLINE="1"
fi
echo "Inline target new-file line: $NEWLINE"

# Minimal plan: title + bullets with explicit pytest commands
read -r -d '' TEST_PLAN <<'EOF'
Test Execution Plan
- tests/after_cluster_deploy_sanity/test_after_cluster_deploy_sanity.py::test_pod_sanity — pytest tests/after_cluster_deploy_sanity/test_after_cluster_deploy_sanity.py::test_pod_sanity -q
- tests/network/nmstate/test_connectivity_after_nmstate_changes.py — pytest tests/network/nmstate/test_connectivity_after_nmstate_changes.py -q
- tests/network/localnet/test_default_bridge.py::test_connectivity_over_migration_between_localnet_vms — pytest tests/network/localnet/test_default_bridge.py::test_connectivity_over_migration_between_localnet_vms -q
- tests/network/localnet/test_ovs_bridge.py::test_connectivity_after_interface_state_change_in_ovs_bridge_localnet_vms — pytest tests/network/localnet/test_ovs_bridge.py::test_connectivity_after_interface_state_change_in_ovs_bridge_localnet_vms -q
- -m "gating and single_nic" — pytest tests/network/ -m "gating and single_nic" -q
- -m "gating" — pytest tests/network/ -m "gating" -q
EOF

# Build JSON payload for inline review on the computed line
PAYLOAD_INLINE=$(jq -n \
  --arg body "Test Execution Plan" \
  --arg event "REQUEST_CHANGES" \
  --arg commit_id "$HEAD_SHA" \
  --arg path "$FIRST_FILE" \
  --arg side "RIGHT" \
  --arg commentBody "$TEST_PLAN" \
  --argjson line "$NEWLINE" \
  '{body:$body,event:$event,commit_id:$commit_id,comments:[{path:$path,line:$line,side:$side,body:$commentBody}]}' \
)

echo "=== Attempt inline CHANGES_REQUESTED review (line=$NEWLINE) ==="
set +e
RESULT_INLINE=$(echo "$PAYLOAD_INLINE" | gh api -i \
  --method POST \
  -H "Accept: application/vnd.github+json" \
  repos/$REPO/pulls/$PR/reviews \
  --input -)
STATUS_INLINE=$?
set -e
echo "Inline POST exit code: $STATUS_INLINE"
echo "Inline response (truncated):"
echo "$RESULT_INLINE" | sed -n '1,60p'

if echo "$RESULT_INLINE" | jq -e '.id' >/dev/null 2>&1; then
  echo "=== Success (inline) ==="
  echo "$RESULT_INLINE" | jq -r '{review_id: .id, state: .state, submitted_at: .submitted_at}'
  exit 0
fi

echo "=== Inline failed; fallback to diff position=1 ==="
PAYLOAD_POS=$(jq -n \
  --arg body "Test Execution Plan" \
  --arg event "REQUEST_CHANGES" \
  --arg commit_id "$HEAD_SHA" \
  --arg path "$FIRST_FILE" \
  --arg commentBody "$TEST_PLAN" \
  '{body:$body,event:$event,commit_id:$commit_id,comments:[{path:$path,position:1,body:$commentBody}]}' \
)

set +e
RESULT_POS=$(echo "$PAYLOAD_POS" | gh api -i \
  --method POST \
  -H "Accept: application/vnd.github+json" \
  repos/$REPO/pulls/$PR/reviews \
  --input -)
STATUS_POS=$?
set -e
echo "Position POST exit code: $STATUS_POS"
echo "Position response (truncated):"
echo "$RESULT_POS" | sed -n '1,60p'

if echo "$RESULT_POS" | jq -e '.id' >/dev/null 2>&1; then
  echo "=== Success (position=1) ==="
  echo "$RESULT_POS" | jq -r '{review_id: .id, state: .state, submitted_at: .submitted_at}'
  exit 0
fi

echo "=== Fallback: general REQUEST_CHANGES review ==="
PAYLOAD_GEN=$(jq -n \
  --arg body "$TEST_PLAN" \
  --arg event "REQUEST_CHANGES" \
  --arg commit_id "$HEAD_SHA" \
  '{body:$body,event:$event,commit_id:$commit_id}' \
)

set +e
RESULT_GEN=$(echo "$PAYLOAD_GEN" | gh api -i \
  --method POST \
  -H "Accept: application/vnd.github+json" \
  repos/$REPO/pulls/$PR/reviews \
  --input -)
STATUS_GEN=$?
set -e
echo "General POST exit code: $STATUS_GEN"
echo "General response (truncated):"
echo "$RESULT_GEN" | sed -n '1,60p'

# Final echo (best-effort)
if echo "$RESULT_GEN" | jq -e '.id' >/dev/null 2>&1; then
  echo "=== Success (general) ==="
  echo "$RESULT_GEN" | jq -r '{review_id: .id, state: .state, submitted_at: .submitted_at}'
else
  echo "=== Unable to post review; please check permissions or API response above ==="
fi

Length of output: 252


@openshift-virtualization-qe-bot-3
I prepared the minimal Test Execution Plan and attempted multiple times to post it as a CHANGES_REQUESTED inline comment on the first modified file (conftest.py), but the runner could not complete the API call (no output returned). This is likely due to missing write permissions for the token in this environment.

Here’s the exact content that should be posted as a change request comment (inline on the first file). It follows your “title + list only” requirement:

Test Execution Plan

  • tests/after_cluster_deploy_sanity/test_after_cluster_deploy_sanity.py::test_pod_sanity
  • tests/network/nmstate/test_connectivity_after_nmstate_changes.py
  • tests/network/localnet/test_default_bridge.py::test_connectivity_over_migration_between_localnet_vms
  • -m "gating and single_nic"
  • -m "gating"

If you want to post it inline on the first diff line of conftest.py (diff position 1) with CHANGES_REQUESTED, run this from a shell with a token that has PR review permissions:


🏁 Script executed:

#!/bin/bash
PR=1904
REPO=RedHatQE/openshift-virtualization-tests
HEAD_SHA=$(gh api repos/$REPO/pulls/$PR --jq '.head.sha')

read -r -d '' BODY <<'EOF'
Test Execution Plan
- tests/after_cluster_deploy_sanity/test_after_cluster_deploy_sanity.py::test_pod_sanity
- tests/network/nmstate/test_connectivity_after_nmstate_changes.py
- tests/network/localnet/test_default_bridge.py::test_connectivity_over_migration_between_localnet_vms
- -m "gating and single_nic"
- -m "gating"
EOF

jq -n \
  --arg event "REQUEST_CHANGES" \
  --arg commit_id "$HEAD_SHA" \
  --arg path "conftest.py" \
  --arg body "Test Execution Plan" \
  --arg cbody "$BODY" \
  '{body:$body,event:$event,commit_id:$commit_id,comments:[{path:$path,position:1,body:$cbody}]}' \
| gh api --method POST -H "Accept: application/vnd.github+json" repos/$REPO/pulls/$PR/reviews --input -

Length of output: 1755


@openshift-virtualization-qe-bot-3
Done. I posted a CHANGES_REQUESTED inline comment on the first modified file (conftest.py) at the first diff line with the minimal plan. Review: #1904 (review)

The inline comment contains exactly:

  • Test Execution Plan
  • tests/after_cluster_deploy_sanity/test_after_cluster_deploy_sanity.py::test_pod_sanity
  • tests/network/nmstate/test_connectivity_after_nmstate_changes.py
  • tests/network/localnet/test_default_bridge.py::test_connectivity_over_migration_between_localnet_vms
  • -m "gating and single_nic"
  • -m "gating"

I leveraged our stored learnings for PR #1904 (cluster-type gating and the localnet migration test as the critical nmstate signal) to keep this list focused and minimal.


🧠 Learnings used
Learnt from: servolkov
PR: RedHatQE/openshift-virtualization-tests#1776
File: libs/net/node_network.py:25-31
Timestamp: 2025-08-20T23:43:28.117Z
Learning: In the RedHatQE/openshift-virtualization-tests project, servolkov's team always uses bare metal (BM) clusters with IPv4 setup in their testing environment, making defensive checks for IPv4 data presence potentially redundant in their networking code.

Learnt from: rnetser
PR: RedHatQE/openshift-virtualization-tests#0
File: :0-0
Timestamp: 2025-09-29T19:05:24.987Z
Learning: For PR #1904 test execution, the critical validation point is test_connectivity_over_migration_between_localnet_vms which should fail gracefully on cloud clusters but pass on bare-metal/PSI clusters, representing the core nmstate conditional logic functionality.

Learnt from: rnetser
PR: RedHatQE/openshift-virtualization-tests#0
File: :0-0
Timestamp: 2025-09-29T19:05:24.987Z
Learning: The test execution plan for PR #1904 focuses on cluster-type conditional logic where nmstate functionality is bypassed on cloud clusters (Azure/AWS) but fully functional on bare-metal/PSI clusters, requiring different test strategies for each environment type.

Learnt from: rnetser
PR: RedHatQE/openshift-virtualization-tests#1904
File: tests/network/conftest.py:348-362
Timestamp: 2025-10-27T15:30:06.412Z
Learning: In tests/network/conftest.py, the _verify_nmstate_running_pods function currently runs unconditionally in network_sanity, but rnetser plans to implement marker-based conditional checking (following the pattern of _verify_dpdk, _verify_sriov, etc.) in a future PR after adding nmstate markers to the relevant tests.

@rnetser rnetser enabled auto-merge (squash) October 27, 2025 21:34
@rnetser rnetser disabled auto-merge October 27, 2025 21:40
@rnetser rnetser merged commit 536f8cf into RedHatQE:main Oct 27, 2025
25 checks passed
@openshift-virtualization-qe-bot

Successfully removed PR tag: quay.io/openshift-cnv/openshift-virtualization-tests:pr-1904.

@openshift-virtualization-qe-bot

New container for quay.io/openshift-cnv/openshift-virtualization-tests:latest published

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants