2 # -*- coding: utf-8 -*-
11 Automate testing of unit tests for xnu.
16 # this needs to be first thing for raft to load its environment correctly
17 if __name__
== '__main__':
18 # The following code allows this test to be invoked outside the harness and should be left unchanged
19 args
= [os
.path
.realpath(os
.path
.expanduser("/usr/local/bin/raft")), "-f"] + sys
.argv
20 os
.execv(args
[0], args
)
24 from raftlibs
.coreos
import crashReporterStop
, crashReporterStart
, doPrivileged
, runFunctionWithTestReRun
25 from raftlibs
.coreos
import runUniversalLogProcess
, spotlightStopSubtest
, spotlightStartSubtest
, svnCheckoutTestTool
, svnCheckoutToPath
, runSimpleProcess
27 from raft
.core
.logging
import log_note
30 from __test__
import __path__
32 # This is a Raft test. For more information see http://raft.apple.com
33 testDescription
= "Runs all tests defined as targets in Makefile" # Add a brief description of test functionality
34 testVersion
= "0.1" # Used to differentiate between results for different versions of the test
35 testState
= DevelopmentState
# Possible values: DevelopmentState, ProductionState
40 """ A container to hold test and its result """
41 def __init__(self
,testName
):
42 self
.name
= str(testName
)
43 self
.buildStatus
= False
44 self
.executeStatus
= False
52 def getSummaryHeader():
53 return "| {0: ^40s} |{1: >6s} |{2: >5s} |{3: >10s} |{4}".format("Test Name", "Build", "Run", "ExitVal", "Comments")
56 formatString
="| {0: <40s} |{1: >6s} |{2: >5s} |{3: >10s} |{4}"
57 nameVal
= str(self
.name
)
58 buildVal
= str(self
.buildStatus
)
59 execVal
= str(self
.executeStatus
)
60 exitVal
= str(self
.exitValue
)
61 commentsVal
= str(self
.comments
)
62 return formatString
.format(nameVal
, buildVal
, execVal
, exitVal
, commentsVal
)
65 def getTestsFromMakeFile(makeFilePath
):
67 targetRegex
= re
.compile("^\s*([a-zA-Z0-9_.]+)\s*:\s*([a-zA-Z0-9_.]*).*",re
.IGNORECASE|re
.DOTALL
)
68 fh
= open(makeFilePath
,"r");
70 tmp_res
= targetRegex
.findall(line
)
72 makeTargets
.append(xnuTest(tmp_res
[0][0]))
77 def buildTest(test
, path
):
79 result
= doCommand("/usr/bin/make",test
)
80 if result
['status'] != 0:
81 print "Failed to Build %s" % test
82 print "**STDOUT**\n%s" % result
['stdout']
83 print "**STDERR**\n%s" % result
['stderr']
85 log_note("Built %s successfully" % test
)
87 def executeTest(testObject
,path
):
89 test
= testObject
.getName()
90 executable_path
= os
.path
.join(path
, test
)
91 print "[TEST] %s" % test
92 print "[BEGIN] %s" % test
94 result
= runSimpleProcess(executable_path
,testName()+"_"+test
, wait_time
=120)
95 testObject
.exitValue
= result
['status']
96 if result
['status'] == 0:
97 print "[PASS] %s returned %d" % (test
,result
['status'])
99 print "[FAIL] %s returned %d" % (test
, result
['status'])
100 testObject
.comments
= "Failed due to timeout or file not found error"
101 log_note("Completed running test %s" % test
)
103 def removeTestExecutable(test
,path
):
105 doCommand("/bin/rm",test
)
108 # Change to /tmp, because make doesn't support directory paths with spaces
109 os
.chdir("/private/tmp")
110 output
= {'status': 1 }
112 output
= svnCheckoutTestTool("unit_tests")
115 if output
['status'] != 0 :
116 # since we are not fully published yet. lets get data from a branch
117 print "Fetching unit_test roots from Branch instead of trunk"
118 baseURL
= "http://src.apple.com/svn/xnu/branches/PR-10938974/tools/tests/unit_tests/"
119 output
= svnCheckoutToPath(baseURL
)
120 if output
['status'] != 0 :
121 logFail("[FAIL] error in checkout from branch")
124 local_path
= os
.path
.join(os
.getcwd(), "unit_tests")
125 makefile_path
= os
.path
.join(local_path
, "Makefile")
126 build_path
= os
.path
.join(local_path
, "BUILD")
129 tests_to_run
= getTestsFromMakeFile(makefile_path
)
130 log_note("Starting raft tests for XNU")
131 stats
= {"total":len(tests_to_run) , "pass":0, "fail":0}
132 for testObject
in tests_to_run
:
133 test
= testObject
.getName()
136 testObject
.buildStatus
= True
137 testObject
.executeStatus
= True
138 testObject
.exitValue
= 0
141 log_note("Running test :%s" % test
)
143 buildTest(test
,local_path
)
144 testObject
.buildStatus
= True
145 res
= executeTest(testObject
,build_path
)
146 testObject
.executeStatus
= True
147 if testObject
.exitValue
== 0 :
151 removeTestExecutable(test
,build_path
)
154 logFail("[FAIL] %s failed." % test
)
155 print "Finished running tests. Cleaning up"
156 doCommand("/usr/bin/make","clean")
157 #Now to print the Summary and statistics
158 print "\n\n Test Summary \n"
159 print xnuTest
.getSummaryHeader()
160 for testObject
in tests_to_run
:
161 print testObject
.getSummary()
162 print "\n===============================\n"
164 print "Total tests: %d" % stats
["total"]
165 print "Passed : %d" % stats
["pass"]
166 print "Failed : %d" % stats
["fail"]
167 print "================================\n\n"
169 logPass() # This line is implicit and can be removed