import json import tempfile import unittest from pathlib import Path from unittest import mock from scripts import local_server as server class LocalServerTests(unittest.TestCase): def test_environment_overrides_unsafe_inherited_values(self): with mock.patch.dict('os.environ', { 'MONITOR_BOOTSTRAP_SERVICES': 'true', 'MONITOR_SERVICE_MODE': 'embedded', 'MONITOR_ALLOWED_HOSTS': '*', 'MONITOR_HTTPS': 'true', 'IMAGEIO_FFMPEG_EXE': 'C:/unrelated/ffmpeg.exe', }): env = server.local_environment() self.assertEqual(env['MONITOR_BOOTSTRAP_SERVICES'], 'false') self.assertEqual(env['MONITOR_SERVICE_MODE'], 'disabled') self.assertEqual(env['MONITOR_ALLOWED_HOSTS'], '127.0.0.1,localhost') self.assertEqual(env['MONITOR_HTTPS'], 'false') self.assertEqual(env['MONITOR_TELEMETRY_ENDPOINT'], '') self.assertEqual(env['YOLO_OFFLINE'], 'true') self.assertEqual(env['YOLO_AUTOINSTALL'], 'false') self.assertEqual(env['CI'], 'true') self.assertTrue(Path(env['MONITOR_FFMPEG']).is_relative_to(server.ROOT / '.venv')) def test_only_exact_project_runserver_command_is_owned(self): proc = mock.Mock() args = [str(server.PYTHON), str(server.MANAGE), 'runserver', '127.0.0.1:10001', '--noreload'] proc.cmdline.return_value = args self.assertTrue(server.is_project_process(proc)) proc.cmdline.return_value = args[:3] + ['0.0.0.0:10001', '--noreload'] self.assertFalse(server.is_project_process(proc)) proc.cmdline.return_value = args[:1] + ['C:/another/manage.py'] + args[2:] self.assertFalse(server.is_project_process(proc)) def test_busy_port_does_not_launch_or_stop_anything(self): with mock.patch.object(server, 'recorded_process', return_value=None), \ mock.patch.object(server, 'port_open', return_value=True), \ mock.patch.object(server, 'discover_project_listener', return_value=None), \ mock.patch.object(server, 'backup') as backup, \ mock.patch.object(server.subprocess, 'Popen') as popen: with self.assertRaises(RuntimeError): server.start() backup.assert_not_called() popen.assert_not_called() def test_existing_owned_server_is_reused(self): with mock.patch.object(server, 'recorded_process', return_value=mock.Mock(pid=123)), \ mock.patch.object(server, 'port_open', return_value=True), \ mock.patch.object(server.subprocess, 'Popen') as popen: server.start() popen.assert_not_called() def test_pid_reuse_is_not_treated_as_owned(self): with tempfile.TemporaryDirectory() as temp: path = Path(temp) / 'pid.json' path.write_text(json.dumps({'pid': 123, 'create_time': 1, 'root': str(server.ROOT)})) proc = mock.Mock() proc.create_time.return_value = 2 with mock.patch.object(server, 'PID_FILE', path), \ mock.patch.object(server.psutil, 'Process', return_value=proc): self.assertIsNone(server.recorded_process()) proc.terminate.assert_not_called() def test_foreign_command_is_not_stopped(self): with tempfile.TemporaryDirectory() as temp: path = Path(temp) / 'pid.json' path.write_text(json.dumps({'pid': 123, 'create_time': 1, 'root': str(server.ROOT)})) proc = mock.Mock() proc.create_time.return_value = 1 proc.cmdline.return_value = ['C:/foreign/python.exe', 'other.py'] with mock.patch.object(server, 'PID_FILE', path), \ mock.patch.object(server.psutil, 'Process', return_value=proc): with self.assertRaises(RuntimeError): server.stop() proc.terminate.assert_not_called()