Skip to content

net: Introduce dual-stream linux bridge tests#4772

Open
azhivovk wants to merge 2 commits intoRedHatQE:mainfrom
azhivovk:new_rhcos9-10_tests
Open

net: Introduce dual-stream linux bridge tests#4772
azhivovk wants to merge 2 commits intoRedHatQE:mainfrom
azhivovk:new_rhcos9-10_tests

Conversation

@azhivovk
Copy link
Copy Markdown
Contributor

@azhivovk azhivovk commented May 7, 2026

Short description:
  • New dual-stream tests: Linux bridge scenarios
  • Shared infra for all upcoming new dual-stream test
More details: STD: #4569
What this PR does / why we need it:

Added automation for new dual-stream tests

Which issue(s) this PR fixes: -
Special notes for reviewer:

Follow-up implementation of new tests of linux bridge

jira-ticket: https://redhat.atlassian.net/browse/CNV-86194

Summary by CodeRabbit

  • New Features

    • Added test infrastructure for mixed RHCOS 9/10 cluster environments, including new test marker for dual-stream OS clusters.
    • Introduced L2 bridge connectivity tests between RHEL 9 and RHEL 10 virtual machines with automated node selection and TCP connection validation.
    • Added test fixtures for RHCOS version-specific node discovery and VM-to-node scheduling.
  • Tests

    • Refactored connectivity migration tests to support cross-version scenarios with enhanced assertion messaging.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 7, 2026

Review Change Stack

📝 Walkthrough

Walkthrough

This PR adds infrastructure for testing VM networking connectivity across clusters with both RHCOS 9 and RHCOS 10 worker nodes. It introduces nodeSelector support to VM specs, utilities to discover and pin VMs to specific RHCOS versions, fixtures to set up dual-interface test VMs with secondary-interface cloud-init, and integration tests validating TCP connectivity survives VM migration between RHCOS versions.

Changes

Mixed RHCOS Cluster Connectivity Tests

Layer / File(s) Summary
VM Spec Schema
libs/vm/spec.py
VMISpec dataclass gains optional nodeSelector: dict[str, str] | None field to enable pod scheduling constraints.
Network Address Utilities
libs/net/ip.py
New cidr_addresses_by_family() generates per-IP-family CIDR-formatted addresses (IPv4 /24, IPv6 /64) for cluster-supported stacks.
Node Selection Utilities
tests/network/libs/nodes.py
New module exports: HOSTNAME_LABEL, RHCOS_9_VERSION_PREFIX, RHCOS_10_VERSION_PREFIX constants; node_by_rhcos_version() to find workers by OS image prefix; update_vm_node_selector() to patch VM pod spec nodeSelector.
RHCOS Version Fixtures
tests/network/conftest.py
Imports node utilities; adds rhcos9_node and rhcos10_node module-scoped fixtures returning workers matched by RHCOS version.
L2 Bridge VM Helper
tests/network/l2_bridge/rhel9_rhel10_cluster/lib_helpers.py
New module: LINUX_BRIDGE_IFACE_NAME constant; bridge_vm() factory assembles dual-interface Fedora VM (masquerade + bridge), pins via nodeSelector, generates cloud-init disk with secondary-interface CIDR addresses.
L2 Bridge Fixtures
tests/network/l2_bridge/rhel9_rhel10_cluster/conftest.py
New fixtures: dual_stream_bridge_nad creates bridge NetworkAttachmentDefinition; bridge_server_vm and bridge_client_vm provision VMs on bridge with distinct secondary IPs and validate interface status; bridge_active_tcp_connection establishes and yields TCP pairs.
L2 Bridge Tests
tests/network/l2_bridge/rhel9_rhel10_cluster/test_connectivity.py
Adds mixed_os_nodes marker, removes __test__ flag; refactors two server-migration tests to accept fixtures, update server VM node selector, migrate, and assert per-IP-version TCP connectivity within subtests for migrations to RHCOS 10 and back to RHCOS 9.
Test Marker Config
pytest.ini
Registers mixed_os_nodes marker for tests requiring dual-stream RHCOS 9/10 clusters.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Rationale: The PR spans 8 files with heterogeneous roles (spec schema, node/network utilities, test fixtures, test logic, and pytest config). Core logic density is moderate—the node selection and VM pinning utilities are straightforward iterators and patchers; bridge VM construction chains together interfaces, cloud-init, and nodeSelector assignment. Bridge fixtures orchestrate multiple dependencies and validate interface state. Migration tests refactor from parameterless to fixture-driven, introducing subtests and IP-version-specific assertions. The breadth across utilities, fixtures, and test methods demands separate reasoning for each area, but repetition patterns (two mirror-image migration tests, two similar VM fixtures) reduce net complexity. Schema and config changes are trivial.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 43.48% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'net: Introduce dual-stream linux bridge tests' accurately summarizes the main change: adding new dual-stream tests for Linux bridge scenarios with shared infrastructure support.
Description check ✅ Passed The PR description includes all required template sections with substantive content: short description, details with STD link, purpose, issue reference, reviewer notes, and JIRA ticket URL.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

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

@openshift-virtualization-qe-bot-5
Copy link
Copy Markdown

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
  • Branch Labeling: Branch-specific labels are applied to track the target branch
  • Auto-verification: Auto-verified users have their PRs automatically marked as verified
  • Labels: Enabled categories: branch, can-be-merged, cherry-pick, has-conflicts, hold, needs-rebase, size, verified, wip

📋 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
  • /reprocess - Trigger complete PR workflow reprocessing (useful if webhook failed or configuration changed)
  • /regenerate-welcome - Regenerate this welcome message

Review & Approval

  • /lgtm - Approve changes (looks good to me)
  • /approve - Approve PR (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 verify-bugs-are-open - verify-bugs-are-open
  • /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, has-conflicts labels and PR must be mergeable (no conflicts)
  5. Verified: PR must be marked as verified

📊 Review Process

Approvers and Reviewers

Approvers:

  • EdDev
  • dshchedr
  • myakove
  • rnetser
  • vsibirsk

Reviewers:

  • Anatw
  • EdDev
  • RoniKishner
  • azhivovk
  • dshchedr
  • frenzyfriday
  • nirdothan
  • orelmisan
  • rnetser
  • servolkov
  • vsibirsk
  • yossisegev
Available Labels
  • hold
  • verified
  • wip
  • lgtm
  • approve
AI Features
  • Cherry-Pick Conflict Resolution: Enabled (claude/claude-opus-4-6[1m])

💡 Tips

  • WIP Status: Use /wip when your PR is not ready for review
  • Verification: The verified label is removed on new commits unless the push is detected as a clean rebase
  • 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.

Copy link
Copy Markdown
Contributor

@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: 4

Caution

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

⚠️ Outside diff range comments (2)
pytest.ini (1)

1-1: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

HIGH: Restore required PR template sections in the PR description

The PR description in the provided context is missing the required template headings (What this PR does / why we need it, Which issue(s) this PR fixes, Special notes for reviewer, jira-ticket). Please restore them before merge.

As per coding guidelines: “Required sections (must be present, even if empty)… If any required section is absent… flag it as HIGH severity.”

🤖 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 `@pytest.ini` at line 1, Restore the required PR description headings in the PR
(add the headings verbatim): "What this PR does / why we need it", "Which
issue(s) this PR fixes", "Special notes for reviewer", and "jira-ticket"; update
the PR description to include those sections (they can be empty but must be
present) so the template requirements are satisfied before merging, and confirm
the PR body now contains each exact heading.
tests/network/libs/vm_factory.py (1)

26-33: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

MEDIUM: Avoid silently dropping template_labels when node is provided

Line 28 introduces an elif path that suppresses label application whenever node is set. Keep labels independent, and only gate anti-affinity on node pinning if needed.

Suggested diff
-    if node is not None:
-        spec.template.spec.nodeSelector = {HOSTNAME_LABEL: node.hostname}
-    elif template_labels:
+    if template_labels:
         spec.template.metadata.labels = spec.template.metadata.labels or {}  # type: ignore
         spec.template.metadata.labels.update(template_labels)  # type: ignore
-        # Use the first label key and first value as the anti-affinity label to use:
-        label, *_ = template_labels.items()
-        spec.template.spec.affinity = new_pod_anti_affinity(label=label, namespaces=anti_affinity_namespaces)
+    if node is not None:
+        spec.template.spec.nodeSelector = {HOSTNAME_LABEL: node.hostname}
+    elif template_labels:
+        # Use the first label key and first value as the anti-affinity label to use:
+        label, *_ = template_labels.items()
+        spec.template.spec.affinity = new_pod_anti_affinity(label=label, namespaces=anti_affinity_namespaces)
🤖 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 `@tests/network/libs/vm_factory.py` around lines 26 - 33, The current branch
only applies template_labels when node is None, dropping labels whenever node
pinning occurs; refactor so template_labels are always merged into
spec.template.metadata.labels (update spec.template.metadata.labels = ... and
spec.template.metadata.labels.update(template_labels) when template_labels is
truthy), then separately handle node pinning by setting
spec.template.spec.nodeSelector when node is not None, and only create/specify
spec.template.spec.affinity via new_pod_anti_affinity when node is None (or when
you explicitly want to gate anti-affinity), using the first key/value from
template_labels and anti_affinity_namespaces as before.
🤖 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 `@libs/vm/spec.py`:
- Line 34: The model field currently declared as nodeSelector with a "# noqa:
N815" should be renamed to snake_case (node_selector) and the linter suppression
removed; then add an explicit serialization alias so external Kubernetes
JSON/YAML still emits "nodeSelector" (e.g., use your model system's alias/Field
parameter like Field(alias="nodeSelector") or serializer mapping and ensure
dict/JSON export uses aliases). Update any places that reference nodeSelector to
use node_selector or to serialize via the alias, and remove the "# noqa: N815"
comment.

In `@tests/network/l2_bridge/rhel9_rhel10_cluster/conftest.py`:
- Line 76: The assertion in the test fixture currently just checks
iface_cloud_init.addresses without context; update the assertion to include a
descriptive failure message so failures show intent — change the assert on
iface_cloud_init.addresses in the conftest fixture to include a message (e.g.,
referencing iface_cloud_init or its name) that explains that no addresses were
assigned to the interface.

In `@tests/network/l2_bridge/rhel9_rhel10_cluster/lib_helpers.py`:
- Around line 16-46: The function bridge_vm lacks a required Google-style
docstring describing its parameters, return value, and side effects; add a
Google-format docstring above bridge_vm that documents each parameter
(namespace, name, client: DynamicClient, bridge_network_name, cloud_init_iface:
EthernetDevice, node: Node), the returned BaseVirtualMachine, and side effects
(node pinning via spec.template.spec.nodeSelector using HOSTNAME_LABEL, added
interfaces/networks using Devices/Interface/Network with
LINUX_BRIDGE_IFACE_NAME, cloud-init userdata built with cloudinit.UserData and
cloudinit.asyaml, disk/volume creation via cloudinitdisk_storage, and that the
final VMI is created by fedora_vm), and mention any important expectations or
invariants (e.g., cloud_init_iface used as eth1); keep it in Google docstring
format.

In `@tests/network/localnet/rhel9_rhel10_cluster/conftest.py`:
- Line 33: The assertion "assert iface_cloud_init.addresses" (and the similar
assertion at line 69) lacks a failure message; update both assertions in the
conftest.py fixture so they include explicit descriptive messages (e.g.,
indicating "unsupported cluster IP-family state: no addresses on
iface_cloud_init") to make test failures diagnosable; locate the assertions
referencing iface_cloud_init (and the second similar assert) and change them to
use the assert condition, "descriptive message" pattern.

---

Outside diff comments:
In `@pytest.ini`:
- Line 1: Restore the required PR description headings in the PR (add the
headings verbatim): "What this PR does / why we need it", "Which issue(s) this
PR fixes", "Special notes for reviewer", and "jira-ticket"; update the PR
description to include those sections (they can be empty but must be present) so
the template requirements are satisfied before merging, and confirm the PR body
now contains each exact heading.

In `@tests/network/libs/vm_factory.py`:
- Around line 26-33: The current branch only applies template_labels when node
is None, dropping labels whenever node pinning occurs; refactor so
template_labels are always merged into spec.template.metadata.labels (update
spec.template.metadata.labels = ... and
spec.template.metadata.labels.update(template_labels) when template_labels is
truthy), then separately handle node pinning by setting
spec.template.spec.nodeSelector when node is not None, and only create/specify
spec.template.spec.affinity via new_pod_anti_affinity when node is None (or when
you explicitly want to gate anti-affinity), using the first key/value from
template_labels and anti_affinity_namespaces as before.
🪄 Autofix (Beta)

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: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: fd3b3507-394a-4715-8e06-28d1b71547a1

📥 Commits

Reviewing files that changed from the base of the PR and between bdafe7b and b12e932.

📒 Files selected for processing (12)
  • libs/vm/spec.py
  • pytest.ini
  • tests/network/conftest.py
  • tests/network/l2_bridge/rhel9_rhel10_cluster/conftest.py
  • tests/network/l2_bridge/rhel9_rhel10_cluster/lib_helpers.py
  • tests/network/l2_bridge/rhel9_rhel10_cluster/test_connectivity.py
  • tests/network/libs/cloudinit.py
  • tests/network/libs/nodes.py
  • tests/network/libs/vm_factory.py
  • tests/network/localnet/liblocalnet.py
  • tests/network/localnet/rhel9_rhel10_cluster/conftest.py
  • tests/network/localnet/rhel9_rhel10_cluster/test_connectivity.py

Comment thread libs/vm/spec.py
Comment thread tests/network/l2_bridge/rhel9_rhel10_cluster/conftest.py Outdated
Comment thread tests/network/l2_bridge/rhel9_rhel10_cluster/lib_helpers.py
Comment thread tests/network/localnet/rhel9_rhel10_cluster/conftest.py Outdated
@azhivovk
Copy link
Copy Markdown
Contributor Author

azhivovk commented May 7, 2026

Change: rebase

@azhivovk
Copy link
Copy Markdown
Contributor Author

azhivovk commented May 8, 2026

Change: order commits, edit PR description

@azhivovk
Copy link
Copy Markdown
Contributor Author

azhivovk commented May 8, 2026

Change: Drop udn changes

azhivovk and others added 2 commits May 8, 2026 13:38
- Add mixed_os_nodes marker to pytest.ini to select tests only on
  compatible clusters
- Add rhcos9_node/rhcos10_node fixtures to network conftest
- Add update_vm_node_selector helper and HOSTNAME_LABEL to nodes lib

Signed-off-by: Asia Khromov <azhivovk@redhat.com>
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Live migration between RHCOS 9 and RHCOS 10 nodes can expose kernel
bridge driver incompatibilities that break active TCP connections.
These tests verify that secondary Linux bridge network connectivity
is preserved during cross-OS migration in both directions.

Signed-off-by: Asia Khromov <azhivovk@redhat.com>
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
@azhivovk azhivovk force-pushed the new_rhcos9-10_tests branch from c58887e to 00747ed Compare May 8, 2026 10:39
@azhivovk
Copy link
Copy Markdown
Contributor Author

azhivovk commented May 8, 2026

Change: edit commits

@openshift-virtualization-qe-bot-2
Copy link
Copy Markdown
Contributor

Clean rebase detected — no code changes compared to previous head (c58887e).

Copy link
Copy Markdown
Contributor

@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: 3

🤖 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 `@tests/network/l2_bridge/rhel9_rhel10_cluster/conftest.py`:
- Around line 40-91: bridge_server_vm and bridge_client_vm are duplicate
fixtures; extract their shared setup into a contextmanager bridge_test_vm in
lib_helpers.py and have both fixtures call it; implement bridge_test_vm to
accept namespace, name, client, bridge_network_name, host_address, node, use
cidr_addresses_by_family, bridge_vm, vm.start, vm.wait_for_agent_connected and
wait_for_ifaces_status with LINUX_BRIDGE_IFACE_NAME as in the diff, then update
bridge_server_vm and bridge_client_vm in conftest.py to invoke bridge_test_vm
with the appropriate name ("server-vm"/"client-vm") and host_address
(_SERVER_HOST_ADDRESS/_CLIENT_HOST_ADDRESS) and yield the returned vm.
- Line 26: Update each pytest fixture return annotation that currently uses a
single-parameter collections.abc.Generator to the three-parameter form
Generator[T, None, None]; e.g., change Generator[NetworkAttachmentDefinition] to
Generator[NetworkAttachmentDefinition, None, None] (and do the same for the
other three fixture annotations at the same locations), and ensure the Generator
import from collections.abc remains present or is added if missing.

In `@tests/network/l2_bridge/rhel9_rhel10_cluster/test_connectivity.py`:
- Around line 20-22: Add the pytest tier marker to classify this complex
platform-specific test: above the existing decorators on class TestConnectivity
(which currently has `@pytest.mark.mixed_os_nodes` and `@pytest.mark.incremental`),
add `@pytest.mark.tier3` so the test is both environment-filtered and correctly
labeled as a tier3 test.
🪄 Autofix (Beta)

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: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 8497d612-93c5-4748-9e43-1bd6b2816ae5

📥 Commits

Reviewing files that changed from the base of the PR and between 862deeb and 00747ed.

📒 Files selected for processing (8)
  • libs/net/ip.py
  • libs/vm/spec.py
  • pytest.ini
  • tests/network/conftest.py
  • tests/network/l2_bridge/rhel9_rhel10_cluster/conftest.py
  • tests/network/l2_bridge/rhel9_rhel10_cluster/lib_helpers.py
  • tests/network/l2_bridge/rhel9_rhel10_cluster/test_connectivity.py
  • tests/network/libs/nodes.py

Comment thread tests/network/l2_bridge/rhel9_rhel10_cluster/conftest.py
Comment thread tests/network/l2_bridge/rhel9_rhel10_cluster/conftest.py
Comment thread tests/network/l2_bridge/rhel9_rhel10_cluster/test_connectivity.py
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.

7 participants