remove py.execnet, substitute py.execnet usages with "execnet" ones.
--HG-- branch : trunk
This commit is contained in:
@@ -1 +0,0 @@
|
||||
#
|
||||
@@ -1,46 +0,0 @@
|
||||
import py
|
||||
|
||||
def pytest_generate_tests(metafunc):
|
||||
if 'gw' in metafunc.funcargnames:
|
||||
if hasattr(metafunc.cls, 'gwtype'):
|
||||
gwtypes = [metafunc.cls.gwtype]
|
||||
else:
|
||||
gwtypes = ['popen', 'socket', 'ssh']
|
||||
for gwtype in gwtypes:
|
||||
metafunc.addcall(id=gwtype, param=gwtype)
|
||||
|
||||
def pytest_funcarg__gw(request):
|
||||
scope = "session"
|
||||
if request.param == "popen":
|
||||
return request.cached_setup(
|
||||
setup=py.execnet.PopenGateway,
|
||||
teardown=lambda gw: gw.exit(),
|
||||
extrakey=request.param,
|
||||
scope=scope)
|
||||
elif request.param == "socket":
|
||||
return request.cached_setup(
|
||||
setup=setup_socket_gateway,
|
||||
teardown=teardown_socket_gateway,
|
||||
extrakey=request.param,
|
||||
scope=scope)
|
||||
elif request.param == "ssh":
|
||||
return request.cached_setup(
|
||||
setup=lambda: setup_ssh_gateway(request),
|
||||
teardown=lambda gw: gw.exit(),
|
||||
extrakey=request.param,
|
||||
scope=scope)
|
||||
|
||||
def setup_socket_gateway():
|
||||
proxygw = py.execnet.PopenGateway()
|
||||
gw = py.execnet.SocketGateway.new_remote(proxygw, ("127.0.0.1", 0))
|
||||
gw.proxygw = proxygw
|
||||
return gw
|
||||
|
||||
def teardown_socket_gateway(gw):
|
||||
gw.exit()
|
||||
gw.proxygw.exit()
|
||||
|
||||
def setup_ssh_gateway(request):
|
||||
sshhost = request.getfuncargvalue('specssh').ssh
|
||||
gw = py.execnet.SshGateway(sshhost)
|
||||
return gw
|
||||
@@ -1,198 +0,0 @@
|
||||
|
||||
import py
|
||||
import sys, os, subprocess, inspect
|
||||
from py.__.execnet import gateway_base, gateway
|
||||
from py.__.execnet.gateway_base import Message, Channel, ChannelFactory
|
||||
|
||||
def test_subprocess_interaction(anypython):
|
||||
line = gateway.popen_bootstrapline
|
||||
compile(line, 'xyz', 'exec')
|
||||
args = [str(anypython), '-c', line]
|
||||
popen = subprocess.Popen(args, bufsize=0, stderr=subprocess.STDOUT,
|
||||
stdin=subprocess.PIPE, stdout=subprocess.PIPE)
|
||||
def send(line):
|
||||
popen.stdin.write(line.encode('ascii'))
|
||||
if sys.version_info > (3,0): # 3k still buffers
|
||||
popen.stdin.flush()
|
||||
def receive():
|
||||
return popen.stdout.readline().decode('ascii')
|
||||
|
||||
try:
|
||||
source = py.code.Source(read_write_loop, "read_write_loop()")
|
||||
repr_source = repr(str(source)) + "\n"
|
||||
sendline = repr_source
|
||||
send(sendline)
|
||||
s = receive()
|
||||
assert s == "ok\n"
|
||||
send("hello\n")
|
||||
s = receive()
|
||||
assert s == "received: hello\n"
|
||||
send("world\n")
|
||||
s = receive()
|
||||
assert s == "received: world\n"
|
||||
finally:
|
||||
popen.stdin.close()
|
||||
popen.stdout.close()
|
||||
popen.wait()
|
||||
|
||||
def read_write_loop():
|
||||
import os, sys
|
||||
sys.stdout.write("ok\n")
|
||||
sys.stdout.flush()
|
||||
while 1:
|
||||
try:
|
||||
line = sys.stdin.readline()
|
||||
sys.stdout.write("received: %s" % line)
|
||||
sys.stdout.flush()
|
||||
except (IOError, EOFError):
|
||||
break
|
||||
|
||||
def pytest_generate_tests(metafunc):
|
||||
if 'anypython' in metafunc.funcargnames:
|
||||
for name in 'python3.1', 'python2.4', 'python2.5', 'python2.6':
|
||||
metafunc.addcall(id=name, param=name)
|
||||
|
||||
def pytest_funcarg__anypython(request):
|
||||
name = request.param
|
||||
executable = py.path.local.sysfind(name)
|
||||
if executable is None:
|
||||
py.test.skip("no %s found" % (name,))
|
||||
return executable
|
||||
|
||||
def test_io_message(anypython, tmpdir):
|
||||
check = tmpdir.join("check.py")
|
||||
check.write(py.code.Source(gateway_base, """
|
||||
try:
|
||||
from io import BytesIO
|
||||
except ImportError:
|
||||
from StringIO import StringIO as BytesIO
|
||||
import tempfile
|
||||
temp_out = BytesIO()
|
||||
temp_in = BytesIO()
|
||||
io = Popen2IO(temp_out, temp_in)
|
||||
for i, msg_cls in Message._types.items():
|
||||
print ("checking %s %s" %(i, msg_cls))
|
||||
for data in "hello", "hello".encode('ascii'):
|
||||
msg1 = msg_cls(i, data)
|
||||
msg1.writeto(io)
|
||||
x = io.outfile.getvalue()
|
||||
io.outfile.truncate(0)
|
||||
io.outfile.seek(0)
|
||||
io.infile.seek(0)
|
||||
io.infile.write(x)
|
||||
io.infile.seek(0)
|
||||
msg2 = Message.readfrom(io)
|
||||
assert msg1.channelid == msg2.channelid, (msg1, msg2)
|
||||
assert msg1.data == msg2.data
|
||||
print ("all passed")
|
||||
"""))
|
||||
#out = py.process.cmdexec("%s %s" %(executable,check))
|
||||
out = anypython.sysexec(check)
|
||||
print (out)
|
||||
assert "all passed" in out
|
||||
|
||||
def test_popen_io(anypython, tmpdir):
|
||||
check = tmpdir.join("check.py")
|
||||
check.write(py.code.Source(gateway_base, """
|
||||
do_exec(Popen2IO.server_stmt, globals())
|
||||
io.write("hello".encode('ascii'))
|
||||
s = io.read(1)
|
||||
assert s == "x".encode('ascii')
|
||||
"""))
|
||||
from subprocess import Popen, PIPE
|
||||
args = [str(anypython), str(check)]
|
||||
proc = Popen(args, stdin=PIPE, stdout=PIPE, stderr=PIPE)
|
||||
proc.stdin.write("x".encode('ascii'))
|
||||
stdout, stderr = proc.communicate()
|
||||
print (stderr)
|
||||
ret = proc.wait()
|
||||
assert "hello".encode('ascii') in stdout
|
||||
|
||||
|
||||
def test_rinfo_source(anypython, tmpdir):
|
||||
check = tmpdir.join("check.py")
|
||||
check.write(py.code.Source("""
|
||||
class Channel:
|
||||
def send(self, data):
|
||||
assert eval(repr(data), {}) == data
|
||||
channel = Channel()
|
||||
""", gateway.rinfo_source, """
|
||||
print ('all passed')
|
||||
"""))
|
||||
out = anypython.sysexec(check)
|
||||
print (out)
|
||||
assert "all passed" in out
|
||||
|
||||
def test_geterrortext(anypython, tmpdir):
|
||||
check = tmpdir.join("check.py")
|
||||
check.write(py.code.Source(gateway_base, """
|
||||
class Arg:
|
||||
pass
|
||||
errortext = geterrortext((Arg, "1", 4))
|
||||
assert "Arg" in errortext
|
||||
import sys
|
||||
try:
|
||||
raise ValueError("17")
|
||||
except ValueError:
|
||||
excinfo = sys.exc_info()
|
||||
s = geterrortext(excinfo)
|
||||
assert "17" in s
|
||||
print ("all passed")
|
||||
"""))
|
||||
out = anypython.sysexec(check)
|
||||
print (out)
|
||||
assert "all passed" in out
|
||||
|
||||
def test_stdouterrin_setnull():
|
||||
cap = py.io.StdCaptureFD()
|
||||
from py.__.execnet.gateway import stdouterrin_setnull
|
||||
stdouterrin_setnull()
|
||||
import os
|
||||
os.write(1, "hello".encode('ascii'))
|
||||
if os.name == "nt":
|
||||
os.write(2, "world")
|
||||
os.read(0, 1)
|
||||
out, err = cap.reset()
|
||||
assert not out
|
||||
assert not err
|
||||
|
||||
|
||||
class TestMessage:
|
||||
def test_wire_protocol(self):
|
||||
for cls in Message._types.values():
|
||||
one = py.io.BytesIO()
|
||||
data = '23'.encode('ascii')
|
||||
cls(42, data).writeto(one)
|
||||
two = py.io.BytesIO(one.getvalue())
|
||||
msg = Message.readfrom(two)
|
||||
assert isinstance(msg, cls)
|
||||
assert msg.channelid == 42
|
||||
assert msg.data == data
|
||||
assert isinstance(repr(msg), str)
|
||||
# == "<Message.%s channelid=42 '23'>" %(msg.__class__.__name__, )
|
||||
|
||||
class TestPureChannel:
|
||||
def setup_method(self, method):
|
||||
self.fac = ChannelFactory(None)
|
||||
|
||||
def test_factory_create(self):
|
||||
chan1 = self.fac.new()
|
||||
assert chan1.id == 1
|
||||
chan2 = self.fac.new()
|
||||
assert chan2.id == 3
|
||||
|
||||
def test_factory_getitem(self):
|
||||
chan1 = self.fac.new()
|
||||
assert self.fac._channels[chan1.id] == chan1
|
||||
chan2 = self.fac.new()
|
||||
assert self.fac._channels[chan2.id] == chan2
|
||||
|
||||
def test_channel_timeouterror(self):
|
||||
channel = self.fac.new()
|
||||
py.test.raises(IOError, channel.waitclose, timeout=0.01)
|
||||
|
||||
def test_channel_makefile_incompatmode(self):
|
||||
channel = self.fac.new()
|
||||
py.test.raises(ValueError, 'channel.makefile("rw")')
|
||||
|
||||
|
||||
@@ -1,545 +0,0 @@
|
||||
"""
|
||||
mostly functional tests of gateways.
|
||||
"""
|
||||
import os, sys, time
|
||||
import py
|
||||
from py.__.execnet import gateway_base, gateway
|
||||
queue = py.builtin._tryimport('queue', 'Queue')
|
||||
|
||||
TESTTIMEOUT = 10.0 # seconds
|
||||
|
||||
class TestBasicRemoteExecution:
|
||||
def test_correct_setup(self, gw):
|
||||
assert gw._receiverthread.isAlive()
|
||||
|
||||
def test_repr_doesnt_crash(self, gw):
|
||||
assert isinstance(repr(gw), str)
|
||||
|
||||
def test_attribute__name__(self, gw):
|
||||
channel = gw.remote_exec("channel.send(__name__)")
|
||||
name = channel.receive()
|
||||
assert name == "__channelexec__"
|
||||
|
||||
def test_correct_setup_no_py(self, gw):
|
||||
channel = gw.remote_exec("""
|
||||
import sys
|
||||
channel.send(list(sys.modules))
|
||||
""")
|
||||
remotemodules = channel.receive()
|
||||
assert 'py' not in remotemodules, (
|
||||
"py should not be imported on remote side")
|
||||
|
||||
def test_remote_exec_waitclose(self, gw):
|
||||
channel = gw.remote_exec('pass')
|
||||
channel.waitclose(TESTTIMEOUT)
|
||||
|
||||
def test_remote_exec_waitclose_2(self, gw):
|
||||
channel = gw.remote_exec('def gccycle(): pass')
|
||||
channel.waitclose(TESTTIMEOUT)
|
||||
|
||||
def test_remote_exec_waitclose_noarg(self, gw):
|
||||
channel = gw.remote_exec('pass')
|
||||
channel.waitclose()
|
||||
|
||||
def test_remote_exec_error_after_close(self, gw):
|
||||
channel = gw.remote_exec('pass')
|
||||
channel.waitclose(TESTTIMEOUT)
|
||||
py.test.raises(IOError, channel.send, 0)
|
||||
|
||||
def test_remote_exec_channel_anonymous(self, gw):
|
||||
channel = gw.remote_exec('''
|
||||
obj = channel.receive()
|
||||
channel.send(obj)
|
||||
''')
|
||||
channel.send(42)
|
||||
result = channel.receive()
|
||||
assert result == 42
|
||||
|
||||
class TestChannelBasicBehaviour:
|
||||
def test_channel_close_and_then_receive_error(self, gw):
|
||||
channel = gw.remote_exec('raise ValueError')
|
||||
py.test.raises(channel.RemoteError, channel.receive)
|
||||
|
||||
def test_channel_finish_and_then_EOFError(self, gw):
|
||||
channel = gw.remote_exec('channel.send(42)')
|
||||
x = channel.receive()
|
||||
assert x == 42
|
||||
py.test.raises(EOFError, channel.receive)
|
||||
py.test.raises(EOFError, channel.receive)
|
||||
py.test.raises(EOFError, channel.receive)
|
||||
|
||||
def test_channel_close_and_then_receive_error_multiple(self, gw):
|
||||
channel = gw.remote_exec('channel.send(42) ; raise ValueError')
|
||||
x = channel.receive()
|
||||
assert x == 42
|
||||
py.test.raises(channel.RemoteError, channel.receive)
|
||||
|
||||
def test_channel__local_close(self, gw):
|
||||
channel = gw._channelfactory.new()
|
||||
gw._channelfactory._local_close(channel.id)
|
||||
channel.waitclose(0.1)
|
||||
|
||||
def test_channel__local_close_error(self, gw):
|
||||
channel = gw._channelfactory.new()
|
||||
gw._channelfactory._local_close(channel.id,
|
||||
channel.RemoteError("error"))
|
||||
py.test.raises(channel.RemoteError, channel.waitclose, 0.01)
|
||||
|
||||
def test_channel_error_reporting(self, gw):
|
||||
channel = gw.remote_exec('def foo():\n return foobar()\nfoo()\n')
|
||||
try:
|
||||
channel.receive()
|
||||
except channel.RemoteError:
|
||||
e = sys.exc_info()[1]
|
||||
assert str(e).startswith('Traceback (most recent call last):')
|
||||
assert str(e).find('NameError: global name \'foobar\' '
|
||||
'is not defined') > -1
|
||||
else:
|
||||
py.test.fail('No exception raised')
|
||||
|
||||
def test_channel_syntax_error(self, gw):
|
||||
# missing colon
|
||||
channel = gw.remote_exec('def foo()\n return 1\nfoo()\n')
|
||||
try:
|
||||
channel.receive()
|
||||
except channel.RemoteError:
|
||||
e = sys.exc_info()[1]
|
||||
assert str(e).startswith('Traceback (most recent call last):')
|
||||
assert str(e).find('SyntaxError') > -1
|
||||
|
||||
def test_channel_iter(self, gw):
|
||||
channel = gw.remote_exec("""
|
||||
for x in range(3):
|
||||
channel.send(x)
|
||||
""")
|
||||
l = list(channel)
|
||||
assert l == [0, 1, 2]
|
||||
|
||||
def test_channel_passing_over_channel(self, gw):
|
||||
channel = gw.remote_exec('''
|
||||
c = channel.gateway.newchannel()
|
||||
channel.send(c)
|
||||
c.send(42)
|
||||
''')
|
||||
c = channel.receive()
|
||||
x = c.receive()
|
||||
assert x == 42
|
||||
|
||||
# check that the both sides previous channels are really gone
|
||||
channel.waitclose(TESTTIMEOUT)
|
||||
#assert c.id not in gw._channelfactory
|
||||
newchan = gw.remote_exec('''
|
||||
assert %d not in channel.gateway._channelfactory._channels
|
||||
''' % (channel.id))
|
||||
newchan.waitclose(TESTTIMEOUT)
|
||||
assert channel.id not in gw._channelfactory._channels
|
||||
|
||||
def test_channel_receiver_callback(self, gw):
|
||||
l = []
|
||||
#channel = gw.newchannel(receiver=l.append)
|
||||
channel = gw.remote_exec(source='''
|
||||
channel.send(42)
|
||||
channel.send(13)
|
||||
channel.send(channel.gateway.newchannel())
|
||||
''')
|
||||
channel.setcallback(callback=l.append)
|
||||
py.test.raises(IOError, channel.receive)
|
||||
channel.waitclose(TESTTIMEOUT)
|
||||
assert len(l) == 3
|
||||
assert l[:2] == [42,13]
|
||||
assert isinstance(l[2], channel.__class__)
|
||||
|
||||
def test_channel_callback_after_receive(self, gw):
|
||||
l = []
|
||||
channel = gw.remote_exec(source='''
|
||||
channel.send(42)
|
||||
channel.send(13)
|
||||
channel.send(channel.gateway.newchannel())
|
||||
''')
|
||||
x = channel.receive()
|
||||
assert x == 42
|
||||
channel.setcallback(callback=l.append)
|
||||
py.test.raises(IOError, channel.receive)
|
||||
channel.waitclose(TESTTIMEOUT)
|
||||
assert len(l) == 2
|
||||
assert l[0] == 13
|
||||
assert isinstance(l[1], channel.__class__)
|
||||
|
||||
def test_waiting_for_callbacks(self, gw):
|
||||
l = []
|
||||
def callback(msg):
|
||||
import time; time.sleep(0.2)
|
||||
l.append(msg)
|
||||
channel = gw.remote_exec(source='''
|
||||
channel.send(42)
|
||||
''')
|
||||
channel.setcallback(callback)
|
||||
channel.waitclose(TESTTIMEOUT)
|
||||
assert l == [42]
|
||||
|
||||
def test_channel_callback_stays_active(self, gw):
|
||||
self.check_channel_callback_stays_active(gw, earlyfree=True)
|
||||
|
||||
def check_channel_callback_stays_active(self, gw, earlyfree=True):
|
||||
# with 'earlyfree==True', this tests the "sendonly" channel state.
|
||||
l = []
|
||||
channel = gw.remote_exec(source='''
|
||||
try:
|
||||
import thread
|
||||
except ImportError:
|
||||
import _thread as thread
|
||||
import time
|
||||
def producer(subchannel):
|
||||
for i in range(5):
|
||||
time.sleep(0.15)
|
||||
subchannel.send(i*100)
|
||||
channel2 = channel.receive()
|
||||
thread.start_new_thread(producer, (channel2,))
|
||||
del channel2
|
||||
''')
|
||||
subchannel = gw.newchannel()
|
||||
subchannel.setcallback(l.append)
|
||||
channel.send(subchannel)
|
||||
if earlyfree:
|
||||
subchannel = None
|
||||
counter = 100
|
||||
while len(l) < 5:
|
||||
if subchannel and subchannel.isclosed():
|
||||
break
|
||||
counter -= 1
|
||||
print(counter)
|
||||
if not counter:
|
||||
py.test.fail("timed out waiting for the answer[%d]" % len(l))
|
||||
time.sleep(0.04) # busy-wait
|
||||
assert l == [0, 100, 200, 300, 400]
|
||||
return subchannel
|
||||
|
||||
def test_channel_callback_remote_freed(self, gw):
|
||||
channel = self.check_channel_callback_stays_active(gw, earlyfree=False)
|
||||
# freed automatically at the end of producer()
|
||||
channel.waitclose(TESTTIMEOUT)
|
||||
|
||||
def test_channel_endmarker_callback(self, gw):
|
||||
l = []
|
||||
channel = gw.remote_exec(source='''
|
||||
channel.send(42)
|
||||
channel.send(13)
|
||||
channel.send(channel.gateway.newchannel())
|
||||
''')
|
||||
channel.setcallback(l.append, 999)
|
||||
py.test.raises(IOError, channel.receive)
|
||||
channel.waitclose(TESTTIMEOUT)
|
||||
assert len(l) == 4
|
||||
assert l[:2] == [42,13]
|
||||
assert isinstance(l[2], channel.__class__)
|
||||
assert l[3] == 999
|
||||
|
||||
def test_channel_endmarker_callback_error(self, gw):
|
||||
q = queue.Queue()
|
||||
channel = gw.remote_exec(source='''
|
||||
raise ValueError()
|
||||
''')
|
||||
channel.setcallback(q.put, endmarker=999)
|
||||
val = q.get(TESTTIMEOUT)
|
||||
assert val == 999
|
||||
err = channel._getremoteerror()
|
||||
assert err
|
||||
assert str(err).find("ValueError") != -1
|
||||
|
||||
@py.test.mark.xfail
|
||||
def test_remote_redirect_stdout(self, gw):
|
||||
out = py.io.TextIO()
|
||||
handle = gw._remote_redirect(stdout=out)
|
||||
c = gw.remote_exec("print 42")
|
||||
c.waitclose(TESTTIMEOUT)
|
||||
handle.close()
|
||||
s = out.getvalue()
|
||||
assert s.strip() == "42"
|
||||
|
||||
@py.test.mark.xfail
|
||||
def test_remote_exec_redirect_multi(self, gw):
|
||||
num = 3
|
||||
l = [[] for x in range(num)]
|
||||
channels = [gw.remote_exec("print %d" % i,
|
||||
stdout=l[i].append)
|
||||
for i in range(num)]
|
||||
for x in channels:
|
||||
x.waitclose(TESTTIMEOUT)
|
||||
|
||||
for i in range(num):
|
||||
subl = l[i]
|
||||
assert subl
|
||||
s = subl[0]
|
||||
assert s.strip() == str(i)
|
||||
|
||||
class TestChannelFile:
|
||||
def test_channel_file_write(self, gw):
|
||||
channel = gw.remote_exec("""
|
||||
f = channel.makefile()
|
||||
f.write("hello world\\n")
|
||||
f.close()
|
||||
channel.send(42)
|
||||
""")
|
||||
first = channel.receive()
|
||||
assert first.strip() == 'hello world'
|
||||
second = channel.receive()
|
||||
assert second == 42
|
||||
|
||||
def test_channel_file_write_error(self, gw):
|
||||
channel = gw.remote_exec("pass")
|
||||
f = channel.makefile()
|
||||
channel.waitclose(TESTTIMEOUT)
|
||||
py.test.raises(IOError, f.write, 'hello')
|
||||
|
||||
def test_channel_file_proxyclose(self, gw):
|
||||
channel = gw.remote_exec("""
|
||||
f = channel.makefile(proxyclose=True)
|
||||
f.write("hello world")
|
||||
f.close()
|
||||
channel.send(42)
|
||||
""")
|
||||
first = channel.receive()
|
||||
assert first.strip() == 'hello world'
|
||||
py.test.raises(EOFError, channel.receive)
|
||||
|
||||
def test_channel_file_read(self, gw):
|
||||
channel = gw.remote_exec("""
|
||||
f = channel.makefile(mode='r')
|
||||
s = f.read(2)
|
||||
channel.send(s)
|
||||
s = f.read(5)
|
||||
channel.send(s)
|
||||
""")
|
||||
channel.send("xyabcde")
|
||||
s1 = channel.receive()
|
||||
s2 = channel.receive()
|
||||
assert s1 == "xy"
|
||||
assert s2 == "abcde"
|
||||
|
||||
def test_channel_file_read_empty(self, gw):
|
||||
channel = gw.remote_exec("pass")
|
||||
f = channel.makefile(mode="r")
|
||||
s = f.read(3)
|
||||
assert s == ""
|
||||
s = f.read(5)
|
||||
assert s == ""
|
||||
|
||||
def test_channel_file_readline_remote(self, gw):
|
||||
channel = gw.remote_exec("""
|
||||
channel.send('123\\n45')
|
||||
""")
|
||||
channel.waitclose(TESTTIMEOUT)
|
||||
f = channel.makefile(mode="r")
|
||||
s = f.readline()
|
||||
assert s == "123\n"
|
||||
s = f.readline()
|
||||
assert s == "45"
|
||||
|
||||
def test_channel_makefile_incompatmode(self, gw):
|
||||
channel = gw.newchannel()
|
||||
py.test.raises(ValueError, 'channel.makefile("rw")')
|
||||
|
||||
def test_confusion_from_os_write_stdout(self, gw):
|
||||
channel = gw.remote_exec("""
|
||||
import os
|
||||
os.write(1, 'confusion!'.encode('ascii'))
|
||||
channel.send(channel.receive() * 6)
|
||||
channel.send(channel.receive() * 6)
|
||||
""")
|
||||
channel.send(3)
|
||||
res = channel.receive()
|
||||
assert res == 18
|
||||
channel.send(7)
|
||||
res = channel.receive()
|
||||
assert res == 42
|
||||
|
||||
def test_confusion_from_os_write_stderr(self, gw):
|
||||
channel = gw.remote_exec("""
|
||||
import os
|
||||
os.write(2, 'test'.encode('ascii'))
|
||||
channel.send(channel.receive() * 6)
|
||||
channel.send(channel.receive() * 6)
|
||||
""")
|
||||
channel.send(3)
|
||||
res = channel.receive()
|
||||
assert res == 18
|
||||
channel.send(7)
|
||||
res = channel.receive()
|
||||
assert res == 42
|
||||
|
||||
def test__rinfo(self, gw):
|
||||
rinfo = gw._rinfo()
|
||||
assert rinfo.executable
|
||||
assert rinfo.cwd
|
||||
assert rinfo.version_info
|
||||
s = repr(rinfo)
|
||||
old = gw.remote_exec("""
|
||||
import os.path
|
||||
cwd = os.getcwd()
|
||||
channel.send(os.path.basename(cwd))
|
||||
os.chdir('..')
|
||||
""").receive()
|
||||
try:
|
||||
rinfo2 = gw._rinfo()
|
||||
assert rinfo2.cwd == rinfo.cwd
|
||||
rinfo3 = gw._rinfo(update=True)
|
||||
assert rinfo3.cwd != rinfo2.cwd
|
||||
finally:
|
||||
gw._cache_rinfo = rinfo
|
||||
gw.remote_exec("import os ; os.chdir(%r)" % old).waitclose()
|
||||
|
||||
def test_join_blocked_execution_gateway():
|
||||
gateway = py.execnet.PopenGateway()
|
||||
channel = gateway.remote_exec("""
|
||||
import time
|
||||
time.sleep(5.0)
|
||||
""")
|
||||
def doit():
|
||||
gateway.exit()
|
||||
gateway.join(joinexec=True)
|
||||
return 17
|
||||
|
||||
pool = py._thread.WorkerPool()
|
||||
reply = pool.dispatch(doit)
|
||||
x = reply.get(timeout=1.0)
|
||||
assert x == 17
|
||||
|
||||
class TestPopenGateway:
|
||||
gwtype = 'popen'
|
||||
|
||||
def test_chdir_separation(self, tmpdir):
|
||||
old = tmpdir.chdir()
|
||||
try:
|
||||
gw = py.execnet.PopenGateway()
|
||||
finally:
|
||||
waschangedir = old.chdir()
|
||||
c = gw.remote_exec("import os ; channel.send(os.getcwd())")
|
||||
x = c.receive()
|
||||
assert x == str(waschangedir)
|
||||
|
||||
def test_many_popen(self):
|
||||
num = 4
|
||||
l = []
|
||||
for i in range(num):
|
||||
l.append(py.execnet.PopenGateway())
|
||||
channels = []
|
||||
for gw in l:
|
||||
channel = gw.remote_exec("""channel.send(42)""")
|
||||
channels.append(channel)
|
||||
## try:
|
||||
## while channels:
|
||||
## channel = channels.pop()
|
||||
## try:
|
||||
## ret = channel.receive()
|
||||
## assert ret == 42
|
||||
## finally:
|
||||
## channel.gateway.exit()
|
||||
## finally:
|
||||
## for x in channels:
|
||||
## x.gateway.exit()
|
||||
while channels:
|
||||
channel = channels.pop()
|
||||
ret = channel.receive()
|
||||
assert ret == 42
|
||||
|
||||
def test_rinfo_popen(self, gw):
|
||||
rinfo = gw._rinfo()
|
||||
assert rinfo.executable == py.std.sys.executable
|
||||
assert rinfo.cwd == py.std.os.getcwd()
|
||||
assert rinfo.version_info == py.std.sys.version_info
|
||||
|
||||
def test_gateway_init_event(self, _pytest):
|
||||
rec = _pytest.gethookrecorder(gateway.ExecnetAPI)
|
||||
gw = py.execnet.PopenGateway()
|
||||
call = rec.popcall("pyexecnet_gateway_init")
|
||||
assert call.gateway == gw
|
||||
gw.exit()
|
||||
call = rec.popcall("pyexecnet_gateway_exit")
|
||||
assert call.gateway == gw
|
||||
|
||||
@py.test.mark.xfail # "fix needed: dying remote process does not cause waitclose() to fail"
|
||||
def test_waitclose_on_remote_killed(self):
|
||||
gw = py.execnet.PopenGateway()
|
||||
channel = gw.remote_exec("""
|
||||
import os
|
||||
import time
|
||||
channel.send(os.getpid())
|
||||
while 1:
|
||||
channel.send("#" * 100)
|
||||
""")
|
||||
remotepid = channel.receive()
|
||||
py.process.kill(remotepid)
|
||||
py.test.raises(channel.RemoteError, "channel.waitclose(TESTTIMEOUT)")
|
||||
py.test.raises(EOFError, channel.send, None)
|
||||
py.test.raises(EOFError, channel.receive)
|
||||
|
||||
@py.test.mark.xfail
|
||||
def test_endmarker_delivery_on_remote_killterm():
|
||||
if not hasattr(py.std.os, 'kill'):
|
||||
py.test.skip("no os.kill()")
|
||||
gw = py.execnet.PopenGateway()
|
||||
try:
|
||||
q = queue.Queue()
|
||||
channel = gw.remote_exec(source='''
|
||||
import os
|
||||
os.kill(os.getpid(), 15)
|
||||
''')
|
||||
channel.setcallback(q.put, endmarker=999)
|
||||
val = q.get(TESTTIMEOUT)
|
||||
assert val == 999
|
||||
err = channel._getremoteerror()
|
||||
finally:
|
||||
gw.exit()
|
||||
assert "killed" in str(err)
|
||||
assert "15" in str(err)
|
||||
|
||||
|
||||
def test_socket_gw_host_not_found(gw):
|
||||
py.test.raises(py.execnet.HostNotFound,
|
||||
'py.execnet.SocketGateway("qowieuqowe", 9000)'
|
||||
)
|
||||
|
||||
class TestSshPopenGateway:
|
||||
gwtype = "ssh"
|
||||
|
||||
def test_sshconfig_config_parsing(self, monkeypatch):
|
||||
import subprocess
|
||||
l = []
|
||||
monkeypatch.setattr(subprocess, 'Popen',
|
||||
lambda *args, **kwargs: l.append(args[0]))
|
||||
py.test.raises(AttributeError,
|
||||
"""py.execnet.SshGateway("xyz", ssh_config='qwe')""")
|
||||
assert len(l) == 1
|
||||
popen_args = l[0]
|
||||
i = popen_args.index('-F')
|
||||
assert popen_args[i+1] == "qwe"
|
||||
|
||||
def test_sshaddress(self, gw, specssh):
|
||||
assert gw.remoteaddress == specssh.ssh
|
||||
|
||||
def test_host_not_found(self):
|
||||
py.test.raises(py.execnet.HostNotFound,
|
||||
"py.execnet.SshGateway('nowhere.codespeak.net')")
|
||||
|
||||
class TestThreads:
|
||||
def test_threads(self):
|
||||
gw = py.execnet.PopenGateway()
|
||||
gw.remote_init_threads(3)
|
||||
c1 = gw.remote_exec("channel.send(channel.receive())")
|
||||
c2 = gw.remote_exec("channel.send(channel.receive())")
|
||||
c2.send(1)
|
||||
res = c2.receive()
|
||||
assert res == 1
|
||||
c1.send(42)
|
||||
res = c1.receive()
|
||||
assert res == 42
|
||||
|
||||
def test_threads_twice(self):
|
||||
gw = py.execnet.PopenGateway()
|
||||
gw.remote_init_threads(3)
|
||||
py.test.raises(IOError, gw.remote_init_threads, 3)
|
||||
|
||||
|
||||
def test_nodebug():
|
||||
from py.__.execnet import gateway_base
|
||||
assert not gateway_base.debug
|
||||
@@ -1,58 +0,0 @@
|
||||
"""
|
||||
tests for
|
||||
- multi channels and multi gateways
|
||||
|
||||
"""
|
||||
|
||||
import py
|
||||
|
||||
class TestMultiChannelAndGateway:
|
||||
def test_multichannel_receive_each(self):
|
||||
class pseudochannel:
|
||||
def receive(self):
|
||||
return 12
|
||||
|
||||
pc1 = pseudochannel()
|
||||
pc2 = pseudochannel()
|
||||
multichannel = py.execnet.MultiChannel([pc1, pc2])
|
||||
l = multichannel.receive_each(withchannel=True)
|
||||
assert len(l) == 2
|
||||
assert l == [(pc1, 12), (pc2, 12)]
|
||||
l = multichannel.receive_each(withchannel=False)
|
||||
assert l == [12,12]
|
||||
|
||||
def test_multichannel_send_each(self):
|
||||
l = [py.execnet.PopenGateway() for x in range(2)]
|
||||
gm = py.execnet.MultiGateway(l)
|
||||
mc = gm.remote_exec("""
|
||||
import os
|
||||
channel.send(channel.receive() + 1)
|
||||
""")
|
||||
mc.send_each(41)
|
||||
l = mc.receive_each()
|
||||
assert l == [42,42]
|
||||
|
||||
def test_multichannel_receive_queue_for_two_subprocesses(self):
|
||||
l = [py.execnet.PopenGateway() for x in range(2)]
|
||||
gm = py.execnet.MultiGateway(l)
|
||||
mc = gm.remote_exec("""
|
||||
import os
|
||||
channel.send(os.getpid())
|
||||
""")
|
||||
queue = mc.make_receive_queue()
|
||||
ch, item = queue.get(timeout=10)
|
||||
ch2, item2 = queue.get(timeout=10)
|
||||
assert ch != ch2
|
||||
assert ch.gateway != ch2.gateway
|
||||
assert item != item2
|
||||
mc.waitclose()
|
||||
|
||||
def test_multichannel_waitclose(self):
|
||||
l = []
|
||||
class pseudochannel:
|
||||
def waitclose(self):
|
||||
l.append(0)
|
||||
multichannel = py.execnet.MultiChannel([pseudochannel(), pseudochannel()])
|
||||
multichannel.waitclose()
|
||||
assert len(l) == 2
|
||||
|
||||
@@ -1,148 +0,0 @@
|
||||
import py
|
||||
from py.execnet import RSync
|
||||
|
||||
|
||||
def pytest_funcarg__gw1(request):
|
||||
return request.cached_setup(
|
||||
setup=py.execnet.PopenGateway,
|
||||
teardown=lambda val: val.exit(),
|
||||
scope="module"
|
||||
)
|
||||
pytest_funcarg__gw2 = pytest_funcarg__gw1
|
||||
|
||||
def pytest_funcarg__dirs(request):
|
||||
t = request.getfuncargvalue('tmpdir')
|
||||
class dirs:
|
||||
source = t.join("source")
|
||||
dest1 = t.join("dest1")
|
||||
dest2 = t.join("dest2")
|
||||
return dirs
|
||||
|
||||
class TestRSync:
|
||||
def test_notargets(self, dirs):
|
||||
rsync = RSync(dirs.source)
|
||||
py.test.raises(IOError, "rsync.send()")
|
||||
assert rsync.send(raises=False) is None
|
||||
|
||||
def test_dirsync(self, dirs, gw1, gw2):
|
||||
dest = dirs.dest1
|
||||
dest2 = dirs.dest2
|
||||
source = dirs.source
|
||||
|
||||
for s in ('content1', 'content2', 'content2-a-bit-longer'):
|
||||
source.ensure('subdir', 'file1').write(s)
|
||||
rsync = RSync(dirs.source)
|
||||
rsync.add_target(gw1, dest)
|
||||
rsync.add_target(gw2, dest2)
|
||||
rsync.send()
|
||||
assert dest.join('subdir').check(dir=1)
|
||||
assert dest.join('subdir', 'file1').check(file=1)
|
||||
assert dest.join('subdir', 'file1').read() == s
|
||||
assert dest2.join('subdir').check(dir=1)
|
||||
assert dest2.join('subdir', 'file1').check(file=1)
|
||||
assert dest2.join('subdir', 'file1').read() == s
|
||||
for x in dest, dest2:
|
||||
fn = x.join("subdir", "file1")
|
||||
fn.setmtime(0)
|
||||
|
||||
source.join('subdir').remove('file1')
|
||||
rsync = RSync(source)
|
||||
rsync.add_target(gw2, dest2)
|
||||
rsync.add_target(gw1, dest)
|
||||
rsync.send()
|
||||
assert dest.join('subdir', 'file1').check(file=1)
|
||||
assert dest2.join('subdir', 'file1').check(file=1)
|
||||
rsync = RSync(source)
|
||||
rsync.add_target(gw1, dest, delete=True)
|
||||
rsync.add_target(gw2, dest2)
|
||||
rsync.send()
|
||||
assert not dest.join('subdir', 'file1').check()
|
||||
assert dest2.join('subdir', 'file1').check()
|
||||
|
||||
def test_dirsync_twice(self, dirs, gw1, gw2):
|
||||
source = dirs.source
|
||||
source.ensure("hello")
|
||||
rsync = RSync(source)
|
||||
rsync.add_target(gw1, dirs.dest1)
|
||||
rsync.send()
|
||||
assert dirs.dest1.join('hello').check()
|
||||
py.test.raises(IOError, "rsync.send()")
|
||||
assert rsync.send(raises=False) is None
|
||||
rsync.add_target(gw1, dirs.dest2)
|
||||
rsync.send()
|
||||
assert dirs.dest2.join('hello').check()
|
||||
py.test.raises(IOError, "rsync.send()")
|
||||
assert rsync.send(raises=False) is None
|
||||
|
||||
def test_rsync_default_reporting(self, capsys, dirs, gw1):
|
||||
source = dirs.source
|
||||
source.ensure("hello")
|
||||
rsync = RSync(source)
|
||||
rsync.add_target(gw1, dirs.dest1)
|
||||
rsync.send()
|
||||
out, err = capsys.readouterr()
|
||||
assert out.find("hello") != -1
|
||||
|
||||
def test_rsync_non_verbose(self, capsys, dirs, gw1):
|
||||
source = dirs.source
|
||||
source.ensure("hello")
|
||||
rsync = RSync(source, verbose=False)
|
||||
rsync.add_target(gw1, dirs.dest1)
|
||||
rsync.send()
|
||||
out, err = capsys.readouterr()
|
||||
assert not out
|
||||
assert not err
|
||||
|
||||
def test_symlink_rsync(self, dirs, gw1):
|
||||
if py.std.sys.platform == 'win32':
|
||||
py.test.skip("symlinks are unsupported on Windows.")
|
||||
source = dirs.source
|
||||
dest = dirs.dest1
|
||||
dirs.source.ensure("existant")
|
||||
source.join("rellink").mksymlinkto(source.join("existant"), absolute=0)
|
||||
source.join('abslink').mksymlinkto(source.join("existant"))
|
||||
|
||||
rsync = RSync(source)
|
||||
rsync.add_target(gw1, dest)
|
||||
rsync.send()
|
||||
|
||||
assert dest.join('rellink').readlink() == dest.join("existant")
|
||||
assert dest.join('abslink').readlink() == dest.join("existant")
|
||||
|
||||
def test_callback(self, dirs, gw1):
|
||||
dest = dirs.dest1
|
||||
source = dirs.source
|
||||
source.ensure("existant").write("a" * 100)
|
||||
source.ensure("existant2").write("a" * 10)
|
||||
total = {}
|
||||
def callback(cmd, lgt, channel):
|
||||
total[(cmd, lgt)] = True
|
||||
|
||||
rsync = RSync(source, callback=callback)
|
||||
#rsync = RSync()
|
||||
rsync.add_target(gw1, dest)
|
||||
rsync.send()
|
||||
|
||||
assert total == {("list", 110):True, ("ack", 100):True, ("ack", 10):True}
|
||||
|
||||
def test_file_disappearing(self, dirs, gw1):
|
||||
dest = dirs.dest1
|
||||
source = dirs.source
|
||||
source.ensure("ex").write("a" * 100)
|
||||
source.ensure("ex2").write("a" * 100)
|
||||
|
||||
class DRsync(RSync):
|
||||
def filter(self, x):
|
||||
assert x != source
|
||||
if x.endswith("ex2"):
|
||||
self.x = 1
|
||||
source.join("ex2").remove()
|
||||
return True
|
||||
|
||||
rsync = DRsync(source)
|
||||
rsync.add_target(gw1, dest)
|
||||
rsync.send()
|
||||
assert rsync.x == 1
|
||||
assert len(dest.listdir()) == 1
|
||||
assert len(source.listdir()) == 1
|
||||
|
||||
@@ -1,179 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import sys
|
||||
import os
|
||||
import tempfile
|
||||
import subprocess
|
||||
import py
|
||||
from py.__.execnet import serializer
|
||||
|
||||
|
||||
def _find_version(suffix=""):
|
||||
name = "python" + suffix
|
||||
executable = py.path.local.sysfind(name)
|
||||
if executable is None:
|
||||
py.test.skip("can't find a %r executable" % (name,))
|
||||
return executable
|
||||
|
||||
def setup_module(mod):
|
||||
mod.TEMPDIR = py.path.local(tempfile.mkdtemp())
|
||||
if sys.version_info > (3, 0):
|
||||
mod._py3_wrapper = PythonWrapper(py.path.local(sys.executable))
|
||||
mod._py2_wrapper = PythonWrapper(_find_version())
|
||||
else:
|
||||
mod._py3_wrapper = PythonWrapper(_find_version("3"))
|
||||
mod._py2_wrapper = PythonWrapper(py.path.local(sys.executable))
|
||||
mod._old_pypath = os.environ.get("PYTHONPATH")
|
||||
pylib = str(py.path.local(py.__file__).dirpath().join(".."))
|
||||
os.environ["PYTHONPATH"] = pylib
|
||||
|
||||
def teardown_module(mod):
|
||||
TEMPDIR.remove(True)
|
||||
if _old_pypath is not None:
|
||||
os.environ["PYTHONPATH"] = _old_pypath
|
||||
|
||||
|
||||
class PythonWrapper(object):
|
||||
|
||||
def __init__(self, executable):
|
||||
self.executable = executable
|
||||
|
||||
def dump(self, obj_rep):
|
||||
script_file = TEMPDIR.join("dump.py")
|
||||
script_file.write("""
|
||||
from py.__.execnet import serializer
|
||||
import sys
|
||||
if sys.version_info > (3, 0): # Need binary output
|
||||
sys.stdout = sys.stdout.detach()
|
||||
saver = serializer.Serializer(sys.stdout)
|
||||
saver.save(%s)""" % (obj_rep,))
|
||||
return self.executable.sysexec(script_file)
|
||||
|
||||
def load(self, data, option_args=""):
|
||||
script_file = TEMPDIR.join("load.py")
|
||||
script_file.write(r"""
|
||||
from py.__.execnet import serializer
|
||||
import sys
|
||||
if sys.version_info > (3, 0):
|
||||
sys.stdin = sys.stdin.detach()
|
||||
options = serializer.UnserializationOptions(%s)
|
||||
loader = serializer.Unserializer(sys.stdin, options)
|
||||
obj = loader.load()
|
||||
sys.stdout.write(type(obj).__name__ + "\n")
|
||||
sys.stdout.write(repr(obj))""" % (option_args,))
|
||||
popen = subprocess.Popen([str(self.executable), str(script_file)],
|
||||
stdin=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE)
|
||||
stdout, stderr = popen.communicate(data.encode("latin-1"))
|
||||
ret = popen.returncode
|
||||
if ret:
|
||||
raise py.process.cmdexec.Error(ret, ret, str(self.executable),
|
||||
stdout, stderr)
|
||||
return [s.decode("ascii") for s in stdout.splitlines()]
|
||||
|
||||
def __repr__(self):
|
||||
return "<PythonWrapper for %s>" % (self.executable,)
|
||||
|
||||
|
||||
def pytest_funcarg__py2(request):
|
||||
return _py2_wrapper
|
||||
|
||||
def pytest_funcarg__py3(request):
|
||||
return _py3_wrapper
|
||||
|
||||
def pytest_funcarg__dump(request):
|
||||
py_dump = request.getfuncargvalue(request.param[0])
|
||||
return py_dump.dump
|
||||
|
||||
def pytest_funcarg__load(request):
|
||||
py_dump = request.getfuncargvalue(request.param[1])
|
||||
return py_dump.load
|
||||
|
||||
def pytest_generate_tests(metafunc):
|
||||
if 'dump' in metafunc.funcargnames and 'load' in metafunc.funcargnames:
|
||||
pys = 'py2', 'py3'
|
||||
for dump in pys:
|
||||
for load in pys:
|
||||
param = (dump, load)
|
||||
conversion = '%s to %s'%param
|
||||
if 'repr' not in metafunc.funcargnames:
|
||||
metafunc.addcall(id=conversion, param=param)
|
||||
else:
|
||||
for tp, repr in simple_tests.items():
|
||||
metafunc.addcall(
|
||||
id='%s:%s'%(tp, conversion),
|
||||
param=param,
|
||||
funcargs={'tp_name':tp, 'repr':repr},
|
||||
)
|
||||
|
||||
|
||||
simple_tests = {
|
||||
# type: expected before/after repr
|
||||
'int': '4',
|
||||
'float':'3.25',
|
||||
'list': '[1, 2, 3]',
|
||||
'tuple': '(1, 2, 3)',
|
||||
'dict': '{6: 2, (1, 2, 3): 32}',
|
||||
}
|
||||
|
||||
def test_simple(tp_name, repr, dump, load):
|
||||
p = dump(repr)
|
||||
tp , v = load(p)
|
||||
assert tp == tp_name
|
||||
assert v == repr
|
||||
|
||||
|
||||
@py.test.mark.xfail
|
||||
# I'm not sure if we need the complexity.
|
||||
def test_recursive_list(py2, py3):
|
||||
l = [1, 2, 3]
|
||||
l.append(l)
|
||||
p = py2.dump(l)
|
||||
tp, rep = py2.load(l)
|
||||
assert tp == "list"
|
||||
|
||||
def test_bigint_should_fail():
|
||||
py.test.raises(serializer.SerializationError,
|
||||
serializer.Serializer(py.io.BytesIO()).save,
|
||||
123456678900)
|
||||
|
||||
def test_bytes(py2, py3):
|
||||
p = py3.dump("b'hi'")
|
||||
tp, v = py2.load(p)
|
||||
assert tp == "str"
|
||||
assert v == "'hi'"
|
||||
tp, v = py3.load(p)
|
||||
assert tp == "bytes"
|
||||
assert v == "b'hi'"
|
||||
|
||||
def test_string(py2, py3):
|
||||
p = py2.dump("'xyz'")
|
||||
tp, s = py2.load(p)
|
||||
assert tp == "str"
|
||||
assert s == "'xyz'"
|
||||
tp, s = py3.load(p)
|
||||
assert tp == "bytes"
|
||||
assert s == "b'xyz'"
|
||||
tp, s = py3.load(p, "True")
|
||||
assert tp == "str"
|
||||
assert s == "'xyz'"
|
||||
p = py3.dump("'xyz'")
|
||||
tp, s = py2.load(p, True)
|
||||
assert tp == "str"
|
||||
assert s == "'xyz'"
|
||||
|
||||
def test_unicode(py2, py3):
|
||||
p = py2.dump("u'hi'")
|
||||
tp, s = py2.load(p)
|
||||
assert tp == "unicode"
|
||||
assert s == "u'hi'"
|
||||
tp, s = py3.load(p)
|
||||
assert tp == "str"
|
||||
assert s == "'hi'"
|
||||
p = py3.dump("'hi'")
|
||||
tp, s = py3.load(p)
|
||||
assert tp == "str"
|
||||
assert s == "'hi'"
|
||||
tp, s = py2.load(p)
|
||||
assert tp == "unicode"
|
||||
assert s == "u'hi'"
|
||||
@@ -1,151 +0,0 @@
|
||||
import py
|
||||
|
||||
XSpec = py.execnet.XSpec
|
||||
|
||||
class TestXSpec:
|
||||
def test_norm_attributes(self):
|
||||
spec = XSpec("socket=192.168.102.2:8888//python=c:/this/python2.5//chdir=d:\hello")
|
||||
assert spec.socket == "192.168.102.2:8888"
|
||||
assert spec.python == "c:/this/python2.5"
|
||||
assert spec.chdir == "d:\hello"
|
||||
assert spec.nice is None
|
||||
assert not hasattr(spec, '_xyz')
|
||||
|
||||
py.test.raises(AttributeError, "spec._hello")
|
||||
|
||||
spec = XSpec("socket=192.168.102.2:8888//python=python2.5//nice=3")
|
||||
assert spec.socket == "192.168.102.2:8888"
|
||||
assert spec.python == "python2.5"
|
||||
assert spec.chdir is None
|
||||
assert spec.nice == "3"
|
||||
|
||||
spec = XSpec("ssh=user@host//chdir=/hello/this//python=/usr/bin/python2.5")
|
||||
assert spec.ssh == "user@host"
|
||||
assert spec.python == "/usr/bin/python2.5"
|
||||
assert spec.chdir == "/hello/this"
|
||||
|
||||
spec = XSpec("popen")
|
||||
assert spec.popen == True
|
||||
|
||||
def test__samefilesystem(self):
|
||||
assert XSpec("popen")._samefilesystem()
|
||||
assert XSpec("popen//python=123")._samefilesystem()
|
||||
assert not XSpec("popen//chdir=hello")._samefilesystem()
|
||||
|
||||
def test__spec_spec(self):
|
||||
for x in ("popen", "popen//python=this"):
|
||||
assert XSpec(x)._spec == x
|
||||
|
||||
def test_samekeyword_twice_raises(self):
|
||||
py.test.raises(ValueError, "XSpec('popen//popen')")
|
||||
py.test.raises(ValueError, "XSpec('popen//popen=123')")
|
||||
|
||||
def test_unknown_keys_allowed(self):
|
||||
xspec = XSpec("hello=3")
|
||||
assert xspec.hello == '3'
|
||||
|
||||
def test_repr_and_string(self):
|
||||
for x in ("popen", "popen//python=this"):
|
||||
assert repr(XSpec(x)).find("popen") != -1
|
||||
assert str(XSpec(x)) == x
|
||||
|
||||
def test_hash_equality(self):
|
||||
assert XSpec("popen") == XSpec("popen")
|
||||
assert hash(XSpec("popen")) == hash(XSpec("popen"))
|
||||
assert XSpec("popen//python=123") != XSpec("popen")
|
||||
assert hash(XSpec("socket=hello:8080")) != hash(XSpec("popen"))
|
||||
|
||||
class TestMakegateway:
|
||||
def test_no_type(self):
|
||||
py.test.raises(ValueError, "py.execnet.makegateway('hello')")
|
||||
|
||||
def test_popen(self):
|
||||
gw = py.execnet.makegateway("popen")
|
||||
assert gw.spec.python == None
|
||||
rinfo = gw._rinfo()
|
||||
assert rinfo.executable == py.std.sys.executable
|
||||
assert rinfo.cwd == py.std.os.getcwd()
|
||||
assert rinfo.version_info == py.std.sys.version_info
|
||||
|
||||
def test_popen_nice(self):
|
||||
gw = py.execnet.makegateway("popen//nice=5")
|
||||
remotenice = gw.remote_exec("""
|
||||
import os
|
||||
if hasattr(os, 'nice'):
|
||||
channel.send(os.nice(0))
|
||||
else:
|
||||
channel.send(None)
|
||||
""").receive()
|
||||
if remotenice is not None:
|
||||
assert remotenice == 5
|
||||
|
||||
def test_popen_explicit(self):
|
||||
gw = py.execnet.makegateway("popen//python=%s" % py.std.sys.executable)
|
||||
assert gw.spec.python == py.std.sys.executable
|
||||
rinfo = gw._rinfo()
|
||||
assert rinfo.executable == py.std.sys.executable
|
||||
assert rinfo.cwd == py.std.os.getcwd()
|
||||
assert rinfo.version_info == py.std.sys.version_info
|
||||
|
||||
def test_popen_cpython25(self):
|
||||
for trypath in ('python2.5', r'C:\Python25\python.exe'):
|
||||
cpython25 = py.path.local.sysfind(trypath)
|
||||
if cpython25 is not None:
|
||||
cpython25 = cpython25.realpath()
|
||||
break
|
||||
else:
|
||||
py.test.skip("cpython2.5 not found")
|
||||
gw = py.execnet.makegateway("popen//python=%s" % cpython25)
|
||||
rinfo = gw._rinfo()
|
||||
if py.std.sys.platform != "darwin": # it's confusing there
|
||||
assert rinfo.executable == cpython25
|
||||
assert rinfo.cwd == py.std.os.getcwd()
|
||||
assert rinfo.version_info[:2] == (2,5)
|
||||
|
||||
def test_popen_cpython26(self):
|
||||
for trypath in ('python2.6', r'C:\Python26\python.exe'):
|
||||
cpython26 = py.path.local.sysfind(trypath)
|
||||
if cpython26 is not None:
|
||||
break
|
||||
else:
|
||||
py.test.skip("cpython2.6 not found")
|
||||
gw = py.execnet.makegateway("popen//python=%s" % cpython26)
|
||||
rinfo = gw._rinfo()
|
||||
assert rinfo.executable == cpython26
|
||||
assert rinfo.cwd == py.std.os.getcwd()
|
||||
assert rinfo.version_info[:2] == (2,6)
|
||||
|
||||
def test_popen_chdir_absolute(self, testdir):
|
||||
gw = py.execnet.makegateway("popen//chdir=%s" % testdir.tmpdir)
|
||||
rinfo = gw._rinfo()
|
||||
assert rinfo.cwd == str(testdir.tmpdir.realpath())
|
||||
|
||||
def test_popen_chdir_newsub(self, testdir):
|
||||
testdir.chdir()
|
||||
gw = py.execnet.makegateway("popen//chdir=hello")
|
||||
rinfo = gw._rinfo()
|
||||
assert rinfo.cwd == str(testdir.tmpdir.join("hello").realpath())
|
||||
|
||||
def test_ssh(self, specssh):
|
||||
sshhost = specssh.ssh
|
||||
gw = py.execnet.makegateway("ssh=%s" % sshhost)
|
||||
rinfo = gw._rinfo()
|
||||
gw2 = py.execnet.SshGateway(sshhost)
|
||||
rinfo2 = gw2._rinfo()
|
||||
assert rinfo.executable == rinfo2.executable
|
||||
assert rinfo.cwd == rinfo2.cwd
|
||||
assert rinfo.version_info == rinfo2.version_info
|
||||
|
||||
def test_socket(self, specsocket):
|
||||
gw = py.execnet.makegateway("socket=%s" % specsocket.socket)
|
||||
rinfo = gw._rinfo()
|
||||
assert rinfo.executable
|
||||
assert rinfo.cwd
|
||||
assert rinfo.version_info
|
||||
# we cannot instantiate a second gateway
|
||||
|
||||
#gw2 = py.execnet.SocketGateway(*specsocket.socket.split(":"))
|
||||
#rinfo2 = gw2._rinfo()
|
||||
#assert rinfo.executable == rinfo2.executable
|
||||
#assert rinfo.cwd == rinfo2.cwd
|
||||
#assert rinfo.version_info == rinfo2.version_info
|
||||
Vendored
+2
-1
@@ -1,8 +1,9 @@
|
||||
from py.__.test.dist.dsession import DSession
|
||||
from py.__.test import outcome
|
||||
import py
|
||||
import execnet
|
||||
|
||||
XSpec = py.execnet.XSpec
|
||||
XSpec = execnet.XSpec
|
||||
|
||||
def run(item, node, excinfo=None):
|
||||
runner = item.config.pluginmanager.getplugin("runner")
|
||||
|
||||
Vendored
+3
-2
@@ -9,6 +9,7 @@ import py
|
||||
import os
|
||||
from py.__.test.dist.gwmanage import GatewayManager, HostRSync
|
||||
from py.__.test.plugin import hookspec
|
||||
import execnet
|
||||
|
||||
def pytest_funcarg__hookrecorder(request):
|
||||
_pytest = request.getfuncargvalue('_pytest')
|
||||
@@ -35,7 +36,7 @@ class TestGatewayManagerPopen:
|
||||
hm = GatewayManager(["popen"] * 2, hook)
|
||||
hm.makegateways()
|
||||
call = hookrecorder.popcall("pytest_gwmanage_newgateway")
|
||||
assert call.gateway.spec == py.execnet.XSpec("popen")
|
||||
assert call.gateway.spec == execnet.XSpec("popen")
|
||||
assert call.gateway.id == "[1]"
|
||||
assert call.platinfo.executable == call.gateway._rinfo().executable
|
||||
call = hookrecorder.popcall("pytest_gwmanage_newgateway")
|
||||
@@ -149,7 +150,7 @@ class TestHRSync:
|
||||
|
||||
def test_hrsync_one_host(self, mysetup):
|
||||
source, dest = mysetup.source, mysetup.dest
|
||||
gw = py.execnet.makegateway("popen//chdir=%s" % dest)
|
||||
gw = execnet.makegateway("popen//chdir=%s" % dest)
|
||||
finished = []
|
||||
rsync = HostRSync(source)
|
||||
rsync.add_target_host(gw, finished=lambda: finished.append(1))
|
||||
|
||||
Vendored
+2
-1
@@ -1,6 +1,7 @@
|
||||
|
||||
import py
|
||||
import sys
|
||||
import execnet
|
||||
|
||||
Queue = py.builtin._tryimport('queue', 'Queue').Queue
|
||||
|
||||
@@ -117,7 +118,7 @@ def test_self_memoize():
|
||||
TESTTIMEOUT = 2.0
|
||||
class TestPickleChannelFunctional:
|
||||
def setup_class(cls):
|
||||
cls.gw = py.execnet.PopenGateway()
|
||||
cls.gw = execnet.PopenGateway()
|
||||
cls.gw.remote_init_threads(5)
|
||||
|
||||
def test_popen_send_instance(self):
|
||||
|
||||
Vendored
+3
-2
@@ -1,5 +1,6 @@
|
||||
|
||||
import py
|
||||
import execnet
|
||||
from py.__.test.dist.txnode import TXNode
|
||||
queue = py.builtin._tryimport("queue", "Queue")
|
||||
Queue = queue.Queue
|
||||
@@ -46,8 +47,8 @@ class MySetup:
|
||||
config = py.test.config._reparse([])
|
||||
self.config = config
|
||||
self.queue = Queue()
|
||||
self.xspec = py.execnet.XSpec("popen")
|
||||
self.gateway = py.execnet.makegateway(self.xspec)
|
||||
self.xspec = execnet.XSpec("popen")
|
||||
self.gateway = execnet.makegateway(self.xspec)
|
||||
self.id += 1
|
||||
self.gateway.id = str(self.id)
|
||||
self.node = TXNode(self.gateway, self.config, putevent=self.queue.put)
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
def test_execnetplugin(testdir):
|
||||
reprec = testdir.inline_runsource("""
|
||||
import py
|
||||
import sys
|
||||
def test_hello():
|
||||
sys._gw = py.execnet.PopenGateway()
|
||||
def test_world():
|
||||
assert hasattr(sys, '_gw')
|
||||
assert sys._gw not in sys._gw._cleanup._activegateways
|
||||
|
||||
""", "-s", "--debug")
|
||||
reprec.assertoutcome(passed=2)
|
||||
@@ -105,6 +105,7 @@ class TestTerminal:
|
||||
])
|
||||
|
||||
def test_gwmanage_events(self, testdir, linecomp):
|
||||
execnet = py.test.importorskip("execnet")
|
||||
modcol = testdir.getmodulecol("""
|
||||
def test_one():
|
||||
pass
|
||||
@@ -113,10 +114,10 @@ class TestTerminal:
|
||||
rep = TerminalReporter(modcol.config, file=linecomp.stringio)
|
||||
class gw1:
|
||||
id = "X1"
|
||||
spec = py.execnet.XSpec("popen")
|
||||
spec = execnet.XSpec("popen")
|
||||
class gw2:
|
||||
id = "X2"
|
||||
spec = py.execnet.XSpec("popen")
|
||||
spec = execnet.XSpec("popen")
|
||||
class rinfo:
|
||||
version_info = (2, 5, 1, 'final', 0)
|
||||
executable = "hello"
|
||||
|
||||
@@ -182,8 +182,9 @@ class TestConfigPickling:
|
||||
old.chdir()
|
||||
|
||||
def test_config__setstate__wired_correctly_in_childprocess(testdir):
|
||||
execnet = py.test.importorskip("execnet")
|
||||
from py.__.test.dist.mypickle import PickleChannel
|
||||
gw = py.execnet.PopenGateway()
|
||||
gw = execnet.PopenGateway()
|
||||
channel = gw.remote_exec("""
|
||||
import py
|
||||
from py.__.test.dist.mypickle import PickleChannel
|
||||
|
||||
Reference in New Issue
Block a user