"""E2B cloud adapter tests.""" from __future__ import annotations from unittest.mock import MagicMock, patch import pytest from sandboxer.extensions.credentials import credentials_available, resolve_api_key from sandboxer.extensions.e2b import E2BExtension from sandboxer.models import Profile def _profile() -> Profile: return Profile.model_validate( { "id": "profile.e2b-burst", "version": "1.0.0", "extension": "ext.e2b", } ) def test_credentials_from_env(monkeypatch: pytest.MonkeyPatch) -> None: monkeypatch.setenv("E2B_API_KEY", "test-key") config = {"api_key_env": "E2B_API_KEY", "secret_ref": "e2b-api-key"} assert resolve_api_key(config, extension_id="ext.e2b") == "test-key" assert credentials_available("ext.e2b", config) def test_provision_and_teardown_with_mock_client(monkeypatch: pytest.MonkeyPatch) -> None: monkeypatch.setenv("E2B_API_KEY", "test-key") ext = E2BExtension( { "api_base": "https://api.e2b.dev", "api_key_env": "E2B_API_KEY", "provider": "e2b", "template_id": "base", } ) mock_client = MagicMock() create_resp = MagicMock() create_resp.status_code = 200 create_resp.json.return_value = { "sandboxID": "e2b-prov-1", "sandboxURL": "https://e2b-prov-1.e2b.dev", } ready_resp = MagicMock() ready_resp.status_code = 200 delete_resp = MagicMock() delete_resp.status_code = 204 mock_client.post.return_value = create_resp mock_client.get.return_value = ready_resp mock_client.delete.return_value = delete_resp mock_client.__enter__.return_value = mock_client mock_client.__exit__.return_value = None with patch.object(ext, "_client_factory", return_value=mock_client): handle = ext.provision(_profile(), {}, "e2b") assert handle["provider_sandbox_id"] == "e2b-prov-1" reach = ext.wait_ready(handle) assert "e2b-prov-1" in reach["endpoint"] report = ext.teardown(handle) assert report["provider_removed"] == "true" def test_estimate_cost() -> None: ext = E2BExtension({"rate_usd_per_hour": 0.15, "session_fee_usd": 0.02}) quote = ext.estimate_cost(_profile(), {}, duration_s=3600) assert quote.extension_id == "ext.e2b" assert quote.estimated_usd > 0