quantum_circuit_optimizer / test_compliance.py
poseidon666's picture
Upload folder using huggingface_hub
18e3b27 verified
Raw
History Blame Contribute Delete
7.6 kB
#!/usr/bin/env python3
"""
OpenEnv Compliance Test Script
Tests all requirements for HF Space deployment:
1. Reset endpoint availability
2. Step/state endpoints
3. All tasks enumerable
4. All graders produce scores in [0, 1]
5. Reward in valid range
"""
import sys
import json
from server.my_env_environment import QuantumCircuitEnvironment
from models import ActionType, GateType, QuantumAction
def test_reset_endpoint():
"""Test reset endpoint with all tasks."""
print("=" * 60)
print("TEST 1: Reset Endpoint")
print("=" * 60)
env = QuantumCircuitEnvironment(seed=42)
tasks = ["easy", "medium", "hard", "efficient", "noisy", "budget", "approx"]
for task_id in tasks:
try:
obs = env.reset(config={"task_id": task_id})
assert obs is not None, f"Reset returned None for task {task_id}"
assert obs.task_id == task_id, f"Task ID mismatch: {obs.task_id} != {task_id}"
assert 0.0 <= obs.score <= 1.0, f"Score out of range: {obs.score}"
print(f" ✓ Task '{task_id}': reset OK, score={obs.score:.4f}")
except Exception as e:
print(f" ✗ Task '{task_id}': FAILED - {e}")
return False
print(" ✓ All tasks reset successfully\n")
return True
def test_step_endpoint():
"""Test step endpoint."""
print("=" * 60)
print("TEST 2: Step Endpoint")
print("=" * 60)
env = QuantumCircuitEnvironment(seed=42)
obs = env.reset(config={"task_id": "easy"})
# Test ADD action
action = QuantumAction(action_type=ActionType.ADD, gate=GateType.H, qubits=[0])
obs = env.step(action)
assert obs is not None, "Step returned None"
assert hasattr(obs, 'reward'), "Observation missing reward"
assert hasattr(obs, 'done'), "Observation missing done"
print(f" ✓ ADD action: reward={obs.reward:.4f}, done={obs.done}")
# Test REMOVE action
action = QuantumAction(action_type=ActionType.REMOVE)
obs = env.step(action)
print(f" ✓ REMOVE action: reward={obs.reward:.4f}, done={obs.done}")
# Test STOP action
action = QuantumAction(action_type=ActionType.STOP)
obs = env.step(action)
assert obs.done == True, "STOP should set done=True"
print(f" ✓ STOP action: reward={obs.reward:.4f}, done={obs.done}\n")
return True
def test_state_endpoint():
"""Test state property."""
print("=" * 60)
print("TEST 3: State Endpoint")
print("=" * 60)
env = QuantumCircuitEnvironment(seed=42)
obs = env.reset(config={"task_id": "easy"})
state = env.state
assert state is not None, "State returned None"
assert hasattr(state, 'episode_id'), "State missing episode_id"
assert hasattr(state, 'step_count'), "State missing step_count"
assert hasattr(state, 'circuit_gates'), "State missing circuit_gates"
print(f" ✓ State accessible: episode_id={state.episode_id[:8]}..., steps={state.step_count}")
print(f" ✓ State fields: {list(state.__dict__.keys())}\n")
return True
def test_all_tasks_with_graders():
"""Test all tasks and verify grader scores."""
print("=" * 60)
print("TEST 4: All Tasks + Graders (3+ tasks)")
print("=" * 60)
env = QuantumCircuitEnvironment(seed=42)
tasks = ["easy", "medium", "hard", "efficient", "noisy", "budget", "approx"]
print(f" Total tasks: {len(tasks)}")
assert len(tasks) >= 3, f"Need at least 3 tasks, found {len(tasks)}"
for task_id in tasks:
obs = env.reset(config={"task_id": task_id})
# Check initial scores
assert 0.0 <= obs.score <= 1.0, f"Score out of range: {obs.score}"
assert 0.0 <= obs.fidelity <= 1.0, f"Fidelity out of range: {obs.fidelity}"
# Take a step
action = QuantumAction(action_type=ActionType.ADD, gate=GateType.H, qubits=[0])
obs = env.step(action)
# Verify all scores in valid range
assert 0.0 <= obs.score <= 1.0, f"Score out of range after step: {obs.score}"
assert 0.0 <= obs.fidelity <= 1.0, f"Fidelity out of range: {obs.fidelity}"
# Check metadata scores
if obs.metadata:
for key, value in obs.metadata.items():
if key.endswith('_score') and isinstance(value, (int, float)):
assert 0.0 <= value <= 1.0, f"{key} out of range: {value}"
print(f" ✓ Task '{task_id}': fid={obs.fidelity:.4f}, score={obs.score:.4f}, reward={obs.reward:.4f}")
print(f" ✓ All {len(tasks)} tasks passed grader validation\n")
return True
def test_reward_range():
"""Test that rewards are in valid range."""
print("=" * 60)
print("TEST 5: Reward Range")
print("=" * 60)
env = QuantumCircuitEnvironment(seed=42)
obs = env.reset(config={"task_id": "easy"})
rewards = []
for i in range(10):
if obs.done:
break
action = QuantumAction(action_type=ActionType.ADD, gate=GateType.H, qubits=[i % 2])
obs = env.step(action)
rewards.append(obs.reward)
for i, r in enumerate(rewards):
# Rewards should be reasonable (typically -1 to 1)
assert -2.0 <= r <= 2.0, f"Reward {i} out of reasonable range: {r}"
print(f" Step {i+1}: reward={r:+.4f}")
print(f" ✓ All rewards in valid range\n")
return True
def test_openenv_yaml():
"""Test openenv.yaml compliance."""
print("=" * 60)
print("TEST 6: openenv.yaml Compliance")
print("=" * 60)
import yaml
with open("openenv.yaml", "r") as f:
config = yaml.safe_load(f)
required_fields = ["spec_version", "name", "type", "runtime", "app", "port", "tasks"]
for field in required_fields:
assert field in config, f"Missing required field: {field}"
print(f" ✓ {field}: {config[field]}")
# Check tasks
assert len(config["tasks"]) >= 3, f"Need at least 3 tasks in openenv.yaml"
print(f" ✓ Tasks defined: {len(config['tasks'])}")
# Check schemas
assert "action_schema" in config, "Missing action_schema"
assert "observation_schema" in config, "Missing observation_schema"
print(f" ✓ Schemas defined\n")
return True
def main():
"""Run all compliance tests."""
print("\n" + "=" * 60)
print("OPENENV COMPLIANCE TEST SUITE")
print("=" * 60 + "\n")
tests = [
("Reset Endpoint", test_reset_endpoint),
("Step Endpoint", test_step_endpoint),
("State Endpoint", test_state_endpoint),
("Tasks + Graders", test_all_tasks_with_graders),
("Reward Range", test_reward_range),
("openenv.yaml", test_openenv_yaml),
]
results = []
for name, test_func in tests:
try:
result = test_func()
results.append((name, result))
except Exception as e:
print(f" ✗ {name} FAILED: {e}\n")
results.append((name, False))
# Summary
print("=" * 60)
print("SUMMARY")
print("=" * 60)
passed = sum(1 for _, r in results if r)
total = len(results)
for name, result in results:
status = "✓ PASS" if result else "✗ FAIL"
print(f" {status}: {name}")
print(f"\nTotal: {passed}/{total} tests passed")
if passed == total:
print("\n🎉 ALL COMPLIANCE TESTS PASSED!")
return 0
else:
print(f"\n❌ {total - passed} test(s) failed")
return 1
if __name__ == "__main__":
sys.exit(main())