mirror of
https://github.com/MacRimi/ProxMenux.git
synced 2026-11-02 10:52:22 +00:00
test(oci): isolate cleanup and recovery fixtures from the host
This commit is contained in:
@@ -75,6 +75,9 @@ class InventoryMessages(unittest.TestCase):
|
|||||||
self.assertNotIn('Host directories that are kept, with their content:', text)
|
self.assertNotIn('Host directories that are kept, with their content:', text)
|
||||||
|
|
||||||
def test_removal_notice_qualifies_saved_record_source(self):
|
def test_removal_notice_qualifies_saved_record_source(self):
|
||||||
|
# Extracted operational functions must never inspect the real pmxcfs.
|
||||||
|
host = Path(self.enterContext(tempfile.TemporaryDirectory()))
|
||||||
|
inert_path = lambda value: host / Path(value).name if str(value).startswith('/etc/pve/') else Path(value)
|
||||||
events = []
|
events = []
|
||||||
scope = {'members_of': lambda root, vmid: (101, {}, [101]),
|
scope = {'members_of': lambda root, vmid: (101, {}, [101]),
|
||||||
'instances': SimpleNamespace(read=lambda root, vmid: {'installation_id': 'owned'},
|
'instances': SimpleNamespace(read=lambda root, vmid: {'installation_id': 'owned'},
|
||||||
@@ -85,7 +88,7 @@ class InventoryMessages(unittest.TestCase):
|
|||||||
'remove_owned_host_firewall': lambda primary: True,
|
'remove_owned_host_firewall': lambda primary: True,
|
||||||
'run': lambda *args: events.append(('run', args)),
|
'run': lambda *args: events.append(('run', args)),
|
||||||
'subprocess': SimpleNamespace(run=lambda *args, **kwargs: None),
|
'subprocess': SimpleNamespace(run=lambda *args, **kwargs: None),
|
||||||
'Path': Path, 'shutil': SimpleNamespace(rmtree=lambda path: None),
|
'Path': inert_path, 'shutil': SimpleNamespace(rmtree=lambda path: None),
|
||||||
'image_cache': SimpleNamespace(prune=lambda root, lock: []),
|
'image_cache': SimpleNamespace(prune=lambda root, lock: []),
|
||||||
'work_backup': SimpleNamespace(forget=lambda root, vmid: None),
|
'work_backup': SimpleNamespace(forget=lambda root, vmid: None),
|
||||||
'oci_console': SimpleNamespace(remove_log=lambda vmid: events.append(('log', vmid))),
|
'oci_console': SimpleNamespace(remove_log=lambda vmid: events.append(('log', vmid))),
|
||||||
|
|||||||
@@ -33,7 +33,8 @@ class BackupCarriedRecordTests(unittest.TestCase):
|
|||||||
code = self.unmount_code if args[1]=='unmount' else 0
|
code = self.unmount_code if args[1]=='unmount' else 0
|
||||||
return SimpleNamespace(returncode=code, stdout=value)
|
return SimpleNamespace(returncode=code, stdout=value)
|
||||||
for name, value in [('_run',run),('_host_directory_missing',lambda _:False),
|
for name, value in [('_run',run),('_host_directory_missing',lambda _:False),
|
||||||
('ROOTFS',self.rootfs_base),('mapped_root',lambda _: (os.getuid(),os.getgid()))]:
|
('ROOTFS',self.rootfs_base),('STACK_CONTRACT',str(Path(temporary.name)/'stack-{}.json')),
|
||||||
|
('mapped_root',lambda _: (os.getuid(),os.getgid()))]:
|
||||||
context=patch.object(carried,name,value);context.start();self.addCleanup(context.stop)
|
context=patch.object(carried,name,value);context.start();self.addCleanup(context.stop)
|
||||||
|
|
||||||
def carry(self, original=None):
|
def carry(self, original=None):
|
||||||
|
|||||||
@@ -19,6 +19,9 @@ class CarriedConfigCacheTests(unittest.TestCase):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.tmp = tempfile.TemporaryDirectory()
|
self.tmp = tempfile.TemporaryDirectory()
|
||||||
self.addCleanup(self.tmp.cleanup)
|
self.addCleanup(self.tmp.cleanup)
|
||||||
|
contract = patch.object(carried, 'STACK_CONTRACT', str(Path(self.tmp.name) / 'stack-{}.json'))
|
||||||
|
contract.start()
|
||||||
|
self.addCleanup(contract.stop)
|
||||||
self.root = Path(self.tmp.name) / 'instances'
|
self.root = Path(self.tmp.name) / 'instances'
|
||||||
self.source = Path(self.tmp.name) / 'lxc'
|
self.source = Path(self.tmp.name) / 'lxc'
|
||||||
self.source.mkdir()
|
self.source.mkdir()
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
"""A migrated container finds what it needs on any node of a cluster."""
|
"""A migrated container finds what it needs on any node of a cluster."""
|
||||||
|
|
||||||
|
import os
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
@@ -50,6 +51,7 @@ class SysctlIncludeTests(unittest.TestCase):
|
|||||||
def config(self, include):
|
def config(self, include):
|
||||||
return f"arch: amd64\nlxc.include: {include}\n".encode()
|
return f"arch: amd64\nlxc.include: {include}\n".encode()
|
||||||
|
|
||||||
|
@unittest.skipUnless(os.geteuid() == 0, "the sysctl include must belong to root")
|
||||||
def test_cluster_path_and_the_path_of_earlier_installs_are_accepted(self):
|
def test_cluster_path_and_the_path_of_earlier_installs_are_accepted(self):
|
||||||
runtime_settings.check(self.config(self.new), DEPLOYMENT, 101)
|
runtime_settings.check(self.config(self.new), DEPLOYMENT, 101)
|
||||||
runtime_settings.check(self.config(self.old), DEPLOYMENT, 101)
|
runtime_settings.check(self.config(self.old), DEPLOYMENT, 101)
|
||||||
@@ -58,6 +60,7 @@ class SysctlIncludeTests(unittest.TestCase):
|
|||||||
with self.assertRaises(ValueError):
|
with self.assertRaises(ValueError):
|
||||||
runtime_settings.check(self.config(self.root / "elsewhere"), DEPLOYMENT, 101)
|
runtime_settings.check(self.config(self.root / "elsewhere"), DEPLOYMENT, 101)
|
||||||
|
|
||||||
|
@unittest.skipUnless(os.geteuid() == 0, "the sysctl include must belong to root")
|
||||||
def test_recovery_accepts_both_paths_only(self):
|
def test_recovery_accepts_both_paths_only(self):
|
||||||
state = {"vmid": 101, "record": {"deployment": DEPLOYMENT}}
|
state = {"vmid": 101, "record": {"deployment": DEPLOYMENT}}
|
||||||
runtime_settings.check_recovery(self.config(self.new), state)
|
runtime_settings.check_recovery(self.config(self.new), state)
|
||||||
|
|||||||
@@ -45,6 +45,8 @@ class RemovalCleanupTests(unittest.TestCase):
|
|||||||
patch.object(oci_remove, "MONITOR_APPS", self.apps),
|
patch.object(oci_remove, "MONITOR_APPS", self.apps),
|
||||||
patch.object(oci_remove, "CLUSTER_RECORDS", self.records),
|
patch.object(oci_remove, "CLUSTER_RECORDS", self.records),
|
||||||
patch.object(oci_remove, "HOST_MONITOR_INCLUDES", self.host_monitor),
|
patch.object(oci_remove, "HOST_MONITOR_INCLUDES", self.host_monitor),
|
||||||
|
patch.object(oci_remove.public_routes, "DIRECTORY", self.root / "public-routes"),
|
||||||
|
patch.object(runtime_settings, "seccomp_path", lambda vmid: self.cluster / f"{vmid}.proxmenux-seccomp"),
|
||||||
patch.object(runtime_settings, "include_path", lambda vmid: self.cluster / f"{vmid}.sysctls"),
|
patch.object(runtime_settings, "include_path", lambda vmid: self.cluster / f"{vmid}.sysctls"),
|
||||||
patch.object(runtime_settings, "legacy_include_path", lambda vmid: self.legacy / f"{vmid}.proxmenux-sysctls"),
|
patch.object(runtime_settings, "legacy_include_path", lambda vmid: self.legacy / f"{vmid}.proxmenux-sysctls"),
|
||||||
patch.object(oci_remove.subprocess, "run"),
|
patch.object(oci_remove.subprocess, "run"),
|
||||||
|
|||||||
@@ -118,7 +118,14 @@ class ManagedRouteLifecycleTests(unittest.TestCase):
|
|||||||
root=Path(folder)/'records';root.mkdir()
|
root=Path(folder)/'records';root.mkdir()
|
||||||
routes.install(deployment(),4901,WORKER)
|
routes.install(deployment(),4901,WORKER)
|
||||||
if case=='changed':routes.include_path(4901).write_text('foreign hook')
|
if case=='changed':routes.include_path(4901).write_text('foreign hook')
|
||||||
with patch.object(removal.instances,'guest_exists',return_value=case=='reused'), \
|
with patch.multiple(removal,CLUSTER_NODES=Path(folder)/'nodes',
|
||||||
|
SNIPPETS=Path(folder)/'snippets',MONITOR_APPS=Path(folder)/'apps',
|
||||||
|
CLUSTER_RECORDS=Path(folder)/'cluster-records'), \
|
||||||
|
patch.object(removal.runtime_settings,'include_path',lambda vmid:Path(folder)/f'{vmid}.sysctls'), \
|
||||||
|
patch.object(removal.runtime_settings,'legacy_include_path',lambda vmid:Path(folder)/f'{vmid}.legacy'), \
|
||||||
|
patch.object(removal.runtime_settings,'seccomp_path',lambda vmid:Path(folder)/f'{vmid}.seccomp'), \
|
||||||
|
patch.object(removal.oci_console,'LOG_DIR',Path(folder)/'logs'), \
|
||||||
|
patch.object(removal.instances,'guest_exists',return_value=case=='reused'), \
|
||||||
patch.object(removal.instances,'has_contract',return_value=case=='pending'), \
|
patch.object(removal.instances,'has_contract',return_value=case=='pending'), \
|
||||||
patch.object(removal.instances,'read',return_value={'installation_id':WORKER}), \
|
patch.object(removal.instances,'read',return_value={'installation_id':WORKER}), \
|
||||||
patch.object(removal.instances,'release_orphan',return_value=False), \
|
patch.object(removal.instances,'release_orphan',return_value=False), \
|
||||||
|
|||||||
Reference in New Issue
Block a user