Change server instantion to be inherited
This commit is contained in:
@@ -91,8 +91,9 @@ cdef public C_Capability.Client * call_py_restorer(PyObject * _restorer, C_Dynam
|
||||
|
||||
ret = restorer.restore(reader)
|
||||
cdef _DynamicCapabilityServer server = ret
|
||||
cdef _InterfaceSchema schema = ret.schema
|
||||
|
||||
return new C_Capability.Client(helpers.server_to_client(server.schema.thisptr, <PyObject *>server.server))
|
||||
return new C_Capability.Client(helpers.server_to_client(schema.thisptr, <PyObject *>server))
|
||||
|
||||
cdef extern from "<kj/string.h>" namespace " ::kj":
|
||||
String strStructReader" ::kj::str"(C_DynamicStruct.Reader)
|
||||
@@ -597,8 +598,9 @@ cdef C_DynamicValue.Reader _extract_dynamic_struct_reader(_DynamicStructReader v
|
||||
cdef C_DynamicValue.Reader _extract_dynamic_client(_DynamicCapabilityClient value):
|
||||
return C_DynamicValue.Reader(value.thisptr)
|
||||
|
||||
cdef C_DynamicValue.Reader _extract_dynamic_server(_DynamicCapabilityServer value):
|
||||
return helpers.new_server(value.schema.thisptr, <PyObject *>value.server)
|
||||
cdef C_DynamicValue.Reader _extract_dynamic_server(object value):
|
||||
cdef _InterfaceSchema schema = value.schema
|
||||
return helpers.new_server(schema.thisptr, <PyObject *>value)
|
||||
|
||||
cdef _setDynamicField(_DynamicSetterClasses thisptr, field, value, parent):
|
||||
cdef C_DynamicValue.Reader temp
|
||||
@@ -632,7 +634,7 @@ cdef _setDynamicField(_DynamicSetterClasses thisptr, field, value, parent):
|
||||
thisptr.set(field, _extract_dynamic_struct_reader(value))
|
||||
elif value_type is _DynamicCapabilityClient:
|
||||
thisptr.set(field, _extract_dynamic_client(value))
|
||||
elif value_type is _DynamicCapabilityServer:
|
||||
elif value_type is _DynamicCapabilityServer or isinstance(value, _DynamicCapabilityServer):
|
||||
thisptr.set(field, _extract_dynamic_server(value))
|
||||
else:
|
||||
raise ValueError("Non primitive type")
|
||||
@@ -1355,6 +1357,9 @@ cdef class _DynamicCapabilityServer:
|
||||
self.schema = s
|
||||
self.server = server
|
||||
|
||||
def __getattr__(self, field):
|
||||
return getattr(self.server, field)
|
||||
|
||||
cdef class _DynamicCapabilityClient:
|
||||
cdef C_DynamicCapability.Client thisptr
|
||||
cdef public object _server, _parent
|
||||
@@ -1846,13 +1851,16 @@ class _StructModule(object):
|
||||
return builder.set_root(obj)
|
||||
|
||||
class _InterfaceModule(object):
|
||||
def __init__(self, schema):
|
||||
def __init__(self, schema, name):
|
||||
def server_init(server_self):
|
||||
pass
|
||||
self.schema = schema
|
||||
self.Server = type(name, (_DynamicCapabilityServer,), {'__init__': server_init, 'schema':schema})
|
||||
|
||||
def _new_client(self, server):
|
||||
return _DynamicCapabilityClient()._init_vals(self.schema, server)
|
||||
|
||||
def new_server(self, server):
|
||||
def _new_server(self, server):
|
||||
return _DynamicCapabilityServer(self.schema, server)
|
||||
|
||||
cdef class SchemaParser:
|
||||
@@ -1949,7 +1957,7 @@ cdef class SchemaParser:
|
||||
elif proto.isConst:
|
||||
module.__dict__[node.name] = schema.as_const_value()
|
||||
elif proto.isInterface:
|
||||
local_module = _InterfaceModule(schema.as_interface())
|
||||
local_module = _InterfaceModule(schema.as_interface(), node.name)
|
||||
|
||||
module.__dict__[node.name] = local_module
|
||||
|
||||
|
||||
@@ -2,13 +2,9 @@ import pytest
|
||||
import capnp
|
||||
import os
|
||||
|
||||
this_dir = os.path.dirname(__file__)
|
||||
import test_capability_capnp as capability
|
||||
|
||||
@pytest.fixture
|
||||
def capability():
|
||||
return capnp.load(os.path.join(this_dir, 'test_capability.capnp'))
|
||||
|
||||
class Server:
|
||||
class Server(capability.TestInterface.Server):
|
||||
def __init__(self, val=1):
|
||||
self.val = val
|
||||
|
||||
@@ -21,16 +17,16 @@ class Server:
|
||||
def buz(self, i, **kwargs):
|
||||
return i.host + '_test'
|
||||
|
||||
class PipelineServer:
|
||||
class PipelineServer(capability.TestPipeline.Server):
|
||||
def getCap(self, n, inCap, _context, **kwargs):
|
||||
def _then(response):
|
||||
_results = _context.results
|
||||
_results.s = response.x + '_foo'
|
||||
_results.outBox.cap = capability().TestInterface.new_server(Server(100))
|
||||
_results.outBox.cap = Server(100)
|
||||
|
||||
return inCap.foo(i=n).then(_then)
|
||||
|
||||
def test_client(capability):
|
||||
def test_client():
|
||||
client = capability.TestInterface._new_client(Server())
|
||||
|
||||
req = client._request('foo')
|
||||
@@ -62,7 +58,7 @@ def test_client(capability):
|
||||
with pytest.raises(ValueError):
|
||||
req.baz = 1
|
||||
|
||||
def test_simple_client(capability):
|
||||
def test_simple_client():
|
||||
client = capability.TestInterface._new_client(Server())
|
||||
|
||||
remote = client._send('foo', i=5)
|
||||
@@ -116,7 +112,7 @@ def test_simple_client(capability):
|
||||
with pytest.raises(ValueError):
|
||||
remote = client.foo(baz=5)
|
||||
|
||||
def test_pipeline(capability):
|
||||
def test_pipeline():
|
||||
client = capability.TestPipeline._new_client(PipelineServer())
|
||||
foo_client = capability.TestInterface._new_client(Server())
|
||||
|
||||
@@ -131,7 +127,7 @@ def test_pipeline(capability):
|
||||
response = remote.wait()
|
||||
assert response.s == '26_foo'
|
||||
|
||||
class BadServer:
|
||||
class BadServer(capability.TestInterface.Server):
|
||||
def __init__(self, val=1):
|
||||
self.val = val
|
||||
|
||||
@@ -141,25 +137,25 @@ class BadServer:
|
||||
extra = 1
|
||||
return str(i * 5 + extra + self.val), 10 # returning too many args
|
||||
|
||||
def test_exception_client(capability):
|
||||
def test_exception_client():
|
||||
client = capability.TestInterface._new_client(BadServer())
|
||||
|
||||
remote = client._send('foo', i=5)
|
||||
with pytest.raises(capnp.KjException):
|
||||
remote.wait()
|
||||
|
||||
class BadPipelineServer:
|
||||
class BadPipelineServer(capability.TestPipeline.Server):
|
||||
def getCap(self, n, inCap, _context, **kwargs):
|
||||
def _then(response):
|
||||
_results = _context.results
|
||||
_results.s = response.x + '_foo'
|
||||
_results.outBox.cap = capability().TestInterface.new_server(Server(100))
|
||||
_results.outBox.cap = Server(100)
|
||||
def _error(error):
|
||||
raise Exception('test was a success')
|
||||
|
||||
return inCap.foo(i=n).then(_then, _error)
|
||||
|
||||
def test_exception_chain(capability):
|
||||
def test_exception_chain():
|
||||
client = capability.TestPipeline._new_client(BadPipelineServer())
|
||||
foo_client = capability.TestInterface._new_client(BadServer())
|
||||
|
||||
@@ -170,7 +166,7 @@ def test_exception_chain(capability):
|
||||
except Exception as e:
|
||||
assert 'test was a success' in str(e)
|
||||
|
||||
def test_pipeline_exception(capability):
|
||||
def test_pipeline_exception():
|
||||
client = capability.TestPipeline._new_client(BadPipelineServer())
|
||||
foo_client = capability.TestInterface._new_client(BadServer())
|
||||
|
||||
@@ -185,7 +181,7 @@ def test_pipeline_exception(capability):
|
||||
with pytest.raises(Exception):
|
||||
remote.wait()
|
||||
|
||||
def test_casting(capability):
|
||||
def test_casting():
|
||||
client = capability.TestExtends._new_client(Server())
|
||||
client2 = client.upcast(capability.TestInterface)
|
||||
client3 = client2.cast_as(capability.TestInterface)
|
||||
@@ -193,7 +189,7 @@ def test_casting(capability):
|
||||
with pytest.raises(Exception):
|
||||
client.upcast(capability.TestPipeline)
|
||||
|
||||
class TailCallOrder:
|
||||
class TailCallOrder(capability.TestCallOrder.Server):
|
||||
def __init__(self):
|
||||
self.count = -1
|
||||
|
||||
@@ -201,7 +197,7 @@ class TailCallOrder:
|
||||
self.count += 1
|
||||
return self.count
|
||||
|
||||
class TailCaller:
|
||||
class TailCaller(capability.TestTailCaller.Server):
|
||||
def __init__(self):
|
||||
self.count = 0
|
||||
|
||||
@@ -211,7 +207,7 @@ class TailCaller:
|
||||
tail = callee.foo_request(i=i, t='from TailCaller')
|
||||
return _context.tail_call(tail)
|
||||
|
||||
class TailCallee:
|
||||
class TailCallee(capability.TestTailCallee.Server):
|
||||
def __init__(self):
|
||||
self.count = 0
|
||||
|
||||
@@ -221,9 +217,9 @@ class TailCallee:
|
||||
results = _context.results
|
||||
results.i = i
|
||||
results.t = t
|
||||
results.c = capability().TestCallOrder.new_server(TailCallOrder())
|
||||
results.c = TailCallOrder()
|
||||
|
||||
def test_tail_call(capability):
|
||||
def test_tail_call():
|
||||
callee_server = TailCallee()
|
||||
caller_server = TailCaller()
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ class PipelineServer:
|
||||
def getCap_context(self, context):
|
||||
def _then(response):
|
||||
context.results.s = response.x + '_foo'
|
||||
context.results.outBox.cap = capability().TestInterface.new_server(Server(100))
|
||||
context.results.outBox.cap = capability().TestInterface._new_server(Server(100))
|
||||
|
||||
return context.params.inCap.foo(i=context.params.n).then(_then)
|
||||
|
||||
@@ -149,7 +149,7 @@ class BadPipelineServer:
|
||||
def getCap_context(self, context):
|
||||
def _then(response):
|
||||
context.results.s = response.x + '_foo'
|
||||
context.results.outBox.cap = capability().TestInterface.new_server(Server(100))
|
||||
context.results.outBox.cap = capability().TestInterface._new_server(Server(100))
|
||||
def _error(error):
|
||||
raise Exception('test was a success')
|
||||
|
||||
@@ -217,7 +217,7 @@ class TailCallee:
|
||||
results = context.results
|
||||
results.i = context.params.i
|
||||
results.t = context.params.t
|
||||
results.c = capability().TestCallOrder.new_server(TailCallOrder())
|
||||
results.c = capability().TestCallOrder._new_server(TailCallOrder())
|
||||
|
||||
def test_tail_call(capability):
|
||||
callee_server = TailCallee()
|
||||
|
||||
252
test/test_capability_old.py
Normal file
252
test/test_capability_old.py
Normal file
@@ -0,0 +1,252 @@
|
||||
import pytest
|
||||
import capnp
|
||||
import os
|
||||
|
||||
this_dir = os.path.dirname(__file__)
|
||||
|
||||
@pytest.fixture
|
||||
def capability():
|
||||
return capnp.load(os.path.join(this_dir, 'test_capability.capnp'))
|
||||
|
||||
class Server:
|
||||
def __init__(self, val=1):
|
||||
self.val = val
|
||||
|
||||
def foo(self, i, j, **kwargs):
|
||||
extra = 0
|
||||
if j:
|
||||
extra = 1
|
||||
return str(i * 5 + extra + self.val)
|
||||
|
||||
def buz(self, i, **kwargs):
|
||||
return i.host + '_test'
|
||||
|
||||
class PipelineServer:
|
||||
def getCap(self, n, inCap, _context, **kwargs):
|
||||
def _then(response):
|
||||
_results = _context.results
|
||||
_results.s = response.x + '_foo'
|
||||
_results.outBox.cap = capability().TestInterface._new_server(Server(100))
|
||||
|
||||
return inCap.foo(i=n).then(_then)
|
||||
|
||||
def test_client(capability):
|
||||
client = capability.TestInterface._new_client(Server())
|
||||
|
||||
req = client._request('foo')
|
||||
req.i = 5
|
||||
|
||||
remote = req.send()
|
||||
response = remote.wait()
|
||||
|
||||
assert response.x == '26'
|
||||
|
||||
req = client.foo_request()
|
||||
req.i = 5
|
||||
|
||||
remote = req.send()
|
||||
response = remote.wait()
|
||||
|
||||
assert response.x == '26'
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
client.foo2_request()
|
||||
|
||||
req = client.foo_request()
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
req.i = 'foo'
|
||||
|
||||
req = client.foo_request()
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
req.baz = 1
|
||||
|
||||
def test_simple_client(capability):
|
||||
client = capability.TestInterface._new_client(Server())
|
||||
|
||||
remote = client._send('foo', i=5)
|
||||
response = remote.wait()
|
||||
|
||||
assert response.x == '26'
|
||||
|
||||
|
||||
remote = client.foo(i=5)
|
||||
response = remote.wait()
|
||||
|
||||
assert response.x == '26'
|
||||
|
||||
remote = client.foo(i=5, j=True)
|
||||
response = remote.wait()
|
||||
|
||||
assert response.x == '27'
|
||||
|
||||
remote = client.foo(5)
|
||||
response = remote.wait()
|
||||
|
||||
assert response.x == '26'
|
||||
|
||||
remote = client.foo(5, True)
|
||||
response = remote.wait()
|
||||
|
||||
assert response.x == '27'
|
||||
|
||||
remote = client.foo(5, j=True)
|
||||
response = remote.wait()
|
||||
|
||||
assert response.x == '27'
|
||||
|
||||
remote = client.buz(capability.TestSturdyRefHostId.new_message(host='localhost'))
|
||||
response = remote.wait()
|
||||
|
||||
assert response.x == 'localhost_test'
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
remote = client.foo(5, 10)
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
remote = client.foo(5, True, 100)
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
remote = client.foo(i='foo')
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
remote = client.foo2(i=5)
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
remote = client.foo(baz=5)
|
||||
|
||||
def test_pipeline(capability):
|
||||
client = capability.TestPipeline._new_client(PipelineServer())
|
||||
foo_client = capability.TestInterface._new_client(Server())
|
||||
|
||||
remote = client.getCap(n=5, inCap=foo_client)
|
||||
|
||||
outCap = remote.outBox.cap
|
||||
pipelinePromise = outCap.foo(i=10)
|
||||
|
||||
response = pipelinePromise.wait()
|
||||
assert response.x == '150'
|
||||
|
||||
response = remote.wait()
|
||||
assert response.s == '26_foo'
|
||||
|
||||
class BadServer:
|
||||
def __init__(self, val=1):
|
||||
self.val = val
|
||||
|
||||
def foo(self, i, j, **kwargs):
|
||||
extra = 0
|
||||
if j:
|
||||
extra = 1
|
||||
return str(i * 5 + extra + self.val), 10 # returning too many args
|
||||
|
||||
def test_exception_client(capability):
|
||||
client = capability.TestInterface._new_client(BadServer())
|
||||
|
||||
remote = client._send('foo', i=5)
|
||||
with pytest.raises(capnp.KjException):
|
||||
remote.wait()
|
||||
|
||||
class BadPipelineServer:
|
||||
def getCap(self, n, inCap, _context, **kwargs):
|
||||
def _then(response):
|
||||
_results = _context.results
|
||||
_results.s = response.x + '_foo'
|
||||
_results.outBox.cap = capability().TestInterface._new_server(Server(100))
|
||||
def _error(error):
|
||||
raise Exception('test was a success')
|
||||
|
||||
return inCap.foo(i=n).then(_then, _error)
|
||||
|
||||
def test_exception_chain(capability):
|
||||
client = capability.TestPipeline._new_client(BadPipelineServer())
|
||||
foo_client = capability.TestInterface._new_client(BadServer())
|
||||
|
||||
remote = client.getCap(n=5, inCap=foo_client)
|
||||
|
||||
try:
|
||||
remote.wait()
|
||||
except Exception as e:
|
||||
assert 'test was a success' in str(e)
|
||||
|
||||
def test_pipeline_exception(capability):
|
||||
client = capability.TestPipeline._new_client(BadPipelineServer())
|
||||
foo_client = capability.TestInterface._new_client(BadServer())
|
||||
|
||||
remote = client.getCap(n=5, inCap=foo_client)
|
||||
|
||||
outCap = remote.outBox.cap
|
||||
pipelinePromise = outCap.foo(i=10)
|
||||
|
||||
with pytest.raises(Exception):
|
||||
loop.wait(pipelinePromise)
|
||||
|
||||
with pytest.raises(Exception):
|
||||
remote.wait()
|
||||
|
||||
def test_casting(capability):
|
||||
client = capability.TestExtends._new_client(Server())
|
||||
client2 = client.upcast(capability.TestInterface)
|
||||
client3 = client2.cast_as(capability.TestInterface)
|
||||
|
||||
with pytest.raises(Exception):
|
||||
client.upcast(capability.TestPipeline)
|
||||
|
||||
class TailCallOrder:
|
||||
def __init__(self):
|
||||
self.count = -1
|
||||
|
||||
def getCallSequence(self, expected, **kwargs):
|
||||
self.count += 1
|
||||
return self.count
|
||||
|
||||
class TailCaller:
|
||||
def __init__(self):
|
||||
self.count = 0
|
||||
|
||||
def foo(self, i, callee, _context, **kwargs):
|
||||
self.count += 1
|
||||
|
||||
tail = callee.foo_request(i=i, t='from TailCaller')
|
||||
return _context.tail_call(tail)
|
||||
|
||||
class TailCallee:
|
||||
def __init__(self):
|
||||
self.count = 0
|
||||
|
||||
def foo(self, i, t, _context, **kwargs):
|
||||
self.count += 1
|
||||
|
||||
results = _context.results
|
||||
results.i = i
|
||||
results.t = t
|
||||
results.c = capability().TestCallOrder._new_server(TailCallOrder())
|
||||
|
||||
def test_tail_call(capability):
|
||||
callee_server = TailCallee()
|
||||
caller_server = TailCaller()
|
||||
|
||||
callee = capability.TestTailCallee._new_client(callee_server)
|
||||
caller = capability.TestTailCaller._new_client(caller_server)
|
||||
|
||||
promise = caller.foo(i=456, callee=callee)
|
||||
dependent_call1 = promise.c.getCallSequence()
|
||||
|
||||
response = promise.wait()
|
||||
|
||||
assert response.i == 456
|
||||
assert response.i == 456
|
||||
|
||||
dependent_call2 = response.c.getCallSequence()
|
||||
dependent_call3 = response.c.getCallSequence()
|
||||
|
||||
result = dependent_call1.wait()
|
||||
assert result.n == 0
|
||||
result = dependent_call2.wait()
|
||||
assert result.n == 1
|
||||
result = dependent_call3.wait()
|
||||
assert result.n == 2
|
||||
|
||||
assert callee_server.count == 1
|
||||
assert caller_server.count == 1
|
||||
@@ -3,32 +3,28 @@ import capnp
|
||||
import os
|
||||
import socket
|
||||
|
||||
this_dir = os.path.dirname(__file__)
|
||||
import test_capability_capnp
|
||||
|
||||
@pytest.fixture
|
||||
def capability():
|
||||
return capnp.load(os.path.join(this_dir, 'test_capability.capnp'))
|
||||
|
||||
class Server:
|
||||
class Server(test_capability_capnp.TestInterface.Server):
|
||||
def __init__(self, val=1):
|
||||
self.val = val
|
||||
|
||||
def foo(self, i, j, **kwargs):
|
||||
return str(i * 5 + self.val)
|
||||
|
||||
def test_simple_rpc(capability):
|
||||
def test_simple_rpc():
|
||||
def _restore(ref_id):
|
||||
return capability.TestInterface.new_server(Server(100))
|
||||
return Server(100)
|
||||
|
||||
read, write = socket.socketpair(socket.AF_UNIX)
|
||||
|
||||
restorer = capnp.Restorer(capability.TestSturdyRefObjectId, _restore)
|
||||
restorer = capnp.Restorer(test_capability_capnp.TestSturdyRefObjectId, _restore)
|
||||
server = capnp.RpcServer(write, restorer)
|
||||
client = capnp.RpcClient(read)
|
||||
|
||||
ref = capability.TestSturdyRefObjectId.new_message()
|
||||
ref = test_capability_capnp.TestSturdyRefObjectId.new_message()
|
||||
cap = client.restore(ref)
|
||||
cap = cap.cast_as(capability.TestInterface)
|
||||
cap = cap.cast_as(test_capability_capnp.TestInterface)
|
||||
|
||||
remote = cap.foo(i=5)
|
||||
response = remote.wait()
|
||||
|
||||
@@ -77,3 +77,25 @@ def test_roundtrip_dict(all_types):
|
||||
|
||||
msg = all_types.TestAllTypes.from_dict(d)
|
||||
test_regression.check_all_types(msg)
|
||||
|
||||
def test_file_and_bytes(all_types):
|
||||
f = open('example', 'w')
|
||||
msg = all_types.TestAllTypes.new_message()
|
||||
test_regression.init_all_types(msg)
|
||||
msg.write(f)
|
||||
f.close()
|
||||
|
||||
f = open('example', 'r')
|
||||
|
||||
assert f.read() == msg.to_bytes()
|
||||
|
||||
def test_file_and_bytes_packed(all_types):
|
||||
f = open('example', 'w')
|
||||
msg = all_types.TestAllTypes.new_message()
|
||||
test_regression.init_all_types(msg)
|
||||
msg.write_packed(f)
|
||||
f.close()
|
||||
|
||||
f = open('example', 'r')
|
||||
|
||||
assert f.read() == msg.to_bytes_packed()
|
||||
|
||||
Reference in New Issue
Block a user