Spaces:
Sleeping
Sleeping
File size: 6,323 Bytes
bc12c74 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 | """
Test the actual HTTP response flow as the OpenEnv validator would see it.
This simulates calling /step endpoint and checking JSON response.
"""
import json
import sys
from fastapi.testclient import TestClient
from server.app import app
client = TestClient(app)
def test_http_flow():
"""Test complete HTTP flow for reward responses."""
print("="*80)
print("HTTP RESPONSE FLOW TEST")
print("="*80)
failures = []
# 1. Reset
print("\n1. Calling /reset...")
resp_reset = client.post("/reset")
if resp_reset.status_code != 200:
print(f" [FAIL] Reset failed: {resp_reset.status_code}")
print(f" Response: {resp_reset.text}")
return
print(f" [OK] Reset successful")
#2. Step with fixed config for task1
print("\n2. Calling /step with fixed config for task1_json...")
step_payload = {
"fixed_config": '{"name": "Alice", "age": 30, "email": "alice@example.com"}'
}
resp_step = client.post("/step", json=step_payload)
if resp_step.status_code != 200:
print(f" [FAIL] Step failed: {resp_step.status_code}")
print(f" Response: {resp_step.text}")
return
print(f" [OK] Step returned 200")
try:
response_json = resp_step.json()
print(f" JSON parsed successfully")
print(f" Response keys: {list(response_json.keys())}")
except json.JSONDecodeError as e:
print(f" [FAIL] Failed to parse JSON: {e}")
print(f" Raw response: {resp_step.text}")
failures.append("JSON parse failed")
return
# 3. Check reward field
if "reward" not in response_json:
print(f" [FAIL] No 'reward' field in response")
print(f" Response: {response_json}")
failures.append("Missing reward field")
return
reward = response_json["reward"]
print(f"\n3. Reward value in response: {reward}")
print(f" Type: {type(reward).__name__}")
print(f" Repr: {repr(reward)}")
# 4. Validate reward
try:
reward_float = float(reward)
print(f" Converted to float: {reward_float}")
except (TypeError, ValueError) as e:
print(f" [FAIL] Cannot convert to float: {e}")
failures.append(f"Reward not numeric: {reward}")
return
# 5. Check bounds
if reward_float == float('inf') or reward_float == float('-inf'):
print(f" [FAIL] Reward is infinite")
failures.append("Reward is infinite")
elif reward_float != reward_float: # NaN
print(f" [FAIL] Reward is NaN")
failures.append("Reward is NaN")
elif not (0.0 < reward_float < 1.0):
print(f" [FAIL] Reward {reward_float} out of bounds (0, 1)")
failures.append(f"Out of bounds: {reward_float}")
else:
print(f" [OK] Reward {reward_float} is in valid range (0, 1)")
# 6. Check JSON serialization round-trip
print(f"\n4. JSON serialization check...")
json_str = json.dumps(response_json)
print(f" JSON string: {json_str[:100]}...")
reparsed = json.loads(json_str)
reparsed_reward = reparsed.get("reward")
print(f" After round-trip: {reparsed_reward}")
print(f" Type: {type(reparsed_reward).__name__}")
if reparsed_reward != reward:
print(f" [WARN] Reward changed during round-trip: {reward} -> {reparsed_reward}")
# Summary
if failures:
print(f"\n{'='*80}")
print(f"[FAIL] Found {len(failures)} issues:")
for f in failures:
print(f" - {f}")
return False
else:
print(f"\n[OK] All HTTP response checks passed")
return True
def test_all_tasks():
"""Test /step with perfect configs for all 7 tasks."""
print("\n" + "="*80)
print("TESTING ALL 7 TASKS VIA /step ENDPOINT")
print("="*80)
test_configs = {
"task1_json": '{"name": "Alice", "age": 30, "email": "alice@example.com"}',
"task2_yaml": "name: Alice\nage: 30\nemail: alice@example.com",
"task3_dockerfile": "FROM python:3.9-slim\nRUN apt-get update\nEXPOSE 3000\nCMD [\"python\", \"app.py\"]",
"task4_compose": "services:\n web:\n image: app\n ports:\n - '8080:3000'\n db:\n image: postgres",
"task5_k8s": "apiVersion: v1\nkind: Pod\nmetadata:\n name: app-pod\nspec:\n containers:\n - name: app\n image: app:latest",
"task6_github_actions": "on: push\njobs:\n build:\n runs-on: ubuntu-latest\n steps:\n - uses: actions/checkout\n - run: echo test",
"task7_nginx": "server {\n listen 80;\n server_name example.com;\n location / {\n proxy_pass http://localhost:3000;\n }\n}",
}
all_passed = True
# Reset once
client.post("/reset")
for task_id, config in test_configs.items():
print(f"\nTask: {task_id}")
resp = client.post("/step", json={"fixed_config": config})
if resp.status_code != 200:
print(f" [FAIL] Status {resp.status_code}: {resp.text[:100]}")
all_passed = False
continue
try:
data = resp.json()
reward = data.get("reward")
if reward is None:
print(f" [FAIL] No reward in response")
all_passed = False
else:
reward_float = float(reward)
if 0.0 < reward_float < 1.0:
print(f" [OK] Reward: {reward}")
else:
print(f" [FAIL] Out of bounds: {reward_float}")
all_passed = False
except Exception as e:
print(f" [FAIL] Exception: {e}")
all_passed = False
return all_passed
def main():
try:
# Test single flow
passed = test_http_flow()
if passed is not False:
# Test all tasks
all_passed = test_all_tasks()
print("\n" + "="*80)
print("HTTP FLOW TEST COMPLETE")
print("="*80)
except Exception as e:
print(f"\n[EXCEPTION] {type(e).__name__}: {e}")
import traceback
traceback.print_exc()
sys.exit(1)
if __name__ == "__main__":
main()
|