__author__ = "Steven Knight <knight at baldmt dot com>"
__revision__ = "TestCommon.py 0.37.D001 2010/01/11 16:55:50 knight"
__version__ = "0.37"
import copy
import os
import os.path
import stat
import string
import sys
import types
import UserList
from TestCmd import *
from TestCmd import __all__
__all__.extend([ 'TestCommon',
'exe_suffix',
'obj_suffix',
'shobj_prefix',
'shobj_suffix',
'lib_prefix',
'lib_suffix',
'dll_prefix',
'dll_suffix',
])
if sys.platform == 'win32':
exe_suffix = '.exe'
obj_suffix = '.obj'
shobj_suffix = '.obj'
shobj_prefix = ''
lib_prefix = ''
lib_suffix = '.lib'
dll_prefix = ''
dll_suffix = '.dll'
module_prefix = ''
module_suffix = '.dll'
elif sys.platform == 'cygwin':
exe_suffix = '.exe'
obj_suffix = '.o'
shobj_suffix = '.os'
shobj_prefix = ''
lib_prefix = 'lib'
lib_suffix = '.a'
dll_prefix = ''
dll_suffix = '.dll'
module_prefix = ''
module_suffix = '.dll'
elif string.find(sys.platform, 'irix') != -1:
exe_suffix = ''
obj_suffix = '.o'
shobj_suffix = '.o'
shobj_prefix = ''
lib_prefix = 'lib'
lib_suffix = '.a'
dll_prefix = 'lib'
dll_suffix = '.so'
module_prefix = 'lib'
module_prefix = '.so'
elif string.find(sys.platform, 'darwin') != -1:
exe_suffix = ''
obj_suffix = '.o'
shobj_suffix = '.os'
shobj_prefix = ''
lib_prefix = 'lib'
lib_suffix = '.a'
dll_prefix = 'lib'
dll_suffix = '.dylib'
module_prefix = ''
module_suffix = '.so'
elif string.find(sys.platform, 'sunos') != -1:
exe_suffix = ''
obj_suffix = '.o'
shobj_suffix = '.os'
shobj_prefix = 'so_'
lib_prefix = 'lib'
lib_suffix = '.a'
dll_prefix = 'lib'
dll_suffix = '.dylib'
module_prefix = ''
module_suffix = '.so'
else:
exe_suffix = ''
obj_suffix = '.o'
shobj_suffix = '.os'
shobj_prefix = ''
lib_prefix = 'lib'
lib_suffix = '.a'
dll_prefix = 'lib'
dll_suffix = '.so'
module_prefix = 'lib'
module_suffix = '.so'
def is_List(e):
return type(e) is types.ListType \
or isinstance(e, UserList.UserList)
def is_writable(f):
mode = os.stat(f)[stat.ST_MODE]
return mode & stat.S_IWUSR
def separate_files(flist):
existing = []
missing = []
for f in flist:
if os.path.exists(f):
existing.append(f)
else:
missing.append(f)
return existing, missing
def _failed(self, status = 0):
if self.status is None or status is None:
return None
try:
return _status(self) not in status
except TypeError:
return _status(self) != status
def _status(self):
return self.status
class TestCommon(TestCmd):
def __init__(self, **kw):
apply(TestCmd.__init__, [self], kw)
os.chdir(self.workdir)
def must_be_writable(self, *files):
files = map(lambda x: is_List(x) and apply(os.path.join, x) or x, files)
existing, missing = separate_files(files)
unwritable = filter(lambda x, iw=is_writable: not iw(x), existing)
if missing:
print "Missing files: `%s'" % string.join(missing, "', `")
if unwritable:
print "Unwritable files: `%s'" % string.join(unwritable, "', `")
self.fail_test(missing + unwritable)
def must_contain(self, file, required, mode = 'rb'):
file_contents = self.read(file, mode)
contains = (string.find(file_contents, required) != -1)
if not contains:
print "File `%s' does not contain required string." % file
print self.banner('Required string ')
print required
print self.banner('%s contents ' % file)
print file_contents
self.fail_test(not contains)
def must_contain_all_lines(self, output, lines, title=None, find=None):
if find is None:
find = lambda o, l: string.find(o, l) != -1
missing = []
for line in lines:
if not find(output, line):
missing.append(line)
if missing:
if title is None:
title = 'output'
sys.stdout.write("Missing expected lines from %s:\n" % title)
for line in missing:
sys.stdout.write(' ' + repr(line) + '\n')
sys.stdout.write(self.banner(title + ' '))
sys.stdout.write(output)
self.fail_test()
def must_contain_any_line(self, output, lines, title=None, find=None):
if find is None:
find = lambda o, l: string.find(o, l) != -1
for line in lines:
if find(output, line):
return
if title is None:
title = 'output'
sys.stdout.write("Missing any expected line from %s:\n" % title)
for line in lines:
sys.stdout.write(' ' + repr(line) + '\n')
sys.stdout.write(self.banner(title + ' '))
sys.stdout.write(output)
self.fail_test()
def must_contain_lines(self, lines, output, title=None):
return self.must_contain_all_lines(output, lines, title)
def must_exist(self, *files):
files = map(lambda x: is_List(x) and apply(os.path.join, x) or x, files)
missing = filter(lambda x: not os.path.exists(x), files)
if missing:
print "Missing files: `%s'" % string.join(missing, "', `")
self.fail_test(missing)
def must_match(self, file, expect, mode = 'rb'):
file_contents = self.read(file, mode)
try:
self.fail_test(not self.match(file_contents, expect))
except KeyboardInterrupt:
raise
except:
print "Unexpected contents of `%s'" % file
self.diff(expect, file_contents, 'contents ')
raise
def must_not_contain(self, file, banned, mode = 'rb'):
file_contents = self.read(file, mode)
contains = (string.find(file_contents, banned) != -1)
if contains:
print "File `%s' contains banned string." % file
print self.banner('Banned string ')
print banned
print self.banner('%s contents ' % file)
print file_contents
self.fail_test(contains)
def must_not_contain_any_line(self, output, lines, title=None, find=None):
if find is None:
find = lambda o, l: string.find(o, l) != -1
unexpected = []
for line in lines:
if find(output, line):
unexpected.append(line)
if unexpected:
if title is None:
title = 'output'
sys.stdout.write("Unexpected lines in %s:\n" % title)
for line in unexpected:
sys.stdout.write(' ' + repr(line) + '\n')
sys.stdout.write(self.banner(title + ' '))
sys.stdout.write(output)
self.fail_test()
def must_not_contain_lines(self, lines, output, title=None):
return self.must_not_contain_any_line(output, lines, title)
def must_not_exist(self, *files):
files = map(lambda x: is_List(x) and apply(os.path.join, x) or x, files)
existing = filter(os.path.exists, files)
if existing:
print "Unexpected files exist: `%s'" % string.join(existing, "', `")
self.fail_test(existing)
def must_not_be_writable(self, *files):
files = map(lambda x: is_List(x) and apply(os.path.join, x) or x, files)
existing, missing = separate_files(files)
writable = filter(is_writable, existing)
if missing:
print "Missing files: `%s'" % string.join(missing, "', `")
if writable:
print "Writable files: `%s'" % string.join(writable, "', `")
self.fail_test(missing + writable)
def _complete(self, actual_stdout, expected_stdout,
actual_stderr, expected_stderr, status, match):
if _failed(self, status):
expect = ''
if status != 0:
expect = " (expected %s)" % str(status)
print "%s returned %s%s" % (self.program, str(_status(self)), expect)
print self.banner('STDOUT ')
print actual_stdout
print self.banner('STDERR ')
print actual_stderr
self.fail_test()
if not expected_stdout is None and not match(actual_stdout, expected_stdout):
self.diff(expected_stdout, actual_stdout, 'STDOUT ')
if actual_stderr:
print self.banner('STDERR ')
print actual_stderr
self.fail_test()
if not expected_stderr is None and not match(actual_stderr, expected_stderr):
print self.banner('STDOUT ')
print actual_stdout
self.diff(expected_stderr, actual_stderr, 'STDERR ')
self.fail_test()
def start(self, program = None,
interpreter = None,
arguments = None,
universal_newlines = None,
**kw):
options = kw.pop('options', None)
if options:
if arguments is None:
arguments = options
else:
arguments = options + " " + arguments
try:
return apply(TestCmd.start,
(self, program, interpreter, arguments, universal_newlines),
kw)
except KeyboardInterrupt:
raise
except Exception, e:
print self.banner('STDOUT ')
try:
print self.stdout()
except IndexError:
pass
print self.banner('STDERR ')
try:
print self.stderr()
except IndexError:
pass
cmd_args = self.command_args(program, interpreter, arguments)
sys.stderr.write('Exception trying to execute: %s\n' % cmd_args)
raise e
def finish(self, popen, stdout = None, stderr = '', status = 0, **kw):
apply(TestCmd.finish, (self, popen,), kw)
match = kw.get('match', self.match)
self._complete(self.stdout(), stdout,
self.stderr(), stderr, status, match)
def run(self, options = None, arguments = None,
stdout = None, stderr = '', status = 0, **kw):
if options:
if arguments is None:
arguments = options
else:
arguments = options + " " + arguments
kw['arguments'] = arguments
match = kw.pop('match', self.match)
apply(TestCmd.run, [self], kw)
self._complete(self.stdout(), stdout,
self.stderr(), stderr, status, match)
def skip_test(self, message="Skipping test.\n"):
if message:
sys.stdout.write(message)
sys.stdout.flush()
pass_skips = os.environ.get('TESTCOMMON_PASS_SKIPS')
if pass_skips in [None, 0, '0']:
self.no_result(skip=1)
else:
self.pass_test()