Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r79819 - trunk/tools/build/v2/test
From: jurko.gospodnetic_at_[hidden]
Date: 2012-07-31 09:46:04


Author: jurko
Date: 2012-07-31 09:46:04 EDT (Tue, 31 Jul 2012)
New Revision: 79819
URL: http://svn.boost.org/trac/boost/changeset/79819

Log:
Internal Boost Build testing system cleanup - minor stylistic changes.
Text files modified:
   trunk/tools/build/v2/test/BoostBuild.py | 192 +++++++++++++++++++-------------------
   trunk/tools/build/v2/test/TestCmd.py | 32 ++---
   trunk/tools/build/v2/test/dependency_test.py | 197 +++++++++++++++++++++------------------
   3 files changed, 217 insertions(+), 204 deletions(-)

Modified: trunk/tools/build/v2/test/BoostBuild.py
==============================================================================
--- trunk/tools/build/v2/test/BoostBuild.py (original)
+++ trunk/tools/build/v2/test/BoostBuild.py 2012-07-31 09:46:04 EDT (Tue, 31 Jul 2012)
@@ -15,7 +15,6 @@
 import os.path
 import re
 import shutil
-import string
 import StringIO
 import sys
 import tempfile
@@ -205,7 +204,8 @@
     def __init__(self, arguments=None, executable="bjam",
         match=TestCmd.match_exact, boost_build_path=None,
         translate_suffixes=True, pass_toolset=True, use_test_config=True,
- ignore_toolset_requirements=True, workdir="", pass_d0=True, **keywords):
+ ignore_toolset_requirements=True, workdir="", pass_d0=True,
+ **keywords):
 
         assert arguments.__class__ is not str
         self.original_workdir = os.getcwd()
@@ -342,8 +342,10 @@
         except Exception, e:
             pass
         f = open(nfile, "wb")
- f.write(content)
- f.close()
+ try:
+ f.write(content)
+ finally:
+ f.close()
 
     def copy(self, src, dst):
         try:
@@ -379,8 +381,8 @@
             n = glob.glob(self.native_file_name(name))
             if n: n = n[0]
             if not n:
- n = self.glob_file(string.replace(name, "$toolset",
- self.toolset + "*"))
+ n = self.glob_file(name.replace("$toolset", self.toolset + "*")
+ )
             if n:
                 if os.path.isdir(n):
                     shutil.rmtree(n, ignore_errors=False)
@@ -398,8 +400,7 @@
         toolset currently being tested.
 
         """
- self.write(name, string.replace(self.read(name), "$toolset",
- self.toolset))
+ self.write(name, self.read(name).replace("$toolset", self.toolset))
 
     def dump_stdio(self):
         annotation("STDOUT", self.stdout())
@@ -526,7 +527,7 @@
     def read(self, name, binary=False):
         try:
             if self.toolset:
- name = string.replace(name, "$toolset", self.toolset + "*")
+ name = name.replace("$toolset", self.toolset + "*")
             name = self.glob_file(name)
             openMode = "r"
             if binary:
@@ -548,7 +549,7 @@
         f = open(self.glob_file(name), "rb")
         lines = f.readlines()
         f.close()
- result = string.join(map(string.rstrip, lines), "\n")
+ result = "\n".join(x.rstrip() for x in lines)
         if lines and lines[-1][-1] != "\n":
             return result + "\n"
         return result
@@ -561,7 +562,8 @@
         if dump_difference and hasattr(self, "difference"):
             f = StringIO.StringIO()
             self.difference.pprint(f)
- annotation("changes caused by the last build command", f.getvalue())
+ annotation("changes caused by the last build command",
+ f.getvalue())
 
         if dump_stdio:
             self.dump_stdio()
@@ -598,7 +600,8 @@
                 self.fail_test(1)
 
     def ignore_addition(self, wildcard):
- self.ignore_elements(self.unexpected_difference.added_files, wildcard)
+ self.__ignore_elements(self.unexpected_difference.added_files,
+ wildcard)
 
     def expect_removal(self, names):
         for name in self.adjust_names(names):
@@ -609,18 +612,20 @@
                 self.fail_test(1)
 
     def ignore_removal(self, wildcard):
- self.ignore_elements(self.unexpected_difference.removed_files, 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:
- annotation("failure", "File %s not modified as expected" % name)
+ annotation("failure", "File %s not modified as expected" %
+ name)
                 self.fail_test(1)
 
     def ignore_modification(self, wildcard):
- self.ignore_elements(self.unexpected_difference.modified_files, \
+ self.__ignore_elements(self.unexpected_difference.modified_files,
             wildcard)
 
     def expect_touch(self, names):
@@ -646,13 +651,14 @@
                 self.fail_test(1)
 
     def ignore_touch(self, wildcard):
- self.ignore_elements(self.unexpected_difference.touched_files, 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)
+ self.ignore_addition(wildcard)
+ self.ignore_removal(wildcard)
+ self.ignore_modification(wildcard)
+ self.ignore_touch(wildcard)
 
     def expect_nothing(self, names):
         for name in self.adjust_names(names):
@@ -702,69 +708,15 @@
             annotation("unexpected changes", output.getvalue())
             self.fail_test(1)
 
- def __expect_lines(self, data, lines, expected):
- # str.splitlines() trims at most one trailing newline while we want the
- # trailing newline to indicate that there should be an extra empty line
- # at the end.
- splitlines = lambda x : (x + "\n").splitlines()
-
- if data is None:
- data = []
- elif data.__class__ is str:
- data = splitlines(data)
-
- if lines.__class__ is str:
- lines = [splitlines(lines)]
- else:
- expanded = []
- for x in lines:
- if x.__class__ is str:
- expanded.extend(splitlines(x))
- else:
- expanded.append(x)
- lines = expanded
-
- if _contains_lines(data, lines) != bool(expected):
- output = []
- if expected:
- output = ["Did not find expected lines:"]
- else:
- output = ["Found unexpected lines:"]
- first = True
- for line_sequence in lines:
- if line_sequence:
- if first:
- first = False
- else:
- output.append("...")
- output.extend(" > " + line for line in line_sequence)
- output.append("in output:")
- output.extend(" > " + line for line in data)
- annotation("failure", "\n".join(output))
- self.fail_test(1)
-
     def expect_output_lines(self, lines, expected=True):
         self.__expect_lines(self.stdout(), lines, expected)
 
     def expect_content_lines(self, filename, line, expected=True):
         self.__expect_lines(self.__read_file(filename), line, expected)
 
- def __read_file(self, name, exact=False):
- name = self.adjust_names(name)[0]
- result = ""
- try:
- if exact:
- result = self.read(name)
- else:
- result = string.replace(self.read_and_strip(name), "\\", "/")
- except (IOError, IndexError):
- print "Note: could not open file", name
- self.fail_test(1)
- return result
-
     def expect_content(self, name, content, exact=False):
         actual = self.__read_file(name, exact)
- content = string.replace(content, "$toolset", self.toolset + "*")
+ content = content.replace("$toolset", self.toolset + "*")
 
         matched = False
         if exact:
@@ -813,7 +765,7 @@
             os.unlink(e)
             os.unlink(a)
         else:
- print("Set environmental variable 'DO_DIFF' to examine "
+ print("Set environmental variable 'DO_DIFF' to examine the "
                 "difference.")
 
     # Helpers.
@@ -836,16 +788,12 @@
         return here
 
     # Internal methods.
- def ignore_elements(self, list, wildcard):
- """Removes in-place 'list' elements matching the given 'wildcard'."""
- list[:] = filter(lambda x, w=wildcard: not fnmatch.fnmatch(x, w), list)
-
     def adjust_lib_name(self, name):
         global lib_prefix
         global dll_prefix
         result = name
 
- pos = string.rfind(name, ".")
+ pos = name.rfind(".")
         if pos != -1:
             suffix = name[pos:]
             if suffix == ".lib":
@@ -860,13 +808,13 @@
                     result = os.path.join(head, tail)
         # If we want to use this name in a Jamfile, we better convert \ to /,
         # as otherwise we would have to quote \.
- result = string.replace(result, "\\", "/")
+ result = result.replace("\\", "/")
         return result
 
     def adjust_suffix(self, name):
         if not self.translate_suffixes:
             return name
- pos = string.rfind(name, ".")
+ pos = name.rfind(".")
         if pos == -1:
             return name
         suffix = name[pos:]
@@ -875,18 +823,16 @@
     # Acceps either a string or a list of strings and returns a list of
     # strings. Adjusts suffixes on all names.
     def adjust_names(self, names):
- if type(names) == types.StringType:
+ if names.__class__ is str:
             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)
+ r = map(lambda x, t=self.toolset: x.replace("$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))
+ return os.path.normpath(os.path.join(self.workdir, *name.split("/")))
 
     def wait_for_time_change(self, original_timestamp=None):
         """
@@ -934,6 +880,47 @@
         if self.last_build_timestamp:
             self.wait_for_time_change(self.last_build_timestamp)
 
+ def __expect_lines(self, data, lines, expected):
+ # str.splitlines() trims at most one trailing newline while we want the
+ # trailing newline to indicate that there should be an extra empty line
+ # at the end.
+ splitlines = lambda x : (x + "\n").splitlines()
+
+ if data is None:
+ data = []
+ elif data.__class__ is str:
+ data = splitlines(data)
+
+ if lines.__class__ is str:
+ lines = [splitlines(lines)]
+ else:
+ expanded = []
+ for x in lines:
+ if x.__class__ is str:
+ expanded.extend(splitlines(x))
+ else:
+ expanded.append(x)
+ lines = expanded
+
+ if _contains_lines(data, lines) != bool(expected):
+ output = []
+ if expected:
+ output = ["Did not find expected lines:"]
+ else:
+ output = ["Found unexpected lines:"]
+ first = True
+ for line_sequence in lines:
+ if line_sequence:
+ if first:
+ first = False
+ else:
+ output.append("...")
+ output.extend(" > " + line for line in line_sequence)
+ output.append("in output:")
+ output.extend(" > " + line for line in data)
+ annotation("failure", "\n".join(output))
+ self.fail_test(1)
+
     def __get_current_file_timestamp(self):
         fd, path = tempfile.mkstemp(prefix="__Boost_Build_timestamp_tester__")
         try:
@@ -942,18 +929,33 @@
             os.close(fd)
             os.unlink(path)
 
+ def __ignore_elements(self, list, wildcard):
+ """Removes in-place 'list' elements matching the given 'wildcard'."""
+ list[:] = filter(lambda x, w=wildcard: not fnmatch.fnmatch(x, w), list)
+
+ def __read_file(self, name, exact=False):
+ name = self.adjust_names(name)[0]
+ result = ""
+ try:
+ if exact:
+ result = self.read(name)
+ else:
+ result = self.read_and_strip(name).replace("\\", "/")
+ except (IOError, IndexError):
+ print "Note: could not open file", name
+ self.fail_test(1)
+ return result
 
-class List:
 
+class List:
     def __init__(self, s=""):
         elements = []
- if isinstance(s, type("")):
+ if s.__class__ is str:
             # Have to handle escaped spaces correctly.
- s = string.replace(s, "\ ", "\001")
- elements = string.split(s)
+ elements = s.replace("\ ", "\001").split()
         else:
             elements = s
- self.l = [string.replace(e, "\001", " ") for e in elements]
+ self.l = [e.replace("\001", " ") for e in elements]
 
     def __len__(self):
         return len(self.l)
@@ -1001,14 +1003,14 @@
         if expected_line_count > data_line_count - index:
             return False
         expected_line_count -= len(expected)
- index = __match_line_sequence(data, index, data_line_count -
+ index = _match_line_sequence(data, index, data_line_count -
             expected_line_count, expected)
         if index < 0:
             return False
     return True
 
 
-def __match_line_sequence(data, start, end, lines):
+def _match_line_sequence(data, start, end, lines):
     if not lines:
         return start
     for index in xrange(start, end - len(lines) + 1):

Modified: trunk/tools/build/v2/test/TestCmd.py
==============================================================================
--- trunk/tools/build/v2/test/TestCmd.py (original)
+++ trunk/tools/build/v2/test/TestCmd.py 2012-07-31 09:46:04 EDT (Tue, 31 Jul 2012)
@@ -212,7 +212,6 @@
 
 
 class TestCmd:
-
     def __init__(self, description=None, program=None, workdir=None,
         subdir=None, verbose=False, match=None, inpath=None):
 
@@ -405,23 +404,20 @@
             cmd += arguments.split(" ")
         if self.verbose:
             sys.stderr.write(join(cmd, " ") + "\n")
- try:
- p = subprocess.Popen(cmd, stdin=subprocess.PIPE,
- stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=chdir,
- universal_newlines=universal_newlines)
- except:
- raise
- else:
- if stdin:
- if type(stdin) is ListType:
- for line in stdin:
- p.tochild.write(line)
- else:
- p.tochild.write(stdin)
- out, err = p.communicate()
- self._stdout.append(out)
- self._stderr.append(err)
- self.status = p.returncode
+ p = subprocess.Popen(cmd, stdin=subprocess.PIPE,
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=chdir,
+ universal_newlines=universal_newlines)
+
+ if stdin:
+ if type(stdin) is ListType:
+ for line in stdin:
+ p.tochild.write(line)
+ else:
+ p.tochild.write(stdin)
+ out, err = p.communicate()
+ self._stdout.append(out)
+ self._stderr.append(err)
+ self.status = p.returncode
 
         if self.verbose:
             sys.stdout.write(self._stdout[-1])

Modified: trunk/tools/build/v2/test/dependency_test.py
==============================================================================
--- trunk/tools/build/v2/test/dependency_test.py (original)
+++ trunk/tools/build/v2/test/dependency_test.py 2012-07-31 09:46:04 EDT (Tue, 31 Jul 2012)
@@ -3,102 +3,117 @@
 # Copyright 2003 Dave Abrahams
 # Copyright 2002, 2003, 2005, 2006 Vladimir Prus
 # Distributed under the Boost Software License, Version 1.0.
-# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
 
 import BoostBuild
 
-t = BoostBuild.Tester(["-d3"], pass_d0=False)
 
-t.set_tree("dependency-test")
+def test_basic():
+ t = BoostBuild.Tester(["-d3", "-d+12"], pass_d0=False)
 
-t.run_build_system()
+ t.set_tree("dependency-test")
 
-# Check that main target 'c' was able to find 'x.h' from 'a's dependency graph.
-t.expect_addition("bin/$toolset/debug/c.exe")
+ t.run_build_system()
 
-# Check handling of first level includes.
-
-# Both 'a' and 'b' include "a.h" and should be updated.
-t.touch("a.h")
-t.run_build_system()
-
-t.expect_touch("bin/$toolset/debug/a.exe")
-t.expect_touch("bin/$toolset/debug/a.obj")
-t.expect_touch("bin/$toolset/debug/a_c.obj")
-t.expect_touch("bin/$toolset/debug/b.exe")
-t.expect_touch("bin/$toolset/debug/b.obj")
-# Now, <dependency> does not add a dependency. It sound weird, but is
-# intentional. Need to rename <dependency> eventually.
-#t.expect_touch("bin/$toolset/debug/main-target-c/c.exe")
-t.ignore("*.tds")
-t.expect_nothing_more()
-
-# Only 'a' include <a.h> and should be updated.
-t.touch("src1/a.h")
-t.run_build_system()
-
-t.expect_touch("bin/$toolset/debug/a.exe")
-t.expect_touch("bin/$toolset/debug/a.obj")
-t.expect_touch("bin/$toolset/debug/a_c.obj")
-t.ignore("*.tds")
-t.expect_nothing_more()
-
-# "src/a.h" includes "b.h" (in the same dir).
-t.touch("src1/b.h")
-t.run_build_system()
-t.expect_touch("bin/$toolset/debug/a.exe")
-t.expect_touch("bin/$toolset/debug/a.obj")
-t.expect_touch("bin/$toolset/debug/a_c.obj")
-t.ignore("*.tds")
-t.expect_nothing_more()
-
-# Included by "src/b.h". We had a bug: file included via "", like "b.h" is in
-# this case, was not scanned at all.
-t.touch("src1/c.h")
-t.run_build_system()
-t.expect_touch("bin/$toolset/debug/a.exe")
-
-t.touch("b.h")
-t.run_build_system()
-t.expect_nothing_more()
-
-# Test dependency on a generated header.
-#
-# TODO: we have also to check that generated header is found correctly if it is
-# different for different subvariants. Lacking any toolset support, this check
-# will be implemented later.
-t.touch("x.foo")
-t.run_build_system()
-t.expect_touch("bin/$toolset/debug/a.obj")
-t.expect_touch("bin/$toolset/debug/a_c.obj")
-
-# Check that generated headers are scanned for dependencies as well.
-t.touch("src1/z.h")
-t.run_build_system()
-t.expect_touch("bin/$toolset/debug/a.obj")
-t.expect_touch("bin/$toolset/debug/a_c.obj")
-
-# Regression test: on Windows, <includes> with absolute paths were not
-# considered when scanning dependencies.
-t.rm(".")
-
-t.write("jamroot.jam", """
-path-constant TOP : . ;
-exe app : main.cpp : <include>$(TOP)/include ;
-""");
-
-t.write("main.cpp", """
-#include <dir/header.h>
-int main() {}
-""")
-
-t.write("include/dir/header.h", "")
-
-t.run_build_system()
-t.expect_addition("bin/$toolset/debug/main.obj")
-
-t.touch("include/dir/header.h")
-t.run_build_system()
-t.expect_touch("bin/$toolset/debug/main.obj")
+ # Check that main target 'c' was able to find 'x.h' from 'a's dependency
+ # graph.
+ t.expect_addition("bin/$toolset/debug/c.exe")
+
+ # Check handling of first level includes.
+
+ # Both 'a' and 'b' include "a.h" and should be updated.
+ t.touch("a.h")
+ t.run_build_system()
+
+ t.expect_touch("bin/$toolset/debug/a.exe")
+ t.expect_touch("bin/$toolset/debug/a.obj")
+ t.expect_touch("bin/$toolset/debug/a_c.obj")
+ t.expect_touch("bin/$toolset/debug/b.exe")
+ t.expect_touch("bin/$toolset/debug/b.obj")
+ # Now, <dependency> does not add a dependency. It sound weird, but is
+ # intentional. Need to rename <dependency> eventually.
+ #t.expect_touch("bin/$toolset/debug/main-target-c/c.exe")
+ t.ignore("*.tds")
+ t.expect_nothing_more()
+
+ # Only 'a' include <a.h> and should be updated.
+ t.touch("src1/a.h")
+ t.run_build_system()
+
+ t.expect_touch("bin/$toolset/debug/a.exe")
+ t.expect_touch("bin/$toolset/debug/a.obj")
+ t.expect_touch("bin/$toolset/debug/a_c.obj")
+ t.ignore("*.tds")
+ t.expect_nothing_more()
+
+ # "src/a.h" includes "b.h" (in the same dir).
+ t.touch("src1/b.h")
+ t.run_build_system()
+ t.expect_touch("bin/$toolset/debug/a.exe")
+ t.expect_touch("bin/$toolset/debug/a.obj")
+ t.expect_touch("bin/$toolset/debug/a_c.obj")
+ t.ignore("*.tds")
+ t.expect_nothing_more()
+
+ # Included by "src/b.h". We had a bug: file included using double quotes
+ # (e.g. "b.h") was not scanned at all in this case.
+ t.touch("src1/c.h")
+ t.run_build_system()
+ t.expect_touch("bin/$toolset/debug/a.exe")
+
+ t.touch("b.h")
+ t.run_build_system()
+ t.expect_nothing_more()
+
+ # Test dependency on a generated header.
+ #
+ # TODO: we have also to check that generated header is found correctly if
+ # it is different for different subvariants. Lacking any toolset support,
+ # this check will be implemented later.
+ t.touch("x.foo")
+ t.run_build_system()
+ t.expect_touch("bin/$toolset/debug/a.obj")
+ t.expect_touch("bin/$toolset/debug/a_c.obj")
+
+ # Check that generated headers are scanned for dependencies as well.
+ t.touch("src1/z.h")
+ t.run_build_system()
+ t.expect_touch("bin/$toolset/debug/a.obj")
+ t.expect_touch("bin/$toolset/debug/a_c.obj")
+
+ t.cleanup()
+
+
+def test_scanned_includes_with_absolute_paths():
+ """
+ Regression test: on Windows, <includes> with absolute paths were not
+ considered when scanning dependencies.
+
+ """
+ t = BoostBuild.Tester(["-d3", "-d+12"], pass_d0=False)
+
+ t.write("jamroot.jam", """\
+ path-constant TOP : . ;
+ exe app : main.cpp : <include>$(TOP)/include ;
+ """);
+
+ t.write("main.cpp", """\
+ #include <dir/header.h>
+ int main() {}
+ """)
+
+ t.write("include/dir/header.h", "\n")
+
+ t.run_build_system()
+ t.expect_addition("bin/$toolset/debug/main.obj")
+
+ t.touch("include/dir/header.h")
+ t.run_build_system()
+ t.expect_touch("bin/$toolset/debug/main.obj")
 
-t.cleanup()
+ t.cleanup()
+
+
+test_basic()
+test_scanned_includes_with_absolute_paths()
\ No newline at end of file


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk