$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
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