Add a local copy of unittest.py so it doesn't have to be downloaded.
authorstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Tue, 17 Jul 2001 18:31:38 +0000 (18:31 +0000)
committerstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Tue, 17 Jul 2001 18:31:38 +0000 (18:31 +0000)
git-svn-id: http://scons.tigris.org/svn/scons/trunk@9 fdb21ef1-2011-0410-befe-b5e4ea1792b1

Construct
TestCmd.py [deleted file]

index 4cc3c460a0e2ad2b7012b1051b8b1b5a448f87ed..43940fc9104b2cd8cb14892487fba516c1444a68 100644 (file)
--- a/Construct
+++ b/Construct
@@ -86,16 +86,30 @@ Command $env [@test_files], $tar_gz, qq(
     tar zxf %< -C $test_dir
 );
 
-Install $env $test_dir, "TestCmd.py";
+Export qw( env test_dir );
+
+Build "aux/Conscript";
 
 #
 # If we're running in the actual Aegis project, pack up a complete
 # source .tar.gz from the project files and files in the change,
 # so we can share it with helpful developers who don't use Aegis.
 #
-eval '@src_files = grep($_ !~ /\.(aeignore|consign)$/ && ! $seen{$_}++,
+# First, lie and say that we've seen any files removed by this
+# change, so they don't get added to the source files list
+# that goes into the archive.
+#
+
+foreach (`aegis -list cf 2>/dev/null`) {
+    $seen{"$1\n"}++ if /^source\s+remove\s.*\s(\S+)$/;
+}
+
+eval '@src_files = grep(! $seen{$_}++,
                    `aegis -list -terse pf 2>/dev/null`,
                    `aegis -list -terse cf 2>/dev/null`)';
+
+@src_files = grep($_ !~ /(\.aeignore|\.consign)$/, @src_files);
+
 if (@src_files) {
     chomp(@src_files);
 
diff --git a/TestCmd.py b/TestCmd.py
deleted file mode 100644 (file)
index 438bbed..0000000
+++ /dev/null
@@ -1,551 +0,0 @@
-"""
-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.
-
-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.
-
-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).
-"""
-
-# Copyright 2000 Steven Knight
-# This module is free software, and you may redistribute it and/or modify
-# it under the same terms as Python itself, so long as this copyright message
-# and disclaimer are retained in their original form.
-#
-# IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
-# SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF
-# THIS CODE, EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
-# DAMAGE.
-#
-# THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-# PARTICULAR PURPOSE.  THE CODE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS,
-# AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
-# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
-
-from string import join, split
-
-__author__ = "Steven Knight <knight@baldmt.com>"
-__revision__ = "TestCmd.py 0.D001 2001/01/14 00:43:41 software"
-__version__ = "0.01"
-
-from types import *
-
-import FCNTL
-import os
-import os.path
-import popen2
-import re
-import shutil
-import stat
-import sys
-import tempfile
-import traceback
-
-tempfile.template = 'testcmd.'
-
-_Cleanup = []
-
-def _clean():
-    global _Cleanup
-    list = _Cleanup[:]
-    _Cleanup = []
-    list.reverse()
-    for test in list:
-       test.cleanup()
-
-sys.exitfunc = _clean
-
-def _caller(tblist, skip):
-    string = ""
-    arr = []
-    for file, line, name, text in tblist:
-       if file[-10:] == "TestCmd.py":
-               break
-       arr = [(file, line, name, text)] + arr
-    atfrom = "at"
-    for file, line, name, text in arr[skip:]:
-       if name == "?":
-           name = ""
-       else:
-           name = " (" + name + ")"
-       string = string + ("%s line %d of %s%s\n" % (atfrom, line, file, name))
-       atfrom = "\tfrom"
-    return string
-
-def fail_test(self = None, condition = 1, 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.
-    """
-    if not condition:
-       return
-    if not function is None:
-       function()
-    of = ""
-    desc = ""
-    sep = " "
-    if not self is None:
-       if self.program:
-           of = " of " + self.program
-           sep = "\n\t"
-       if self.description:
-           desc = " [" + self.description + "]"
-           sep = "\n\t"
-
-    at = _caller(traceback.extract_stack(), skip)
-    sys.stderr.write("FAILED test" + of + desc + sep + at)
-
-    sys.exit(1)
-
-def no_result(self = None, condition = 1, 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.
-    """
-    if not condition:
-       return
-    if not function is None:
-       function()
-    of = ""
-    desc = ""
-    sep = " "
-    if not self is None:
-       if self.program:
-           of = " of " + self.program
-           sep = "\n\t"
-       if self.description:
-           desc = " [" + self.description + "]"
-           sep = "\n\t"
-
-    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):
-    """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.
-    """
-    if not condition:
-       return
-    if not function is None:
-       function()
-    sys.stderr.write("PASSED\n")
-    sys.exit(0)
-
-def match_exact(lines = None, matches = None):
-    """
-    """
-    if not type(lines) is ListType:
-       lines = split(lines, "\n")
-    if not type(matches) is ListType:
-       matches = split(matches, "\n")
-    if len(lines) != len(matches):
-       return
-    for i in range(len(lines)):
-       if lines[i] != matches[i]:
-           return
-    return 1
-
-def match_re(lines = None, res = None):
-    """
-    """
-    if not type(lines) is ListType:
-       lines = split(lines, "\n")
-    if not type(res) is ListType:
-       res = split(res, "\n")
-    if len(lines) != len(res):
-       return
-    for i in range(len(lines)):
-       if not re.compile("^" + res[i] + "$").search(lines[i]):
-           return
-    return 1
-
-class TestCmd:
-    """Class TestCmd
-    """
-
-    def __init__(self, description = None,
-                       program = None,
-                       interpreter = None,
-                       workdir = None,
-                       subdir = None,
-                       verbose = 0,
-                       match = None):
-       self._cwd = os.getcwd()
-       self.description_set(description)
-       self.program_set(program)
-       self.interpreter_set(interpreter)
-       self.verbose_set(verbose)
-       if not match is None:
-           self.match_func = match
-       else:
-           self.match_func = match_re
-       self._dirlist = []
-       self._preserve = {'pass_test': 0, 'fail_test': 0, 'no_result': 0}
-       if os.environ.has_key('PRESERVE') and not os.environ['PRESERVE'] is '':
-           self._preserve['pass_test'] = os.environ['PRESERVE']
-           self._preserve['fail_test'] = os.environ['PRESERVE']
-           self._preserve['no_result'] = os.environ['PRESERVE']
-       else:
-           try:
-               self._preserve['pass_test'] = os.environ['PRESERVE_PASS']
-           except KeyError:
-               pass
-           try:
-               self._preserve['fail_test'] = os.environ['PRESERVE_FAIL']
-           except KeyError:
-               pass
-           try:
-               self._preserve['no_result'] = os.environ['PRESERVE_NO_RESULT']
-           except KeyError:
-               pass
-       self._stdout = []
-       self._stderr = []
-       self.status = None
-       self.condition = 'no_result'
-       self.workdir_set(workdir)
-       self.subdir(subdir)
-
-    def __del__(self):
-       self.cleanup()
-
-    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.
-       """
-       if not self._dirlist:
-           return
-       if condition is None:
-           condition = self.condition
-       #print "cleanup(" + condition + "):  ", self._preserve
-       if self._preserve[condition]:
-           return
-       os.chdir(self._cwd)
-       self.workdir = None
-       list = self._dirlist[:]
-       self._dirlist = []
-       list.reverse()
-       for dir in list:
-           self.writable(dir, 1)
-           shutil.rmtree(dir, ignore_errors = 1)
-       try:
-           global _Cleanup
-           _Cleanup.remove(self)
-       except (AttributeError, ValueError):
-           pass
-
-    def description_set(self, description):
-       """Set the description of the functionality being tested.
-       """
-       self.description = description
-
-#    def diff(self):
-#      """Diff two arrays.
-#      """
-
-    def fail_test(self, condition = 1, function = None, skip = 0):
-       """Cause the test to fail.
-       """
-       if not condition:
-           return
-       self.condition = 'fail_test'
-       fail_test(self = self,
-                 condition = condition,
-                 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.
-       """
-       return self.match_func(lines, matches)
-
-    def match_exact(self, lines, matches):
-       """Compare actual and expected file contents.
-       """
-       return match_exact(lines, matches)
-
-    def match_re(self, lines, res):
-       """Compare actual and expected file contents.
-       """
-       return match_re(lines, res)
-
-    def no_result(self, condition = 1, function = None, skip = 0):
-       """Report that the test could not be run.
-       """
-       if not condition:
-           return
-       self.condition = 'no_result'
-       no_result(self = self,
-                 condition = condition,
-                 function = function,
-                 skip = skip)
-
-    def pass_test(self, condition = 1, function = None):
-       """Cause the test to pass.
-       """
-       if not condition:
-           return
-       self.condition = 'pass_test'
-       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.
-       """
-       if conditions is ():
-           conditions = ('pass_test', 'fail_test', 'no_result')
-       for cond in conditions:
-           self._preserve[cond] = 1
-
-    def program_set(self, program):
-       """Set the executable program or script to be tested.
-       """
-       if program and not os.path.isabs(program):
-           program = os.path.join(self._cwd, program)
-       self.program = program
-
-    def read(self, file):
-       """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.
-       """
-       if type(file) is ListType:
-           file = apply(os.path.join, tuple(file))
-       if not os.path.isabs(file):
-           file = os.path.join(self.workdir, file)
-       f = os.fdopen(os.open(file, FCNTL.O_RDONLY))
-       contents = f.read()
-       f.close()
-       return contents
-
-    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.
-       """
-       if chdir:
-           oldcwd = os.getcwd()
-           if not os.path.isabs(chdir):
-               chdir = os.path.join(self.workpath(chdir))
-           if self.verbose:
-               sys.stderr.write("chdir(" + chdir + ")\n")
-           os.chdir(chdir)
-       cmd = None
-       if program:
-           if not os.path.isabs(program):
-               program = os.path.join(self._cwd, program)
-           cmd = program
-           if interpreter:
-               cmd = interpreter + " " + cmd
-       else:
-           cmd = self.program
-           if self.interpreter:
-               cmd =  self.interpreter + " " + cmd
-       if arguments:
-           cmd = cmd + " " + arguments
-       if self.verbose:
-           sys.stderr.write(cmd + "\n")
-       p = popen2.Popen3(cmd, 1)
-       if stdin:
-           if type(stdin) is ListType:
-               for line in stdin:
-                   p.tochild.write(line)
-           else:
-               p.tochild.write(stdin)
-       p.tochild.close()
-       self._stdout.append(p.fromchild.read())
-       self._stderr.append(p.childerr.read())
-       self.status = p.wait()
-       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.
-       """
-       if not run:
-           run = len(self._stderr)
-       elif run < 0:
-           run = len(self._stderr) + run
-       run = run - 1
-       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.
-       """
-       if not run:
-           run = len(self._stdout)
-       elif run < 0:
-           run = len(self._stdout) + run
-       run = run - 1
-       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:
-
-               test.subdir('sub', ['sub', 'dir'], ['sub', 'dir', 'ectory'])
-
-       Returns the number of subdirectories actually created.
-       """
-       count = 0
-       for sub in subdirs:
-           if sub is None:
-               continue
-           if type(sub) is ListType:
-               sub = apply(os.path.join, tuple(sub))
-           new = os.path.join(self.workdir, sub)
-           try:
-               os.mkdir(new)
-           except:
-               pass
-           else:
-               count = count + 1
-       return count
-
-    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.
-       """
-       if (path != None):
-           if path == '':
-               path = tempfile.mktemp()
-           if path != None:
-               os.mkdir(path)
-           self._dirlist.append(path)
-           global _Cleanup
-           try:
-               _Cleanup.index(self)
-           except ValueError:
-               _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.
-           cwd = os.getcwd()
-           os.chdir(path)
-           self.workdir = os.getcwd()
-           os.chdir(cwd)
-       else:
-           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.
-       """
-       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).
-       """
-
-       def _walk_chmod(arg, dirname, names):
-           st = os.stat(dirname)
-           os.chmod(dirname, arg(st[stat.ST_MODE]))
-           for name in names:
-               n = os.path.join(dirname, name)
-               st = os.stat(n)
-               os.chmod(n, arg(st[stat.ST_MODE]))
-
-       def _mode_writable(mode):
-           return stat.S_IMODE(mode|0200)
-
-       def _mode_non_writable(mode):
-           return stat.S_IMODE(mode&~0200)
-
-       if write:
-           f = _mode_writable
-       else:
-           f = _mode_non_writable
-       os.path.walk(top, _walk_chmod, f)
-
-    def write(self, file, content):
-       """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.  """
-       if type(file) is ListType:
-           file = apply(os.path.join, tuple(file))
-       if not os.path.isabs(file):
-           file = os.path.join(self.workdir, file)
-       fd = os.open(file, FCNTL.O_CREAT|FCNTL.O_WRONLY)
-       os.write(fd, content)
-       os.close(fd)