Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions server/src/api/lifecycle.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
@router.post(
"/sandboxes",
response_model=CreateSandboxResponse,
response_model_exclude_none=True,
status_code=status.HTTP_202_ACCEPTED,
responses={
202: {"description": "Sandbox creation accepted for asynchronous provisioning"},
Expand Down Expand Up @@ -92,6 +93,7 @@ async def create_sandbox(
@router.get(
"/sandboxes",
response_model=ListSandboxesResponse,
response_model_exclude_none=True,
responses={
200: {"description": "Paginated collection of sandboxes"},
400: {"model": ErrorResponse, "description": "The request was invalid or malformed"},
Expand Down Expand Up @@ -155,6 +157,7 @@ async def list_sandboxes(
@router.get(
"/sandboxes/{sandbox_id}",
response_model=Sandbox,
response_model_exclude_none=True,
responses={
200: {"description": "Sandbox current state and metadata"},
401: {"model": ErrorResponse, "description": "Authentication credentials are missing or invalid"},
Expand Down
2 changes: 1 addition & 1 deletion server/src/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@

from src.api.lifecycle import router # noqa: E402
from src.api.pool import router as pool_router # noqa: E402
from src.api.lifecycle import router, sandbox_service # noqa: E402
from src.api.lifecycle import sandbox_service # noqa: E402
from src.api.proxy import router as proxy_router # noqa: E402
from src.integrations.renew_intent.proxy_renew import ProxyRenewCoordinator # noqa: E402
from src.middleware.auth import AuthMiddleware # noqa: E402
Expand Down
2 changes: 1 addition & 1 deletion server/tests/k8s/test_pool_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"""

import pytest
from unittest.mock import MagicMock, call
from unittest.mock import MagicMock
from kubernetes.client import ApiException

from src.api.schema import (
Expand Down
1 change: 0 additions & 1 deletion server/tests/test_pool_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
so no real cluster connection is needed.
"""

import pytest
from unittest.mock import MagicMock, patch
from fastapi.testclient import TestClient
from fastapi import HTTPException, status as http_status
Expand Down
15 changes: 7 additions & 8 deletions server/tests/test_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,14 +164,14 @@ def test_get_sandbox_success(
"""
pass

def test_get_sandbox_preserves_nullable_expires_at(
def test_get_sandbox_omits_null_optional_fields(
self,
client: TestClient,
auth_headers: dict,
monkeypatch,
):
"""
Ensure expiresAt is returned as null for manual-cleanup sandboxes.
Ensure optional null fields are omitted from JSON (manual-cleanup sandboxes).
"""
now = datetime.now(timezone.utc)
sandbox = Sandbox(
Expand All @@ -195,16 +195,15 @@ def get_sandbox(sandbox_id: str) -> Sandbox:
assert response.status_code == 200

payload = response.json()
assert payload["metadata"] is None
assert "metadata" not in payload
assert payload["id"] == "sandbox-123"
assert payload["entrypoint"] == ["python"]
assert "expiresAt" in payload
assert payload["expiresAt"] is None
assert "expiresAt" not in payload
assert "createdAt" in payload
assert payload["status"]["state"] == "Running"
assert payload["status"]["reason"] is None
assert payload["status"]["message"] is None
assert payload["status"]["lastTransitionAt"] is None
assert "reason" not in payload["status"]
assert "message" not in payload["status"]
assert "lastTransitionAt" not in payload["status"]

def test_get_sandbox_not_found(
self,
Expand Down
12 changes: 6 additions & 6 deletions server/tests/test_routes_create_delete.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ async def create_sandbox(request) -> CreateSandboxResponse:
assert calls[0].image.uri == "python:3.11"


def test_create_sandbox_manual_cleanup_returns_null_expiration(
def test_create_sandbox_manual_cleanup_omits_null_optional_fields(
client: TestClient,
auth_headers: dict,
sample_sandbox_request: dict,
Expand Down Expand Up @@ -91,11 +91,11 @@ async def create_sandbox(request) -> CreateSandboxResponse:

assert response.status_code == 202
payload = response.json()
assert payload["expiresAt"] is None
assert payload["metadata"] is None
assert payload["status"]["reason"] is None
assert payload["status"]["message"] is None
assert payload["status"]["lastTransitionAt"] is None
assert "expiresAt" not in payload
assert "metadata" not in payload
assert "reason" not in payload["status"]
assert "message" not in payload["status"]
assert "lastTransitionAt" not in payload["status"]


def test_create_sandbox_rejects_invalid_request(
Expand Down
12 changes: 6 additions & 6 deletions server/tests/test_routes_list_sandboxes.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ def list_sandboxes(request) -> ListSandboxesResponse:
assert captured_requests[0].filter.metadata == {"team": "infra", "note": ""}


def test_list_sandboxes_preserves_only_nullable_expires_at(
def test_list_sandboxes_omits_null_optional_fields(
client: TestClient,
auth_headers: dict,
monkeypatch,
Expand Down Expand Up @@ -169,11 +169,11 @@ def list_sandboxes(request) -> ListSandboxesResponse:

assert response.status_code == 200
item = response.json()["items"][0]
assert item["expiresAt"] is None
assert item["metadata"] is None
assert item["status"]["reason"] is None
assert item["status"]["message"] is None
assert item["status"]["lastTransitionAt"] is None
assert "expiresAt" not in item
assert "metadata" not in item
assert "reason" not in item["status"]
assert "message" not in item["status"]
assert "lastTransitionAt" not in item["status"]


def test_list_sandboxes_validates_page_bounds(
Expand Down