From b0f0812b406608e0fb5151987667b936d46b7196 Mon Sep 17 00:00:00 2001 From: Sebastian Cao Date: Sat, 1 Aug 2026 19:30:14 +0800 Subject: [PATCH] Do not run the shutdown command in debug mode --- app/local_system.py | 12 ++++++++++ app/local_system_test.py | 51 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 app/local_system_test.py diff --git a/app/local_system.py b/app/local_system.py index f2bf27d6e..87f51afd5 100644 --- a/app/local_system.py +++ b/app/local_system.py @@ -1,6 +1,8 @@ import logging import subprocess +import flask + logger = logging.getLogger(__name__) @@ -22,7 +24,17 @@ def restart(): return _exec_shutdown(restart_after=True) +def _is_debug(): + return flask.current_app.debug + + def _exec_shutdown(restart_after): + # In debug mode, don't actually shut down or restart the system, as that + # would be disruptive to a developer running the app locally. + if _is_debug(): + logger.info('Skipping system shutdown because app is in debug mode') + return True + if restart_after: param = '--reboot' else: diff --git a/app/local_system_test.py b/app/local_system_test.py new file mode 100644 index 000000000..31bc9b0e2 --- /dev/null +++ b/app/local_system_test.py @@ -0,0 +1,51 @@ +import subprocess +import unittest +from unittest import mock + +import local_system + + +class ExecShutdownTest(unittest.TestCase): + + def setUp(self): + # Run all unit tests with debug mode disabled. + is_debug_patch = mock.patch.object(local_system, + '_is_debug', + return_value=False) + self.addCleanup(is_debug_patch.stop) + is_debug_patch.start() + + @mock.patch.object(subprocess, 'run') + def test_shutdown_runs_poweroff_command(self, mock_run): + mock_run.return_value = subprocess.CompletedProcess(args=[], + returncode=0, + stdout='', + stderr='') + self.assertTrue(local_system.shutdown()) + mock_run.assert_called_once() + self.assertIn('--poweroff', mock_run.call_args[0][0]) + + @mock.patch.object(subprocess, 'run') + def test_restart_runs_reboot_command(self, mock_run): + mock_run.return_value = subprocess.CompletedProcess(args=[], + returncode=0, + stdout='', + stderr='') + self.assertTrue(local_system.restart()) + mock_run.assert_called_once() + self.assertIn('--reboot', mock_run.call_args[0][0]) + + +class DebugModeTest(unittest.TestCase): + + @mock.patch.object(subprocess, 'run') + def test_shutdown_does_not_run_command_in_debug_mode(self, mock_run): + with mock.patch.object(local_system, '_is_debug', return_value=True): + self.assertTrue(local_system.shutdown()) + mock_run.assert_not_called() + + @mock.patch.object(subprocess, 'run') + def test_restart_does_not_run_command_in_debug_mode(self, mock_run): + with mock.patch.object(local_system, '_is_debug', return_value=True): + self.assertTrue(local_system.restart()) + mock_run.assert_not_called()