unit-test: Run coverage and valgrind testing

This is oportunisticly enabled. If a build supports valgrind and
coverage metrics through the standard autoconf-archive mechanisms,
it will be forced to enable those settings. The unit test script then
checks to see if the makefile has the generated `check-valgrind` and
`check-code-coverage` targets and runs them if they exist.

Tested:
    With valgrind and code coverage tests added to sdbuplus, the tests
    all run as expected. With a non-enabled repo like phosphor-logging
    the unit test script still works. Also tested that when valgrind
    tests fail the exception is thrown and logs are written out as
    expected.

Change-Id: I4709cc6dbea7c97f0ef64fdddc5bce496d0751c7
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/scripts/unit-test.py b/scripts/unit-test.py
index 7405395..1642ade 100755
--- a/scripts/unit-test.py
+++ b/scripts/unit-test.py
@@ -286,6 +286,8 @@
         # Build & install this package
         conf_flags = [
             '--disable-silent-rules',
+            '--enable-code-coverage',
+            '--enable-valgrind',
         ]
         os.chdir(pkgdir)
         # Add any necessary configure flags for package
@@ -449,4 +451,36 @@
                 continue
             check_call_cmd(root, 'cat', os.path.join(root, 'test-suite.log'))
         raise Exception('Unit tests failed')
+
+    with open(os.devnull, 'w') as devnull:
+        # Run unit tests through valgrind if it exists
+        top_dir = os.path.join(WORKSPACE, UNIT_TEST_PKG)
+        try:
+            cmd = [ 'make', '-n', 'check-valgrind' ]
+            check_call(cmd, stdout=devnull, stderr=devnull)
+            try:
+                cmd = [ 'make', 'check-valgrind' ]
+                check_call_cmd(top_dir,  *cmd)
+            except CalledProcessError:
+                for root, _, files in os.walk(top_dir):
+                    for f in files:
+                        if re.search('test-suite-[a-z]+.log', f) is None:
+                            continue
+                        check_call_cmd(root, 'cat', os.path.join(root, f))
+                raise Exception('Valgrind tests failed')
+        except CalledProcessError:
+            pass
+
+        # Run code coverage if possible
+        try:
+            cmd = [ 'make', '-n', 'check-code-coverage' ]
+            check_call(cmd, stdout=devnull, stderr=devnull)
+            try:
+                cmd = [ 'make', 'check-code-coverage' ]
+                check_call_cmd(top_dir,  *cmd)
+            except CalledProcessError:
+                raise Exception('Code coverage failed')
+        except CalledProcessError:
+            pass
+
     os.umask(prev_umask)