Skip to content

tests: fix grpc topotest xdist collection mismatch in CI - #22048

Merged
riw777 merged 3 commits into
FRRouting:masterfrom
Jafaral:ci-grpc-flaky
May 30, 2026
Merged

tests: fix grpc topotest xdist collection mismatch in CI #22048
riw777 merged 3 commits into
FRRouting:masterfrom
Jafaral:ci-grpc-flaky

Conversation

@Jafaral

@Jafaral Jafaral commented May 24, 2026

Copy link
Copy Markdown
Member

Fix intermittent CI topotest failures where pytest-xdist aborts with Different tests were collected between gw0 and gw5 because grpc_basic was collected on some workers but module-skipped on others.

Example CI failure here

@frrbot frrbot Bot added the tests Topotests, make check, etc label May 24, 2026
@greptile-apps

greptile-apps Bot commented May 24, 2026

Copy link
Copy Markdown

Greptile Summary

This PR fixes intermittent pytest-xdist CI failures where workers collected grpc_basic differently because the old skip guard ran grpc-query.py --check as a subprocess β€” a non-deterministic operation that could succeed on some workers and fail on others. The fix replaces that subprocess call with a deterministic filesystem check for grpc.so, and separately filters xdist worker-id entries from analyze.py XML parsing.

  • test_basic_grpc.py: Adds _frr_grpc_module_available() which globs standard system paths and an optional FRR_BUILD_DIR for grpc.so; the commander.cmd_raises skip guard is replaced with this file-existence check, eliminating per-worker variance during collection.
  • analyze.py: Introduces XDIST_WORKER_RE = re.compile(r"^gw\d+$") and skips any testcase whose @name matches a worker ID, preventing downstream name-processing errors on xdist-injected error entries in JUnit XML output.

Confidence Score: 5/5

Safe to merge β€” both changes are narrowly scoped to CI test infrastructure and do not touch any FRR daemon or production code.

The subprocess-to-filesystem swap removes the sole source of non-determinism that caused xdist mismatches; file existence is evaluated identically on every worker. The analyze.py regex guard is correct and only skips entries that were previously causing downstream name-processing errors. No functional test logic was altered.

No files require special attention.

Important Files Changed

Filename Overview
tests/topotests/grpc_basic/test_basic_grpc.py Replaces non-deterministic subprocess-based skip check with a deterministic filesystem glob search for grpc.so, fixing xdist collection mismatch; also removes unused commander import.
tests/topotests/analyze.py Adds XDIST_WORKER_RE regex to filter out xdist worker-id entries (e.g. gw5) that appear as @name in JUnit XML when collection errors occur, preventing analysis failures on those entries.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[pytest-xdist worker: collection phase] --> B{grpc / grpc_tools\nPython imports OK?}
    B -- No --> C[pytest.skip: gRPC modules not installed\nallow_module_level=True]
    B -- Yes --> D{_frr_grpc_module_available?\nglob grpc.so in system paths\n+ FRR_BUILD_DIR}
    D -- No --> E[pytest.skip: FRR gRPC northbound\nmodule not installed\nallow_module_level=True]
    D -- Yes --> F[Collect & run grpc_basic tests]

    style C fill:#f88,stroke:#c00
    style E fill:#f88,stroke:#c00
    style F fill:#8f8,stroke:#080
Loading

Reviews (3): Last reviewed commit: "tests: skip grpc_basic when FRR gRPC mod..." | Re-trigger Greptile

@Jafaral

Jafaral commented May 24, 2026

Copy link
Copy Markdown
Member Author

@greptile

Removing the --check guard in test_basic_grpc.py trades a clean module-level skip for a runtime error if proto generation ever fails in an environment where grpc/grpc_tools are importable but frr-northbound.proto is missing β€” those cases would now surface as test failures rather than skips.

The runtime-vs-skip tradeoff is acceptable: CI Docker always builds with --enable-grpc, and a proto/protoc problem there should fail as a normal test error, not a per-worker collection skip that aborts the whole xdist run.

For local runs without --enable-grpc: if grpcio/grpcio-tools aren’t installed, the module still skips via the import guard (unchanged since ea85c7c). The removed --check never verified the FRR build anyway β€” only Python proto generation. A deterministic skip based on GRPC_TRUE / grpc.so would be a nice follow-up for devs who have pip grpc but don’t enable gRPC in the build.

If you have better ideas or code suggestions, let me know.

@greptile-apps

greptile-apps Bot commented May 24, 2026

Copy link
Copy Markdown

The rationale is sound. The key insight is that --check runs protoc to regenerate the proto modules, and whether that succeeds is environment-dependent (proto file path, protoc binary availability) β€” making it a flaky, worker-local check that's the root cause of the xdist collection mismatch.

Your analysis of the tradeoffs is correct:

  1. CI (Docker, --enable-grpc): proto generation happens at build time; if it fails there, a test error is the right signal.
  2. Local without --enable-grpc: the grpcio/grpcio-tools import guard still fires deterministically before collection, so the module skips cleanly on all workers.

The one gap you identified β€” a dev with pip-installed grpc but a non-grpc FRR build β€” is real but narrow. A clean follow-up would be to check for grpc.so or a build flag at the session level rather than per-module. Something like a conftest.py hook:

# tests/topotests/conftest.py
def pytest_ignore_collect(collection_path, config):
    if "grpc_basic" in str(collection_path) and not _frr_built_with_grpc():
        return True

where _frr_built_with_grpc() checks for grpc.so or runs frr-config --grpc. Since pytest_ignore_collect is called on the collection master before workers fork, the decision is made once and is consistent across all xdist workers β€” safe by construction.

But that's genuinely a follow-up. The current fix correctly removes the per-worker non-determinism, and the tradeoff is well-reasoned.

@riw777 riw777 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

looks good

Jafaral added 2 commits May 28, 2026 15:13
Follow-up to ea85c7c ("fix grpc_basic xdist collection mismatch"):
that commit made missing grpc imports skip consistently, but the
per-worker grpc-query --check subprocess could still fail on some xdist
workers while others collected grpc_basic tests, aborting CI with
"Different tests were collected". Rely on the import guard only; proto
generation still runs when tests execute grpc-query.

Signed-off-by: Jafar Al-Gharaibeh <jafar@atcorp.com>
When parallel collection fails, xdist records errors named gw0, gw5, etc.
analyze.py turned those into nonexistent gw5.py rerun targets. Skip worker
ids so CI serial reruns only real topotest modules.

Signed-off-by: Jafar Al-Gharaibeh <jafar@atcorp.com>
@Jafaral

Jafaral commented May 29, 2026

Copy link
Copy Markdown
Member Author

@greptile review

After dropping the collection-time grpc-query --check guard, CI always
collected grpc_basic when Python grpc was installed, but grpc.s (frr-grpc)
might not be installed. Zebra then failed to start with -M grpc and
surfaced as a misleading mgmtd connection timeout. Skip the module when
the northbound gRPC module is absent.

Signed-off-by: Jafar Al-Gharaibeh <jafar@atcorp.com>
@Jafaral

Jafaral commented May 29, 2026

Copy link
Copy Markdown
Member Author

@greptile review

@riw777 riw777 added the bugfix label May 30, 2026
@riw777
riw777 merged commit bda757a into FRRouting:master May 30, 2026
24 checks passed
@Jafaral

Jafaral commented Jun 3, 2026

Copy link
Copy Markdown
Member Author

@Mergifyio backport stable/10.6

@mergify

mergify Bot commented Jun 3, 2026

Copy link
Copy Markdown

backport stable/10.6

βœ… Backports have been created

Details

Cherry-pick of 54429f5 has failed:

On branch mergify/bp/stable/10.6/pr-22048
Your branch is up to date with 'origin/stable/10.6'.

You are currently cherry-picking commit 54429f53c.
  (fix conflicts and run "git cherry-pick --continue")
  (use "git cherry-pick --skip" to skip this patch)
  (use "git cherry-pick --abort" to cancel the cherry-pick operation)

Unmerged paths:
  (use "git add <file>..." to mark resolution)
	both modified:   tests/topotests/grpc_basic/test_basic_grpc.py

no changes added to commit (use "git add" and/or "git commit -a")

To fix up this pull request, you can check it out locally. See documentation: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/reviewing-changes-in-pull-requests/checking-out-pull-requests-locally

Jafaral added a commit that referenced this pull request Jun 5, 2026
tests: fix grpc topotest xdist collection mismatch in CI  (backport #22048)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants