Skip to content
This repository was archived by the owner on Nov 1, 2021. It is now read-only.

Commit d8eca0a

Browse files
author
George Karpenkov
committed
[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
1 parent 7ffb1b2 commit d8eca0a

File tree

2 files changed

+122
-115
lines changed

2 files changed

+122
-115
lines changed

utils/analyzer/SATestBuild.py

+14-115
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
variable. It should contain a comma separated list.
4444
"""
4545
import CmpRuns
46+
import SATestUtils
4647

4748
import os
4849
import csv
@@ -53,59 +54,15 @@
5354
import time
5455
import plistlib
5556
import argparse
56-
from subprocess import check_call, check_output, CalledProcessError
57+
from subprocess import check_call, CalledProcessError
5758
import multiprocessing
5859

5960
#------------------------------------------------------------------------------
6061
# Helper functions.
6162
#------------------------------------------------------------------------------
6263

6364

64-
def which(command, paths=None):
65-
"""which(command, [paths]) - Look up the given command in the paths string
66-
(or the PATH environment variable, if unspecified)."""
67-
68-
if paths is None:
69-
paths = os.environ.get('PATH', '')
70-
71-
# Check for absolute match first.
72-
if os.path.exists(command):
73-
return command
74-
75-
# Would be nice if Python had a lib function for this.
76-
if not paths:
77-
paths = os.defpath
78-
79-
# Get suffixes to search.
80-
# On Cygwin, 'PATHEXT' may exist but it should not be used.
81-
if os.pathsep == ';':
82-
pathext = os.environ.get('PATHEXT', '').split(';')
83-
else:
84-
pathext = ['']
85-
86-
# Search the paths...
87-
for path in paths.split(os.pathsep):
88-
for ext in pathext:
89-
p = os.path.join(path, command + ext)
90-
if os.path.exists(p):
91-
return p
92-
93-
return None
94-
95-
96-
class flushfile(object):
97-
"""
98-
Wrapper to flush the output after every print statement.
99-
"""
100-
def __init__(self, f):
101-
self.f = f
102-
103-
def write(self, x):
104-
self.f.write(x)
105-
self.f.flush()
106-
107-
108-
sys.stdout = flushfile(sys.stdout)
65+
sys.stdout = SATestUtils.flushfile(sys.stdout)
10966

11067

11168
def getProjectMapPath():
@@ -137,7 +94,7 @@ def getSBOutputDirName(IsReferenceBuild):
13794
if 'CC' in os.environ:
13895
Clang = os.environ['CC']
13996
else:
140-
Clang = which("clang", os.environ['PATH'])
97+
Clang = SATestUtils.which("clang", os.environ['PATH'])
14198
if not Clang:
14299
print "Error: cannot find 'clang' in PATH"
143100
sys.exit(-1)
@@ -215,37 +172,15 @@ def runCleanupScript(Dir, PBuildLogFile):
215172
"""
216173
Cwd = os.path.join(Dir, PatchedSourceDirName)
217174
ScriptPath = os.path.join(Dir, CleanupScript)
218-
runScript(ScriptPath, PBuildLogFile, Cwd)
175+
SATestUtils.runScript(ScriptPath, PBuildLogFile, Cwd)
219176

220177

221178
def runDownloadScript(Dir, PBuildLogFile):
222179
"""
223180
Run the script to download the project, if it exists.
224181
"""
225182
ScriptPath = os.path.join(Dir, DownloadScript)
226-
runScript(ScriptPath, PBuildLogFile, Dir)
227-
228-
229-
def runScript(ScriptPath, PBuildLogFile, Cwd):
230-
"""
231-
Run the provided script if it exists.
232-
"""
233-
if os.path.exists(ScriptPath):
234-
try:
235-
if Verbose == 1:
236-
print " Executing: %s" % (ScriptPath,)
237-
check_call("chmod +x '%s'" % ScriptPath, cwd=Cwd,
238-
stderr=PBuildLogFile,
239-
stdout=PBuildLogFile,
240-
shell=True)
241-
check_call("'%s'" % ScriptPath, cwd=Cwd,
242-
stderr=PBuildLogFile,
243-
stdout=PBuildLogFile,
244-
shell=True)
245-
except:
246-
print "Error: Running %s failed. See %s for details." % (
247-
ScriptPath, PBuildLogFile.name)
248-
sys.exit(-1)
183+
SATestUtils.runScript(ScriptPath, PBuildLogFile, Dir)
249184

250185

251186
def downloadAndPatch(Dir, PBuildLogFile):
@@ -343,28 +278,6 @@ def runScanBuild(Dir, SBOutputDir, PBuildLogFile):
343278
raise
344279

345280

346-
def hasNoExtension(FileName):
347-
(Root, Ext) = os.path.splitext(FileName)
348-
return (Ext == "")
349-
350-
351-
def isValidSingleInputFile(FileName):
352-
(Root, Ext) = os.path.splitext(FileName)
353-
return Ext in (".i", ".ii", ".c", ".cpp", ".m", "")
354-
355-
356-
def getSDKPath(SDKName):
357-
"""
358-
Get the path to the SDK for the given SDK name. Returns None if
359-
the path cannot be determined.
360-
"""
361-
if which("xcrun") is None:
362-
return None
363-
364-
Cmd = "xcrun --sdk " + SDKName + " --show-sdk-path"
365-
return check_output(Cmd, shell=True).rstrip()
366-
367-
368281
def runAnalyzePreprocessed(Dir, SBOutputDir, Mode):
369282
"""
370283
Run analysis on a set of preprocessed files.
@@ -378,7 +291,7 @@ def runAnalyzePreprocessed(Dir, SBOutputDir, Mode):
378291

379292
# For now, we assume the preprocessed files should be analyzed
380293
# with the OS X SDK.
381-
SDKPath = getSDKPath("macosx")
294+
SDKPath = SATestUtils.getSDKPath("macosx")
382295
if SDKPath is not None:
383296
CmdPrefix += "-isysroot " + SDKPath + " "
384297

@@ -398,9 +311,9 @@ def runAnalyzePreprocessed(Dir, SBOutputDir, Mode):
398311
Failed = False
399312

400313
# Only run the analyzes on supported files.
401-
if (hasNoExtension(FileName)):
314+
if SATestUtils.hasNoExtension(FileName):
402315
continue
403-
if (not isValidSingleInputFile(FileName)):
316+
if not SATestUtils.isValidSingleInputFile(FileName):
404317
print "Error: Invalid single input file %s." % (FullFileName,)
405318
raise Exception()
406319

@@ -563,14 +476,6 @@ def checkBuild(SBOutputDir):
563476
sys.exit(-1)
564477

565478

566-
class Discarder(object):
567-
"""
568-
Auxiliary object to discard stdout.
569-
"""
570-
def write(self, text):
571-
pass # do nothing
572-
573-
574479
def runCmpResults(Dir, Strictness=0):
575480
"""
576481
Compare the warnings produced by scan-build.
@@ -624,7 +529,7 @@ def runCmpResults(Dir, Strictness=0):
624529
# Discard everything coming out of stdout
625530
# (CmpRun produces a lot of them).
626531
OLD_STDOUT = sys.stdout
627-
sys.stdout = Discarder()
532+
sys.stdout = SATestUtils.Discarder()
628533
# Scan the results, delete empty plist files.
629534
NumDiffs, ReportsInRef, ReportsInNew = \
630535
CmpRuns.dumpScanBuildResultsDiff(RefDir, NewDir, Opts, False)
@@ -694,13 +599,6 @@ def testProject(ID, ProjectBuildMode, IsReferenceBuild=False, Strictness=0):
694599
return TestsPassed
695600

696601

697-
def isCommentCSVLine(Entries):
698-
"""
699-
Treat CSV lines starting with a '#' as a comment.
700-
"""
701-
return len(Entries) > 0 and Entries[0].startswith("#")
702-
703-
704602
def projectFileHandler():
705603
return open(getProjectMapPath(), "rb")
706604

@@ -712,7 +610,7 @@ def iterateOverProjects(PMapFile):
712610
"""
713611
PMapFile.seek(0)
714612
for I in csv.reader(PMapFile):
715-
if (isCommentCSVLine(I)):
613+
if (SATestUtils.isCommentCSVLine(I)):
716614
continue
717615
yield I
718616

@@ -722,10 +620,10 @@ def validateProjectFile(PMapFile):
722620
Validate project file.
723621
"""
724622
for I in iterateOverProjects(PMapFile):
725-
if (len(I) != 2):
623+
if len(I) != 2:
726624
print "Error: Rows in the ProjectMapFile should have 2 entries."
727625
raise Exception()
728-
if (not ((I[1] == "0") | (I[1] == "1") | (I[1] == "2"))):
626+
if I[1] not in ('0', '1', '2'):
729627
print "Error: Second entry in the ProjectMapFile should be 0" \
730628
" (single file), 1 (project), or 2(single file c++11)."
731629
raise Exception()
@@ -763,4 +661,5 @@ def testAll(IsReferenceBuild=False, Strictness=0):
763661

764662
TestsPassed = testAll(IsReference, Strictness)
765663
if not TestsPassed:
664+
print "ERROR: Tests failed."
766665
sys.exit(-1)

utils/analyzer/SATestUtils.py

+108
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
import os
2+
from subprocess import check_output, check_call
3+
import sys
4+
5+
6+
Verbose = 1
7+
8+
def which(command, paths=None):
9+
"""which(command, [paths]) - Look up the given command in the paths string
10+
(or the PATH environment variable, if unspecified)."""
11+
12+
if paths is None:
13+
paths = os.environ.get('PATH', '')
14+
15+
# Check for absolute match first.
16+
if os.path.exists(command):
17+
return command
18+
19+
# Would be nice if Python had a lib function for this.
20+
if not paths:
21+
paths = os.defpath
22+
23+
# Get suffixes to search.
24+
# On Cygwin, 'PATHEXT' may exist but it should not be used.
25+
if os.pathsep == ';':
26+
pathext = os.environ.get('PATHEXT', '').split(';')
27+
else:
28+
pathext = ['']
29+
30+
# Search the paths...
31+
for path in paths.split(os.pathsep):
32+
for ext in pathext:
33+
p = os.path.join(path, command + ext)
34+
if os.path.exists(p):
35+
return p
36+
37+
return None
38+
39+
40+
class flushfile(object):
41+
"""
42+
Wrapper to flush the output after every print statement.
43+
"""
44+
def __init__(self, f):
45+
self.f = f
46+
47+
def write(self, x):
48+
self.f.write(x)
49+
self.f.flush()
50+
51+
52+
def hasNoExtension(FileName):
53+
(Root, Ext) = os.path.splitext(FileName)
54+
return (Ext == "")
55+
56+
57+
def isValidSingleInputFile(FileName):
58+
(Root, Ext) = os.path.splitext(FileName)
59+
return Ext in (".i", ".ii", ".c", ".cpp", ".m", "")
60+
61+
62+
def getSDKPath(SDKName):
63+
"""
64+
Get the path to the SDK for the given SDK name. Returns None if
65+
the path cannot be determined.
66+
"""
67+
if which("xcrun") is None:
68+
return None
69+
70+
Cmd = "xcrun --sdk " + SDKName + " --show-sdk-path"
71+
return check_output(Cmd, shell=True).rstrip()
72+
73+
74+
def runScript(ScriptPath, PBuildLogFile, Cwd):
75+
"""
76+
Run the provided script if it exists.
77+
"""
78+
if os.path.exists(ScriptPath):
79+
try:
80+
if Verbose == 1:
81+
print " Executing: %s" % (ScriptPath,)
82+
check_call("chmod +x '%s'" % ScriptPath, cwd=Cwd,
83+
stderr=PBuildLogFile,
84+
stdout=PBuildLogFile,
85+
shell=True)
86+
check_call("'%s'" % ScriptPath, cwd=Cwd,
87+
stderr=PBuildLogFile,
88+
stdout=PBuildLogFile,
89+
shell=True)
90+
except:
91+
print "Error: Running %s failed. See %s for details." % (
92+
ScriptPath, PBuildLogFile.name)
93+
sys.exit(-1)
94+
95+
96+
class Discarder(object):
97+
"""
98+
Auxiliary object to discard stdout.
99+
"""
100+
def write(self, text):
101+
pass # do nothing
102+
103+
104+
def isCommentCSVLine(Entries):
105+
"""
106+
Treat CSV lines starting with a '#' as a comment.
107+
"""
108+
return len(Entries) > 0 and Entries[0].startswith("#")

0 commit comments

Comments
 (0)