Skip to content

Navier-Stokes with Eulerian SUPG momentum transport, and a partition-independent cell size (#687) #1436

Navier-Stokes with Eulerian SUPG momentum transport, and a partition-independent cell size (#687)

Navier-Stokes with Eulerian SUPG momentum transport, and a partition-independent cell size (#687) #1436

name: test_uw3
# Build + test on every PR / push to main / development.
#
# Uses pixi (with the committed pixi.lock) for a deterministic, fast install
# rather than micromamba + environment.yaml, which had been backtracking for
# 60+ minutes on conda-forge solves and timing the runner out before tests
# could start. The pixi.lock matches what local development uses, so CI now
# runs against the same dependency state developers see.
on:
push:
branches:
- main
- development
- Quick_Start_Docs
pull_request:
workflow_dispatch:
env:
# Some Azure runners carry a MANA NIC whose InfiniBand verbs device UCX
# advertises but cannot open: uct_iface_open(ud_verbs/mana_0) fails inside
# MPI_Init, so `import underworld3` dies before any UW3 code runs (issues
# #461/#528 — four hits in the first week of 2026-08, each costing a manual
# re-roll). A single-node CI runner needs only shared memory and TCP, so pin
# the UCX transports and retire the whole flake class.
UCX_TLS: tcp,sm,self
# Distribute the serial batches across worker processes. This was held back
# until #567 was fixed: worker counts change which files share a process, and
# a units test that switched the units system on at import time then reached
# a module-scoped fixture in the point-locator suite before anything reset it.
# That is fixed at source in tests/conftest.py, and the whole suite is green
# at 4, 8 and 16 workers.
#
# 4 is the vCPU count of the runner. Do NOT try to detect it: the first
# attempt derived the count inside the job, got 1, and ran xdist with a single
# worker — a spawn and a fresh underworld3 import per batch, parallelising
# nothing, for 52m37s. The MPI batches are unaffected either way; they run
# their own mpirun.
WORKERS: 4
jobs:
test:
runs-on: ubuntu-latest
# The suite has outgrown 60 minutes. Measured 2026-08-15: the SERIAL phase
# alone is ~55 min (three batches at 14-15 min each), so the parallel phase
# - which runs last - was being cut off mid-run and reported as a failure
# that looked like a test failure. Any addition at all pushed a run over.
# This is a stop-gap that unblocks landing work; the durable fix is to split
# the batches across parallel jobs so wall-clock stops tracking total test
# time. See the CI-runtime issue for that.
timeout-minutes: 120
steps:
- uses: actions/checkout@v4
- name: Install pixi from lockfile
uses: prefix-dev/setup-pixi@v0.9.4
with:
# Use the env that matches local development for tests.
# `dev` = conda-petsc + runtime + dev features (pytest, jupyter, etc.)
environments: dev
# Hard-fail if pixi.lock disagrees with pixi.toml — never re-solve
# silently in CI; that's exactly the failure mode we're escaping.
frozen: true
cache: true
- name: Build UW3
# `pixi run -e dev build` invokes the build task from pixi.toml,
# which is `pip install . --no-build-isolation` (non-editable —
# editable installs are project policy violation, see CLAUDE.md).
run: pixi run -e dev build
# Import smoke test: a hard crash during `import underworld3` (segfault
# / abort in a compiled module, e.g. from a poisoned env cache) kills
# pytest BEFORE its first stdout flush, so every batch below fails with
# zero output and the run is undiagnosable from the log (this happened
# on PR #394 — a runner-side flake that cost a full debug round-trip).
# This 5-second step makes any import-time crash loud and localised:
# faulthandler prints the native traceback here rather than nothing
# there.
- name: Import smoke test (faulthandler)
run: pixi run -e dev python -u -X faulthandler -c "import faulthandler; faulthandler.enable(); import underworld3; print('import OK', underworld3.__version__)"
- name: Run tests
run: pixi run -e dev ./scripts/test.sh --p 2