Fix CI abort: skip PyVista Plotter test on headless runners#59
Fix CI abort: skip PyVista Plotter test on headless runners#59lmoresi merged 1 commit intodevelopmentfrom
Conversation
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
There was a problem hiding this comment.
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_RENDERINGflags and arequires_pyvista_renderingskip marker based on display environment variable detection - Switched
test_pyvista_plotter_availablefrom@requires_pyvistato@requires_pyvista_renderingand added a globalpv.OFF_SCREEN = Trueassignment - Fixed
\*\*kwargsand\*argsdocstring escape sequences inmodel.pyandmaterials.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 |
There was a problem hiding this comment.
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.
| pv.OFF_SCREEN = True |
|
|
||
| requires_pyvista_rendering = pytest.mark.skipif( | ||
| not HAS_PYVISTA_RENDERING, | ||
| reason="Requires pyvista and a display server (DISPLAY or PYVISTA_OFF_SCREEN)" |
There was a problem hiding this comment.
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.
| 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)" |
| # 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 |
There was a problem hiding this comment.
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.
Summary
test_pyvista_plotter_availablecreates apv.Plotter(off_screen=True)which calls VTK's OpenGL probe — this aborts the entire process on headless GitHub Actions runners (noDISPLAY). The abort kills thetest_08*pytest session (334 tests), masking all results from that batch.HAS_DISPLAYcheck usingDISPLAY,WAYLAND_DISPLAY, orPYVISTA_OFF_SCREENenvironment variables. Plotter tests skip when no display is available.\*\*kwargsescape sequences inmodel.pyandmaterials.pydocstrings (Python 3.12+ SyntaxWarning).Test plan
test_0800_optional_modules.pypasses locally (10 passed, 4 skipped)test_08*batch (instead of aborting)Underworld development team with AI support from Claude Code