15ddac178c
- Updated production.spec.ts, stock-adjustments.spec.ts, and stock-transfers.spec.ts to eliminate UOM references in API seeder and test cases. - Adjusted ApiSeeder methods to remove UOM parameters from stock receiving and production template creation. - Revised documentation to reflect changes in UOM handling, emphasizing that stock is counted in base UOM only. - Introduced new enums for MeasureUnit and StageQtyUnit to clarify content size and stage input quantities. - Implemented ItemContent service to validate and normalize content sizes. - Updated smoke tests to validate production stage inputs expressed in content units, ensuring correct consumption calculations. - Modified frontend UOM label handling to reflect the removal of per-line UOMs in document lines.
71 lines
2.5 KiB
Python
71 lines
2.5 KiB
Python
"""Run the whole manufacturing smoke suite in dependency order.
|
|
|
|
python Backend/smoke/run_all.py
|
|
|
|
Order matters: m4 creates the isolated SMOKE-PRD warehouse and drains it, m5 consumes the
|
|
run m4 leaves with its terminal stage InProgress. Each script is individually re-runnable,
|
|
but m5 deliberately refuses to run twice against an already-approved terminal stage — that
|
|
guard is what stops it silently asserting against the wrong state.
|
|
|
|
Prerequisites: ERPCore on :5224 and AuthHex on :5602 (override with ERP_SMOKE_API /
|
|
ERP_SMOKE_AUTH / ERP_SMOKE_USER / ERP_SMOKE_PASSWORD).
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import re
|
|
import subprocess
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
SCRIPTS = [
|
|
("M2 templates + graph validation", "m2_templates.py"),
|
|
("M3 run creation / board / quantities", "m3_runs.py"),
|
|
("M4 stage start / complete / approve / transfer", "m4_stage_actions.py"),
|
|
("M4c content-unit stage inputs + fractional packs", "m4c_content_units.py"),
|
|
("M5 terminal receipt + cost pool", "m5_receipt.py"),
|
|
("M6+M7 leftover / rework / cancel", "m6_m7_leftover_rework_cancel.py"),
|
|
]
|
|
|
|
SUMMARY = re.compile(r"^(\S+): (\d+)/(\d+) assertions passed")
|
|
|
|
|
|
def main() -> int:
|
|
here = Path(__file__).parent
|
|
results = []
|
|
failed = False
|
|
|
|
for label, script in SCRIPTS:
|
|
print(f"\n{'=' * 70}\n{label} ({script})\n{'=' * 70}", flush=True)
|
|
proc = subprocess.run(
|
|
[sys.executable, script, *sys.argv[1:]],
|
|
cwd=here, capture_output=True, text=True, encoding="utf-8", errors="replace",
|
|
)
|
|
sys.stdout.write(proc.stdout)
|
|
if proc.stderr.strip():
|
|
sys.stderr.write(proc.stderr)
|
|
|
|
passed = total = 0
|
|
for line in proc.stdout.splitlines():
|
|
m = SUMMARY.match(line.strip())
|
|
if m:
|
|
passed, total = int(m.group(2)), int(m.group(3))
|
|
results.append((label, passed, total, proc.returncode))
|
|
if proc.returncode != 0:
|
|
failed = True
|
|
|
|
print(f"\n{'=' * 70}\nSUITE SUMMARY\n{'=' * 70}")
|
|
grand_passed = grand_total = 0
|
|
for label, passed, total, rc in results:
|
|
grand_passed += passed
|
|
grand_total += total
|
|
state = "OK " if rc == 0 else "FAIL"
|
|
print(f" [{state}] {label:<48} {passed}/{total}")
|
|
print(f"\n TOTAL: {grand_passed}/{grand_total} assertions"
|
|
+ (" — ALL GREEN" if not failed else " (SUITE FAILED)"))
|
|
return 1 if failed else 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|