import os
import time
import subprocess
+import marshal
+import select
+from optparse import OptionParser
def check(s):
row = None
return 0 not in row
return 0
-def runcmd(cmd,args,output,wait):
- #fo = open(tempfile, "wb")
- fo= os.tmpfile()
+def runcmd(cmd,args,wait):
+ #fo = os.tmpfile()
+ fi,fo = os.pipe()
+ fo = os.fdopen(fo, "wb")
p = subprocess.Popen([cmd] + args, executable=cmd, stdout=fo, stderr=fo)
ret = -1
+ output = ""
for i in range(wait*10):
+ if fi in select.select([fi],[],[], 0.01)[0]:
+ output += os.read(fi, 8192)
+ if "[exit]" in output:
+ break
ret = p.poll()
if ret is not None:
break
time.sleep(0.1)
else:
os.kill(p.pid, 9)
- os.system("killall -9 "+cmd)
-
- fo.seek(0)
- output = fo.read()
+ os.system("killall -9 %s >/dev/null 2>/dev/null" % cmd)
fo.close()
+
+ if fi in select.select([fi],[],[], 0.01)[0]:
+ output += os.read(fi, 8192)
+
+ os.close(fi)
return ret,output
-class Test:
- def __init__(self, nr, file):
+class Cache:
+ def __init__(self, filename):
+ try:
+ self.filename2status = marshal.load(open(filename, "rb"))
+ except IOError:
+ self.filename2status = {}
+
+ def parse_args(self):
+ parser = OptionParser()
+ parser.add_option("-d", "--diff", dest="diff", help="Only run tests that failed the last time",action="store_true")
+ (options, args) = parser.parse_args()
+ self.__dict__.update(options.__dict__)
+
+ self.checknum=-1
+ if len(args):
+ self.checknum = int(args[0])
+
+ @staticmethod
+ def load(filename):
+ return Cache(filename)
+
+ def save(self, filename):
+ fi = open(filename, "wb")
+ marshal.dump(self.filename2status, fi)
+ fi.close()
+
+ def highlight(self, nr, filename):
+ return self.checknum==nr
+
+ def skip_file(self, nr, filename):
+ if self.checknum>=0 and nr!=self.checknum:
+ return 1
+ if self.diff and self.filename2status[filename]=="ok":
+ return 1
+ return 0
+
+ def file_status(self, filename, status):
+ self.filename2status[filename] = status
+
+class TestBase:
+ def __init__(self, nr, file, run):
self.nr = nr
+ self.dorun = run
self.file = file
self.flash_output = None
self.flash_error = None
self.compile_output = None
self.compile_error = None
- self.compile()
- if not self.compile_error:
- self.run()
def compile(self):
try: os.unlink("abc.swf");
except: pass
- ret,output = runcmd("./parser",[self.file],"/tmp/abctest.txt",wait=60)
+ ret,output = runcmd("./parser",[self.file],wait=60)
self.compile_error = 0
self.compile_output = output
+ self.exit_status = 0
if ret:
+ self.compile_output += "\nExit status %d" % (-ret)
+ self.exit_status = -ret
self.compile_error = 1
+ return 0
if not os.path.isfile("abc.swf"):
self.compile_error = 1
+ return 0
+ return 1
def run(self):
- ret,output = runcmd("flashplayer",["abc.swf"],"/tmp/abctest.txt",wait=1)
+ ret,output = runcmd("flashplayer",["abc.swf"],wait=1)
os.system("killall flashplayer")
self.flash_output = output
if not check(self.flash_output):
self.flash_error = 1
+ return 0
+ return 1
def doprint(self):
- def r(s,l):
- if(len(s)>=l):
- return s
- return (" "*(l-len(s))) + s
- def l(s,l):
- if(len(s)>=l):
- return s
- return s + (" "*(l-len(s)))
-
- print r(str(self.nr),3)," ",
+ print self.r(str(self.nr),3)," ",
if self.compile_error:
- print "err"," - ",
+ if self.dorun:
+ if self.exit_status == 11:
+ print "crash"," - ",
+ else:
+ print "err "," - ",
+ else:
+ print "err "," ",
else:
- print "ok ",
- if not self.flash_error:
- print "ok ",
+ print "ok ",
+ if self.dorun:
+ if not self.flash_error:
+ print "ok ",
+ else:
+ print "err",
else:
- print "err",
+ print " ",
print " ",
- print file
+ print self.file
def doprintlong(self):
print self.nr, self.file
print "================================"
- print test.compile_output
+ print "compile:", (self.compile_error and "error" or "ok")
+ print self.compile_output
+ if not self.dorun:
+ return
print "================================"
- print test.flash_output
+ print "run:", (self.flash_error and "error" or "ok")
+ print self.flash_output
print "================================"
-checknum=-1
-if len(sys.argv)>1:
- checknum = int(sys.argv[1])
+ def r(self,s,l):
+ if(len(s)>=l):
+ return s
+ return (" "*(l-len(s))) + s
+ def l(self,s,l):
+ if(len(s)>=l):
+ return s
+ return s + (" "*(l-len(s)))
-for nr,file in sorted(enumerate(os.listdir("ok"))):
- if not file.endswith(".as"):
- continue
- file = os.path.join("ok", file)
- if checknum>=0 and nr!=checknum:
- continue
- test = Test(nr,file)
+class Test(TestBase):
+ def __init__(self, cache, nr, file):
+ TestBase.__init__(self, nr, file, run=1)
+ if self.compile() and self.run():
+ cache.file_status(file, "ok")
+ else:
+ cache.file_status(file, "error")
- if checknum!=nr:
- test.doprint()
- else:
- test.doprintlong()
+class ErrTest(TestBase):
+ def __init__(self, cache, nr, file):
+ TestBase.__init__(self, nr, file, run=0)
+ if self.compile():
+ cache.file_status(file, "error")
+ self.compile_error = True
+ else:
+ cache.file_status(file, "ok")
+ self.compile_error = False
+
+class Suite:
+ def __init__(self, cache, dir):
+ self.dir = dir
+ self.cache = cache
+ self.errtest = "err" in dir
+ def run(self, nr):
+ print "-"*40,"tests \""+self.dir+"\"","-"*40
+ for file in sorted(os.listdir(self.dir)):
+ if not file.endswith(".as"):
+ continue
+ nr = nr + 1
+ file = os.path.join(self.dir, file)
+
+ if cache.skip_file(nr, file):
+ continue
+
+ if self.errtest:
+ test = ErrTest(cache, nr, file)
+ else:
+ test = Test(cache, nr, file)
+
+ if not cache.highlight(nr, file):
+ test.doprint()
+ else:
+ test.doprintlong()
+ return nr
+
+cache = Cache.load(".tests.cache")
+cache.parse_args()
+nr = 0
+nr = Suite(cache, "err").run(nr)
+nr = Suite(cache, "ok").run(nr)
+cache.save(".tests.cache")