Skip to content

Commit 3f0393f

Browse files
committed
updated for the new naming
1 parent 7614c11 commit 3f0393f

26 files changed

Lines changed: 104 additions & 104 deletions

‎tests/README.md‎

Lines changed: 29 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -14,38 +14,38 @@ means a green pipeline.
1414
| `python3 tests/test_density.py` | nothing | backend gap-fill and edge-extension rules |
1515
| `node tests/test_density_rail_parity.mjs` | Node | live-rail edge-gap parity with the backend, including gaps larger than 25% of HS |
1616
| `python3 tests/test_instrument_state.py` | nothing | Y / N / unanswered persistence, CSV export, re-archive and contradiction validation |
17-
| `python3 tests/test_stage6_integration.py` | nothing | cumulative site identity, legacy migration, staged first archive, recovery, re-archive renaming, attachment preservation, duplicate-ID and instrument-state behavior |
18-
| `python3 tests/test_stage8_photo_manifest.py` | nothing | expected-photo schema/migration, archive registration, recovery, explicit cancellation, limits, queue-ID identity and idempotent server upload |
19-
| `python3 tests/test_stage9_attachment_consistency.py` | nothing | staged publication, crash recovery, DB-failure compensation, missing/orphan reconciliation, stale-temp cleanup, safe deletion, ownership, and Stage 8-to-9 migration |
20-
| `python3 tests/test_stage10_saved_pits.py` | nothing | owner-scoped Saved Pits search, campaign/date filters, sort order, pagination, recovery separation, status counts, API validation, and indexes |
21-
| `python3 tests/test_stage11_workspace.py` | nothing | owner-scoped workspace summary, recovery/photo counts, API identity boundary, and assembled initial view |
22-
| `python3 tests/test_stage12_security.py` | nothing | fail-closed identity parsing, owner-bound CSRF tokens, configuration requirements, and rate limiting |
23-
| `python3 tests/test_stage12_ops.py` | nothing | consistent backup, manifest verification, traversal/tamper rejection, restore, and rollback copies |
24-
| `python3 tests/test_stage12_storage_lifecycle.py` | nothing | shared archive/attachment lock, stale-folder rejection, degraded-lock warnings, and rename durability |
25-
| `python3 tests/test_stage13_ui.py` | nothing | offline font independence, workspace hierarchy, section subtitles, responsive/contrast/print modes, and explicit attachment-state styling |
26-
| `python3 tests/test_stage14_transfer.py` | nothing | installation/revision identities, one-way bundles, dry-run, owner mapping, idempotency, fast-forward updates, multiple field databases, attachment transfer, recovery resume, tamper rejection, conflicts, and audit rows |
27-
| `python3 tests/test_resource_stage1_downloads.py` | nothing | disk-backed download ZIP contents, normal/interrupted cleanup, and startup stale-file recovery |
28-
| `python3 tests/test_resource_stage2_uploads.py` | nothing | bounded upload-stream staging, incremental digest/header checks, rejection cleanup, and startup stale-file recovery |
29-
| `python3 tests/test_resource_stage3_heic.py` | Pillow | HEIC conversion semaphore, failure-safe permit release, disk-backed JPEG staging, crash cleanup, and conversion-before-storage-lock ordering |
30-
| `python3 tests/test_resource_stage4_profiles.py` | matplotlib | profile render semaphore, failure-safe permit release, single-build PNG+PDF equivalence, and 300-DPI guardrail |
31-
| `python3 tests/test_resource_stage5_threads.py` | nothing | eight-thread shared-server default, four-thread override, Waitress thread wiring, and startup concurrency diagnostics |
32-
| `python3 tests/test_resource_stage6_resilience.py` | nothing | abrupt-process-kill recovery for download/upload scratch files and process-local HEIC/profile permits |
33-
| `python3 tests/test_resource_stage6_live.py` | flask, waitress, matplotlib | boots the real eight-thread Waitress server, verifies startup scratch cleanup, runs two profile requests concurrently, and checks health traffic remains responsive |
34-
| `python3 tests/test_resource_stage7_sizing.py` | nothing | Stage 7 sizing-policy PASS/PROVISIONAL/FAIL boundaries for peak RSS, host headroom, HEIC mode, soak stability, swap, latency, and cleanup |
17+
| `python3 tests/test_archive_integration.py` | nothing | cumulative site identity, legacy migration, staged first archive, recovery, re-archive renaming, attachment preservation, duplicate-ID and instrument-state behavior |
18+
| `python3 tests/test_photo_manifest.py` | nothing | expected-photo schema/migration, archive registration, recovery, explicit cancellation, limits, queue-ID identity and idempotent server upload |
19+
| `python3 tests/test_attachment_consistency.py` | nothing | staged publication, crash recovery, DB-failure compensation, missing/orphan reconciliation, stale-temp cleanup, safe deletion, ownership, and legacy attachment-schema migration |
20+
| `python3 tests/test_saved_pits.py` | nothing | owner-scoped Saved Pits search, campaign/date filters, sort order, pagination, recovery separation, status counts, API validation, and indexes |
21+
| `python3 tests/test_workspace.py` | nothing | owner-scoped workspace summary, recovery/photo counts, API identity boundary, and assembled initial view |
22+
| `python3 tests/test_security_core.py` | nothing | fail-closed identity parsing, owner-bound CSRF tokens, configuration requirements, and rate limiting |
23+
| `python3 tests/test_backup_restore.py` | nothing | consistent backup, manifest verification, traversal/tamper rejection, restore, and rollback copies |
24+
| `python3 tests/test_storage_lifecycle.py` | nothing | shared archive/attachment lock, stale-folder rejection, degraded-lock warnings, and rename durability |
25+
| `python3 tests/test_interface_contract.py` | nothing | offline font independence, workspace hierarchy, section subtitles, responsive/contrast/print modes, and explicit attachment-state styling |
26+
| `python3 tests/test_field_transfer.py` | nothing | installation/revision identities, one-way bundles, dry-run, owner mapping, idempotency, fast-forward updates, multiple field databases, attachment transfer, recovery resume, tamper rejection, conflicts, and audit rows |
27+
| `python3 tests/test_resource_downloads.py` | nothing | disk-backed download ZIP contents, normal/interrupted cleanup, and startup stale-file recovery |
28+
| `python3 tests/test_resource_uploads.py` | nothing | bounded upload-stream staging, incremental digest/header checks, rejection cleanup, and startup stale-file recovery |
29+
| `python3 tests/test_resource_heic.py` | Pillow | HEIC conversion semaphore, failure-safe permit release, disk-backed JPEG staging, crash cleanup, and conversion-before-storage-lock ordering |
30+
| `python3 tests/test_resource_profiles.py` | matplotlib | profile render semaphore, failure-safe permit release, single-build PNG+PDF equivalence, and 300-DPI guardrail |
31+
| `python3 tests/test_resource_threads.py` | nothing | eight-thread shared-server default, four-thread override, Waitress thread wiring, and startup concurrency diagnostics |
32+
| `python3 tests/test_resource_resilience.py` | nothing | abrupt-process-kill recovery for download/upload scratch files and process-local HEIC/profile permits |
33+
| `python3 tests/test_resource_live_server.py` | flask, waitress, matplotlib | boots the real eight-thread Waitress server, verifies startup scratch cleanup, runs two profile requests concurrently, and checks health traffic remains responsive |
34+
| `python3 tests/test_resource_sizing.py` | nothing | server-sizing PASS/PROVISIONAL/FAIL boundaries for peak RSS, host headroom, HEIC mode, soak stability, swap, latency, and cleanup |
3535
| `python3 tests/test_weather_multiselect.py` | nothing | canonical weather arrays, legacy scalar compatibility, validation, normalized reporting columns, and CSV export |
36-
| `node tests/test_stage13_ui.mjs` | nothing | automatic accessible field names and non-invasive populated-field presentation state |
36+
| `node tests/test_interface_ui.mjs` | nothing | automatic accessible field names and non-invasive populated-field presentation state |
3737
| `node tests/test_table_enter_navigation.mjs` | nothing | Enter moves vertically through existing Temperature, Density, LWC, and Stratigraphy rows without adding rows or submitting |
3838
| `node tests/test_clearable_radios.mjs` | nothing | optional native-radio clear action, accessible naming, idempotent setup, and no-scroll focus return |
3939
| `node tests/test_weather_multiselect.mjs` | nothing | native checkbox coexistence, precipitation None exclusivity, array collection, and legacy/new restore behavior |
40-
| `python3 tests/test_stage12_flask_security.py` | flask, matplotlib | real route-level CSRF, headers, health/readiness, size limits, generic errors, and Alice/Bob isolation |
41-
| `node tests/test_stage12_csrf_ui.mjs` | nothing | browser API helper sends CSRF only on unsafe requests |
40+
| `python3 tests/test_flask_security.py` | flask, matplotlib | real route-level CSRF, headers, health/readiness, size limits, generic errors, and Alice/Bob isolation |
41+
| `node tests/test_csrf_ui.mjs` | nothing | browser API helper sends CSRF only on unsafe requests |
4242
| `node tests/test_instrument_ui.mjs` | nothing | lightweight real-function checks for collect() and Y/N/unanswered button state |
4343
| `node tests/test_record_workflow_ui.mjs` | nothing | lightweight execution of edit mode, pending recovery state, Start New Pit, and site_id-based loading |
4444
| `node tests/test_attachment_outbox.mjs` | nothing | durable queue persistence, restore, draft-to-site binding, quota failure, duplicate selection, and explicit discard |
4545
| `node tests/test_attachment_flush.mjs` | nothing | failed upload retention, confirmed upload cleanup, duplicate confirmation, and network retry state |
4646
| `node tests/test_attachment_manifest_ui.mjs` | nothing | archive manifest handoff, cancellation safety, server-only expectations, and stored-attachment deletion controls |
47-
| `node tests/test_stage10_saved_pits_ui.mjs` | nothing | finder query construction, status cards, campaign facets, recovery separation, and load-more accumulation |
48-
| `node tests/test_stage11_workspace_ui.mjs` | nothing | workspace navigation, current-record awareness, recent/recovery actions, finder-state preservation, and all-context photo-queue summary |
47+
| `node tests/test_saved_pits_ui.mjs` | nothing | finder query construction, status cards, campaign facets, recovery separation, and load-more accumulation |
48+
| `node tests/test_workspace_ui.mjs` | nothing | workspace navigation, current-record awareness, recent/recovery actions, finder-state preservation, and all-context photo-queue summary |
4949
| `python3 tests/test_plot.py` | matplotlib | profile figure geometry |
5050
| `python3 tests/test_smoke.py` | flask, matplotlib | end-to-end: archive -> load -> download, the seven CSVs + PNG, attachment limits, the pit-sheet PDF/image rule |
5151
| `node tests/test_coords.mjs` | nothing | UTM/WGS84 converter vs PROJ ground truth |
@@ -57,17 +57,17 @@ runtimes — it is not a pure-JS suite.
5757
## Server resource qualification
5858

5959
The normal suite keeps tests bounded for CI. Before sizing or changing a shared
60-
server, run the Stage 6 resource harness on that host after installing the locked
60+
server, run the server-resource harness on that host after installing the locked
6161
Python dependencies:
6262

6363
```bash
64-
python3 tests/benchmark_resource_stage6.py --qualification --output stage6.json
64+
python3 tests/benchmark_server_resources.py --qualification --output server-resources.json
6565
```
6666

6767
For a multi-hour stability check, add a wall-clock soak, for example:
6868

6969
```bash
70-
python3 tests/benchmark_resource_stage6.py --qualification --soak-minutes 180 --output stage6-soak.json
70+
python3 tests/benchmark_server_resources.py --qualification --soak-minutes 180 --output server-resource-soak.json
7171
```
7272

7373
The harness reports peak/current RSS, host total RAM, minimum `MemAvailable`,
@@ -77,10 +77,10 @@ codec or the clearly labelled decoded-image proxy. On Linux it uses `/proc` if
7777
`psutil` is not installed; on other platforms install `psutil` only for
7878
qualification. `psutil` is intentionally not a CryoPit runtime dependency.
7979

80-
Evaluate a completed target-host soak against the Stage 7 3.5 GiB policy with:
80+
Evaluate a completed target-host soak against the 3.5 GiB server-sizing policy with:
8181

8282
```bash
83-
python3 tests/evaluate_resource_stage7.py stage6-soak.json --ram-gib 3.5
83+
python3 tests/evaluate_server_sizing.py server-resource-soak.json --ram-gib 3.5
8484
```
8585

8686
The evaluator returns `PASS`, `PROVISIONAL`, or `FAIL`. It deliberately refuses
@@ -102,7 +102,7 @@ checks that it opened.
102102

103103
CryoPit supports Python 3.11 and newer. CI installs `requirements.lock` across the supported Python matrix and also runs the full dependency-backed suite in a Python 3.11 Conda environment. A separate floating-dependency job installs `requirements.txt` to detect future compatibility drift.
104104

105-
The scientific, cumulative integration, operations, security-core, and lightweight JavaScript suites do not require Flask or jsdom. The end-to-end and route-isolation suites require the Python dependencies in `requirements.lock`; the DOM suite requires `npm ci`. A syntax-only pass is not reported as a runtime pass when those dependencies are unavailable. A Stage 14 release candidate is not production-ready until the full dependency-backed suite passes in the target build environment. The Stage 13 interface also receives a real-browser layout/runtime check at representative desktop, tablet, and mobile widths; screenshot review supplements but does not replace the DOM assertions.
105+
The scientific, cumulative integration, operations, security-core, and lightweight JavaScript suites do not require Flask or jsdom. The end-to-end and route-isolation suites require the Python dependencies in `requirements.lock`; the DOM suite requires `npm ci`. A syntax-only pass is not reported as a runtime pass when those dependencies are unavailable. A release candidate is not production-ready until the full dependency-backed suite passes in the target build environment. The interface also receives a real-browser layout/runtime check at representative desktop, tablet, and mobile widths; screenshot review supplements but does not replace the DOM assertions.
106106

107107
### DOM placeholder guard
108108

‎tests/benchmark_server_resources.py‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
"""Reproducible CryoPit Stage 6 server-resource qualification harness.
1+
"""Reproducible CryoPit server-resource qualification harness.
22
33
This is intentionally not part of the normal CI suite: qualification loads are
44
large and machine-specific. Run it on the deployment host after installing
5-
``requirements.lock``. It exercises the exact Stage 1/2/3/4 resource paths in
5+
``requirements.lock``. It exercises the production download/upload/HEIC/profile resource paths in
66
one process and emits JSON suitable for attaching to an infrastructure ticket.
77
88
Examples:
9-
python tests/benchmark_resource_stage6.py --quick
10-
python tests/benchmark_resource_stage6.py --qualification --output stage6.json
9+
python tests/benchmark_server_resources.py --quick
10+
python tests/benchmark_server_resources.py --qualification --output server-resources.json
1111
"""
1212
from __future__ import annotations
1313

@@ -41,7 +41,7 @@ def __init__(self):
4141
self._proc = None
4242
else:
4343
raise SystemExit(
44-
"Stage 6 benchmark needs psutil on this platform; install it only "
44+
"Server-resource benchmark needs psutil on this platform; install it only "
4545
"for qualification (it is not a CryoPit runtime dependency)."
4646
)
4747

@@ -192,7 +192,7 @@ def main():
192192
image = Image.new("RGB", (width, height), (135, 145, 155))
193193
image.save(source, format="JPEG", quality=95)
194194
image.close()
195-
# Let the Stage 3 file-to-file helper exercise the same Pillow decode /
195+
# Let the file-to-file helper exercise the same Pillow decode /
196196
# encode path without claiming this is HEIC codec performance.
197197
import types
198198
sys.modules["pillow_heif"] = types.SimpleNamespace(register_heif_opener=lambda: None)

‎tests/evaluate_server_sizing.py‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
"""Evaluate a Stage 6 qualification report against CryoPit's Stage 7 RAM policy.
1+
"""Evaluate a server-resource qualification report against CryoPit's RAM policy.
22
33
This does not benchmark the machine. It evaluates JSON produced by
4-
``tests/benchmark_resource_stage6.py`` and reports whether a planned memory
4+
``tests/benchmark_server_resources.py`` and reports whether a planned memory
55
allocation has been demonstrated on a representative host.
66
77
Example:
8-
python tests/evaluate_resource_stage7.py stage6-soak.json --ram-gib 3.5
8+
python tests/evaluate_server_sizing.py server-resource-soak.json --ram-gib 3.5
99
"""
1010
from __future__ import annotations
1111

@@ -53,7 +53,7 @@ def evaluate(report: dict, ram_gib: float) -> dict:
5353
failures.append("peak RSS is missing")
5454
elif peak > peak_limit:
5555
failures.append(
56-
f"CryoPit peak RSS {peak:.0f} MiB exceeds the Stage 7 planning ceiling "
56+
f"CryoPit peak RSS {peak:.0f} MiB exceeds the server planning ceiling "
5757
f"of {peak_limit:.0f} MiB ({APP_PEAK_FRACTION:.0%} of target RAM)"
5858
)
5959
else:
@@ -68,7 +68,7 @@ def evaluate(report: dict, ram_gib: float) -> dict:
6868
elif system_total is not None and system_total <= ram_mib * (1.0 + TARGET_HOST_TOLERANCE):
6969
if min_available < available_floor:
7070
failures.append(
71-
f"minimum MemAvailable {min_available:.0f} MiB is below the Stage 7 "
71+
f"minimum MemAvailable {min_available:.0f} MiB is below the server headroom "
7272
f"floor of {available_floor:.0f} MiB"
7373
)
7474
else:
@@ -157,7 +157,7 @@ def evaluate(report: dict, ram_gib: float) -> dict:
157157

158158
def main() -> int:
159159
parser = argparse.ArgumentParser()
160-
parser.add_argument("report", help="Stage 6 qualification JSON")
160+
parser.add_argument("report", help="server-resource qualification JSON")
161161
parser.add_argument("--ram-gib", type=float, default=3.5,
162162
help="planned server RAM in GiB (default: 3.5)")
163163
parser.add_argument("--output", help="optional path for evaluator JSON")

‎tests/test_archive_integration.py‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
"""Cumulative Stage 1-5 integration tests without Flask.
1+
"""Cumulative archive integration tests without Flask.
22
33
Covers immutable site identity, legacy migration, recoverable first archive,
44
recoverable re-archive folder renaming, in-place attachment preservation, edit
@@ -353,5 +353,5 @@ def test_archive_retry_returns_pending_conflict_instead_of_raising():
353353
for test in tests:
354354
test()
355355
print("PASS", test.__name__)
356-
print(f"{len(tests)} Stage 6 integration tests passed")
356+
print(f"{len(tests)} archive integration tests passed")
357357

‎tests/test_attachment_consistency.py‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
"""Stage 9 attachment filesystem/SQLite compensation and recovery tests."""
1+
"""Attachment filesystem/SQLite compensation and recovery tests."""
22
from __future__ import annotations
33

44
import hashlib
@@ -140,9 +140,9 @@ def prepare_staged(site_id, item, data, filename="reserved.jpg"):
140140
return folder, staged, rel
141141

142142

143-
def test_stage8_database_migrates_before_new_index_is_created():
143+
def test_legacy_database_migrates_before_new_index_is_created():
144144
# CREATE TABLE IF NOT EXISTS cannot add columns to an existing table, so
145-
# indexes involving Stage 9 columns must be created by _migrate afterward.
145+
# indexes involving later attachment columns must be created by _migrate afterward.
146146
db_path = Path(os.environ["CRYOPIT_DB_PATH"])
147147
exports = Path(os.environ["CRYOPIT_EXPORT_DIR"])
148148
if db_path.exists(): db_path.unlink()
@@ -162,7 +162,7 @@ def test_stage8_database_migrates_before_new_index_is_created():
162162
):
163163
legacy_sql = legacy_sql.replace(line, "")
164164
# Removing the final attachment column leaves the preceding timestamp
165-
# with a comma; restore the Stage 8 closing form.
165+
# with a comma; restore the legacy closing form.
166166
legacy_sql = legacy_sql.replace(
167167
" uploaded_at TEXT DEFAULT (datetime('now')),\n);",
168168
" uploaded_at TEXT DEFAULT (datetime('now'))\n);")
@@ -365,4 +365,4 @@ def test_delete_enforces_owner():
365365
tests = sorted((n, f) for n, f in globals().items() if n.startswith("test_") and callable(f))
366366
for name, fn in tests:
367367
fn(); print("PASS", name)
368-
print(f"{len(tests)} Stage 9 attachment-consistency tests passed")
368+
print(f"{len(tests)} attachment-consistency tests passed")

0 commit comments

Comments
 (0)