google / gtest-parallel

Run Google Test suites in parallel.
Apache License 2.0
421 stars 104 forks source link

Add support for running tests in a pty #88

Closed tekknolagi closed 2 years ago

tekknolagi commented 2 years ago

Hi,

Some software behaves differently in a TTY vs not. gtest-parallel makes the tests think they are not running interactively. It would be neat to add a mode to spawn a pty for each test.

I have a patch that I wrote, but it is probably not in a place to be merged. When I run it, sometimes I have issues with my terminal after. I'm not sure if I need to change modes with the tty module or something.

Here is the patch for your consideration. Feel free to take it as-is or modify it to your needs or completely ignore it.

commit 35514e9cd340153fcba481d66b6d073da42fd64f (HEAD -> master)
Author: Max Bernstein <max@bernsteinbear.com>
Date:   Tue May 31 01:43:18 2022 -0700

    Add --pty option

    If --pty is given, run each test with a pty.

diff --git a/gtest_parallel.py b/gtest_parallel.py
index d682dbe..185d8c7 100755
--- a/gtest_parallel.py
+++ b/gtest_parallel.py
@@ -167,6 +167,11 @@ def get_save_file_path():
     return os.path.join(os.path.expanduser('~'), '.gtest-parallel-times')

+def with_pty(command):
+    return [sys.executable, '-c', 'import pty, sys; pty.spawn(sys.argv[1:])',
+            *command]
+
+
 @total_ordering
 class Task(object):
   """Stores information about a task (single execution of a test).
@@ -180,13 +185,17 @@ class Task(object):
   """

   def __init__(self, test_binary, test_name, test_command, execution_number,
-               last_execution_time, output_dir):
+               last_execution_time, output_dir, pty):
     self.test_name = test_name
     self.output_dir = output_dir
     self.test_binary = test_binary
-    self.test_command = test_command
+    if pty:
+        self.test_command = test_command
+    else:
+        self.test_command = with_pty(test_command)
     self.execution_number = execution_number
     self.last_execution_time = last_execution_time
+    self.pty = pty

     self.exit_code = None
     self.runtime_ms = None
@@ -643,7 +652,7 @@ def find_tests(binaries, additional_args, options, times):
         for execution_number in range(options.repeat):
           tasks.append(
               Task(test_binary, test_name, test_command, execution_number + 1,
-                   last_execution_time, options.output_dir))
+                   last_execution_time, options.output_dir, options.pty))

       test_count += 1

@@ -780,6 +789,10 @@ def default_options_parser():
                     default=False,
                     help='Do not run tests from the same test '
                     'case in parallel.')
+  parser.add_option('--pty',
+                    action='store_true',
+                    default=False,
+                    help='Give each test a pty.')
   return parser

Cheers, Max

pbos commented 2 years ago

Unless this turns out to be a massive problem I think I'd be inclined to have the solution to this be a pty wrapper live outside gtest-parallel (both script and repo) and you could invoke that like:

$ gtest-parallel pty_wrapper_for_my_binary_that_cares_about_pty

I'll close this for now but thank you for the patch.