import sys
import re
import shutil
+import subprocess
+import time
sys.path.append("..")
import rulesdef
+class Results(dict):
+ def __init__(self):
+ self.time = time.gmtime()
+ self.datetime = time.strftime("%Y-%m-%d %H:%M:%S +0000", self.time)
+ self.filename = "results-"+time.strftime("%Y%m%d-%H%M%S", self.time)+".html"
+
+ def toHtml(self):
+ s="""
+<?xml version="1.0" encoding="iso-8859-1" ?>
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
+ <title>OMK test report %(datetime)s</title>
+</head>
+<body>
+<h2>Summary</h2>TODO
+ """
+ s+="""
+<h2>Chart</h2>
+<table cellpadding='2' border='1'>
+<tbody>
+ """ % self.__dict__
+ tests = sorted(self.keys())
+ for t in tests:
+ s+=self[t].toHtml()
+ s+="""
+</tbody></table>
+<h2>Outputs of tests</h2>
+ """
+ for t in tests:
+ s+=self[t].toHtmlOutputs()
+ s+="""
+</body></html>
+ """
+ return s
+
+ def save(self):
+ f = file(self.filename, "w+")
+ f.write(self.toHtml())
+ try:
+ os.remove("results.html")
+ except:
+ pass
+ os.symlink(self.filename, "results.html")
+ print "Results written to "+self.filename
+
+class TestCaseResult(dict):
+ def __init__(self, tcname):
+ self.tcname = tcname
+
+ def toHtml(self):
+ rules = sorted(self.keys())
+ s="""
+ <tr><td colspan='6'><strong>%s</strong></td></tr>
+ """ % self.tcname
+ for r in rules:
+ s+=self[r].toHtml()
+ return s
+
+ def toHtmlOutputs(self):
+ rules = sorted(self.keys())
+ s="<h3>Testcase: %s</h3>" % self.tcname
+ for r in rules:
+ s+=self[r].toHtmlOutputs()
+ return s
+
+class ResultEntry:
+ def __init__(self, tcname, rules):
+ self.tcname = tcname
+ self.rules = rules
+
+ def toHtml(self):
+ if self.exitcode == 0: color=''
+ else:
+ if self.exitcode == 1: color=' bgcolor="red"'
+ elif self.exitcode == 2: color=' bgcolor="yellow"'
+ else: color=' bgcolor="silver"'
+ if self.stdout: stdoutlink="<a href='#stdout-%(tcname)s-%(rules)s'>stdout</a>" % self.__dict__
+ else: stdoutlink=''
+ if self.stderr: stderrlink="<a href='#stderr-%(tcname)s-%(rules)s'>stderr</a>" % self.__dict__
+ else: stderrlink=''
+ s="""
+ <tr%(color)s>
+ <td>%(rules)s</td>
+ <td>%(exitcode)d</td>
+ <td>%(message)s</td>
+ <td>%(time).1f s</td>
+ <td>%(stdoutlink)s</td>
+ <td>%(stderrlink)s</td>
+ </tr>
+ """ % {
+ 'color' : color,
+ 'tcname' : self.rules,
+ 'rules' : self.rules,
+ 'exitcode' : self.exitcode,
+ 'message' : self.message,
+ 'time' : self.time,
+ 'stdoutlink' : stdoutlink,
+ 'stderrlink' : stderrlink,
+ }
+ return s
+ def toHtmlOutputs(self):
+ vals = {
+ 'tcname':self.tcname,
+ 'rules':self.rules,
+ 'stdout':self.stdout,
+ 'stderr':self.stderr
+ }
+ s=""
+ if self.stdout: s+="""
+<a name='stdout-%(tcname)s-%(rules)s'/>
+<h5>Test %(tcname)s, rules %(rules)s, stdout</h5>
+<pre>%(stdout)s</pre>""" % vals
+ if self.stderr: s+="""
+<a name='stderr-%(tcname)s-%(rules)s'/>
+<h5>Test %(tcname)s, rules %(rules)s, stderr</h5>
+<pre>%(stderr)s</pre>""" % vals
+ return s
+
class TestCase:
def __init__(self, directory):
self.directory = directory # Absolute directory
+ self.name = self._getName()
self._whichRules()
+ def _getName(self):
+ name = self.directory
+ if name.startswith(testsRoot+"/"):
+ name = name[len(testsRoot)+1:]
+ return name
+
def _whichRules(self):
"""Reads the rules file and creates the self.rules list of all
rules to test"""
def run(self):
- print "Testing %s:" % self.directory,
+ self.results = TestCaseResult(self.name)
+ print "Testing %s:" % self.name,
os.chdir(os.path.join(testsRoot, self.directory))
+# if os.path.exists("Makefile.test"):
+# self._exec = self._execMake
+ if os.path.exists("runtest"):
+ self._exec = self._execRuntest
+ else: return
for rules in self.rules:
+ resultEntry = ResultEntry(self.name, rules)
+ self.results[rules] = resultEntry
+ print rules,
os.environ['OMK_RULES'] = rules
+ filesBefore = self._getFileSet()
self._copyRules(rules)
- self._doRun()
+ self._doRun(resultEntry)
+ filesAfter = self._getFileSet()
+ self._clean(filesBefore, filesAfter)
print
- # TODO remove makefile rules if sucessfull
+
+ def _getFileSet(self):
+ files = set()
+ for f in os.listdir("."):
+ files.add(f)
+ return files
+
+ def _clean(self, filesBefore, filesAfter):
+ remove = filesAfter - filesBefore
+ for f in remove:
+ os.system("rm -rf "+f)
+
+# def _execMake(self):
+# return os.system("make -k -f Makefile.test > /dev/null 2>&1")
+
+ def _execRuntest(self, log):
+ startTime = time.clock()
+ pipe = subprocess.Popen("./runtest", stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True)
+ endTime = time.clock()
+ (output, errors) = pipe.communicate()
+ ret = pipe.returncode
+ log.exitcode = ret
+ log.time = endTime - startTime
+ log.stdout = output
+ log.stderr = errors
+ if ret != 0 and os.path.exists("_error"):
+ log.message = file("_error").read()
+ else: log.message = ''
+
+ return ret
def _copyRules(self, rules):
"Copies the rules to the current directory"
src = os.path.join(testsRoot, "..", "rules", rules, "Makefile.rules")
shutil.copy(src, ".")
- def _doRun(self):
+ def _doRun(self, log):
"Runs the teset in current directory."
- if os.path.exists("Makefile.test"):
- ret = os.system("make -k -f Makefile.test")
- elif os.path.exists("runtest"):
- ret = os.system("./runtest")
+ ret = self._exec(log)
print ret,
testsRoot = os.path.dirname(os.path.abspath(__file__))
if not os.path.exists(os.path.join(testsRoot, "runtests.py")): raise "Can't find tests root directory!"
+results = Results()
+
for dirpath, dirnames, filenames in os.walk(testsRoot):
if not ("Makefile.test" in filenames or \
"runtest" in filenames):
continue
- print dirpath
t = TestCase(dirpath)
t.run()
+ results[t.name] = t.results
+
+os.chdir(testsRoot)
+results.save()
# Local Variables:
# compile-command: "python runtests.py"