[PATCH v2 1/5] tests/guest-debug: Make QEMU optional in run-test.py

Gustavo Romero posted 5 patches 1 day, 22 hours ago
Maintainers: Paolo Bonzini <pbonzini@redhat.com>, "Alex Bennée" <alex.bennee@linaro.org>, Thomas Huth <thuth@redhat.com>, "Marc-André Lureau" <marcandre.lureau@redhat.com>, "Daniel P. Berrangé" <berrange@redhat.com>, "Philippe Mathieu-Daudé" <philmd@linaro.org>, Zhao Liu <zhao1.liu@intel.com>
[PATCH v2 1/5] tests/guest-debug: Make QEMU optional in run-test.py
Posted by Gustavo Romero 1 day, 22 hours ago
This commit makes QEMU optional in run-test.py, allowing it to be used
as a GDB runner, i.e., to call GDB and pass a test script to it without
launching QEMU. In this configuration, it is the test script’s duty to
configure and run the VMs that GDB connects to.

sys.argv passed via -ex now includes the full path to the test script in
addition to the script’s arguments, which allows unittest introspection
to work properly in case it is used in the test script.

The --binary option continues to be required when --qemu is passed.

Signed-off-by: Gustavo Romero <gustavo.romero@linaro.org>
---
 tests/guest-debug/run-test.py | 60 +++++++++++++++++++----------------
 1 file changed, 33 insertions(+), 27 deletions(-)

diff --git a/tests/guest-debug/run-test.py b/tests/guest-debug/run-test.py
index 75e9c92e03..d21a5dda77 100755
--- a/tests/guest-debug/run-test.py
+++ b/tests/guest-debug/run-test.py
@@ -15,6 +15,7 @@
 import subprocess
 import shutil
 import shlex
+import sys
 import os
 from time import sleep
 from tempfile import TemporaryDirectory
@@ -22,10 +23,10 @@
 def get_args():
     parser = argparse.ArgumentParser(description="A gdbstub test runner")
     parser.add_argument("--qemu", help="Qemu binary for test",
-                        required=True)
+                        required=False)
     parser.add_argument("--qargs", help="Qemu arguments for test")
     parser.add_argument("--binary", help="Binary to debug",
-                        required=True)
+                        required='--qemu' in sys.argv)
     parser.add_argument("--test", help="GDB test script")
     parser.add_argument('test_args', nargs='*',
                         help="Additional args for GDB test script. "
@@ -73,27 +74,30 @@ def log(output, msg):
     socket_dir = TemporaryDirectory("qemu-gdbstub")
     socket_name = os.path.join(socket_dir.name, "gdbstub.socket")
 
-    # Launch QEMU with binary
-    if "system" in args.qemu:
-        if args.no_suspend:
-            suspend = ''
+    if args.qemu:
+        # Launch QEMU with binary.
+        if "system" in args.qemu:
+            if args.no_suspend:
+                suspend = ''
+            else:
+                suspend = ' -S'
+            cmd = f'{args.qemu} {args.qargs} {args.binary}' \
+                f'{suspend} -gdb unix:path={socket_name},server=on'
         else:
-            suspend = ' -S'
-        cmd = f'{args.qemu} {args.qargs} {args.binary}' \
-            f'{suspend} -gdb unix:path={socket_name},server=on'
-    else:
-        if args.no_suspend:
-            suspend = ',suspend=n'
-        else:
-            suspend = ''
-        cmd = f'{args.qemu} {args.qargs} -g {socket_name}{suspend}' \
-            f' {args.binary}'
+            if args.no_suspend:
+                suspend = ',suspend=n'
+            else:
+                suspend = ''
+            cmd = f'{args.qemu} {args.qargs} -g {socket_name}{suspend}' \
+                f' {args.binary}'
 
-    log(output, "QEMU CMD: %s" % (cmd))
-    inferior = subprocess.Popen(shlex.split(cmd))
+        log(output, "QEMU CMD: %s" % (cmd))
+        inferior = subprocess.Popen(shlex.split(cmd))
 
     # Now launch gdb with our test and collect the result
-    gdb_cmd = "%s %s" % (args.gdb, args.binary)
+    gdb_cmd = args.gdb
+    if args.binary:
+        gdb_cmd += " %s" % (args.binary)
     if args.gdb_args:
         gdb_cmd += " %s" % (args.gdb_args)
     # run quietly and ignore .gdbinit
@@ -103,11 +107,12 @@ def log(output, msg):
     # disable prompts in case of crash
     gdb_cmd += " -ex 'set confirm off'"
     # connect to remote
-    gdb_cmd += " -ex 'target remote %s'" % (socket_name)
+    if args.qemu:
+        gdb_cmd += " -ex 'target remote %s'" % (socket_name)
     # finally the test script itself
     if args.test:
-        if args.test_args:
-            gdb_cmd += f" -ex \"py sys.argv={args.test_args}\""
+        argv = [args.test] + args.test_args
+        gdb_cmd += f" -ex \"py sys.argv={argv}\""
         gdb_cmd += " -x %s" % (args.test)
 
 
@@ -129,10 +134,11 @@ def log(output, msg):
         log(output, "GDB crashed? (%d, %d) SKIPPING" % (result, result - 128))
         exit(0)
 
-    try:
-        inferior.wait(2)
-    except subprocess.TimeoutExpired:
-        log(output, "GDB never connected? Killed guest")
-        inferior.kill()
+    if args.qemu:
+        try:
+            inferior.wait(2)
+        except subprocess.TimeoutExpired:
+            log(output, "GDB never connected? Killed guest")
+            inferior.kill()
 
     exit(result)
-- 
2.34.1


Re: [PATCH v2 1/5] tests/guest-debug: Make QEMU optional in run-test.py
Posted by Alex Bennée 1 day, 7 hours ago
Gustavo Romero <gustavo.romero@linaro.org> writes:

> This commit makes QEMU optional in run-test.py, allowing it to be used
> as a GDB runner, i.e., to call GDB and pass a test script to it without
> launching QEMU. In this configuration, it is the test script’s duty to
> configure and run the VMs that GDB connects to.
>
> sys.argv passed via -ex now includes the full path to the test script in
> addition to the script’s arguments, which allows unittest introspection
> to work properly in case it is used in the test script.
>
> The --binary option continues to be required when --qemu is passed.
>
> Signed-off-by: Gustavo Romero <gustavo.romero@linaro.org>

Reviewed-by: Alex Bennée <alex.bennee@linaro.org>

> ---
>  tests/guest-debug/run-test.py | 60 +++++++++++++++++++----------------
>  1 file changed, 33 insertions(+), 27 deletions(-)
>
> diff --git a/tests/guest-debug/run-test.py b/tests/guest-debug/run-test.py
> index 75e9c92e03..d21a5dda77 100755
> --- a/tests/guest-debug/run-test.py
> +++ b/tests/guest-debug/run-test.py
> @@ -15,6 +15,7 @@
>  import subprocess
>  import shutil
>  import shlex
> +import sys
>  import os
>  from time import sleep
>  from tempfile import TemporaryDirectory
> @@ -22,10 +23,10 @@
>  def get_args():
>      parser = argparse.ArgumentParser(description="A gdbstub test runner")
>      parser.add_argument("--qemu", help="Qemu binary for test",
> -                        required=True)
> +                        required=False)
>      parser.add_argument("--qargs", help="Qemu arguments for test")
>      parser.add_argument("--binary", help="Binary to debug",
> -                        required=True)
> +                        required='--qemu' in sys.argv)
>      parser.add_argument("--test", help="GDB test script")
>      parser.add_argument('test_args', nargs='*',
>                          help="Additional args for GDB test script. "
> @@ -73,27 +74,30 @@ def log(output, msg):
>      socket_dir = TemporaryDirectory("qemu-gdbstub")
>      socket_name = os.path.join(socket_dir.name, "gdbstub.socket")
>  
> -    # Launch QEMU with binary
> -    if "system" in args.qemu:
> -        if args.no_suspend:
> -            suspend = ''
> +    if args.qemu:
> +        # Launch QEMU with binary.
> +        if "system" in args.qemu:
> +            if args.no_suspend:
> +                suspend = ''
> +            else:
> +                suspend = ' -S'
> +            cmd = f'{args.qemu} {args.qargs} {args.binary}' \
> +                f'{suspend} -gdb unix:path={socket_name},server=on'
>          else:
> -            suspend = ' -S'
> -        cmd = f'{args.qemu} {args.qargs} {args.binary}' \
> -            f'{suspend} -gdb unix:path={socket_name},server=on'
> -    else:
> -        if args.no_suspend:
> -            suspend = ',suspend=n'
> -        else:
> -            suspend = ''
> -        cmd = f'{args.qemu} {args.qargs} -g {socket_name}{suspend}' \
> -            f' {args.binary}'
> +            if args.no_suspend:
> +                suspend = ',suspend=n'
> +            else:
> +                suspend = ''
> +            cmd = f'{args.qemu} {args.qargs} -g {socket_name}{suspend}' \
> +                f' {args.binary}'
>  
> -    log(output, "QEMU CMD: %s" % (cmd))
> -    inferior = subprocess.Popen(shlex.split(cmd))
> +        log(output, "QEMU CMD: %s" % (cmd))
> +        inferior = subprocess.Popen(shlex.split(cmd))
>  
>      # Now launch gdb with our test and collect the result
> -    gdb_cmd = "%s %s" % (args.gdb, args.binary)
> +    gdb_cmd = args.gdb
> +    if args.binary:
> +        gdb_cmd += " %s" % (args.binary)
>      if args.gdb_args:
>          gdb_cmd += " %s" % (args.gdb_args)
>      # run quietly and ignore .gdbinit
> @@ -103,11 +107,12 @@ def log(output, msg):
>      # disable prompts in case of crash
>      gdb_cmd += " -ex 'set confirm off'"
>      # connect to remote
> -    gdb_cmd += " -ex 'target remote %s'" % (socket_name)
> +    if args.qemu:
> +        gdb_cmd += " -ex 'target remote %s'" % (socket_name)
>      # finally the test script itself
>      if args.test:
> -        if args.test_args:
> -            gdb_cmd += f" -ex \"py sys.argv={args.test_args}\""
> +        argv = [args.test] + args.test_args
> +        gdb_cmd += f" -ex \"py sys.argv={argv}\""
>          gdb_cmd += " -x %s" % (args.test)
>  
>  
> @@ -129,10 +134,11 @@ def log(output, msg):
>          log(output, "GDB crashed? (%d, %d) SKIPPING" % (result, result - 128))
>          exit(0)
>  
> -    try:
> -        inferior.wait(2)
> -    except subprocess.TimeoutExpired:
> -        log(output, "GDB never connected? Killed guest")
> -        inferior.kill()
> +    if args.qemu:
> +        try:
> +            inferior.wait(2)
> +        except subprocess.TimeoutExpired:
> +            log(output, "GDB never connected? Killed guest")
> +            inferior.kill()
>  
>      exit(result)

-- 
Alex Bennée
Virtualisation Tech Lead @ Linaro