From fijal at codespeak.net Mon Oct 8 10:19:56 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 8 Oct 2007 10:19:56 +0200 (CEST) Subject: [py-svn] r47277 - py/trunk/py/test Message-ID: <20071008081956.ACCF7815D@code0.codespeak.net> Author: fijal Date: Mon Oct 8 10:19:55 2007 New Revision: 47277 Modified: py/trunk/py/test/reporter.py Log: Argh. Fix -d -x Modified: py/trunk/py/test/reporter.py ============================================================================== --- py/trunk/py/test/reporter.py (original) +++ py/trunk/py/test/reporter.py Mon Oct 8 10:19:55 2007 @@ -311,7 +311,7 @@ self.nodes = event.nodes def was_failure(self): - return len(self.failed) > 0 + return sum(self.failed.values()) > 0 class RemoteReporter(AbstractReporter): def get_item_name(self, event, colitem): From fijal at codespeak.net Fri Oct 19 15:46:12 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 19 Oct 2007 15:46:12 +0200 (CEST) Subject: [py-svn] r47584 - in py/trunk/py/test: . testing Message-ID: <20071019134612.390248132@code0.codespeak.net> Author: fijal Date: Fri Oct 19 15:46:10 2007 New Revision: 47584 Modified: py/trunk/py/test/collect.py py/trunk/py/test/session.py py/trunk/py/test/testing/test_session.py Log: Implement very sophisticated algorith for -k TestClass.test to work Modified: py/trunk/py/test/collect.py ============================================================================== --- py/trunk/py/test/collect.py (original) +++ py/trunk/py/test/collect.py Fri Oct 19 15:46:10 2007 @@ -150,8 +150,8 @@ cur = next return cur - def _haskeyword(self, keyword): - return keyword in self.name + def _keywords(self): + return [self.name] def _getmodpath(self): """ return dotted module path (relative to the containing). """ @@ -176,17 +176,30 @@ if not keyword: return chain = self.listchain() - for key in filter(None, keyword.split()): + for key in filter(None, keyword.split()): eor = key[:1] == '-' if eor: key = key[1:] if not (eor ^ self._matchonekeyword(key, chain)): py.test.skip("test not selected by keyword %r" %(keyword,)) - def _matchonekeyword(self, key, chain): - for subitem in chain: - if subitem._haskeyword(key): - return True + def _matchonekeyword(self, key, chain): + elems = key.split(".") + # XXX O(n^2), anyone cares? + chain = [item._keywords() for item in chain if item._keywords()] + for start, _ in enumerate(chain): + if start + len(elems) > len(chain): + return False + for num, elem in enumerate(elems): + for keyword in chain[num + start]: + ok = False + if elem in keyword: + ok = True + break + if not ok: + break + if num == len(elems) - 1 and ok: + return True return False def _tryiter(self, yieldtype=None): @@ -425,7 +438,9 @@ return self.parent.obj() def Function(self): return getattr(self.obj, 'Function', - Collector.Function.__get__(self)) # XXX for python 2.2 + Collector.Function.__get__(self)) # XXX for python 2.2 + def _keywords(self): + return [] Function = property(Function) Modified: py/trunk/py/test/session.py ============================================================================== --- py/trunk/py/test/session.py (original) +++ py/trunk/py/test/session.py Fri Oct 19 15:46:10 2007 @@ -44,7 +44,7 @@ class Session(AbstractSession): """ - A Session gets test Items from Collectors, # executes the + A Session gets test Items from Collectors, executes the Items and sends the Outcome to the Reporter. """ def shouldclose(self): Modified: py/trunk/py/test/testing/test_session.py ============================================================================== --- py/trunk/py/test/testing/test_session.py (original) +++ py/trunk/py/test/testing/test_session.py Fri Oct 19 15:46:10 2007 @@ -55,20 +55,24 @@ assert not config.option.boxed class TestKeywordSelection: - def test_select_simple(self): - for keyword in ['test_one', 'est_on']: + def test_select_simple(self): + def check(keyword, name): config = py.test.config._reparse([datadir/'filetest.py', - '-k', keyword]) + '-s', '-k', keyword]) session = config._getsessionclass()(config, py.std.sys.stdout) session.main() l = session.getitemoutcomepairs(Failed) assert len(l) == 1 item = l[0][0] - assert item.name == 'test_one' + assert item.name == name l = session.getitemoutcomepairs(Skipped) - assert len(l) == 1 + assert len(l) == 1 + + for keyword in ['test_one', 'est_on']: + check(keyword, 'test_one') + check('TestClass.test', 'test_method_one') - def test_select_extra_keywords(self): + def test_select_extra_keywords(self): o = tmpdir.ensure('selecttest', dir=1) tfile = o.join('test_select.py').write(py.code.Source(""" def test_1(): @@ -80,14 +84,13 @@ conftest = o.join('conftest.py').write(py.code.Source(""" import py class Class(py.test.collect.Class): - def _haskeyword(self, keyword): - return keyword == 'xxx' or \ - super(Class, self)._haskeyword(keyword) + def _keywords(self): + return ['xxx', self.name] """)) for keyword in ('xxx', 'xxx test_2', 'TestClass', 'xxx -test_1', 'TestClass test_2', 'xxx TestClass test_2',): f = py.std.StringIO.StringIO() - config = py.test.config._reparse([o, '-k', keyword]) + config = py.test.config._reparse([o, '-s', '-k', keyword]) session = config._getsessionclass()(config, f) session.main() print "keyword", repr(keyword) From fijal at codespeak.net Sun Oct 21 00:02:05 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 21 Oct 2007 00:02:05 +0200 (CEST) Subject: [py-svn] r47660 - py/branch/reporter-merge Message-ID: <20071020220205.C601E8142@code0.codespeak.net> Author: fijal Date: Sun Oct 21 00:02:04 2007 New Revision: 47660 Added: py/branch/reporter-merge/ - copied from r47659, py/trunk/ Log: Create a new branch for reporter merge From fijal at codespeak.net Sun Oct 21 13:00:20 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 21 Oct 2007 13:00:20 +0200 (CEST) Subject: [py-svn] r47667 - in py/branch/reporter-merge/py/test: . rsession rsession/testing terminal testing Message-ID: <20071021110020.E78048160@code0.codespeak.net> Author: fijal Date: Sun Oct 21 13:00:20 2007 New Revision: 47667 Modified: py/branch/reporter-merge/py/test/collect.py py/branch/reporter-merge/py/test/config.py py/branch/reporter-merge/py/test/outcome.py py/branch/reporter-merge/py/test/repevent.py py/branch/reporter-merge/py/test/reporter.py py/branch/reporter-merge/py/test/representation.py py/branch/reporter-merge/py/test/rsession/master.py py/branch/reporter-merge/py/test/rsession/rsession.py py/branch/reporter-merge/py/test/rsession/testing/basetest.py py/branch/reporter-merge/py/test/rsession/testing/test_master.py py/branch/reporter-merge/py/test/rsession/testing/test_slave.py py/branch/reporter-merge/py/test/session.py py/branch/reporter-merge/py/test/terminal/terminal.py py/branch/reporter-merge/py/test/testing/test_collect.py py/branch/reporter-merge/py/test/testing/test_config.py py/branch/reporter-merge/py/test/testing/test_outcome.py py/branch/reporter-merge/py/test/testing/test_remote.py py/branch/reporter-merge/py/test/testing/test_repevent.py py/branch/reporter-merge/py/test/testing/test_reporter.py py/branch/reporter-merge/py/test/testing/test_repr.py py/branch/reporter-merge/py/test/testing/test_session.py Log: Huge refactoring, the target is unification of session reporters and eventually sessions. Right now there is about 200 lines of code cut, but there is still some code to die and also some features missing :) Modified: py/branch/reporter-merge/py/test/collect.py ============================================================================== --- py/branch/reporter-merge/py/test/collect.py (original) +++ py/branch/reporter-merge/py/test/collect.py Sun Oct 21 13:00:20 2007 @@ -379,7 +379,7 @@ self._obj = obj = self.fspath.pyimport() except KeyboardInterrupt: raise - except: + except: self._stickyfailure = py.std.sys.exc_info() raise return obj Modified: py/branch/reporter-merge/py/test/config.py ============================================================================== --- py/branch/reporter-merge/py/test/config.py (original) +++ py/branch/reporter-merge/py/test/config.py Sun Oct 21 13:00:20 2007 @@ -134,10 +134,10 @@ except AttributeError: return self._conftest.rget(name, path) - def initsession(self): + def initsession(self, reporter=None): """ return an initialized session object. """ cls = self._getsessionclass() - session = cls(self) + session = cls(self, reporter) session.fixoptions() return session Modified: py/branch/reporter-merge/py/test/outcome.py ============================================================================== --- py/branch/reporter-merge/py/test/outcome.py (original) +++ py/branch/reporter-merge/py/test/outcome.py Sun Oct 21 13:00:20 2007 @@ -45,10 +45,9 @@ self.stderr = "" assert bool(self.passed) + bool(excinfo) + bool(skipped) == 1 - def make_excinfo_repr(self, tbstyle): - if self.excinfo is None: - return None - excinfo = self.excinfo + def make_excinfo_repr(self, excinfo, tbstyle): + if excinfo is None or isinstance(excinfo, basestring): + return excinfo tb_info = [self.traceback_entry_repr(x, tbstyle) for x in excinfo.traceback] rec_index = excinfo.traceback.recursionindex() @@ -85,8 +84,9 @@ def make_repr(self, tbstyle="long"): return (self.passed, self.setupfailure, - self.make_excinfo_repr(tbstyle), - self.skipped, self.is_critical, 0, self.stdout, self.stderr) + self.make_excinfo_repr(self.excinfo, tbstyle), + self.make_excinfo_repr(self.skipped, tbstyle), + self.is_critical, 0, self.stdout, self.stderr) class TracebackEntryRepr(object): def __init__(self, tbentry): @@ -136,12 +136,15 @@ class ReprOutcome(object): def __init__(self, repr_tuple): - (self.passed, self.setupfailure, excinfo, self.skipped, + (self.passed, self.setupfailure, excinfo, skipped, self.is_critical, self.signal, self.stdout, self.stderr) = repr_tuple - if excinfo is None: - self.excinfo = None - else: - self.excinfo = ExcInfoRepr(excinfo) + self.excinfo = self.unpack(excinfo) + self.skipped = self.unpack(skipped) + + def unpack(self, what): + if what is None or isinstance(what, basestring): + return what + return ExcInfoRepr(what) def __repr__(self): l = ["%s=%s" %(x, getattr(self, x)) Modified: py/branch/reporter-merge/py/test/repevent.py ============================================================================== --- py/branch/reporter-merge/py/test/repevent.py (original) +++ py/branch/reporter-merge/py/test/repevent.py Sun Oct 21 13:00:20 2007 @@ -97,11 +97,11 @@ self.root = root class TestStarted(ReportEvent): - def __init__(self, hosts, topdir, roots): + def __init__(self, hosts, config, roots): self.hosts = hosts - self.topdir = topdir self.roots = roots self.timestart = time.time() + self.config = config class TestFinished(ReportEvent): def __init__(self): Modified: py/branch/reporter-merge/py/test/reporter.py ============================================================================== --- py/branch/reporter-merge/py/test/reporter.py (original) +++ py/branch/reporter-merge/py/test/reporter.py Sun Oct 21 13:00:20 2007 @@ -11,10 +11,13 @@ from py.__.test import repevent from py.__.test import outcome from py.__.misc.terminal_helper import ansi_print, get_terminal_width -from py.__.test.representation import Presenter +from py.__.test.representation import Presenter, repr_pythonversion,\ + getrelpath import sys +from time import time as now + def choose_reporter(config): option = config.option if option.startserver or option.runbrowser: @@ -79,7 +82,7 @@ print excinfo # XXX reenable test before removing below line and # run it with raise - #raise + raise __call__ = report @@ -130,12 +133,13 @@ print "%15s: READY" % hostrepr def report_TestStarted(self, item): + topdir = item.config.topdir hostreprs = [self._hostrepr(host) for host in item.hosts] txt = " Test started, hosts: %s " % ", ".join(hostreprs) self.hosts_to_rsync = len(item.hosts) self.out.sep("=", txt) self.timestart = item.timestart - self.out.write("local top directory: %s\n" % item.topdir) + self.out.write("local top directory: %s\n" % topdir) for i, root in py.builtin.enumerate(item.roots): outof = "%d/%d" %(i+1, len(item.roots)) self.out.write("local RSync root [%s]: %s\n" % @@ -227,8 +231,8 @@ colitem = event.item if isinstance(event, repevent.ReceivedItemOutcome): outcome = event.outcome - text = outcome.skipped - itemname = self.get_item_name(event, colitem) + text = outcome.skipped.value + itemname = repr(outcome.skipped.traceback[-2]).split("\n")[0] elif isinstance(event, repevent.SkippedTryiter): text = str(event.excinfo.value) itemname = "/".join(colitem.listnames()) @@ -243,7 +247,8 @@ for text, items in texts.items(): for item in items: self.out.line('Skipped in %s' % item) - self.out.line("reason: %s" % text) + self.out.line("reason: %s" % text[1:-1]) + self.out.line() def summary(self): def gather(dic): @@ -263,6 +268,7 @@ total = total_passed + total_failed + total_skipped skipped_str = create_str("skipped", total_skipped) failed_str = create_str("failed", total_failed) + self.out.line() self.print_summary(total, skipped_str, failed_str) def print_summary(self, total, skipped_str, failed_str): @@ -329,9 +335,33 @@ join(event.item.listnames()))) class LocalReporter(AbstractReporter): + def report_TestStarted(self, item): + colitems = item.config.getcolitems() + txt = " test process starts " + self.out.sep("=", txt) + self.timestart = item.timestart + self.out.line("executable: %s (%s)" % + (py.std.sys.executable, repr_pythonversion())) + rev = py.__package__.getrev() + self.out.line("using py lib: %s " % ( + py.path.local(py.__file__).dirpath(), rev)) + config = item.config + if config.option.traceconfig or config.option.verbose: + + for x in colitems: + self.out.line("test target: %s" %(x.fspath,)) + + conftestmodules = config._conftest.getconftestmodules(None) + for i,x in py.builtin.enumerate(conftestmodules): + self.out.line("initial conf %d: %s" %(i, x.__file__)) + def get_item_name(self, event, colitem): return "/".join(colitem.listnames()) - + + def print_summary(self, total, skipped_str, failed_str): + self.out.sep("=", " %d test run%s%s in %.2fs" % + (total, skipped_str, failed_str, self.timeend - self.timestart)) + def report_SkippedTryiter(self, event): #self.show_item(event.item, False) if isinstance(event.item, py.test.collect.Module): @@ -361,24 +391,30 @@ self.out.write("F") def report_ItemStart(self, event): + # XXX + event.item.start = now() self.show_item(event.item) def show_item(self, item, count_elems = True): if isinstance(item, py.test.collect.Module): - # XXX This is a terrible hack, I don't like it - # and will rewrite it at some point - #self.count = 0 - lgt = len(list(item._tryiter())) - #self.lgt = lgt - # print names relative to current workdir - name = "/".join(item.listnames()) - local = str(py.path.local()) - d = str(self.config.topdir) - if local.startswith(d): - local = local[len(d) + 1:] - if local and name.startswith(local): - name = name[len(local) + 1:] - self.out.write("\n%s[%d] " % (name, lgt)) + self.show_Module(item) + if self.config.option.verbose > 0 and\ + isinstance(item, py.test.collect.Item): + self.show_ItemVerbose(item) + + def show_ItemVerbose(self, item): + realpath, lineno = item._getpathlineno() + location = "%s:%d" % (realpath.basename, lineno+1) + self.out.write("%-20s %s " % (location, item._getmodpath())) + + def show_Module(self, mod): + lgt = len(list(mod._tryiter())) + if self.config.option.verbose == 0: + base = getrelpath(py.path.local(), mod.fspath) + self.out.write("\n%s[%d] " % (base, lgt)) + else: + self.out.line() + self.out.line('+ testmodule: %s[%d]' % (mod.fspath, lgt)) def gethost(self, event): return 'localhost' Modified: py/branch/reporter-merge/py/test/representation.py ============================================================================== --- py/branch/reporter-merge/py/test/representation.py (original) +++ py/branch/reporter-merge/py/test/representation.py Sun Oct 21 13:00:20 2007 @@ -8,6 +8,17 @@ import py from py.__.code import safe_repr +def getrelpath(source, dest): + base = source.common(dest) + if not base: + return None + # with posix local paths '/' is always a common base + relsource = source.relto(base) + reldest = dest.relto(base) + n = relsource.count(source.sep) + target = dest.sep.join(('..', )*n + (reldest, )) + return target + class Presenter(object): """ Class used for presentation of various objects, sharing common output style @@ -128,7 +139,7 @@ if index == recursionindex: self.out.line("Recursion detected (same locals & position)") self.out.sep("!") - break + break def repr_failure_tbshort(self, item, excinfo, traceback, out_err_reporter): # print a Python-style short traceback @@ -176,3 +187,11 @@ # the following is only used by the combination '--pdb --tb=no' repr_failure_tbno = repr_failure_tbshort + + +def repr_pythonversion(): + v = py.std.sys.version_info + try: + return "%s.%s.%s-%s-%s" % v + except ValueError: + return str(v) Modified: py/branch/reporter-merge/py/test/rsession/master.py ============================================================================== --- py/branch/reporter-merge/py/test/rsession/master.py (original) +++ py/branch/reporter-merge/py/test/rsession/master.py Sun Oct 21 13:00:20 2007 @@ -41,31 +41,6 @@ # of hanging nodes and such raise -def itemgen(colitems, reporter, keyword=None): - stopitems = py.test.collect.Item # XXX should be generator here as well - for next in colitems: - if isinstance(next, stopitems): - try: - next._skipbykeyword(keyword) - yield next - except Skipped: - excinfo = py.code.ExceptionInfo() - reporter(repevent.SkippedTryiter(excinfo, next)) - else: - reporter(repevent.ItemStart(next)) - try: - for x in itemgen([next.join(x) for x in next.run()], reporter, - keyword): - yield x - except (KeyboardInterrupt, SystemExit, GeneratorExit): - raise - except: - excinfo = py.code.ExceptionInfo() - if excinfo.type is Skipped: - reporter(repevent.SkippedTryiter(excinfo, next)) - else: - reporter(repevent.FailedTryiter(excinfo, next)) - def dispatch_loop(masternodes, itemgenerator, shouldstop, waiter = lambda: py.std.time.sleep(0.1), max_tasks_per_node=None): Modified: py/branch/reporter-merge/py/test/rsession/rsession.py ============================================================================== --- py/branch/reporter-merge/py/test/rsession/rsession.py (original) +++ py/branch/reporter-merge/py/test/rsession/rsession.py Sun Oct 21 13:00:20 2007 @@ -9,12 +9,12 @@ import time from py.__.test import repevent -from py.__.test.rsession.master import MasterNode, dispatch_loop, itemgen +from py.__.test.rsession.master import MasterNode, dispatch_loop from py.__.test.rsession.hostmanage import HostInfo, HostManager from py.__.test.rsession.local import local_loop, plain_runner, apigen_runner,\ box_runner from py.__.test.reporter import LocalReporter, RemoteReporter, TestReporter -from py.__.test.session import AbstractSession +from py.__.test.session import AbstractSession, itemgen from py.__.test.outcome import Skipped, Failed class RSession(AbstractSession): @@ -47,7 +47,7 @@ hm = HostManager(config) reporter, checkfun = self.init_reporter(reporter, config, hm.hosts) - reporter(repevent.TestStarted(hm.hosts, self.config.topdir, + reporter(repevent.TestStarted(hm.hosts, self.config, hm.roots)) try: @@ -79,7 +79,7 @@ def dispatch_tests(self, nodes, reporter, checkfun): colitems = self.config.getcolitems() keyword = self.config.option.keyword - itemgenerator = itemgen(colitems, reporter, keyword) + itemgenerator = itemgen(self, colitems, reporter, keyword) all_tests = dispatch_loop(nodes, itemgenerator, checkfun) class LSession(AbstractSession): @@ -88,14 +88,13 @@ def main(self, reporter=None, runner=None): # check out if used options makes any sense config = self.config - hm = HostManager(config, hosts=[HostInfo('localhost')]) - hosts = hm.hosts + hosts = [HostInfo('localhost')] if not self.config.option.nomagic: py.magic.invoke(assertion=1) reporter, checkfun = self.init_reporter(reporter, config, hosts) - reporter(repevent.TestStarted(hosts, self.config.topdir, [])) + reporter(repevent.TestStarted(hosts, config, [])) colitems = self.config.getcolitems() reporter(repevent.RsyncFinished()) @@ -104,7 +103,7 @@ keyword = self.config.option.keyword - itemgenerator = itemgen(colitems, reporter, keyword) + itemgenerator = itemgen(self, colitems, reporter, keyword) local_loop(self, reporter, itemgenerator, checkfun, self.config, runner=runner) retval = reporter(repevent.TestFinished()) Modified: py/branch/reporter-merge/py/test/rsession/testing/basetest.py ============================================================================== --- py/branch/reporter-merge/py/test/rsession/testing/basetest.py (original) +++ py/branch/reporter-merge/py/test/rsession/testing/basetest.py Sun Oct 21 13:00:20 2007 @@ -38,12 +38,20 @@ testonepath.write(source) cls.config = py.test.config._reparse([tmpdir]) cls.collector_test_one = cls.config._getcollector(testonepath) + cls.doctest = tmpdir.ensure("xxx.txt").write(py.code.Source(""" + Aha!!!!!! + ========= + + """)) def getexample(self, name): funcname = "func" + name col = self.collector_test_one.join(funcname) assert col is not None, funcname - return col + return col + + def getdocexample(self): + return self.doctest def getmod(self): return self.collector_test_one Modified: py/branch/reporter-merge/py/test/rsession/testing/test_master.py ============================================================================== --- py/branch/reporter-merge/py/test/rsession/testing/test_master.py (original) +++ py/branch/reporter-merge/py/test/rsession/testing/test_master.py Sun Oct 21 13:00:20 2007 @@ -96,7 +96,7 @@ assert len(reportlist) == 4 def test_outcome_repr(): - out = ReprOutcome(SerializableOutcome(skipped=True).make_repr()) + out = ReprOutcome(SerializableOutcome(skipped="xxx").make_repr()) s = repr(out) assert s.lower().find("skip") != -1 @@ -136,21 +136,6 @@ item = self.rootcol._getitembynames(names) return self.config.get_collector_trail(item) - def test_slave_setup(self): - py.test.skip("Doesn't work anymore") - pkgname = self.pkgpath.basename - host = HostInfo("localhost:%s" %(self.tmpdir,)) - host.initgateway() - channel = setup_slave(host, self.config) - spec = self._gettrail(pkgname, "test_something.py", "funcpass") - print "sending", spec - channel.send(spec) - output = ReprOutcome(channel.receive()) - assert output.passed - channel.send(42) - channel.waitclose(10) - host.gw.exit() - def test_slave_running(self): py.test.skip("XXX test broken, needs refactoring") def simple_report(event): @@ -164,15 +149,17 @@ def open_gw(): gw = py.execnet.PopenGateway() - gw.host = HostInfo("localhost") - gw.host.gw = gw + host = HostInfo("localhost") + host.gw_remotepath = '' + host.gw = gw + #gw.host.gw = gw config = py.test.config._reparse([tmpdir]) - channel = setup_slave(gw.host, config) - mn = MasterNode(channel, simple_report, {}) + channel = setup_slave(host, config) + mn = MasterNode(channel, simple_report) return mn master_nodes = [open_gw(), open_gw(), open_gw()] - funcpass_item = rootcol._getitembynames(funcpass_spec) + funcpass_item = self.xxx funcfail_item = rootcol._getitembynames(funcfail_spec) itemgenerator = iter([funcfail_item] + [funcpass_item] * 5 + [funcfail_item] * 5) Modified: py/branch/reporter-merge/py/test/rsession/testing/test_slave.py ============================================================================== --- py/branch/reporter-merge/py/test/rsession/testing/test_slave.py (original) +++ py/branch/reporter-merge/py/test/rsession/testing/test_slave.py Sun Oct 21 13:00:20 2007 @@ -69,7 +69,5 @@ assert outcome.excinfo def test_slave_run_different_stuff(self): - py.test.skip("XXX not this way") node = self.gettestnode() - node.run(self.rootcol._getitembynames("py doc log.txt".split()). - _get_collector_trail()) + node.run(self.getdocexample()) Modified: py/branch/reporter-merge/py/test/session.py ============================================================================== --- py/branch/reporter-merge/py/test/session.py (original) +++ py/branch/reporter-merge/py/test/session.py Sun Oct 21 13:00:20 2007 @@ -1,14 +1,47 @@ import py +import sys from py.__.test.outcome import Outcome, Failed, Passed, Skipped from py.__.test.reporter import choose_reporter, TestReporter +from py.__.test import repevent +from py.__.test.outcome import SerializableOutcome, ReprOutcome + +def itemgen(session, colitems, reporter, keyword=None): + stopitems = py.test.collect.Item # XXX should be generator here as well + for next in colitems: + session.start(next) + if isinstance(next, stopitems): + try: + next._skipbykeyword(keyword) + yield next + except Skipped: + if session.config.option.keyword_oneshot: + keyword = None + excinfo = py.code.ExceptionInfo() + reporter(repevent.SkippedTryiter(excinfo, next)) + else: + try: + cols = [next.join(x) for x in next.run()] + for x in itemgen(session, cols, reporter, keyword): + yield x + except (KeyboardInterrupt, SystemExit, GeneratorExit): + raise + except: + excinfo = py.code.ExceptionInfo() + if excinfo.type is Skipped: + reporter(repevent.SkippedTryiter(excinfo, next)) + else: + reporter(repevent.FailedTryiter(excinfo, next)) + session.finish(next) class AbstractSession(object): """ An abstract session executes collectors/items through a runner. """ - def __init__(self, config): + def __init__(self, config, reporter=None): self._memo = [] self.config = config self._keyword = config.option.keyword + self.reporter, self.shouldstop = self.init_reporter(reporter, + config, ['localhost']) def fixoptions(self): """ check, fix and determine conflicting options. """ @@ -42,6 +75,16 @@ reporter.was_failure() return reporter, checkfun + def start(self, item): + """ A hook invoked per every item started + """ + self.reporter(repevent.ItemStart(item)) + + def finish(self, item): + """ A hook invoked per every item ending + """ + pass + class Session(AbstractSession): """ A Session gets test Items from Collectors, executes the @@ -52,6 +95,8 @@ def header(self, colitems): """ setup any neccessary resources ahead of the test run. """ + self.reporter(repevent.TestStarted(None, self.config, + None)) if not self.config.option.nomagic: py.magic.invoke(assertion=1) @@ -60,90 +105,62 @@ py.test.collect.Function._state.teardown_all() if not self.config.option.nomagic: py.magic.revoke(assertion=1) - - def start(self, colitem): - """ hook invoked before each colitem.run() invocation. """ - - def finish(self, colitem, outcome): - """ hook invoked after each colitem.run() invocation. """ - self._memo.append((colitem, outcome)) - - def startiteration(self, colitem, subitems): - pass - - def getitemoutcomepairs(self, cls): - return [x for x in self._memo if isinstance(x[1], cls)] - - def main(self): + self.reporter(repevent.TestFinished()) + + def main(self): """ main loop for running tests. """ colitems = self.config.getcolitems() + self.header(colitems) + keyword = self.config.option.keyword + reporter = self.reporter + itemgenerator = itemgen(self, colitems, reporter, keyword) try: - self.header(colitems) - try: - try: - for colitem in colitems: - self.runtraced(colitem) - except KeyboardInterrupt: - raise - finally: - self.footer(colitems) - except Exit, ex: - pass - - def runtraced(self, colitem): - if self.shouldclose(): - raise Exit, "received external close signal" - - outcome = None - colitem.startcapture() - try: - self.start(colitem) - try: + while 1: try: - if colitem._stickyfailure: - raise colitem._stickyfailure - outcome = self.run(colitem) - except (KeyboardInterrupt, Exit): - raise - except Outcome, outcome: - if outcome.excinfo is None: - outcome.excinfo = py.code.ExceptionInfo() - except: - excinfo = py.code.ExceptionInfo() - outcome = Failed(excinfo=excinfo) - assert (outcome is None or - isinstance(outcome, (list, Outcome))) - finally: - self.finish(colitem, outcome) - if isinstance(outcome, Failed) and self.config.option.exitfirst: - py.test.exit("exit on first problem configured.", item=colitem) - finally: - colitem.finishcapture() - - def run(self, colitem): - if self.config.option.collectonly and isinstance(colitem, py.test.collect.Item): - return - if isinstance(colitem, py.test.collect.Item): - colitem._skipbykeyword(self._keyword) - if self.config.option.keyword_oneshot: - self._keyword = "" - res = colitem.run() - if res is None: - return Passed() - elif not isinstance(res, (list, tuple)): - raise TypeError("%r.run() returned neither " - "list, tuple nor None: %r" % (colitem, res)) - else: - finish = self.startiteration(colitem, res) - try: - for name in res: - obj = colitem.join(name) - assert obj is not None - self.runtraced(obj) - finally: - if finish: - finish() - return res + item = itemgenerator.next() + if self.shouldstop(): + return + outcome = self.run(item) + reporter(repevent.ReceivedItemOutcome(None, item, outcome)) + except StopIteration: + break + finally: + self.footer(colitems) + + def run(self, item): + try: + item.startcapture() + try: + item.run() + finally: + item.finishcapture() + outcome = SerializableOutcome() + except Skipped: + e = py.code.ExceptionInfo() + outcome = SerializableOutcome(skipped=e) + except (SystemExit, KeyboardInterrupt): + raise + except: + e = sys.exc_info()[1] + if isinstance(e, Failed) and e.excinfo: + excinfo = e.excinfo + else: + excinfo = py.code.ExceptionInfo() + if isinstance(item, py.test.collect.Function): + fun = item.obj # hope this is stable + code = py.code.Code(fun) + excinfo.traceback = excinfo.traceback.cut( + path=code.path, firstlineno=code.firstlineno) + outcome = SerializableOutcome(excinfo=excinfo, setupfailure=False) + if self.config.option.usepdb: + if self.reporter is not None: + self.reporter(repevent.ImmediateFailure(item, + ReprOutcome(outcome.make_repr + (self.config.option.tbstyle)))) + py.__.test.custompdb.post_mortem(excinfo._excinfo[2]) + + outcome.stdout, outcome.stderr = item._getouterr() + return ReprOutcome(outcome.make_repr()) class Exit(Exception): """ for immediate program exits without tracebacks and reporter/summary. """ Modified: py/branch/reporter-merge/py/test/terminal/terminal.py ============================================================================== --- py/branch/reporter-merge/py/test/terminal/terminal.py (original) +++ py/branch/reporter-merge/py/test/terminal/terminal.py Sun Oct 21 13:00:20 2007 @@ -2,293 +2,11 @@ from time import time as now from py.__.test.terminal.out import getout -from py.__.test.representation import Presenter +from py.__.test.representation import Presenter, getrelpath from py.__.test.outcome import Skipped, Passed, Failed import py.__.test.custompdb -def getrelpath(source, dest): - base = source.common(dest) - if not base: - return None - # with posix local paths '/' is always a common base - relsource = source.relto(base) - reldest = dest.relto(base) - n = relsource.count(source.sep) - target = dest.sep.join(('..', )*n + (reldest, )) - return target - from py.__.test.session import Session class TerminalSession(Session): - def __init__(self, config, file=None): - super(TerminalSession, self).__init__(config) - if file is None: - file = py.std.sys.stdout - self._file = file - self.out = getout(file) - self._opencollectors = [] - self.presenter = Presenter(self.out, config) - - # --------------------- - # PROGRESS information - # --------------------- - - def start(self, colitem): - super(TerminalSession, self).start(colitem) - if self.config.option.collectonly: - cols = self._opencollectors - self.out.line(' ' * len(cols) + repr(colitem)) - cols.append(colitem) - else: - cls = getattr(colitem, '__class__', None) - if cls is None: - return - if issubclass(cls, py.test.collect.Module): - self.start_Module(colitem) - elif issubclass(cls, py.test.collect.Item): - self.start_Item(colitem) - #for typ in py.std.inspect.getmro(cls): - # meth = getattr(self, 'start_%s' % typ.__name__, None) - # if meth: - # meth(colitem) - # break - colitem.start = py.std.time.time() - - def start_Module(self, colitem): - if self.config.option.verbose == 0: - abbrev_fn = getrelpath(py.path.local('.xxx.'), colitem.fspath) - self.out.write('%s' % (abbrev_fn, )) - else: - self.out.line() - self.out.line("+ testmodule: %s" % colitem.fspath) - - def startiteration(self, colitem, subitems): - if (isinstance(colitem, py.test.collect.Module) - and self.config.option.verbose == 0 - and not self.config.option.collectonly): - try: - sum = 0 - for sub in subitems: - sum += len(list(colitem.join(sub)._tryiter())) - except (SystemExit, KeyboardInterrupt): - raise - except: - self.out.write('[?]') - else: - self.out.write('[%d] ' % sum) - return self.out.line - - def start_Item(self, colitem): - if self.config.option.verbose >= 1: - if isinstance(colitem, py.test.collect.Item): - realpath, lineno = colitem._getpathlineno() - location = "%s:%d" % (realpath.basename, lineno+1) - self.out.write("%-20s %s " % (location, colitem._getmodpath())) - - def finish(self, colitem, outcome): - end = now() - super(TerminalSession, self).finish(colitem, outcome) - if self.config.option.collectonly: - cols = self._opencollectors - last = cols.pop() - #assert last == colitem, "expected %r, got %r" %(last, colitem) - return - colitem.elapsedtime = end - colitem.start - if self.config.option.usepdb: - if isinstance(outcome, Failed): - print "dispatching to ppdb", colitem - self.repr_failure(colitem, outcome) - self.out.write('\n%s\n' % (outcome.excinfo.exconly(),)) - py.__.test.custompdb.post_mortem(outcome.excinfo._excinfo[2]) - if isinstance(colitem, py.test.collect.Module): - resultstring = self.repr_progress_module_result(colitem, outcome) - if resultstring: - self.out.line(" - " + resultstring) - if isinstance(colitem, py.test.collect.Item): - if self.config.option.verbose >= 1: - resultstring = self.repr_progress_long_result(colitem, outcome) - resultstring += " (%.2f)" % (colitem.elapsedtime,) - self.out.line(resultstring) - else: - c = self.repr_progress_short_result(colitem, outcome) - self.out.write(c) - - - # ------------------- - # HEADER information - # ------------------- - def header(self, colitems): - super(TerminalSession, self).header(colitems) - self.out.sep("=", "test process starts") - option = self.config.option - modes = [] - for name in 'looponfailing', 'exitfirst', 'nomagic': - if getattr(option, name): - modes.append(name) - #if self._isremoteoption._fromremote: - # modes.insert(0, 'child process') - #else: - # modes.insert(0, 'inprocess') - #mode = "/".join(modes) - #self.out.line("testing-mode: %s" % mode) - self.out.line("executable: %s (%s)" % - (py.std.sys.executable, repr_pythonversion())) - rev = py.__package__.getrev() - self.out.line("using py lib: %s " % ( - py.path.local(py.__file__).dirpath(), rev)) - - if self.config.option.traceconfig or self.config.option.verbose: - - for x in colitems: - self.out.line("test target: %s" %(x.fspath,)) - - conftestmodules = self.config._conftest.getconftestmodules(None) - for i,x in py.builtin.enumerate(conftestmodules): - self.out.line("initial conf %d: %s" %(i, x.__file__)) - - #for i, x in py.builtin.enumerate(py.test.config.configpaths): - # self.out.line("initial testconfig %d: %s" %(i, x)) - #additional = py.test.config.getfirst('additionalinfo') - #if additional: - # for key, descr in additional(): - # self.out.line("%s: %s" %(key, descr)) - self.out.line() - self.starttime = now() - - # ------------------- - # FOOTER information - # ------------------- - - def footer(self, colitems): - super(TerminalSession, self).footer(colitems) - self.endtime = now() - self.out.line() - self.skippedreasons() - self.failures() - self.summaryline() - - # -------------------- - # progress information - # -------------------- - typemap = { - Passed: '.', - Skipped: 's', - Failed: 'F', - } - namemap = { - Passed: 'ok', - Skipped: 'SKIP', - Failed: 'FAIL', - } - - def repr_progress_short_result(self, item, outcome): - for outcometype, char in self.typemap.items(): - if isinstance(outcome, outcometype): - return char - else: - #raise TypeError, "not an Outomce instance: %r" % (outcome,) - return '?' - - def repr_progress_long_result(self, item, outcome): - for outcometype, char in self.namemap.items(): - if isinstance(outcome, outcometype): - return char - else: - #raise TypeError, "not an Outcome instance: %r" % (outcome,) - return 'UNKNOWN' - - def repr_progress_module_result(self, item, outcome): - if isinstance(outcome, Failed): - return "FAILED TO LOAD MODULE" - elif isinstance(outcome, Skipped): - return "skipped" - elif not isinstance(outcome, (list, Passed)): - return "?" - - # -------------------- - # summary information - # -------------------- - def summaryline(self): - outlist = [] - sum = 0 - for typ in Passed, Failed, Skipped: - l = self.getitemoutcomepairs(typ) - if l: - outlist.append('%d %s' % (len(l), typ.__name__.lower())) - sum += len(l) - elapsed = self.endtime-self.starttime - status = "%s" % ", ".join(outlist) - self.out.sep('=', 'tests finished: %s in %4.2f seconds' % - (status, elapsed)) - - def getlastvisible(self, sourcetraceback): - traceback = sourcetraceback[:] - while traceback: - entry = traceback.pop() - try: - x = entry.frame.eval("__tracebackhide__") - except: - x = False - if not x: - return entry - else: - return sourcetraceback[-1] - - def skippedreasons(self): - texts = {} - for colitem, outcome in self.getitemoutcomepairs(Skipped): - raisingtb = self.getlastvisible(outcome.excinfo.traceback) - fn = raisingtb.frame.code.path - lineno = raisingtb.lineno - d = texts.setdefault(outcome.excinfo.exconly(), {}) - d[(fn,lineno)] = outcome - - if texts: - self.out.line() - self.out.sep('_', 'reasons for skipped tests') - for text, dict in texts.items(): - for (fn, lineno), outcome in dict.items(): - self.out.line('Skipped in %s:%d' %(fn, lineno+1)) - self.out.line("reason: %s" % text) - self.out.line() - - def failures(self): - if self.config.option.tbstyle == 'no': - return # skip the detailed failure reports altogether - l = self.getitemoutcomepairs(Failed) - if l: - self.out.sep('_') - for colitem, outcome in l: - self.repr_failure(colitem, outcome) - - def repr_failure(self, item, outcome): - excinfo = outcome.excinfo - traceback = excinfo.traceback - #print "repr_failures sees item", item - #print "repr_failures sees traceback" - #py.std.pprint.pprint(traceback) - if item and not self.config.option.fulltrace: - path, firstlineno = item._getpathlineno() - ntraceback = traceback.cut(path=path, firstlineno=firstlineno) - if ntraceback == traceback: - ntraceback = ntraceback.cut(path=path) - traceback = ntraceback.filter() - if not traceback: - self.out.line("empty traceback from item %r" % (item,)) - return - handler = getattr(self.presenter, 'repr_failure_tb%s' % self.config.option.tbstyle) - handler(item, excinfo, traceback, lambda : self.repr_out_err(item)) - - def repr_out_err(self, colitem): - for parent in colitem.listchain(): - for name, obj in zip(['out', 'err'], parent._getouterr()): - if obj: - self.out.sep("- ", "%s: recorded std%s" % (parent.name, name)) - self.out.line(obj) - -def repr_pythonversion(): - v = py.std.sys.version_info - try: - return "%s.%s.%s-%s-%s" % v - except ValueError: - return str(v) + pass Modified: py/branch/reporter-merge/py/test/testing/test_collect.py ============================================================================== --- py/branch/reporter-merge/py/test/testing/test_collect.py (original) +++ py/branch/reporter-merge/py/test/testing/test_collect.py Sun Oct 21 13:00:20 2007 @@ -2,6 +2,13 @@ import py from setupdata import setupdatadir from py.__.test.outcome import Skipped, Failed, Passed, Outcome +from py.__.test.terminal.out import getout +from py.__.test.repevent import ReceivedItemOutcome + +def getpassed(all): + outcomes = [i.outcome for i in all if isinstance(i, ReceivedItemOutcome)] + l = [i for i in outcomes if i.passed] + return l def setup_module(mod): mod.datadir = setupdatadir() @@ -204,9 +211,11 @@ try: config = py.test.config._reparse([]) out = py.std.cStringIO.StringIO() - session = config._getsessionclass()(config, out) - session.main() - l = session.getitemoutcomepairs(Passed) + all = [] + session = config._getsessionclass()(config, all.append) + session.reporter.out = getout(out) + session.main() + l = getpassed(all) assert len(l) == 2 finally: old.chdir() @@ -214,9 +223,11 @@ # test that running the file directly works config = py.test.config._reparse([str(checkfile)]) out = py.std.cStringIO.StringIO() - session = config._getsessionclass()(config, out) - session.main() - l = session.getitemoutcomepairs(Passed) + all = [] + session = config._getsessionclass()(config, all.append) + session.reporter.out = getout(out) + session.main() + l = getpassed(all) assert len(l) == 2 def test_custom_NONpython_collection_from_conftest(): @@ -251,9 +262,11 @@ try: config = py.test.config._reparse([]) out = py.std.cStringIO.StringIO() - session = config._getsessionclass()(config, out) - session.main() - l = session.getitemoutcomepairs(Passed) + all = [] + session = config._getsessionclass()(config, all.append) + session.reporter.out = getout(out) + session.main() + l = getpassed(all) assert len(l) == 1 finally: old.chdir() @@ -261,9 +274,11 @@ # test that running the file directly works config = py.test.config._reparse([str(checkfile)]) out = py.std.cStringIO.StringIO() - session = config._getsessionclass()(config, out) - session.main() - l = session.getitemoutcomepairs(Passed) + all = [] + session = config._getsessionclass()(config, all.append) + session.reporter.out = getout(out) + session.main() + l = getpassed(all) assert len(l) == 1 def test_order_of_execution_generator_same_codeline(): @@ -286,9 +301,10 @@ yield assert_order_of_execution """)) config = py.test.config._reparse([o]) - session = config.initsession() + all = [] + session = config.initsession(all.append) session.main() - l = session.getitemoutcomepairs(Passed) + l = getpassed(all) assert len(l) == 7 def test_order_of_execution_generator_different_codeline(): @@ -318,9 +334,10 @@ yield assert_order_of_execution """)) config = py.test.config._reparse([o]) - session = config.initsession() + all = [] + session = config.initsession(all.append) session.main() - l = session.getitemoutcomepairs(Passed) + l = getpassed(all) assert len(l) == 4 Modified: py/branch/reporter-merge/py/test/testing/test_config.py ============================================================================== --- py/branch/reporter-merge/py/test/testing/test_config.py (original) +++ py/branch/reporter-merge/py/test/testing/test_config.py Sun Oct 21 13:00:20 2007 @@ -228,7 +228,7 @@ self.tmpdir.join("conftest.py").write(py.code.Source(""" from py.__.test.session import Session class MySession(Session): - def __init__(self, config): + def __init__(self, config, reporter=None): self.config = config """)) config = py.test.config._reparse(["--session=MySession", self.tmpdir]) Modified: py/branch/reporter-merge/py/test/testing/test_outcome.py ============================================================================== --- py/branch/reporter-merge/py/test/testing/test_outcome.py (original) +++ py/branch/reporter-merge/py/test/testing/test_outcome.py Sun Oct 21 13:00:20 2007 @@ -3,6 +3,7 @@ from py.__.test.outcome import SerializableOutcome, ReprOutcome, ExcInfoRepr import marshal +import py def test_critical_debugging_flag(): outcome = SerializableOutcome(is_critical=True) @@ -22,13 +23,16 @@ def f3(): f2() +def f4(): + py.test.skip("argh!") + def test_exception_info_repr(): try: f3() except: outcome = SerializableOutcome(excinfo=py.code.ExceptionInfo()) - repr = outcome.make_excinfo_repr("long") + repr = outcome.make_excinfo_repr(outcome.excinfo, "long") assert marshal.dumps(repr) excinfo = ExcInfoRepr(repr) @@ -46,5 +50,15 @@ assert excinfo.traceback[1].lineno == f3.func_code.co_firstlineno assert excinfo.traceback[1].relline == 1 +def test_packed_skipped(): + try: + f4() + except: + outcome = SerializableOutcome(skipped=py.code.ExceptionInfo()) + repr = outcome.make_excinfo_repr(outcome.skipped, "long") + assert marshal.dumps(repr) + skipped = ExcInfoRepr(repr) + assert skipped.value == "'argh!'" + #def test_f3(): # f3() Modified: py/branch/reporter-merge/py/test/testing/test_remote.py ============================================================================== --- py/branch/reporter-merge/py/test/testing/test_remote.py (original) +++ py/branch/reporter-merge/py/test/testing/test_remote.py Sun Oct 21 13:00:20 2007 @@ -23,7 +23,7 @@ else: py.test.fail("did not see test_1 failure") - def test_looponfailing(self): + def test_looponfailing(self): o = tmpdir.ensure('looponfailing', dir=1) tfile = o.join('test_looponfailing.py') tfile.write(py.code.Source(""" Modified: py/branch/reporter-merge/py/test/testing/test_repevent.py ============================================================================== --- py/branch/reporter-merge/py/test/testing/test_repevent.py (original) +++ py/branch/reporter-merge/py/test/testing/test_repevent.py Sun Oct 21 13:00:20 2007 @@ -42,7 +42,7 @@ assert repevent.FailedTryiter(None, None).is_failure() out = ReprOutcome(SerializableOutcome().make_repr()) assert not repevent.ReceivedItemOutcome(None, None, out).is_failure() - out = ReprOutcome(SerializableOutcome(skipped=True).make_repr()) + out = ReprOutcome(SerializableOutcome(skipped="xxx").make_repr()) assert not repevent.ReceivedItemOutcome(None, None, out).is_failure() try: 1/0 Modified: py/branch/reporter-merge/py/test/testing/test_reporter.py ============================================================================== --- py/branch/reporter-merge/py/test/testing/test_reporter.py (original) +++ py/branch/reporter-merge/py/test/testing/test_reporter.py Sun Oct 21 13:00:20 2007 @@ -18,17 +18,26 @@ import py, os -from py.__.test.session import AbstractSession +from py.__.test.session import AbstractSession, itemgen from py.__.test.reporter import RemoteReporter, LocalReporter, choose_reporter from py.__.test import repevent from py.__.test.outcome import ReprOutcome, SerializableOutcome from py.__.test.rsession.hostmanage import HostInfo from py.__.test.rsession.box import Box from py.__.test.rsession.testing.basetest import BasicRsessionTest -from py.__.test.rsession.master import itemgen import sys from StringIO import StringIO +class MockSession(object): + def __init__(self, reporter): + self.reporter = reporter + + def start(self, item): + self.reporter(repevent.ItemStart(item)) + + def finish(self, item): + pass + class DummyGateway(object): def __init__(self, host): self.host = host @@ -44,9 +53,14 @@ 1/0 except: exc = py.code.ExceptionInfo() + + try: + py.test.skip("xxx") + except: + skipexc = py.code.ExceptionInfo() outcomes = [SerializableOutcome(()), - SerializableOutcome(skipped=True), + SerializableOutcome(skipped=skipexc), SerializableOutcome(excinfo=exc), SerializableOutcome()] @@ -112,7 +126,7 @@ rootcol = py.test.collect.Directory(tmpdir) hosts = [HostInfo('localhost')] r = self.reporter(config, hosts) - list(itemgen([rootcol], r.report)) + list(itemgen(MockSession(r), [rootcol], r.report)) cap = py.io.StdCaptureFD() boxfun() @@ -131,9 +145,9 @@ rootcol = py.test.collect.Directory(tmpdir) host = HostInfo('localhost') r = self.reporter(config, [host]) - r.report(repevent.TestStarted([host], config.topdir, ["a"])) + r.report(repevent.TestStarted([host], config, ["a"])) r.report(repevent.RsyncFinished()) - list(itemgen([rootcol], r.report)) + list(itemgen(MockSession(r), [rootcol], r.report)) r.report(repevent.TestFinished()) return r @@ -144,6 +158,24 @@ assert out.find("1 failed in") != -1 assert out.find("NameError: name 'sadsadsa' is not defined") != -1 + def _test_verbose(self): + tmpdir = py.test.ensuretemp("reporterverbose") + tmpdir.ensure("__init__.py") + tmpdir.ensure("test_one.py").write("def test_x(): pass") + cap = py.io.StdCaptureFD() + config = py.test.config._reparse([str(tmpdir), '-v']) + hosts = [HostInfo("host")] + r = self.reporter(config, hosts) + r.report(repevent.TestStarted(hosts, config, [])) + r.report(repevent.RsyncFinished()) + rootcol = py.test.collect.Directory(tmpdir) + list(itemgen(MockSession(r), [rootcol], r.report)) + r.report(repevent.TestFinished()) + out, err = cap.reset() + assert not err + for i in ['+ testmodule:', 'test_one.py[1]']: # XXX finish + assert i in out + def _test_still_to_go(self): tmpdir = py.test.ensuretemp("stilltogo") tmpdir.ensure("__init__.py") @@ -153,7 +185,7 @@ for host in hosts: host.gw_remotepath = '' r = self.reporter(config, hosts) - r.report(repevent.TestStarted(hosts, config.topdir, ["a", "b", "c"])) + r.report(repevent.TestStarted(hosts, config, ["a", "b", "c"])) for host in hosts: r.report(repevent.HostGatewayReady(host, ["a", "b", "c"])) for host in hosts: @@ -177,6 +209,9 @@ def test_report_received_item_outcome(self): assert self.report_received_item_outcome() == 'FsF.' + def test_verbose(self): + self._test_verbose() + def test_module(self): output = self._test_module() assert output.find("test_one") != -1 Modified: py/branch/reporter-merge/py/test/testing/test_repr.py ============================================================================== --- py/branch/reporter-merge/py/test/testing/test_repr.py (original) +++ py/branch/reporter-merge/py/test/testing/test_repr.py Sun Oct 21 13:00:20 2007 @@ -56,7 +56,7 @@ for key in locals().keys(): assert s.getvalue().find(key) != -1 -def test_repr_traceback_long(): +def XXXtest_repr_traceback_long(): py.test.skip("unfinished") config = py.test.config._reparse([]) s = StringIO() Modified: py/branch/reporter-merge/py/test/testing/test_session.py ============================================================================== --- py/branch/reporter-merge/py/test/testing/test_session.py (original) +++ py/branch/reporter-merge/py/test/testing/test_session.py Sun Oct 21 13:00:20 2007 @@ -1,12 +1,15 @@ import py from setupdata import setup_module # sets up global 'tmpdir' from py.__.test.outcome import Skipped, Failed, Passed, Outcome +from py.__.test.terminal.out import getout +from py.__.test.repevent import ReceivedItemOutcome, SkippedTryiter,\ + FailedTryiter implied_options = { '--pdb': 'usepdb and nocapture', '-v': 'verbose', '-l': 'showlocals', - '--runbrowser': 'startserver and runbrowser', + #'--runbrowser': 'startserver and runbrowser', XXX starts browser } conflict_options = ('--looponfailing --pdb', @@ -14,6 +17,21 @@ '--exec=%s --pdb' % py.std.sys.executable, ) +def getoutcomes(all): + return [i.outcome for i in all if isinstance(i, ReceivedItemOutcome)] + + +def getpassed(all): + return [i for i in getoutcomes(all) if i.passed] + +def getskipped(all): + return [i for i in getoutcomes(all) if i.skipped] + \ + [i for i in all if isinstance(i, SkippedTryiter)] + +def getfailed(all): + return [i for i in getoutcomes(all) if i.excinfo] + \ + [i for i in all if isinstance(i, FailedTryiter)] + def test_conflict_options(): for spec in conflict_options: opts = spec.split() @@ -42,13 +60,12 @@ yield runfiletest, opts def runfiletest(opts): - config = py.test.config._reparse(opts + [datadir/'filetest.py']) - session = config.initsession() + config = py.test.config._reparse(opts + [datadir/'filetest.py']) + all = [] + session = config.initsession(all.append) session.main() - l = session.getitemoutcomepairs(Failed) - assert len(l) == 2 - l = session.getitemoutcomepairs(Passed) - assert not l + assert len(getfailed(all)) == 2 + assert not getskipped(all) def test_is_not_boxed_by_default(): config = py.test.config._reparse([datadir]) @@ -59,13 +76,13 @@ def check(keyword, name): config = py.test.config._reparse([datadir/'filetest.py', '-s', '-k', keyword]) - session = config._getsessionclass()(config, py.std.sys.stdout) + all = [] + session = config._getsessionclass()(config, all.append) session.main() - l = session.getitemoutcomepairs(Failed) - assert len(l) == 1 - item = l[0][0] - assert item.name == name - l = session.getitemoutcomepairs(Skipped) + outcomes = [i for i in all if isinstance(i, ReceivedItemOutcome)] + assert len(getfailed(all)) == 1 + assert outcomes[0].item.name == name + l = getskipped(all) assert len(l) == 1 for keyword in ['test_one', 'est_on']: @@ -90,65 +107,64 @@ for keyword in ('xxx', 'xxx test_2', 'TestClass', 'xxx -test_1', 'TestClass test_2', 'xxx TestClass test_2',): f = py.std.StringIO.StringIO() - config = py.test.config._reparse([o, '-s', '-k', keyword]) - session = config._getsessionclass()(config, f) + config = py.test.config._reparse([o, '-s', '-k', keyword]) + all = [] + session = config._getsessionclass()(config, all.append) + session.reporter.out = getout(f) session.main() print "keyword", repr(keyword) - l = session.getitemoutcomepairs(Passed) + l = getpassed(all) + outcomes = [i for i in all if isinstance(i, ReceivedItemOutcome)] assert len(l) == 1 - assert l[0][0].name == 'test_2' - l = session.getitemoutcomepairs(Skipped) - assert l[0][0].name == 'test_1' + assert outcomes[0].item.name == 'test_2' + l = getskipped(all) + assert l[0].item.name == 'test_1' def test_select_starton(self): config = py.test.config._reparse([datadir/'testmore.py', '-j', '-k', "test_two"]) - session = config._getsessionclass()(config, py.std.sys.stdout) + all = [] + session = config._getsessionclass()(config, all.append) session.main() - l = session.getitemoutcomepairs(Passed) - assert len(l) == 2 - l = session.getitemoutcomepairs(Skipped) - assert len(l) == 1 + assert len(getpassed(all)) == 2 + assert len(getskipped(all)) == 1 -class TestTerminalSession: - def mainsession(self, *args): +class TestTerminalSession: + def mainsession(self, *args): from py.__.test.terminal.terminal import TerminalSession - self.file = py.std.StringIO.StringIO() + from py.__.test.terminal.out import getout config = py.test.config._reparse(list(args)) - session = TerminalSession(config, file=self.file) + all = [] + session = TerminalSession(config, all.append) session.main() - return session + return session, all def test_terminal(self): - session = self.mainsession(datadir / 'filetest.py') - out = self.file.getvalue() - l = session.getitemoutcomepairs(Failed) - assert len(l) == 2 - assert out.find('2 failed') != -1 + session, all = self.mainsession(datadir / 'filetest.py') + outcomes = getoutcomes(all) + assert len(getfailed(all)) == 2 def test_syntax_error_module(self): - session = self.mainsession(datadir / 'syntax_error.py') - l = session.getitemoutcomepairs(Failed) - assert len(l) == 1 - out = self.file.getvalue() + session, all = self.mainsession(datadir / 'syntax_error.py') + l = getfailed(all) + assert len(l) == 1 + out = l[0].excinfo.exconly() assert out.find(str('syntax_error.py')) != -1 assert out.find(str('not python')) != -1 def test_exit_first_problem(self): - session = self.mainsession("--exitfirst", - datadir / 'filetest.py') + session, all = self.mainsession("--exitfirst", + datadir / 'filetest.py') assert session.config.option.exitfirst - l = session.getitemoutcomepairs(Failed) - assert len(l) == 1 - l = session.getitemoutcomepairs(Passed) - assert not l + assert len(getfailed(all)) == 1 + assert not getpassed(all) - def test_collectonly(self): - session = self.mainsession("--collectonly", - datadir / 'filetest.py') + def test_collectonly(self): + py.test.skip("XXX Reimplement this feature") + session, out = self.mainsession("--collectonly", + datadir / 'filetest.py') assert session.config.option.collectonly - out = self.file.getvalue() #print out l = session.getitemoutcomepairs(Failed) #if l: @@ -160,7 +176,8 @@ 'TestClass', 'test_method_one'): assert out.find(line) - def test_recursion_detection(self): + def test_recursion_detection(self): + py.test.skip("XXX the test is bogus here") o = tmpdir.ensure('recursiontest', dir=1) tfile = o.join('test_recursion.py') tfile.write(py.code.Source(""" @@ -171,10 +188,10 @@ f() f() """)) - session = self.mainsession(o) + session, all = self.mainsession(o) print "back from main", o - out = self.file.getvalue() #print out + outcomes = getoutcomes(all) i = out.find('Recursion detected') assert i != -1 @@ -185,9 +202,10 @@ def test_1(): yield None """)) - session = self.mainsession(o) - out = self.file.getvalue() + session, all = self.mainsession(o) #print out + failures = getfailed(all) + out = failures[0].excinfo.exconly() i = out.find('TypeError') assert i != -1 @@ -213,20 +231,16 @@ def finishcapture(self): self._testmycapture = None """)) - session = self.mainsession(o) - l = session.getitemoutcomepairs(Passed) + session, all = self.mainsession(o) + l = getpassed(all) + outcomes = getoutcomes(all) assert len(l) == 1 - item = l[0][0] + item = all[3].item # item is not attached to outcome, but it's the + # started before assert hasattr(item, '_testmycapture') print item._testmycapture assert isinstance(item.parent, py.test.collect.Module) - out, err = item.parent._getouterr() - assert out.find('module level output') != -1 - allout = self.file.getvalue() - print "allout:", allout - assert allout.find('module level output') != -1, ( - "session didn't show module output") def test_raises_output(self): o = tmpdir.ensure('raisestest', dir=1) @@ -236,8 +250,9 @@ def test_raises_doesnt(): py.test.raises(ValueError, int, "3") """)) - session = self.mainsession(o) - out = self.file.getvalue() + session, all = self.mainsession(o) + outcomes = getoutcomes(all) + out = outcomes[0].excinfo.exconly() if not out.find("DID NOT RAISE") != -1: print out py.test.fail("incorrect raises() output") @@ -265,16 +280,10 @@ assert self.reslist == [1,2,1,2,3] """)) - session = self.mainsession(o) - l = session.getitemoutcomepairs(Failed) - assert len(l) == 0 - l = session.getitemoutcomepairs(Passed) - assert len(l) == 7 + session, all = self.mainsession(o) + assert len(getfailed(all)) == 0 + assert len(getpassed(all)) == 7 # also test listnames() here ... - item, result = l[-1] - assert item.name == 'test_4' - names = item.listnames() - assert names == ['ordertest', 'test_orderofexecution.py', 'Testmygroup', '()', 'test_4'] def test_nested_import_error(self): o = tmpdir.ensure('Ians_importfailure', dir=1) @@ -288,47 +297,23 @@ import does_not_work a = 1 """)) - session = self.mainsession(o) - l = session.getitemoutcomepairs(Failed) + session, all = self.mainsession(o) + l = getfailed(all) assert len(l) == 1 - item, outcome = l[0] - assert str(outcome.excinfo).find('does_not_work') != -1 + out = l[0].excinfo.exconly() + assert out.find('does_not_work') != -1 def test_safe_repr(self): - session = self.mainsession(datadir/'brokenrepr.py') - out = self.file.getvalue() - print 'Output of simulated "py.test brokenrepr.py":' - print out - - l = session.getitemoutcomepairs(Failed) + session, all = self.mainsession(datadir/'brokenrepr.py') + #print 'Output of simulated "py.test brokenrepr.py":' + #print all + + l = getfailed(all) assert len(l) == 2 + out = l[0].excinfo.exconly() assert out.find("""[Exception("Ha Ha fooled you, I'm a broken repr().") raised in repr()]""") != -1 #' + out = l[1].excinfo.exconly() assert out.find("[unknown exception raised in repr()]") != -1 - - def test_E_on_correct_line(self): - o = tmpdir.ensure('E_on_correct_line', dir=1) - tfile = o.join('test_correct_line.py') - source = py.code.Source(""" - import py - def test_hello(): - assert (None == - ['a', - 'b', - 'c']) - """) - tfile.write(source) - session = self.mainsession(o) - out = self.file.getvalue() - print 'Output of simulated "py.test test_correct_line.py":' - print out - i = out.find('test_correct_line.py:') - assert i >= 0 - linenum = int(out[i+len('test_correct_line.py:')]) # a single char - line_to_report = source[linenum-1] - expected_output = '\nE ' + line_to_report + '\n' - print 'Looking for:', expected_output - assert expected_output in out - def test_skip_reasons(): tmp = py.test.ensuretemp("check_skip_reasons") @@ -342,10 +327,11 @@ """)) tmp.ensure("__init__.py") config = py.test.config._reparse([tmp]) - session = config.initsession() + all = [] + session = config.initsession(all.append) session.main() - skips = session.getitemoutcomepairs(Skipped) + skips = getskipped(all) assert len(skips) == 2 - assert repr(skips[0][1]) == 'Broken: stuff' - assert repr(skips[1][1]) == 'Not implemented: stuff' + assert str(skips[0].skipped.value) == 'Broken: stuff' + assert str(skips[1].skipped.value) == 'Not implemented: stuff' From fijal at codespeak.net Sun Oct 21 18:43:56 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 21 Oct 2007 18:43:56 +0200 (CEST) Subject: [py-svn] r47678 - in py/branch/reporter-merge/py/test: . rsession rsession/testing testing Message-ID: <20071021164356.AD38C817E@code0.codespeak.net> Author: fijal Date: Sun Oct 21 18:43:54 2007 New Revision: 47678 Modified: py/branch/reporter-merge/py/test/config.py py/branch/reporter-merge/py/test/rsession/executor.py py/branch/reporter-merge/py/test/rsession/rsession.py py/branch/reporter-merge/py/test/rsession/testing/test_lsession.py py/branch/reporter-merge/py/test/rsession/testing/test_rsession.py py/branch/reporter-merge/py/test/rsession/web.py py/branch/reporter-merge/py/test/session.py py/branch/reporter-merge/py/test/testing/test_collect.py py/branch/reporter-merge/py/test/testing/test_config.py py/branch/reporter-merge/py/test/testing/test_session.py Log: Make even less things working. Modified: py/branch/reporter-merge/py/test/config.py ============================================================================== --- py/branch/reporter-merge/py/test/config.py (original) +++ py/branch/reporter-merge/py/test/config.py Sun Oct 21 18:43:54 2007 @@ -163,18 +163,8 @@ if self.option.dist: name = 'RSession' else: - optnames = 'startserver runbrowser apigen restreport boxed'.split() - for opt in optnames: - if getattr(self.option, opt, False): - name = 'LSession' - break - else: - if self.getvalue('dist_boxed'): - name = 'LSession' - if self.option.looponfailing: - name = 'RemoteTerminalSession' - elif self.option.executable: - name = 'RemoteTerminalSession' + if self.option.looponfailing or self.option.executable: + name = 'RemoteTerminalSession' return name def _reparse(self, args): Modified: py/branch/reporter-merge/py/test/rsession/executor.py ============================================================================== --- py/branch/reporter-merge/py/test/rsession/executor.py (original) +++ py/branch/reporter-merge/py/test/rsession/executor.py Sun Oct 21 18:43:54 2007 @@ -35,8 +35,9 @@ try: self.run(capture) outcome = SerializableOutcome() - except Skipped, e: - outcome = SerializableOutcome(skipped=str(e)) + except Skipped: + e = py.code.ExceptionInfo() + outcome = SerializableOutcome(skipped=e) except (SystemExit, KeyboardInterrupt): raise except: Modified: py/branch/reporter-merge/py/test/rsession/rsession.py ============================================================================== --- py/branch/reporter-merge/py/test/rsession/rsession.py (original) +++ py/branch/reporter-merge/py/test/rsession/rsession.py Sun Oct 21 18:43:54 2007 @@ -40,15 +40,18 @@ print print "see also: http://codespeak.net/py/current/doc/test.html#automated-distributed-testing" raise SystemExit - - def main(self, reporter=None): + + def main(self): + """ main loop for running tests. """ config = self.config hm = HostManager(config) - reporter, checkfun = self.init_reporter(reporter, config, hm.hosts) + reporter, checkfun = self.init_reporter(self.reporter, config, + hm.hosts) reporter(repevent.TestStarted(hm.hosts, self.config, hm.roots)) + self.reporter = reporter try: nodes = hm.setup_hosts(reporter) @@ -89,10 +92,10 @@ # check out if used options makes any sense config = self.config hosts = [HostInfo('localhost')] - if not self.config.option.nomagic: - py.magic.invoke(assertion=1) - reporter, checkfun = self.init_reporter(reporter, config, hosts) + #reporter, checkfun = self.init_reporter(reporter, config, hosts) + reporter = self.reporter + checkfun = self.shouldstop reporter(repevent.TestStarted(hosts, config, [])) colitems = self.config.getcolitems() Modified: py/branch/reporter-merge/py/test/rsession/testing/test_lsession.py ============================================================================== --- py/branch/reporter-merge/py/test/rsession/testing/test_lsession.py (original) +++ py/branch/reporter-merge/py/test/rsession/testing/test_lsession.py Sun Oct 21 18:43:54 2007 @@ -8,7 +8,8 @@ from py.__.test.rsession.local import box_runner, plain_runner, apigen_runner import py.__.test.custompdb -def setup_module(mod): +def setup_module(mod): + py.test.skip("Not working") mod.tmp = py.test.ensuretemp("lsession_module") class TestLSession(object): Modified: py/branch/reporter-merge/py/test/rsession/testing/test_rsession.py ============================================================================== --- py/branch/reporter-merge/py/test/rsession/testing/test_rsession.py (original) +++ py/branch/reporter-merge/py/test/rsession/testing/test_rsession.py Sun Oct 21 18:43:54 2007 @@ -34,9 +34,9 @@ pass """)) config = py.test.config._reparse([self.source.join("sub"), '-x']) - rsession = RSession(config) allevents = [] - rsession.main(reporter=allevents.append) + rsession = RSession(config, allevents.append) + rsession.main() testevents = [x for x in allevents if isinstance(x, repevent.ReceivedItemOutcome)] assert len(testevents) == 3 @@ -69,9 +69,9 @@ config = py.test.config._reparse([tmpdir.join(subdir)]) assert config.topdir == tmpdir assert not tmpdir.join("__init__.py").check() - rsession = RSession(config) allevents = [] - rsession.main(reporter=allevents.append) + rsession = RSession(config, allevents.append) + rsession.main() testevents = [x for x in allevents if isinstance(x, repevent.ReceivedItemOutcome)] assert len(testevents) @@ -176,9 +176,8 @@ """) config = py.test.config._reparse([tmpdir]) - rsession = RSession(config) - allevents = [] - rsession.main(reporter=allevents.append) + rsession = RSession(config, allevents.append) + rsession.main() testevents = [x for x in allevents if isinstance(x, repevent.ReceivedItemOutcome)] passevents = [x for x in testevents if x.outcome.passed] Modified: py/branch/reporter-merge/py/test/rsession/web.py ============================================================================== --- py/branch/reporter-merge/py/test/rsession/web.py (original) +++ py/branch/reporter-merge/py/test/rsession/web.py Sun Oct 21 18:43:54 2007 @@ -309,9 +309,12 @@ # XXX: It overrides our self.hosts self.hosts = {} self.ready_hosts = {} - for host in event.hosts: - self.hosts[host] = host - self.ready_hosts[host] = False + if not event.hosts: + self.hosts = [] + else: + for host in event.hosts: + self.hosts[host] = host + self.ready_hosts[host] = False self.start_event.set() self.pending_events.put(event) Modified: py/branch/reporter-merge/py/test/session.py ============================================================================== --- py/branch/reporter-merge/py/test/session.py (original) +++ py/branch/reporter-merge/py/test/session.py Sun Oct 21 18:43:54 2007 @@ -37,11 +37,9 @@ """ An abstract session executes collectors/items through a runner. """ def __init__(self, config, reporter=None): - self._memo = [] self.config = config self._keyword = config.option.keyword - self.reporter, self.shouldstop = self.init_reporter(reporter, - config, ['localhost']) + self.reporter = reporter def fixoptions(self): """ check, fix and determine conflicting options. """ @@ -109,6 +107,10 @@ def main(self): """ main loop for running tests. """ + config = self.config + self.reporter, self.shouldstop = self.init_reporter(self.reporter, + config, ['localhost']) + colitems = self.config.getcolitems() self.header(colitems) keyword = self.config.option.keyword Modified: py/branch/reporter-merge/py/test/testing/test_collect.py ============================================================================== --- py/branch/reporter-merge/py/test/testing/test_collect.py (original) +++ py/branch/reporter-merge/py/test/testing/test_collect.py Sun Oct 21 18:43:54 2007 @@ -210,10 +210,8 @@ old = o.chdir() try: config = py.test.config._reparse([]) - out = py.std.cStringIO.StringIO() all = [] session = config._getsessionclass()(config, all.append) - session.reporter.out = getout(out) session.main() l = getpassed(all) assert len(l) == 2 @@ -222,10 +220,8 @@ # test that running the file directly works config = py.test.config._reparse([str(checkfile)]) - out = py.std.cStringIO.StringIO() all = [] session = config._getsessionclass()(config, all.append) - session.reporter.out = getout(out) session.main() l = getpassed(all) assert len(l) == 2 @@ -261,10 +257,8 @@ old = o.chdir() try: config = py.test.config._reparse([]) - out = py.std.cStringIO.StringIO() all = [] session = config._getsessionclass()(config, all.append) - session.reporter.out = getout(out) session.main() l = getpassed(all) assert len(l) == 1 @@ -273,10 +267,8 @@ # test that running the file directly works config = py.test.config._reparse([str(checkfile)]) - out = py.std.cStringIO.StringIO() all = [] session = config._getsessionclass()(config, all.append) - session.reporter.out = getout(out) session.main() l = getpassed(all) assert len(l) == 1 Modified: py/branch/reporter-merge/py/test/testing/test_config.py ============================================================================== --- py/branch/reporter-merge/py/test/testing/test_config.py (original) +++ py/branch/reporter-merge/py/test/testing/test_config.py Sun Oct 21 18:43:54 2007 @@ -207,6 +207,7 @@ assert config._getsessionname() == 'RSession' def test_implied_lsession(self): + py.test.skip("Different sessions probably") optnames = 'startserver runbrowser apigen=x rest boxed'.split() for x in optnames: config = py.test.config._reparse([self.tmpdir, '--%s' % x]) Modified: py/branch/reporter-merge/py/test/testing/test_session.py ============================================================================== --- py/branch/reporter-merge/py/test/testing/test_session.py (original) +++ py/branch/reporter-merge/py/test/testing/test_session.py Sun Oct 21 18:43:54 2007 @@ -106,11 +106,9 @@ """)) for keyword in ('xxx', 'xxx test_2', 'TestClass', 'xxx -test_1', 'TestClass test_2', 'xxx TestClass test_2',): - f = py.std.StringIO.StringIO() config = py.test.config._reparse([o, '-s', '-k', keyword]) all = [] session = config._getsessionclass()(config, all.append) - session.reporter.out = getout(f) session.main() print "keyword", repr(keyword) l = getpassed(all) From fijal at codespeak.net Sun Oct 28 12:48:36 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 28 Oct 2007 12:48:36 +0100 (CET) Subject: [py-svn] r48126 - in py/branch/reporter-merge/py/test: . testing Message-ID: <20071028114836.AC5988171@code0.codespeak.net> Author: fijal Date: Sun Oct 28 12:48:35 2007 New Revision: 48126 Added: py/branch/reporter-merge/py/test/testing/test_itemgen.py (contents, props changed) Modified: py/branch/reporter-merge/py/test/session.py Log: Some real test for itemgen Modified: py/branch/reporter-merge/py/test/session.py ============================================================================== --- py/branch/reporter-merge/py/test/session.py (original) +++ py/branch/reporter-merge/py/test/session.py Sun Oct 28 12:48:35 2007 @@ -8,7 +8,8 @@ def itemgen(session, colitems, reporter, keyword=None): stopitems = py.test.collect.Item # XXX should be generator here as well for next in colitems: - session.start(next) + if session: + session.start(next) if isinstance(next, stopitems): try: next._skipbykeyword(keyword) @@ -31,7 +32,8 @@ reporter(repevent.SkippedTryiter(excinfo, next)) else: reporter(repevent.FailedTryiter(excinfo, next)) - session.finish(next) + if session: + session.finish(next) class AbstractSession(object): """ An abstract session executes collectors/items through a runner. Added: py/branch/reporter-merge/py/test/testing/test_itemgen.py ============================================================================== --- (empty file) +++ py/branch/reporter-merge/py/test/testing/test_itemgen.py Sun Oct 28 12:48:35 2007 @@ -0,0 +1,39 @@ + +import py +from py.__.test.session import itemgen +from py.__.test import repevent + +class TestItemgen: + def setup_class(cls): + tmp = py.test.ensuretemp('itemgentest') + tmp.ensure("__init__.py") + tmp.ensure("test_one.py").write(py.code.Source(""" + def test_one(): + pass + + class TestX: + def test_method_one(self): + pass + + class TestY(TestX): + pass + """)) + tmp.ensure("test_two.py").write(py.code.Source(""" + import py + py.test.skip('xxx') + """)) + tmp.ensure("test_three.py").write("xxxdsadsadsadsa") + cls.tmp = tmp + + def test_itemgen(self): + l = [] + colitems = [py.test.collect.Directory(self.tmp)] + gen = itemgen(None, colitems, l.append) + items = [i for i in gen] + assert len([i for i in l if isinstance(i, repevent.SkippedTryiter)]) == 1 + assert len([i for i in l if isinstance(i, repevent.FailedTryiter)]) == 1 + assert len(items) == 3 + assert items[0].name == 'test_one' + assert items[1].name == 'test_method_one' + assert items[2].name == 'test_method_one' + From fijal at codespeak.net Sun Oct 28 12:56:43 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 28 Oct 2007 12:56:43 +0100 (CET) Subject: [py-svn] r48127 - in py/branch/reporter-merge/py/test: . terminal testing Message-ID: <20071028115643.8F3548171@code0.codespeak.net> Author: fijal Date: Sun Oct 28 12:56:41 2007 New Revision: 48127 Removed: py/branch/reporter-merge/py/test/terminal/terminal.py Modified: py/branch/reporter-merge/py/test/config.py py/branch/reporter-merge/py/test/session.py py/branch/reporter-merge/py/test/testing/test_config.py py/branch/reporter-merge/py/test/testing/test_session.py Log: Remove terminal session as it's no longer needed Modified: py/branch/reporter-merge/py/test/config.py ============================================================================== --- py/branch/reporter-merge/py/test/config.py (original) +++ py/branch/reporter-merge/py/test/config.py Sun Oct 28 12:56:41 2007 @@ -159,7 +159,7 @@ def _getsessionname(self): """ return default session name as determined from options. """ - name = 'TerminalSession' + name = 'Session' if self.option.dist: name = 'RSession' else: @@ -263,7 +263,7 @@ # default import paths for sessions -TerminalSession = 'py.__.test.terminal.terminal' +Session = 'py.__.test.session' RemoteTerminalSession = 'py.__.test.terminal.remote' RSession = 'py.__.test.rsession.rsession' LSession = 'py.__.test.rsession.rsession' Modified: py/branch/reporter-merge/py/test/session.py ============================================================================== --- py/branch/reporter-merge/py/test/session.py (original) +++ py/branch/reporter-merge/py/test/session.py Sun Oct 28 12:56:41 2007 @@ -5,6 +5,15 @@ from py.__.test import repevent from py.__.test.outcome import SerializableOutcome, ReprOutcome +""" The session implementation - reporter version: + +* itemgen is responsible for iterating and telling reporter + about skipped and failed iterations (this is for collectors only), + this should be probably moved to session (for uniformity) +* session gets items which needs to be executed one after another + and tells reporter about that +""" + def itemgen(session, colitems, reporter, keyword=None): stopitems = py.test.collect.Item # XXX should be generator here as well for next in colitems: Deleted: /py/branch/reporter-merge/py/test/terminal/terminal.py ============================================================================== --- /py/branch/reporter-merge/py/test/terminal/terminal.py Sun Oct 28 12:56:41 2007 +++ (empty file) @@ -1,12 +0,0 @@ -import py - -from time import time as now -from py.__.test.terminal.out import getout -from py.__.test.representation import Presenter, getrelpath -from py.__.test.outcome import Skipped, Passed, Failed -import py.__.test.custompdb - -from py.__.test.session import Session - -class TerminalSession(Session): - pass Modified: py/branch/reporter-merge/py/test/testing/test_config.py ============================================================================== --- py/branch/reporter-merge/py/test/testing/test_config.py (original) +++ py/branch/reporter-merge/py/test/testing/test_config.py Sun Oct 28 12:56:41 2007 @@ -200,7 +200,7 @@ def test_sessionname_default(self): config = py.test.config._reparse([self.tmpdir]) - assert config._getsessionname() == 'TerminalSession' + assert config._getsessionname() == 'Session' def test_sessionname_dist(self): config = py.test.config._reparse([self.tmpdir, '--dist']) Modified: py/branch/reporter-merge/py/test/testing/test_session.py ============================================================================== --- py/branch/reporter-merge/py/test/testing/test_session.py (original) +++ py/branch/reporter-merge/py/test/testing/test_session.py Sun Oct 28 12:56:41 2007 @@ -130,11 +130,11 @@ class TestTerminalSession: def mainsession(self, *args): - from py.__.test.terminal.terminal import TerminalSession + from py.__.test.session import Session from py.__.test.terminal.out import getout config = py.test.config._reparse(list(args)) all = [] - session = TerminalSession(config, all.append) + session = Session(config, all.append) session.main() return session, all From fijal at codespeak.net Sun Oct 28 14:24:42 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 28 Oct 2007 14:24:42 +0100 (CET) Subject: [py-svn] r48128 - in py/branch/reporter-merge/py/test: . rsession rsession/testing testing Message-ID: <20071028132442.2F80C80EC@code0.codespeak.net> Author: fijal Date: Sun Oct 28 14:24:41 2007 New Revision: 48128 Modified: py/branch/reporter-merge/py/test/config.py py/branch/reporter-merge/py/test/reporter.py py/branch/reporter-merge/py/test/rsession/rsession.py py/branch/reporter-merge/py/test/rsession/testing/test_rsession.py py/branch/reporter-merge/py/test/session.py py/branch/reporter-merge/py/test/testing/test_collect.py py/branch/reporter-merge/py/test/testing/test_reporter.py py/branch/reporter-merge/py/test/testing/test_session.py Log: Small regactoring for simple usage of default reporter class Modified: py/branch/reporter-merge/py/test/config.py ============================================================================== --- py/branch/reporter-merge/py/test/config.py (original) +++ py/branch/reporter-merge/py/test/config.py Sun Oct 28 14:24:41 2007 @@ -134,10 +134,10 @@ except AttributeError: return self._conftest.rget(name, path) - def initsession(self, reporter=None): + def initsession(self): """ return an initialized session object. """ cls = self._getsessionclass() - session = cls(self, reporter) + session = cls(self) session.fixoptions() return session Modified: py/branch/reporter-merge/py/test/reporter.py ============================================================================== --- py/branch/reporter-merge/py/test/reporter.py (original) +++ py/branch/reporter-merge/py/test/reporter.py Sun Oct 28 14:24:41 2007 @@ -18,7 +18,7 @@ from time import time as now -def choose_reporter(config): +def choose_reporter(reporterclass, config): option = config.option if option.startserver or option.runbrowser: from py.__.test.rsession.web import WebReporter @@ -27,10 +27,7 @@ from py.__.test.rsession.rest import RestReporter return RestReporter else: - if option.dist: - return RemoteReporter - else: - return LocalReporter + return reporterclass class TestReporter(object): """ Simple test reporter which tracks failures Modified: py/branch/reporter-merge/py/test/rsession/rsession.py ============================================================================== --- py/branch/reporter-merge/py/test/rsession/rsession.py (original) +++ py/branch/reporter-merge/py/test/rsession/rsession.py Sun Oct 28 14:24:41 2007 @@ -20,6 +20,8 @@ class RSession(AbstractSession): """ Remote version of session """ + reporter = RemoteReporter + def fixoptions(self): super(RSession, self).fixoptions() option = self.config.option @@ -41,13 +43,12 @@ print "see also: http://codespeak.net/py/current/doc/test.html#automated-distributed-testing" raise SystemExit - def main(self): + def main(self, reporter=None): """ main loop for running tests. """ config = self.config hm = HostManager(config) - reporter, checkfun = self.init_reporter(self.reporter, config, - hm.hosts) + reporter, checkfun = self.init_reporter(reporter, config, hm.hosts) reporter(repevent.TestStarted(hm.hosts, self.config, hm.roots)) Modified: py/branch/reporter-merge/py/test/rsession/testing/test_rsession.py ============================================================================== --- py/branch/reporter-merge/py/test/rsession/testing/test_rsession.py (original) +++ py/branch/reporter-merge/py/test/rsession/testing/test_rsession.py Sun Oct 28 14:24:41 2007 @@ -35,8 +35,8 @@ """)) config = py.test.config._reparse([self.source.join("sub"), '-x']) allevents = [] - rsession = RSession(config, allevents.append) - rsession.main() + rsession = RSession(config) + rsession.main(allevents.append) testevents = [x for x in allevents if isinstance(x, repevent.ReceivedItemOutcome)] assert len(testevents) == 3 @@ -70,8 +70,8 @@ assert config.topdir == tmpdir assert not tmpdir.join("__init__.py").check() allevents = [] - rsession = RSession(config, allevents.append) - rsession.main() + rsession = RSession(config) + rsession.main(allevents.append) testevents = [x for x in allevents if isinstance(x, repevent.ReceivedItemOutcome)] assert len(testevents) @@ -176,8 +176,8 @@ """) config = py.test.config._reparse([tmpdir]) - rsession = RSession(config, allevents.append) - rsession.main() + rsession = RSession(config) + rsession.main(allevents.append) testevents = [x for x in allevents if isinstance(x, repevent.ReceivedItemOutcome)] passevents = [x for x in testevents if x.outcome.passed] Modified: py/branch/reporter-merge/py/test/session.py ============================================================================== --- py/branch/reporter-merge/py/test/session.py (original) +++ py/branch/reporter-merge/py/test/session.py Sun Oct 28 14:24:41 2007 @@ -4,6 +4,7 @@ from py.__.test.reporter import choose_reporter, TestReporter from py.__.test import repevent from py.__.test.outcome import SerializableOutcome, ReprOutcome +from py.__.test.reporter import LocalReporter """ The session implementation - reporter version: @@ -47,10 +48,9 @@ class AbstractSession(object): """ An abstract session executes collectors/items through a runner. """ - def __init__(self, config, reporter=None): + def __init__(self, config): self.config = config self._keyword = config.option.keyword - self.reporter = reporter def fixoptions(self): """ check, fix and determine conflicting options. """ @@ -77,7 +77,8 @@ def init_reporter(self, reporter, config, hosts): if reporter is None: - reporter = choose_reporter(config)(config, hosts) + reporter = choose_reporter(self.reporterclass, config)\ + (config, hosts) else: reporter = TestReporter(reporter) checkfun = lambda : self.config.option.exitfirst and \ @@ -99,6 +100,8 @@ A Session gets test Items from Collectors, executes the Items and sends the Outcome to the Reporter. """ + reporterclass = LocalReporter + def shouldclose(self): return False @@ -116,11 +119,11 @@ py.magic.revoke(assertion=1) self.reporter(repevent.TestFinished()) - def main(self): + def main(self, reporter=None): """ main loop for running tests. """ config = self.config - self.reporter, self.shouldstop = self.init_reporter(self.reporter, - config, ['localhost']) + self.reporter, shouldstop = self.init_reporter(reporter, + config, ['localhost']) colitems = self.config.getcolitems() self.header(colitems) @@ -131,7 +134,7 @@ while 1: try: item = itemgenerator.next() - if self.shouldstop(): + if shouldstop(): return outcome = self.run(item) reporter(repevent.ReceivedItemOutcome(None, item, outcome)) Modified: py/branch/reporter-merge/py/test/testing/test_collect.py ============================================================================== --- py/branch/reporter-merge/py/test/testing/test_collect.py (original) +++ py/branch/reporter-merge/py/test/testing/test_collect.py Sun Oct 28 14:24:41 2007 @@ -211,8 +211,8 @@ try: config = py.test.config._reparse([]) all = [] - session = config._getsessionclass()(config, all.append) - session.main() + session = config._getsessionclass()(config) + session.main(all.append) l = getpassed(all) assert len(l) == 2 finally: @@ -221,8 +221,8 @@ # test that running the file directly works config = py.test.config._reparse([str(checkfile)]) all = [] - session = config._getsessionclass()(config, all.append) - session.main() + session = config._getsessionclass()(config) + session.main(all.append) l = getpassed(all) assert len(l) == 2 @@ -258,8 +258,8 @@ try: config = py.test.config._reparse([]) all = [] - session = config._getsessionclass()(config, all.append) - session.main() + session = config._getsessionclass()(config) + session.main(all.append) l = getpassed(all) assert len(l) == 1 finally: @@ -268,8 +268,8 @@ # test that running the file directly works config = py.test.config._reparse([str(checkfile)]) all = [] - session = config._getsessionclass()(config, all.append) - session.main() + session = config._getsessionclass()(config) + session.main(all.append) l = getpassed(all) assert len(l) == 1 @@ -294,8 +294,8 @@ """)) config = py.test.config._reparse([o]) all = [] - session = config.initsession(all.append) - session.main() + session = config.initsession() + session.main(all.append) l = getpassed(all) assert len(l) == 7 @@ -327,8 +327,8 @@ """)) config = py.test.config._reparse([o]) all = [] - session = config.initsession(all.append) - session.main() + session = config.initsession() + session.main(all.append) l = getpassed(all) assert len(l) == 4 Modified: py/branch/reporter-merge/py/test/testing/test_reporter.py ============================================================================== --- py/branch/reporter-merge/py/test/testing/test_reporter.py (original) +++ py/branch/reporter-merge/py/test/testing/test_reporter.py Sun Oct 28 14:24:41 2007 @@ -257,12 +257,10 @@ from py.__.test.rsession.web import WebReporter from py.__.test.rsession.rest import RestReporter choices = [ - (['-d'], RemoteReporter), (['-d', '--rest'], RestReporter), - ([], LocalReporter), (['-w'], WebReporter), (['-r'], WebReporter)] for opts, reporter in choices: config = py.test.config._reparse(['xxx'] + opts) - assert choose_reporter(config) is reporter + assert choose_reporter(None, config) is reporter Modified: py/branch/reporter-merge/py/test/testing/test_session.py ============================================================================== --- py/branch/reporter-merge/py/test/testing/test_session.py (original) +++ py/branch/reporter-merge/py/test/testing/test_session.py Sun Oct 28 14:24:41 2007 @@ -62,8 +62,8 @@ def runfiletest(opts): config = py.test.config._reparse(opts + [datadir/'filetest.py']) all = [] - session = config.initsession(all.append) - session.main() + session = config.initsession() + session.main(all.append) assert len(getfailed(all)) == 2 assert not getskipped(all) @@ -77,8 +77,8 @@ config = py.test.config._reparse([datadir/'filetest.py', '-s', '-k', keyword]) all = [] - session = config._getsessionclass()(config, all.append) - session.main() + session = config._getsessionclass()(config) + session.main(all.append) outcomes = [i for i in all if isinstance(i, ReceivedItemOutcome)] assert len(getfailed(all)) == 1 assert outcomes[0].item.name == name @@ -108,8 +108,8 @@ 'TestClass test_2', 'xxx TestClass test_2',): config = py.test.config._reparse([o, '-s', '-k', keyword]) all = [] - session = config._getsessionclass()(config, all.append) - session.main() + session = config._getsessionclass()(config) + session.main(all.append) print "keyword", repr(keyword) l = getpassed(all) outcomes = [i for i in all if isinstance(i, ReceivedItemOutcome)] @@ -122,8 +122,8 @@ config = py.test.config._reparse([datadir/'testmore.py', '-j', '-k', "test_two"]) all = [] - session = config._getsessionclass()(config, all.append) - session.main() + session = config._getsessionclass()(config) + session.main(all.append) assert len(getpassed(all)) == 2 assert len(getskipped(all)) == 1 @@ -134,8 +134,8 @@ from py.__.test.terminal.out import getout config = py.test.config._reparse(list(args)) all = [] - session = Session(config, all.append) - session.main() + session = Session(config) + session.main(all.append) return session, all def test_terminal(self): @@ -326,8 +326,8 @@ tmp.ensure("__init__.py") config = py.test.config._reparse([tmp]) all = [] - session = config.initsession(all.append) - session.main() + session = config.initsession() + session.main(all.append) skips = getskipped(all) assert len(skips) == 2 assert str(skips[0].skipped.value) == 'Broken: stuff' From fijal at codespeak.net Sun Oct 28 14:41:07 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 28 Oct 2007 14:41:07 +0100 (CET) Subject: [py-svn] r48129 - in py/branch/reporter-merge/py/test: . rsession rsession/testing testing Message-ID: <20071028134107.0C2CA8105@code0.codespeak.net> Author: fijal Date: Sun Oct 28 14:41:06 2007 New Revision: 48129 Modified: py/branch/reporter-merge/py/test/reporter.py py/branch/reporter-merge/py/test/rsession/rest.py py/branch/reporter-merge/py/test/rsession/testing/test_rest.py py/branch/reporter-merge/py/test/session.py py/branch/reporter-merge/py/test/testing/test_reporter.py Log: Refactor LocalReporter not to rely on hosts being there Modified: py/branch/reporter-merge/py/test/reporter.py ============================================================================== --- py/branch/reporter-merge/py/test/reporter.py (original) +++ py/branch/reporter-merge/py/test/reporter.py Sun Oct 28 14:41:06 2007 @@ -56,9 +56,6 @@ self.skipped_tests_outcome = [] self.out = getout(py.std.sys.stdout) self.presenter = Presenter(self.out, config) - self.failed = dict([(host, 0) for host in hosts]) - self.skipped = dict([(host, 0) for host in hosts]) - self.passed = dict([(host, 0) for host in hosts]) self.to_rsync = {} def get_item_name(self, event, colitem): @@ -249,6 +246,9 @@ def summary(self): def gather(dic): + # XXX hack to handle dicts & ints here, get rid of it + if isinstance(dic, int): + return dic total = 0 for key, val in dic.iteritems(): total += val @@ -316,7 +316,13 @@ def was_failure(self): return sum(self.failed.values()) > 0 -class RemoteReporter(AbstractReporter): +class RemoteReporter(AbstractReporter): + def __init__(self, config, hosts): + super(RemoteReporter, self).__init__(config, hosts) + self.failed = dict([(host, 0) for host in hosts]) + self.skipped = dict([(host, 0) for host in hosts]) + self.passed = dict([(host, 0) for host in hosts]) + def get_item_name(self, event, colitem): return event.host.hostname + ":" + \ "/".join(colitem.listnames()) @@ -332,6 +338,13 @@ join(event.item.listnames()))) class LocalReporter(AbstractReporter): + def __init__(self, config, hosts=None): + assert not hosts + super(LocalReporter, self).__init__(config, hosts) + self.failed = 0 + self.skipped = 0 + self.passed = 0 + def report_TestStarted(self, item): colitems = item.config.getcolitems() txt = " test process starts " @@ -371,19 +384,18 @@ #self.show_item(event.item, False) self.out.write("- FAILED TO LOAD MODULE") self.failed_tests_outcome.append(event) - self.failed[self.hosts[0]] += 1 + self.failed += 1 def report_ReceivedItemOutcome(self, event): - host = self.hosts[0] if event.outcome.passed: - self.passed[host] += 1 + self.passed += 1 self.out.write(".") elif event.outcome.skipped: self.skipped_tests_outcome.append(event) - self.skipped[host] += 1 + self.skipped += 1 self.out.write("s") else: - self.failed[host] += 1 + self.failed += 1 self.failed_tests_outcome.append(event) self.out.write("F") @@ -418,3 +430,6 @@ def hangs(self): pass + + def was_failure(self): + return self.failed > 0 Modified: py/branch/reporter-merge/py/test/rsession/rest.py ============================================================================== --- py/branch/reporter-merge/py/test/rsession/rest.py (original) +++ py/branch/reporter-merge/py/test/rsession/rest.py Sun Oct 28 14:41:06 2007 @@ -12,10 +12,13 @@ class RestReporter(AbstractReporter): linkwriter = None - def __init__(self, *args, **kwargs): - super(RestReporter, self).__init__(*args, **kwargs) + def __init__(self, config, hosts): + super(RestReporter, self).__init__(config, hosts) self.rest = Rest() self.traceback_num = 0 + self.failed = dict([(host, 0) for host in hosts]) + self.skipped = dict([(host, 0) for host in hosts]) + self.passed = dict([(host, 0) for host in hosts]) def get_linkwriter(self): if self.linkwriter is None: Modified: py/branch/reporter-merge/py/test/rsession/testing/test_rest.py ============================================================================== --- py/branch/reporter-merge/py/test/rsession/testing/test_rest.py (original) +++ py/branch/reporter-merge/py/test/rsession/testing/test_rest.py Sun Oct 28 14:41:06 2007 @@ -332,6 +332,9 @@ class TestRestReporter(AbstractTestReporter): reporter = RestReporter + def get_hosts(self): + return [HostInfo('localhost')] + def test_failed_to_load(self): py.test.skip("Not implemented") Modified: py/branch/reporter-merge/py/test/session.py ============================================================================== --- py/branch/reporter-merge/py/test/session.py (original) +++ py/branch/reporter-merge/py/test/session.py Sun Oct 28 14:41:06 2007 @@ -122,8 +122,7 @@ def main(self, reporter=None): """ main loop for running tests. """ config = self.config - self.reporter, shouldstop = self.init_reporter(reporter, - config, ['localhost']) + self.reporter, shouldstop = self.init_reporter(reporter, config, None) colitems = self.config.getcolitems() self.header(colitems) Modified: py/branch/reporter-merge/py/test/testing/test_reporter.py ============================================================================== --- py/branch/reporter-merge/py/test/testing/test_reporter.py (original) +++ py/branch/reporter-merge/py/test/testing/test_reporter.py Sun Oct 28 14:41:06 2007 @@ -75,9 +75,12 @@ outcomes = self.prepare_outcomes() def boxfun(config, item, outcomes): - hosts = [HostInfo("localhost")] + hosts = self.get_hosts() r = self.reporter(config, hosts) - ch = DummyChannel(hosts[0]) + if hosts: + ch = DummyChannel(hosts[0]) + else: + ch = None for outcome in outcomes: r.report(repevent.ReceivedItemOutcome(ch, item, outcome)) @@ -93,10 +96,13 @@ outcomes = self.prepare_outcomes() def boxfun(config, item, funcitem, outcomes): - hosts = [HostInfo('localhost')] + hosts = self.get_hosts() r = self.reporter(config, hosts) r.report(repevent.ItemStart(item)) - ch = DummyChannel(hosts[0]) + if hosts: + ch = DummyChannel(hosts[0]) + else: + ch = None for outcome in outcomes: r.report(repevent.ReceivedItemOutcome(ch, funcitem, outcome)) @@ -124,7 +130,7 @@ def boxfun(): config = py.test.config._reparse([str(tmpdir)]) rootcol = py.test.collect.Directory(tmpdir) - hosts = [HostInfo('localhost')] + hosts = self.get_hosts() r = self.reporter(config, hosts) list(itemgen(MockSession(r), [rootcol], r.report)) @@ -143,9 +149,9 @@ def boxfun(): config = py.test.config._reparse([str(tmpdir)]) rootcol = py.test.collect.Directory(tmpdir) - host = HostInfo('localhost') - r = self.reporter(config, [host]) - r.report(repevent.TestStarted([host], config, ["a"])) + hosts = self.get_hosts() + r = self.reporter(config, hosts) + r.report(repevent.TestStarted(hosts, config, ["a"])) r.report(repevent.RsyncFinished()) list(itemgen(MockSession(r), [rootcol], r.report)) r.report(repevent.TestFinished()) @@ -164,7 +170,7 @@ tmpdir.ensure("test_one.py").write("def test_x(): pass") cap = py.io.StdCaptureFD() config = py.test.config._reparse([str(tmpdir), '-v']) - hosts = [HostInfo("host")] + hosts = self.get_hosts() r = self.reporter(config, hosts) r.report(repevent.TestStarted(hosts, config, [])) r.report(repevent.RsyncFinished()) @@ -205,6 +211,9 @@ class TestLocalReporter(AbstractTestReporter): reporter = LocalReporter + + def get_hosts(self): + return None def test_report_received_item_outcome(self): assert self.report_received_item_outcome() == 'FsF.' @@ -227,12 +236,15 @@ class TestRemoteReporter(AbstractTestReporter): reporter = RemoteReporter + def get_hosts(self): + return [HostInfo("host")] + def test_still_to_go(self): self._test_still_to_go() def test_report_received_item_outcome(self): val = self.report_received_item_outcome() - expected_lst = ["localhost", "FAILED", + expected_lst = ["host", "FAILED", "funcpass", "test_one", "SKIPPED", "PASSED"] @@ -241,7 +253,7 @@ def test_module(self): val = self._test_module() - expected_lst = ["localhost", "FAILED", + expected_lst = ["host", "FAILED", "funcpass", "test_one", "SKIPPED", "PASSED"] From fijal at codespeak.net Sun Oct 28 14:58:43 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 28 Oct 2007 14:58:43 +0100 (CET) Subject: [py-svn] r48130 - in py/branch/reporter-merge/py/test: . testing Message-ID: <20071028135843.F15D2813D@code0.codespeak.net> Author: fijal Date: Sun Oct 28 14:58:42 2007 New Revision: 48130 Added: py/branch/reporter-merge/py/test/collectonly.py (contents, props changed) py/branch/reporter-merge/py/test/testing/test_collectonly.py (contents, props changed) Modified: py/branch/reporter-merge/py/test/config.py py/branch/reporter-merge/py/test/repevent.py py/branch/reporter-merge/py/test/session.py py/branch/reporter-merge/py/test/testing/test_config.py py/branch/reporter-merge/py/test/testing/test_session.py Log: Add --collectonly handling, new style, logic separated Added: py/branch/reporter-merge/py/test/collectonly.py ============================================================================== --- (empty file) +++ py/branch/reporter-merge/py/test/collectonly.py Sun Oct 28 14:58:42 2007 @@ -0,0 +1,37 @@ + +""" --collectonly session, not to spread logic all over the place +""" + +import py +from py.__.test.session import Session +from py.__.test.reporter import LocalReporter + +class CollectReporter(LocalReporter): + def __init__(self, *args, **kwds): + super(LocalReporter, self).__init__(*args, **kwds) + self.indent = 0 + + def report_ReceivedItemOutcome(self, event): + pass + + def report_ItemStart(self, event): + self.out.line(" " * self.indent + str(event.item)) + self.indent += 2 + + def report_ItemFinish(self, event): + self.indent -= 2 + + def report_FailedTryiter(self, event): + self.out.line(" " * self.indent + "- FAILED TO LOAD MODULE -") + + def report_SkippedTryiter(self, event): + self.out.line(" " * self.indent + "- skipped -") + + def summary(self): + self.out.sep("=", "Total time: %.1f" % (self.timeend - self.timestart)) + +class CollectSession(Session): + reporterclass = CollectReporter + + def run(self, item): + pass Modified: py/branch/reporter-merge/py/test/config.py ============================================================================== --- py/branch/reporter-merge/py/test/config.py (original) +++ py/branch/reporter-merge/py/test/config.py Sun Oct 28 14:58:42 2007 @@ -162,6 +162,8 @@ name = 'Session' if self.option.dist: name = 'RSession' + elif self.option.collectonly: + name = 'CollectSession' else: if self.option.looponfailing or self.option.executable: name = 'RemoteTerminalSession' @@ -267,6 +269,7 @@ RemoteTerminalSession = 'py.__.test.terminal.remote' RSession = 'py.__.test.rsession.rsession' LSession = 'py.__.test.rsession.rsession' +CollectSession = 'py.__.test.collectonly' # # helpers Modified: py/branch/reporter-merge/py/test/repevent.py ============================================================================== --- py/branch/reporter-merge/py/test/repevent.py (original) +++ py/branch/reporter-merge/py/test/repevent.py Sun Oct 28 14:58:42 2007 @@ -131,6 +131,13 @@ def __init__(self, item): self.item = item +class ItemFinish(ReportEvent): + """ This class shows most of the start stuff, like directory, module, class + can be used for containers + """ + def __init__(self, item): + self.item = item + class RsyncFinished(ReportEvent): def __init__(self): self.time = time.time() Modified: py/branch/reporter-merge/py/test/session.py ============================================================================== --- py/branch/reporter-merge/py/test/session.py (original) +++ py/branch/reporter-merge/py/test/session.py Sun Oct 28 14:58:42 2007 @@ -93,7 +93,7 @@ def finish(self, item): """ A hook invoked per every item ending """ - pass + self.reporter(repevent.ItemFinish(item)) class Session(AbstractSession): """ Added: py/branch/reporter-merge/py/test/testing/test_collectonly.py ============================================================================== --- (empty file) +++ py/branch/reporter-merge/py/test/testing/test_collectonly.py Sun Oct 28 14:58:42 2007 @@ -0,0 +1,49 @@ + +import py + +class TestCollectonly: + def setup_class(cls): + tmp = py.test.ensuretemp('itemgentest') + tmp.ensure("__init__.py") + tmp.ensure("test_one.py").write(py.code.Source(""" + def test_one(): + pass + + class TestX: + def test_method_one(self): + pass + + class TestY(TestX): + pass + """)) + tmp.ensure("test_two.py").write(py.code.Source(""" + import py + py.test.skip('xxx') + """)) + tmp.ensure("test_three.py").write("xxxdsadsadsadsa") + cls.tmp = tmp + + def test_collectonly(self): + config = py.test.config._reparse([self.tmp, '--collectonly']) + session = config.initsession() + # test it all in once + cap = py.io.StdCaptureFD() + session.main() + out, err = cap.reset() + # XXX exact output matching + lines = """ + + + + + + + + + + - FAILED TO LOAD MODULE - + + - skipped - +""" + for line in lines: + assert line in out Modified: py/branch/reporter-merge/py/test/testing/test_config.py ============================================================================== --- py/branch/reporter-merge/py/test/testing/test_config.py (original) +++ py/branch/reporter-merge/py/test/testing/test_config.py Sun Oct 28 14:58:42 2007 @@ -224,6 +224,8 @@ assert config._getsessionname() == 'RemoteTerminalSession' config = py.test.config._reparse([self.tmpdir, '--dist', '--exec=x']) assert config._getsessionname() == 'RSession' + config = py.test.config._reparse([self.tmpdir, '--collectonly']) + assert config._getsessionname() == 'CollectSession' def test_sessionname_lookup_custom(self): self.tmpdir.join("conftest.py").write(py.code.Source(""" Modified: py/branch/reporter-merge/py/test/testing/test_session.py ============================================================================== --- py/branch/reporter-merge/py/test/testing/test_session.py (original) +++ py/branch/reporter-merge/py/test/testing/test_session.py Sun Oct 28 14:58:42 2007 @@ -158,22 +158,6 @@ assert len(getfailed(all)) == 1 assert not getpassed(all) - def test_collectonly(self): - py.test.skip("XXX Reimplement this feature") - session, out = self.mainsession("--collectonly", - datadir / 'filetest.py') - assert session.config.option.collectonly - #print out - l = session.getitemoutcomepairs(Failed) - #if l: - # x = l[0][1].excinfo - # print x.exconly() - # print x.traceback - assert len(l) == 0 - for line in ('filetest.py', 'test_one', - 'TestClass', 'test_method_one'): - assert out.find(line) - def test_recursion_detection(self): py.test.skip("XXX the test is bogus here") o = tmpdir.ensure('recursiontest', dir=1) From fijal at codespeak.net Sun Oct 28 19:08:34 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 28 Oct 2007 19:08:34 +0100 (CET) Subject: [py-svn] r48134 - py/branch/reporter-merge/py/test/testing Message-ID: <20071028180834.A01C18139@code0.codespeak.net> Author: fijal Date: Sun Oct 28 19:08:33 2007 New Revision: 48134 Modified: py/branch/reporter-merge/py/test/testing/test_config.py Log: Remove part of the test checking for LSession Modified: py/branch/reporter-merge/py/test/testing/test_config.py ============================================================================== --- py/branch/reporter-merge/py/test/testing/test_config.py (original) +++ py/branch/reporter-merge/py/test/testing/test_config.py Sun Oct 28 19:08:33 2007 @@ -207,17 +207,16 @@ assert config._getsessionname() == 'RSession' def test_implied_lsession(self): - py.test.skip("Different sessions probably") - optnames = 'startserver runbrowser apigen=x rest boxed'.split() - for x in optnames: - config = py.test.config._reparse([self.tmpdir, '--%s' % x]) - assert config._getsessionname() == 'LSession' + #optnames = 'startserver runbrowser apigen=x rest boxed'.split() + #for x in optnames: + # config = py.test.config._reparse([self.tmpdir, '--%s' % x]) + # assert config._getsessionname() == 'LSession' for x in 'startserver runbrowser rest'.split(): config = py.test.config._reparse([self.tmpdir, '--dist', '--%s' % x]) assert config._getsessionname() == 'RSession' - def test_implied_remote_terminal_session(self): + def test_implied_different_sessions(self): config = py.test.config._reparse([self.tmpdir, '--looponfailing']) assert config._getsessionname() == 'RemoteTerminalSession' config = py.test.config._reparse([self.tmpdir, '--exec=x']) From fijal at codespeak.net Sun Oct 28 19:10:31 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 28 Oct 2007 19:10:31 +0100 (CET) Subject: [py-svn] r48135 - py/branch/reporter-merge/py/apigen/testing Message-ID: <20071028181031.53E978139@code0.codespeak.net> Author: fijal Date: Sun Oct 28 19:10:31 2007 New Revision: 48135 Modified: py/branch/reporter-merge/py/apigen/testing/test_apigen_functional.py Log: Disable apigen tests. Apigen needs some rethinking as it's not a very usable tool right now. Modified: py/branch/reporter-merge/py/apigen/testing/test_apigen_functional.py ============================================================================== --- py/branch/reporter-merge/py/apigen/testing/test_apigen_functional.py (original) +++ py/branch/reporter-merge/py/apigen/testing/test_apigen_functional.py Sun Oct 28 19:10:31 2007 @@ -5,6 +5,7 @@ import py from py.__.apigen import apigen +py.test.skip("Apigen functionality temporarily disabled") def setup_module(mod): if py.std.sys.platform == "win32": From fijal at codespeak.net Sun Oct 28 19:16:48 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 28 Oct 2007 19:16:48 +0100 (CET) Subject: [py-svn] r48136 - in py/branch/reporter-merge/py/test: . rsession rsession/testing testing Message-ID: <20071028181648.8AFE48124@code0.codespeak.net> Author: fijal Date: Sun Oct 28 19:16:47 2007 New Revision: 48136 Added: py/branch/reporter-merge/py/test/box.py - copied unchanged from r47660, py/branch/reporter-merge/py/test/rsession/box.py py/branch/reporter-merge/py/test/executor.py - copied unchanged from r47678, py/branch/reporter-merge/py/test/rsession/executor.py py/branch/reporter-merge/py/test/test_executor.py - copied, changed from r47660, py/branch/reporter-merge/py/test/rsession/testing/test_executor.py py/branch/reporter-merge/py/test/testing/test_boxing.py - copied unchanged from r47660, py/branch/reporter-merge/py/test/rsession/testing/test_boxing.py Removed: py/branch/reporter-merge/py/test/rsession/box.py py/branch/reporter-merge/py/test/rsession/executor.py py/branch/reporter-merge/py/test/rsession/testing/test_boxing.py py/branch/reporter-merge/py/test/rsession/testing/test_executor.py Modified: py/branch/reporter-merge/py/test/rsession/rsession.py Log: Intermediate checkin to start moving things Deleted: /py/branch/reporter-merge/py/test/rsession/box.py ============================================================================== --- /py/branch/reporter-merge/py/test/rsession/box.py Sun Oct 28 19:16:47 2007 +++ (empty file) @@ -1,120 +0,0 @@ - -""" boxing - wrapping process with another process so we can run -a process inside and see if it crashes -""" - -import py -import os -import sys -import marshal -from py.__.test import config as pytestconfig - -PYTESTSTDOUT = "pyteststdout" -PYTESTSTDERR = "pyteststderr" -PYTESTRETVAL = "pytestretval" - -import tempfile -import itertools -from StringIO import StringIO - -counter = itertools.count().next - -class FileBox(object): - def __init__(self, fun, args=None, kwargs=None, config=None): - if args is None: - args = [] - if kwargs is None: - kwargs = {} - self.fun = fun - self.config = config - assert self.config - self.args = args - self.kwargs = kwargs - - def run(self, continuation=False): - # XXX we should not use py.test.ensuretemp here - count = counter() - tempdir = py.test.ensuretemp("box%d" % count) - self.tempdir = tempdir - self.PYTESTRETVAL = tempdir.join('retval') - self.PYTESTSTDOUT = tempdir.join('stdout') - self.PYTESTSTDERR = tempdir.join('stderr') - - nice_level = self.config.getvalue('dist_nicelevel') - pid = os.fork() - if pid: - if not continuation: - self.parent(pid) - else: - return self.parent, pid - else: - try: - outcome = self.children(nice_level) - except: - excinfo = py.code.ExceptionInfo() - x = open("/tmp/traceback", "w") - print >>x, "Internal box error" - for i in excinfo.traceback: - print >>x, str(i)[2:-1] - print >>x, excinfo - x.close() - os._exit(1) - os.close(1) - os.close(2) - os._exit(0) - return pid - - def children(self, nice_level): - # right now we need to call a function, but first we need to - # map all IO that might happen - # make sure sys.stdout points to file descriptor one - sys.stdout = stdout = self.PYTESTSTDOUT.open('w') - sys.stdout.flush() - fdstdout = stdout.fileno() - if fdstdout != 1: - os.dup2(fdstdout, 1) - sys.stderr = stderr = self.PYTESTSTDERR.open('w') - fdstderr = stderr.fileno() - if fdstderr != 2: - os.dup2(fdstderr, 2) - retvalf = self.PYTESTRETVAL.open("w") - try: - if nice_level: - os.nice(nice_level) - # with fork() we have duplicated py.test's basetemp - # directory so we want to set it manually here. - # this may be expensive for some test setups, - # but that is what you get with boxing. - # XXX but we are called in more than strict boxing - # mode ("AsyncExecutor") so we can't do the following without - # inflicting on --dist speed, hum: - # pytestconfig.basetemp = self.tempdir.join("childbasetemp") - retval = self.fun(*self.args, **self.kwargs) - retvalf.write(marshal.dumps(retval)) - finally: - stdout.close() - stderr.close() - retvalf.close() - os._exit(0) - - def parent(self, pid, waiter=os.waitpid): - pid, exitstat = waiter(pid, 0) - self.signal = exitstat & 0x7f - self.exitstat = exitstat & 0xff00 - - - if not exitstat: - retval = self.PYTESTRETVAL.open() - try: - retval_data = retval.read() - finally: - retval.close() - self.retval = marshal.loads(retval_data) - else: - self.retval = None - - self.stdoutrepr = self.PYTESTSTDOUT.read() - self.stderrrepr = self.PYTESTSTDERR.read() - return self.stdoutrepr, self.stderrrepr - -Box = FileBox Deleted: /py/branch/reporter-merge/py/test/rsession/executor.py ============================================================================== --- /py/branch/reporter-merge/py/test/rsession/executor.py Sun Oct 28 19:16:47 2007 +++ (empty file) @@ -1,136 +0,0 @@ -""" Remote executor -""" - -import py, os, sys - -from py.__.test.outcome import SerializableOutcome, ReprOutcome -from py.__.test.rsession.box import Box -from py.__.test import repevent -from py.__.test.outcome import Skipped, Failed -import py.__.test.custompdb - -class RunExecutor(object): - """ Same as in executor, but just running run - """ - wraps = False - - def __init__(self, item, usepdb=False, reporter=None, config=None): - self.item = item - self.usepdb = usepdb - self.reporter = reporter - self.config = config - assert self.config - - def run(self, capture=True): - if capture: - self.item.startcapture() - try: - self.item.run() - finally: - self.item.finishcapture() - else: - self.item.run() - - def execute(self, capture=True): - try: - self.run(capture) - outcome = SerializableOutcome() - except Skipped: - e = py.code.ExceptionInfo() - outcome = SerializableOutcome(skipped=e) - except (SystemExit, KeyboardInterrupt): - raise - except: - e = sys.exc_info()[1] - if isinstance(e, Failed) and e.excinfo: - excinfo = e.excinfo - else: - excinfo = py.code.ExceptionInfo() - if isinstance(self.item, py.test.collect.Function): - fun = self.item.obj # hope this is stable - code = py.code.Code(fun) - excinfo.traceback = excinfo.traceback.cut( - path=code.path, firstlineno=code.firstlineno) - outcome = SerializableOutcome(excinfo=excinfo, setupfailure=False) - if self.usepdb: - if self.reporter is not None: - self.reporter(repevent.ImmediateFailure(self.item, - ReprOutcome(outcome.make_repr - (self.config.option.tbstyle)))) - py.__.test.custompdb.post_mortem(excinfo._excinfo[2]) - # XXX hmm, we probably will not like to continue from that - # point - raise SystemExit() - outcome.stdout, outcome.stderr = self.item._getouterr() - return outcome - -class ApigenExecutor(RunExecutor): - """ Same as RunExecutor, but takes tracer to trace calls as - an argument to execute - """ - def execute(self, tracer): - self.tracer = tracer - return super(ApigenExecutor, self).execute() - - def wrap_underlaying(self, target, *args): - try: - self.tracer.start_tracing() - return target(*args) - finally: - self.tracer.end_tracing() - - def run(self, capture): - """ We want to trace *only* function objects here. Unsure - what to do with custom collectors at all - """ - if hasattr(self.item, 'obj') and type(self.item) is py.test.collect.Function: - self.item.execute = self.wrap_underlaying - self.item.run() - -class BoxExecutor(RunExecutor): - """ Same as RunExecutor, but boxes test instead - """ - wraps = True - - def execute(self): - def fun(): - outcome = RunExecutor.execute(self, False) - return outcome.make_repr(self.config.option.tbstyle) - b = Box(fun, config=self.config) - pid = b.run() - assert pid - if b.retval is not None: - passed, setupfailure, excinfo, skipped, critical, _, _, _\ - = b.retval - return (passed, setupfailure, excinfo, skipped, critical, 0, - b.stdoutrepr, b.stderrrepr) - else: - return (False, False, None, False, False, b.signal, - b.stdoutrepr, b.stderrrepr) - -class AsyncExecutor(RunExecutor): - """ same as box executor, but instead it returns function to continue - computations (more async mode) - """ - wraps = True - - def execute(self): - def fun(): - outcome = RunExecutor.execute(self, False) - return outcome.make_repr(self.config.option.tbstyle) - - b = Box(fun, config=self.config) - parent, pid = b.run(continuation=True) - - def cont(waiter=os.waitpid): - parent(pid, waiter=waiter) - if b.retval is not None: - passed, setupfailure, excinfo, skipped,\ - critical, _, _, _ = b.retval - return (passed, setupfailure, excinfo, skipped, critical, 0, - b.stdoutrepr, b.stderrrepr) - else: - return (False, False, None, False, False, - b.signal, b.stdoutrepr, b.stderrrepr) - - return cont, pid Modified: py/branch/reporter-merge/py/test/rsession/rsession.py ============================================================================== --- py/branch/reporter-merge/py/test/rsession/rsession.py (original) +++ py/branch/reporter-merge/py/test/rsession/rsession.py Sun Oct 28 19:16:47 2007 @@ -85,72 +85,3 @@ keyword = self.config.option.keyword itemgenerator = itemgen(self, colitems, reporter, keyword) all_tests = dispatch_loop(nodes, itemgenerator, checkfun) - -class LSession(AbstractSession): - """ Local version of session - """ - def main(self, reporter=None, runner=None): - # check out if used options makes any sense - config = self.config - hosts = [HostInfo('localhost')] - - #reporter, checkfun = self.init_reporter(reporter, config, hosts) - reporter = self.reporter - checkfun = self.shouldstop - - reporter(repevent.TestStarted(hosts, config, [])) - colitems = self.config.getcolitems() - reporter(repevent.RsyncFinished()) - - if runner is None: - runner = self.init_runner() - - keyword = self.config.option.keyword - - itemgenerator = itemgen(self, colitems, reporter, keyword) - local_loop(self, reporter, itemgenerator, checkfun, self.config, runner=runner) - - retval = reporter(repevent.TestFinished()) - - if not self.config.option.nomagic: - py.magic.revoke(assertion=1) - - self.write_docs() - return retval - - def write_docs(self): - if self.config.option.apigen: - from py.__.apigen.tracer.docstorage import DocStorageAccessor - apigen = py.path.local(self.config.option.apigen).pyimport() - if not hasattr(apigen, 'build'): - raise NotImplementedError("%s does not contain 'build' " - "function" %(apigen,)) - print >>sys.stderr, 'building documentation' - capture = py.io.StdCaptureFD() - try: - pkgdir = py.path.local(self.config.args[0]).pypkgpath() - apigen.build(pkgdir, - DocStorageAccessor(self.docstorage), - capture) - finally: - capture.reset() - print >>sys.stderr, '\ndone' - - def init_runner(self): - if self.config.option.apigen: - from py.__.apigen.tracer.tracer import Tracer, DocStorage - pkgdir = py.path.local(self.config.args[0]).pypkgpath() - apigen = py.path.local(self.config.option.apigen).pyimport() - if not hasattr(apigen, 'get_documentable_items'): - raise NotImplementedError("Provided script does not seem " - "to contain get_documentable_items") - pkgname, items = apigen.get_documentable_items(pkgdir) - self.docstorage = DocStorage().from_dict(items, - module_name=pkgname) - self.tracer = Tracer(self.docstorage) - return apigen_runner - elif self.config.option.boxed: - return box_runner - else: - return plain_runner - Deleted: /py/branch/reporter-merge/py/test/rsession/testing/test_boxing.py ============================================================================== --- /py/branch/reporter-merge/py/test/rsession/testing/test_boxing.py Sun Oct 28 19:16:47 2007 +++ (empty file) @@ -1,95 +0,0 @@ - -""" test boxing functionality -""" - -import py, sys, os - -if sys.platform == 'win32': - py.test.skip("rsession is unsupported on Windows.") - -from py.__.test.rsession.box import Box -from py.__.test.rsession.testing import example2 - -def setup_module(mod): - tmpdir = py.test.ensuretemp("boxtests") - mod.config = py.test.config._reparse([tmpdir]) - -def test_basic_boxing(): - # XXX: because we do not have option transfer -## if not hasattr(option, 'nocapture') or not option.nocapture: -## py.test.skip("Interacts with pylib i/o skipping which is bad actually") - b = Box(example2.boxf1, config=config) - b.run() - assert b.stdoutrepr == "some out\n" - assert b.stderrrepr == "some err\n" - assert b.exitstat == 0 - assert b.signal == 0 - assert b.retval == 1 - -def test_boxing_on_fds(): - b = Box(example2.boxf2, config=config) - b.run() - assert b.stdoutrepr == "someout" - assert b.stderrrepr == "someerr" - assert b.exitstat == 0 - assert b.signal == 0 - assert b.retval == 2 - -def test_boxing_signal(): - b = Box(example2.boxseg, config=config) - b.run() - assert b.retval is None - if py.std.sys.version_info < (2,4): - py.test.skip("signal detection does not work with python prior 2.4") - assert b.signal == 11 - -def test_boxing_huge_data(): - b = Box(example2.boxhuge, config=config) - b.run() - assert b.stdoutrepr - assert b.exitstat == 0 - assert b.signal == 0 - assert b.retval == 3 - -def test_box_seq(): - # we run many boxes with huge data, just one after another - for i in xrange(100): - b = Box(example2.boxhuge, config=config) - b.run() - assert b.stdoutrepr - assert b.exitstat == 0 - assert b.signal == 0 - assert b.retval == 3 - -def test_box_in_a_box(): - def boxfun(): - b = Box(example2.boxf2, config=config) - b.run() - print b.stdoutrepr - print >>sys.stderr, b.stderrrepr - return b.retval - - b = Box(boxfun, config=config) - b.run() - assert b.stdoutrepr == "someout\n" - assert b.stderrrepr == "someerr\n" - assert b.exitstat == 0 - assert b.signal == 0 - assert b.retval == 2 - -def test_box_killer(): - class A: - pass - info = A() - import time - - def box_fun(): - time.sleep(10) # we don't want to last forever here - - b = Box(box_fun, config=config) - par, pid = b.run(continuation=True) - os.kill(pid, 15) - par(pid) - if py.std.sys.version_info < (2,4): - py.test.skip("signal detection does not work with python prior 2.4") - assert b.signal == 15 Deleted: /py/branch/reporter-merge/py/test/rsession/testing/test_executor.py ============================================================================== --- /py/branch/reporter-merge/py/test/rsession/testing/test_executor.py Sun Oct 28 19:16:47 2007 +++ (empty file) @@ -1,171 +0,0 @@ - -import py -import example1 - -from py.__.test.rsession.executor import RunExecutor, BoxExecutor,\ - AsyncExecutor, ApigenExecutor -from py.__.test.outcome import ReprOutcome -from py.__.test.rsession.testing.basetest import BasicRsessionTest -from py.__.test.outcome import Failed - -def setup_module(mod): - if py.std.sys.platform == "win32": - py.test.skip("skipping executor tests (some require os.fork)") - -class Item(py.test.collect.Item): - def __init__(self, name, config): - super(Item, self).__init__(name) - self._config = config - -class ItemTestPassing(Item): - def run(self): - return None - -class ItemTestFailing(Item): - def run(self): - assert 0 == 1 - -class ItemTestSkipping(Item): - def run(self): - py.test.skip("hello") - -class ItemTestPrinting(Item): - def run(self): - print "hello" - -class ItemTestFailingExplicit(Item): - def run(self): - raise Failed(excinfo="3") - -class ItemTestFailingExplicitEmpty(Item): - def run(self): - py.test.raises(ValueError, lambda : 123) - -class TestExecutor(BasicRsessionTest): - def test_run_executor(self): - ex = RunExecutor(ItemTestPassing("pass", self.config), config=self.config) - outcome = ex.execute() - assert outcome.passed - - ex = RunExecutor(ItemTestFailing("fail", self.config), config=self.config) - outcome = ex.execute() - assert not outcome.passed - - ex = RunExecutor(ItemTestSkipping("skip", self.config), config=self.config) - outcome = ex.execute() - assert outcome.skipped - assert not outcome.passed - assert not outcome.excinfo - - def test_run_executor_capture(self): - ex = RunExecutor(ItemTestPrinting("print", self.config), config=self.config) - outcome = ex.execute() - assert outcome.stdout == "hello\n" - - def test_box_executor(self): - ex = BoxExecutor(ItemTestPassing("pass", self.config), config=self.config) - outcome_repr = ex.execute() - outcome = ReprOutcome(outcome_repr) - assert outcome.passed - - ex = BoxExecutor(ItemTestFailing("fail", self.config), config=self.config) - outcome_repr = ex.execute() - outcome = ReprOutcome(outcome_repr) - assert not outcome.passed - - ex = BoxExecutor(ItemTestSkipping("skip", self.config), config=self.config) - outcome_repr = ex.execute() - outcome = ReprOutcome(outcome_repr) - assert outcome.skipped - assert not outcome.passed - assert not outcome.excinfo - - def test_box_executor_stdout(self): - item = self.getexample("print") - ex = BoxExecutor(item, config=self.config) - outcome_repr = ex.execute() - outcome = ReprOutcome(outcome_repr) - assert outcome.passed - assert outcome.stdout.find("samfing") != -1 - - def test_box_executor_stdout_error(self): - item = self.getexample("printfail") - ex = BoxExecutor(item, config=self.config) - outcome_repr = ex.execute() - outcome = ReprOutcome(outcome_repr) - assert not outcome.passed - assert outcome.stdout.find("samfing elz") != -1 - - def test_cont_executor(self): - item = self.getexample("printfail") - ex = AsyncExecutor(item, config=self.config) - cont, pid = ex.execute() - assert pid - outcome_repr = cont() - outcome = ReprOutcome(outcome_repr) - assert not outcome.passed - assert outcome.stdout.find("samfing elz") != -1 - - def test_apigen_executor(self): - class Tracer(object): - def __init__(self): - self.starts = 0 - self.ends = 0 - - def start_tracing(self): - self.starts += 1 - - def end_tracing(self): - self.ends += 1 - - tmpdir = py.test.ensuretemp("apigen_executor") - tmpdir.ensure("__init__.py") - tmpdir.ensure("test_one.py").write(py.code.Source(""" - def g(): - pass - - def test_1(): - g() - - class TestX(object): - def setup_method(self, m): - self.ttt = 1 - - def test_one(self): - self.ttt += 1 - - def test_raise(self): - 1/0 - """)) - config = py.test.config._reparse([tmpdir]) - rootcol = config._getcollector(tmpdir) - tracer = Tracer() - item = rootcol._getitembynames("test_one.py/test_1") - ex = ApigenExecutor(item, config=config) - out1 = ex.execute(tracer) - item = rootcol._getitembynames("test_one.py/TestX/()/test_one") - ex = ApigenExecutor(item, config=config) - out2 = ex.execute(tracer) - item = rootcol._getitembynames("test_one.py/TestX/()/test_raise") - ex = ApigenExecutor(item, config=config) - out3 = ex.execute(tracer) - assert tracer.starts == 3 - assert tracer.ends == 3 - assert out1.passed - assert out2.passed - assert not out3.passed - - def test_executor_explicit_Failed(self): - ex = RunExecutor(ItemTestFailingExplicit("failex", self.config), - config=self.config) - - outcome = ex.execute() - assert not outcome.passed - assert outcome.excinfo == "3" - - def test_executor_explicit_Faile_no_excinfo(self): - ex = RunExecutor(ItemTestFailingExplicitEmpty("failexx", self.config), - config=self.config) - outcome = ex.execute() - assert not outcome.passed - Copied: py/branch/reporter-merge/py/test/test_executor.py (from r47660, py/branch/reporter-merge/py/test/rsession/testing/test_executor.py) ============================================================================== --- py/branch/reporter-merge/py/test/rsession/testing/test_executor.py (original) +++ py/branch/reporter-merge/py/test/test_executor.py Sun Oct 28 19:16:47 2007 @@ -2,7 +2,7 @@ import py import example1 -from py.__.test.rsession.executor import RunExecutor, BoxExecutor,\ +from py.__.test.executor import RunExecutor, BoxExecutor,\ AsyncExecutor, ApigenExecutor from py.__.test.outcome import ReprOutcome from py.__.test.rsession.testing.basetest import BasicRsessionTest From fijal at codespeak.net Sun Oct 28 19:19:02 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 28 Oct 2007 19:19:02 +0100 (CET) Subject: [py-svn] r48137 - in py/branch/reporter-merge/py/test: . rsession rsession/testing testing Message-ID: <20071028181902.0EFBA812D@code0.codespeak.net> Author: fijal Date: Sun Oct 28 19:19:01 2007 New Revision: 48137 Added: py/branch/reporter-merge/py/test/testing/example1.py - copied unchanged from r47660, py/branch/reporter-merge/py/test/rsession/testing/example1.py py/branch/reporter-merge/py/test/testing/example2.py - copied unchanged from r47660, py/branch/reporter-merge/py/test/rsession/testing/example2.py py/branch/reporter-merge/py/test/testing/test_executor.py - copied unchanged from r48136, py/branch/reporter-merge/py/test/test_executor.py Removed: py/branch/reporter-merge/py/test/rsession/testing/example1.py py/branch/reporter-merge/py/test/rsession/testing/example2.py py/branch/reporter-merge/py/test/test_executor.py Modified: py/branch/reporter-merge/py/test/rsession/local.py py/branch/reporter-merge/py/test/rsession/slave.py py/branch/reporter-merge/py/test/rsession/testing/test_lsession.py py/branch/reporter-merge/py/test/rsession/testing/test_slave.py Log: Move files around. Modified: py/branch/reporter-merge/py/test/rsession/local.py ============================================================================== --- py/branch/reporter-merge/py/test/rsession/local.py (original) +++ py/branch/reporter-merge/py/test/rsession/local.py Sun Oct 28 19:19:01 2007 @@ -3,7 +3,7 @@ """ import py -from py.__.test.rsession.executor import BoxExecutor, RunExecutor,\ +from py.__.test.executor import BoxExecutor, RunExecutor,\ ApigenExecutor from py.__.test import repevent from py.__.test.outcome import ReprOutcome Modified: py/branch/reporter-merge/py/test/rsession/slave.py ============================================================================== --- py/branch/reporter-merge/py/test/rsession/slave.py (original) +++ py/branch/reporter-merge/py/test/rsession/slave.py Sun Oct 28 19:19:01 2007 @@ -3,7 +3,7 @@ """ import py -from py.__.test.rsession.executor import RunExecutor, BoxExecutor, AsyncExecutor +from py.__.test.executor import RunExecutor, BoxExecutor, AsyncExecutor from py.__.test.outcome import SerializableOutcome from py.__.test.outcome import Skipped import thread Deleted: /py/branch/reporter-merge/py/test/rsession/testing/example1.py ============================================================================== --- /py/branch/reporter-merge/py/test/rsession/testing/example1.py Sun Oct 28 19:19:01 2007 +++ (empty file) @@ -1,12 +0,0 @@ - -def f1(): - f2() - -def f2(): - pass - -def g1(): - g2() - -def g2(): - raise ValueError() Deleted: /py/branch/reporter-merge/py/test/rsession/testing/example2.py ============================================================================== --- /py/branch/reporter-merge/py/test/rsession/testing/example2.py Sun Oct 28 19:19:01 2007 +++ (empty file) @@ -1,30 +0,0 @@ - -""" some example for running box stuff inside -""" - -import sys -import py, os - -def boxf1(): - print "some out" - print >>sys.stderr, "some err" - return 1 - -def boxf2(): - os.write(1, "someout") - os.write(2, "someerr") - return 2 - -def boxseg(): - os.kill(os.getpid(), 11) - -def boxhuge(): - os.write(1, " " * 10000) - os.write(2, " " * 10000) - os.write(1, " " * 10000) - - os.write(1, " " * 10000) - os.write(2, " " * 10000) - os.write(2, " " * 10000) - os.write(1, " " * 10000) - return 3 Modified: py/branch/reporter-merge/py/test/rsession/testing/test_lsession.py ============================================================================== --- py/branch/reporter-merge/py/test/rsession/testing/test_lsession.py (original) +++ py/branch/reporter-merge/py/test/rsession/testing/test_lsession.py Sun Oct 28 19:19:01 2007 @@ -3,6 +3,7 @@ """ import py +py.test.skip("Skipped") from py.__.test.rsession.rsession import LSession from py.__.test import repevent from py.__.test.rsession.local import box_runner, plain_runner, apigen_runner Modified: py/branch/reporter-merge/py/test/rsession/testing/test_slave.py ============================================================================== --- py/branch/reporter-merge/py/test/rsession/testing/test_slave.py (original) +++ py/branch/reporter-merge/py/test/rsession/testing/test_slave.py Sun Oct 28 19:19:01 2007 @@ -13,7 +13,7 @@ # ---------------------------------------------------------------------- -from py.__.test.rsession.executor import RunExecutor +from py.__.test.executor import RunExecutor class TestSlave(BasicRsessionTest): def gettestnode(self): Deleted: /py/branch/reporter-merge/py/test/test_executor.py ============================================================================== --- /py/branch/reporter-merge/py/test/test_executor.py Sun Oct 28 19:19:01 2007 +++ (empty file) @@ -1,171 +0,0 @@ - -import py -import example1 - -from py.__.test.executor import RunExecutor, BoxExecutor,\ - AsyncExecutor, ApigenExecutor -from py.__.test.outcome import ReprOutcome -from py.__.test.rsession.testing.basetest import BasicRsessionTest -from py.__.test.outcome import Failed - -def setup_module(mod): - if py.std.sys.platform == "win32": - py.test.skip("skipping executor tests (some require os.fork)") - -class Item(py.test.collect.Item): - def __init__(self, name, config): - super(Item, self).__init__(name) - self._config = config - -class ItemTestPassing(Item): - def run(self): - return None - -class ItemTestFailing(Item): - def run(self): - assert 0 == 1 - -class ItemTestSkipping(Item): - def run(self): - py.test.skip("hello") - -class ItemTestPrinting(Item): - def run(self): - print "hello" - -class ItemTestFailingExplicit(Item): - def run(self): - raise Failed(excinfo="3") - -class ItemTestFailingExplicitEmpty(Item): - def run(self): - py.test.raises(ValueError, lambda : 123) - -class TestExecutor(BasicRsessionTest): - def test_run_executor(self): - ex = RunExecutor(ItemTestPassing("pass", self.config), config=self.config) - outcome = ex.execute() - assert outcome.passed - - ex = RunExecutor(ItemTestFailing("fail", self.config), config=self.config) - outcome = ex.execute() - assert not outcome.passed - - ex = RunExecutor(ItemTestSkipping("skip", self.config), config=self.config) - outcome = ex.execute() - assert outcome.skipped - assert not outcome.passed - assert not outcome.excinfo - - def test_run_executor_capture(self): - ex = RunExecutor(ItemTestPrinting("print", self.config), config=self.config) - outcome = ex.execute() - assert outcome.stdout == "hello\n" - - def test_box_executor(self): - ex = BoxExecutor(ItemTestPassing("pass", self.config), config=self.config) - outcome_repr = ex.execute() - outcome = ReprOutcome(outcome_repr) - assert outcome.passed - - ex = BoxExecutor(ItemTestFailing("fail", self.config), config=self.config) - outcome_repr = ex.execute() - outcome = ReprOutcome(outcome_repr) - assert not outcome.passed - - ex = BoxExecutor(ItemTestSkipping("skip", self.config), config=self.config) - outcome_repr = ex.execute() - outcome = ReprOutcome(outcome_repr) - assert outcome.skipped - assert not outcome.passed - assert not outcome.excinfo - - def test_box_executor_stdout(self): - item = self.getexample("print") - ex = BoxExecutor(item, config=self.config) - outcome_repr = ex.execute() - outcome = ReprOutcome(outcome_repr) - assert outcome.passed - assert outcome.stdout.find("samfing") != -1 - - def test_box_executor_stdout_error(self): - item = self.getexample("printfail") - ex = BoxExecutor(item, config=self.config) - outcome_repr = ex.execute() - outcome = ReprOutcome(outcome_repr) - assert not outcome.passed - assert outcome.stdout.find("samfing elz") != -1 - - def test_cont_executor(self): - item = self.getexample("printfail") - ex = AsyncExecutor(item, config=self.config) - cont, pid = ex.execute() - assert pid - outcome_repr = cont() - outcome = ReprOutcome(outcome_repr) - assert not outcome.passed - assert outcome.stdout.find("samfing elz") != -1 - - def test_apigen_executor(self): - class Tracer(object): - def __init__(self): - self.starts = 0 - self.ends = 0 - - def start_tracing(self): - self.starts += 1 - - def end_tracing(self): - self.ends += 1 - - tmpdir = py.test.ensuretemp("apigen_executor") - tmpdir.ensure("__init__.py") - tmpdir.ensure("test_one.py").write(py.code.Source(""" - def g(): - pass - - def test_1(): - g() - - class TestX(object): - def setup_method(self, m): - self.ttt = 1 - - def test_one(self): - self.ttt += 1 - - def test_raise(self): - 1/0 - """)) - config = py.test.config._reparse([tmpdir]) - rootcol = config._getcollector(tmpdir) - tracer = Tracer() - item = rootcol._getitembynames("test_one.py/test_1") - ex = ApigenExecutor(item, config=config) - out1 = ex.execute(tracer) - item = rootcol._getitembynames("test_one.py/TestX/()/test_one") - ex = ApigenExecutor(item, config=config) - out2 = ex.execute(tracer) - item = rootcol._getitembynames("test_one.py/TestX/()/test_raise") - ex = ApigenExecutor(item, config=config) - out3 = ex.execute(tracer) - assert tracer.starts == 3 - assert tracer.ends == 3 - assert out1.passed - assert out2.passed - assert not out3.passed - - def test_executor_explicit_Failed(self): - ex = RunExecutor(ItemTestFailingExplicit("failex", self.config), - config=self.config) - - outcome = ex.execute() - assert not outcome.passed - assert outcome.excinfo == "3" - - def test_executor_explicit_Faile_no_excinfo(self): - ex = RunExecutor(ItemTestFailingExplicitEmpty("failexx", self.config), - config=self.config) - outcome = ex.execute() - assert not outcome.passed - From fijal at codespeak.net Sun Oct 28 19:22:42 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 28 Oct 2007 19:22:42 +0100 (CET) Subject: [py-svn] r48138 - py/branch/reporter-merge/py/test Message-ID: <20071028182242.BBAA2812D@code0.codespeak.net> Author: fijal Date: Sun Oct 28 19:22:42 2007 New Revision: 48138 Modified: py/branch/reporter-merge/py/test/executor.py py/branch/reporter-merge/py/test/session.py Log: Share more code. Modified: py/branch/reporter-merge/py/test/executor.py ============================================================================== --- py/branch/reporter-merge/py/test/executor.py (original) +++ py/branch/reporter-merge/py/test/executor.py Sun Oct 28 19:22:42 2007 @@ -60,7 +60,7 @@ py.__.test.custompdb.post_mortem(excinfo._excinfo[2]) # XXX hmm, we probably will not like to continue from that # point - raise SystemExit() + #raise SystemExit() outcome.stdout, outcome.stderr = self.item._getouterr() return outcome Modified: py/branch/reporter-merge/py/test/session.py ============================================================================== --- py/branch/reporter-merge/py/test/session.py (original) +++ py/branch/reporter-merge/py/test/session.py Sun Oct 28 19:22:42 2007 @@ -5,6 +5,7 @@ from py.__.test import repevent from py.__.test.outcome import SerializableOutcome, ReprOutcome from py.__.test.reporter import LocalReporter +from py.__.test.executor import RunExecutor """ The session implementation - reporter version: @@ -143,39 +144,9 @@ self.footer(colitems) def run(self, item): - try: - item.startcapture() - try: - item.run() - finally: - item.finishcapture() - outcome = SerializableOutcome() - except Skipped: - e = py.code.ExceptionInfo() - outcome = SerializableOutcome(skipped=e) - except (SystemExit, KeyboardInterrupt): - raise - except: - e = sys.exc_info()[1] - if isinstance(e, Failed) and e.excinfo: - excinfo = e.excinfo - else: - excinfo = py.code.ExceptionInfo() - if isinstance(item, py.test.collect.Function): - fun = item.obj # hope this is stable - code = py.code.Code(fun) - excinfo.traceback = excinfo.traceback.cut( - path=code.path, firstlineno=code.firstlineno) - outcome = SerializableOutcome(excinfo=excinfo, setupfailure=False) - if self.config.option.usepdb: - if self.reporter is not None: - self.reporter(repevent.ImmediateFailure(item, - ReprOutcome(outcome.make_repr - (self.config.option.tbstyle)))) - py.__.test.custompdb.post_mortem(excinfo._excinfo[2]) - - outcome.stdout, outcome.stderr = item._getouterr() - return ReprOutcome(outcome.make_repr()) + executor = RunExecutor(item, self.config.option.usepdb, self.reporter, + self.config) + return ReprOutcome(executor.execute().make_repr()) class Exit(Exception): """ for immediate program exits without tracebacks and reporter/summary. """ From fijal at codespeak.net Sun Oct 28 19:31:32 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 28 Oct 2007 19:31:32 +0100 (CET) Subject: [py-svn] r48139 - in py/branch/reporter-merge/py/test: . rsession/testing testing Message-ID: <20071028183132.799E480D9@code0.codespeak.net> Author: fijal Date: Sun Oct 28 19:31:32 2007 New Revision: 48139 Added: py/branch/reporter-merge/py/test/testing/test_session2.py - copied, changed from r48137, py/branch/reporter-merge/py/test/rsession/testing/test_lsession.py Removed: py/branch/reporter-merge/py/test/rsession/testing/test_lsession.py Modified: py/branch/reporter-merge/py/test/defaultconftest.py Log: * Kill lsession * Disable boxing option, as it's not working (and I'm not sure whether it should be done via other session or just option) * Move test_lsession into test_session2 as this tests normal session as well, just using slightly different style Modified: py/branch/reporter-merge/py/test/defaultconftest.py ============================================================================== --- py/branch/reporter-merge/py/test/defaultconftest.py (original) +++ py/branch/reporter-merge/py/test/defaultconftest.py Sun Oct 28 19:31:32 2007 @@ -88,9 +88,9 @@ action="store_true", dest="runbrowser", default=False, help="run browser (implies --startserver)." ), - Option('', '--boxed', - action="store_true", dest="boxed", default=False, - help="box each test run in a separate process"), + #Option('', '--boxed', + # action="store_true", dest="boxed", default=False, + # help="box each test run in a separate process"), Option('', '--rest', action='store_true', dest="restreport", default=False, help="restructured text output reporting."), Deleted: /py/branch/reporter-merge/py/test/rsession/testing/test_lsession.py ============================================================================== --- /py/branch/reporter-merge/py/test/rsession/testing/test_lsession.py Sun Oct 28 19:31:32 2007 +++ (empty file) @@ -1,298 +0,0 @@ - -""" test of local version of py.test distributed -""" - -import py -py.test.skip("Skipped") -from py.__.test.rsession.rsession import LSession -from py.__.test import repevent -from py.__.test.rsession.local import box_runner, plain_runner, apigen_runner -import py.__.test.custompdb - -def setup_module(mod): - py.test.skip("Not working") - mod.tmp = py.test.ensuretemp("lsession_module") - -class TestLSession(object): - # XXX: Some tests of that should be run as well on RSession, while - # some not at all - def example_distribution(self, runner): - # XXX find a better way for the below - tmpdir = tmp - dirname = "sub_lsession"+runner.func_name - tmpdir.ensure(dirname, "__init__.py") - tmpdir.ensure(dirname, "test_one.py").write(py.code.Source(""" - def test_1(): - pass - def test_2(): - assert 0 - def test_3(): - raise ValueError(23) - def test_4(someargs): - pass - #def test_5(): - # import os - # os.kill(os.getpid(), 11) - """)) - args = [str(tmpdir.join(dirname))] - config = py.test.config._reparse(args) - lsession = LSession(config) - allevents = [] - lsession.main(reporter=allevents.append, runner=runner) - testevents = [x for x in allevents - if isinstance(x, repevent.ReceivedItemOutcome)] - assert len(testevents) - passevents = [i for i in testevents if i.outcome.passed] - failevents = [i for i in testevents if i.outcome.excinfo] - skippedevents = [i for i in testevents if i.outcome.skipped] - signalevents = [i for i in testevents if i.outcome.signal] - assert len(passevents) == 1 - assert len(failevents) == 3 - assert len(skippedevents) == 0 - #assert len(signalevents) == 1 - tb = failevents[0].outcome.excinfo.traceback - assert str(tb[0].path).find("test_one") != -1 - assert str(tb[0].source).find("test_2") != -1 - assert failevents[0].outcome.excinfo.typename == 'AssertionError' - tb = failevents[1].outcome.excinfo.traceback - assert str(tb[0].path).find("test_one") != -1 - assert str(tb[0].source).find("test_3") != -1 - assert failevents[1].outcome.excinfo.typename == 'ValueError' - assert str(failevents[1].outcome.excinfo.value) == '23' - tb = failevents[2].outcome.excinfo.traceback - assert failevents[2].outcome.excinfo.typename == 'TypeError' - assert str(tb[0].path).find("executor") != -1 - assert str(tb[0].source).find("execute") != -1 - - def test_normal(self): - if not hasattr(py.std.os, 'fork'): - py.test.skip('operating system not supported') - self.example_distribution(box_runner) - - def test_plain(self): - self.example_distribution(plain_runner) - - def test_pdb_run(self): - # we make sure that pdb is engaged - tmpdir = tmp - subdir = "sub_pdb_run" - tmpdir.ensure(subdir, "__init__.py") - tmpdir.ensure(subdir, "test_one.py").write(py.code.Source(""" - def test_1(): - assert 0 - """)) - l = [] - def some_fun(*args): - l.append(args) - - try: - post_mortem = py.__.test.custompdb.post_mortem - py.__.test.custompdb.post_mortem = some_fun - args = [str(tmpdir.join(subdir)), '--pdb'] - config = py.test.config._reparse(args) - lsession = LSession(config) - allevents = [] - try: - lsession.main(reporter=allevents.append, runner=plain_runner) - except SystemExit: - pass - else: - py.test.fail("Didn't raise system exit") - failure_events = [event for event in allevents if isinstance(event, - repevent.ImmediateFailure)] - assert len(failure_events) == 1 - assert len(l) == 1 - finally: - py.__.test.custompdb.post_mortem = post_mortem - - def test_minus_x(self): - if not hasattr(py.std.os, 'fork'): - py.test.skip('operating system not supported') - tmpdir = tmp - subdir = "sub_lsession_minus_x" - tmpdir.ensure(subdir, "__init__.py") - tmpdir.ensure(subdir, "test_one.py").write(py.code.Source(""" - def test_1(): - pass - def test_2(): - assert 0 - def test_3(): - raise ValueError(23) - def test_4(someargs): - pass - """)) - args = [str(tmpdir.join(subdir)), '-x'] - config = py.test.config._reparse(args) - assert config.option.exitfirst - lsession = LSession(config) - allevents = [] - - lsession.main(reporter=allevents.append, runner=box_runner) - testevents = [x for x in allevents - if isinstance(x, repevent.ReceivedItemOutcome)] - assert len(testevents) - passevents = [i for i in testevents if i.outcome.passed] - failevents = [i for i in testevents if i.outcome.excinfo] - assert len(passevents) == 1 - assert len(failevents) == 1 - - def test_minus_k(self): - if not hasattr(py.std.os, 'fork'): - py.test.skip('operating system not supported') - tmpdir = tmp - tmpdir.ensure("sub3", "__init__.py") - tmpdir.ensure("sub3", "test_some.py").write(py.code.Source(""" - def test_one(): - pass - def test_one_one(): - assert 0 - def test_other(): - raise ValueError(23) - def test_two(someargs): - pass - """)) - args = [str(tmpdir.join("sub3")), '-k', 'test_one'] - config = py.test.config._reparse(args) - lsession = LSession(config) - allevents = [] - - lsession.main(reporter=allevents.append, runner=box_runner) - testevents = [x for x in allevents - if isinstance(x, repevent.ReceivedItemOutcome)] - assert len(testevents) - passevents = [i for i in testevents if i.outcome.passed] - failevents = [i for i in testevents if i.outcome.excinfo] - assert len(passevents) == 1 - assert len(failevents) == 1 - - def test_lsession(self): - tmpdir = tmp - tmpdir.ensure("sub4", "__init__.py") - tmpdir.ensure("sub4", "test_some.py").write(py.code.Source(""" - def test_one(): - pass - def test_one_one(): - assert 0 - def test_other(): - raise ValueError(23) - def test_two(someargs): - pass - """)) - - args = [str(tmpdir.join("sub4"))] - config = py.test.config._reparse(args) - lsession = LSession(config) - allevents = [] - allruns = [] - def dummy_runner(item, config, reporter): - allruns.append(item) - item.passed = True - return item - lsession.main(reporter=allevents.append, runner=dummy_runner) - - assert len(allruns) == 4 - testevents = [x for x in allevents - if isinstance(x, repevent.ReceivedItemOutcome)] - assert len(testevents) == 4 - lst = ['test_one', 'test_one_one', 'test_other', 'test_two'] - for num, i in enumerate(testevents): - assert i.item == i.outcome - assert i.item.name == lst[num] - - def test_module_raising(self): - tmpdir = tmp - tmpdir.ensure("sub5", "__init__.py") - tmpdir.ensure("sub5", "test_some.py").write(py.code.Source(""" - 1/0 - """)) - tmpdir.ensure("sub5", "test_other.py").write(py.code.Source(""" - import py - py.test.skip("reason") - """)) - - args = [str(tmpdir.join("sub5"))] - config = py.test.config._reparse(args) - lsession = LSession(config) - allevents = [] - lsession.main(reporter=allevents.append, runner=box_runner) - testevents = [x for x in allevents - if isinstance(x, repevent.ReceivedItemOutcome)] - assert len(testevents) == 0 - failedtryiter = [x for x in allevents - if isinstance(x, repevent.FailedTryiter)] - assert len(failedtryiter) == 1 - skippedtryiter = [x for x in allevents - if isinstance(x, repevent.SkippedTryiter)] - assert len(skippedtryiter) == 1 - - - def test_assert_reinterpret(self): - if not hasattr(py.std.os, 'fork'): - py.test.skip('operating system not supported') - tmpdir = tmp - tmpdir.ensure("sub6", "__init__.py") - tmpdir.ensure("sub6", "test_some.py").write(py.code.Source(""" - def test_one(): - x = [1, 2] - assert [0] == x - """)) - args = [str(tmpdir.join("sub6"))] - config = py.test.config._reparse(args) - lsession = LSession(config) - allevents = [] - lsession.main(reporter=allevents.append, runner=box_runner) - testevents = [x for x in allevents - if isinstance(x, repevent.ReceivedItemOutcome)] - failevents = [i for i in testevents if i.outcome.excinfo] - assert len(failevents) == 1 - assert len(testevents) == 1 - assert failevents[0].outcome.excinfo.value == 'assert [0] == [1, 2]' - - def test_nocapture(self): - tmpdir = tmp - tmpdir.ensure("sub7", "__init__.py") - tmpdir.ensure("sub7", "test_nocap.py").write(py.code.Source(""" - def test_one(): - print 1 - print 2 - print 3 - """)) - args = [str(tmpdir.join("sub7"))] - config = py.test.config._reparse(args) - lsession = LSession(config) - allevents = [] - lsession.main(reporter=allevents.append, runner=plain_runner) - testevents = [x for x in allevents - if isinstance(x, repevent.ReceivedItemOutcome)] - assert len(testevents) == 1 - assert testevents[0].outcome.passed - assert testevents[0].outcome.stderr == "" - assert testevents[0].outcome.stdout == "1\n2\n3\n" - - def test_runner_selection(self): - tmpdir = py.test.ensuretemp("lsession_runner_selection") - tmpdir.ensure("apigen.py").write(py.code.Source(""" - def get_documentable_items(*args): - return 'foo', {} - """)) - opt_mapping = { - '': plain_runner, - '--box': box_runner, - '--apigen=%s/apigen.py' % str(tmpdir): apigen_runner, - } - pkgdir = tmpdir.dirpath() - for opt in opt_mapping.keys(): - if opt: - all = opt + " " + str(tmpdir) - else: - all = str(tmpdir) - config = py.test.config._reparse(all.split(" ")) - lsession = LSession(config) - assert lsession.init_runner() is opt_mapping[opt] - #tmpdir.dirpath().ensure("conftest.py").write(py.code.Source(""" - #dist_boxing=True - #""")) - #config = py.test.config._reparse([str(tmpdir)]) - #lsession = LSession(config) - #assert lsession.init_runner(pkgdir) is box_runner - # XXX check why it fails Copied: py/branch/reporter-merge/py/test/testing/test_session2.py (from r48137, py/branch/reporter-merge/py/test/rsession/testing/test_lsession.py) ============================================================================== --- py/branch/reporter-merge/py/test/rsession/testing/test_lsession.py (original) +++ py/branch/reporter-merge/py/test/testing/test_session2.py Sun Oct 28 19:31:32 2007 @@ -3,23 +3,21 @@ """ import py -py.test.skip("Skipped") -from py.__.test.rsession.rsession import LSession from py.__.test import repevent -from py.__.test.rsession.local import box_runner, plain_runner, apigen_runner +#from py.__.test.rsession.local import box_runner, plain_runner, apigen_runner import py.__.test.custompdb +from py.__.test.session import Session def setup_module(mod): - py.test.skip("Not working") mod.tmp = py.test.ensuretemp("lsession_module") -class TestLSession(object): +class TestSession(object): # XXX: Some tests of that should be run as well on RSession, while # some not at all - def example_distribution(self, runner): + def example_distribution(self): # XXX find a better way for the below tmpdir = tmp - dirname = "sub_lsession"+runner.func_name + dirname = "sub_lsession"#+runner.func_name tmpdir.ensure(dirname, "__init__.py") tmpdir.ensure(dirname, "test_one.py").write(py.code.Source(""" def test_1(): @@ -36,9 +34,9 @@ """)) args = [str(tmpdir.join(dirname))] config = py.test.config._reparse(args) - lsession = LSession(config) + lsession = Session(config) allevents = [] - lsession.main(reporter=allevents.append, runner=runner) + lsession.main(reporter=allevents.append) testevents = [x for x in allevents if isinstance(x, repevent.ReceivedItemOutcome)] assert len(testevents) @@ -65,12 +63,13 @@ assert str(tb[0].source).find("execute") != -1 def test_normal(self): + py.test.skip("Boxing not supported") if not hasattr(py.std.os, 'fork'): py.test.skip('operating system not supported') self.example_distribution(box_runner) def test_plain(self): - self.example_distribution(plain_runner) + self.example_distribution() def test_pdb_run(self): # we make sure that pdb is engaged @@ -90,14 +89,14 @@ py.__.test.custompdb.post_mortem = some_fun args = [str(tmpdir.join(subdir)), '--pdb'] config = py.test.config._reparse(args) - lsession = LSession(config) + lsession = Session(config) allevents = [] - try: - lsession.main(reporter=allevents.append, runner=plain_runner) - except SystemExit: - pass - else: - py.test.fail("Didn't raise system exit") + #try: + lsession.main(reporter=allevents.append) + #except SystemExit: + # pass + #else: + # py.test.fail("Didn't raise system exit") failure_events = [event for event in allevents if isinstance(event, repevent.ImmediateFailure)] assert len(failure_events) == 1 @@ -124,10 +123,10 @@ args = [str(tmpdir.join(subdir)), '-x'] config = py.test.config._reparse(args) assert config.option.exitfirst - lsession = LSession(config) + lsession = Session(config) allevents = [] - lsession.main(reporter=allevents.append, runner=box_runner) + lsession.main(reporter=allevents.append) testevents = [x for x in allevents if isinstance(x, repevent.ReceivedItemOutcome)] assert len(testevents) @@ -153,10 +152,10 @@ """)) args = [str(tmpdir.join("sub3")), '-k', 'test_one'] config = py.test.config._reparse(args) - lsession = LSession(config) + lsession = Session(config) allevents = [] - lsession.main(reporter=allevents.append, runner=box_runner) + lsession.main(reporter=allevents.append) testevents = [x for x in allevents if isinstance(x, repevent.ReceivedItemOutcome)] assert len(testevents) @@ -181,22 +180,17 @@ args = [str(tmpdir.join("sub4"))] config = py.test.config._reparse(args) - lsession = LSession(config) + lsession = Session(config) allevents = [] allruns = [] - def dummy_runner(item, config, reporter): - allruns.append(item) - item.passed = True - return item - lsession.main(reporter=allevents.append, runner=dummy_runner) + lsession.main(reporter=allevents.append) - assert len(allruns) == 4 testevents = [x for x in allevents if isinstance(x, repevent.ReceivedItemOutcome)] assert len(testevents) == 4 lst = ['test_one', 'test_one_one', 'test_other', 'test_two'] for num, i in enumerate(testevents): - assert i.item == i.outcome + #assert i.item == i.outcome assert i.item.name == lst[num] def test_module_raising(self): @@ -212,9 +206,9 @@ args = [str(tmpdir.join("sub5"))] config = py.test.config._reparse(args) - lsession = LSession(config) + lsession = Session(config) allevents = [] - lsession.main(reporter=allevents.append, runner=box_runner) + lsession.main(reporter=allevents.append) testevents = [x for x in allevents if isinstance(x, repevent.ReceivedItemOutcome)] assert len(testevents) == 0 @@ -238,9 +232,9 @@ """)) args = [str(tmpdir.join("sub6"))] config = py.test.config._reparse(args) - lsession = LSession(config) + lsession = Session(config) allevents = [] - lsession.main(reporter=allevents.append, runner=box_runner) + lsession.main(reporter=allevents.append) testevents = [x for x in allevents if isinstance(x, repevent.ReceivedItemOutcome)] failevents = [i for i in testevents if i.outcome.excinfo] @@ -259,40 +253,12 @@ """)) args = [str(tmpdir.join("sub7"))] config = py.test.config._reparse(args) - lsession = LSession(config) + lsession = Session(config) allevents = [] - lsession.main(reporter=allevents.append, runner=plain_runner) + lsession.main(reporter=allevents.append) testevents = [x for x in allevents if isinstance(x, repevent.ReceivedItemOutcome)] assert len(testevents) == 1 assert testevents[0].outcome.passed assert testevents[0].outcome.stderr == "" assert testevents[0].outcome.stdout == "1\n2\n3\n" - - def test_runner_selection(self): - tmpdir = py.test.ensuretemp("lsession_runner_selection") - tmpdir.ensure("apigen.py").write(py.code.Source(""" - def get_documentable_items(*args): - return 'foo', {} - """)) - opt_mapping = { - '': plain_runner, - '--box': box_runner, - '--apigen=%s/apigen.py' % str(tmpdir): apigen_runner, - } - pkgdir = tmpdir.dirpath() - for opt in opt_mapping.keys(): - if opt: - all = opt + " " + str(tmpdir) - else: - all = str(tmpdir) - config = py.test.config._reparse(all.split(" ")) - lsession = LSession(config) - assert lsession.init_runner() is opt_mapping[opt] - #tmpdir.dirpath().ensure("conftest.py").write(py.code.Source(""" - #dist_boxing=True - #""")) - #config = py.test.config._reparse([str(tmpdir)]) - #lsession = LSession(config) - #assert lsession.init_runner(pkgdir) is box_runner - # XXX check why it fails From fijal at codespeak.net Sun Oct 28 19:43:21 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 28 Oct 2007 19:43:21 +0100 (CET) Subject: [py-svn] r48140 - in py/branch/reporter-merge/py/test: . testing Message-ID: <20071028184321.0BD7B812D@code0.codespeak.net> Author: fijal Date: Sun Oct 28 19:43:21 2007 New Revision: 48140 Modified: py/branch/reporter-merge/py/test/defaultconftest.py py/branch/reporter-merge/py/test/executor.py py/branch/reporter-merge/py/test/session.py py/branch/reporter-merge/py/test/testing/test_session.py py/branch/reporter-merge/py/test/testing/test_session2.py Log: Reintroduce boxing Modified: py/branch/reporter-merge/py/test/defaultconftest.py ============================================================================== --- py/branch/reporter-merge/py/test/defaultconftest.py (original) +++ py/branch/reporter-merge/py/test/defaultconftest.py Sun Oct 28 19:43:21 2007 @@ -88,9 +88,9 @@ action="store_true", dest="runbrowser", default=False, help="run browser (implies --startserver)." ), - #Option('', '--boxed', - # action="store_true", dest="boxed", default=False, - # help="box each test run in a separate process"), + Option('', '--boxed', + action="store_true", dest="boxed", default=False, + help="box each test run in a separate process"), Option('', '--rest', action='store_true', dest="restreport", default=False, help="restructured text output reporting."), Modified: py/branch/reporter-merge/py/test/executor.py ============================================================================== --- py/branch/reporter-merge/py/test/executor.py (original) +++ py/branch/reporter-merge/py/test/executor.py Sun Oct 28 19:43:21 2007 @@ -105,7 +105,7 @@ return (passed, setupfailure, excinfo, skipped, critical, 0, b.stdoutrepr, b.stderrrepr) else: - return (False, False, None, False, False, b.signal, + return (False, False, None, None, False, b.signal, b.stdoutrepr, b.stderrrepr) class AsyncExecutor(RunExecutor): Modified: py/branch/reporter-merge/py/test/session.py ============================================================================== --- py/branch/reporter-merge/py/test/session.py (original) +++ py/branch/reporter-merge/py/test/session.py Sun Oct 28 19:43:21 2007 @@ -5,7 +5,7 @@ from py.__.test import repevent from py.__.test.outcome import SerializableOutcome, ReprOutcome from py.__.test.reporter import LocalReporter -from py.__.test.executor import RunExecutor +from py.__.test.executor import RunExecutor, BoxExecutor """ The session implementation - reporter version: @@ -144,9 +144,14 @@ self.footer(colitems) def run(self, item): - executor = RunExecutor(item, self.config.option.usepdb, self.reporter, - self.config) - return ReprOutcome(executor.execute().make_repr()) + if not self.config.option.boxed: + executor = RunExecutor(item, self.config.option.usepdb, + self.reporter, self.config) + return ReprOutcome(executor.execute().make_repr()) + else: + executor = BoxExecutor(item, self.config.option.usepdb, + self.reporter, self.config) + return ReprOutcome(executor.execute()) class Exit(Exception): """ for immediate program exits without tracebacks and reporter/summary. """ Modified: py/branch/reporter-merge/py/test/testing/test_session.py ============================================================================== --- py/branch/reporter-merge/py/test/testing/test_session.py (original) +++ py/branch/reporter-merge/py/test/testing/test_session.py Sun Oct 28 19:43:21 2007 @@ -158,25 +158,6 @@ assert len(getfailed(all)) == 1 assert not getpassed(all) - def test_recursion_detection(self): - py.test.skip("XXX the test is bogus here") - o = tmpdir.ensure('recursiontest', dir=1) - tfile = o.join('test_recursion.py') - tfile.write(py.code.Source(""" - def test_1(): - def f(): - g() - def g(): - f() - f() - """)) - session, all = self.mainsession(o) - print "back from main", o - #print out - outcomes = getoutcomes(all) - i = out.find('Recursion detected') - assert i != -1 - def test_generator_yields_None(self): o = tmpdir.ensure('generatornonetest', dir=1) tfile = o.join('test_generatornone.py') Modified: py/branch/reporter-merge/py/test/testing/test_session2.py ============================================================================== --- py/branch/reporter-merge/py/test/testing/test_session2.py (original) +++ py/branch/reporter-merge/py/test/testing/test_session2.py Sun Oct 28 19:43:21 2007 @@ -14,7 +14,7 @@ class TestSession(object): # XXX: Some tests of that should be run as well on RSession, while # some not at all - def example_distribution(self): + def example_distribution(self, boxed=False): # XXX find a better way for the below tmpdir = tmp dirname = "sub_lsession"#+runner.func_name @@ -33,6 +33,8 @@ # os.kill(os.getpid(), 11) """)) args = [str(tmpdir.join(dirname))] + if boxed: + args.append('--boxed') config = py.test.config._reparse(args) lsession = Session(config) allevents = [] @@ -62,14 +64,35 @@ assert str(tb[0].path).find("executor") != -1 assert str(tb[0].source).find("execute") != -1 - def test_normal(self): - py.test.skip("Boxing not supported") + def test_boxed(self): if not hasattr(py.std.os, 'fork'): py.test.skip('operating system not supported') - self.example_distribution(box_runner) + self.example_distribution(True) + + def test_box_exploding(self): + if not hasattr(py.std.os, 'fork'): + py.test.skip('operating system not supported') + tmpdir = tmp + dirname = "boxtest" + tmpdir.ensure(dirname, "__init__.py") + tmpdir.ensure(dirname, "test_one.py").write(py.code.Source(""" + def test_5(): + import os + os.kill(os.getpid(), 11) + """)) + args = [str(tmpdir.join(dirname))] + args.append('--boxed') + config = py.test.config._reparse(args) + lsession = Session(config) + allevents = [] + lsession.main(reporter=allevents.append) + testevents = [x for x in allevents + if isinstance(x, repevent.ReceivedItemOutcome)] + assert len(testevents) + assert testevents[0].outcome.signal def test_plain(self): - self.example_distribution() + self.example_distribution(False) def test_pdb_run(self): # we make sure that pdb is engaged From py-svn at codespeak.net Wed Oct 31 11:16:39 2007 From: py-svn at codespeak.net (VIAGRA ® Official Site) Date: Wed, 31 Oct 2007 11:16:39 +0100 (CET) Subject: [py-svn] October 78% OFF Message-ID: <20071031121631.9337.qmail@ppp-58.10.0.28.revip2.asianet.co.th> An HTML attachment was scrubbed... URL: