[lit] Lift XFAIL handling to core infrastructure.
authorDaniel Dunbar <daniel@zuster.org>
Wed, 21 Aug 2013 22:26:42 +0000 (22:26 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Wed, 21 Aug 2013 22:26:42 +0000 (22:26 +0000)
llvm-svn: 188949

llvm/utils/lit/lit/Test.py
llvm/utils/lit/lit/TestRunner.py
llvm/utils/lit/tests/shtest-format.py

index c1bacb3..59ca694 100644 (file)
@@ -59,6 +59,10 @@ class Test:
         self.suite = suite
         self.path_in_suite = path_in_suite
         self.config = config
+        # A list of conditions under which this test is expected to fail. These
+        # can optionally be provided by test format handlers, and will be
+        # honored when the test result is supplied.
+        self.xfails = []
         # The test result, once complete.
         self.result = None
 
@@ -70,6 +74,13 @@ class Test:
 
         self.result = result
 
+        # Apply the XFAIL handling to resolve the result exit code.
+        if self.isExpectedToFail():
+            if self.result.code == PASS:
+                self.result.code = XPASS
+            elif self.result.code == FAIL:
+                self.result.code = XFAIL
+        
     def getFullName(self):
         return self.suite.config.name + ' :: ' + '/'.join(self.path_in_suite)
 
@@ -78,3 +89,29 @@ class Test:
 
     def getExecPath(self):
         return self.suite.getExecPath(self.path_in_suite)
+
+    def isExpectedToFail(self):
+        """
+        isExpectedToFail() -> bool
+
+        Check whether this test is expected to fail in the current
+        configuration. This check relies on the test xfails property which by
+        some test formats may not be computed until the test has first been
+        executed.
+        """
+
+        # Check if any of the xfails match an available feature or the target.
+        for item in self.xfails:
+            # If this is the wildcard, it always fails.
+            if item == '*':
+                return True
+
+            # If this is an exact match for one of the features, it fails.
+            if item in self.config.available_features:
+                return True
+
+            # If this is a part of the target triple, it fails.
+            if item in self.suite.config.target_triple:
+                return True
+
+        return False
index 6e03eb9..cf98b7a 100644 (file)
@@ -298,23 +298,6 @@ def executeScript(test, litConfig, tmpBase, commands, cwd):
     return lit.util.executeCommand(command, cwd=cwd,
                                    env=test.config.environment)
 
-def isExpectedFail(test, xfails):
-    # Check if any of the xfails match an available feature or the target.
-    for item in xfails:
-        # If this is the wildcard, it always fails.
-        if item == '*':
-            return True
-
-        # If this is an exact match for one of the features, it fails.
-        if item in test.config.available_features:
-            return True
-
-        # If this is a part of the target triple, it fails.
-        if item in test.suite.config.target_triple:
-            return True
-
-    return False
-
 def parseIntegratedTestScriptCommands(source_path):
     """
     parseIntegratedTestScriptCommands(source_path) -> commands
@@ -415,7 +398,6 @@ def parseIntegratedTestScript(test, normalize_slashes=False,
 
     # Collect the test lines from the script.
     script = []
-    xfails = []
     requires = []
     for line_number, command_type, ln in \
             parseIntegratedTestScriptCommands(sourcepath):
@@ -438,7 +420,7 @@ def parseIntegratedTestScript(test, normalize_slashes=False,
             else:
                 script.append(ln)
         elif command_type == 'XFAIL':
-            xfails.extend([s.strip() for s in ln.split(',')])
+            test.xfails.extend([s.strip() for s in ln.split(',')])
         elif command_type == 'REQUIRES':
             requires.extend([s.strip() for s in ln.split(',')])
         elif command_type == 'END':
@@ -480,8 +462,7 @@ def parseIntegratedTestScript(test, normalize_slashes=False,
         return (Test.UNSUPPORTED,
                 "Test requires the following features: %s" % msg)
 
-    isXFail = isExpectedFail(test, xfails)
-    return script,isXFail,tmpBase,execdir
+    return script,tmpBase,execdir
 
 def formatTestOutput(status, out, err, exitCode, script):
     output = """\
@@ -521,7 +502,7 @@ def executeShTest(test, litConfig, useExternalSh,
     if len(res) == 2:
         return res
 
-    script, isXFail, tmpBase, execdir = res
+    script, tmpBase, execdir = res
 
     if litConfig.noExecute:
         return (Test.PASS, '')
@@ -537,20 +518,9 @@ def executeShTest(test, litConfig, useExternalSh,
         return res
 
     out,err,exitCode = res
-    if isXFail:
-        ok = exitCode != 0
-        if ok:
-            status = Test.XFAIL
-        else:
-            status = Test.XPASS
+    if exitCode == 0:
+        status = Test.PASS
     else:
-        ok = exitCode == 0
-        if ok:
-            status = Test.PASS
-        else:
-            status = Test.FAIL
-
-    if ok:
-        return (status,'')
+        status = Test.FAIL
 
     return formatTestOutput(status, out, err, exitCode, script)
index a5ce2ff..1c23119 100644 (file)
 # CHECK: XFAIL: shtest-format :: xfail-target.txt
 # CHECK: XFAIL: shtest-format :: xfail.txt
 # CHECK: XPASS: shtest-format :: xpass.txt
+# CHECK-NEXT: *** TEST 'shtest-format :: xpass.txt' FAILED ***
+# CHECK-NEXT: Script
+# CHECK-NEXT: --
+# CHECK-NEXT: true
+# CHECK-NEXT: --
 # CHECK: Testing Time
 
 # CHECK: Unexpected Passing Tests (1)