|
Boost-Commit : |
From: jurko.gospodnetic_at_[hidden]
Date: 2008-05-01 13:04:22
Author: jurko
Date: 2008-05-01 13:04:22 EDT (Thu, 01 May 2008)
New Revision: 44981
URL: http://svn.boost.org/trac/boost/changeset/44981
Log:
Added explanation comments for match_exact() and match_re() functions in tools/build/v2/test/TestCmd.py. Removed corpse interpreted member from the TescCmd class and the related setter function in tools/build/v2/test/TestCmd.py. Minor stylistic comment changes.
Text files modified:
trunk/tools/build/v2/test/TestCmd.py | 261 ++++++++++++++++++---------------------
1 files changed, 118 insertions(+), 143 deletions(-)
Modified: trunk/tools/build/v2/test/TestCmd.py
==============================================================================
--- trunk/tools/build/v2/test/TestCmd.py (original)
+++ trunk/tools/build/v2/test/TestCmd.py 2008-05-01 13:04:22 EDT (Thu, 01 May 2008)
@@ -1,28 +1,26 @@
"""
TestCmd.py: a testing framework for commands and scripts.
-The TestCmd module provides a framework for portable automated testing
-of executable commands and scripts (in any language, not just Python),
-especially commands and scripts that require file system interaction.
+The TestCmd module provides a framework for portable automated testing of
+executable commands and scripts (in any language, not just Python), especially
+commands and scripts that require file system interaction.
In addition to running tests and evaluating conditions, the TestCmd module
-manages and cleans up one or more temporary workspace directories, and
-provides methods for creating files and directories in those workspace
-directories from in-line data, here-documents), allowing tests to be
-completely self-contained.
+manages and cleans up one or more temporary workspace directories, and provides
+methods for creating files and directories in those workspace directories from
+in-line data, here-documents), allowing tests to be completely self-contained.
A TestCmd environment object is created via the usual invocation:
test = TestCmd()
-The TestCmd module provides pass_test(), fail_test(), and no_result()
-unbound methods that report test results for use with the Aegis change
-management system. These methods terminate the test immediately,
-reporting PASSED, FAILED, or NO RESULT respectively, and exiting with
-status 0 (success), 1 or 2 respectively. This allows for a distinction
-between an actual failed test and a test that could not be properly
-evaluated because of an external condition (such as a full file system
-or incorrect permissions).
+The TestCmd module provides pass_test(), fail_test(), and no_result() unbound
+methods that report test results for use with the Aegis change management
+system. These methods terminate the test immediately, reporting PASSED, FAILED
+or NO RESULT respectively and exiting with status 0 (success), 1 or 2
+respectively. This allows for a distinction between an actual failed test and a
+test that could not be properly evaluated because of an external condition (such
+as a full file system or incorrect permissions).
"""
# Copyright 2000 Steven Knight
@@ -67,6 +65,7 @@
import tempfile
import traceback
+
tempfile.template = 'testcmd.'
_Cleanup = []
@@ -81,6 +80,7 @@
sys.exitfunc = _clean
+
def caller(tblist, skip):
string = ""
arr = []
@@ -98,12 +98,13 @@
atfrom = "\tfrom"
return string
-def fail_test(self = None, condition = 1, function = None, skip = 0):
+
+def fail_test(self=None, condition=True, function=None, skip=0):
"""Cause the test to fail.
- By default, the fail_test() method reports that the test FAILED
- and exits with a status of 1. If a condition argument is supplied,
- the test fails only if the condition is true.
+ By default, the fail_test() method reports that the test FAILED and exits
+ with a status of 1. If a condition argument is supplied, the test fails only
+ if the condition is true.
"""
if not condition:
return
@@ -124,15 +125,15 @@
sys.stderr.write("FAILED test" + of + desc + sep + at + """
in directory: """ + os.getcwd() )
-
sys.exit(1)
-def no_result(self = None, condition = 1, function = None, skip = 0):
+
+def no_result(self=None, condition=True, function=None, skip=0):
"""Causes a test to exit with no valid result.
- By default, the no_result() method reports NO RESULT for the test
- and exits with a status of 2. If a condition argument is supplied,
- the test fails only if the condition is true.
+ By default, the no_result() method reports NO RESULT for the test and exits
+ with a status of 2. If a condition argument is supplied, the test fails only
+ if the condition is true.
"""
if not condition:
return
@@ -151,15 +152,15 @@
at = caller(traceback.extract_stack(), skip)
sys.stderr.write("NO RESULT for test" + of + desc + sep + at)
-
sys.exit(2)
-def pass_test(self = None, condition = 1, function = None):
+
+def pass_test(self=None, condition=True, function=None):
"""Causes a test to pass.
- By default, the pass_test() method reports PASSED for the test
- and exits with a status of 0. If a condition argument is supplied,
- the test passes only if the condition is true.
+ By default, the pass_test() method reports PASSED for the test and exits
+ with a status of 0. If a condition argument is supplied, the test passes
+ only if the condition is true.
"""
if not condition:
return
@@ -168,8 +169,10 @@
sys.stderr.write("PASSED\n")
sys.exit(0)
-def match_exact(lines = None, matches = None):
- """
+
+def match_exact(lines=None, matches=None):
+ """Returns whether the given lists or strings containing lines separated
+ using newline characters contain exactly the same data.
"""
if not type(lines) is ListType:
lines = split(lines, "\n")
@@ -182,8 +185,11 @@
return
return 1
-def match_re(lines = None, res = None):
- """
+
+def match_re(lines=None, res=None):
+ """Given lists or strings contain lines separated using newline characters.
+ This function matches those lines one by one, interpreting the lines in the
+ res parameter as regular expressions.
"""
if not type(lines) is ListType:
lines = split(lines, "\n")
@@ -196,25 +202,20 @@
return
return 1
+
class TestCmd:
- """Class TestCmd
+ """Class TestCmd.
"""
- def __init__(self, description = None,
- program = None,
- interpreter = None,
- workdir = None,
- subdir = None,
- verbose = 0,
- match = None,
- inpath = None):
+ def __init__(self, description=None, program=None, workdir=None,
+ subdir=None, verbose=False, match=None, inpath=None):
+
self._cwd = os.getcwd()
self.description_set(description)
if inpath:
self.program = program
else:
self.program_set(program)
- self.interpreter_set(interpreter)
self.verbose_set(verbose)
if not match is None:
self.match_func = match
@@ -252,20 +253,20 @@
def __repr__(self):
return "%x" % id(self)
- def cleanup(self, condition = None):
- """Removes any temporary working directories for the specified
- TestCmd environment. If the environment variable PRESERVE was
- set when the TestCmd environment was created, temporary working
- directories are not removed. If any of the environment variables
- PRESERVE_PASS, PRESERVE_FAIL, or PRESERVE_NO_RESULT were set
- when the TestCmd environment was created, then temporary working
- directories are not removed if the test passed, failed, or had
- no result, respectively. Temporary working directories are also
- preserved for conditions specified via the preserve method.
-
- Typically, this method is not called directly, but is used when
- the script exits to clean up temporary working directories as
- appropriate for the exit status.
+ def cleanup(self, condition=None):
+ """Removes any temporary working directories for the specified TestCmd
+ environment. If the environment variable PRESERVE was set when the
+ TestCmd environment was created, temporary working directories are not
+ removed. If any of the environment variables PRESERVE_PASS,
+ PRESERVE_FAIL or PRESERVE_NO_RESULT were set when the TestCmd
+ environment was created, then temporary working directories are not
+ removed if the test passed, failed or had no result, respectively.
+ Temporary working directories are also preserved for conditions
+ specified via the preserve method.
+
+ Typically, this method is not called directly, but is used when the
+ script exits to clean up temporary working directories as appropriate
+ for the exit status.
"""
if not self._dirlist:
return
@@ -280,10 +281,10 @@
for dir in list:
self.writable(dir, 1)
shutil.rmtree(dir, ignore_errors = 1)
-
+
self._dirlist = []
self.workdir = None
- os.chdir(self._cwd)
+ os.chdir(self._cwd)
try:
global _Cleanup
_Cleanup.remove(self)
@@ -295,11 +296,7 @@
"""
self.description = description
-# def diff(self):
-# """Diff two arrays.
-# """
-
- def fail_test(self, condition = 1, function = None, skip = 0):
+ def fail_test(self, condition=True, function=None, skip=0):
"""Cause the test to fail.
"""
if not condition:
@@ -310,12 +307,6 @@
function = function,
skip = skip)
- def interpreter_set(self, interpreter):
- """Set the program to be used to interpret the program
- under test as a script.
- """
- self.interpreter = interpreter
-
def match(self, lines, matches):
"""Compare actual and expected file contents.
"""
@@ -331,7 +322,7 @@
"""
return match_re(lines, res)
- def no_result(self, condition = 1, function = None, skip = 0):
+ def no_result(self, condition=True, function=None, skip=0):
"""Report that the test could not be run.
"""
if not condition:
@@ -342,7 +333,7 @@
function = function,
skip = skip)
- def pass_test(self, condition = 1, function = None):
+ def pass_test(self, condition=True, function=None):
"""Cause the test to pass.
"""
if not condition:
@@ -351,11 +342,10 @@
pass_test(self = self, condition = condition, function = function)
def preserve(self, *conditions):
- """Arrange for the temporary working directories for the
- specified TestCmd environment to be preserved for one or more
- conditions. If no conditions are specified, arranges for
- the temporary working directories to be preserved for all
- conditions.
+ """Arrange for the temporary working directories for the specified
+ TestCmd environment to be preserved for one or more conditions. If no
+ conditions are specified, arranges for the temporary working directories
+ to be preserved for all conditions.
"""
if conditions is ():
conditions = ('pass_test', 'fail_test', 'no_result')
@@ -369,13 +359,12 @@
program[0] = os.path.join(self._cwd, program[0])
self.program = program
- def read(self, file, mode = 'rb'):
- """Reads and returns the contents of the specified file name.
- The file name may be a list, in which case the elements are
- concatenated with the os.path.join() method. The file is
- assumed to be under the temporary working directory unless it
- is an absolute path name. The I/O mode for the file may
- be specified; it must begin with an 'r'. The default is
+ def read(self, file, mode='rb'):
+ """Reads and returns the contents of the specified file name. The file
+ name may be a list, in which case the elements are concatenated with the
+ os.path.join() method. The file is assumed to be under the temporary
+ working directory unless it is an absolute path name. The I/O mode for
+ the file may be specified; it must begin with an 'r'. The default is
'rb' (binary read).
"""
if type(file) is ListType:
@@ -386,14 +375,10 @@
raise ValueError, "mode must begin with 'r'"
return open(file, mode).read()
- def run(self, program = None,
- interpreter = None,
- arguments = None,
- chdir = None,
- stdin = None):
- """Runs a test of the program or script for the test
- environment. Standard output and error output are saved for
- future retrieval via the stdout() and stderr() methods.
+ def run(self, program=None, arguments=None, chdir=None, stdin=None):
+ """Runs a test of the program or script for the test environment.
+ Standard output and error output are saved for future retrieval via the
+ stdout() and stderr() methods.
"""
if chdir:
oldcwd = os.getcwd()
@@ -407,12 +392,8 @@
if program[0] != self.program[0] and not os.path.isabs(program[0]):
program[0] = os.path.join(self._cwd, program[0])
cmd += program
- # if interpreter:
- # cmd = interpreter + " " + cmd
else:
cmd += self.program
- # if self.interpreter:
- # cmd = self.interpreter + " " + cmd
if arguments:
cmd += arguments.split(" ")
if self.verbose:
@@ -429,7 +410,7 @@
tochild.write(stdin)
tochild.close()
self._stdout.append(fromchild.read())
- self._stderr.append(childerr.read())
+ self._stderr.append(childerr.read())
fromchild.close()
self.status = childerr.close()
if not self.status:
@@ -447,20 +428,19 @@
self._stdout.append(p.fromchild.read())
self._stderr.append(p.childerr.read())
self.status = p.wait()
-
+
if self.verbose:
sys.stdout.write(self._stdout[-1])
sys.stderr.write(self._stderr[-1])
-
+
if chdir:
os.chdir(oldcwd)
- def stderr(self, run = None):
- """Returns the error output from the specified run number.
- If there is no specified run number, then returns the error
- output of the last run. If the run number is less than zero,
- then returns the error output from that many runs back from the
- current run.
+ def stderr(self, run=None):
+ """Returns the error output from the specified run number. If there is
+ no specified run number, then returns the error output of the last run.
+ If the run number is less than zero, then returns the error output from
+ that many runs back from the current run.
"""
if not run:
run = len(self._stderr)
@@ -471,12 +451,11 @@
return ''
return self._stderr[run]
- def stdout(self, run = None):
- """Returns the standard output from the specified run number.
- If there is no specified run number, then returns the standard
- output of the last run. If the run number is less than zero,
- then returns the standard output from that many runs back from
- the current run.
+ def stdout(self, run=None):
+ """Returns the standard output from the specified run number. If there
+ is no specified run number, then returns the standard output of the last
+ run. If the run number is less than zero, then returns the standard
+ output from that many runs back from the current run.
"""
if not run:
run = len(self._stdout)
@@ -488,11 +467,11 @@
return self._stdout[run]
def subdir(self, *subdirs):
- """Create new subdirectories under the temporary working
- directory, one for each argument. An argument may be a list,
- in which case the list elements are concatenated using the
- os.path.join() method. Subdirectories multiple levels deep
- must be created using a separate argument for each level:
+ """Create new subdirectories under the temporary working directory, one
+ for each argument. An argument may be a list, in which case the list
+ elements are concatenated using the os.path.join() method.
+ Subdirectories multiple levels deep must be created using a separate
+ argument for each level:
test.subdir('sub', ['sub', 'dir'], ['sub', 'dir', 'ectory'])
@@ -514,11 +493,10 @@
return count
def unlink (self, file):
- """Unlinks the specified file name.
- The file name may be a list, in which case the elements are
- concatenated with the os.path.join() method. The file is
- assumed to be under the temporary working directory unless it
- is an absolute path name.
+ """Unlinks the specified file name. The file name may be a list, in
+ which case the elements are concatenated using the os.path.join()
+ method. The file is assumed to be under the temporary working directory
+ unless it is an absolute path name.
"""
if type(file) is ListType:
file = apply(os.path.join, tuple(file))
@@ -526,16 +504,14 @@
file = os.path.join(self.workdir, file)
os.unlink(file)
-
def verbose_set(self, verbose):
"""Set the verbose level.
"""
self.verbose = verbose
def workdir_set(self, path):
- """Creates a temporary working directory with the specified
- path name. If the path is a null string (''), a unique
- directory name is created.
+ """Creates a temporary working directory with the specified path name.
+ If the path is a null string (''), a unique directory name is created.
"""
if os.path.isabs(path):
@@ -554,9 +530,9 @@
_Cleanup.append(self)
# We'd like to set self.workdir like this:
# self.workdir = path
- # But symlinks in the path will report things
- # differently from os.getcwd(), so chdir there
- # and back to fetch the canonical path.
+ # But symlinks in the path will report things differently from
+ # os.getcwd(), so chdir there and back to fetch the canonical
+ # path.
cwd = os.getcwd()
os.chdir(path)
self.workdir = os.getcwd()
@@ -565,16 +541,16 @@
self.workdir = None
def workpath(self, *args):
- """Returns the absolute path name to a subdirectory or file
- within the current temporary working directory. Concatenates
- the temporary working directory name with the specified
- arguments using the os.path.join() method.
+ """Returns the absolute path name to a subdirectory or file within the
+ current temporary working directory. Concatenates the temporary working
+ directory name with the specified arguments using the os.path.join()
+ method.
"""
return apply(os.path.join, (self.workdir,) + tuple(args))
def writable(self, top, write):
- """Make the specified directory tree writable (write == 1)
- or not (write == None).
+ """Make the specified directory tree writable (write == 1) or not
+ (write == None).
"""
def _walk_chmod(arg, dirname, names):
@@ -598,16 +574,15 @@
try:
os.path.walk(top, _walk_chmod, f)
except:
- pass # ignore any problems changing modes
+ pass # Ignore any problems changing modes.
- def write(self, file, content, mode = 'wb'):
- """Writes the specified content text (second argument) to the
- specified file name (first argument). The file name may be
- a list, in which case the elements are concatenated with the
- os.path.join() method. The file is created under the temporary
- working directory. Any subdirectories in the path must already
- exist. The I/O mode for the file may be specified; it must
- begin with a 'w'. The default is 'wb' (binary write).
+ def write(self, file, content, mode='wb'):
+ """Writes the specified content text (second argument) to the specified
+ file name (first argument). The file name may be a list, in which case
+ the elements are concatenated using the os.path.join() method. The file
+ is created under the temporary working directory. Any subdirectories in
+ the path must already exist. The I/O mode for the file may be specified;
+ it must begin with a 'w'. The default is 'wb' (binary write).
"""
if type(file) is ListType:
file = apply(os.path.join, tuple(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