📄 boostbuild.py
字号:
print self.stdout()
print "Expected STDERR =========="
print stderr
print "Actual STDERR ============"
print actual_stderr
self.maybe_do_diff(actual_stderr, stderr)
self.fail_test(1, dump_stdio = 0)
self.tree = build_tree(self.workdir)
self.difference = trees_difference(self.previous_tree, self.tree)
self.difference.ignore_directories()
self.unexpected_difference = copy.deepcopy(self.difference)
self.last_build_time = time.time()
def read(self, name):
return open(self.native_file_name(name), "rb").read()
def read_and_strip(self, name):
lines = open(self.native_file_name(name), "rb").readlines()
result = string.join(map(string.rstrip, lines), "\n")
if lines and lines[-1][-1] == '\n':
return result + '\n'
else:
return result
def fail_test(self, condition, dump_stdio = 1, *args):
# If test failed, print the difference
if condition and hasattr(self, 'difference'):
print '-------- all changes caused by last build command ----------'
self.difference.pprint()
if condition and dump_stdio:
self.dump_stdio()
if '--preserve' in sys.argv:
print
print "*** Copying the state of working dir into 'failed_test' ***"
print
path = os.path.join(self.original_workdir, "failed_test")
if os.path.isdir(path):
shutil.rmtree(path, ignore_errors=0)
elif os.path.exists(path):
raise "The path " + path + " already exists and is not directory";
shutil.copytree(self.workdir, path)
TestCmd.TestCmd.fail_test(self, condition, *args)
# A number of methods below check expectations with actual difference
# between directory trees before and after build.
# All the 'expect*' methods require exact names to be passed.
# All the 'ignore*' methods allow wildcards.
# All names can be lists, which are taken to be directory components
def expect_addition(self, names):
for name in self.adjust_names(names):
try:
self.unexpected_difference.added_files.remove(name)
except:
print "File %s not added as expected" % (name,)
self.fail_test(1)
def ignore_addition(self, wildcard):
self.ignore_elements(self.unexpected_difference.added_files, wildcard)
def expect_removal(self, names):
for name in self.adjust_names(names):
try:
self.unexpected_difference.removed_files.remove(name)
except:
print "File %s not removed as expected" % (name,)
self.fail_test(1)
def ignore_removal(self, wildcard):
self.ignore_elements(self.unexpected_difference.removed_files, wildcard)
def expect_modification(self, names):
for name in self.adjust_names(names):
try:
self.unexpected_difference.modified_files.remove(name)
except:
print "File %s not modified as expected" % (name,)
self.fail_test(1)
def ignore_modification(self, wildcard):
self.ignore_elements(self.unexpected_difference.modified_files, wildcard)
def expect_touch(self, names):
d = self.unexpected_difference
for name in self.adjust_names(names):
# We need to check in both touched and modified files.
# The reason is that:
# (1) for windows binaries often have slight
# differences even with identical inputs
# (2) Intel's compiler for Linux has the same behaviour
filesets = [d.modified_files, d.touched_files]
while filesets:
try:
filesets[-1].remove(name)
break
except ValueError:
filesets.pop()
if not filesets:
print "File %s not touched as expected" % (name,)
self.fail_test(1)
def ignore_touch(self, wildcard):
self.ignore_elements(self.unexpected_difference.touched_files, wildcard)
def ignore(self, wildcard):
self.ignore_elements(self.unexpected_difference.added_files, wildcard)
self.ignore_elements(self.unexpected_difference.removed_files, wildcard)
self.ignore_elements(self.unexpected_difference.modified_files, wildcard)
self.ignore_elements(self.unexpected_difference.touched_files, wildcard)
def expect_nothing(self, names):
for name in self.adjust_names(names):
if name in self.difference.added_files:
print "File %s is added, but no action was expected" % (name,)
self.fail_test(1)
if name in self.difference.removed_files:
print "File %s is removed, but no action was expected" % (name,)
self.fail_test(1)
pass
if name in self.difference.modified_files:
print "File %s is modified, but no action was expected" % (name,)
self.fail_test(1)
if name in self.difference.touched_files:
print "File %s is touched, but no action was expected" % (name,)
self.fail_test(1)
def expect_nothing_more(self):
# not totally sure about this change, but I don't see a good alternative
if windows:
self.ignore('*.ilk') # msvc incremental linking files
self.ignore('*.pdb') # msvc program database files
self.ignore('*.rsp') # response files
self.ignore('*.tds') # borland debug symbols
# debug builds of bjam built with gcc produce this profiling data
self.ignore('gmon.out')
self.ignore('*/gmon.out')
if not self.unexpected_difference.empty():
print 'FAILED'
print '------- The following changes were unexpected ------- '
self.unexpected_difference.pprint()
self.fail_test(1)
def expect_content(self, name, content, exact=0):
name = self.adjust_names(name)[0]
try:
if exact:
actual = self.read(name)
else:
actual = string.replace(self.read_and_strip(name), "\\", "/")
except IOError:
print "Note: could not open file", name
self.fail_test(1)
content = string.replace(content, "$toolset", self.toolset)
if actual != content:
print "Expected:\n"
print content
print "Got:\n"
print actual
self.fail_test(1)
def maybe_do_diff(self, actual, expected):
if os.environ.has_key("DO_DIFF") and os.environ["DO_DIFF"] != '':
e = tempfile.mktemp("expected")
a = tempfile.mktemp("actual")
open(e, "w").write(expected)
open(a, "w").write(actual)
print "DIFFERENCE"
if os.system("diff -u " + e + " " + a):
print "Unable to compute difference"
os.unlink(e)
os.unlink(a)
else:
print "Set environmental variable 'DO_DIFF' to examine difference."
# Helpers
def mul(self, *arguments):
if len(arguments) == 0:
return None
else:
here = arguments[0]
if type(here) == type(''):
here = [here]
if len(arguments) > 1:
there = apply(self.mul, arguments[1:])
result = []
for i in here:
for j in there:
result.append(i + j)
return result
else:
return here
# Internal methods
def ignore_elements(self, list, wildcard):
"""Removes in-place, element of 'list' that match the given wildcard."""
list[:] = filter(lambda x, w=wildcard: not fnmatch.fnmatch(x, w), list)
def adjust_lib_name(self, name):
global lib_prefix
result = name
pos = string.rfind(name, ".")
if pos != -1:
suffix = name[pos:]
if suffix in [".lib", ".dll"]:
(head, tail) = os.path.split(name)
if lib_prefix:
tail = "lib" + tail
result = os.path.join(head, tail)
return result
def adjust_suffix(self, name):
if not self.translate_suffixes:
return name
pos = string.rfind(name, ".")
if pos != -1:
suffix = name[pos:]
name = name[:pos]
if suffixes.has_key(suffix):
suffix = suffixes[suffix]
else:
suffix = ''
return name + suffix
# Acceps either string of list of string and returns list of strings
# Adjusts suffixes on all names.
def adjust_names(self, names):
if type(names) == types.StringType:
names = [names]
r = map(self.adjust_lib_name, names)
r = map(self.adjust_suffix, r)
r = map(lambda x, t=self.toolset: string.replace(x, "$toolset", t), r)
return r
def native_file_name(self, name):
name = self.adjust_names(name)[0]
elements = string.split(name, "/")
return os.path.normpath(apply(os.path.join, [self.workdir]+elements))
# Wait while time is no longer equal to the time last "run_build_system"
# call finished.
def wait_for_time_change(self):
while int(time.time()) < int(self.last_build_time) + 1:
time.sleep(0.1)
class List:
def __init__(self, s=""):
elements = []
if isinstance(s, type("")):
# Have to handle espaced spaces correctly
s = string.replace(s, "\ ", '\001')
elements = string.split(s)
else:
elements = s;
self.l = []
for e in elements:
self.l.append(string.replace(e, '\001', ' '))
def __len__(self):
return len(self.l)
def __getitem__(self, key):
return self.l[key]
def __setitem__(self, key, value):
self.l[key] = value
def __delitem__(self, key):
del self.l[key]
def __str__(self):
return str(self.l)
def __repr__(self):
return ( self.__module__ + '.List('
+ repr(string.join(self.l, ' '))
+ ')')
def __mul__(self, other):
result = List()
if not isinstance(other, List):
other = List(other)
for f in self:
for s in other:
result.l.append(f + s)
return result
def __rmul__(self, other):
if not isinstance(other, List):
other = List(other)
return List.__mul__(other, self)
def __add__(self, other):
result = List()
result.l = self.l[:] + other.l[:]
return result
# quickie tests. Should use doctest instead.
if __name__ == '__main__':
assert str(List("foo bar") * "/baz") == "['foo/baz', 'bar/baz']"
assert repr("foo/" * List("bar baz")) == "__main__.List('foo/bar foo/baz')"
print 'tests passed'
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -