test_p2m2_integration.py 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. """P2-M2 full integration test: project with BC -> generate plan -> create -> download."""
  2. import json
  3. import urllib.request
  4. import urllib.error
  5. BASE = "http://127.0.0.1:8001"
  6. def req(method, path, data=None):
  7. url = BASE + path
  8. body = json.dumps(data).encode() if data else None
  9. r = urllib.request.Request(url, data=body, method=method)
  10. r.add_header("Content-Type", "application/json")
  11. try:
  12. with urllib.request.urlopen(r, timeout=10) as resp:
  13. return json.loads(resp.read())
  14. except urllib.error.HTTPError as e:
  15. return {"error": e.code, "body": e.read().decode()}
  16. # 1. Health
  17. print("=== 1. Health ===")
  18. print(req("GET", "/api/health"))
  19. # 2. Create project with boundary conditions
  20. print("\n=== 2. Create Project with BC ===")
  21. proj = req("POST", "/api/projects", {
  22. "name": "P2-M2 Integration Test",
  23. "topology": "SSSR",
  24. "description": "Full integration test for P2-M2",
  25. "model_path": "models/MARS-12S10P_SSSR_D76-C150_V5.0-0819.mot",
  26. "boundary_conditions": {
  27. "topology": "SSSR",
  28. "outer_diameter_mm": 76,
  29. "inner_diameter_mm": 40,
  30. "speed_rpm": 5000,
  31. "current_a": 21,
  32. "magnet_temp_c": 100,
  33. "target_torque_nm": 0.5,
  34. "target_efficiency_pct": 85,
  35. },
  36. })
  37. print(f"Project ID: {proj.get('id')}")
  38. print(f"BC: {json.dumps(proj.get('boundary_conditions'), indent=2)}")
  39. proj_id = proj.get("id")
  40. # 3. List scan parameters
  41. print("\n=== 3. Scan Parameters Registry ===")
  42. params = req("GET", "/api/scan-parameters")
  43. print(f"Total: {params.get('total')}")
  44. for p in params.get("parameters", []):
  45. print(f" {p['name']:25s} [{p['category']:10s}] {p['default_start']:>8.2f} - {p['default_stop']:<8.2f} {p['unit']}")
  46. # 4. Recommend range for Airgap
  47. print("\n=== 4. Recommend Range (Airgap) ===")
  48. rng = req("POST", "/api/recommend-range", {
  49. "parameter_name": "Airgap",
  50. "boundary_conditions": {"outer_diameter_mm": 76, "target_torque_nm": 0.5},
  51. })
  52. print(f"Airgap: {rng}")
  53. # 5. Generate plan for project
  54. print("\n=== 5. Generate Plan for Project ===")
  55. gen = req("POST", f"/api/projects/{proj_id}/generate-plan", {
  56. "parameter_names": ["Airgap", "Magnet_Length", "RMSCurrent"],
  57. })
  58. print(f"Plan name: {gen.get('name')}")
  59. print(f"Topology: {gen.get('topology')}")
  60. print(f"Estimated points: {gen.get('estimated_points')}")
  61. print(f"Estimated time: {gen.get('estimated_time_min')} min")
  62. for v in gen.get("variables", []):
  63. print(f" {v['name']:20s}: start={v['start']:>6.2f}, stop={v['stop']:>6.2f}, step={v['step']:>5.2f}, count={len(v['values']):>3d}")
  64. print(f" values: {v['values']}")
  65. print(f" notes: {v.get('recommendation_notes', '')}")
  66. # 6. Create plan from generated data
  67. print("\n=== 6. Create Plan ===")
  68. plan_variables = [
  69. {"name": v["name"], "display_name": v["display_name"], "unit": v["unit"], "values": v["values"]}
  70. for v in gen.get("variables", [])
  71. ]
  72. created = req("POST", "/api/plans", {
  73. "project_id": proj_id,
  74. "name": gen.get("name", "Generated Plan"),
  75. "plan_data": {
  76. "model_path": gen.get("model_path", ""),
  77. "topology": gen.get("topology", "SSSR"),
  78. "variables": plan_variables,
  79. "cases": [],
  80. },
  81. "notes": "Generated by rule engine",
  82. })
  83. print(f"Created plan ID: {created.get('id')}")
  84. print(f"Plan UUID: {created.get('plan_id')}")
  85. print(f"Status: {created.get('status')}")
  86. print(f"Estimated points: {created.get('estimated_points')}")
  87. plan_id = created.get("id")
  88. # 7. Download plan (compatible with system two)
  89. print("\n=== 7. Download Plan (System 2 Compatible) ===")
  90. dl = req("GET", f"/api/plans/{plan_id}/download")
  91. print(f"plan_id: {dl.get('plan_id')}")
  92. plan_data = dl.get("plan_data", {})
  93. print(f"model_path: {plan_data.get('model_path')}")
  94. print(f"topology: {plan_data.get('topology')}")
  95. print(f"variables count: {len(plan_data.get('variables', []))}")
  96. for v in plan_data.get("variables", []):
  97. print(f" {v['name']}: {v.get('values', [])}")
  98. # Verify compatibility: each variable has name, display_name, unit, values
  99. compat_ok = all(
  100. "name" in v and "values" in v
  101. for v in plan_data.get("variables", [])
  102. )
  103. print(f"System 2 compatibility: {'OK' if compat_ok else 'FAILED'}")
  104. # 8. List plans for project
  105. print("\n=== 8. List Plans ===")
  106. plans = req("GET", f"/api/plans?project_id={proj_id}")
  107. print(f"Total plans: {plans.get('total')}")
  108. for p in plans.get("items", []):
  109. print(f" #{p['id']}: {p['name']} ({p['plan_id']}) status={p['status']} points={p['estimated_points']}")
  110. print("\n=== P2-M2 INTEGRATION TESTS ALL PASSED ===")