"""
A very crude emulator of dejagnu, just enough to integrate the libbfi
unittests into the pyobjc ones.
"""
import os
import re
import sys
import signal
from fnmatch import fnmatch
import unittest
from distutils.util import get_platform
gDgCommands=re.compile(r'''
(?:{\s*(dg-do)\s*run\s*({[^}]*})?\s*})
|
(?:{\s*(dg-output)\s*"([^"]*)"\s*})
''',
re.VERBOSE|re.MULTILINE)
def signame(code):
for nm in dir(signal):
if nm.startswith('SIG') and nm[3] != '_' \
and getattr(signal, nm) == code:
return nm
return code
def exitCode2Description(code):
"""
Convert the exit code as returned by os.popen().close() to a string
"""
if os.WIFEXITED(code):
return 'exited with status %s'%(os.WEXITSTATUS(code),)
elif os.WIFSIGNALED(code):
sig = os.WTERMSIG(code)
return 'crashed with signal %s [%s]'%(signame(sig), sig)
else:
return 'exit code %s'%(code,)
def platform_matches(matchstr):
if sys.byteorder == 'little':
platform = 'i386-apple-darwin'
else:
platform = 'powerpc-apple-darwin'
return fnmatch(platform, matchstr)
def parseDG(fdata):
result = []
for item in gDgCommands.findall(fdata):
if item[0] == 'dg-do':
result.append(('run', item[1]))
elif item[2] == 'dg-output':
result.append(('expect', item[3].decode('string_escape')))
return result
class DgTestCase (unittest.TestCase):
def __init__(self, filename):
unittest.TestCase.__init__(self)
self.filename = filename
archOption = "-arch x86_64"
compileOptionsBase = "-g -DMACOSX -Iinclude -o /tmp/test.bin -lffi"
compileOptionsList = ( "%s %s %s" % (compileOptionsBase, archOption, "-O0"),
"%s %s %s" % (compileOptionsBase, archOption, "-O1"),
"%s %s %s" % (compileOptionsBase, archOption, "-O2"),
"%s %s %s" % (compileOptionsBase, archOption, "-O3"),
"%s %s %s" % (compileOptionsBase, archOption, "-Os"), "%s %s %s" % (compileOptionsBase, archOption, "-Oz"), )
def runTest(self):
script = parseDG(open(self.filename).read())
output = []
for command, data in script:
if command == 'run':
action = 'run'
action_data = data
if command == 'expect':
output.append(data)
output = ''.join(output)
output = output.replace('\\', '')
d = action_data.split()
if d and d[1] == 'target':
for item in d[2:]:
if platform_matches(item):
break
else:
return
for compileOptions in self.compileOptionsList:
self.compileTestCase(compileOptions)
data = self.runTestCase()
if output != '':
self.assertEquals(data.rstrip(), output.rstrip())
os.unlink('/tmp/test.bin')
def shortDescription(self):
fn = os.path.basename(self.filename)[:-2]
dn = os.path.basename(os.path.dirname(self.filename))
return "dejagnu.%s.%s"%(dn, fn)
def compileTestCase(self, compileOptions):
commandline='cc %s %s 2>&1' % (compileOptions, self.filename)
fp = os.popen(commandline)
data = fp.read()
xit = fp.close()
if xit != None:
self.fail("Compile failed[%s]:\n%s"%(xit, data))
def runTestCase(self):
os.environ['DYLD_BIND_AT_LAUNCH'] = '1'
fp = os.popen('/tmp/test.bin', 'r')
del os.environ['DYLD_BIND_AT_LAUNCH']
data = fp.read()
xit = fp.close()
if xit != None:
self.fail("Running failed (%s)"%(exitCode2Description(xit),))
return data
def object_files(self, basedir):
result = []
for dirpath, dirnames, filenames in os.walk(basedir):
for fn in filenames:
if fn.endswith('.o'):
result.append(os.path.join(dirpath, fn))
return result
def testSuiteForDirectory(dirname):
tests = []
for fn in os.listdir(dirname):
if not fn.endswith('.c'): continue
tst = DgTestCase(os.path.join(dirname, fn))
if alltests and tst.shortDescription() not in alltests:
continue
tests.append(tst)
return unittest.TestSuite(tests)
alltests = []
if __name__ == "__main__":
alltests = sys.argv[1:]
runner = unittest.TextTestRunner(verbosity=2)
runner.run(testSuiteForDirectory('tests/testsuite/libffi.call'))