[Zope3-checkins] CVS: Zope3 - test.py:1.26
Barry Warsaw
barry@wooz.org
Thu, 19 Dec 2002 17:23:26 -0500
Update of /cvs-repository/Zope3
In directory cvs.zope.org:/tmp/cvs-serv10538
Modified Files:
test.py
Log Message:
Working code to run the tests from the build directory, and from the
source directory, depending on whether the -b or -B option was given.
If neither was given then we guess based on the existance of
build/lib.<plat>
=== Zope3/test.py 1.25 => 1.26 ===
--- Zope3/test.py:1.25 Thu Dec 19 15:50:19 2002
+++ Zope3/test.py Thu Dec 19 17:23:26 2002
@@ -122,11 +122,11 @@
import unittest
import linecache
import traceback
-from os.path import join, commonprefix
from distutils.util import get_platform
PROGRAM = sys.argv[0]
+PLAT_SPEC = "%s-%s" % (get_platform(), sys.version[0:3])
# For Python's earlier than 2.2.2
try:
@@ -251,12 +251,35 @@
# setup list of directories to put on the path
-def setup_path():
- DIRS = [join('lib','python'),
- ]
- cwd = os.getcwd()
- for d in DIRS:
- sys.path.insert(0, join(cwd, d))
+class PathInit:
+ def __init__(self):
+ self.inplace = None
+ # Figure out if we should test in-place or test in-build. If the -b
+ # or -B option was given, test in the place we were told to build in.
+ # Otherwise, we'll look for a build directory and if we find one,
+ # we'll test there, otherwise we'll test in-place.
+ #
+ # XXX build and build_inplace are globals created in process_args()
+ if build:
+ self.inplace = build_inplace
+ if self.inplace is None:
+ # Need to figure it out
+ if os.path.isdir(os.path.join('build', 'lib.%s' % PLAT_SPEC)):
+ self.inplace = False
+ else:
+ self.inplace = True
+ # Calculate which directories we're going to add to sys.path, and cd
+ # to the appropriate working directory
+ if self.inplace:
+ self.libdir = os.path.join('lib', 'python')
+ else:
+ self.libdir = 'lib.%s' % PLAT_SPEC
+ os.chdir('build')
+ # Hack sys.path
+ self.cwd = os.getcwd()
+ print 'Running tests from', self.cwd
+ sys.path.insert(0, os.path.join(self.cwd, self.libdir))
+
def match(rx, s):
if not rx:
@@ -266,13 +289,14 @@
else:
return re.search(rx, s) is not None
+
class TestFileFinder:
def __init__(self, prefix):
self.files = []
- self.prefix = prefix
+ self._plen = len(prefix)+1
def visit(self, rx, dir, files):
- if not dir.endswith('tests'):
+ if os.path.split(dir)[-1] != 'tests':
return
# ignore tests that aren't in packages
if not "__init__.py" in files:
@@ -280,10 +304,9 @@
return
print "not a package", dir
return
-
# ignore tests when the package can't be imported, possibly due to
# dependency failures.
- pkg = dir[len(self.prefix)+1:].replace(os.sep, '.')
+ pkg = dir[self._plen:].replace(os.sep, '.')
try:
__import__(pkg)
# We specifically do not want to catch ImportError since that's useful
@@ -291,38 +314,38 @@
except RuntimeError, e:
print 'skipping', pkg, 'because:', e
return
-
for file in files:
- if file[:4] == "test" and file[-3:] == ".py":
- path = join(dir, file)
+ if file.startswith('test') and os.path.splitext(file)[-1] == '.py':
+ path = os.path.join(dir, file)
if match(rx, path):
self.files.append(path)
+ def module_from_path(self, path):
+ """Return the Python package name indiciated by the filesystem path."""
+ assert path.endswith('.py')
+ path = path[self._plen:-3]
+ mod = path.replace(os.sep, '.')
+ return mod
+
+
def find_tests(rx):
- prefix = join('lib', 'python')
+ global finder
+ # pathinit is a global created in main()
+ prefix = pathinit.libdir
finder = TestFileFinder(prefix)
os.path.walk(prefix, finder.visit, rx)
return finder.files
+
def package_import(modname):
mod = __import__(modname)
for part in modname.split(".")[1:]:
mod = getattr(mod, part)
return mod
-def module_from_path(path):
- """Return the Python package name indiciated by the filesystem path."""
-
- assert path.endswith('.py')
- path = path[:-3]
- dirs = []
- while path:
- path, end = os.path.split(path)
- dirs.insert(0, end)
- return ".".join(dirs[2:])
def get_suite(file):
- modname = module_from_path(file)
+ modname = finder.module_from_path(file)
try:
mod = package_import(modname)
except ImportError, err:
@@ -340,6 +363,7 @@
return None
return suite_func()
+
def filter_testcases(s, rx):
new = unittest.TestSuite()
for test in s._tests:
@@ -354,8 +378,9 @@
new.addTest(filtered)
return new
+
def gui_runner(files, test_filter):
- sys.path.insert(0, join(os.getcwd(), 'utilities'))
+ sys.path.insert(0, os.path.join(os.getcwd(), 'utilities'))
import unittestgui
suites = []
for file in files:
@@ -365,6 +390,7 @@
minimal = (GUI == 'minimal')
unittestgui.main(suites, minimal)
+
def runner(files, test_filter, debug):
runner = ImmediateTestRunner(verbosity=VERBOSE, debug=debug,
progress=progress)
@@ -384,6 +410,7 @@
else:
raise
+
def remove_stale_bytecode(arg, dirname, names):
names = map(os.path.normcase, names)
for name in names:
@@ -394,9 +421,13 @@
print "Removing stale bytecode file", fullname
os.unlink(fullname)
+
def main(module_filter, test_filter):
+ global pathinit
+
os.path.walk(os.curdir, remove_stale_bytecode, None)
- setup_path()
+ # Initialize the path and cwd
+ pathinit = PathInit()
# Initialize the logging module.
import logging.config
@@ -415,7 +446,7 @@
while 1:
runner(files, test_filter, debug)
elif TRACE:
- coverdir = os.path.join(os.getcwd(),"coverage")
+ coverdir = os.path.join(os.getcwd(), "coverage")
import trace
tracer = trace.Trace(ignoredirs=[sys.prefix, sys.exec_prefix],
trace=0, count=1)
@@ -521,11 +552,11 @@
val |= v
gc.set_debug(v)
- # XXX support not-build-in-place, when we get a setup.py
+ # Do the builds
if build:
- cmd = sys.executable + " stupid_build.py"
- if VERBOSE:
- print cmd
+ cmd = sys.executable + ' setup.py -q build'
+ if build_inplace:
+ cmd += '_ext -i'
sts = os.system(cmd)
if sts:
print "Build failed", hex(sts)
@@ -571,8 +602,6 @@
if line: file.write(' %s\n' % line.strip())
break
-if __name__ == "__main__":
- process_args()
# The following method is for debugging unit tests from a Python prompt:
def debug(args=""):
@@ -581,18 +610,19 @@
Just run the debug function with a string containing command-line
arguments. (The function uses a cheesy parser, aka split. ;)
- For example, to debug the tests in package Zope.App.DublinCore::
+ For example, to debug the tests in package Zope.App.DublinCore:
import test
test.debug('Zope.App.DublinCore')
At the first failure or error, an exception will be raised. At
- that point, you can use pdb's post-mortem debugger::
+ that point, you can use pdb's post-mortem debugger:
import pdb
pdb.pm()
-
"""
-
process_args(["", "-d"] + args.split())
+
+if __name__ == "__main__":
+ process_args()