Skip to content

[CI-test] Split OS-specific addon tests via filename convention#10

Closed
eduralph wants to merge 4 commits into
maintenance/gramps60from
feature/ci-cd-pipeline-upstream
Closed

[CI-test] Split OS-specific addon tests via filename convention#10
eduralph wants to merge 4 commits into
maintenance/gramps60from
feature/ci-cd-pipeline-upstream

Conversation

@eduralph

Copy link
Copy Markdown
Owner

Fork-internal PR to trigger CI on the filename-convention split.

Summary

  • Introduces test_{linux,windows,integration}_*.py filename convention in ci.yml filters
  • Splits TMGimporter/tests/test_libtmg.py: 13 DB-backed classes → test_linux_libtmg.py; 7 pure-logic classes stay
  • Expected: unit-test-windows no longer hangs (skips test_linux_libtmg.py); Linux still runs both

Validation done locally

  • Both new/modified files compile (py_compile)
  • Both new/modified files pass all 175 tests via gramps-testbed runner
  • Simulated ci.yml filter logic confirms Windows skips test_linux_libtmg.py while Linux runs both

Test plan

  • Unit Tests (Linux) green
  • Unit Tests (Windows) completes without hanging
  • Integration Tests (Gramps) green

The Dockerfile bakes in only `dbf`, but addons declare a wider set of
Python deps in their .gpr.py `requires_mod` lists (networkx, psycopg2,
pygraphviz, lxml, svgwrite, boto3, litellm, life_line_chart, psycopg).
Without these installed, per-addon unit tests and the plugin-
registration subprocess load fail with ImportError/NameError.

Add a pre-test step to unit-test-linux, unit-test-windows, and
integration-test that globs every *.gpr.py, extracts the requires_mod
union via ast.literal_eval, and pip-installs each package one at a
time. Per-package install (not batched) keeps a single build failure
(pygraphviz without graphviz-dev, psycopg2 without libpq-dev) from
aborting the rest — the affected addon's tests will skip or fail in
isolation without blocking others.

Mirrors Gramps' Addon Manager install path
(gramps/gui/plug/_windows.py __on_install_clicked → req.install →
gen/utils/requirements.py), keeping .gpr.py files as the single source
of truth for addon deps. New addon deps do not need a parallel update
to the Dockerfile or this workflow.
With ci.yml's auto-derive step in place (previous commit), dbf is
installed at CI runtime from TMGimporter's .gpr.py requires_mod list.
Keeping it baked into the Dockerfile and environment.yml in parallel
would defeat the "single source of truth = .gpr.py" goal and drift
the moment a new addon declares an additional dep.

Remove dbf from both; leave the stable base (PyGObject, pycairo,
Gramps, orjson, ruff) since those are not addon deps. Add a comment
pointing readers at the auto-derive step so future edits do not
re-bake runtime deps back in.
Root cause of "Unit Tests (Linux)" and "Integration Tests (Gramps)"
failures was not broken test modules — the steps never invoked
unittest. The container's default shell is /bin/sh (dash on
python:3.12-slim), and the inline scripts use bash-only parameter
expansions (${f%.py}, ${mod//\//.}) to build the dotted module list.
Dash fails with "Bad substitution" on the first such line; the rest
of the script never runs. continue-on-error: true masked this as a
generic job failure for two CI rounds.

Add "shell: bash" explicitly to:
- unit-test-linux / Run per-addon unit tests (bashisms)
- integration-test / Run per-addon integration tests (bashisms)
- integration-test / Run plugin registration tests (no bashisms today,
  but consistent and future-proof)

Compile Check already sets shell: bash. Windows jobs inherit bash
via defaults.run at the job level. No other steps affected.
The Windows unit-test job hung on TMGimporter's DB-backed tests because
make_database("sqlite").load(":memory:", None) deadlocks under the
conda-forge GTK + pip Gramps combination. Rather than patch the hang,
introduce a filename convention so per-addon authors can declare OS
scope up front:

  test_*.py              general (every OS)
  test_linux_*.py        Linux-only
  test_windows_*.py      Windows-only
  test_integration_*.py  Linux-only, full-pipeline/DB-backed (pre-existing)

unit-test-linux skips test_windows_* and test_integration_*;
unit-test-windows skips test_linux_* and test_integration_*.

Applied to TMGimporter: the 13 DB-backed classes in tests/test_libtmg.py
move to tests/test_linux_libtmg.py (along with the _Rec/_table/_make_db/
_add_person/_MockUser helpers they use). The 7 pure-logic classes
(TestStripTmgCodes, TestTmgDateToGrampsDate, TestNumTo{Month,Date},
TestParseDate, TestRepoTypeFromName, TestUrlFromName) stay in
test_libtmg.py and will run on every OS.

Locally all 175 tests still pass via run-addon-unit.sh TMGimporter.
@eduralph

Copy link
Copy Markdown
Owner Author

CI signal captured: Windows completed in 3m43s instead of hanging. Filename convention merged upstream into PR gramps-project#820 → see commit 715e71d.

@eduralph eduralph closed this Apr 20, 2026
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.

1 participant