예제 #1
0
def test_packet_creation(message_addresses, random_arguments, faker):
    sp = AddressSpace()

    base_tt = TimeTag.now()

    for i, addr in enumerate(message_addresses):
        root, node = sp.create_from_address(addr)
        client = Client(address=faker.ipv4(), port=faker.port_number())
        args = tuple([next(random_arguments) for _ in range(3)])
        arg_vals = tuple([arg.value for arg in args])

        msg = node.create_message(*args, remote_client=client)
        assert msg.remote_client == client
        assert msg.address == node.address
        assert msg.address is not node.address
        assert tuple([arg.value for arg in msg]) == arg_vals

        tt = TimeTag(seconds=base_tt.seconds + i, fraction=base_tt.fraction)
        bun = node.create_bundled_message(*args,
                                          remote_client=client,
                                          timetag=tt)
        assert bun.timetag == tt
        assert bun.remote_client == client
        assert len(bun) == 1
        bun_msg = bun[0]
        assert bun_msg.address == node.address
        assert bun_msg.address is not node.address
        assert tuple([arg.value for arg in bun_msg]) == arg_vals
예제 #2
0
def test_address_node_wildcards(patterns):
    space = AddressSpace()
    root, concrete_node = space.create_from_address(patterns['base_pattern'])
    assert concrete_node.address.is_concrete

    def get_match(pattern):
        r = [node for node in space.match(pattern)]
        if not len(r):
            return None
        else:
            assert len(r) == 1
            return r[0]

    for pattern in patterns['matched']:
        assert get_match(pattern) is concrete_node

        truncated_pattern = '/'.join(pattern.split('/')[:-1])
        assert get_match(truncated_pattern) is concrete_node.parent

        extra_pattern = f'{pattern}/extrapart'
        assert get_match(extra_pattern) is None

    for pattern in patterns['unmatched']:
        assert get_match(pattern) is None

        extra_pattern = f'{pattern}/extrapart'
        assert get_match(extra_pattern) is None

    for pattern in patterns['double_slash']:
        if '//' not in pattern or pattern.startswith('//'):
            assert get_match(pattern) is concrete_node
        else:
            assert get_match(pattern) is None
예제 #3
0
def test_add_and_reparent():
    sp = AddressSpace()

    foo = sp.add_root('foo')
    assert foo.name == 'foo'
    assert foo.address.pattern == '/foo'
    assert 'foo' in sp
    assert foo.parent is None
    assert foo.is_root
    assert foo.root is foo
    assert foo.address_space is sp
    assert sp['foo'] is foo
    assert sp.add_root('foo') is foo
    assert len(sp) == 1
    assert len(foo) == 0

    bar = foo.add_child('bar')
    assert bar.name == 'bar'
    assert bar.address.pattern == '/foo/bar'
    assert 'bar' in foo
    assert foo['bar'] is bar
    assert foo.address_space is sp
    assert bar.parent is foo
    assert not bar.is_root
    assert bar.root is foo
    assert len(foo) == 1
    assert len(sp) == 1

    last_node = AddressNode('last')
    bar.add_child_instance(last_node)
    assert last_node.address.pattern == '/foo/bar/last'
    assert last_node.root is foo
    assert len(bar) == 1

    baz = sp.add_root('baz')
    assert baz.address.pattern == '/baz'
    assert 'baz' in sp
    assert baz.is_root
    assert len(sp) == 2

    bar.parent = baz
    assert bar.address.pattern == '/baz/bar'
    assert bar.address_space is sp
    assert bar.root is baz
    assert not bar.is_root
    assert len(foo) == 0
    assert len(bar) == 1

    assert last_node.address.pattern == '/baz/bar/last'
    assert last_node.address_space is sp
    assert not last_node.is_root
    assert last_node.root is baz

    all_addresses = ('/foo', '/baz', '/baz/bar', '/baz/bar/last')
    node_addrs = set()
    for node in sp.walk():
        print(node)
        assert node.address.pattern not in node_addrs
        node_addrs.add(node.address.pattern)
    assert set(node_addrs) == set(all_addresses)
예제 #4
0
def test_node_tree(message_addresses):
    message_addresses = set(message_addresses)

    sp = AddressSpace()
    all_addr_nodes = set()
    for addr in message_addresses:
        root, last_child = sp.create_from_address(addr)
        assert root.is_root
        if last_child is not root:
            assert not last_child.is_root
        all_addr_nodes.add(last_child)
        assert last_child.address.pattern == addr
        assert last_child.root is root
        assert root.find(addr) is last_child
        assert sp.find(addr) is last_child

        matched = 0
        for node in sp.match(addr):
            assert node is last_child
            matched += 1

        assert matched == 1

    assert len(message_addresses) == len(all_addr_nodes)
예제 #5
0
    def __init__(self,
                 listen_address: Optional[Client] = None,
                 address_space: Optional[AddressSpace] = None):

        if listen_address is None:
            listen_address = self.default_listen_address
        self.listen_address = listen_address
        if address_space is None:
            address_space = AddressSpace()
        self.__address_space = address_space
        self.__message_handler = MessageHandler(address_space)
        self.running = False
        self.rx_queue = asyncio.Queue()
        self.tx_queue = asyncio.Queue()
        self._tx_loop_task = None
        self._rx_loop_task = None
        self.loop = asyncio.get_event_loop()
예제 #6
0
def test_exceptions():
    class MyAddressNode(AddressNode):
        pass

    sp = AddressSpace()

    foo = sp.add_root('foo')
    assert sp.add_root('foo') is foo

    my_bar = foo.add_child('bar', cls=MyAddressNode)
    assert foo.add_child('bar', cls=MyAddressNode) is my_bar

    with pytest.raises(KeyError):
        sp.add_root('foo', cls=MyAddressNode)
    with pytest.raises(KeyError):
        sp.add_root_instance(AddressNode('foo'))
    with pytest.raises(KeyError):
        sp.add_root_instance(MyAddressNode('foo'))
    with pytest.raises(KeyError):
        sp.create_from_address('/foo', cls=MyAddressNode)

    with pytest.raises(KeyError):
        foo.add_child('bar')
    with pytest.raises(KeyError):
        foo.add_child_instance(AddressNode('bar'))
    with pytest.raises(KeyError):
        foo.add_child_instance(MyAddressNode('bar'))

    baz1 = MyAddressNode('baz')
    baz1.parent = my_bar
    assert baz1.address.pattern == '/foo/bar/baz'

    baz2 = MyAddressNode('baz')
    with pytest.raises(KeyError):
        baz2.parent = my_bar
예제 #7
0
def test_node_dispatch(message_addresses, random_arguments, faker):
    class SpaceListener:
        def __init__(self, address_space):
            self.address_space = address_space
            self.results = []
            self.address_space.bind(on_message=self.callback)

        def get_result(self):
            r = self.results[0]
            self.results = self.results[1:]
            return r

        def callback(self, address, msg, timetag):
            self.results.append((address, msg, timetag))

    class NodeListener:
        def __init__(self):
            self.results = []

        def bind_to_node(self, node):
            self.results.clear()
            node.add_callback(self.callback)

        def unbind_node(self, node):
            node.remove_callback(self.callback)
            self.results.clear()

        def get_result(self):
            r = self.results[0]
            self.results = self.results[1:]
            return r

        def callback(self, node, msg, timetag):
            self.results.append((node, msg, timetag))

    sp = AddressSpace()
    sp_listener = SpaceListener(sp)
    node_listener = NodeListener()

    base_tt = TimeTag.now()

    for i, addr in enumerate(message_addresses):
        tt = TimeTag(seconds=base_tt.seconds + i, fraction=base_tt.fraction)

        root, node = sp.create_from_address(addr)
        assert not node.has_callbacks
        assert node.event_handler is None
        node_listener.bind_to_node(node)
        assert node.has_callbacks
        assert node.event_handler is not None

        client = Client(address=faker.ipv4(), port=faker.port_number())
        args = tuple([next(random_arguments) for _ in range(3)])
        arg_vals = tuple([arg.value for arg in args])

        msg = node.create_message(*args, remote_client=client)
        node.dispatch(msg, tt)

        sp_result = sp_listener.get_result()
        r_addr, r_msg, r_tt = sp_result
        assert r_addr == node.address
        assert r_msg == msg
        assert r_tt == tt

        node_result = node_listener.get_result()
        r_node, r_msg, r_tt = node_result
        assert r_node is node
        assert r_msg == msg
        assert r_tt == tt

        node_listener.unbind_node(node)
        assert not node.has_callbacks
        assert node.event_handler is None
예제 #8
0
def test_multiple_address_spaces():
    sp1 = AddressSpace()
    sp2 = AddressSpace()

    arm_addrs = (
        '/arm/left/hand',
        '/arm/right/hand',
    )
    leg_addrs = ('/leg/left/foot', '/leg/right/foot')

    all_arm_addrs = (
        '/arm',
        '/arm/left',
        '/arm/right',
        '/arm/left/hand',
        '/arm/right/hand',
    )

    all_leg_addrs = (
        '/leg',
        '/leg/left',
        '/leg/right',
        '/leg/left/foot',
        '/leg/right/foot',
    )

    for addr in arm_addrs:
        sp1.create_from_address(addr)
    for addr in leg_addrs:
        sp2.create_from_address(addr)

    assert list(sp1.keys()) == ['arm']
    assert list(sp2.keys()) == ['leg']

    for addr in all_arm_addrs:
        node = sp1.find(addr)
        assert node.address.pattern == addr
        assert node.address_space is sp1
        if addr == '/arm':
            assert node.is_root
            assert node.name in sp1.keys()
        else:
            assert not node.is_root
            assert node.name in node.parent.keys()

            with pytest.raises(ValueError) as excinfo:
                node.address_space = sp2
            assert 'only root nodes' in str(excinfo.value).lower()

    for addr in all_leg_addrs:
        node = sp2.find(addr)
        assert node.address.pattern == addr
        assert node.address_space is sp2
        if addr == '/leg':
            assert node.is_root
            assert node.name in sp2.keys()
        else:
            assert not node.is_root
            assert node.name in node.parent.keys()

            with pytest.raises(ValueError) as excinfo:
                node.address_space = sp1
            assert 'only root nodes' in str(excinfo.value).lower()

    arm_node = sp1['arm']
    leg_node = sp2['leg']

    sp1.add_root_instance(leg_node)

    for addr in all_leg_addrs:
        assert sp2.find(addr) is None

        node = sp1.find(addr)
        assert node.address_space is sp1

    arm_node.address_space = sp2

    for addr in all_arm_addrs:
        assert sp1.find(addr) is None

        node = sp2.find(addr)
        assert node.address_space is sp2