test_ok2/py/test/config.py.merge.tmp

289 lines
10 KiB
Plaintext
Raw Normal View History

[svn r37269] merging of file:///svn/py/branch/config/py/test/config.py revisions 36936 to 37267: ------------------------------------------------------------------------ r37263 | hpk | 2007-01-24 14:59:20 +0100 (Wed, 24 Jan 2007) | 19 lines * introduce config.initdirect() which should be the central place to perform initialization on remote nodes/sides. * fix --looponfailing (which works nicely now) * have Conftest() be an instance instead of a class-variable (avoid global state) * more thoroughly use the "config.topdir" concept (which is not neccessarily the pkgdir.dirpath()) * on merge_repr don't write values to global defaultconftest module (this gets tests failing that reuse defaultconftest module, but also we want to avoid global state in general) ------------------------------------------------------------------------ r37243 | hpk | 2007-01-24 00:06:24 +0100 (Wed, 24 Jan 2007) | 2 lines small step-wise cleanups ------------------------------------------------------------------------ r37238 | hpk | 2007-01-23 23:09:57 +0100 (Tue, 23 Jan 2007) | 2 lines why do it complicated? ------------------------------------------------------------------------ r37235 | hpk | 2007-01-23 22:25:16 +0100 (Tue, 23 Jan 2007) | 5 lines added get_collector_trail method to get a representation of a collector relative to the topdir. ------------------------------------------------------------------------ r37230 | hpk | 2007-01-23 20:44:22 +0100 (Tue, 23 Jan 2007) | 2 lines typo-level fixes ------------------------------------------------------------------------ r37193 | hpk | 2007-01-23 14:53:17 +0100 (Tue, 23 Jan 2007) | 5 lines introduced config.topdir, tests and use it from terminal/remote at least. also fix fijal's "--box" option handling a bit, but i am not sure it should stay this way at all. ------------------------------------------------------------------------ r37172 | fijal | 2007-01-23 11:26:10 +0100 (Tue, 23 Jan 2007) | 2 lines Boxing implies lsession ------------------------------------------------------------------------ r37114 | hpk | 2007-01-22 02:20:30 +0100 (Mon, 22 Jan 2007) | 6 lines streamlining initial construction of collectors (to unify topdir/pkgdir/collector handling in rsession/terminal/normal) still work in-progress with a skipped test ------------------------------------------------------------------------ r37112 | hpk | 2007-01-22 01:07:09 +0100 (Mon, 22 Jan 2007) | 3 lines * moving towards a common rootdir/root collector * adding an xxxed test ------------------------------------------------------------------------ r37110 | hpk | 2007-01-22 00:39:24 +0100 (Mon, 22 Jan 2007) | 2 lines renaming some variables for more clarity ------------------------------------------------------------------------ r37077 | hpk | 2007-01-20 22:26:52 +0100 (Sat, 20 Jan 2007) | 2 lines cleaning up fixoptions() a bit ------------------------------------------------------------------------ r37076 | hpk | 2007-01-20 22:19:42 +0100 (Sat, 20 Jan 2007) | 2 lines unskip exec and looponfailing tests, fixes for that ------------------------------------------------------------------------ r37075 | hpk | 2007-01-20 21:51:18 +0100 (Sat, 20 Jan 2007) | 2 lines remove two debug prints ------------------------------------------------------------------------ r37074 | hpk | 2007-01-20 21:43:52 +0100 (Sat, 20 Jan 2007) | 9 lines * config.initsession() deals with getting at a session class and initiliazing it * config._getcollector(path) gets a collector pointing to path * added lots of tests * thus remove the strange getfscollector and map2colitems logic * mark some tkinter tests as skipped * fixing things all around ------------------------------------------------------------------------ r37065 | arigo | 2007-01-20 17:15:10 +0100 (Sat, 20 Jan 2007) | 3 lines Choose a random free port when using the --runbrowser option, but stick to the fixed 8000 when using --startserver only. ------------------------------------------------------------------------ r37061 | hpk | 2007-01-20 16:29:25 +0100 (Sat, 20 Jan 2007) | 8 lines refactoring/fixing the remote terminal approach (used for --exec and --looponfailing) to use the new configiguration. Removes lots of strange code. XXX there are still some recursive testing issues. ------------------------------------------------------------------------ r37055 | hpk | 2007-01-20 12:51:54 +0100 (Sat, 20 Jan 2007) | 4 lines reintroducing --session to lookup custom session objects in conftests.py there is no other way to override a session object from conftests. ------------------------------------------------------------------------ r37025 | hpk | 2007-01-19 17:59:50 +0100 (Fri, 19 Jan 2007) | 2 lines remove lget and its last usage (which was a bit random) ------------------------------------------------------------------------ r37020 | hpk | 2007-01-19 17:48:15 +0100 (Fri, 19 Jan 2007) | 3 lines switching in the new way of getting to a sessionclass, removing code in cmdline.py and elsewhere accordingly ------------------------------------------------------------------------ r37013 | hpk | 2007-01-19 17:14:11 +0100 (Fri, 19 Jan 2007) | 2 lines somewhat simpler lookup mechanism for sessions ------------------------------------------------------------------------ r37009 | hpk | 2007-01-19 16:50:32 +0100 (Fri, 19 Jan 2007) | 2 lines adding a config method to determine the session name ------------------------------------------------------------------------ r36994 | fijal | 2007-01-19 15:08:16 +0100 (Fri, 19 Jan 2007) | 2 lines removal of some trailing white-spaces. ------------------------------------------------------------------------ r36964 | hpk | 2007-01-18 19:30:02 +0100 (Thu, 18 Jan 2007) | 8 lines move rconfig functionality to general Config object, with docstrings, and trying to change rsession accordingly. note that it's called "make_repr" and "merge_repr" the latter to make it obvious that we are changing the instance with the given repr. ------------------------------------------------------------------------ r36942 | hpk | 2007-01-18 16:08:06 +0100 (Thu, 18 Jan 2007) | 4 lines group things used for testing and not use non-underscore names (otherwise they are consdiered public and are possibly seen from apigen through py.test.config!) ------------------------------------------------------------------------ r36941 | fijal | 2007-01-18 15:59:08 +0100 (Thu, 18 Jan 2007) | 2 lines Add a hack which allows to temporarily overwrite the config value. ------------------------------------------------------------------------ r36937 | fijal | 2007-01-18 14:22:54 +0100 (Thu, 18 Jan 2007) | 2 lines Create a branch for further config cleanups. ------------------------------------------------------------------------ --HG-- branch : trunk
2007-01-25 00:39:42 +08:00
from __future__ import generators
import py
from conftesthandle import Conftest
optparse = py.compat.optparse
# XXX move to Config class
basetemp = None
def ensuretemp(string, dir=1):
""" return temporary directory path with
the given string as the trailing part.
"""
global basetemp
if basetemp is None:
basetemp = py.path.local.make_numbered_dir(prefix='pytest-')
return basetemp.ensure(string, dir=dir)
class CmdOptions(object):
""" pure container instance for holding cmdline options
as attributes.
"""
def __repr__(self):
return "<CmdOptions %r>" %(self.__dict__,)
class Config(object):
""" central hub for dealing with configuration/initialization data. """
Option = optparse.Option
def __init__(self):
self.option = CmdOptions()
self._parser = optparse.OptionParser(
usage="usage: %prog [options] [query] [filenames of tests]")
self.conftest = Conftest()
self._initialized = False
self._overwrite_dict = {}
def parse(self, args):
""" parse cmdline arguments into this config object.
Note that this can only be called once per testing process.
"""
assert not self._initialized, (
"can only parse cmdline args once per Config object")
self._initialized = True
self.conftest.setinitial(args)
self.conftest.rget('adddefaultoptions')()
args = [str(x) for x in args]
cmdlineoption, args = self._parser.parse_args(args)
self.option.__dict__.update(vars(cmdlineoption))
fixoptions(self.option) # XXX fixing should be moved to sessions
if not args:
args.append(py.std.os.getcwd())
self.topdir = gettopdir(args)
self.args = args
def initdirect(self, topdir, repr, coltrails=None):
assert not self._initialized
self._initialized = True
self.topdir = py.path.local(topdir)
self.merge_repr(repr)
self._coltrails = coltrails
def getcolitems(self):
""" return initial collectors. """
trails = getattr(self, '_coltrails', None)
return [self._getcollector(path) for path in (trails or self.args)]
def _getcollector(self, path):
if isinstance(path, tuple):
relpath, names = path
fspath = self.topdir.join(relpath)
col = self._getcollector(fspath)
else:
path = py.path.local(path)
assert path.check(), "%s: path does not exist" %(path,)
col = self._getrootcollector(path)
names = path.relto(col.fspath).split(path.sep)
return col.getitembynames(names)
def _getrootcollector(self, path):
pkgpath = path.pypkgpath()
if pkgpath is None:
pkgpath = path.check(file=1) and path.dirpath() or path
col = self.conftest.rget("Directory", pkgpath)(pkgpath)
col.config = self
return col
def addoptions(self, groupname, *specs):
""" add a named group of options to the current testing session.
This function gets invoked during testing session initialization.
"""
optgroup = optparse.OptionGroup(self._parser, groupname)
optgroup.add_options(specs)
self._parser.add_option_group(optgroup)
for opt in specs:
if hasattr(opt, 'default') and opt.dest:
setattr(self.option, opt.dest, opt.default)
return self.option
def getvalue(self, name, path=None):
""" return 'name' value looked up from the first conftest file
found up the path (including the path itself).
if path is None, lookup the value in the initial
conftest modules found during command line parsing.
"""
try:
return self._overwrite_dict[name]
except KeyError:
return self.conftest.rget(name, path)
def initsession(self):
""" return an initialized session object. """
cls = self._getsessionclass()
session = cls(self)
#session.fixoptions()
return session
def _getsessionclass(self):
""" return Session class determined from cmdline options
and looked up in initial config modules.
"""
if self.option.session is not None:
return self.conftest.rget(self.option.session)
else:
name = self._getsessionname()
importpath = globals()[name]
mod = __import__(importpath, None, None, '__doc__')
return getattr(mod, name)
def _getsessionname(self):
""" return default session name as determined from options. """
name = 'TerminalSession'
if self.option.dist:
name = 'RSession'
elif self.option.tkinter:
name = 'TkinterSession'
else:
optnames = 'startserver runbrowser apigen restreport boxing'.split()
for opt in optnames:
if getattr(self.option, opt, False):
name = 'LSession'
break
else:
if self.getvalue('dist_boxing'):
name = 'LSession'
if self.option.looponfailing:
name = 'RemoteTerminalSession'
elif self.option.executable:
name = 'RemoteTerminalSession'
return name
def is_boxed(self):
# XXX probably not a good idea to have this special function ...
return self.option.boxing or self.getvalue("dist_boxing")
def _reparse(self, args):
""" this is used from tests that want to re-invoke parse(). """
global config_per_process
oldconfig = py.test.config
try:
config_per_process = py.test.config = Config()
config_per_process.parse(args)
return config_per_process
finally:
config_per_process = py.test.config = oldconfig
def _overwrite(self, name, value):
""" this is used from tests to overwrite values irrespectives of conftests.
"""
self._overwrite_dict[name] = value
def make_repr(self, conftestnames, optnames=None):
""" return a marshallable representation
of conftest and cmdline options.
if optnames is None, all options
on self.option will be transferred.
"""
conftestdict = {}
for name in conftestnames:
value = self.getvalue(name)
checkmarshal(name, value)
conftestdict[name] = value
cmdlineopts = {}
if optnames is None:
optnames = dir(self.option)
for name in optnames:
if not name.startswith("_"):
value = getattr(self.option, name)
checkmarshal(name, value)
cmdlineopts[name] = value
l = []
for path in self.args:
path = py.path.local(path)
l.append(path.relto(self.topdir))
return l, conftestdict, cmdlineopts
def merge_repr(self, repr):
""" merge in the conftest and cmdline option values
found in the given representation (produced
by make_repr above).
The repr-contained conftest values are
stored on the default conftest module (last
priority) and the cmdline options on self.option.
"""
class override:
def __init__(self, d):
self.__dict__.update(d)
args, conftestdict, cmdlineopts = repr
self.args = [self.topdir.join(x) for x in args]
self.conftest.setinitial(self.args)
self.conftest._path2confmods[None].append(override(conftestdict))
for name, val in cmdlineopts.items():
setattr(self.option, name, val)
def get_collector_trail(self, collector):
""" provide a trail relative to the topdir,
which can be used to reconstruct the
collector (possibly on a different host
starting from a different topdir).
"""
chain = collector.listchain()
relpath = chain[0].fspath.relto(self.topdir)
if not relpath:
if chain[0].fspath == self.topdir:
relpath = "."
else:
raise ValueError("%r not relative to %s"
%(chain[0], self.topdir))
return relpath, tuple([x.name for x in chain[1:]])
# this is the one per-process instance of py.test configuration
config_per_process = Config()
# default import paths for sessions
TkinterSession = 'py.__.test.tkinter.reportsession'
TerminalSession = 'py.__.test.terminal.terminal'
TerminalSession = 'py.__.test.terminal.terminal'
RemoteTerminalSession = 'py.__.test.terminal.remote'
RSession = 'py.__.test.rsession.rsession'
LSession = 'py.__.test.rsession.rsession'
#
# helpers
#
def checkmarshal(name, value):
try:
py.std.marshal.dumps(value)
except ValueError:
raise ValueError("%s=%r is not marshallable" %(name, value))
def fixoptions(option):
""" sanity checks and making option values canonical. """
# implied options
if option.usepdb:
if not option.nocapture:
#print "--pdb implies --nocapture"
option.nocapture = True
if option.runbrowser and not option.startserver:
#print "--runbrowser implies --startserver"
option.startserver = True
# conflicting options
if option.looponfailing and option.usepdb:
raise ValueError, "--looponfailing together with --pdb not supported."
if option.looponfailing and option.dist:
raise ValueError, "--looponfailing together with --dist not supported."
if option.executable and option.usepdb:
raise ValueError, "--exec together with --pdb not supported."
def gettopdir(args):
""" return the top directory for the given paths.
if the common base dir resides in a python package
parent directory of the root package is returned.
"""
args = [py.path.local(arg) for arg in args]
p = reduce(py.path.local.common, args)
assert p, "cannot determine common basedir of %s" %(args,)
pkgdir = p.pypkgpath()
if pkgdir is None:
return p
else:
return pkgdir.dirpath()