Bring back sandbox VCR

This commit is contained in:
Yiorgis Gozadinos 2026-02-11 16:49:59 +02:00
parent 81140e9d19
commit 0562809344
No known key found for this signature in database
4 changed files with 210 additions and 21 deletions

View file

@ -1,14 +1,21 @@
import os import os
from contextlib import AbstractContextManager
from pathlib import Path
import docker import docker
import docker.errors import docker.errors
import pytest import pytest
import vcr
import vcr.cassette
from tests import json_body_serializer
from haiku.rag.agents.rlm.dependencies import RLMContext from haiku.rag.agents.rlm.dependencies import RLMContext
from haiku.rag.agents.rlm.docker_sandbox import DockerSandbox, SandboxResult from haiku.rag.agents.rlm.docker_sandbox import DockerSandbox, SandboxResult
from haiku.rag.client import HaikuRAG from haiku.rag.client import HaikuRAG
from haiku.rag.config.models import RLMConfig from haiku.rag.config.models import RLMConfig
CASSETTE_DIR = str(Path(__file__).parent.parent.parent / "cassettes" / "test_sandbox")
def is_docker_available() -> bool: def is_docker_available() -> bool:
"""Check if Docker daemon is available.""" """Check if Docker daemon is available."""
@ -27,6 +34,19 @@ docker_required = pytest.mark.skipif(
) )
def cassette(name: str) -> AbstractContextManager[vcr.cassette.Cassette]:
"""VCR cassette scoped to embedding calls only (not docker-py)."""
v = vcr.VCR()
v.register_serializer("yaml", json_body_serializer)
return v.use_cassette(
f"{CASSETTE_DIR}/{name}.yaml",
record_mode="none" if os.environ.get("CI") else "new_episodes",
filter_headers=["authorization", "x-api-key"],
ignore_hosts=["huggingface.co"],
decode_compressed_response=True,
)
@pytest.mark.integration @pytest.mark.integration
class TestDockerSandboxBasics: class TestDockerSandboxBasics:
"""Test basic Docker sandbox functionality.""" """Test basic Docker sandbox functionality."""
@ -106,11 +126,12 @@ class TestDockerSandboxHaikuRAG:
async def test_list_documents_with_data(self, temp_db_path, test_docker_image): async def test_list_documents_with_data(self, temp_db_path, test_docker_image):
"""Test list_documents returns documents when populated.""" """Test list_documents returns documents when populated."""
async with HaikuRAG(temp_db_path, create=True) as client: async with HaikuRAG(temp_db_path, create=True) as client:
await client.create_document( with cassette("test_list_documents_with_data"):
content="Test content", await client.create_document(
uri="test://doc1", content="Test content",
title="Test Document", uri="test://doc1",
) title="Test Document",
)
config = RLMConfig(docker_image=test_docker_image) config = RLMConfig(docker_image=test_docker_image)
context = RLMContext() context = RLMContext()
@ -128,7 +149,7 @@ class TestDockerSandboxHaikuRAG:
@pytest.mark.asyncio @pytest.mark.asyncio
@pytest.mark.skipif( @pytest.mark.skipif(
os.environ.get("CI") == "true", os.environ.get("CI") == "true",
reason="Requires Ollama running inside Docker container", reason="Requires Ollama inside Docker container",
) )
async def test_search_with_data(self, temp_db_path, test_docker_image): async def test_search_with_data(self, temp_db_path, test_docker_image):
"""Test search function works.""" """Test search function works."""
@ -159,11 +180,12 @@ class TestDockerSandboxHaikuRAG:
async def test_get_document(self, temp_db_path, test_docker_image): async def test_get_document(self, temp_db_path, test_docker_image):
"""Test get_document function.""" """Test get_document function."""
async with HaikuRAG(temp_db_path, create=True) as client: async with HaikuRAG(temp_db_path, create=True) as client:
doc = await client.create_document( with cassette("test_get_document"):
content="Content about foxes and dogs.", doc = await client.create_document(
uri="test://doc", content="Content about foxes and dogs.",
title="Fox Document", uri="test://doc",
) title="Fox Document",
)
config = RLMConfig(docker_image=test_docker_image) config = RLMConfig(docker_image=test_docker_image)
context = RLMContext() context = RLMContext()
@ -199,16 +221,17 @@ class TestDockerSandboxContextFilter:
): ):
"""Test that context filter is passed to list_documents.""" """Test that context filter is passed to list_documents."""
async with HaikuRAG(temp_db_path, create=True) as client: async with HaikuRAG(temp_db_path, create=True) as client:
await client.create_document( with cassette("test_filter_applied_to_list_documents"):
content="Public content", await client.create_document(
uri="public://doc1", content="Public content",
title="Public Doc", uri="public://doc1",
) title="Public Doc",
await client.create_document( )
content="Private content", await client.create_document(
uri="private://doc2", content="Private content",
title="Private Doc", uri="private://doc2",
) title="Private Doc",
)
config = RLMConfig(docker_image=test_docker_image) config = RLMConfig(docker_image=test_docker_image)
context = RLMContext(filter="uri LIKE 'public://%'") context = RLMContext(filter="uri LIKE 'public://%'")

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long