feat: add ProcessDock process and port manager
This commit is contained in:
85
tests/test_services.py
Normal file
85
tests/test_services.py
Normal file
@@ -0,0 +1,85 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
from processdock.services import (
|
||||
ProcessService,
|
||||
ProtectedProcessError,
|
||||
format_command,
|
||||
humanize_bytes,
|
||||
matches_process,
|
||||
)
|
||||
|
||||
|
||||
class FormattingTests(unittest.TestCase):
|
||||
def test_humanize_bytes(self) -> None:
|
||||
self.assertEqual(humanize_bytes(0), "0 B")
|
||||
self.assertEqual(humanize_bytes(1024), "1.0 KB")
|
||||
self.assertEqual(humanize_bytes(512 * 1024 * 1024), "512.0 MB")
|
||||
|
||||
def test_format_command_preserves_arguments(self) -> None:
|
||||
command = format_command(["python", "demo app.py", "--port", "8080"])
|
||||
self.assertIn("python", command)
|
||||
self.assertIn("demo app.py", command)
|
||||
self.assertIn("8080", command)
|
||||
|
||||
def test_searches_name_pid_port_path_and_command(self) -> None:
|
||||
process = {
|
||||
"pid": 9824,
|
||||
"name": "java.exe",
|
||||
"username": "wang",
|
||||
"exe": r"D:\jdk-17\bin\java.exe",
|
||||
"command": "java -jar demo.jar",
|
||||
"ports": [8080, 9000],
|
||||
}
|
||||
for query in ("JAVA", "9824", "8080", "jdk-17", "demo.jar", "wang"):
|
||||
with self.subTest(query=query):
|
||||
self.assertTrue(matches_process(process, query))
|
||||
self.assertFalse(matches_process(process, "nginx"))
|
||||
|
||||
|
||||
class LiveServiceTests(unittest.TestCase):
|
||||
def test_snapshot_contains_current_process_and_required_fields(self) -> None:
|
||||
snapshot = ProcessService().snapshot()
|
||||
current = next(item for item in snapshot["processes"] if item["pid"] == os.getpid())
|
||||
required = {
|
||||
"pid",
|
||||
"name",
|
||||
"ports",
|
||||
"cpu_percent",
|
||||
"memory_bytes",
|
||||
"username",
|
||||
"status_label",
|
||||
"exe",
|
||||
"command",
|
||||
"create_time_text",
|
||||
"ppid",
|
||||
}
|
||||
self.assertTrue(required.issubset(current))
|
||||
self.assertIn("process_count", snapshot["summary"])
|
||||
|
||||
def test_service_refuses_to_terminate_itself(self) -> None:
|
||||
service = ProcessService()
|
||||
with self.assertRaises(ProtectedProcessError):
|
||||
service.terminate(os.getpid(), force=True)
|
||||
|
||||
def test_force_terminates_owned_child_process(self) -> None:
|
||||
child = subprocess.Popen(
|
||||
[sys.executable, "-c", "import time; time.sleep(30)"],
|
||||
creationflags=getattr(subprocess, "CREATE_NO_WINDOW", 0),
|
||||
)
|
||||
try:
|
||||
result = ProcessService().terminate(child.pid, force=True)
|
||||
self.assertTrue(result.success)
|
||||
self.assertFalse(result.still_running)
|
||||
finally:
|
||||
if child.poll() is None:
|
||||
child.kill()
|
||||
child.wait()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user