Skip to content

Fix CI abort: skip PyVista Plotter test on headless runners#59

Merged
lmoresi merged 1 commit intodevelopmentfrom
bugfix/ci-pyvista-crash
Feb 28, 2026
Merged

Fix CI abort: skip PyVista Plotter test on headless runners#59
lmoresi merged 1 commit intodevelopmentfrom
bugfix/ci-pyvista-crash

Conversation

@lmoresi
Copy link
Member

@lmoresi lmoresi commented Feb 28, 2026

Summary

  • test_pyvista_plotter_available creates a pv.Plotter(off_screen=True) which calls VTK's OpenGL probe — this aborts the entire process on headless GitHub Actions runners (no DISPLAY). The abort kills the test_08* pytest session (334 tests), masking all results from that batch.
  • Added HAS_DISPLAY check using DISPLAY, WAYLAND_DISPLAY, or PYVISTA_OFF_SCREEN environment variables. Plotter tests skip when no display is available.
  • Fixed \*\*kwargs escape sequences in model.py and materials.py docstrings (Python 3.12+ SyntaxWarning).

Test plan

  • test_0800_optional_modules.py passes locally (10 passed, 4 skipped)
  • Plotter test correctly skipped when no display available
  • Docstring escape warnings eliminated
  • CI should now pass all 334 tests in the test_08* batch (instead of aborting)

Underworld development team with AI support from Claude Code

pv.Plotter() calls VTK's OpenGL probe which aborts the entire process
on headless CI (no DISPLAY). This killed the test_08* pytest session,
masking all 334 tests in that batch.

Fix: add HAS_DISPLAY check (DISPLAY, WAYLAND_DISPLAY, or
PYVISTA_OFF_SCREEN env var) and skip plotter tests when no
display is available. Also fix escaped-star docstring warnings
in model.py and materials.py.

Underworld development team with AI support from Claude Code
Copilot AI review requested due to automatic review settings February 28, 2026 19:14
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes a CI abort issue where test_pyvista_plotter_available was calling pv.Plotter(off_screen=True), which triggers VTK's OpenGL probe on headless GitHub Actions runners (no DISPLAY), causing a process abort that killed the entire test_08* pytest session. The fix introduces a display availability check and a new requires_pyvista_rendering skip marker, so the Plotter test is skipped on headless runners. The PR also fixes Python 3.12+ SyntaxWarning caused by unescaped \*\* in docstrings in model.py and materials.py.

Changes:

  • Added HAS_DISPLAY / HAS_PYVISTA_RENDERING flags and a requires_pyvista_rendering skip marker based on display environment variable detection
  • Switched test_pyvista_plotter_available from @requires_pyvista to @requires_pyvista_rendering and added a global pv.OFF_SCREEN = True assignment
  • Fixed \*\*kwargs and \*args docstring escape sequences in model.py and materials.py

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
tests/test_0800_optional_modules.py Adds display detection logic and requires_pyvista_rendering marker; updates Plotter test to skip on headless CI
src/underworld3/model.py Fixes \*\*kwargs escape sequences in three docstrings to resolve Python 3.12+ SyntaxWarnings
src/underworld3/materials.py Fixes \*args escape sequence in one docstring

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

import pyvista as pv

# Just verify we can create a plotter (off-screen)
pv.OFF_SCREEN = True
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

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

Setting pv.OFF_SCREEN = True as a global module-level attribute mutation inside a test method has a side effect: it permanently modifies the PyVista global state for the entire test session. Any subsequent tests that create a pv.Plotter() without off_screen=True will inherit this global flag. Since this test already passes off_screen=True directly to pv.Plotter(), the global pv.OFF_SCREEN = True assignment is redundant and should be removed to avoid unintended side effects on other tests.

Suggested change
pv.OFF_SCREEN = True

Copilot uses AI. Check for mistakes.

requires_pyvista_rendering = pytest.mark.skipif(
not HAS_PYVISTA_RENDERING,
reason="Requires pyvista and a display server (DISPLAY or PYVISTA_OFF_SCREEN)"
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

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

The skip reason at line 112 mentions only DISPLAY and PYVISTA_OFF_SCREEN, but the HAS_DISPLAY check at line 58-59 also includes WAYLAND_DISPLAY. The reason message should mention all three environment variables to give users accurate guidance on how to enable the test.

Suggested change
reason="Requires pyvista and a display server (DISPLAY or PYVISTA_OFF_SCREEN)"
reason="Requires pyvista and a display server (DISPLAY, WAYLAND_DISPLAY, or PYVISTA_OFF_SCREEN)"

Copilot uses AI. Check for mistakes.
# On headless CI (no DISPLAY, no WAYLAND), pyvista.Plotter() calls
# VTK's OpenGL probe which aborts the entire process — not catchable
# with try/except. We must skip rendering tests before they run.
import os
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

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

The import os statement is placed mid-file at line 57, after module-level dependency flags have already been set. The existing imports at the top of the file (lines 22-25) are where os should be imported along with pytest and sys. Placing imports mid-module deviates from PEP 8 conventions and from the import pattern used throughout this file. Move import os to the top-level imports block near line 22-24, alongside import pytest and import sys. Note that os is also re-imported inside check_petsc_has_pragmatic() at line 70, which would then be unnecessary.

Copilot uses AI. Check for mistakes.
@lmoresi lmoresi merged commit a769793 into development Feb 28, 2026
5 checks passed
@lmoresi lmoresi deleted the bugfix/ci-pyvista-crash branch February 28, 2026 20:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants