summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorGeorge Karpenkov <ekarpenkov@apple.com>2017-10-24 23:52:48 +0000
committerGeorge Karpenkov <ekarpenkov@apple.com>2017-10-24 23:52:48 +0000
commitd8eca0ac0820ec3df63a9e44f8b4b4b80922eb9a (patch)
treeab77e5a1b12e199699cf82140cf6764985fd6ac4 /utils
parent7ffb1b28fb076bf42863e76533ead4eb686e59d1 (diff)
[Analyzer] [Tests] Minor refactor of testing infrastructure:
Move utilities functions into a separate file to make comprehension easier. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@316535 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils')
-rwxr-xr-xutils/analyzer/SATestBuild.py129
-rw-r--r--utils/analyzer/SATestUtils.py108
2 files changed, 122 insertions, 115 deletions
diff --git a/utils/analyzer/SATestBuild.py b/utils/analyzer/SATestBuild.py
index 947cb5341a..5853cf438a 100755
--- a/utils/analyzer/SATestBuild.py
+++ b/utils/analyzer/SATestBuild.py
@@ -43,6 +43,7 @@ For testing additional checkers, use the SA_ADDITIONAL_CHECKERS environment
variable. It should contain a comma separated list.
"""
import CmpRuns
+import SATestUtils
import os
import csv
@@ -53,7 +54,7 @@ import shutil
import time
import plistlib
import argparse
-from subprocess import check_call, check_output, CalledProcessError
+from subprocess import check_call, CalledProcessError
import multiprocessing
#------------------------------------------------------------------------------
@@ -61,51 +62,7 @@ import multiprocessing
#------------------------------------------------------------------------------
-def which(command, paths=None):
- """which(command, [paths]) - Look up the given command in the paths string
- (or the PATH environment variable, if unspecified)."""
-
- if paths is None:
- paths = os.environ.get('PATH', '')
-
- # Check for absolute match first.
- if os.path.exists(command):
- return command
-
- # Would be nice if Python had a lib function for this.
- if not paths:
- paths = os.defpath
-
- # Get suffixes to search.
- # On Cygwin, 'PATHEXT' may exist but it should not be used.
- if os.pathsep == ';':
- pathext = os.environ.get('PATHEXT', '').split(';')
- else:
- pathext = ['']
-
- # Search the paths...
- for path in paths.split(os.pathsep):
- for ext in pathext:
- p = os.path.join(path, command + ext)
- if os.path.exists(p):
- return p
-
- return None
-
-
-class flushfile(object):
- """
- Wrapper to flush the output after every print statement.
- """
- def __init__(self, f):
- self.f = f
-
- def write(self, x):
- self.f.write(x)
- self.f.flush()
-
-
-sys.stdout = flushfile(sys.stdout)
+sys.stdout = SATestUtils.flushfile(sys.stdout)
def getProjectMapPath():
@@ -137,7 +94,7 @@ def getSBOutputDirName(IsReferenceBuild):
if 'CC' in os.environ:
Clang = os.environ['CC']
else:
- Clang = which("clang", os.environ['PATH'])
+ Clang = SATestUtils.which("clang", os.environ['PATH'])
if not Clang:
print "Error: cannot find 'clang' in PATH"
sys.exit(-1)
@@ -215,7 +172,7 @@ def runCleanupScript(Dir, PBuildLogFile):
"""
Cwd = os.path.join(Dir, PatchedSourceDirName)
ScriptPath = os.path.join(Dir, CleanupScript)
- runScript(ScriptPath, PBuildLogFile, Cwd)
+ SATestUtils.runScript(ScriptPath, PBuildLogFile, Cwd)
def runDownloadScript(Dir, PBuildLogFile):
@@ -223,29 +180,7 @@ def runDownloadScript(Dir, PBuildLogFile):
Run the script to download the project, if it exists.
"""
ScriptPath = os.path.join(Dir, DownloadScript)
- runScript(ScriptPath, PBuildLogFile, Dir)
-
-
-def runScript(ScriptPath, PBuildLogFile, Cwd):
- """
- Run the provided script if it exists.
- """
- if os.path.exists(ScriptPath):
- try:
- if Verbose == 1:
- print " Executing: %s" % (ScriptPath,)
- check_call("chmod +x '%s'" % ScriptPath, cwd=Cwd,
- stderr=PBuildLogFile,
- stdout=PBuildLogFile,
- shell=True)
- check_call("'%s'" % ScriptPath, cwd=Cwd,
- stderr=PBuildLogFile,
- stdout=PBuildLogFile,
- shell=True)
- except:
- print "Error: Running %s failed. See %s for details." % (
- ScriptPath, PBuildLogFile.name)
- sys.exit(-1)
+ SATestUtils.runScript(ScriptPath, PBuildLogFile, Dir)
def downloadAndPatch(Dir, PBuildLogFile):
@@ -343,28 +278,6 @@ def runScanBuild(Dir, SBOutputDir, PBuildLogFile):
raise
-def hasNoExtension(FileName):
- (Root, Ext) = os.path.splitext(FileName)
- return (Ext == "")
-
-
-def isValidSingleInputFile(FileName):
- (Root, Ext) = os.path.splitext(FileName)
- return Ext in (".i", ".ii", ".c", ".cpp", ".m", "")
-
-
-def getSDKPath(SDKName):
- """
- Get the path to the SDK for the given SDK name. Returns None if
- the path cannot be determined.
- """
- if which("xcrun") is None:
- return None
-
- Cmd = "xcrun --sdk " + SDKName + " --show-sdk-path"
- return check_output(Cmd, shell=True).rstrip()
-
-
def runAnalyzePreprocessed(Dir, SBOutputDir, Mode):
"""
Run analysis on a set of preprocessed files.
@@ -378,7 +291,7 @@ def runAnalyzePreprocessed(Dir, SBOutputDir, Mode):
# For now, we assume the preprocessed files should be analyzed
# with the OS X SDK.
- SDKPath = getSDKPath("macosx")
+ SDKPath = SATestUtils.getSDKPath("macosx")
if SDKPath is not None:
CmdPrefix += "-isysroot " + SDKPath + " "
@@ -398,9 +311,9 @@ def runAnalyzePreprocessed(Dir, SBOutputDir, Mode):
Failed = False
# Only run the analyzes on supported files.
- if (hasNoExtension(FileName)):
+ if SATestUtils.hasNoExtension(FileName):
continue
- if (not isValidSingleInputFile(FileName)):
+ if not SATestUtils.isValidSingleInputFile(FileName):
print "Error: Invalid single input file %s." % (FullFileName,)
raise Exception()
@@ -563,14 +476,6 @@ def checkBuild(SBOutputDir):
sys.exit(-1)
-class Discarder(object):
- """
- Auxiliary object to discard stdout.
- """
- def write(self, text):
- pass # do nothing
-
-
def runCmpResults(Dir, Strictness=0):
"""
Compare the warnings produced by scan-build.
@@ -624,7 +529,7 @@ def runCmpResults(Dir, Strictness=0):
# Discard everything coming out of stdout
# (CmpRun produces a lot of them).
OLD_STDOUT = sys.stdout
- sys.stdout = Discarder()
+ sys.stdout = SATestUtils.Discarder()
# Scan the results, delete empty plist files.
NumDiffs, ReportsInRef, ReportsInNew = \
CmpRuns.dumpScanBuildResultsDiff(RefDir, NewDir, Opts, False)
@@ -694,13 +599,6 @@ def testProject(ID, ProjectBuildMode, IsReferenceBuild=False, Strictness=0):
return TestsPassed
-def isCommentCSVLine(Entries):
- """
- Treat CSV lines starting with a '#' as a comment.
- """
- return len(Entries) > 0 and Entries[0].startswith("#")
-
-
def projectFileHandler():
return open(getProjectMapPath(), "rb")
@@ -712,7 +610,7 @@ def iterateOverProjects(PMapFile):
"""
PMapFile.seek(0)
for I in csv.reader(PMapFile):
- if (isCommentCSVLine(I)):
+ if (SATestUtils.isCommentCSVLine(I)):
continue
yield I
@@ -722,10 +620,10 @@ def validateProjectFile(PMapFile):
Validate project file.
"""
for I in iterateOverProjects(PMapFile):
- if (len(I) != 2):
+ if len(I) != 2:
print "Error: Rows in the ProjectMapFile should have 2 entries."
raise Exception()
- if (not ((I[1] == "0") | (I[1] == "1") | (I[1] == "2"))):
+ if I[1] not in ('0', '1', '2'):
print "Error: Second entry in the ProjectMapFile should be 0" \
" (single file), 1 (project), or 2(single file c++11)."
raise Exception()
@@ -763,4 +661,5 @@ if __name__ == '__main__':
TestsPassed = testAll(IsReference, Strictness)
if not TestsPassed:
+ print "ERROR: Tests failed."
sys.exit(-1)
diff --git a/utils/analyzer/SATestUtils.py b/utils/analyzer/SATestUtils.py
new file mode 100644
index 0000000000..961ebfac13
--- /dev/null
+++ b/utils/analyzer/SATestUtils.py
@@ -0,0 +1,108 @@
+import os
+from subprocess import check_output, check_call
+import sys
+
+
+Verbose = 1
+
+def which(command, paths=None):
+ """which(command, [paths]) - Look up the given command in the paths string
+ (or the PATH environment variable, if unspecified)."""
+
+ if paths is None:
+ paths = os.environ.get('PATH', '')
+
+ # Check for absolute match first.
+ if os.path.exists(command):
+ return command
+
+ # Would be nice if Python had a lib function for this.
+ if not paths:
+ paths = os.defpath
+
+ # Get suffixes to search.
+ # On Cygwin, 'PATHEXT' may exist but it should not be used.
+ if os.pathsep == ';':
+ pathext = os.environ.get('PATHEXT', '').split(';')
+ else:
+ pathext = ['']
+
+ # Search the paths...
+ for path in paths.split(os.pathsep):
+ for ext in pathext:
+ p = os.path.join(path, command + ext)
+ if os.path.exists(p):
+ return p
+
+ return None
+
+
+class flushfile(object):
+ """
+ Wrapper to flush the output after every print statement.
+ """
+ def __init__(self, f):
+ self.f = f
+
+ def write(self, x):
+ self.f.write(x)
+ self.f.flush()
+
+
+def hasNoExtension(FileName):
+ (Root, Ext) = os.path.splitext(FileName)
+ return (Ext == "")
+
+
+def isValidSingleInputFile(FileName):
+ (Root, Ext) = os.path.splitext(FileName)
+ return Ext in (".i", ".ii", ".c", ".cpp", ".m", "")
+
+
+def getSDKPath(SDKName):
+ """
+ Get the path to the SDK for the given SDK name. Returns None if
+ the path cannot be determined.
+ """
+ if which("xcrun") is None:
+ return None
+
+ Cmd = "xcrun --sdk " + SDKName + " --show-sdk-path"
+ return check_output(Cmd, shell=True).rstrip()
+
+
+def runScript(ScriptPath, PBuildLogFile, Cwd):
+ """
+ Run the provided script if it exists.
+ """
+ if os.path.exists(ScriptPath):
+ try:
+ if Verbose == 1:
+ print " Executing: %s" % (ScriptPath,)
+ check_call("chmod +x '%s'" % ScriptPath, cwd=Cwd,
+ stderr=PBuildLogFile,
+ stdout=PBuildLogFile,
+ shell=True)
+ check_call("'%s'" % ScriptPath, cwd=Cwd,
+ stderr=PBuildLogFile,
+ stdout=PBuildLogFile,
+ shell=True)
+ except:
+ print "Error: Running %s failed. See %s for details." % (
+ ScriptPath, PBuildLogFile.name)
+ sys.exit(-1)
+
+
+class Discarder(object):
+ """
+ Auxiliary object to discard stdout.
+ """
+ def write(self, text):
+ pass # do nothing
+
+
+def isCommentCSVLine(Entries):
+ """
+ Treat CSV lines starting with a '#' as a comment.
+ """
+ return len(Entries) > 0 and Entries[0].startswith("#")