Nicely display compile failures.
[riscv-tests.git] / debug / testlib.py
index b8e9ad4d209c47e41865e4aab933ab6d99d90504..6655e05511ecb7863284fa36f09109d62bc017c1 100644 (file)
@@ -27,9 +27,17 @@ def compile(args, xlen=32): # pylint: disable=redefined-builtin
             cmd.append(found)
         else:
             cmd.append(arg)
-    cmd = " ".join(cmd)
-    result = os.system(cmd)
-    assert result == 0, "%r failed" % cmd
+    process = subprocess.Popen(cmd, stdout=subprocess.PIPE,
+            stderr=subprocess.PIPE)
+    stdout, stderr = process.communicate()
+    if process.returncode:
+        print
+        header("Compile failed")
+        print "+", " ".join(cmd)
+        print stdout,
+        print stderr,
+        header("")
+        raise Exception("Compile failed!")
 
 def unused_port():
     # http://stackoverflow.com/questions/2838244/get-open-tcp-port-in-python/2838309#2838309
@@ -165,14 +173,20 @@ class Openocd(object):
         PORT_REGEX = re.compile(r'(?P<port>\d+) \(LISTEN\)')
         for _ in range(MAX_ATTEMPTS):
             with open(os.devnull, 'w') as devnull:
-                output = subprocess.check_output([
-                    'lsof',
-                    '-a',  # Take the AND of the following selectors
-                    '-p{}'.format(self.process.pid),  # Filter on PID
-                    '-iTCP',  # Filter only TCP sockets
-                ], stderr=devnull)
+                try:
+                    output = subprocess.check_output([
+                        'lsof',
+                        '-a',  # Take the AND of the following selectors
+                        '-p{}'.format(self.process.pid),  # Filter on PID
+                        '-iTCP',  # Filter only TCP sockets
+                    ], stderr=devnull)
+                except subprocess.CalledProcessError:
+                    output = ""
             matches = list(PORT_REGEX.finditer(output))
+            matches = [m for m in matches
+                    if m.group('port') not in ('6666', '4444')]
             if len(matches) > 1:
+                print output
                 raise Exception(
                     "OpenOCD listening on multiple ports. Cannot uniquely "
                     "identify gdb server port.")
@@ -340,10 +354,13 @@ def add_test_run_options(parser):
             help="Run only tests that are named here.")
 
 def header(title, dash='-'):
-    dashes = dash * (36 - len(title))
-    before = dashes[:len(dashes)/2]
-    after = dashes[len(dashes)/2:]
-    print "%s[ %s ]%s" % (before, title, after)
+    if title:
+        dashes = dash * (36 - len(title))
+        before = dashes[:len(dashes)/2]
+        after = dashes[len(dashes)/2:]
+        print "%s[ %s ]%s" % (before, title, after)
+    else:
+        print dash * 40
 
 class BaseTest(object):
     compiled = {}
@@ -369,18 +386,9 @@ class BaseTest(object):
         compile_args = getattr(self, 'compile_args', None)
         if compile_args:
             if compile_args not in BaseTest.compiled:
-                try:
-                    # pylint: disable=star-args
-                    BaseTest.compiled[compile_args] = \
-                            self.target.compile(*compile_args)
-                except Exception: # pylint: disable=broad-except
-                    print "exception while compiling in %.2fs" % (
-                            time.time() - self.start)
-                    print "=" * 40
-                    header("Traceback")
-                    traceback.print_exc(file=sys.stdout)
-                    print "/" * 40
-                    return "exception"
+                # pylint: disable=star-args
+                BaseTest.compiled[compile_args] = \
+                        self.target.compile(*compile_args)
         self.binary = BaseTest.compiled.get(compile_args)
 
     def classSetup(self):