Upload 34 files
Browse files- tests/test_v52_ui_fixes.py +1 -1
- tests/test_v54_live_progress_cancel.py +1 -1
- tests/test_v57_live_pi_traces.py +1 -1
- tests/test_v58_stable_refresh_pi_stdout.py +1 -1
- tests/test_v59_job_log_progress_clean.py +1 -1
- tests/test_v60_cancel_persist_delete_run.py +1 -1
- tests/test_v61_stabilize_buttons_runtime.py +1 -1
- tests/test_v62_progress_perf_clean_delete.py +1 -1
- tests/test_v63_delete_import_fix.py +1 -1
- tests/test_v64_delete_clean_events_timeline.py +1 -1
- tests/test_v65_floating_form_timeline.py +1 -1
- tests/test_v66_clean_qwen_coder_path.py +1 -1
- tests/test_v67_monotonic_progress_events.py +39 -0
tests/test_v52_ui_fixes.py
CHANGED
|
@@ -37,6 +37,6 @@ def test_runs_explorer_is_limited_to_five_rows_with_pagination():
|
|
| 37 |
|
| 38 |
def test_progress_endpoint_uses_view_model_links_for_job_url():
|
| 39 |
app_py = Path("app.py").read_text(encoding="utf-8")
|
| 40 |
-
assert '"version": "
|
| 41 |
assert 'view = build_run_view_model(run_id, bundle, bucket_source=bucket_source)' in app_py
|
| 42 |
assert '"links": view.get("links")' in app_py
|
|
|
|
| 37 |
|
| 38 |
def test_progress_endpoint_uses_view_model_links_for_job_url():
|
| 39 |
app_py = Path("app.py").read_text(encoding="utf-8")
|
| 40 |
+
assert '"version": "v67-monotonic-progress-events"' in app_py
|
| 41 |
assert 'view = build_run_view_model(run_id, bundle, bucket_source=bucket_source)' in app_py
|
| 42 |
assert '"links": view.get("links")' in app_py
|
tests/test_v54_live_progress_cancel.py
CHANGED
|
@@ -26,7 +26,7 @@ def test_frontend_progress_polling_is_no_cache_and_faster():
|
|
| 26 |
assert 'cache:"no-store"' in api_js
|
| 27 |
assert "withCacheBust" in api_js
|
| 28 |
assert "setInterval(refreshProgress,2500)" in app_js
|
| 29 |
-
assert "
|
| 30 |
|
| 31 |
|
| 32 |
def test_cancel_endpoint_and_button_exist():
|
|
|
|
| 26 |
assert 'cache:"no-store"' in api_js
|
| 27 |
assert "withCacheBust" in api_js
|
| 28 |
assert "setInterval(refreshProgress,2500)" in app_js
|
| 29 |
+
assert "stabilizeProgressPayload" in progress_js
|
| 30 |
|
| 31 |
|
| 32 |
def test_cancel_endpoint_and_button_exist():
|
tests/test_v57_live_pi_traces.py
CHANGED
|
@@ -32,4 +32,4 @@ def test_ui_has_pi_live_trace_panel_and_renderer():
|
|
| 32 |
|
| 33 |
|
| 34 |
def test_app_version_v57():
|
| 35 |
-
assert '"version": "
|
|
|
|
| 32 |
|
| 33 |
|
| 34 |
def test_app_version_v57():
|
| 35 |
+
assert '"version": "v67-monotonic-progress-events"' in Path("app.py").read_text(encoding="utf-8")
|
tests/test_v58_stable_refresh_pi_stdout.py
CHANGED
|
@@ -23,4 +23,4 @@ def test_elapsed_ticks_client_side_each_second():
|
|
| 23 |
|
| 24 |
|
| 25 |
def test_app_version_v62():
|
| 26 |
-
assert '"version": "
|
|
|
|
| 23 |
|
| 24 |
|
| 25 |
def test_app_version_v62():
|
| 26 |
+
assert '"version": "v67-monotonic-progress-events"' in Path("app.py").read_text(encoding="utf-8")
|
tests/test_v59_job_log_progress_clean.py
CHANGED
|
@@ -51,4 +51,4 @@ def test_progress_renderer_no_longer_sets_active_run_link_buttons():
|
|
| 51 |
|
| 52 |
|
| 53 |
def test_app_version_v59():
|
| 54 |
-
assert '"version": "
|
|
|
|
| 51 |
|
| 52 |
|
| 53 |
def test_app_version_v59():
|
| 54 |
+
assert '"version": "v67-monotonic-progress-events"' in Path("app.py").read_text(encoding="utf-8")
|
tests/test_v60_cancel_persist_delete_run.py
CHANGED
|
@@ -44,4 +44,4 @@ def test_active_run_still_only_has_cancel_button():
|
|
| 44 |
|
| 45 |
|
| 46 |
def test_app_version_v60():
|
| 47 |
-
assert '"version": "
|
|
|
|
| 44 |
|
| 45 |
|
| 46 |
def test_app_version_v60():
|
| 47 |
+
assert '"version": "v67-monotonic-progress-events"' in Path("app.py").read_text(encoding="utf-8")
|
tests/test_v61_stabilize_buttons_runtime.py
CHANGED
|
@@ -45,4 +45,4 @@ setTimeout(()=>process.exit(0), 25);
|
|
| 45 |
|
| 46 |
|
| 47 |
def test_app_version_v61():
|
| 48 |
-
assert '"version": "
|
|
|
|
| 45 |
|
| 46 |
|
| 47 |
def test_app_version_v61():
|
| 48 |
+
assert '"version": "v67-monotonic-progress-events"' in Path("app.py").read_text(encoding="utf-8")
|
tests/test_v62_progress_perf_clean_delete.py
CHANGED
|
@@ -40,4 +40,4 @@ def test_delete_selected_run_clears_ui_and_refreshes_runs():
|
|
| 40 |
|
| 41 |
|
| 42 |
def test_app_version_v62():
|
| 43 |
-
assert '"version": "
|
|
|
|
| 40 |
|
| 41 |
|
| 42 |
def test_app_version_v62():
|
| 43 |
+
assert '"version": "v67-monotonic-progress-events"' in Path("app.py").read_text(encoding="utf-8")
|
tests/test_v63_delete_import_fix.py
CHANGED
|
@@ -14,4 +14,4 @@ def test_bucket_delete_helper_exists():
|
|
| 14 |
|
| 15 |
|
| 16 |
def test_app_version_v63():
|
| 17 |
-
assert '"version": "
|
|
|
|
| 14 |
|
| 15 |
|
| 16 |
def test_app_version_v63():
|
| 17 |
+
assert '"version": "v67-monotonic-progress-events"' in Path("app.py").read_text(encoding="utf-8")
|
tests/test_v64_delete_clean_events_timeline.py
CHANGED
|
@@ -50,4 +50,4 @@ def test_timeline_has_stopped_state_without_running_animation_confusion():
|
|
| 50 |
|
| 51 |
|
| 52 |
def test_app_version_v64():
|
| 53 |
-
assert '"version": "
|
|
|
|
| 50 |
|
| 51 |
|
| 52 |
def test_app_version_v64():
|
| 53 |
+
assert '"version": "v67-monotonic-progress-events"' in Path("app.py").read_text(encoding="utf-8")
|
tests/test_v65_floating_form_timeline.py
CHANGED
|
@@ -57,4 +57,4 @@ def test_frontend_timeline_supports_stopped_status():
|
|
| 57 |
|
| 58 |
|
| 59 |
def test_app_version_v65():
|
| 60 |
-
assert '"version": "
|
|
|
|
| 57 |
|
| 58 |
|
| 59 |
def test_app_version_v65():
|
| 60 |
+
assert '"version": "v67-monotonic-progress-events"' in Path("app.py").read_text(encoding="utf-8")
|
tests/test_v66_clean_qwen_coder_path.py
CHANGED
|
@@ -19,4 +19,4 @@ def test_preferred_gpu_stays_zerogpu_only_and_fallback_a10g_large_default():
|
|
| 19 |
|
| 20 |
|
| 21 |
def test_app_version_v66():
|
| 22 |
-
assert '"version": "
|
|
|
|
| 19 |
|
| 20 |
|
| 21 |
def test_app_version_v66():
|
| 22 |
+
assert '"version": "v67-monotonic-progress-events"' in Path("app.py").read_text(encoding="utf-8")
|
tests/test_v67_monotonic_progress_events.py
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from pathlib import Path
|
| 2 |
+
|
| 3 |
+
from app import _events_from_job_logs
|
| 4 |
+
|
| 5 |
+
|
| 6 |
+
def test_job_log_event_parser_handles_prefix_suffix_and_ansi():
|
| 7 |
+
logs = """
|
| 8 |
+
2026-06-02T10:00:00Z stdout: \x1b[32m{"ts":"2026-06-02T10:00:00+00:00","step":"bootstrap","status":"success","message":"ok"}\x1b[0m
|
| 9 |
+
INFO prefix {"ts":"2026-06-02T10:01:00+00:00","step":"pi_run","status":"running","message":"Pi"} trailing text
|
| 10 |
+
"""
|
| 11 |
+
events = _events_from_job_logs(logs)
|
| 12 |
+
assert [e["step"] for e in events] == ["bootstrap", "pi_run"]
|
| 13 |
+
|
| 14 |
+
|
| 15 |
+
def test_progress_endpoint_fetches_deeper_job_log_window():
|
| 16 |
+
app = Path("app.py").read_text(encoding="utf-8")
|
| 17 |
+
assert "max_lines=1000" in app
|
| 18 |
+
assert "JSONDecoder().raw_decode" not in app # implementation uses decoder variable
|
| 19 |
+
assert "decoder.raw_decode" in app
|
| 20 |
+
assert "ANSI_RE" in app
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
def test_frontend_progress_is_monotonic_per_run():
|
| 24 |
+
js = Path("web/static/progress.js").read_text(encoding="utf-8")
|
| 25 |
+
assert "const progressStability" in js
|
| 26 |
+
assert "function stabilizeProgressPayload" in js
|
| 27 |
+
assert "Math.max(rawProgress,progressStability.progress)" in js
|
| 28 |
+
assert "timelineFurthestIndex" in js
|
| 29 |
+
assert "resetProgressStability(runId)" in Path("web/static/app.js").read_text(encoding="utf-8")
|
| 30 |
+
|
| 31 |
+
|
| 32 |
+
def test_light_poll_cannot_reset_timeline_signature_to_earlier_steps():
|
| 33 |
+
js = Path("web/static/progress.js").read_text(encoding="utf-8")
|
| 34 |
+
assert "rawIndex>=progressStability.furthestIndex" in js
|
| 35 |
+
assert "cloneTimeline(progressStability.timeline)" in js
|
| 36 |
+
|
| 37 |
+
|
| 38 |
+
def test_app_version_v67():
|
| 39 |
+
assert '"version": "v67-monotonic-progress-events"' in Path("app.py").read_text(encoding="utf-8")
|