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 <?xml version="1.0" encoding="iso-8859-1" ?>
31 PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
32 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
33 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
35 <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
36 <title>OMK test report %(datetime)s</title>
43 <table cellpadding='2' border='1'>
46 tests = sorted(self.keys())
51 <h2>Outputs of tests</h2>
54 s+=self[t].toHtmlOutputs()
61 f = file(self.filename, "w+")
62 f.write(self.toHtml())
64 os.remove("results.html")
67 os.symlink(self.filename, "results.html")
68 print "Results written to "+self.filename
70 class TestCaseResult(dict):
71 def __init__(self, tcname):
75 rules = sorted(self.keys())
77 <tr><td colspan='6'><strong>%s</strong></td></tr>
83 def toHtmlOutputs(self):
84 rules = sorted(self.keys())
85 s="<h3>Testcase: %s</h3>" % self.tcname
87 s+=self[r].toHtmlOutputs()
91 def __init__(self, tcname, rules):
96 if self.exitcode == 0: color=''
98 if self.exitcode == 1: color=' bgcolor="red"'
99 elif self.exitcode == 2: color=' bgcolor="yellow"'
100 else: color=' bgcolor="gray"'
101 if self.stdout: stdoutlink="<a href='#stdout-%(tcname)s-%(rules)s'>stdout</a>" % self.__dict__
103 if self.stderr: stderrlink="<a href='#stderr-%(tcname)s-%(rules)s'>stderr</a>" % self.__dict__
108 <td>%(exitcode)d</td>
110 <td>%(time).1f s</td>
111 <td>%(stdoutlink)s</td>
112 <td>%(stderrlink)s</td>
116 'tcname' : self.rules,
117 'rules' : self.rules,
118 'exitcode' : self.exitcode,
119 'message' : escape(self.message),
121 'stdoutlink' : stdoutlink,
122 'stderrlink' : stderrlink,
125 def toHtmlOutputs(self):
127 'tcname':self.tcname,
129 'stdout':escape(self.stdout),
130 'stderr':escape(self.stderr)
133 if self.stdout: s+="""
134 <a name='stdout-%(tcname)s-%(rules)s'/>
135 <h5>Test %(tcname)s, rules %(rules)s, stdout</h5>
136 <pre>%(stdout)s</pre>""" % vals
137 if self.stderr: s+="""
138 <a name='stderr-%(tcname)s-%(rules)s'/>
139 <h5>Test %(tcname)s, rules %(rules)s, stderr</h5>
140 <pre>%(stderr)s</pre>""" % vals
144 def __init__(self, directory, executable):
145 self.directory = directory # Absolute directory
146 self.executable = executable
147 self.name = self._getName()
151 name = self.directory
152 if name.startswith(testsRoot+"/"):
153 name = name[len(testsRoot)+1:]
154 testSuffix = re.match("^runtest[-_. :]*(.*)", self.executable).group(1)
159 def _whichRules(self):
160 """Reads the rules file and creates the self.rules list of all
164 f = open(os.path.join(self.directory, 'rules'))
166 self.rules = rulesdef.rules.keys()
169 colonMatch = re.search('([^:]*) *: *(.*)', line)
171 if colonMatch.group(1) == "all":
173 self.rules = rulesdef.rules.keys()
174 elif colonMatch.group(1) == "snip":
176 snip = colonMatch.group(2)
177 for r in rulesdef.rules:
178 if snip in rulesdef.rules[r]:
180 elif colonMatch.group(1) == "python":
182 expr = colonMatch.group(2)
183 for r in rulesdef.rules:
184 if eval(expr, {'rules': r, 'snippets': rulesdef.rules[r]}):
188 if line in rulesdef.rules: self.rules = [ line ]
193 self.results = TestCaseResult(self.name)
194 print "Testing %s:" % self.name,
195 os.chdir(os.path.join(testsRoot, self.directory))
196 # if os.path.exists("Makefile.test"):
197 # self._exec = self._execMake
198 if os.path.exists("runtest"):
199 self._exec = self._execRuntest
201 for rules in self.rules:
202 resultEntry = ResultEntry(self.name, rules)
203 self.results[rules] = resultEntry
205 os.environ['OMK_RULES'] = rules
206 filesBefore = self._getFileSet()
207 self._copyRules(rules)
209 self._doRun(resultEntry)
211 filesAfter = self._getFileSet()
212 self._clean(filesBefore, filesAfter)
215 def _getFileSet(self):
217 for f in os.listdir("."):
221 def _clean(self, filesBefore, filesAfter):
222 remove = filesAfter - filesBefore
224 os.system("rm -rf "+f)
226 # def _execMake(self):
227 # return os.system("make -k -f Makefile.test > /dev/null 2>&1")
229 def _execRuntest(self, log):
230 startTime = time.clock()
231 pipe = subprocess.Popen("./"+self.executable, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True)
232 endTime = time.clock()
233 (output, errors) = pipe.communicate()
234 ret = pipe.returncode
236 log.time = endTime - startTime
239 if ret != 0 and os.path.exists("_error"):
240 log.message = file("_error").read()
241 else: log.message = ''
245 def _copyRules(self, rules):
246 "Copies the rules to the current directory"
247 src = os.path.join(testsRoot, "..", "rules", rules, "Makefile.rules")
248 shutil.copy(src, ".")
250 def _doRun(self, log):
251 "Runs the teset in current directory."
252 ret = self._exec(log)
258 for dirpath, dirnames, filenames in os.walk(invokeDir):
259 executables = fnmatch.filter(filenames, "runtest*")
260 if not executables: continue
261 for exe in executables:
262 if exe[-1] == "~": continue
263 t = TestCase(dirpath, exe)
265 results[t.name] = t.results
271 # compile-command: "python runtests.py"