[svn r58107] first step in moving experimental filelog session into contrib
--HG-- branch : trunk
This commit is contained in:
parent
7afc30d130
commit
bb9b0e7361
|
@ -0,0 +1,58 @@
|
||||||
|
from py.__.test.session import Session
|
||||||
|
from py.__.test import event
|
||||||
|
|
||||||
|
|
||||||
|
def generic_path(item):
|
||||||
|
chain = item.listchain()
|
||||||
|
gpath = [chain[0].name]
|
||||||
|
fspath = chain[0].fspath
|
||||||
|
fspart = False
|
||||||
|
for node in chain[1:]:
|
||||||
|
newfspath = node.fspath
|
||||||
|
if newfspath == fspath:
|
||||||
|
if fspart:
|
||||||
|
gpath.append(':')
|
||||||
|
fspart = False
|
||||||
|
else:
|
||||||
|
gpath.append('.')
|
||||||
|
else:
|
||||||
|
gpath.append('/')
|
||||||
|
fspart = True
|
||||||
|
name = node.name
|
||||||
|
if name[0] in '([':
|
||||||
|
gpath.pop()
|
||||||
|
gpath.append(name)
|
||||||
|
fspath = newfspath
|
||||||
|
return ''.join(gpath)
|
||||||
|
|
||||||
|
class FileLogSession(Session):
|
||||||
|
|
||||||
|
def __init__(self, config):
|
||||||
|
super(FileLogSession, self).__init__(config)
|
||||||
|
self.bus.subscribe(self.log_event_to_file)
|
||||||
|
if hasattr(config.option, 'filelog'):
|
||||||
|
filelog = config.option.filelog
|
||||||
|
self.logfile = open(filelog, 'w') # line buffering ?
|
||||||
|
|
||||||
|
def write_log_entry(self, shortrepr, name, longrepr):
|
||||||
|
print >>self.logfile, "%s %s" % (shortrepr, name)
|
||||||
|
for line in longrepr.splitlines():
|
||||||
|
print >>self.logfile, " %s" % line
|
||||||
|
|
||||||
|
def log_outcome(self, ev):
|
||||||
|
outcome = ev.outcome
|
||||||
|
gpath = generic_path(ev.colitem)
|
||||||
|
self.write_log_entry(outcome.shortrepr, gpath, str(outcome.longrepr))
|
||||||
|
|
||||||
|
def log_event_to_file(self, ev):
|
||||||
|
if isinstance(ev, event.ItemTestReport):
|
||||||
|
self.log_outcome(ev)
|
||||||
|
elif isinstance(ev, event.CollectionReport):
|
||||||
|
if not ev.passed:
|
||||||
|
self.log_outcome(ev)
|
||||||
|
elif isinstance(ev, event.InternalException):
|
||||||
|
path = ev.repr.reprcrash.path # fishing :(
|
||||||
|
self.write_log_entry('!', path, str(ev.repr))
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,210 @@
|
||||||
|
import py
|
||||||
|
|
||||||
|
from filelog import session
|
||||||
|
|
||||||
|
import os, StringIO
|
||||||
|
|
||||||
|
from py.__.test.collect import Node, Item, FSCollector
|
||||||
|
from py.__.test.event import ItemTestReport, CollectionReport
|
||||||
|
from py.__.test.event import InternalException
|
||||||
|
from py.__.test.runner import OutcomeRepr
|
||||||
|
|
||||||
|
|
||||||
|
class Fake(object):
|
||||||
|
def __init__(self, **kwds):
|
||||||
|
self.__dict__.update(kwds)
|
||||||
|
|
||||||
|
|
||||||
|
def test_generic_path():
|
||||||
|
p1 = Node('a', config='dummy')
|
||||||
|
assert p1.fspath is None
|
||||||
|
p2 = Node('B', parent=p1)
|
||||||
|
p3 = Node('()', parent = p2)
|
||||||
|
item = Item('c', parent = p3)
|
||||||
|
|
||||||
|
res = session.generic_path(item)
|
||||||
|
assert res == 'a.B().c'
|
||||||
|
|
||||||
|
p0 = FSCollector('proj/test', config='dummy')
|
||||||
|
p1 = FSCollector('proj/test/a', parent=p0)
|
||||||
|
p2 = Node('B', parent=p1)
|
||||||
|
p3 = Node('()', parent = p2)
|
||||||
|
p4 = Node('c', parent=p3)
|
||||||
|
item = Item('[1]', parent = p4)
|
||||||
|
|
||||||
|
res = session.generic_path(item)
|
||||||
|
assert res == 'test/a:B().c[1]'
|
||||||
|
|
||||||
|
|
||||||
|
def make_item(*names):
|
||||||
|
node = None
|
||||||
|
config = "dummy"
|
||||||
|
for name in names[:-1]:
|
||||||
|
if '/' in name:
|
||||||
|
node = FSCollector(name, parent=node, config=config)
|
||||||
|
else:
|
||||||
|
node = Node(name, parent=node, config=config)
|
||||||
|
if names[-1] is None:
|
||||||
|
return node
|
||||||
|
return Item(names[-1], parent=node)
|
||||||
|
|
||||||
|
class TestFileLogSession(object):
|
||||||
|
|
||||||
|
|
||||||
|
def test_sanity(self):
|
||||||
|
option = Fake(eventlog=None)
|
||||||
|
config = Fake(option=option)
|
||||||
|
|
||||||
|
session.FileLogSession(config)
|
||||||
|
|
||||||
|
def test_open_logfile(self):
|
||||||
|
logfname = os.tempnam()
|
||||||
|
|
||||||
|
option = Fake(eventlog=None, filelog=logfname)
|
||||||
|
config = Fake(option=option)
|
||||||
|
|
||||||
|
sess = session.FileLogSession(config)
|
||||||
|
|
||||||
|
assert len(sess.bus._subscribers) == 1
|
||||||
|
|
||||||
|
assert sess.logfile
|
||||||
|
assert os.path.exists(logfname)
|
||||||
|
|
||||||
|
sess.logfile.close()
|
||||||
|
os.unlink(logfname)
|
||||||
|
|
||||||
|
def test_write_log_entry(self):
|
||||||
|
option = Fake(eventlog=None)
|
||||||
|
config = Fake(option=option)
|
||||||
|
sess = session.FileLogSession(config)
|
||||||
|
|
||||||
|
sess.logfile = StringIO.StringIO()
|
||||||
|
sess.write_log_entry('.', 'name', '')
|
||||||
|
entry = sess.logfile.getvalue()
|
||||||
|
assert entry[-1] == '\n'
|
||||||
|
entry_lines = entry.splitlines()
|
||||||
|
assert len(entry_lines) == 1
|
||||||
|
assert entry_lines[0] == '. name'
|
||||||
|
|
||||||
|
sess.logfile = StringIO.StringIO()
|
||||||
|
sess.write_log_entry('s', 'name', 'Skipped')
|
||||||
|
entry = sess.logfile.getvalue()
|
||||||
|
assert entry[-1] == '\n'
|
||||||
|
entry_lines = entry.splitlines()
|
||||||
|
assert len(entry_lines) == 2
|
||||||
|
assert entry_lines[0] == 's name'
|
||||||
|
assert entry_lines[1] == ' Skipped'
|
||||||
|
|
||||||
|
sess.logfile = StringIO.StringIO()
|
||||||
|
sess.write_log_entry('s', 'name', 'Skipped\n')
|
||||||
|
entry = sess.logfile.getvalue()
|
||||||
|
assert entry[-1] == '\n'
|
||||||
|
entry_lines = entry.splitlines()
|
||||||
|
assert len(entry_lines) == 2
|
||||||
|
assert entry_lines[0] == 's name'
|
||||||
|
assert entry_lines[1] == ' Skipped'
|
||||||
|
|
||||||
|
sess.logfile = StringIO.StringIO()
|
||||||
|
longrepr = ' tb1\n tb 2\nE tb3\nSome Error'
|
||||||
|
sess.write_log_entry('F', 'name', longrepr)
|
||||||
|
entry = sess.logfile.getvalue()
|
||||||
|
assert entry[-1] == '\n'
|
||||||
|
entry_lines = entry.splitlines()
|
||||||
|
assert len(entry_lines) == 5
|
||||||
|
assert entry_lines[0] == 'F name'
|
||||||
|
assert entry_lines[1:] == [' '+line for line in longrepr.splitlines()]
|
||||||
|
|
||||||
|
def test_log_outcome(self):
|
||||||
|
option = Fake(eventlog=None)
|
||||||
|
config = Fake(option=option)
|
||||||
|
sess = session.FileLogSession(config)
|
||||||
|
|
||||||
|
sess.logfile = StringIO.StringIO()
|
||||||
|
colitem = make_item('some', 'path', 'a', 'b')
|
||||||
|
|
||||||
|
try:
|
||||||
|
raise ValueError
|
||||||
|
except ValueError:
|
||||||
|
the_repr = py.code.ExceptionInfo().getrepr()
|
||||||
|
|
||||||
|
outcome=OutcomeRepr('execute', 'F', the_repr)
|
||||||
|
ev = Fake(colitem=colitem, outcome=outcome)
|
||||||
|
|
||||||
|
sess.log_outcome(ev)
|
||||||
|
|
||||||
|
entry = sess.logfile.getvalue()
|
||||||
|
entry_lines = entry.splitlines()
|
||||||
|
|
||||||
|
assert entry_lines[0] == 'F some.path.a.b'
|
||||||
|
assert entry_lines[-1][0] == ' '
|
||||||
|
assert 'ValueError' in entry
|
||||||
|
|
||||||
|
def test_item_test_passed(self):
|
||||||
|
option = Fake(eventlog=None)
|
||||||
|
config = Fake(option=option)
|
||||||
|
sess = session.FileLogSession(config)
|
||||||
|
sess.logfile = StringIO.StringIO()
|
||||||
|
|
||||||
|
colitem = make_item('proj/test', 'proj/test/mod', 'a', 'b')
|
||||||
|
|
||||||
|
outcome=OutcomeRepr('execute', '.', '')
|
||||||
|
rep_ev = ItemTestReport(colitem, passed=outcome)
|
||||||
|
|
||||||
|
sess.bus.notify(rep_ev)
|
||||||
|
|
||||||
|
lines = sess.logfile.getvalue().splitlines()
|
||||||
|
assert len(lines) == 1
|
||||||
|
line = lines[0]
|
||||||
|
assert line.startswith(". ")
|
||||||
|
assert line[2:] == 'test/mod:a.b'
|
||||||
|
|
||||||
|
def test_collection_report(self):
|
||||||
|
option = Fake(eventlog=None)
|
||||||
|
config = Fake(option=option)
|
||||||
|
sess = session.FileLogSession(config)
|
||||||
|
sess.logfile = StringIO.StringIO()
|
||||||
|
|
||||||
|
colitem = make_item('proj/test', 'proj/test/mod', 'A', None)
|
||||||
|
|
||||||
|
outcome=OutcomeRepr('execute', '', '')
|
||||||
|
rep_ev = CollectionReport(colitem, object(), passed=outcome)
|
||||||
|
|
||||||
|
sess.bus.notify(rep_ev)
|
||||||
|
|
||||||
|
entry = sess.logfile.getvalue()
|
||||||
|
assert not entry
|
||||||
|
|
||||||
|
sess.logfile = StringIO.StringIO()
|
||||||
|
outcome=OutcomeRepr('execute', 'F', 'Some Error')
|
||||||
|
rep_ev = CollectionReport(colitem, object(), failed=outcome)
|
||||||
|
|
||||||
|
sess.bus.notify(rep_ev)
|
||||||
|
|
||||||
|
lines = sess.logfile.getvalue().splitlines()
|
||||||
|
assert len(lines) == 2
|
||||||
|
assert lines[0] == 'F test/mod:A'
|
||||||
|
|
||||||
|
def test_internal_exception(self):
|
||||||
|
# they are produced for example by a teardown failing
|
||||||
|
# at the end of the run
|
||||||
|
option = Fake(eventlog=None)
|
||||||
|
config = Fake(option=option)
|
||||||
|
sess = session.FileLogSession(config)
|
||||||
|
sess.logfile = StringIO.StringIO()
|
||||||
|
|
||||||
|
try:
|
||||||
|
raise ValueError
|
||||||
|
except ValueError:
|
||||||
|
excinfo = py.code.ExceptionInfo()
|
||||||
|
|
||||||
|
internal = InternalException(excinfo)
|
||||||
|
|
||||||
|
sess.bus.notify(internal)
|
||||||
|
|
||||||
|
entry = sess.logfile.getvalue()
|
||||||
|
entry_lines = entry.splitlines()
|
||||||
|
|
||||||
|
assert entry_lines[0].startswith('! ')
|
||||||
|
assert os.path.basename(__file__)[:-1] in entry_lines[0] #.py/.pyc
|
||||||
|
assert entry_lines[-1][0] == ' '
|
||||||
|
assert 'ValueError' in entry
|
Loading…
Reference in New Issue