echo-cli / src /core /containers /test_local_docker_provider.py
burtenshaw's picture
burtenshaw HF Staff
Upload folder using huggingface_hub
2d8433b verified
#!/usr/bin/env python3
"""
End-to-end test for LocalDockerProvider.
This script tests the complete flow:
1. Start a container using LocalDockerProvider
2. Wait for it to be ready
3. Make HTTP requests to test the environment
4. Clean up the container
"""
import sys
from pathlib import Path
# Add src to path
sys.path.insert(0, str(Path(__file__).parent.parent.parent))
import requests
from core.containers.runtime import LocalDockerProvider
# TODO: Remove this test or make it a functional test sicne this will be tested in e2e test for echo env
def test_local_docker_provider():
"""Test LocalDockerProvider end-to-end."""
print("=" * 60)
print("LocalDockerProvider End-to-End Test")
print("=" * 60)
print()
provider = None
try:
# Step 1: Create provider
print("Step 1: Creating LocalDockerProvider...")
provider = LocalDockerProvider()
print("βœ“ Provider created\n")
# Step 2: Start container
print("Step 2: Starting echo-env container...")
base_url = provider.start_container("echo-env:latest")
print(f"βœ“ Container started at: {base_url}")
if provider._container_id:
print(f" Container ID: {provider._container_id[:12]}...")
if provider._container_name:
print(f" Container name: {provider._container_name}\n")
# Step 3: Wait for ready
print("Step 3: Waiting for container to be ready...")
provider.wait_for_ready(base_url, timeout_s=30.0)
print("βœ“ Container is ready!\n")
# Step 4: Test health endpoint
print("Step 4: Testing /health endpoint...")
response = requests.get(f"{base_url}/health")
print(f" Status: {response.status_code}")
print(f" Response: {response.json()}")
assert response.status_code == 200
assert response.json()["status"] == "healthy"
print("βœ“ Health check passed\n")
# Step 5: Test reset endpoint
print("Step 5: Testing /reset endpoint...")
response = requests.post(
f"{base_url}/reset",
json={},
headers={"Content-Type": "application/json"},
)
print(f" Status: {response.status_code}")
data = response.json()
print(f" Message: {data['observation']['echoed_message']}")
print(f" Reward: {data['reward']}")
print(f" Done: {data['done']}")
assert response.status_code == 200
assert data["observation"]["echoed_message"] == "Echo environment ready!"
print("βœ“ Reset test passed\n")
# Step 6: Test step endpoint
print("Step 6: Testing /step endpoint...")
response = requests.post(
f"{base_url}/step",
json={"action": {"message": "Hello from LocalDockerProvider!"}},
headers={"Content-Type": "application/json"},
)
print(f" Status: {response.status_code}")
data = response.json()
print(f" Echoed: {data['observation']['echoed_message']}")
print(f" Length: {data['observation']['message_length']}")
print(f" Reward: {data['reward']}")
assert response.status_code == 200
assert data["observation"]["echoed_message"] == "Hello from LocalDockerProvider!"
assert data["observation"]["message_length"] == 31
print("βœ“ Step test passed\n")
# Step 7: Test state endpoint
print("Step 7: Testing /state endpoint...")
response = requests.get(f"{base_url}/state")
print(f" Status: {response.status_code}")
data = response.json()
print(f" Episode ID: {data['episode_id']}")
print(f" Step count: {data['step_count']}")
assert response.status_code == 200
assert data["step_count"] == 1 # One step from above
print("βœ“ State test passed\n")
# Step 8: Multiple steps
print("Step 8: Testing multiple steps...")
for i in range(3):
response = requests.post(
f"{base_url}/step",
json={"action": {"message": f"Message {i+1}"}},
headers={"Content-Type": "application/json"},
)
assert response.status_code == 200
print(f" Step {i+1}: βœ“")
# Check state updated
response = requests.get(f"{base_url}/state")
data = response.json()
assert data["step_count"] == 4 # 1 + 3 more steps
print(f" Final step count: {data['step_count']}")
print("βœ“ Multiple steps test passed\n")
print("=" * 60)
print("βœ“ All tests passed!")
print("=" * 60)
print()
return True
except Exception as e:
print(f"\n❌ Test failed: {e}")
import traceback
traceback.print_exc()
return False
finally:
# Step 9: Cleanup
if provider is not None:
print("\nStep 9: Cleaning up container...")
try:
provider.stop_container()
print("βœ“ Container stopped and removed\n")
except Exception as e:
print(f"⚠️ Cleanup warning: {e}\n")
def test_provider_with_custom_port():
"""Test provider with custom port."""
print("=" * 60)
print("LocalDockerProvider with Custom Port Test")
print("=" * 60)
print()
provider = None
try:
provider = LocalDockerProvider()
print("Starting container on custom port 8123...")
base_url = provider.start_container("echo-env:latest", port=8123)
print(f"βœ“ Started at: {base_url}")
assert ":8123" in base_url
print("Waiting for ready...")
provider.wait_for_ready(base_url)
print("βœ“ Ready!")
print("Testing health...")
response = requests.get(f"{base_url}/health")
assert response.status_code == 200
print("βœ“ Health check passed")
print("\nβœ“ Custom port test passed!\n")
return True
except Exception as e:
print(f"\n❌ Test failed: {e}")
return False
finally:
if provider is not None:
provider.stop_container()
print("βœ“ Cleaned up\n")
def test_provider_with_env_vars():
"""Test provider with environment variables."""
print("=" * 60)
print("LocalDockerProvider with Environment Variables Test")
print("=" * 60)
print()
provider = None
try:
provider = LocalDockerProvider()
print("Starting container with environment variables...")
base_url = provider.start_container(
"echo-env:latest",
env_vars={"DEBUG": "true", "LOG_LEVEL": "info"}
)
print(f"βœ“ Started at: {base_url}")
print("Waiting for ready...")
provider.wait_for_ready(base_url)
print("βœ“ Ready!")
print("Testing health...")
response = requests.get(f"{base_url}/health")
assert response.status_code == 200
print("βœ“ Health check passed")
print("\nβœ“ Environment variables test passed!\n")
return True
except Exception as e:
print(f"\n❌ Test failed: {e}")
return False
finally:
if provider is not None:
provider.stop_container()
print("βœ“ Cleaned up\n")
if __name__ == "__main__":
print()
print("🐳 LocalDockerProvider Test Suite")
print()
results = []
# Run basic test
results.append(("Basic End-to-End", test_local_docker_provider()))
# Run custom port test
results.append(("Custom Port", test_provider_with_custom_port()))
# Run environment variables test
results.append(("Environment Variables", test_provider_with_env_vars()))
# Summary
print("=" * 60)
print("Test Summary")
print("=" * 60)
for name, passed in results:
status = "βœ“ PASSED" if passed else "βœ— FAILED"
print(f"{name:25} {status}")
print("=" * 60)
all_passed = all(result for _, result in results)
if all_passed:
print("\nπŸŽ‰ All tests passed!")
exit(0)
else:
print("\n❌ Some tests failed")
exit(1)