dyld-625.13.tar.gz
[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 noCrashLogs = []
24 for file in os.listdir(testCaseSourceDir):
25 if file.endswith((".c", ".cpp", ".cxx")):
26 with open(testCaseSourceDir + "/" + file) as f:
27 for line in f.read().splitlines():
28 buildIndex = string.find(line, "BUILD:")
29 if buildIndex != -1:
30 buildLines.append(line[buildIndex + 6:].lstrip())
31 runIndex = string.find(line, "RUN:")
32 if runIndex != -1:
33 runLines.append(line[runIndex+4:].lstrip())
34 onlyIndex = string.find(line, "BUILD_ONLY:")
35 if onlyIndex != -1:
36 onlyLines.append(line[onlyIndex+11:].lstrip())
37 minOsIndex = string.find(line, "BUILD_MIN_OS:")
38 if minOsIndex != -1:
39 minOS = line[minOsIndex+13:].lstrip()
40 timeoutIndex = string.find(line, "RUN_TIMEOUT:")
41 if timeoutIndex != -1:
42 timeout = line[timeoutIndex+12:].lstrip()
43 noCrashLogsIndex = string.find(line, "NO_CRASH_LOG:")
44 if noCrashLogsIndex != -1:
45 noCrashLogs.append(line[noCrashLogsIndex+13:].lstrip())
46 return {
47 "BUILD": buildLines,
48 "BUILD_ONLY": onlyLines,
49 "BUILD_MIN_OS": minOS,
50 "RUN": runLines,
51 "RUN_TIMEOUT": timeout,
52 "NO_CRASH_LOG": noCrashLogs
53 }
54
55
56 #
57 # Look at directives dictionary to see if this test should be skipped for this platform
58 #
59 def useTestCase(testCaseDirectives, platformName):
60 onlyLines = testCaseDirectives["BUILD_ONLY"]
61 for only in onlyLines:
62 if only == "MacOSX" and platformName != "macosx":
63 return False
64 if only == "iOS" and platformName != "iphoneos":
65 return False
66 return True
67
68
69 #
70 # Use BUILD directives to construct the test case
71 # Use RUN directives to generate a shell script to run test(s)
72 #
73 def buildTestCase(testCaseDirectives, testCaseSourceDir, toolsDir, sdkDir, dyldIncludesDir, minOsOptionsName, defaultMinOS, archOptions, testCaseDestDirBuild, testCaseDestDirRun):
74 scratchDir = tempfile.mkdtemp()
75 if testCaseDirectives["BUILD_MIN_OS"]:
76 minOS = testCaseDirectives["BUILD_MIN_OS"]
77 else:
78 minOS = defaultMinOS
79 compilerSearchOptions = " -isysroot " + sdkDir + " -I" + sdkDir + "/System/Library/Frameworks/System.framework/PrivateHeaders" + " -I" + dyldIncludesDir
80 if minOsOptionsName == "mmacosx-version-min":
81 taskForPidCommand = "touch "
82 envEnableCommand = "touch "
83 else:
84 taskForPidCommand = "codesign --force --sign - --entitlements " + testCaseSourceDir + "/../../task_for_pid_entitlement.plist "
85 envEnableCommand = "codesign --force --sign - --entitlements " + testCaseSourceDir + "/../../get_task_allow_entitlement.plist "
86 buildSubs = {
87 "CC": toolsDir + "/usr/bin/clang " + archOptions + " -" + minOsOptionsName + "=" + str(minOS) + compilerSearchOptions,
88 "CXX": toolsDir + "/usr/bin/clang++ " + archOptions + " -" + minOsOptionsName + "=" + str(minOS) + compilerSearchOptions,
89 "BUILD_DIR": testCaseDestDirBuild,
90 "RUN_DIR": testCaseDestDirRun,
91 "TEMP_DIR": scratchDir,
92 "TASK_FOR_PID_ENABLE": taskForPidCommand,
93 "DYLD_ENV_VARS_ENABLE": envEnableCommand
94 }
95 os.makedirs(testCaseDestDirBuild)
96 os.chdir(testCaseSourceDir)
97 print >> sys.stderr, "cd " + testCaseSourceDir
98 for line in testCaseDirectives["BUILD"]:
99 cmd = string.Template(line).safe_substitute(buildSubs)
100 print >> sys.stderr, cmd
101 if "&&" in cmd:
102 result = subprocess.call(cmd, shell=True)
103 else:
104 cmdList = []
105 cmdList = string.split(cmd)
106 result = subprocess.call(cmdList)
107 if result:
108 return result
109 shutil.rmtree(scratchDir, ignore_errors=True)
110 sudoSub = ""
111 if minOsOptionsName == "mmacosx-version-min":
112 sudoSub = "sudo"
113 runSubs = {
114 "RUN_DIR": testCaseDestDirRun,
115 "REQUIRE_CRASH": "nocr -require_crash",
116 "SUDO": sudoSub,
117 }
118 runFilePath = testCaseDestDirBuild + "/run.sh"
119 with open(runFilePath, "a") as runFile:
120 runFile.write("#!/bin/sh\n")
121 runFile.write("cd " + testCaseDestDirRun + "\n")
122 os.chmod(runFilePath, 0755)
123 runFile.write("echo \"run in dyld2 mode\" \n");
124 for runline in testCaseDirectives["RUN"]:
125 runFile.write(string.Template(runline).safe_substitute(runSubs) + "\n")
126 runFile.write("echo \"run in dyld3 mode\" \n");
127 for runline in testCaseDirectives["RUN"]:
128 subLine = string.Template(runline).safe_substitute(runSubs)
129 if subLine.startswith("sudo "):
130 subLine = "sudo DYLD_USE_CLOSURES=1 " + subLine[5:]
131 else:
132 subLine = "DYLD_USE_CLOSURES=1 " + subLine
133 runFile.write(subLine + "\n")
134 runFile.write("\n")
135 runFile.close()
136 return 0
137
138
139
140 #
141 # Use XCode build settings to build all unit tests for specified platform
142 # Generate a .plist for BATS to use to run all tests
143 #
144 if __name__ == "__main__":
145 dstDir = os.getenv("DSTROOT", "/tmp/dyld_tests/")
146 testsRunDstTopDir = "/AppleInternal/CoreOS/tests/dyld/"
147 testsBuildDstTopDir = dstDir + testsRunDstTopDir
148 shutil.rmtree(testsBuildDstTopDir, ignore_errors=True)
149 dyldSrcDir = os.getenv("SRCROOT", "")
150 if not dyldSrcDir:
151 dyldSrcDir = os.getcwd()
152 testsSrcTopDir = dyldSrcDir + "/testing/test-cases/"
153 dyldIncludesDir = dyldSrcDir + "/include/"
154 sdkDir = os.getenv("SDKROOT", "")
155 if not sdkDir:
156 sdkDir = subprocess.check_output(["xcrun", "-sdk", "macosx.internal", "--show-sdk-path"]).rstrip()
157 toolsDir = os.getenv("TOOLCHAIN_DIR", "/")
158 defaultMinOS = ""
159 minVersNum = "10.14"
160 minOSOption = os.getenv("DEPLOYMENT_TARGET_CLANG_FLAG_NAME", "")
161 if minOSOption:
162 minOSVersName = os.getenv("DEPLOYMENT_TARGET_CLANG_ENV_NAME", "")
163 if minOSVersName:
164 minVersNum = os.getenv(minOSVersName, "")
165 else:
166 minOSOption = "mmacosx-version-min"
167 platformName = os.getenv("PLATFORM_NAME", "osx")
168 archOptions = ""
169 archList = os.getenv("RC_ARCHS", "")
170 if archList:
171 for arch in string.split(archList, " "):
172 archOptions = archOptions + " -arch " + arch
173 else:
174 archList = os.getenv("ARCHS_STANDARD_32_64_BIT", "")
175 if platformName == "watchos":
176 archOptions = "-arch armv7k"
177 elif platformName == "appletvos":
178 archOptions = "-arch arm64"
179 else:
180 if archList:
181 for arch in string.split(archList, " "):
182 archOptions = archOptions + " -arch " + arch
183 else:
184 archOptions = "-arch x86_64"
185 allTests = []
186 suppressCrashLogs = []
187 for f in sorted(os.listdir(testsSrcTopDir)):
188 if f.endswith(".dtest"):
189 testName = f[0:-6]
190 outDirBuild = testsBuildDstTopDir + testName
191 outDirRun = testsRunDstTopDir + testName
192 testCaseDir = testsSrcTopDir + f
193 testCaseDirectives = parseDirectives(testCaseDir)
194 if useTestCase(testCaseDirectives, platformName):
195 result = buildTestCase(testCaseDirectives, testCaseDir, toolsDir, sdkDir, dyldIncludesDir, minOSOption, minVersNum, archOptions, outDirBuild, outDirRun)
196 if result:
197 sys.exit(result)
198 mytest = {}
199 mytest["TestName"] = testName
200 mytest["Arch"] = "platform-native"
201 mytest["WorkingDirectory"] = testsRunDstTopDir + testName
202 mytest["Command"] = []
203 mytest["Command"].append("./run.sh")
204 usesDtrace = False
205 for runline in testCaseDirectives["RUN"]:
206 if "$SUDO" in runline:
207 mytest["AsRoot"] = True
208 if "dtrace" in runline:
209 usesDtrace = True
210 if testCaseDirectives["RUN_TIMEOUT"]:
211 mytest["Timeout"] = testCaseDirectives["RUN_TIMEOUT"]
212 if usesDtrace and minOSOption != "mmacosx-version-min":
213 mytest["BootArgsSet"] = "dtrace_dof_mode=1"
214 allTests.append(mytest)
215 if testCaseDirectives["NO_CRASH_LOG"]:
216 for skipCrash in testCaseDirectives["NO_CRASH_LOG"]:
217 suppressCrashLogs.append(skipCrash)
218 batsInfo = { "BATSConfigVersion": "0.1.0",
219 "Project": "dyld_tests",
220 "Tests": allTests }
221 if suppressCrashLogs:
222 batsInfo["IgnoreCrashes"] = []
223 for skipCrash in suppressCrashLogs:
224 batsInfo["IgnoreCrashes"].append(skipCrash)
225 batsFileDir = dstDir + "/AppleInternal/CoreOS/BATS/unit_tests/"
226 shutil.rmtree(batsFileDir, ignore_errors=True)
227 os.makedirs(batsFileDir)
228 batsFilePath = batsFileDir + "dyld.plist"
229 with open(batsFilePath, "w") as batsFile:
230 batsFile.write(plistlib.writePlistToString(batsInfo))
231 batsFile.close()
232 os.system('plutil -convert binary1 ' + batsFilePath) # convert the plist in place to binary
233 runHelper = dstDir + "/AppleInternal/CoreOS/tests/dyld/run_all_dyld_tests.sh"
234 print runHelper
235 with open(runHelper, "w") as shFile:
236 shFile.write("#!/bin/sh\n")
237 for test in allTests:
238 shFile.write(test["WorkingDirectory"] + "/run.sh\n")
239 shFile.close()
240 os.chmod(runHelper, 0755)
241