Beispiel #1
0
def limo(zone, player, antechamber):
    limo = zone.spawn(
        [Named("a fancy limo", "It's electric!"), Spatial(), Container(), Enterable()]
    )
    connect(zone, antechamber, is_="out", of=limo)
    antechamber.Container.store(limo)
    return limo
Beispiel #2
0
def limo(zone, player, antechamber):
    limo = zone.spawn([
        Named('a fancy limo', "It's electric!"),
        Spatial(),
        Container(),
        Enterable(),
    ])
    connect(zone, antechamber, is_='out', of=limo)
    antechamber.Container.store(limo)
    return limo
Beispiel #3
0
def courtyard(zone, antechamber):
    courtyard = room(
        zone,
        'The World Foundry - Courtyard (South Side)',
        """
        A wide-open green space in front of the Library, criss-crossed with a
        network of walking paths.
        """
    )
    connect(zone, courtyard, is_='north', of=antechamber, returning='south')
    return courtyard
Beispiel #4
0
def courtyard(zone, antechamber):
    courtyard = room(
        zone,
        "The World Foundry - Courtyard (South Side)",
        """
        A wide-open green space in front of the Library, criss-crossed with a
        network of walking paths.
        """,
    )
    connect(zone, courtyard, is_="north", of=antechamber, returning="south")
    return courtyard
async def perform_test_from_obj(obj, router_factory):
    """
    Perform pubsub tests from a test obj.
    test obj are composed as follows:

    {
        "supported_protocols": ["supported/protocol/1.0.0",...],
        "adj_list": {
            "node1": ["neighbor1_of_node1", "neighbor2_of_node1", ...],
            "node2": ["neighbor1_of_node2", "neighbor2_of_node2", ...],
            ...
        },
        "topic_map": {
            "topic1": ["node1_subscribed_to_topic1", "node2_subscribed_to_topic1", ...]
        },
        "messages": [
            {
                "topics": ["topic1_for_message", "topic2_for_message", ...],
                "data": b"some contents of the message (newlines are not supported)",
                "node_id": "message sender node id"
            },
            ...
        ]
    }
    NOTE: In adj_list, for any neighbors A and B, only list B as a neighbor of A
    or B as a neighbor of A once. Do NOT list both A: ["B"] and B:["A"] as the behavior
    is undefined (even if it may work)
    """

    # Step 1) Create graph
    adj_list = obj["adj_list"]
    node_map = {}
    pubsub_map = {}

    async def add_node(node_id_str: str) -> None:
        pubsub_router = router_factory(protocols=obj["supported_protocols"])
        pubsub = PubsubFactory(router=pubsub_router)
        await pubsub.host.get_network().listen(LISTEN_MADDR)
        node_map[node_id_str] = pubsub.host
        pubsub_map[node_id_str] = pubsub

    tasks_connect = []
    for start_node_id in adj_list:
        # Create node if node does not yet exist
        if start_node_id not in node_map:
            await add_node(start_node_id)

        # For each neighbor of start_node, create if does not yet exist,
        # then connect start_node to neighbor
        for neighbor_id in adj_list[start_node_id]:
            # Create neighbor if neighbor does not yet exist
            if neighbor_id not in node_map:
                await add_node(neighbor_id)
            tasks_connect.append(
                connect(node_map[start_node_id], node_map[neighbor_id]))
    # Connect nodes and wait at least for 2 seconds
    await asyncio.gather(*tasks_connect, asyncio.sleep(2))

    # Step 2) Subscribe to topics
    queues_map = {}
    topic_map = obj["topic_map"]

    tasks_topic = []
    tasks_topic_data = []
    for topic, node_ids in topic_map.items():
        for node_id in node_ids:
            tasks_topic.append(pubsub_map[node_id].subscribe(topic))
            tasks_topic_data.append((node_id, topic))
    tasks_topic.append(asyncio.sleep(2))

    # Gather is like Promise.all
    responses = await asyncio.gather(*tasks_topic)
    for i in range(len(responses) - 1):
        node_id, topic = tasks_topic_data[i]
        if node_id not in queues_map:
            queues_map[node_id] = {}
        # Store queue in topic-queue map for node
        queues_map[node_id][topic] = responses[i]

    # Allow time for subscribing before continuing
    await asyncio.sleep(0.01)

    # Step 3) Publish messages
    topics_in_msgs_ordered = []
    messages = obj["messages"]
    tasks_publish = []

    for msg in messages:
        topics = msg["topics"]
        data = msg["data"]
        node_id = msg["node_id"]

        # Publish message
        # TODO: Should be single RPC package with several topics
        for topic in topics:
            tasks_publish.append(pubsub_map[node_id].publish(topic, data))

        # For each topic in topics, add (topic, node_id, data) tuple to ordered test list
        for topic in topics:
            topics_in_msgs_ordered.append((topic, node_id, data))

    # Allow time for publishing before continuing
    await asyncio.gather(*tasks_publish, asyncio.sleep(2))

    # Step 4) Check that all messages were received correctly.
    for topic, origin_node_id, data in topics_in_msgs_ordered:
        # Look at each node in each topic
        for node_id in topic_map[topic]:
            # Get message from subscription queue
            msg = await queues_map[node_id][topic].get()
            assert data == msg.data
            # Check the message origin
            assert node_map[origin_node_id].get_id().to_bytes() == msg.from_id