Ejemplo n.º 1
0
 def run(self):
     client = RPCClient(self.addr)
     qt = client._import('pyqtgraph.Qt')
     # widget creation happens in main GUI thread; we are working with
     # proxies from here.
     self.l = qt.QtGui.QLabel('remote-controlled label')
     self.l.show()
     time.sleep(0.3)
     self.l.hide()
     with self.lock:
         self.done = True
Ejemplo n.º 2
0
def test_host1():
    
    process_host0 = ProcessSpawner(Host, 'host0', 'tcp://127.0.0.1:*')
    process_host1 = ProcessSpawner(Host, 'host1', 'tcp://127.0.0.1:*')
    
    client0 = RPCClient('host0', process_host0.addr)
    print('on ping: ', client0.ping())
    
    time.sleep(1.)
    
    process_host0.stop()
    process_host1.stop()
Ejemplo n.º 3
0
def test_host2():
    
    process_host0 = ProcessSpawner(Host, 'host0', 'tcp://127.0.0.1:*')
    
    client0 = RPCClient('host0', process_host0.addr)
    
    client0.create_nodegroup('nodegroup 0.1', 'tcp://127.0.0.1:*')
    client0.create_nodegroup('nodegroup 0.2', 'tcp://127.0.0.1:*')
    
    time.sleep(2.)
    
    client0.close_nodegroup('nodegroup 0.1')
    client0.close_nodegroup('nodegroup 0.2')
    
    time.sleep(1.)
    
    process_host0.stop()
Ejemplo n.º 4
0
def test_remotly_show_qwidget_node():
    name, addr = 'nodegroup0', 'tcp://127.0.0.1:*'
    process_nodegroup0  = ProcessSpawner(NodeGroup,  name, addr)
    client0 = RPCClient(name, process_nodegroup0.addr)
    client0.create_node('mynode', '_MyTestNodeQWidget')
    client0.control_node('mynode', 'show')
    
    name, addr = 'nodegroup1', 'tcp://127.0.0.1:*'
    process_nodegroup1  = ProcessSpawner(NodeGroup,  name, addr)
    client1 = RPCClient(name, process_nodegroup1.addr)
    client1.create_node('mynode', '_MyTestNodeQWidget')
    client1.control_node('mynode', 'show')
    
    time.sleep(3.)
    
    process_nodegroup0.stop()
    process_nodegroup1.stop()
Ejemplo n.º 5
0
def bench_ping_pong_nodegroup():
    # compare Qt4 mainloop of NodeGroup vs Host main loop which is infinite loop (fastest possible)
    for name, class_ in [ ('Host', Host), ('NodeGroup', NodeGroup)]:
        addr = 'tcp://127.0.0.1:*'
        process  = ProcessSpawner(class_,  name, addr)
        client = RPCClient(name, process.addr)
        
        N =1000
        
        t1 = time.time()
        for i in range(N):
            client.ping()
        t2 = time.time()
        print(name, ' : sync ping per second', N/(t2-t1))

        t1 = time.time()
        rets = []
        for i in range(N):
            rets.append(client.ping(_sync=False))
        for ret in rets:
            ret.result()
        t2 = time.time()
        print(name, ' : async ping per second', N/(t2-t1))
        
        client.close()
Ejemplo n.º 6
0
def test_rpc():
    previous_level = logger.level
    #logger.level = logging.DEBUG
    
    class TestClass(object):
        count = 0
        def __init__(self, name):
            self.name = name
            TestClass.count += 1

        def __del__(self):
            TestClass.count -= 1
        
        def add(self, x, y):
            return x + y
        
        def array(self):
            return np.arange(20).astype('int64')
   
        def sleep(self, t):
            time.sleep(t)
            
        def get_list(self):
            return [0, 'x', 7]
        
        def test(self, obj):
            return self.name, obj.name, obj.add(5, 7), obj.array(), obj.get_list()

        def types(self):
            return {'int': 7, 'float': 0.5, 'str': 'xxx', 'bytes': bytes('xxx', 'utf8'),
                    'ndarray': np.arange(10), 'dict': {}, 'list': [],
                    'ObjectProxy': self}
    
        def type(self, x):
            return type(x).__name__
    
    
    server1 = RPCServer()
    server1['test_class'] = TestClass
    server1['my_object'] = TestClass('obj1')
    serve_thread = threading.Thread(target=server1.run_forever, daemon=True)
    serve_thread.start()
    
    client = RPCClient.get_client(server1.address)
    
    # test clients are cached
    assert client == RPCClient.get_client(server1.address)
    try:
        # can't manually create client for the same address
        RPCClient(server1.address)
        assert False, "Should have raised KeyError."
    except KeyError:
        pass
    
    # get proxy to TestClass instance
    obj = client['my_object']
    assert isinstance(obj, ObjectProxy)
    
    # check equality with duplicate proxy
    obj2 = client['my_object']
    assert obj == obj2
    assert obj._obj_id == obj2._obj_id
    assert obj._ref_id != obj2._ref_id    

    # check hashability
    assert obj in {obj2: None}
    assert obj in set([obj2])
    
    logger.info("-- Test call with sync return --")
    add = obj.add
    assert isinstance(add, ObjectProxy)
    assert add(7, 5) == 12

    # test return types
    for k, v in obj.types().items():
        assert type(v).__name__ == k
        if k != 'ObjectProxy':
            assert obj.type(v) == k

    # NOTE: msgpack converts list to tuple. 
    # See: https://github.com/msgpack/msgpack-python/issues/98
    assert obj.get_list() == [0, 'x', 7]

    logger.info("-- Test async return --")
    fut = obj.sleep(0.1, _sync='async')
    assert not fut.done()
    assert fut.result() is None

    logger.info("-- Test no return --")
    assert obj.add(1, 2, _sync='off') is None

    logger.info("-- Test return by proxy --")
    list_prox = obj.get_list(_return_type='proxy')
    assert isinstance(list_prox, ObjectProxy)
    assert list_prox._type_str == "<class 'list'>"
    assert len(list_prox) == 3
    assert list_prox[2] == 7

    logger.info("-- Test proxy access to server --")
    srv = client['self']
    assert srv.address == server1.address


    logger.info("-- Test remote exception raising --")
    try:
        obj.add(7, 'x')
    except RemoteCallException as err:
        if err.type_str != 'TypeError':
            raise
    else:
        raise AssertionError('should have raised TypeError')

    try:
        client.asdffhgk
        raise AssertionError('should have raised AttributeError')
    except AttributeError:
        pass

    logger.info("-- Test deferred getattr --")
    arr = obj.array(_return_type='proxy')
    dt1 = arr.dtype.name._get_value()
    assert isinstance(dt1, str)
    arr._set_proxy_options(defer_getattr=True)
    dt2 = arr.dtype.name
    assert isinstance(dt2, ObjectProxy)
    assert dt2._obj_id == arr._obj_id
    assert dt2._attributes == ('dtype', 'name')
    dt3 = dt2._undefer()
    assert dt3 == dt2

    logger.info("-- Test remote object creation / deletion --")
    class_proxy = client['test_class']
    obj2 = class_proxy('obj2')
    assert class_proxy.count == 2
    assert obj2.add(3, 4) == 7
    
    obj2._delete()
    handler.flush_records()  # log records might have refs to the object
    assert class_proxy.count._get_value() == 1
    try:
        obj2.array()
        assert False, "Should have raised RemoteCallException"
    except RemoteCallException:
        pass

    logger.info("-- Test proxy auto-delete --")
    obj2 = class_proxy('obj2')
    obj2._set_proxy_options(auto_delete=True)
    assert class_proxy.count == 2
    
    del obj2
    handler.flush_records()  # log records might have refs to the object
    assert class_proxy.count._get_value() == 1


    logger.info("-- Test timeouts --")
    try:
        obj.sleep(0.2, _timeout=0.01)
    except TimeoutError:
        pass
    else:
        raise AssertionError('should have raised TimeoutError')
    obj.sleep(0.2, _timeout=0.5)

    logger.info("-- Test result order --")
    a = obj.add(1, 2, _sync='async')
    b = obj.add(3, 4, _sync='async')
    assert b.result() == 7
    assert a.result() == 3

    
    logger.info("-- Test transfer --")
    arr = np.ones(10, dtype='float32')
    arr_prox = client.transfer(arr)
    assert arr_prox.dtype.name == 'float32'
    print(arr_prox, arr_prox.shape)
    assert arr_prox.shape._get_value() == [10]


    logger.info("-- Test import --")
    import os.path as osp
    rosp = client._import('os.path')
    assert osp.abspath(osp.dirname(__file__)) == rosp.abspath(rosp.dirname(__file__))


    logger.info("-- Test proxy sharing between servers --")
    obj._set_proxy_options(defer_getattr=True)
    r1 = obj.test(obj)
    server2 = RPCServer()
    server2['test_class'] = TestClass
    serve_thread2 = threading.Thread(target=server2.run_forever, daemon=True)
    serve_thread2.start()
    
    client2 = RPCClient(server2.address)
    client2.default_proxy_options['defer_getattr'] = True
    obj3 = client2['test_class']('obj3')
    # send proxy from server1 to server2
    r2 = obj3.test(obj)
    # check that we have a new client between the two servers
    assert (serve_thread2.ident, server1.address) in RPCClient.clients_by_thread 
    # check all communication worked correctly
    assert r1[0] == 'obj1'
    assert r2[0] == 'obj3'
    assert r1[1] == r2[1] == 'obj1'
    assert r1[2] == r2[2] == 12
    assert np.all(r1[3] == r2[3])
    assert r1[4] == r2[4]
    
    logger.info("-- Test publishing objects --")
    arr = np.arange(5, 10)
    client['arr'] = arr  # publish to server1
    s2rpc = client2._import('pyacq.core.rpc')
    s2cli = s2rpc.RPCClient.get_client(client.address)  # server2's client for server1
    assert np.all(s2cli['arr'] == arr)  # retrieve via server2

    logger.info("-- Test JSON client --")
    # Start a JSON client in a remote process
    cli_proc = ProcessSpawner()
    cli = cli_proc.client._import('pyacq.core.rpc').RPCClient(server2.address, serializer='json')
    # Check everything is ok..
    assert cli.serializer.type._get_value() == 'json'
    assert cli['test_class']('json-tester').add(3, 4) == 7
    cli_proc.kill()

    
    logger.info("-- Setup reentrant communication test.. --")
    class PingPong(object):
        def set_other(self, o):
            self.other = o
        def pingpong(self, depth=0):
            if depth > 6:
                return "reentrant!"
            return self.other.pingpong(depth+1)

    server1['pp1'] = PingPong()
    server2['pp2'] = PingPong()
    pp1 = client['pp1']
    pp2 = client2['pp2']
    pp1.set_other(pp2)
    pp2.set_other(pp1)
    
    logger.info("-- Test reentrant communication --")
    assert pp1.pingpong() == 'reentrant!'

    
    logger.info("-- Shut down servers --")
    client2.close_server()
    serve_thread2.join()
    
    
    client.close_server()
    client.close()
    serve_thread.join()
    
    logger.level = previous_level
Ejemplo n.º 7
0
def basic_test_manager():
    # Create a local Host to communicate with
    test_host = ProcessSpawner(Host, name="test-host", addr="tcp://127.0.0.1:*")
    host_cli = RPCClient(test_host.name, test_host.addr)

    mgr = ProcessSpawner(Manager, name="manager", addr="tcp://127.0.0.1:*")
    mcli = RPCClient(mgr.name, mgr.addr)

    # test connection to host
    host_name = test_host.name
    mcli.connect_host(host_name, test_host.addr)
    assert mcli.list_hosts() == [host_name]

    # create nodegroup and nodes
    assert mcli.list_nodegroups(host_name) == []
    mcli.create_nodegroup(host_name, "nodegroup1")
    assert mcli.list_nodegroups(host_name) == ["nodegroup1"]

    assert mcli.list_nodes("nodegroup1") == []
    mcli.create_node("nodegroup1", "node1", "_MyTestNode")
    assert mcli.list_nodes("nodegroup1") == ["node1"]
    mcli.control_node("node1", "start")
    mcli.control_node("node1", "stop")
    mcli.delete_node("node1")
    assert mcli.list_nodes("nodegroup1") == []

    # mcli.close()
    # host_cli.close()
    mgr.stop()
    test_host.stop()
Ejemplo n.º 8
0
def test_rpc():
    previsous_level = logging.getLogger().level
    logging.getLogger().level=logging.INFO
    
    class Server1(RPCServer):
        def add(self, a, b):
            return a + b
        def sleep(self, t):
            time.sleep(t)

    server = Server1(name='some_server', addr='tcp://*:5152')
    serve_thread = threading.Thread(target=server.run_forever, daemon=True)
    serve_thread.start()
    
    client = RPCClient('some_server', 'tcp://localhost:5152')
    # atexit.register(client.close)
    
    # test call / sync return
    assert client.add(7, 5) == 12

    # test async return
    fut = client.sleep(0.1, _sync=False)
    assert not fut.done()
    assert fut.result() is None

    # Test remote exception raising
    try:
        client.add(7, 'x')
    except RemoteCallException as err:
        if err.type_str != 'TypeError':
            raise
    else:
        raise AssertionError('should have raised TypeError')

    try:
        client.fn()
    except RemoteCallException as err:
        if err.type_str != 'AttributeError':
            raise
    else:
        raise AssertionError('should have raised AttributeError')

    # test timeouts
    try:
        client.sleep(0.2, _timeout=0.01)
    except TimeoutError:
        pass
    else:
        raise AssertionError('should have raised TimeoutError')

    # test result order
    a = client.add(1, 2, _sync=False)
    b = client.add(3, 4, _sync=False)
    assert b.result() == 7
    assert a.result() == 3

    # test multiple clients per server
    client2 = RPCClient('some_server', 'tcp://localhost:5152')
    
    a = client2.add(1, 2, _sync=False)
    b = client.add(3, 4, _sync=False)
    c = client2.add(5, 6, _sync=False)
    assert b.result() == 7
    assert a.result() == 3
    assert c.result() == 11

    # test multiple clients sharing one socket
    server2 = Server1(name='some_server2', addr='tcp://*:5153')
    serve_thread2 = threading.Thread(target=server2.run_forever, daemon=True)
    serve_thread2.start()
    
    client3 = RPCClient('some_server2', 'tcp://localhost:5153',
                        rpc_socket=client2._rpc_socket)
    
    a = client2.add(1, 2, _sync=False)
    b = client3.add(3, 4, _sync=False)
    assert b.result() == 7
    assert a.result() == 3
    
    client.close()
    serve_thread.join()
    
    client3.close()
    serve_thread2.join()
    
    logging.getLogger().level=previsous_level
Ejemplo n.º 9
0
def test_cannot_delete_node_while_running():
    name, addr = 'nodegroup', 'tcp://127.0.0.1:*'
    process_nodegroup0  = ProcessSpawner(NodeGroup,  name, addr)
    client0 = RPCClient(name, process_nodegroup0.addr)
    
    client0.create_node('mynode', '_MyTestNode')
    client0.control_node('mynode', 'configure')
    client0.control_node('mynode', 'initialize')
    client0.control_node('mynode', 'start')
    
    with pytest.raises(RemoteCallException):
        # a running node cannot be delete
        client0.delete_node('mynode')
    
    client0.control_node('mynode', 'stop')
    client0.delete_node('mynode')

    process_nodegroup0.stop()
Ejemplo n.º 10
0
def test_nodegroup0():
    name, addr = 'nodegroup', 'tcp://127.0.0.1:*'
    process_nodegroup0  = ProcessSpawner(NodeGroup,  name, addr)
    client0 = RPCClient(name, process_nodegroup0.addr)
    
    n = 5
    
    for i in range(n):
        client0.create_node('mynode{}'.format(i), '_MyTestNode')

    for i in range(n):
        client0.control_node('mynode{}'.format(i), 'configure')

    for i in range(n):
        client0.control_node('mynode{}'.format(i), 'initialize')

    for i in range(n):
        client0.control_node('mynode{}'.format(i), 'start')

    for i in range(n):
        client0.control_node('mynode{}'.format(i), 'stop')

    for i in range(n):
        client0.delete_node('mynode{}'.format(i))
    
    process_nodegroup0.stop()