📄 boostbuild.py
字号:
# It is not possible to remove the current directory. d = os.getcwd() os.chdir(os.path.dirname(self.workdir)) shutil.rmtree(self.workdir, ignore_errors=False) if not os.path.isabs(tree_location): tree_location = os.path.join(self.original_workdir, tree_location) shutil.copytree(tree_location, self.workdir) os.chdir(d) def make_writable(unused, dir, entries): for e in entries: name = os.path.join(dir, e) os.chmod(name, os.stat(name)[0] | 0222) os.path.walk(".", make_writable, None) def write(self, file, content): self.wait_for_time_change_since_last_build() nfile = self.native_file_name(file) try: os.makedirs(os.path.dirname(nfile)) except Exception, e: pass open(nfile, "wb").write(content) def rename(self, old, new): try: os.makedirs(os.path.dirname(new)) except: pass try: os.remove(new) except: pass os.rename(old, new) self.touch(new); def copy(self, src, dst): self.wait_for_time_change_since_last_build() try: self.write(dst, self.read(src, 1)) except: self.fail_test(1) def copy_preserving_timestamp(self, src, dst): src_name = self.native_file_name(src) dst_name = self.native_file_name(dst) stats = os.stat(src_name) self.write(dst, self.read(src, 1)) os.utime(dst_name, (stats.st_atime, stats.st_mtime)) def touch(self, names): self.wait_for_time_change_since_last_build() for name in self.adjust_names(names): os.utime(self.native_file_name(name), None) def rm(self, names): self.wait_for_time_change_since_last_build() if not type(names) == types.ListType: names = [names] # Avoid attempts to remove the current directory. os.chdir(self.original_workdir) for name in names: n = self.native_file_name(name) n = glob.glob(n) if n: n = n[0] if not n: n = self.glob_file(string.replace(name, "$toolset", self.toolset+"*")) if n: if os.path.isdir(n): shutil.rmtree(n, ignore_errors=False) else: os.unlink(n) # Create working dir root again in case we removed it. if not os.path.exists(self.workdir): os.mkdir(self.workdir) os.chdir(self.workdir) def expand_toolset(self, name): """Expands $toolset in the given file to tested toolset. """ content = self.read(name) content = string.replace(content, "$toolset", self.toolset) self.write(name, content) def dump_stdio(self): annotation("STDOUT", self.stdout()) annotation("STDERR", self.stderr()) # # FIXME: Large portion copied from TestSCons.py, should be moved? # def run_build_system(self, extra_args="", subdir="", stdout=None, stderr="", status=0, match=None, pass_toolset=None, use_test_config=None, ignore_toolset_requirements=None, expected_duration=None, **kw): self.last_build_time_start = time.time() try: if os.path.isabs(subdir): if stderr: print "You must pass a relative directory to subdir <"+subdir+">." status = 1 return self.previous_tree = tree.build_tree(self.workdir) if match is None: match = self.match if pass_toolset is None: pass_toolset = self.pass_toolset if use_test_config is None: use_test_config = self.use_test_config if ignore_toolset_requirements is None: ignore_toolset_requirements = self.ignore_toolset_requirements try: kw['program'] = [] kw['program'] += self.program if extra_args: kw['program'] += extra_args.split(" ") if pass_toolset: kw['program'].append("toolset=" + self.toolset) if use_test_config: kw['program'].append('--test-config="%s"' % os.path.join(self.original_workdir, "test-config.jam")) if ignore_toolset_requirements: kw['program'].append("--ignore-toolset-requirements") kw['chdir'] = subdir apply(TestCmd.TestCmd.run, [self], kw) except: self.dump_stdio() raise finally: self.last_build_time_finish = time.time() if (status != None) and _failed(self, status): expect = '' if status != 0: expect = " (expected %d)" % status annotation("failure", '"%s" returned %d%s' % (kw['program'], _status(self), expect)) annotation("reason", "error returned by bjam") self.fail_test(1) if not (stdout is None) and not match(self.stdout(), stdout): annotation("failure", "Unexpected stdout") annotation("Expected STDOUT", stdout) annotation("Actual STDOUT", self.stdout()) stderr = self.stderr() if stderr: annotation("STDERR", stderr) self.maybe_do_diff(self.stdout(), stdout) self.fail_test(1, dump_stdio=False) # Intel tends to produce some messages to stderr which make tests fail. intel_workaround = re.compile("^xi(link|lib): executing.*\n", re.M) actual_stderr = re.sub(intel_workaround, "", self.stderr()) if not (stderr is None) and not match(actual_stderr, stderr): annotation("failure", "Unexpected stderr") annotation("Expected STDERR", stderr) annotation("Actual STDERR", self.stderr()) annotation("STDOUT", self.stdout()) self.maybe_do_diff(actual_stderr, stderr) self.fail_test(1, dump_stdio=False) if not expected_duration is None: actual_duration = self.last_build_time_finish - self.last_build_time_start if (actual_duration > expected_duration): print "Test run lasted %f seconds while it was expected to " \ "finish in under %f seconds." % (actual_duration, expected_duration) self.fail_test(1, dump_stdio=False) self.tree = tree.build_tree(self.workdir) self.difference = tree.trees_difference(self.previous_tree, self.tree) self.difference.ignore_directories() self.unexpected_difference = copy.deepcopy(self.difference) def glob_file(self, name): result = None if hasattr(self, 'difference'): for f in self.difference.added_files+self.difference.modified_files+self.difference.touched_files: if fnmatch.fnmatch(f, name): result = self.native_file_name(f) break if not result: result = glob.glob(self.native_file_name(name)) if result: result = result[0] return result def read(self, name, binary=False): try: if self.toolset: name = string.replace(name, "$toolset", self.toolset+"*") name = self.glob_file(name) openMode = "r" if binary: openMode += "b" else: openMode += "U" return open(name, openMode).read() except: annotation("failure", "Could not open '%s'" % name) self.fail_test(1) return '' def read_and_strip(self, name): lines = open(self.glob_file(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=True, *args): if not condition: return if hasattr(self, 'difference'): f = StringIO.StringIO() self.difference.pprint(f) annotation("changes caused by the last build command", f.getvalue()) if 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=False) elif os.path.exists(path): raise "Path " + path + " already exists and is not a directory"; shutil.copytree(self.workdir, path) at = TestCmd.caller(traceback.extract_stack(), 0) annotation("stacktrace", at) sys.exit(1) # A number of methods below check expectations with actual difference # between directory trees before and after a 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: glob_remove(self.unexpected_difference.added_files, 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: glob_remove(self.unexpected_difference.removed_files, 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: glob_remove(self.unexpected_difference.modified_files, 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 both touched and modified files. The reason is # that: # (1) Windows binaries such as obj, exe or dll files have slight # differences even with identical inputs due to Windows PE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -