fix(tests): run sandbox integration on firecracker
test / integration-firecracker (pull_request) Failing after 5s
test / integration-docker (pull_request) Successful in 9s
tracker-policy-pr / check-pr (pull_request) Successful in 7s
test / unit (pull_request) Successful in 33s
test / coverage (pull_request) Failing after 27s
lint / lint (push) Failing after 42s
test / integration-firecracker (pull_request) Failing after 5s
test / integration-docker (pull_request) Successful in 9s
tracker-policy-pr / check-pr (pull_request) Successful in 7s
test / unit (pull_request) Successful in 33s
test / coverage (pull_request) Failing after 27s
lint / lint (push) Failing after 42s
This commit is contained in:
@@ -30,3 +30,16 @@ def docker_available() -> bool:
|
|||||||
|
|
||||||
def skip_unless_docker(reason: str = "docker unreachable"):
|
def skip_unless_docker(reason: str = "docker unreachable"):
|
||||||
return unittest.skipUnless(docker_available(), reason)
|
return unittest.skipUnless(docker_available(), reason)
|
||||||
|
|
||||||
|
|
||||||
|
def skip_unless_docker_or_firecracker(
|
||||||
|
reason: str = "neither Docker nor Firecracker selected",
|
||||||
|
):
|
||||||
|
"""Skip a backend-agnostic test unless one supported backend can run.
|
||||||
|
|
||||||
|
Firecracker does not require the host Docker daemon. The KVM coverage job
|
||||||
|
deliberately sets ``SKIP_DOCKER_TESTS`` to exclude Docker-only integration
|
||||||
|
classes while still exercising this path.
|
||||||
|
"""
|
||||||
|
firecracker_selected = os.environ.get("BOT_BOTTLE_BACKEND") == "firecracker"
|
||||||
|
return unittest.skipUnless(firecracker_selected or docker_available(), reason)
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ from pathlib import Path
|
|||||||
from bot_bottle.backend import BottleSpec, get_bottle_backend
|
from bot_bottle.backend import BottleSpec, get_bottle_backend
|
||||||
from bot_bottle.bottle_state import cleanup_state
|
from bot_bottle.bottle_state import cleanup_state
|
||||||
from bot_bottle.manifest import ManifestIndex
|
from bot_bottle.manifest import ManifestIndex
|
||||||
from tests._docker import skip_unless_docker
|
from tests._docker import skip_unless_docker_or_firecracker
|
||||||
|
|
||||||
|
|
||||||
# Secrets planted in the bottle env as literals (agents substitute via
|
# Secrets planted in the bottle env as literals (agents substitute via
|
||||||
@@ -67,7 +67,7 @@ _DUMMY_HOST_KEY = (
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@skip_unless_docker()
|
@skip_unless_docker_or_firecracker()
|
||||||
@unittest.skipIf(
|
@unittest.skipIf(
|
||||||
os.environ.get("GITEA_ACTIONS") == "true"
|
os.environ.get("GITEA_ACTIONS") == "true"
|
||||||
and os.environ.get("BOT_BOTTLE_BACKEND") != "firecracker",
|
and os.environ.get("BOT_BOTTLE_BACKEND") != "firecracker",
|
||||||
@@ -91,11 +91,9 @@ class TestSandboxEscape(unittest.TestCase):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def setUpClass(cls) -> None:
|
def setUpClass(cls) -> None:
|
||||||
# Docker is always required (the agent + companion containers run under it,
|
# Pin Docker when BOT_BOTTLE_BACKEND is unset to preserve the
|
||||||
# and VM backends still use it for the gateway); the
|
# Docker-backed CI path. Firecracker uses its persistent infra VM for
|
||||||
# class-level @skip_unless_docker already covers that. Pin
|
# the shared gateway and therefore does not require host Docker.
|
||||||
# Docker when BOT_BOTTLE_BACKEND is unset to preserve the
|
|
||||||
# Docker-backed CI path.
|
|
||||||
cls._backend_name = os.environ.get("BOT_BOTTLE_BACKEND", "docker")
|
cls._backend_name = os.environ.get("BOT_BOTTLE_BACKEND", "docker")
|
||||||
|
|
||||||
# Throwaway static key for the git-gate fixture. It need not
|
# Throwaway static key for the git-gate fixture. It need not
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
"""Tests for integration-test backend selection helpers."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import os
|
||||||
|
import unittest
|
||||||
|
from unittest.mock import patch
|
||||||
|
|
||||||
|
from tests._docker import skip_unless_docker_or_firecracker
|
||||||
|
|
||||||
|
|
||||||
|
class TestSkipUnlessDockerOrFirecracker(unittest.TestCase):
|
||||||
|
def test_firecracker_runs_when_docker_tests_are_disabled(self):
|
||||||
|
with patch.dict(
|
||||||
|
os.environ,
|
||||||
|
{"BOT_BOTTLE_BACKEND": "firecracker", "SKIP_DOCKER_TESTS": "1"},
|
||||||
|
clear=True,
|
||||||
|
):
|
||||||
|
decorated = skip_unless_docker_or_firecracker()(type("Case", (), {}))
|
||||||
|
|
||||||
|
self.assertFalse(getattr(decorated, "__unittest_skip__", False))
|
||||||
|
|
||||||
|
def test_non_firecracker_still_skips_when_docker_tests_are_disabled(self):
|
||||||
|
with patch.dict(
|
||||||
|
os.environ,
|
||||||
|
{"BOT_BOTTLE_BACKEND": "docker", "SKIP_DOCKER_TESTS": "1"},
|
||||||
|
clear=True,
|
||||||
|
):
|
||||||
|
decorated = skip_unless_docker_or_firecracker()(type("Case", (), {}))
|
||||||
|
|
||||||
|
self.assertTrue(decorated.__unittest_skip__)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
unittest.main()
|
||||||
Reference in New Issue
Block a user