kunit: tool: skip stty when stdin is not a tty
run_kernel() cleanup and signal_handler() invoke stty unconditionally. When stdin is not a tty (for example in CI or unit tests), this writes noise to stderr. Call stty only when stdin is a tty. Add regression tests for these paths: - run_kernel() with non-tty stdin - signal_handler() with non-tty stdin - signal_handler() with tty stdin Signed-off-by: Shuvam Pandey <shuvampandey1@gmail.com> Reviewed-by: David Gow <david@davidgow.net> Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>master
parent
b73f50ffd4
commit
e42c349f4c
|
|
@ -345,6 +345,12 @@ class LinuxSourceTree:
|
|||
return False
|
||||
return self.validate_config(build_dir)
|
||||
|
||||
def _restore_terminal_if_tty(self) -> None:
|
||||
# stty requires a controlling terminal; skip headless runs.
|
||||
if sys.stdin is None or not sys.stdin.isatty():
|
||||
return
|
||||
subprocess.call(['stty', 'sane'])
|
||||
|
||||
def run_kernel(self, args: Optional[List[str]]=None, build_dir: str='', filter_glob: str='', filter: str='', filter_action: Optional[str]=None, timeout: Optional[int]=None) -> Iterator[str]:
|
||||
# Copy to avoid mutating the caller-supplied list. exec_tests() reuses
|
||||
# the same args across repeated run_kernel() calls (e.g. --run_isolated),
|
||||
|
|
@ -386,8 +392,8 @@ class LinuxSourceTree:
|
|||
process.stdout.close()
|
||||
|
||||
waiter.join()
|
||||
subprocess.call(['stty', 'sane'])
|
||||
self._restore_terminal_if_tty()
|
||||
|
||||
def signal_handler(self, unused_sig: int, unused_frame: Optional[FrameType]) -> None:
|
||||
logging.error('Build interruption occurred. Cleaning console.')
|
||||
subprocess.call(['stty', 'sane'])
|
||||
self._restore_terminal_if_tty()
|
||||
|
|
|
|||
|
|
@ -529,6 +529,48 @@ class LinuxSourceTreeTest(unittest.TestCase):
|
|||
self.assertIn('kunit.filter_glob=suite.test1', start_calls[0])
|
||||
self.assertIn('kunit.filter_glob=suite.test2', start_calls[1])
|
||||
|
||||
def test_run_kernel_skips_terminal_reset_without_tty(self):
|
||||
def fake_start(unused_args, unused_build_dir):
|
||||
return subprocess.Popen(['printf', 'KTAP version 1\n'],
|
||||
text=True, stdout=subprocess.PIPE)
|
||||
|
||||
non_tty_stdin = mock.Mock()
|
||||
non_tty_stdin.isatty.return_value = False
|
||||
|
||||
with tempfile.TemporaryDirectory('') as build_dir:
|
||||
tree = kunit_kernel.LinuxSourceTree(build_dir, kunitconfig_paths=[os.devnull])
|
||||
with mock.patch.object(tree._ops, 'start', side_effect=fake_start), \
|
||||
mock.patch.object(kunit_kernel.sys, 'stdin', non_tty_stdin), \
|
||||
mock.patch.object(kunit_kernel.subprocess, 'call') as mock_call:
|
||||
for _ in tree.run_kernel(build_dir=build_dir):
|
||||
pass
|
||||
|
||||
mock_call.assert_not_called()
|
||||
|
||||
def test_signal_handler_skips_terminal_reset_without_tty(self):
|
||||
non_tty_stdin = mock.Mock()
|
||||
non_tty_stdin.isatty.return_value = False
|
||||
tree = kunit_kernel.LinuxSourceTree('', kunitconfig_paths=[os.devnull])
|
||||
|
||||
with mock.patch.object(kunit_kernel.sys, 'stdin', non_tty_stdin), \
|
||||
mock.patch.object(kunit_kernel.subprocess, 'call') as mock_call, \
|
||||
mock.patch.object(kunit_kernel.logging, 'error') as mock_error:
|
||||
tree.signal_handler(signal.SIGINT, None)
|
||||
mock_error.assert_called_once()
|
||||
mock_call.assert_not_called()
|
||||
|
||||
def test_signal_handler_resets_terminal_with_tty(self):
|
||||
tty_stdin = mock.Mock()
|
||||
tty_stdin.isatty.return_value = True
|
||||
tree = kunit_kernel.LinuxSourceTree('', kunitconfig_paths=[os.devnull])
|
||||
|
||||
with mock.patch.object(kunit_kernel.sys, 'stdin', tty_stdin), \
|
||||
mock.patch.object(kunit_kernel.subprocess, 'call') as mock_call, \
|
||||
mock.patch.object(kunit_kernel.logging, 'error') as mock_error:
|
||||
tree.signal_handler(signal.SIGINT, None)
|
||||
mock_error.assert_called_once()
|
||||
mock_call.assert_called_once_with(['stty', 'sane'])
|
||||
|
||||
def test_build_reconfig_no_config(self):
|
||||
with tempfile.TemporaryDirectory('') as build_dir:
|
||||
with open(kunit_kernel.get_kunitconfig_path(build_dir), 'w') as f:
|
||||
|
|
|
|||
Loading…
Reference in New Issue