test: add unit tests for stale-image checks to reach ≥90% diff-coverage
lint / lint (push) Failing after 2m2s
test / unit (pull_request) Successful in 58s
test / integration (pull_request) Successful in 15s
test / coverage (pull_request) Successful in 1m11s

Covers StaleImageError / check_stale / check_stale_path, the
BottleBackend.launch template method (skip_stale flag), stale_checks
functions across docker / smolmachines / macos-container backends,
_build_images cached paths in the macOS backend, image_created_at edge
cases in both docker and container util modules, the CLI stale loop
(headless die, interactive decline, interactive confirm + retry), and
ConfigStore.cached_image_stale_warning_days fallback paths.

Diff-coverage: 488/507 changed lines covered (96.3%).
This commit is contained in:
2026-07-09 19:06:38 +00:00
parent 60b394e4fb
commit 1a53e07039
7 changed files with 807 additions and 0 deletions
+98
View File
@@ -365,5 +365,103 @@ class TestMacosContainerLaunchCommittedImage(unittest.TestCase):
self.assertEqual("bot-bottle-agent:latest", calls[1][0])
class TestMacosContainerLaunchCachedImages(unittest.TestCase):
def setUp(self):
self._tmp = tempfile.TemporaryDirectory()
self.stage_dir = Path(self._tmp.name)
def tearDown(self):
self._tmp.cleanup()
def test_cached_mode_dies_when_agent_image_missing(self):
plan = _build_plan(self.stage_dir)
from bot_bottle.backend import BottleSpec
import dataclasses
plan = dataclasses.replace(
plan,
spec=cast(BottleSpec, SimpleNamespace(image_policy="cached")),
)
from bot_bottle.log import Die
def image_exists(ref: str) -> bool:
return False # Nothing cached.
with patch.object(
launch, "read_committed_image", return_value="",
), patch.object(
launch.container_mod, "image_exists", side_effect=image_exists,
), patch.object(
launch, "die", side_effect=Die("no agent image"),
):
with self.assertRaises(Die):
launch._build_images(plan)
def test_cached_mode_dies_when_sidecar_image_missing(self):
plan = _build_plan(self.stage_dir)
from bot_bottle.backend import BottleSpec
import dataclasses
plan = dataclasses.replace(
plan,
spec=cast(BottleSpec, SimpleNamespace(image_policy="cached")),
)
from bot_bottle.log import Die
def image_exists(ref: str) -> bool:
# Agent image is present; sidecar is missing.
return ref == plan.image
with patch.object(
launch, "read_committed_image", return_value="",
), patch.object(
launch.container_mod, "image_exists", side_effect=image_exists,
), patch.object(
launch, "die", side_effect=Die("no sidecar image"),
):
with self.assertRaises(Die):
launch._build_images(plan)
def test_cached_mode_both_present_returns_unchanged_plan(self):
plan = _build_plan(self.stage_dir)
from bot_bottle.backend import BottleSpec
import dataclasses
plan = dataclasses.replace(
plan,
spec=cast(BottleSpec, SimpleNamespace(image_policy="cached")),
)
with patch.object(
launch, "read_committed_image", return_value="",
), patch.object(
launch.container_mod, "image_exists", return_value=True,
), patch.object(
launch.container_mod, "build_image",
) as build, patch.object(launch, "info"):
result = launch._build_images(plan)
build.assert_not_called()
self.assertEqual(plan.image, result.image)
def test_committed_image_plus_cached_skips_sidecar_build(self):
plan = _build_plan(self.stage_dir)
from bot_bottle.backend import BottleSpec
import dataclasses
plan = dataclasses.replace(
plan,
spec=cast(BottleSpec, SimpleNamespace(image_policy="cached")),
)
with patch.object(
launch, "read_committed_image",
return_value="bot-bottle-committed-dev-abc:latest",
), patch.object(
launch.container_mod, "image_exists", return_value=True,
), patch.object(
launch.container_mod, "build_image",
) as build, patch.object(launch, "info"):
result = launch._build_images(plan)
# In cached mode with a committed image, no builds should fire.
build.assert_not_called()
self.assertEqual("bot-bottle-committed-dev-abc:latest", result.image)
if __name__ == "__main__":
unittest.main()