test_executor_m3.py 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. # One-off: P3-M3 regression - executor point_id passthrough + claim check.
  2. import json
  3. import os
  4. import sys
  5. import tempfile
  6. _SCRIPTS = os.path.dirname(os.path.abspath(__file__))
  7. sys.path.insert(0, _SCRIPTS)
  8. import task_executor as te # noqa: E402
  9. # force local-file mode (no web calls)
  10. te.requests = None
  11. tmp = tempfile.mkdtemp()
  12. captured = {}
  13. def make_task(tid, params):
  14. path = os.path.join(tmp, tid + "_task.json")
  15. with open(path, "w", encoding="utf-8") as f:
  16. json.dump({"task_id": tid, "task_name": "m3", "status": "pending",
  17. "parameters": params}, f)
  18. return {"task_id": tid, "_local_file": path, "status": "pending",
  19. "parameters": params}
  20. # ---------------- 1) point_id passthrough (claim succeeds) ----------------
  21. ex = te.TaskExecutor(task_dir=tmp, enable_mock=True)
  22. ex.dispatch_task = lambda tid: True # claim ok
  23. ex.on_complete = lambda tid, res, met: captured.setdefault(tid, res)
  24. task = make_task("t1", [{"airgap_mm": 1.0, "current_a": 10.0, "point_id": 7},
  25. {"airgap_mm": 2.0, "current_a": 5.0, "point_id": 8}])
  26. ex.execute_task(task)
  27. res1 = captured.get("t1")
  28. assert res1 and len(res1) == 2, res1
  29. for r in res1:
  30. assert r["status"] == "OK", r
  31. assert r["point_id"] in (7, 8), r
  32. assert r["params"].get("point_id") == r["point_id"], r
  33. print("[1] point_id passthrough OK:", [(r["point_id"], r["status"]) for r in res1])
  34. # ---------------- 2) FAILED point keeps point_id ----------------
  35. captured2 = {}
  36. def _boom(params, idx):
  37. raise RuntimeError("simulation failed")
  38. ex2 = te.TaskExecutor(task_dir=tmp, enable_mock=True)
  39. ex2.dispatch_task = lambda tid: True
  40. ex2._run_simulation_point = _boom
  41. ex2.on_complete = lambda tid, res, met: captured2.setdefault(tid, res)
  42. task2 = make_task("t2", [{"airgap_mm": 1.0, "point_id": 42}])
  43. ex2.execute_task(task2)
  44. r2 = captured2["t2"][0]
  45. assert r2["status"] == "FAILED", r2
  46. assert r2["point_id"] == 42, r2
  47. print("[2] FAILED point keeps point_id OK:", r2["point_id"], r2["status"])
  48. # ---------------- 3) claim rejected -> task skipped ----------------
  49. captured3 = {}
  50. ex3 = te.TaskExecutor(task_dir=tmp, enable_mock=True)
  51. ex3.dispatch_task = lambda tid: False # already claimed by another instance
  52. ex3.on_complete = lambda tid, res, met: captured3.setdefault(tid, res)
  53. task3 = make_task("t3", [{"airgap_mm": 1.0, "point_id": 99}])
  54. ex3.execute_task(task3)
  55. assert "t3" not in captured3, "claimed task must be skipped"
  56. print("[3] claim-rejected task skipped OK")
  57. # ---------------- 4) unique executor ids ----------------
  58. a = te.TaskExecutor(task_dir=tmp)
  59. b = te.TaskExecutor(task_dir=tmp)
  60. c = te.TaskExecutor(task_dir=tmp, executor_id="motorcad-executor-9")
  61. assert a.executor_id != b.executor_id, (a.executor_id, b.executor_id)
  62. assert c.executor_id == "motorcad-executor-9"
  63. print("[4] unique executor ids OK:", a.executor_id, "|", b.executor_id, "|", c.executor_id)
  64. print("\nALL P3-M3 EXECUTOR TESTS PASSED")