test_executor_m3.py 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  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", "parameters": params}, f)
  17. return {"task_id": tid, "_local_file": path, "parameters": params}
  18. # ---------------- 1) point_id passthrough (claim succeeds) ----------------
  19. ex = te.TaskExecutor(task_dir=tmp, enable_mock=True)
  20. ex.dispatch_task = lambda tid: True # claim ok
  21. ex.on_complete = lambda tid, res, met: captured.setdefault(tid, res)
  22. task = make_task("t1", [{"airgap_mm": 1.0, "current_a": 10.0, "point_id": 7},
  23. {"airgap_mm": 2.0, "current_a": 5.0, "point_id": 8}])
  24. ex.execute_task(task)
  25. res1 = captured.get("t1")
  26. assert res1 and len(res1) == 2, res1
  27. for r in res1:
  28. assert r["status"] == "OK", r
  29. assert r["point_id"] in (7, 8), r
  30. assert r["params"].get("point_id") == r["point_id"], r
  31. print("[1] point_id passthrough OK:", [(r["point_id"], r["status"]) for r in res1])
  32. # ---------------- 2) FAILED point keeps point_id ----------------
  33. captured2 = {}
  34. def _boom(params, idx):
  35. raise RuntimeError("simulation failed")
  36. ex2 = te.TaskExecutor(task_dir=tmp, enable_mock=True)
  37. ex2.dispatch_task = lambda tid: True
  38. ex2._run_simulation_point = _boom
  39. ex2.on_complete = lambda tid, res, met: captured2.setdefault(tid, res)
  40. task2 = make_task("t2", [{"airgap_mm": 1.0, "point_id": 42}])
  41. ex2.execute_task(task2)
  42. r2 = captured2["t2"][0]
  43. assert r2["status"] == "FAILED", r2
  44. assert r2["point_id"] == 42, r2
  45. print("[2] FAILED point keeps point_id OK:", r2["point_id"], r2["status"])
  46. # ---------------- 3) claim rejected -> task skipped ----------------
  47. captured3 = {}
  48. ex3 = te.TaskExecutor(task_dir=tmp, enable_mock=True)
  49. ex3.dispatch_task = lambda tid: False # already claimed by another instance
  50. ex3.on_complete = lambda tid, res, met: captured3.setdefault(tid, res)
  51. task3 = make_task("t3", [{"airgap_mm": 1.0, "point_id": 99}])
  52. ex3.execute_task(task3)
  53. assert "t3" not in captured3, "claimed task must be skipped"
  54. print("[3] claim-rejected task skipped OK")
  55. # ---------------- 4) unique executor ids ----------------
  56. a = te.TaskExecutor(task_dir=tmp)
  57. b = te.TaskExecutor(task_dir=tmp)
  58. c = te.TaskExecutor(task_dir=tmp, executor_id="motorcad-executor-9")
  59. assert a.executor_id != b.executor_id, (a.executor_id, b.executor_id)
  60. assert c.executor_id == "motorcad-executor-9"
  61. print("[4] unique executor ids OK:", a.executor_id, "|", b.executor_id, "|", c.executor_id)
  62. print("\nALL P3-M3 EXECUTOR TESTS PASSED")