fix(deploy): reconcile device plane foundation
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
#!/usr/bin/env python3
|
||||
import importlib.machinery
|
||||
import importlib.util
|
||||
import json
|
||||
import tempfile
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
@@ -207,6 +208,15 @@ class DevicePlaneRegistryTest(unittest.TestCase):
|
||||
"\n".join(entries) + "\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
(backup / "runtime-before.json").write_text(
|
||||
json.dumps({
|
||||
"schemaVersion":
|
||||
"nodedc.device-plane.runtime-inventory.v1",
|
||||
"composeProject": "nodedc-device-plane",
|
||||
"services": [],
|
||||
}),
|
||||
encoding="utf-8",
|
||||
)
|
||||
with (
|
||||
mock.patch.object(
|
||||
RUNNER,
|
||||
@@ -234,6 +244,165 @@ class DevicePlaneRegistryTest(unittest.TestCase):
|
||||
restore.assert_called_once()
|
||||
self.assertEqual(result, "source-restored-runtime-unchanged:3")
|
||||
|
||||
def test_db_bootstrap_compose_does_not_invent_stateless_baseline(self):
|
||||
entries = (
|
||||
"docker-compose.device-plane.yml",
|
||||
"services/device-control-core",
|
||||
"services/device-gateway",
|
||||
)
|
||||
with tempfile.TemporaryDirectory(
|
||||
prefix="nodedc-device-plane-compose-predecessor-",
|
||||
) as directory:
|
||||
root = Path(directory) / "live"
|
||||
backup = Path(directory) / "backup"
|
||||
root.mkdir()
|
||||
backup.mkdir()
|
||||
(backup / "existing-files.txt").write_text(
|
||||
"docker-compose.device-plane.yml\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
(backup / "missing-files.txt").write_text(
|
||||
"services/device-control-core\n"
|
||||
"services/device-gateway\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
(backup / "runtime-before.json").write_text(
|
||||
json.dumps({
|
||||
"schemaVersion":
|
||||
"nodedc.device-plane.runtime-inventory.v1",
|
||||
"composeProject": "nodedc-device-plane",
|
||||
"services": [{
|
||||
"service": "device-postgres",
|
||||
"containerId": "a" * 64,
|
||||
"imageId": "sha256:" + "b" * 64,
|
||||
"status": "running",
|
||||
"running": True,
|
||||
"health": "healthy",
|
||||
"restartCount": 0,
|
||||
}],
|
||||
}),
|
||||
encoding="utf-8",
|
||||
)
|
||||
with (
|
||||
mock.patch.object(
|
||||
RUNNER,
|
||||
"stop_and_remove_compose_services",
|
||||
) as stop,
|
||||
mock.patch.object(
|
||||
RUNNER,
|
||||
"restore_platform_overlay",
|
||||
return_value=3,
|
||||
),
|
||||
mock.patch.object(
|
||||
RUNNER,
|
||||
"run_component_runtime",
|
||||
) as run_runtime,
|
||||
):
|
||||
result = RUNNER.rollback_device_plane_apply(
|
||||
root,
|
||||
backup,
|
||||
entries,
|
||||
"test-stamp",
|
||||
True,
|
||||
("device-control-core", "device-gateway"),
|
||||
)
|
||||
|
||||
stop.assert_called_once_with(
|
||||
"device-plane",
|
||||
("device-control-core", "device-gateway"),
|
||||
)
|
||||
run_runtime.assert_not_called()
|
||||
self.assertEqual(result, "source-restored-runtime-unchanged:3")
|
||||
|
||||
def test_installed_stateless_baseline_is_restored_from_runtime_inventory(
|
||||
self,
|
||||
):
|
||||
entries = (
|
||||
"docker-compose.device-plane.yml",
|
||||
"services/device-control-core",
|
||||
"services/device-gateway",
|
||||
)
|
||||
with tempfile.TemporaryDirectory(
|
||||
prefix="nodedc-device-plane-installed-predecessor-",
|
||||
) as directory:
|
||||
root = Path(directory) / "live"
|
||||
backup = Path(directory) / "backup"
|
||||
root.mkdir()
|
||||
backup.mkdir()
|
||||
(backup / "existing-files.txt").write_text(
|
||||
"\n".join(entries) + "\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
(backup / "missing-files.txt").write_text(
|
||||
"",
|
||||
encoding="utf-8",
|
||||
)
|
||||
(backup / "runtime-before.json").write_text(
|
||||
json.dumps({
|
||||
"schemaVersion":
|
||||
"nodedc.device-plane.runtime-inventory.v1",
|
||||
"composeProject": "nodedc-device-plane",
|
||||
"services": [
|
||||
{
|
||||
"service": "device-control-core",
|
||||
"containerId": "a" * 64,
|
||||
"imageId": "sha256:" + "b" * 64,
|
||||
"status": "running",
|
||||
"running": True,
|
||||
"health": "healthy",
|
||||
"restartCount": 0,
|
||||
},
|
||||
{
|
||||
"service": "device-gateway",
|
||||
"containerId": "c" * 64,
|
||||
"imageId": "sha256:" + "d" * 64,
|
||||
"status": "running",
|
||||
"running": True,
|
||||
"health": "healthy",
|
||||
"restartCount": 0,
|
||||
},
|
||||
],
|
||||
}),
|
||||
encoding="utf-8",
|
||||
)
|
||||
with (
|
||||
mock.patch.object(
|
||||
RUNNER,
|
||||
"stop_and_remove_compose_services",
|
||||
) as stop,
|
||||
mock.patch.object(
|
||||
RUNNER,
|
||||
"restore_platform_overlay",
|
||||
return_value=3,
|
||||
),
|
||||
mock.patch.object(
|
||||
RUNNER,
|
||||
"run_component_runtime",
|
||||
) as run_runtime,
|
||||
mock.patch.object(RUNNER, "run_healthchecks") as healthchecks,
|
||||
):
|
||||
result = RUNNER.rollback_device_plane_apply(
|
||||
root,
|
||||
backup,
|
||||
entries,
|
||||
"test-stamp",
|
||||
True,
|
||||
("device-control-core", "device-gateway"),
|
||||
)
|
||||
|
||||
stop.assert_not_called()
|
||||
run_runtime.assert_called_once_with(
|
||||
"device-plane",
|
||||
list(entries),
|
||||
("device-control-core", "device-gateway"),
|
||||
)
|
||||
healthchecks.assert_called_once_with(
|
||||
"device-plane",
|
||||
list(entries),
|
||||
("device-control-core", "device-gateway"),
|
||||
)
|
||||
self.assertEqual(result, "source+runtime-restored:3")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main(verbosity=2)
|
||||
|
||||
Reference in New Issue
Block a user