scripts/unit-test: meson: Support custom valgrind setup

This makes it possible for the build to specify custom wrapper
parameters and timeout values using the
add_test_setup('valgrind', ...) infrastructure in meson.

Tested:
    Using the meson enabled sdeventplus build and manually added special
    parameters for the test suite.

Change-Id: I25df040463433cf2d91b416eaaa159cef9ba8235
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/scripts/unit-test.py b/scripts/unit-test.py
index d48b03e..da64a81 100755
--- a/scripts/unit-test.py
+++ b/scripts/unit-test.py
@@ -562,6 +562,38 @@
     """
     return re.match('ppc64', platform.machine()) is None
 
+def meson_setup_exists(setup):
+    """
+    Returns whether the meson build supports the named test setup.
+
+    Parameter descriptions:
+    setup              The setup target to check
+    """
+    try:
+        with open(os.devnull, 'w') as devnull:
+            output = subprocess.check_output(
+                    ['meson', 'test', '-C', 'build',
+                     '--setup', setup, '-t', '0'],
+                    stderr=subprocess.STDOUT)
+    except CalledProcessError as e:
+        output = e.output
+    return not re.search('Test setup .* not found from project', output)
+
+def maybe_meson_valgrind():
+    """
+    Potentially runs the unit tests through valgrind for the package
+    via `meson test`. The package can specify custom valgrind configurations
+    by utilizing add_test_setup() in a meson.build
+    """
+    if not is_valgrind_safe():
+        return
+    if meson_setup_exists('valgrind'):
+        check_call_cmd('meson', 'test', '-C', 'build',
+                       '--setup', 'valgrind')
+    else:
+        check_call_cmd('meson', 'test', '-C', 'build',
+                       '--wrapper', 'valgrind')
+
 def maybe_make_valgrind():
     """
     Potentially runs the unit tests through valgrind for the package
@@ -722,10 +754,7 @@
         build_and_install(UNIT_TEST_PKG, True)
         if os.path.isfile(CODE_SCAN_DIR + '/meson.build'):
             if not TEST_ONLY:
-                # Run valgrind if it is supported
-                if is_valgrind_safe():
-                    check_call_cmd('meson', 'test', '-C', 'build',
-                                   '--wrap', 'valgrind')
+                maybe_meson_valgrind()
 
                 # Run clang-tidy only if the project has a configuration
                 if os.path.isfile('.clang-tidy'):