187 lines
7.2 KiB
Python
187 lines
7.2 KiB
Python
"""`main.py sandbox check` 探测函数单元测试。
|
|
|
|
mock subprocess,验:
|
|
- daemon 不可达 / image 缺 / network 缺 / uid 错配的各种分支
|
|
- detect_fs_quota 对 xfs/ext4/zfs/btrfs/其他 + prjquota mount option 的判断
|
|
- 汇总 exit code:全 ok / 仅 warn / 有 err
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import sys
|
|
import unittest
|
|
from pathlib import Path
|
|
from unittest.mock import patch
|
|
|
|
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
|
|
|
|
from core.sandbox.check import (
|
|
check_docker_daemon,
|
|
check_image_present,
|
|
check_host_uid_alignment,
|
|
detect_fs_quota,
|
|
run_sandbox_check,
|
|
)
|
|
|
|
|
|
def _mk_run(returns):
|
|
"""构造 `_run` 替身:按调用次序返 (rc, stdout, stderr) 列表里的元素。"""
|
|
iter_ret = iter(returns)
|
|
|
|
def fake_run(argv, timeout=10):
|
|
return next(iter_ret)
|
|
return fake_run
|
|
|
|
|
|
class TestDaemonCheck(unittest.TestCase):
|
|
def test_daemon_ok(self):
|
|
with patch("core.sandbox.check._run", _mk_run([(0, "24.0.7", "")])):
|
|
self.assertTrue(check_docker_daemon())
|
|
|
|
def test_daemon_cli_missing(self):
|
|
with patch("core.sandbox.check._run", _mk_run([(127, "", "docker not found in PATH")])):
|
|
self.assertFalse(check_docker_daemon())
|
|
|
|
def test_daemon_permission_denied(self):
|
|
with patch(
|
|
"core.sandbox.check._run",
|
|
_mk_run([(1, "", "Got permission denied while trying to connect")]),
|
|
):
|
|
self.assertFalse(check_docker_daemon())
|
|
|
|
|
|
class TestImageCheck(unittest.TestCase):
|
|
def test_image_present(self):
|
|
with patch("core.sandbox.check._run", _mk_run([(0, "[...]", "")])):
|
|
self.assertTrue(check_image_present())
|
|
|
|
def test_image_missing(self):
|
|
with patch("core.sandbox.check._run", _mk_run([(1, "", "No such image")])):
|
|
self.assertFalse(check_image_present())
|
|
|
|
|
|
class TestHostUidAlignment(unittest.TestCase):
|
|
def test_uid_aligned(self):
|
|
if sys.platform == "win32":
|
|
self.skipTest("getuid not on Windows")
|
|
import os
|
|
host_uid = os.getuid() # type: ignore[attr-defined]
|
|
with patch(
|
|
"core.sandbox.check._run",
|
|
_mk_run([(0, str(host_uid), "")]),
|
|
):
|
|
self.assertTrue(check_host_uid_alignment())
|
|
|
|
def test_uid_mismatch(self):
|
|
if sys.platform == "win32":
|
|
self.skipTest("getuid not on Windows")
|
|
import os
|
|
bad = os.getuid() + 1 # type: ignore[attr-defined]
|
|
with patch("core.sandbox.check._run", _mk_run([(0, str(bad), "")])):
|
|
self.assertFalse(check_host_uid_alignment())
|
|
|
|
def test_image_not_built_yet(self):
|
|
# docker run 失败 → warn 不 err
|
|
with patch(
|
|
"core.sandbox.check._run",
|
|
_mk_run([(125, "", "Unable to find image")]),
|
|
):
|
|
self.assertTrue(check_host_uid_alignment())
|
|
|
|
def test_skipped_on_windows(self):
|
|
with patch("core.sandbox.check.sys") as mock_sys, \
|
|
patch("core.sandbox.check._run", _mk_run([(0, "1000", "")])):
|
|
mock_sys.platform = "win32"
|
|
self.assertTrue(check_host_uid_alignment())
|
|
|
|
|
|
class TestDetectFsQuota(unittest.TestCase):
|
|
"""detect_fs_quota:不依赖 print,纯返 (level, msg) 便于断言。"""
|
|
|
|
def test_xfs_with_prjquota(self):
|
|
with patch("core.sandbox.check._run", _mk_run([(0, "xfs rw,relatime,prjquota,attr2", "")])), \
|
|
patch("core.sandbox.check.sys") as mock_sys:
|
|
mock_sys.platform = "linux"
|
|
level, msg = detect_fs_quota(Path("/opt/zcbot/workspace/users"))
|
|
self.assertEqual(level, "ok")
|
|
self.assertIn("xfs with prjquota", msg)
|
|
|
|
def test_xfs_without_prjquota(self):
|
|
with patch("core.sandbox.check._run", _mk_run([(0, "xfs rw,relatime,attr2", "")])), \
|
|
patch("core.sandbox.check.sys") as mock_sys:
|
|
mock_sys.platform = "linux"
|
|
level, msg = detect_fs_quota(Path("/opt"))
|
|
self.assertEqual(level, "warn")
|
|
self.assertIn("NO prjquota", msg)
|
|
|
|
def test_ext4_with_project_quota(self):
|
|
with patch("core.sandbox.check._run", _mk_run([(0, "ext4 rw,prjquota", "")])), \
|
|
patch("core.sandbox.check.sys") as mock_sys:
|
|
mock_sys.platform = "linux"
|
|
level, msg = detect_fs_quota(Path("/opt"))
|
|
self.assertEqual(level, "ok")
|
|
self.assertIn("ext4 with project quota", msg)
|
|
|
|
def test_zfs(self):
|
|
with patch("core.sandbox.check._run", _mk_run([(0, "zfs rw,xattr,noacl", "")])), \
|
|
patch("core.sandbox.check.sys") as mock_sys:
|
|
mock_sys.platform = "linux"
|
|
level, msg = detect_fs_quota(Path("/tank/zcbot"))
|
|
self.assertEqual(level, "ok")
|
|
self.assertIn("zfs", msg)
|
|
|
|
def test_btrfs_warns(self):
|
|
with patch("core.sandbox.check._run", _mk_run([(0, "btrfs rw,relatime", "")])), \
|
|
patch("core.sandbox.check.sys") as mock_sys:
|
|
mock_sys.platform = "linux"
|
|
level, msg = detect_fs_quota(Path("/opt"))
|
|
self.assertEqual(level, "warn")
|
|
self.assertIn("btrfs", msg)
|
|
|
|
def test_tmpfs_warns(self):
|
|
with patch("core.sandbox.check._run", _mk_run([(0, "tmpfs rw", "")])), \
|
|
patch("core.sandbox.check.sys") as mock_sys:
|
|
mock_sys.platform = "linux"
|
|
level, msg = detect_fs_quota(Path("/tmp"))
|
|
self.assertEqual(level, "warn")
|
|
|
|
def test_findmnt_missing(self):
|
|
with patch("core.sandbox.check._run", _mk_run([(127, "", "findmnt not found in PATH")])), \
|
|
patch("core.sandbox.check.sys") as mock_sys:
|
|
mock_sys.platform = "linux"
|
|
level, msg = detect_fs_quota(Path("/opt"))
|
|
self.assertEqual(level, "warn")
|
|
self.assertIn("findmnt", msg)
|
|
|
|
def test_windows_skipped(self):
|
|
with patch("core.sandbox.check.sys") as mock_sys:
|
|
mock_sys.platform = "win32"
|
|
level, msg = detect_fs_quota(Path("C:/"))
|
|
self.assertEqual(level, "warn")
|
|
self.assertIn("Windows", msg)
|
|
|
|
|
|
class TestSummaryExitCode(unittest.TestCase):
|
|
"""run_sandbox_check 汇总:err → exit 1,全 ok / 仅 warn → exit 0。"""
|
|
|
|
def test_all_ok_exits_zero(self):
|
|
with patch("core.sandbox.check.check_docker_daemon", return_value=True), \
|
|
patch("core.sandbox.check.check_image_present", return_value=True), \
|
|
patch("core.sandbox.check.check_network_present", return_value=True), \
|
|
patch("core.sandbox.check.check_host_uid_alignment", return_value=True), \
|
|
patch("core.sandbox.check.check_fs_quota_capable", return_value=True):
|
|
rc = run_sandbox_check()
|
|
self.assertEqual(rc, 0)
|
|
|
|
def test_any_err_exits_one(self):
|
|
with patch("core.sandbox.check.check_docker_daemon", return_value=False), \
|
|
patch("core.sandbox.check.check_image_present", return_value=True), \
|
|
patch("core.sandbox.check.check_network_present", return_value=True), \
|
|
patch("core.sandbox.check.check_host_uid_alignment", return_value=True), \
|
|
patch("core.sandbox.check.check_fs_quota_capable", return_value=True):
|
|
rc = run_sandbox_check()
|
|
self.assertEqual(rc, 1)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|