[py-svn] r36986 - in py/branch/config/py/test/rsession: . testing webdata
fijal at codespeak.net
fijal at codespeak.net
Fri Jan 19 13:06:02 CET 2007
Author: fijal
Date: Fri Jan 19 13:05:58 2007
New Revision: 36986
Modified:
py/branch/config/py/test/rsession/box.py
py/branch/config/py/test/rsession/executor.py
py/branch/config/py/test/rsession/master.py
py/branch/config/py/test/rsession/slave.py
py/branch/config/py/test/rsession/testing/test_master.py
py/branch/config/py/test/rsession/testing/test_slave.py
py/branch/config/py/test/rsession/testing/test_webjs.py
py/branch/config/py/test/rsession/webdata/source.js
Log:
Improve the behaviour off cleanup and channel closing, at least on slave side.
Some cleanups, got rid of some hacks (in favor of other hacks, but posix
is a bit hackish anyway)
Modified: py/branch/config/py/test/rsession/box.py
==============================================================================
--- py/branch/config/py/test/rsession/box.py (original)
+++ py/branch/config/py/test/rsession/box.py Fri Jan 19 13:05:58 2007
@@ -86,8 +86,8 @@
retvalf.close()
os._exit(0)
- def parent(self, pid):
- pid, exitstat = os.waitpid(pid, 0)
+ def parent(self, pid, waiter=os.waitpid):
+ pid, exitstat = waiter(pid, 0)
self.signal = exitstat & 0x7f
self.exitstat = exitstat & 0xff00
Modified: py/branch/config/py/test/rsession/executor.py
==============================================================================
--- py/branch/config/py/test/rsession/executor.py (original)
+++ py/branch/config/py/test/rsession/executor.py Fri Jan 19 13:05:58 2007
@@ -84,8 +84,8 @@
b = Box(fun, config=self.config)
parent, pid = b.run(continuation=True)
- def cont():
- parent(pid)
+ def cont(waiter=os.waitpid):
+ parent(pid, waiter=waiter)
if b.retval is not None:
passed, setupfailure, excinfo, skipped,\
critical, _, _, _ = b.retval
Modified: py/branch/config/py/test/rsession/master.py
==============================================================================
--- py/branch/config/py/test/rsession/master.py (original)
+++ py/branch/config/py/test/rsession/master.py Fri Jan 19 13:05:58 2007
@@ -35,7 +35,7 @@
self.reporter(report.SendItem(self.channel, item))
def itemgen(colitems, reporter, keyword, reporterror):
- for x in colitems:
+ for x in colitems:
for y in x.tryiter(reporterror = lambda x: reporterror(reporter, x), keyword = keyword):
yield y
Modified: py/branch/config/py/test/rsession/slave.py
==============================================================================
--- py/branch/config/py/test/rsession/slave.py (original)
+++ py/branch/config/py/test/rsession/slave.py Fri Jan 19 13:05:58 2007
@@ -5,16 +5,51 @@
import py
from py.__.test.rsession.executor import RunExecutor, BoxExecutor, AsyncExecutor
from py.__.test.rsession.outcome import Outcome
+import thread
+import os
-class Info:
- # XXX: Another nasty hack to get rid off
- pid = None
+class PidInfo(object):
+ """ Pure container class to store information of actually running
+ pid
+ """
+ def __init__(self):
+ self.pid = 0
+ self.lock = thread.allocate_lock()
+
+ def set_pid(self, pid):
+ self.lock.acquire()
+ try:
+ self.pid = pid
+ finally:
+ self.lock.release()
+
+ def kill(self):
+ self.lock.acquire()
+ try:
+ if self.pid:
+ os.kill(self.pid, 15)
+ self.pid = 0
+ finally:
+ self.lock.release()
+
+ def waitandclear(self, pid, num):
+ """ This is an obscure hack to keep locking properly, adhere to posix semantics
+ and try to clean it as much as possible, not clean at all
+ """
+ self.lock.acquire()
+ try:
+ retval = os.waitpid(self.pid, 0)
+ self.pid = 0
+ return retval
+ finally:
+ self.lock.release()
class SlaveNode(object):
- def __init__(self, rootcollector, config, executor=AsyncExecutor):
+ def __init__(self, rootcollector, config, pidinfo, executor=AsyncExecutor):
self.rootcollector = rootcollector
self.config = config
self.executor = executor
+ self.pidinfo = pidinfo
def execute(self, itemspec):
item = self.rootcollector.getitembynames(itemspec)
@@ -24,11 +59,11 @@
ex = self.executor(item, config=self.config)
if self.executor is AsyncExecutor:
cont, pid = ex.execute()
+ self.pidinfo.set_pid(pid)
else:
# for tests only
return ex.execute()
- Info.pid = pid
- return cont()
+ return cont(self.pidinfo.waitandclear)
def run(self, itemspec):
#outcome = self.execute(itemspec)
@@ -39,7 +74,7 @@
else:
return outcome.make_repr(self.config.option.tbstyle)
-def slave_main(receive, send, path, config, info = None):
+def slave_main(receive, send, path, config, pidinfo):
import os
assert os.path.exists(path)
path = os.path.abspath(path)
@@ -49,7 +84,7 @@
if node is not None:
return node
col = py.test.collect.Directory(str(py.path.local(path).join(item[0])))
- node = nodes[item[0]] = SlaveNode(col, config)
+ node = nodes[item[0]] = SlaveNode(col, config, pidinfo)
return node
while 1:
nextitem = receive()
@@ -72,15 +107,14 @@
while nextitem is not None:
nextitem = receive()
-
+
def setup():
- def callback_gen(queue):
- from py.__.test.rsession.slave import Info
+ def callback_gen(channel, queue, info):
def callback(item):
if item == 42: # magic call-cleanup
# XXX should kill a pid here
- if Info.pid:
- os.kill(Info.pid, 15)
+ info.kill()
+ channel.close()
sys.exit(0)
queue.put(item)
return callback
@@ -100,15 +134,15 @@
config.conftest.setinitial([basedir])
#config.conftest.lget('adddefaultoptions')()
config.merge_repr(config_repr)
- from py.__.test.rsession.slave import Info
- Info.pid = 0
if not config.option.nomagic:
py.magic.invoke(assertion=1)
mod = __import__(pkgname)
assert py.path.local(mod.__file__).dirpath() == py.path.local(pkgdir)
- from py.__.test.rsession.slave import slave_main
+ from py.__.test.rsession.slave import slave_main, PidInfo
queue = py.std.Queue.Queue()
- channel.setcallback(callback_gen(queue))
- slave_main(queue.get, channel.send, basedir, config)
+ pidinfo = PidInfo()
+ channel.setcallback(callback_gen(channel, queue, pidinfo))
+ slave_main(queue.get, channel.send, basedir, config, pidinfo)
if not config.option.nomagic:
py.magic.revoke(assertion=1)
+ channel.close()
Modified: py/branch/config/py/test/rsession/testing/test_master.py
==============================================================================
--- py/branch/config/py/test/rsession/testing/test_master.py (original)
+++ py/branch/config/py/test/rsession/testing/test_master.py Fri Jan 19 13:05:58 2007
@@ -11,7 +11,7 @@
from py.__.test.rsession.master import dispatch_loop, setup_slave, MasterNode, randomgen
from py.__.test.rsession.outcome import ReprOutcome, Outcome
-from py.__.test.rsession.testing.test_slave import funcpass_spec, funcfail_spec
+from py.__.test.rsession.testing.test_slave import funcpass_spec, funcfail_spec, funchang_spec
from py.__.test.rsession import report
from py.__.test.rsession.hostmanage import HostInfo
@@ -94,7 +94,7 @@
channel.send(funcpass_spec)
output = ReprOutcome(channel.receive())
assert output.passed
- channel.send(None)
+ channel.send(42)
channel.waitclose(10)
gw.exit()
@@ -126,6 +126,34 @@
shouldstop = lambda : False
dispatch_loop(master_nodes, itemgenerator, shouldstop)
+def test_slave_running_interrupted():
+ #def simple_report(event):
+ # if not isinstance(event, report.ReceivedItemOutcome):
+ # return
+ # item = event.item
+ # if item.code.name == 'funcpass':
+ # assert event.outcome.passed
+ # else:
+ # assert not event.outcome.passed
+ reports = []
+
+ def open_gw():
+ gw = py.execnet.PopenGateway()
+ gw.host = HostInfo("localhost")
+ gw.host.gw = gw
+ config = py.test.config._reparse([])
+ channel = setup_slave(gw, pkgdir, config)
+ mn = MasterNode(channel, reports.append, {})
+ return mn, gw, channel
+
+ mn, gw, channel = open_gw()
+ rootcol = py.test.collect.Directory(pkgdir.dirpath())
+ funchang_item = rootcol.getitembynames(funchang_spec)
+ mn.send(funchang_item)
+ mn.send(StopIteration)
+ # XXX: We have to wait here a bit to make sure that it really did happen
+ channel.waitclose(2)
+
def test_randomgen():
d = {}
gen = randomgen({1:True, 2:True, 3:True}, d)
Modified: py/branch/config/py/test/rsession/testing/test_slave.py
==============================================================================
--- py/branch/config/py/test/rsession/testing/test_slave.py (original)
+++ py/branch/config/py/test/rsession/testing/test_slave.py Fri Jan 19 13:05:58 2007
@@ -1,6 +1,6 @@
""" Testing the slave side node code (in a local way). """
-from py.__.test.rsession.slave import SlaveNode, slave_main, setup
+from py.__.test.rsession.slave import SlaveNode, slave_main, setup, PidInfo
from py.__.test.rsession.outcome import ReprOutcome
import py, sys
@@ -55,7 +55,8 @@
def gettestnode():
rootcol = py.test.collect.Directory(rootdir)
config = py.test.config._reparse([rootdir])
- node = SlaveNode(rootcol, config, executor=RunExecutor)
+ pidinfo = PidInfo()
+ node = SlaveNode(rootcol, config, pidinfo, executor=RunExecutor)
return node
def test_slave_run_passing():
@@ -109,7 +110,8 @@
funcfail_spec
]
config = py.test.config._reparse([])
- slave_main(q.pop, res.append, str(rootdir), config)
+ pidinfo = PidInfo()
+ slave_main(q.pop, res.append, str(rootdir), config, pidinfo)
assert len(res) == 2
res_repr = [ReprOutcome(r) for r in res]
assert not res_repr[0].passed and res_repr[1].passed
@@ -134,6 +136,10 @@
raise NotImplementedError("more data")
self.count += 1
return retval
+
+ def close(self):
+ pass
+
try:
exec py.code.Source(setup, "setup()").compile() in {
'channel': C()}
@@ -168,6 +174,9 @@
callback(self.q.pop())
f()
#thread.start_new_thread(f, ())
+
+ def close(self):
+ pass
send = res.append
try:
Modified: py/branch/config/py/test/rsession/testing/test_webjs.py
==============================================================================
--- py/branch/config/py/test/rsession/testing/test_webjs.py (original)
+++ py/branch/config/py/test/rsession/testing/test_webjs.py Fri Jan 19 13:05:58 2007
@@ -7,8 +7,6 @@
from pypy.translator.js.tester import schedule_callbacks
here = py.magic.autopath().dirpath()
-py.test.skip("will fix later, multiple issues")
-
def setup_module(mod):
# load HTML into window object
html = here.join('../webdata/index.html').read()
@@ -18,9 +16,7 @@
dom.window = dom.Window(html)
dom.document = dom.window.document
config = py.test.config._reparse([])
- from py.__.test.rsession.rsession import session_options
- session_options.bind_config(config)
- session_options.import_pypy = True
+ config._overwrite('_dist_import_pypy', True)
from py.__.test.rsession import webjs
from py.__.test.rsession.web import exported_methods
mod.webjs = webjs
Modified: py/branch/config/py/test/rsession/webdata/source.js
==============================================================================
Binary files. No diff available.
More information about the pytest-commit
mailing list