5 # Run compiler unit tests
7 # Copyright (c) 2008/2009 Matthias Kramm <kramm@quiss.org>
9 # This program is free software; you can redistribute it and/or modify
10 # it under the terms of the GNU General Public License as published by
11 # the Free Software Foundation; either version 2 of the License, or
12 # (at your option) any later version.
14 # This program is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 # GNU General Public License for more details.
19 # You should have received a copy of the GNU General Public License
20 # along with this program; if not, write to the Free Software
21 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
29 from optparse
import OptionParser
34 CMD_ARGS
=["-o","abc.swf"]
39 for line
in s
.split("\n"):
40 if line
.startswith("[") and line
.endswith("]"):
44 if not line
.startswith("ok"):
46 if line
.startswith("ok "):
51 nr
,l
= int(line
[3:i
]),int(line
[i
+1:])
71 def runcmd(cmd
,args
,wait
):
74 fo
= os
.fdopen(fo
, "wb")
75 p
= subprocess
.Popen([cmd
] + args
, executable
=cmd
, stdout
=fo
, stderr
=fo
)
78 for i
in range(wait
*10):
79 if fi
in select
.select([fi
],[],[], 0.01)[0]:
80 output
+= os
.read(fi
, 8192)
81 if "[exit]" in output
:
89 # valgrind never returns true
95 os
.system("killall -9 %s >/dev/null 2>/dev/null" % cmd
)
99 if fi
in select
.select([fi
],[],[], 0.01)[0]:
100 output
+= os
.read(fi
, 8192)
106 def __init__(self
, filename
):
107 self
.filename
= filename
108 self
.filename_milestone
= filename
+"_milestone"
110 self
.filename2status
= marshal
.load(open(self
.filename
, "rb"))
112 self
.filename2status
= {}
114 self
.milestone
= marshal
.load(open(self
.filename_milestone
, "rb"))
118 def parse_args(self
):
119 parser
= OptionParser()
120 parser
.add_option("-d", "--diff", dest
="diff", help="Only run tests that failed the last time",action
="store_true")
121 parser
.add_option("-a", "--all", dest
="all", help="Run all tests (also tests expected to fail)",action
="store_true")
122 parser
.add_option("-t", "--tag", dest
="tag", help="Mark the current pass/fail statistic as milestone",action
="store_true")
123 parser
.add_option("-m", "--valgrind", dest
="valgrind", help="Run compiler through valgrind",action
="store_true")
124 (options
, args
) = parser
.parse_args()
126 if args
and args
[0]=="add":
129 self
.milestone
[args
[1]] = "ok"
130 self
.filename2status
= self
.milestone
134 self
.__dict
__.update(options
.__dict
__)
138 self
.runtime
= 3 # allow more time if we're tagging this state
142 CMD_ARGS
= [CMD
] + CMD_ARGS
144 self
.runtime
= 20 # allow even more time for valgrind
150 self
.checknum
= int(args
[0])
152 self
.checkfile
= args
[0]
156 return Cache(filename
)
159 fi
= open(self
.filename
, "wb")
160 marshal
.dump(self
.filename2status
, fi
)
164 fi
= open(self
.filename_milestone
, "wb")
165 marshal
.dump(self
.filename2status
, fi
)
168 def highlight(self
, nr
, filename
):
169 if self
.checkfile
and filename
==self
.checkfile
:
171 return self
.checknum
==nr
173 def skip_file(self
, nr
, filename
):
174 if self
.checknum
>=0 and nr
!=self
.checknum
:
176 if self
.checkfile
and filename
!=self
.checkfile
:
178 if not self
.all
and self
.milestone
.get(filename
,"new")!="ok":
180 if self
.diff
and self
.filename2status(filename
,"new")=="ok":
184 def file_status(self
, filename
, status
):
185 self
.filename2status
[filename
] = status
188 def __init__(self
, cache
, nr
, file, run
):
193 self
.flash_output
= None
194 self
.flash_error
= None
195 self
.compile_output
= None
196 self
.compile_error
= None
199 try: os
.unlink("abc.swf");
201 ret
,output
= runcmd(CMD
,CMD_ARGS
+[self
.file],wait
=cache
.runtime
)
202 self
.compile_error
= 0
203 self
.compile_output
= output
206 self
.compile_output
+= "\nExit status %d" % (-ret
)
207 self
.exit_status
= -ret
208 self
.compile_error
= 1
210 if not os
.path
.isfile("abc.swf"):
211 self
.compile_error
= 1
216 ret
,output
= runcmd("flashplayer",[os
.path
.join(os
.getcwd(),"abc.swf")],wait
=cache
.runtime
)
217 os
.system("killall flashplayer")
218 self
.flash_output
= output
220 if not check(self
.flash_output
):
226 print self
.r(str(self
.nr
),3)," ",
227 if self
.compile_error
:
229 if self
.exit_status
== 11:
238 if not self
.flash_error
:
247 def doprintlong(self
):
248 print self
.nr
, self
.file
249 print "================================"
250 print "compile:", (self
.compile_error
and "error" or "ok")
251 print self
.compile_output
254 print "================================"
255 print "run:", (self
.flash_error
and "error" or "ok")
256 print self
.flash_output
257 print "================================"
262 return (" "*(l
-len(s
))) + s
266 return s
+ (" "*(l
-len(s
)))
268 class Test(TestBase
):
269 def __init__(self
, cache
, nr
, file):
270 TestBase
.__init
__(self
, cache
, nr
, file, run
=1)
271 if self
.compile() and self
.run():
272 cache
.file_status(file, "ok")
274 cache
.file_status(file, "error")
276 class ErrTest(TestBase
):
277 def __init__(self
, cache
, nr
, file):
278 TestBase
.__init
__(self
, cache
, nr
, file, run
=0)
280 cache
.file_status(file, "error")
281 self
.compile_error
= True
283 cache
.file_status(file, "ok")
284 self
.compile_error
= False
287 def __init__(self
, cache
, dir):
290 self
.errtest
= "err" in dir
292 print "-"*40,"tests \""+self
.dir+"\"","-"*40
293 for file in sorted(os
.listdir(self
.dir)):
294 if not file.endswith(".as"):
297 file = os
.path
.join(self
.dir, file)
299 if cache
.skip_file(nr
, file):
303 test
= ErrTest(cache
, nr
, file)
305 test
= Test(cache
, nr
, file)
307 if not cache
.highlight(nr
, file):
313 cache
= Cache
.load(".tests.cache")
317 nr
= Suite(cache
, "err").run(nr
)
318 nr
= Suite(cache
, "ok").run(nr
)