10 from xml.sax.saxutils import escape
13 invokeDir = os.getcwd();
14 testsRoot = os.path.dirname(os.path.abspath(__file__))
15 if not os.path.exists(os.path.join(testsRoot, "tester.py")): raise "Can't find tests root directory!"
16 os.environ['OMK_TESTSROOT'] = testsRoot
18 sys.path.append(os.path.join(testsRoot, ".."))
23 self.time = time.gmtime()
24 self.datetime = time.strftime("%Y-%m-%d %H:%M:%S +0000", self.time)
25 self.filename = "results-"+time.strftime("%Y%m%d-%H%M%S", self.time)+".html"
29 self.stats = Stats(self)
33 <?xml version="1.0" encoding="iso-8859-1" ?>
35 PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
36 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
37 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
39 <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
40 <title>OMK test report %(datetime)s</title>
45 s+=self.stats.toHtml()
48 <table cellpadding='2' border='1'>
51 tests = sorted(self.keys())
56 <h2>Outputs of tests</h2>
59 s+=self[t].toHtmlOutputs()
66 f = file(self.filename, "w+")
67 f.write(self.toHtml())
69 os.remove("results.html")
72 os.symlink(self.filename, "results.html")
73 print "Results written to "+self.filename
75 class TestCaseResult(dict):
76 def __init__(self, tcname):
80 rules = sorted(self.keys())
82 <tr><td colspan='6'><strong>%s</strong></td></tr>
88 def toHtmlOutputs(self):
89 rules = sorted(self.keys())
90 s="<h3>Testcase: %s</h3>" % self.tcname
92 s+=self[r].toHtmlOutputs()
96 def __init__(self, tcname, rules):
101 if self.exitcode == 0: color=''
103 if self.exitcode == 1: color=' bgcolor="red"'
104 elif self.exitcode == 2: color=' bgcolor="gray"'
105 else: color=' bgcolor="gray"'
106 if self.stdout: stdoutlink="<a href='#stdout-%(tcname)s-%(rules)s'>stdout</a>" % self.__dict__
108 if self.stderr: stderrlink="<a href='#stderr-%(tcname)s-%(rules)s'>stderr</a>" % self.__dict__
113 <td>%(exitcode)d</td>
115 <td>%(time).1f s</td>
116 <td>%(stdoutlink)s</td>
117 <td>%(stderrlink)s</td>
121 'tcname' : self.rules,
122 'rules' : self.rules,
123 'exitcode' : self.exitcode,
124 'message' : escape(self.message),
126 'stdoutlink' : stdoutlink,
127 'stderrlink' : stderrlink,
130 def toHtmlOutputs(self):
132 'tcname':self.tcname,
134 'stdout':escape(self.stdout),
135 'stderr':escape(self.stderr)
138 if self.stdout: s+="""
139 <a name='stdout-%(tcname)s-%(rules)s'/>
140 <h5>Test %(tcname)s, rules %(rules)s, stdout</h5>
141 <pre>%(stdout)s</pre>""" % vals
142 if self.stderr: s+="""
143 <a name='stderr-%(tcname)s-%(rules)s'/>
144 <h5>Test %(tcname)s, rules %(rules)s, stderr</h5>
145 <pre>%(stderr)s</pre>""" % vals
149 def __init__(self, rules):
156 def update(self, testCaseResult):
158 resultEntry = testCaseResult[self.rules]
160 if resultEntry.exitcode == 0: self.success+=1
161 elif resultEntry.exitcode == 1: self.errors+=1
162 elif resultEntry.exitcode == 2: self.canttest+=1
163 else: self.unknown+=1
167 if self.errors == 0 and self.canttest == 0: self.color=''
168 elif self.errors != 0: self.color=' bgcolor="red"'
169 elif self.canttest != 0: self.color=' bgcolor="gray"'
170 else: self.color = ' bgcolor="gray"'
177 <td>%(canttest)d</td>
184 def __init__(self, results):
185 rules = rulesdef.rules.keys()
187 rulesStat = RulesStat(rule)
189 for resultEntry in results.values():
190 rulesStat.update(resultEntry)
194 <table cellpadding='2' border='1'>
196 <col span='5' align='right' />
207 rules = sorted(self.keys())
215 def __init__(self, directory, executable):
216 self.directory = directory # Absolute directory
217 self.executable = executable
218 self.name = self._getName()
222 name = self.directory
223 if name.startswith(testsRoot+"/"):
224 name = name[len(testsRoot)+1:]
225 testSuffix = re.match("^runtest[-_. :]*(.*)", self.executable).group(1)
230 def _whichRules(self):
231 """Reads the rules file and creates the self.rules list of all
235 f = open(os.path.join(self.directory, self.executable+'.rules'))
237 self.rules = rulesdef.rules.keys()
240 colonMatch = re.search('([^:]*) *: *(.*)', line)
242 if colonMatch.group(1) == "all":
244 self.rules = rulesdef.rules.keys()
245 elif colonMatch.group(1) == "snip":
247 snip = colonMatch.group(2)
248 for r in rulesdef.rules:
249 if snip in rulesdef.rules[r]:
251 elif colonMatch.group(1) == "python":
253 expr = colonMatch.group(2)
254 for r in rulesdef.rules:
255 if eval(expr, {'rules': r, 'snippets': rulesdef.rules[r]}):
260 if line in rulesdef.rules: self.rules = [ line ]
265 self.results = TestCaseResult(self.name)
266 print "Testing %s:\n" % self.name,
267 os.chdir(os.path.join(testsRoot, self.directory))
268 # if os.path.exists("Makefile.test"):
269 # self._exec = self._execMake
270 if os.path.exists(self.executable):
271 self._exec = self._execRuntest
273 for rules in self.rules:
274 resultEntry = ResultEntry(self.name, rules)
275 self.results[rules] = resultEntry
276 os.environ['OMK_RULES'] = rules
277 filesBefore = self._getFileSet()
278 self._copyRules(rules)
280 self._doRun(resultEntry)
282 filesAfter = self._getFileSet()
283 self._clean(filesBefore, filesAfter)
286 def _getFileSet(self):
288 for f in os.listdir("."):
292 def _clean(self, filesBefore, filesAfter):
293 remove = filesAfter - filesBefore
295 os.system("rm -rf "+f)
297 # def _execMake(self):
298 # return os.system("make -k -f Makefile.test > /dev/null 2>&1")
300 def _execRuntest(self, log):
301 startTime = time.clock()
302 pipe = subprocess.Popen("./"+self.executable, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True)
303 endTime = time.clock()
304 (output, errors) = pipe.communicate()
305 ret = pipe.returncode
307 log.time = endTime - startTime
310 if ret != 0 and os.path.exists("_error"):
311 log.message = file("_error").read()
312 else: log.message = ''
316 def _copyRules(self, rules):
317 "Copies the rules to the current directory"
318 src = os.path.join(testsRoot, "..", "rules", rules, "Makefile.rules")
319 shutil.copy(src, ".")
321 def _doRun(self, log):
322 "Runs the teset in current directory."
323 print " ",os.environ['OMK_RULES'],
325 ret = self._exec(log)
326 if ret == 0: retstr = "OK"
327 elif ret == 1: retstr = "FAILED"
328 elif ret == 2: retstr = "--"
330 print "%*s%s" % (20-len(os.environ['OMK_RULES']), "", retstr)
335 for dirpath, dirnames, filenames in os.walk(invokeDir):
336 executables = fnmatch.filter(filenames, "runtest*")
337 if not executables: continue
338 for exe in executables:
339 if exe[-1] == "~": continue
340 if re.search(".rules$", exe): continue
341 t = TestCase(dirpath, exe)
343 results[t.name] = t.results
350 # compile-command: "python tester.py"