Files
ProxMenux/.github/scripts/tests/test_log2ram_setup.py
T

126 lines
5.9 KiB
Python

"""Log2RAM keeps /var/log in RAM while the journal and the task logs of
Proxmox VE and Proxmox Backup Server stay on disk behind a link. An update keeps the size
and interval the host already has."""
import os
from pathlib import Path
import shutil
import subprocess
import tempfile
import unittest
ROOT = Path(__file__).resolve().parents[3]
KEEP = ROOT / "scripts/global/log2ram_keep_on_disk.sh"
SETUP = ROOT / "scripts/global/log2ram_setup.sh"
@unittest.skipUnless(shutil.which("bash"), "bash is needed")
class KeepOnDiskTests(unittest.TestCase):
def setUp(self):
folder = tempfile.TemporaryDirectory()
self.addCleanup(folder.cleanup)
self.root = Path(folder.name)
self.log = self.root / "var/log"
(self.log / "journal/abc").mkdir(parents=True)
(self.log / "journal/abc/system.journal").write_text("entries")
(self.log / "pveproxy").mkdir()
(self.log / "pveproxy/access.log").write_text("GET /")
def run_script(self, revert=False):
env = dict(os.environ, PMX_L2R_ROOT=str(self.root), PMX_L2R_REVERT="1" if revert else "0")
return subprocess.run(["bash", str(KEEP)], env=env, capture_output=True, text=True)
def test_the_journal_moves_to_disk_behind_a_link(self):
self.assertEqual(self.run_script().returncode, 0)
journal = self.log / "journal"
self.assertTrue(journal.is_symlink())
self.assertEqual(os.readlink(journal), "/var/hdd.journal")
self.assertEqual((self.root / "var/hdd.journal/abc/system.journal").read_text(), "entries")
self.assertTrue((self.log / "pveproxy/access.log").exists())
self.assertFalse((self.root / "var/hdd.proxmox-backup").exists())
def test_running_again_changes_nothing(self):
self.run_script()
self.assertEqual(self.run_script().returncode, 0)
self.assertEqual(os.readlink(self.log / "journal"), "/var/hdd.journal")
self.assertEqual(sorted(p.name for p in (self.root / "var/hdd.journal").iterdir()), ["abc"])
def test_the_task_logs_of_backup_server_stay_on_disk_too(self):
(self.log / "proxmox-backup/tasks").mkdir(parents=True)
(self.log / "proxmox-backup/tasks/active").write_text("task")
self.run_script()
self.assertEqual(os.readlink(self.log / "proxmox-backup"), "/var/hdd.proxmox-backup")
self.assertEqual((self.root / "var/hdd.proxmox-backup/tasks/active").read_text(), "task")
def test_files_written_back_to_the_folder_join_the_copy_on_disk(self):
self.run_script()
(self.log / "journal").unlink()
(self.log / "journal/def").mkdir(parents=True)
(self.log / "journal/def/system.journal").write_text("later")
self.run_script()
disk = self.root / "var/hdd.journal"
self.assertEqual(sorted(p.name for p in disk.iterdir()), ["abc", "def"])
self.assertTrue((self.log / "journal").is_symlink())
def test_a_host_without_a_journal_folder_gets_one_on_disk(self):
shutil.rmtree(self.log / "journal")
self.run_script()
self.assertTrue((self.root / "var/hdd.journal").is_dir())
self.assertTrue((self.log / "journal").is_symlink())
def test_the_task_logs_of_proxmox_ve_stay_on_disk(self):
(self.log / "pve/tasks").mkdir(parents=True)
(self.log / "pve/tasks/index").write_text("UPID")
self.run_script()
self.assertEqual(os.readlink(self.log / "pve"), "/var/hdd.pve")
self.assertEqual((self.root / "var/hdd.pve/tasks/index").read_text(), "UPID")
def test_removing_log2ram_puts_the_folders_back(self):
(self.log / "proxmox-backup").mkdir()
self.run_script()
self.assertEqual(self.run_script(revert=True).returncode, 0)
for name in ("journal", "proxmox-backup"):
self.assertFalse((self.log / name).is_symlink(), name)
self.assertTrue((self.log / name).is_dir(), name)
self.assertFalse((self.root / f"var/hdd.{name}").exists(), name)
self.assertEqual((self.log / "journal/abc/system.journal").read_text(), "entries")
@unittest.skipUnless(shutil.which("bash"), "bash is needed")
class KeptSettingsTests(unittest.TestCase):
def read(self, function, files):
with tempfile.TemporaryDirectory() as folder:
script = SETUP.read_text()
for path, content in files.items():
target = Path(folder) / path.lstrip("/")
target.parent.mkdir(parents=True, exist_ok=True)
target.write_text(content)
script = script.replace(path, str(target))
library = Path(folder) / "setup.sh"
library.write_text(script)
result = subprocess.run(["bash", "-c", f'source "{library}"; {function}'],
capture_output=True, text=True)
return result.stdout.strip()
def test_the_size_comes_from_the_installed_configuration(self):
self.assertEqual(self.read("pmx_log2ram_current_size", {"/etc/log2ram.conf": "SIZE=256M\n"}), "256")
def test_the_interval_comes_from_the_timer_of_this_version(self):
timer = "[Timer]\nOnCalendar=\nOnCalendar=*-*-* 00/6:55:00\n"
self.assertEqual(self.read("pmx_log2ram_current_hours",
{"/etc/systemd/system/log2ram-daily.timer.d/proxmenux.conf": timer}), "6")
def test_the_interval_of_an_earlier_version_is_kept(self):
cron = "MAILTO=\"\"\n0 */3 * * * root /usr/local/bin/log2ram write >/dev/null 2>&1\n"
self.assertEqual(self.read("pmx_log2ram_current_hours", {"/etc/cron.d/log2ram": cron}), "3")
def test_the_release_is_pinned_to_a_verified_commit(self):
text = SETUP.read_text()
self.assertIn('PMX_L2R_TAG="1.7.2"', text)
self.assertIn('PMX_L2R_COMMIT="f171449530f8984374c8f69fff3c92af813a694b"', text)
self.assertNotIn("install.sh", text.split("_pmx_log2ram_install_release() {", 1)[1].split("\n}\n", 1)[0])
if __name__ == "__main__":
unittest.main()