import glob, os, string, sys, thread, time
import libxml2
defaultParams = {}
def compFiles(res, expected, base1, base2):
l1 = len(base1)
exp = expected.readlines()
expected.close()
for i in range(len(res)):
j = string.find(res[i],base1)
if (j == 0) or ((j == 2) and (res[i][0:2] == './')):
col = string.find(res[i],':')
if col > 0:
start = string.rfind(res[i][:col], '/')
if start > 0:
res[i] = res[i][start+1:]
for i in range(len(exp)):
j = string.find(exp[i],base2)
if (j == 0) or ((j == 2) and (exp[i][0:2] == './')):
col = string.find(exp[i],':')
if col > 0:
start = string.rfind(exp[i][:col], '/')
if start > 0:
exp[i] = exp[i][start+1:]
ret = 0
rl = len(res)
el = len(exp)
if el != rl:
print 'Length of expected is %d, result is %d' % (el, rl)
ret = -1
for i in range(min(el, rl)):
if string.strip(res[i]) != string.strip(exp[i]):
print '+:%s-:%s' % (res[i], exp[i])
ret = -1
if el > rl:
for i in range(rl, el):
print '-:%s' % exp[i]
ret = -1
elif rl > el:
for i in range (el, rl):
print '+:%s' % res[i]
ret = -1
return ret
def readPfile(file, list, flag):
data = file.readlines() for l in data:
list.append(l)
file.close()
flag.append('ok')
def runOneTest(testDescription, filename, inbase, errbase):
if 'execpath' in testDescription:
dir = testDescription['execpath'] + '/'
else:
dir = ''
cmd = os.path.abspath(dir + testDescription['testprog'])
if 'flag' in testDescription:
for f in string.split(testDescription['flag']):
cmd += ' ' + f
if 'stdin' not in testDescription:
cmd += ' ' + inbase + filename
if 'extarg' in testDescription:
cmd += ' ' + testDescription['extarg']
noResult = 0
expout = None
if 'resext' in testDescription:
if testDescription['resext'] == 'None':
noResult = 1
else:
ext = '.' + testDescription['resext']
else:
ext = ''
if not noResult:
try:
fname = errbase + filename + ext
expout = open(fname, 'rt')
except:
print "Can't open result file %s - bypassing test" % fname
return
noErrors = 0
if 'reserrext' in testDescription:
if testDescription['reserrext'] == 'None':
noErrors = 1
else:
if len(testDescription['reserrext'])>0:
ext = '.' + testDescription['reserrext']
else:
ext = ''
else:
ext = ''
if not noErrors:
try:
fname = errbase + filename + ext
experr = open(fname, 'rt')
except:
experr = None
else:
experr = None
pin, pout, perr = os.popen3(cmd)
if 'stdin' in testDescription:
infile = open(inbase + filename, 'rt')
pin.writelines(infile.readlines())
infile.close()
pin.close()
th1Flag = [] th2Flag = []
outfile = [] errfile = []
th1 = thread.start_new_thread(readPfile, (pout, outfile, th1Flag))
th2 = thread.start_new_thread(readPfile, (perr, errfile, th2Flag))
while (len(th1Flag)==0) or (len(th2Flag)==0):
time.sleep(0.001)
if not noResult:
ret = compFiles(outfile, expout, inbase, 'test/')
if ret != 0:
print 'trouble with %s' % cmd
else:
if len(outfile) != 0:
for l in outfile:
print l
print 'trouble with %s' % cmd
if experr != None:
ret = compFiles(errfile, experr, inbase, 'test/')
if ret != 0:
print 'trouble with %s' % cmd
else:
if not noErrors:
if len(errfile) != 0:
for l in errfile:
print l
print 'trouble with %s' % cmd
if 'stdin' not in testDescription:
pin.close()
def runTest(description):
testDescription = defaultParams.copy() testDescription.update(description) if 'testname' in testDescription:
print "## %s" % testDescription['testname']
if not 'file' in testDescription:
print "No file specified - can't run this test!"
return
dir = ''
if 'srcdir' in testDescription:
dir += testDescription['srcdir'] + '/'
if 'srcsub' in testDescription:
dir += testDescription['srcsub'] + '/'
rdir = ''
if 'resdir' in testDescription:
rdir += testDescription['resdir'] + '/'
if 'ressub' in testDescription:
rdir += testDescription['ressub'] + '/'
testFiles = glob.glob(os.path.abspath(dir + testDescription['file']))
if testFiles == []:
print "No files result from '%s'" % testDescription['file']
return
count = 0
excl = []
if 'exclfile' in testDescription:
for f in string.split(testDescription['exclfile']):
glb = glob.glob(dir + f)
for g in glb:
excl.append(os.path.abspath(g))
for f in testFiles:
if not os.path.isdir(f):
if f not in excl:
count = count + 1
runOneTest(testDescription, os.path.basename(f), dir, rdir)
class testDefaults:
curText = ''
def addToDict(self, key):
txt = string.strip(self.curText)
if key not in defaultParams:
defaultParams[key] = txt
else:
defaultParams[key] += ' ' + txt
def processNode(self, reader, curClass):
if reader.Depth() == 2:
if reader.NodeType() == 1:
self.curText = '' elif reader.NodeType() == 15:
if (reader.Name() != '#text') and (reader.Name() != '#comment'):
self.addToDict(reader.Name())
elif reader.Depth() == 3:
if reader.Name() == '#text':
self.curText += reader.Value()
elif reader.NodeType() == 15: print "Defaults have been set to:"
for k in defaultParams.keys():
print " %s : '%s'" % (k, defaultParams[k])
curClass = rootClass()
return curClass
class testClass:
def __init__(self):
self.testParams = {} self.curText = ''
def addToDict(self, key):
data = string.strip(self.curText)
if key not in self.testParams:
self.testParams[key] = data
else:
if self.testParams[key] != '':
data = ' ' + data
self.testParams[key] += data
def processNode(self, reader, curClass):
if reader.Depth() == 2:
if reader.NodeType() == 1:
self.curText = '' if reader.Name() not in self.testParams:
self.testParams[reader.Name()] = ''
elif reader.NodeType() == 15:
if (reader.Name() != '#text') and (reader.Name() != '#comment'):
self.addToDict(reader.Name())
elif reader.Depth() == 3:
if reader.Name() == '#text':
self.curText += reader.Value()
elif reader.NodeType() == 15: runTest(self.testParams)
curClass = rootClass()
return curClass
class rootClass:
def processNode(self, reader, curClass):
if reader.Depth() == 0:
return curClass
if reader.Depth() != 1:
print "Unexpected junk: Level %d, type %d, name %s" % (
reader.Depth(), reader.NodeType(), reader.Name())
return curClass
if reader.Name() == 'test':
curClass = testClass()
curClass.testParams = {}
elif reader.Name() == 'defaults':
curClass = testDefaults()
return curClass
def streamFile(filename):
try:
reader = libxml2.newTextReaderFilename(filename)
except:
print "unable to open %s" % (filename)
return
curClass = rootClass()
ret = reader.Read()
while ret == 1:
curClass = curClass.processNode(reader, curClass)
ret = reader.Read()
if ret != 0:
print "%s : failed to parse" % (filename)
if len(sys.argv) != 2:
print "Usage: maketest {filename}"
sys.exit(-1)
streamFile(sys.argv[1])