目录

sap (SRASS Application Platform)

Web-based seismic computing platform that consumes SRASS over VPN+SSH on domestic HPC systems (Tianhe, Dawning, Shenwei). No agent is installed on the supercomputer login node; all interaction goes through ssh/scp.

Status

Phase 1 MVP:

  • P1 Backend — see docs/superpowers/specs/2026-06-17-sap-phase1-mvp-design.md
  • P1 Frontend scaffold — Vite + React + TS, routing, job list view
    • polling.
  • P1 Frontend round 2 (submit form + multipart file uploads)
  • P1 Frontend round 3 (detail page + status timeline + outputs + logs)
  • P2 End-to-end integration on a real Tianhe account — full job lifecycle (DRAFT → PENDING_UPLOAD → SUBMITTING → QUEUED → RUNNING → COMPLETED) verified against hnu_wuq@25.8.100.22 (Tianhe new-generation, partition mt_module, account ecology). /api/jobs/{id}/output and /api/jobs/{id}/logs serve real artifacts fetched eagerly on COMPLETED.
  • P2 Automated real-Tianhe integration suite (tests/integration/test_tianhe_real.py) — 11 gated tests covering sinfo smoke + sbatch hello + Tier 1 (FAKE_SRASS) lifecycle for forward/fwi/grond/unicycle + compute-node PATH propagation
    • real startup recovery (submit → seed orphan YAML → restart Scheduler → verify re-attach via real squeue/sacct instead of LOST). Tier 1.5 fwi/grond/unicycle SKIPPED with informative reasons documenting three upstream SRASS wrapper bugs on this operator’s cluster (fwi: mpich/mpi-x vs PMI2 mismatch; grond: CLI surface difference; unicycle: missing libcurl.so.4 / libnetcdff.so.7). NOTE: this cluster’s mt_module partition is INACTIVE (2026-07-01 — all nodes drain/down/resv); tests default to SAP_TIANHE_PARTITION=ft_module which has 110+ idle nodes.
  • Dawning (Sugon new-generation) real-HPC integration — SRASS uploaded, built on the hpctest06 compute nodes, and verified with a SLURM smoke test. DawningPlatform now generates srass specfem3d-globe forward ... jobs for the new SRASS CLI.

Real-HPC bugs fixed during end-to-end testing (2026-06-22 / 23)

The unit / integration tests pass against mocks, but the mocks cannot reproduce the SLURM toolchain’s exact behavior. End-to-end runs against the real Tianhe cluster surfaced six bugs that the test suite could not:

# Bug Surface Fix
1 scp_upload does not expand $HOME (sftp-server has no shell) First submit failed SSHClient._resolve_remote_path caches remote_home and rewrites paths before scp
2 #SBATCH --chdir=$HOME/... is parsed literally by SLURM JobLaunchFailure (workdir concatenation) TianhePlatform._workdir resolves $HOME to absolute before generating the sbatch script
3 SlurmClient.query raises on squeue "Invalid job id" for completed jobs Scheduler stuck polling forever squeue wrapped in try/except SSHError; falls through to sacct
4 State machine rejects QUEUED → COMPLETED for fast jobs Job stuck at QUEUED after run Added COMPLETED to the allowed set under QUEUED
5 GET /api/jobs/{id}/logs was never wired up to anything Endpoint existed, always 404 New Platform.download_log + JobService.download_log + eager fetch in scheduler on COMPLETED
6 GET /api/jobs/{id}/output listed local files only, never invoked download_outputs Endpoint existed, always empty Eager fetch in scheduler on COMPLETED pulls remote output dir to local

Every fix has a regression test. Total tests: 270 backend + 96 frontend = 366 (259 → 270 added 2026-07-02 with the new test_tianhe_real.py suite: 8 passing (2 smoke + 4 Tier 1 lifecycle + 1 startup recovery + 1 compute-node PATH propagation) and 3 skipped with informative reasons documenting three upstream SRASS wrapper bugs on this Tianhe cluster. The original 259 includes the Dawning real-SRASS Tier 1.5 + Tier 2 suite.) (up from 242 after adding 17 new tests on 2026-06-30 for the Unicycle “restrict + sniff” change: the public schema now exposes only the two Unicycle variants actually built into SRASS 0.4.0 on Dawning hpctest06 (3d-ratestate, 3d-viscouscycles) — the other 10 entries in srass/commands/unicycle.py:VARIANTS are accepted by FAKE_SRASS but missing from the real build, so they were dead options in the public schema. A submit-time sniffer (sniff_unicycle_param_format in sap/clients/command_templates.py) now rejects param files in the TOML/INI format that the un-deployed ap-* / ps-* variants read, returning 422 with a clear message instead of letting the user queue a job the real solver would reject with a confusing upstream error. The sniffer is unit-tested (11 cases covering fortran/toml/ empty/prose/leading-comments) and the API is tested for the positive (Fortran-format accepted for both built variants) and negative (TOML/binary rejected, non-unicycle jobs never sniffed, variant-only submissions skip the check). The Tier 1 + Tier 1.5 + Tier 2 unicycle tests all share one fixture (tests/fixtures/unicycle_params) that is now in the Fortran list-directed format the real solver reads. The 242 baseline came from test_dawning_full_lifecycle_{fwi,grond,unicycle}_real_srass on 2026-06-30 — full sap lifecycle DRAFT→COMPLETED for fwi/grond/unicycle on real Dawning hpctest06 against the real SRASS 0.4.0 build at /public/home/scnethpc26108/SRASS/build/bin/, closing the “Tier 1.5” gap: the three Tier 1 FAKE_SRASS tests prove the dispatch + state machine work, and the three Tier 2 e2e tests prove the real solver runs, but no test combined both — i.e. showed JobService + Scheduler + DawningPlatform driving a real SRASS 0.4.0 invocation through to COMPLETED. Tier 1.5 fwi=19s, grond=38s, unicycle=35s. The 239 baseline came from test_dawning_{fwi,grond,unicycle}_real_srass_e2e (added 2026-06-29 — full real-SRASS 0.4.0 coverage for all three remaining job_types on Dawning hpctest06: SPECFEM3D Cartesian FWI (3-step pipeline: setup_models + create_raw_data + run_inversion) in 540s, Grond init + check in 117s, Unicycle 3d-ratestate in 117s) plus test_dawning_forward_real_srass_e2e (added 2026-06-29 — full SPECFEM3D Globe meshfem + forward pipeline on real SRASS 0.4.0 producing real seismograms, validated end-to-end on hpctest06 in 33.9s) plus three Tier 1 FAKE_SRASS lifecycle tests test_dawning_full_lifecycle_{fwi,grond,unicycle} plus Tier 0 lifecycle + smoke, all walking the full DRAFT → COMPLETED on real Dawning via the FAKE_SRASS harness and asserting both the dispatched sbatch script shape and the eager artifact fetch.) The Dawning forward end-to-end walk (DRAFT → PENDING_UPLOAD → SUBMITTING → QUEUED → RUNNING → COMPLETED plus eager output + log fetch) is covered by tests/integration/test_dawning_real.py::test_dawning_full_lifecycle_draft_to_completed, gated on SAP_DAWNING_KEY_PATH + SAP_DAWNING_USER + SAP_DAWNING_SRASS_BIN_DIR.

The per-platform forward override itself was validated end-to-end on real Dawning hpctest06 on 2026-06-27 against the real SRASS 0.4.0 wrapper at /public/home/scnethpc26108/SRASS/build/bin/: (a) sbatch job 630147 invoked srass specfem3d-globe forward --par=<uploaded Par_file> --nprocs=1 and the wrapper accepted the CLI (no unrecognized arguments) and proceeded to mpirun-launch srass-specfem3d-globe; (b) the full sap lifecycle test (test_dawning_full_lifecycle_draft_to_completed) drove DRAFT → COMPLETED through JobService + Scheduler + DawningPlatform in 31.9s on the cluster.

The full compute pipeline behind that CLI was then validated end-to-end on 2026-06-29: test_dawning_forward_real_srass_e2e stages the smallest viable SPECFEM3D Globe configuration (NEX=16 / NPROC=1 / RECORD=0.05d0) with MODEL = 1D_transversely_isotropic_prem, sources the HPCSDK toolchain on the compute node, and runs meshfem (2s) + forward (10s) against the real SRASS build — producing 15 real .sem.ascii seismograms (5 stations × 3 components, max amplitude ~7.7e-7) that the test verifies contain non-zero samples. This is the final closure proof: the upstream smoke test only proves the binary loads; this test proves the solver actually computes.

All fourteen Dawning integration tests pass in ~12.5 min wall-clock:

  • test_dawning_ssh_sinfo <2s
  • test_dawning_slurm_submit_hello_job ~13s
  • test_dawning_srass_specfem3d_globe_smoke ~14s (real SRASS --smoke)
  • test_dawning_full_lifecycle_draft_to_completed ~32s (FAKE_SRASS)
  • test_dawning_full_lifecycle_fwi ~36s (FAKE_SRASS)
  • test_dawning_full_lifecycle_grond ~36s (FAKE_SRASS)
  • test_dawning_full_lifecycle_unicycle ~36s (FAKE_SRASS)
  • test_dawning_full_lifecycle_fwi_real_srass ~19s (real SRASS via sap lifecycle)
  • test_dawning_full_lifecycle_grond_real_srass ~38s (real SRASS via sap lifecycle)
  • test_dawning_full_lifecycle_unicycle_real_srass ~35s (real SRASS via sap lifecycle)
  • test_dawning_forward_real_srass_e2e ~34s (real SRASS meshfem+forward)
  • test_dawning_fwi_real_srass_e2e ~540s (real SRASS FWI: setup_models + create_raw_data + run_inversion)
  • test_dawning_grond_real_srass_e2e ~117s (real SRASS Grond init+check)
  • test_dawning_unicycle_real_srass_e2e ~117s (real SRASS Unicycle 3d-ratestate)

The three new real-SRASS e2e tests validate compute pipelines, not just CLI acceptance:

  • test_dawning_fwi_real_srass_e2e runs SPECFEM3D Cartesian’s fwi_test_acoustic end-to-end (setup_models → create_raw_data → run_inversion), asserting all three sub-scripts return 0 and that output_inverse.txt contains real FWI markers. The example is staged as a real directory at the canonical depth inside the specfem3d tree because 0.setup_models.sh uses relative ../../../../bin/x* paths (a symlink trick doesn’t work — bash .. follows the physical path through the symlink). NPROC=1 is set, plus NPROC_ETA=1 in both Mesh_Par_file.TRUE and Mesh_Par_file.INIT (required for serial). LOCAL_PATH is not overridden because xmeshfem3D ignores absolute paths and writes to ./DATABASES_MPI/ regardless — the safest path is to keep the upstream default.
  • test_dawning_grond_real_srass_e2e runs srass-grond init example_regional_cmt example (which generates a real ~3KB Grond config from the bundled example problem) followed by srass-grond check <config> <event>. The init must return 0 and the generated config must contain Grond markers ([, ], engine, problem_name). Pyrocko must be installed in the runtime python (see docs/sugon-usage.md).
  • test_dawning_unicycle_real_srass_e2e runs srass-unicycle-3d-ratestate with a minimal hand-written parameter file (one rectangle, one frictional rectangle, zero observations/events). Asserts rc=0 and at least one patch-*.{dat,grd,vtp,xyz} output. The output directory and time.dat file must be pre-created because Unicycle’s Fortran input.f90 opens output/time.dat with POSITION="APPEND" and fails if either is missing (a known Unicycle upstream quirk; the production build_unicycle_sbatch_script now prepends mkdir -p output; : > output/time.dat so the run.sh works without the operator knowing about this).

The three new “Tier 1.5” tests close the lifecycle gap: the Tier 1 FAKE_SRASS tests prove sap’s JobService + Scheduler + DawningPlatform correctly dispatch the right sbatch script and walk the job to COMPLETED, and the Tier 2 e2e tests prove the real SRASS solvers actually run, but no test combined both — i.e. showed the sap lifecycle driving a real SRASS 0.4.0 invocation through to COMPLETED. The Tier 1.5 tests are exactly that: same dispatch path as the Tier 1 tests but with srass_bin_dir pointed at the real SRASS build instead of ~/srass_bin. Each runs in well under a minute on hpctest06 (fwi 19s, grond 38s, unicycle 35s) because the real wrappers may exit 0 even when the minimal fixtures are non-physical — the production cost of running real solvers on real data is paid by the Tier 2 tests; what Tier 1.5 proves is that the dispatch + state machine + eager-fetch correctly drive a real SRASS invocation, which is what the operator actually cares about for day-to-day platform smoke-testing.

Note (2026-08-07): Dawning (Sugon new-generation) resources were shut down in August 2026. The 14 Dawning integration tests are preserved but skip without SAP_DAWNING_KEY_PATH. Tianhe is the sole operational platform.

2026-08-07 updates

  • Tianhe integration suite re-verified — 8 pass / 3 skip against the live Tianhe cluster (partition ft_module, 121 idle nodes). ~90s wall-clock.
  • ~ expansion bug fixedTianhePlatform.__init__ now resolves ~/ $HOME via _resolve_remote_path before passing srass_bin_dir to the sbatch header (previously shlex.quote single-quoted ~ → exit 127).
  • grond subcommand schema — added subcommand select field (check/go/report/…) matching real SRASS srass grond <subcommand> <args>. Backend templates, platform dispatch, and frontend form/test all updated.
  • fwi upstream SRASS wrapper bug fixedsrass/commands/specfem3d.py::run_inverse was calling run_cmd([exe]), dropping --par. Fixed on cluster.
  • PYTHONPATH supportbuild_sbatch_header accepts srass_pythonpath for real SRASS Python package on Tianhe compute nodes.
  • openmpi build — Tianhe real-SRASS defaults switched to build-openmpi/bin, avoiding the PMI2 runtime mismatch.
  • Vite proxy parameterized via SAP_BACKEND_URL env var.
  • bootstrap scriptscripts/bootstrap.sh for one-step dev setup.

Total: 233 backend + 96 frontend = 329 tests passing.

Tier 1.5 (real SRASS) status

Infrastructure ready but tests remain skipped due to upstream behavior:

job_type blocker
fwi binary ignores --par when DATA/Par_file missing in workdir
grond srass-grond needs valid config + event
unicycle missing libnetcdff.so.7 on compute nodes

Phase 1 scope

Minimum end-to-end slice started with one job type (球坐标全球正演 / forward) on one platform (Tianhe) and has since expanded to four job types on two working platforms. Dawning is a working SLURM adapter and has been validated end-to-end on the scnet.cn E-Shell gateway; Shenwei remains a stub that returns 501 Not Implemented.

Supported job types (see GET /api/job-types for the live schemas):

name label SRASS CLI inputs
forward 球坐标全球正演 Tianhe: srass forward --nx=... --nt=... · Dawning: srass specfem3d-globe forward --par=<uploaded Par_file> --nprocs=N per-platform override; see below
fwi SPECFEM3D 反演 (Cartesian) srass specfem3d inverse --par=<uploaded Par_file> one required file
grond Grond 震源反演 srass grond <uploaded config> [-- <extra_args>] one required file + str
unicycle Unicycle 地震周期预测 srass unicycle <variant> [param_file] --nprocs=N optional file + 3 params; variant restricted to the 2 built into SRASS 0.4.0 (3d-ratestate, 3d-viscouscycles); param file must be Fortran list-directed format

forward per-platform schema override

The forward job_type has a different input schema on each platform because the SRASS CLI surface differs between Tianhe (legacy forward subcommand, accepts --nx/--ny/--nz/--nt flag set) and Dawning (SRASS 0.4.0, requires specfem3d-globe forward --par DATA/Par_file --nprocs N with a SPECFEM3D Globe Par_file). The form picks the per-platform schema from JobType.outrides[platform]; the backend’s DawningPlatform._build_sbatch_script dispatches to build_forward_parfile_sbatch_script while TianhePlatform keeps the legacy flag-style builder.

Platform Schema CLI
Tianhe nx (int), ny (int), nz (int), dx (float), dy (float), dz (float), nt (int), dt (float), output_dir (str, optional) srass forward --nx=… --ny=… --nz=… --dx=… --dy=… --dz=… --nt=… --dt=…
Dawning par_file (file, required), nprocs (int, optional, default 1) srass specfem3d-globe forward --par=<workdir>/input/Par_file --nprocs=N

Adjoint is intentionally deferred (not exposed by SRASS 0.4.0).

Running locally

Prerequisites: Python 3.11+, network access to the Tianhe login node.

cd backend
python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"

Set the required env vars (or put them in .env and export them):

export SAP_DATA_ROOT=$HOME/.local/share/sap
export SAP_TIANHE_HOST=tianhe.login.example
export SAP_TIANHE_USER=your-username

Tianhe environment variables

These knobs control how jobs are submitted to the Tianhe SLURM cluster. All have safe defaults so a vanilla uvicorn start works for CI / mock testing, but a real deployment needs at least SAP_TIANHE_ACCOUNT and SAP_TIANHE_QOS set (Tianhe rejects account-less submissions with Invalid account or account/partition combination).

Env var Default Meaning
SAP_TIANHE_HOST tianhe.login SSH hostname of the login node
SAP_TIANHE_USER sap SSH username
SAP_TIANHE_PARTITION mt_module SLURM partition to submit into. NOTE: on the operator’s cluster (hnu_wuq@25.8.100.22) mt_module is INACTIVE as of 2026-07-01 — set this to ft_module (or another active partition) for real submissions.
SAP_TIANHE_ACCOUNT (empty) SLURM account. Omit the #SBATCH --account directive when empty.
SAP_TIANHE_QOS (empty) SLURM QOS. Omit the #SBATCH --qos directive when empty.
SAP_TIANHE_SRASS_BIN_DIR (empty) Directory containing the FAKE_SRASS harness (bash script). Used by test_tianhe_real.py Tier 1 lifecycle tests. When set, the generated sbatch script prepends it to PATH on the compute node (login /tmp is not shared with compute nodes).
SAP_TIANHE_REAL_SRASS_BIN_DIR /vol8/home/hnu_wuq/srass-test/build-pmi2/bin Directory containing the real SRASS 0.4.0 build. The corresponding Tier 1.5 lifecycle tests are SKIPPED on Tianhe because the operator’s upstream wrapper has three documented bugs (see _TIANHE_TIER15_SKIP_REASONS in tests/integration/test_tianhe_real.py).

Worked example for the Tianhe new-generation system (hnu_wuq@25.8.100.22, partition ft_module because mt_module is INACTIVE on this cluster, account ecology, FAKE_SRASS at ~/srass_bin):

export SAP_TIANHE_HOST=25.8.100.22
export SAP_TIANHE_USER=hnu_wuq
export SAP_TIANHE_PARTITION=ft_module
export SAP_TIANHE_ACCOUNT=ecology
export SAP_TIANHE_QOS=nor8000
export SAP_TIANHE_SRASS_BIN_DIR=$HOME/srass_bin

Dawning (Sugon new-generation) environment variables

Dawning is accessed through the scnet.cn E-Shell gateway on a non-standard SSH port with key-based authentication. Set at least SAP_DAWNING_USER and SAP_DAWNING_KEY_PATH; the other knobs have safe defaults for the hpctest06 debug queue.

Env var Default Meaning
SAP_DAWNING_HOST zzeshell.scnet.cn E-Shell gateway hostname
SAP_DAWNING_PORT 65032 SSH port for the gateway
SAP_DAWNING_USER (empty) SSH username
SAP_DAWNING_KEY_PATH (empty) Path to the scnet.cn SSH private key
SAP_DAWNING_PARTITION hpctest06 SLURM partition to submit into
SAP_DAWNING_TIME_LIMIT 00:10:00 Wall-clock time limit for jobs
SAP_DAWNING_SRASS_BIN_DIR ~/srass_bin Directory containing the FAKE_SRASS harness. Used by the lifecycle e2e test.
SAP_DAWNING_REAL_SRASS_BIN_DIR /public/home/scnethpc26108/SRASS/build/bin Directory containing the real SRASS build. Used by the SRASS smoke test only.

Example (lifecycle test on Dawning):

export SAP_DAWNING_USER=scnethpc26108
export SAP_DAWNING_KEY_PATH=$HOME/.ssh/scnethpc26108_zzeshell.scnet.cn_RsaKeyExpireTime_2026-07-17_16-59-07.txt
export SAP_DAWNING_PARTITION=hpctest06
# Lifecycle test uses FAKE_SRASS by default. No need to override.
pytest -q -m integration tests/integration/test_dawning_real.py::test_dawning_full_lifecycle_draft_to_completed

To verify the real SRASS build instead (a manual sanity check on hpctest06, not part of CI):

export SAP_DAWNING_REAL_SRASS_BIN_DIR=/public/home/scnethpc26108/SRASS/build/bin
pytest -q -m integration tests/integration/test_dawning_real.py::test_dawning_srass_specfem3d_globe_smoke

Tianhe real-HPC integration tests

tests/integration/test_tianhe_real.py runs against the live Tianhe cluster. All tests are gated on SAP_TIANHE_KEY_PATH + SAP_TIANHE_USER (plus SAP_TIANHE_SRASS_BIN_DIR for the lifecycle tests). Default partition is ft_module because mt_module is currently INACTIVE on this cluster. Full wall-clock for all 11 tests: ~7 min on hnu_wuq account (cluster-load dependent).

export SAP_TIANHE_KEY_PATH=$HOME/.ssh/id_ed25519
export SAP_TIANHE_USER=hnu_wuq
export SAP_TIANHE_HOST=25.8.100.22
export SAP_TIANHE_PARTITION=ft_module
export SAP_TIANHE_ACCOUNT=ecology
export SAP_TIANHE_QOS=nor8000
export SAP_TIANHE_SRASS_BIN_DIR=$HOME/srass_bin
pytest -q -m integration tests/integration/test_tianhe_real.py

Three Tier 1.5 lifecycle tests (fwi/grond/unicycle against the real SRASS 0.4.0 build) SKIP with informative reasons — the operator’s upstream SRASS wrapper on this cluster has documented bugs that block end-to-end real-SRASS dispatch:

  • fwi: mpich/mpi-x (PMIx) vs SLURM PMI2 mismatch. Direct invocation of srass-specfem3d-inverse fails with MPI_Init failed: PMI2_Job_GetId returned 14. Workaround: srun --mpi=pmi2 -n 1 srass-specfem3d-inverse works, but the wrapper doesn’t emit srun. Fix: rebuild SRASS with openmpi.
  • grond: CLI surface difference. sap dispatches srass grond <config> but the operator’s wrapper expects <subcommand> <args> (e.g. srass grond check <config> <event>).
  • unicycle: missing libcurl.so.4 + libnetcdff.so.7 on compute node. The operator’s env.sh notes explicitly call this out: ‘libcurl.so.4 在计算节点缺失 (Unicycle 依赖)’. Fix: static linking or Singularity container.

The Dawning Tier 1.5 suite (tests/integration/test_dawning_real.py) covers the same dispatch path on a working wrapper. Once the operator rebuilds Tianhe SRASS with the fixes above, replace the pytest.skip(_TIANHE_TIER15_SKIP_REASONS[job_type]) calls with the standard prereq gate to enable these tests.

Dawning SRASS build

A CPU-only build of SRASS (SPECFEM3D_GLOBE only) has already been produced on the Dawning hpctest06 debug queue. The build script, source tree, and binaries are at:

/public/home/scnethpc26108/build_srass_cpu.sh   # sbatch script used
/public/home/scnethpc26108/SRASS/               # uploaded source tree
/public/home/scnethpc26108/SRASS/build/bin/     # srass + specfem3d-globe binaries

The build/bin/srass wrapper loads scripts/platform/dawning/env.sh so that python3, MPI, NetCDF, and the srass Python package are available on the compute node without requiring SAP to emit module load commands.

To rebuild or add components (Cartesian, Unicycle, Grond, HIP/DCU), edit the CMake flags in ~/build_srass_cpu.sh and submit it from the login node:

sbatch ~/build_srass_cpu.sh

Dawning FAKE_SRASS harness

Like Tianhe, Dawning has a FAKE_SRASS wrapper at ~/srass_bin/srass that accepts any args, writes a deterministic output/result.txt, and exits 0. It exists so the integration lifecycle test (DRAFT → COMPLETED plus eager output + log fetch) can run without burning real cluster queue slots or requiring a valid SPECFEM3D Par_file. The wrapper is intentionally separate from the real SRASS build at /public/home/scnethpc26108/SRASS/build/ so an operator can update one without touching the other.

The SAP_DAWNING_SRASS_BIN_DIR env var defaults to ~/srass_bin (the FAKE harness). To run the real-SRASS smoke test instead, set SAP_DAWNING_REAL_SRASS_BIN_DIR and run that test in isolation.

Then start the server in dev mode (auto-reload):

../scripts/dev.sh

Or directly:

uvicorn sap.main:app --reload --host 0.0.0.0 --port 8000

Running tests

Backend:

cd backend
pytest -q

Tests are organized:

  • tests/unit/ — module-level unit tests
  • tests/api/ — FastAPI TestClient tests
  • tests/integration/ — tests that hit a real HPC login node; currently test_dawning_real.py exercises the Dawning E-Shell gateway and SLURM scheduler (gated by SAP_DAWNING_KEY_PATH).

Frontend:

cd frontend
npm install
npm run test:run     # vitest run
npm run lint         # eslint
npm run typecheck    # tsc --noEmit
npm run build        # production bundle

Frontend tests live next to source as *.test.{ts,tsx}. Vitest with jsdom + @testing-library/react. Coverage: npm run test:coverage.

Frontend dev workflow

# Terminal 1: backend on :8000
cd backend && source .venv/bin/activate
uvicorn sap.main:app --reload

# Terminal 2: frontend dev server on :5173
cd frontend
npm run dev

The Vite dev server proxies /api/* to http://localhost:8000, so the frontend can call /api/jobs directly with no CORS configuration.

For production, run scripts/prod-build.sh from the repo root. It builds the frontend SPA into backend/sap/static/ and then packages the backend as a wheel. FastAPI serves the static files at / (API routes still take precedence).

API surface

Method Path Notes
GET /api/health Liveness probe
GET /api/platforms List known platforms + availability
GET /api/job-types List job types + param schemas
GET /api/jobs List all jobs
POST /api/jobs Create a DRAFT job
GET /api/jobs/{id} Get job details
POST /api/jobs/{id}/submit Walk DRAFT → QUEUED via platform.submit
POST /api/jobs/{id}/cancel Cancel a QUEUED/RUNNING job
GET /api/jobs/{id}/output List output files
GET /api/jobs/{id}/output/{filename} Download an output file
GET /api/jobs/{id}/logs Download the run log

Architecture

See docs/superpowers/specs/2026-06-17-sap-phase1-mvp-design.md and docs/superpowers/plans/2026-06-17-sap-phase1-p1-backend.md (the TDD-style implementation plan that produced this code). The design doc was backfilled 2026-06-24 with §12 (Phase 1.5 increments — Dawning adapter, fwi/grond/unicycle, eager fetch on COMPLETED), §13 (lessons learned from the six real-HPC bugs), and §14 (Phase 2 candidates). For a conversational record of one working session on 2026-06-24 (problems hit + solutions + next-step suggestions) see docs/superpowers/specs/2026-06-24-sap-session-summary.md.

Layered modules under backend/sap/:

api/         FastAPI routes + DTOs
services/    JobService, Scheduler, file_service
platforms/   Platform Protocol + Tianhe/Dawning/Shenwei adapters
clients/     ssh_client, slurm_client, srass_client, command_templates
state/       JobRepo (YAML CRUD), atomic file_store
models/      Job, JobStatus, state_machine
core/        exceptions, paths, logging
config.py    Pydantic settings
main.py      FastAPI app + lifespan

License

Internal. Not for redistribution.

关于

Seismic Application Platform

834.0 KB
邀请码
    Gitlink(确实开源)
  • 加入我们
  • 官网邮箱:gitlink@ccf.org.cn
  • QQ群
  • QQ群
  • 公众号
  • 公众号

版权所有:中国计算机学会技术支持:开源发展技术委员会
京ICP备13000930号-9 京公网安备 11010802047560号