Skip to content

Skip SGE submission for tests with invalid qsub options, and add a self-test suite - #53

Open
milechin wants to merge 7 commits into
mainfrom
qsub_validate_nf
Open

Skip SGE submission for tests with invalid qsub options, and add a self-test suite#53
milechin wants to merge 7 commits into
mainfrom
qsub_validate_nf

Conversation

@milechin

@milechin milechin commented Jul 9, 2026

Copy link
Copy Markdown
Collaborator

Skip SGE submission for tests with invalid qsub options, and add a self-test suite

Summary

Builds on the existing qsub_valid column (from #47) to make the pipeline act on it. Tests whose qsub options are rejected by qsub -w p are no longer submitted to SGE — they are marked FAILED locally instead of being silently dropped when the scheduler rejects the job at submission. Also adds the repo's first automated test suite, covering this end to end.

What changed

Execution — nextflow/pkgtest.nf

  • The workflow now branches input rows on qsub_valid:
    • TruerunTests (submitted to SGE, unchanged behavior).
    • not True → a new reportInvalid process pinned to executor 'local', so no job is submitted to the scheduler. It records the test as FAILED (exit_code=1, tests_failed=1, job_number=NA) with an explanatory results.txt.
  • Both paths emit the same 13-column test_metrics.csv, so the report layout is unchanged and email_notif.pl / the rshiny app are unaffected.
  • Rationale: the CSV qsub_options are injected into each job's clusterOptions, so invalid options make SGE reject the job at submission — before any in-process guard inside runTests could run. Handling it outside runTests is the only place that works.

Tests — new tests/ directory (pytest)

  • First self-test suite: validates find_qsub.py + pkgtest.nf against a checked-in fixture (a fake module pkgselfcheck/1.0 with one valid and one invalid test.qsub).
  • test_invalid_qsub.py asserts that find_qsub.py sets qsub_valid correctly, and that the pipeline PASSES the valid test while FAILING the invalid one via reportInvalid (job_number=NA), never submitting it.
  • Two tiers via a --mode option:
    • local (default) — stubs replace module/qsub and the pipeline runs --executor local: no Lmod, no SGE, no module load. Runs in the conda env (tests/environment.yml).
    • integration — real Lmod module, real qsub, and real SGE on an SCC node.
  • find_qsub.py is not modified for testing; it runs as a subprocess with a scrubbed env (Lmod's exported module function removed, stubs prepended to PATH).
  • Extensible: add a future test as a new tests/test_<feature>.py reusing the run_env fixture in tests/conftest.py.
  • tests/environment.yml pins nextflow>=24 and openjdk=17; leaving them unpinned lets conda install a JDK newer than Nextflow supports (Java 11–21), which fails with "cannot find Java or it's a wrong version".

Docs

  • README.md gains a Testing section; CLAUDE.md added with architecture notes and the branching behavior; .gitignore excludes the test runtime artifacts.

Testing

  • Local tier green: bash tests/run_local.sh -v → 2 passed (Nextflow --executor local, no SGE).
  • Integration behavior verified manually on the SCC with gdal2.csv: the invalid gdal/3.1.2 row is reported FAILED/NA with no SGE job submitted, and the valid rows submit and PASS.

How to run the tests

conda env create -f tests/environment.yml   # on the SCC: module load miniconda first
conda activate pkgautotest-selftest
bash tests/run_local.sh -v

milechin and others added 7 commits July 9, 2026 16:28
find_qsub.py's qsub_valid column flags tests whose qsub options were
rejected by `qsub -w p` at discovery time. pkgtest.nf now branches the
input channel on it: valid rows go to runTests (submitted to SGE, as
before) while invalid rows go to a new reportInvalid process pinned to
`executor 'local'`, so no job is submitted to the scheduler. Invalid
tests are recorded as FAILED (exit_code=1, tests_failed=1, job_number=NA)
with an explanatory results.txt, and merged into the same report.

This avoids the prior behavior where invalid qsub_options, injected into
the job's clusterOptions, made SGE reject the job at submission time --
before any in-script guard could run -- so the row silently dropped from
the report.

The report's 13-column layout is unchanged, so email_notif.pl and the
rshiny app are unaffected. Updates README.md and CLAUDE.md to document
the new behavior.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds the repo's first tests/ directory as a small, extensible pytest suite
that validates find_qsub.py and pkgtest.nf against a checked-in fixture
(a fake module pkgselfcheck/1.0 with a valid test.qsub and an invalid
test.bad.qsub). test_invalid_qsub.py asserts: find_qsub sets qsub_valid
True/False correctly, and the pipeline PASSES the valid test while FAILING
the invalid one via reportInvalid (job_number=NA), never submitting it.

Two tiers via --mode:
- local (default): stubs replace `module`/`qsub` (tests/stubs/) and the
  pipeline runs --executor local -- no Lmod, no SGE, no `module load`. Runs
  in the conda env (tests/environment.yml). find_qsub.py is not modified;
  it runs as a subprocess with a scrubbed env (Lmod's exported `module`
  function removed, stubs prepended to PATH).
- integration: real Lmod/qsub + real SGE on an SCC node.

Shared machinery (fixture build, per-mode env, runners, CSV-by-header
parsing, preflight skips) lives in conftest.py's run_env fixture; add a
future test as tests/test_<feature>.py reusing it.

environment.yml pins nextflow>=24 and openjdk=17: leaving them unpinned
lets conda install a JDK newer than nextflow supports (Java 11-21), which
fails with "cannot find Java or it's a wrong version".

Docs: README.md gains a Testing section; CLAUDE.md's stale "no test suite"
note now describes the suite; .gitignore excludes the runtime artifacts.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Runs the local (scheduler-free) tier of the pytest suite on push to main
and on pull requests: installs Python + Nextflow + Java, points /bin/sh at
bash (find_qsub.py uses the `|&` bashism, unsupported by ubuntu's dash),
ensures ~/.bashrc exists (pkgtest.nf's beforeScript sources it), then runs
tests/run_local.sh and uploads the JUnit results. The integration tier is
SCC-only and is not run in CI.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The `get.nextflow.io` installer writes a file named `nextflow` in the
current directory; run from the repo root it collided with the repo's
nextflow/ directory and aborted. Run the installer in $RUNNER_TEMP.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Nextflow latest (26.x) runs task scripts with pipefail, which aborts
pkgtest.nf runTests where `grep Error | wc -l` finds no match on a
passing test. Pin NXF_VER to a version used on the cluster.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Nextflow runs task scripts with set -u, and pkgtest.nf runTests echoes
SGE-provided vars ($NSLOTS, $QUEUE, $JOB_ID). Off-SGE (executor local,
e.g. GitHub Actions) these are unset and abort the task. The local-mode
test env now supplies inert defaults. Also removes the temporary CI
diagnostic step.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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