]> git.saurik.com Git - apple/dyld.git/blob - testing/build_tests.py
fd7874a1135a15b3fc34c1bba01db7dd65f3ebbd
[apple/dyld.git] / testing / build_tests.py
1 #!/usr/bin/python2.7
2
3 import plistlib
4 import string
5 import argparse
6 import sys
7 import os
8 import tempfile
9 import shutil
10 import subprocess
11
12
13 #
14 # Scan files in .dtest directory looking for BUILD: or RUN: directives.
15 # Return a dictionary of all directives.
16 #
17 def parseDirectives(testCaseSourceDir):
18 onlyLines = []
19 buildLines = []
20 runLines = []
21 minOS = ""
22 timeout = ""
23 for file in os.listdir(testCaseSourceDir):
24 if file.endswith((".c", ".cpp", ".cxx")):
25 with open(testCaseSourceDir + "/" + file) as f:
26 for line in f.read().splitlines():
27 buildIndex = string.find(line, "BUILD:")
28 if buildIndex != -1:
29 buildLines.append(line[buildIndex + 6:].lstrip())
30 runIndex = string.find(line, "RUN:")
31 if runIndex != -1:
32 runLines.append(line[runIndex+4:].lstrip())
33 onlyIndex = string.find(line, "BUILD_ONLY:")
34 if onlyIndex != -1:
35 onlyLines.append(line[onlyIndex+11:].lstrip())
36 minOsIndex = string.find(line, "BUILD_MIN_OS:")
37 if minOsIndex != -1:
38 minOS = line[minOsIndex+13:].lstrip()
39 timeoutIndex = string.find(line, "RUN_TIMEOUT:")
40 if timeoutIndex != -1:
41 timeout = line[timeoutIndex+12:].lstrip()
42
43 return {
44 "BUILD": buildLines,
45 "BUILD_ONLY": onlyLines,
46 "BUILD_MIN_OS": minOS,
47 "RUN": runLines,
48 "RUN_TIMEOUT": timeout
49 }
50
51
52 #
53 # Look at directives dictionary to see if this test should be skipped for this platform
54 #
55 def useTestCase(testCaseDirectives, platformName):
56 onlyLines = testCaseDirectives["BUILD_ONLY"]
57 for only in onlyLines:
58 if only == "MacOSX" and platformName != "macosx":
59 return False
60 if only == "iOS" and platformName != "iphoneos":
61 return False
62 return True
63
64
65 #
66 # Use BUILD directives to construct the test case
67 # Use RUN directives to generate a shell script to run test(s)
68 #
69 def buildTestCase(testCaseDirectives, testCaseSourceDir, toolsDir, sdkDir, minOsOptionsName, defaultMinOS, archOptions, testCaseDestDirBuild, testCaseDestDirRun):
70 scratchDir = tempfile.mkdtemp()
71 if testCaseDirectives["BUILD_MIN_OS"]:
72 minOS = testCaseDirectives["BUILD_MIN_OS"]
73 else:
74 minOS = defaultMinOS
75 compilerSearchOptions = " -isysroot " + sdkDir + " -I" + sdkDir + "/System/Library/Frameworks/System.framework/PrivateHeaders"
76 if minOsOptionsName == "mmacosx-version-min":
77 taskForPidCommand = "touch "
78 else:
79 taskForPidCommand = "codesign --force --sign - --entitlements " + testCaseSourceDir + "/../../task_for_pid_entitlement.plist "
80 buildSubs = {
81 "CC": toolsDir + "/usr/bin/clang " + archOptions + " -" + minOsOptionsName + "=" + str(minOS) + compilerSearchOptions,
82 "CXX": toolsDir + "/usr/bin/clang++ " + archOptions + " -" + minOsOptionsName + "=" + str(minOS) + compilerSearchOptions,
83 "BUILD_DIR": testCaseDestDirBuild,
84 "RUN_DIR": testCaseDestDirRun,
85 "TEMP_DIR": scratchDir,
86 "TASK_FOR_PID_ENABLE": taskForPidCommand
87 }
88 os.makedirs(testCaseDestDirBuild)
89 os.chdir(testCaseSourceDir)
90 print >> sys.stderr, "cd " + testCaseSourceDir
91 for line in testCaseDirectives["BUILD"]:
92 cmd = string.Template(line).safe_substitute(buildSubs)
93 print >> sys.stderr, cmd
94 cmdList = []
95 cmdList = string.split(cmd)
96 result = subprocess.call(cmdList)
97 if result:
98 return result
99 shutil.rmtree(scratchDir, ignore_errors=True)
100 sudoSub = ""
101 if minOsOptionsName == "mmacosx-version-min":
102 sudoSub = "sudo"
103 runSubs = {
104 "RUN_DIR": testCaseDestDirRun,
105 "REQUIRE_CRASH": "nocr -require_crash",
106 "SUDO": sudoSub,
107 }
108 runFilePath = testCaseDestDirBuild + "/run.sh"
109 with open(runFilePath, "a") as runFile:
110 runFile.write("#!/bin/sh\n")
111 runFile.write("cd " + testCaseDestDirRun + "\n")
112 os.chmod(runFilePath, 0755)
113 for runline in testCaseDirectives["RUN"]:
114 runFile.write(string.Template(runline).safe_substitute(runSubs) + "\n")
115 runFile.write("\n")
116 runFile.close()
117 return 0
118
119
120
121 #
122 # Use XCode build settings to build all unit tests for specified platform
123 # Generate a .plist for BATS to use to run all tests
124 #
125 if __name__ == "__main__":
126 dstDir = os.getenv("DSTROOT", "/tmp/dyld_tests/")
127 testsRunDstTopDir = "/AppleInternal/CoreOS/tests/dyld/"
128 testsBuildDstTopDir = dstDir + testsRunDstTopDir
129 shutil.rmtree(testsBuildDstTopDir, ignore_errors=True)
130 testsSrcTopDir = os.getenv("SRCROOT", "./") + "/testing/test-cases/"
131 sdkDir = os.getenv("SDKROOT", "/")
132 toolsDir = os.getenv("TOOLCHAIN_DIR", "/")
133 defaultMinOS = ""
134 minOSOption = os.getenv("DEPLOYMENT_TARGET_CLANG_FLAG_NAME", "")
135 if minOSOption:
136 minOSVersName = os.getenv("DEPLOYMENT_TARGET_CLANG_ENV_NAME", "")
137 if minOSVersName:
138 minVersNum = os.getenv(minOSVersName, "")
139 platformName = os.getenv("PLATFORM_NAME", "osx")
140 archOptions = ""
141 archList = os.getenv("RC_ARCHS", "")
142 if archList:
143 for arch in string.split(archList, " "):
144 archOptions = archOptions + " -arch " + arch
145 else:
146 archList = os.getenv("ARCHS_STANDARD_32_64_BIT", "")
147 if platformName == "watchos":
148 archOptions = "-arch armv7k"
149 elif platformName == "appletvos":
150 archOptions = "-arch arm64"
151 else:
152 archOptions = ""
153 for arch in string.split(archList, " "):
154 archOptions = archOptions + " -arch " + arch
155 allTests = []
156 for f in os.listdir(testsSrcTopDir):
157 if f.endswith(".dtest"):
158 testName = f[0:-6]
159 outDirBuild = testsBuildDstTopDir + testName
160 outDirRun = testsRunDstTopDir + testName
161 testCaseDir = testsSrcTopDir + f
162 testCaseDirectives = parseDirectives(testCaseDir)
163 if useTestCase(testCaseDirectives, platformName):
164 result = buildTestCase(testCaseDirectives, testCaseDir, toolsDir, sdkDir, minOSOption, minVersNum, archOptions, outDirBuild, outDirRun)
165 if result:
166 sys.exit(result)
167 mytest = {}
168 mytest["TestName"] = testName
169 mytest["Arch"] = "platform-native"
170 mytest["WorkingDirectory"] = testsRunDstTopDir + testName
171 mytest["Command"] = []
172 mytest["Command"].append("./run.sh")
173 for runline in testCaseDirectives["RUN"]:
174 if "$SUDO" in runline:
175 mytest["AsRoot"] = 1
176 if testCaseDirectives["RUN_TIMEOUT"]:
177 mytest["Timeout"] = testCaseDirectives["RUN_TIMEOUT"]
178 allTests.append(mytest)
179 batsInfo = { "BATSConfigVersion": "0.1.0",
180 "Project": "dyld_tests",
181 "Tests": allTests }
182 batsFileDir = dstDir + "/AppleInternal/CoreOS/BATS/unit_tests/"
183 shutil.rmtree(batsFileDir, ignore_errors=True)
184 os.makedirs(batsFileDir)
185 batsFilePath = batsFileDir + "dyld.plist"
186 with open(batsFilePath, "w") as batsFile:
187 batsFile.write(plistlib.writePlistToString(batsInfo))
188 batsFile.close()
189 os.system('plutil -convert binary1 ' + batsFilePath) # convert the plist in place to binary
190 runHelper = dstDir + "/AppleInternal/CoreOS/tests/dyld/run_all_dyld_tests.sh"
191 print runHelper
192 with open(runHelper, "w") as shFile:
193 shFile.write("#!/bin/sh\n")
194 for test in allTests:
195 shFile.write(test["WorkingDirectory"] + "/run.sh\n")
196 shFile.close()
197 os.chmod(runHelper, 0755)
198
199