62 lines
2.7 KiB
Python
62 lines
2.7 KiB
Python
import unittest
|
|
|
|
from plan import build_plan
|
|
|
|
|
|
def observation():
|
|
return {
|
|
"name": "VacatureRadar", "containerId": "a" * 64,
|
|
"imageId": "sha256:" + "b" * 64, "running": True,
|
|
"health": "healthy", "composeProject": "vacatureradar",
|
|
"mounts": [
|
|
{"type": "bind", "source": "/mnt/pool/appdata/VacatureRadar/local",
|
|
"destination": "/app/local", "rw": True},
|
|
{"type": "bind", "source": "/mnt/pool/appdata/VacatureRadar/local/logs",
|
|
"destination": "/app/logs", "rw": True},
|
|
],
|
|
}
|
|
|
|
|
|
class PlanTests(unittest.TestCase):
|
|
def test_nested_mounts_share_one_cold_copy(self):
|
|
plan = build_plan("vacatureradar", "c" * 40, "migration-20260909", observation())
|
|
self.assertEqual(len(plan["coldCopyRoots"]), 1)
|
|
self.assertTrue(plan["candidateMounts"][1]["source"].endswith("/data/0/logs"))
|
|
self.assertFalse(plan["executable"])
|
|
self.assertIsNone(plan["originalRevision"])
|
|
self.assertEqual(plan["originalProvenance"], "unknown-legacy")
|
|
self.assertNotEqual(plan["candidateComposeProject"], "vacatureradar")
|
|
|
|
def test_rejects_runtime_drift_and_unsafe_paths(self):
|
|
for key, value in [("name", "other"), ("containerId", "short"),
|
|
("running", False), ("health", "starting")]:
|
|
observed = observation()
|
|
observed[key] = value
|
|
with self.subTest(key=key), self.assertRaises(ValueError):
|
|
build_plan("vacatureradar", "c" * 40, "migration-20260909", observed)
|
|
for source in ["/", "/mnt/pool/appdata", "/mnt/pool/appdata/VacatureRadar/../other"]:
|
|
observed = observation()
|
|
observed["mounts"][0]["source"] = source
|
|
with self.subTest(source=source), self.assertRaises(ValueError):
|
|
build_plan("vacatureradar", "c" * 40, "migration-20260909", observed)
|
|
|
|
def test_rejects_secret_bearing_full_inspect(self):
|
|
observed = observation()
|
|
observed["Config"] = {"Env": ["fixture-only"]}
|
|
with self.assertRaises(ValueError):
|
|
build_plan("vacatureradar", "c" * 40, "migration-20260909", observed)
|
|
|
|
def test_anonymous_volume_is_cloned_not_reused(self):
|
|
observed = observation()
|
|
observed.update(name="lumaops", composeProject="lumaops", mounts=[
|
|
{"type": "volume", "source": "/var/lib/docker/volumes/" + "d" * 64 + "/_data",
|
|
"destination": "/config", "rw": True},
|
|
])
|
|
plan = build_plan("lumaops", "c" * 40, "migration-20260909", observed)
|
|
self.assertEqual(plan["candidateMounts"][0]["type"], "bind")
|
|
self.assertNotIn("/var/lib/docker/volumes/", plan["candidateMounts"][0]["source"])
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|