Example #1
0
def test_rpc():
    a0.File.remove("foo.rpc.a0")
    assert not os.path.exists("/dev/shm/alephzero/foo.rpc.a0")

    cv = threading.Condition()

    class State:
        requests = []
        cancels = []
        replies = []

    def onrequest(req):
        with cv:
            State.requests.append(req.pkt.payload)
            if req.pkt.payload == b"reply":
                req.reply(b"reply")
            if req.pkt.payload.startswith(b"sleep"):
                time.sleep(0.2)
                req.reply(b"slept")
            cv.notify()

    def oncancel(id):
        with cv:
            State.cancels.append(id)
            cv.notify()

    server = a0.RpcServer("foo", onrequest, oncancel)
    assert os.path.exists("/dev/shm/alephzero/foo.rpc.a0")

    def onreply(pkt):
        with cv:
            State.replies.append(pkt.payload)
            cv.notify()

    client = a0.RpcClient("foo")
    client.send("reply", onreply)
    client.send("reply", onreply)
    pkt = a0.Packet("cancel")
    client.send(pkt, onreply)
    client.cancel(pkt.id)

    with cv:
        cv.wait_for(lambda: (len(State.requests) == 3 and len(State.cancels) ==
                             1 and len(State.replies) == 2))

    reply = client.send_blocking("sleep")
    assert reply.payload == b"slept"
    reply = client.send_blocking("sleep", timeout=a0.TimeMono.now() + 0.3)
    assert reply.payload == b"slept"
    with pytest.raises(RuntimeError, match="Connection timed out"):
        client.send_blocking("sleep", timeout=a0.TimeMono.now() + 0.1)
Example #2
0
async def test_rpc(sandbox):
    await sandbox.WaitUntilStartedAsync(timeout=1.0)

    ns = types.SimpleNamespace()
    ns.collected_requests = []

    def on_request(req):
        ns.collected_requests.append(req.pkt.payload.decode("utf-8"))
        req.reply(f"success_{len(ns.collected_requests)}")

    tm = a0.TopicManager({"container": "aaa"})
    topic = tm.rpc_server_topic("bbb")
    server = a0.RpcServer(topic, on_request, None)  # noqa: F841

    async with aiohttp.ClientSession() as session:
        endpoint = "http://localhost:24880/api/rpc"
        rpc_data = {
            "container": "aaa",
            "topic": "bbb",
            "packet": {
                "payload": "",
            },
        }

        # Normal request.
        rpc_data["packet"]["payload"] = base64.b64encode(b"request_0").decode(
            "utf-8")
        async with session.post(endpoint, data=json.dumps(rpc_data)) as resp:
            assert resp.status == 200
            resp_pkt = await resp.json()
            assert base64.b64decode(resp_pkt.get("payload",
                                                 "")) == b"success_1"

        # Normal request.
        rpc_data["packet"]["payload"] = base64.b64encode(b"request_1").decode(
            "utf-8")
        async with session.post(endpoint, data=json.dumps(rpc_data)) as resp:
            assert resp.status == 200
            resp_pkt = await resp.json()
            assert base64.b64decode(resp_pkt.get("payload",
                                                 "")) == b"success_2"

        # Missing "container".
        rpc_data.pop("container")
        async with session.post(endpoint, data=json.dumps(rpc_data)) as resp:
            assert resp.status == 400
            assert await resp.text() == "Missing required 'container' field."
        rpc_data["container"] = "aaa"

        # Missing "topic".
        rpc_data.pop("topic")
        async with session.post(endpoint, data=json.dumps(rpc_data)) as resp:
            assert resp.status == 400
            assert await resp.text() == "Missing required 'topic' field."
        rpc_data["topic"] = "bbb"

        # Not JSON.
        async with session.post(endpoint, data="not json") as resp:
            assert resp.status == 400
            assert await resp.text() == "Body must be json."

        # Not JSON object.
        async with session.post(endpoint,
                                data=json.dumps("not object")) as resp:
            assert resp.status == 400
            assert await resp.text() == "Body must be a json object."

    assert ns.collected_requests == ["request_0", "request_1"]
Example #3
0
def test_rpc(sandbox):
    ns = types.SimpleNamespace()
    ns.collected_requests = []

    def on_request(req):
        ns.collected_requests.append(req.pkt.payload)
        req.reply(f"success_{len(ns.collected_requests) - 1}")

    server = a0.RpcServer("mytopic", on_request, None)

    endpoint = f"http://localhost:{os.environ['PORT_STR']}/api/rpc"
    rpc_data = {
        "topic": "mytopic",
        "packet": {
            "payload": "",
        },
    }

    # Normal request.
    rpc_data["packet"]["payload"] = "request_0"
    resp = requests.post(endpoint, data=json.dumps(rpc_data))
    assert resp.status_code == 200
    assert sorted([k for k, v in resp.json()["headers"]]) == [
        "a0_dep",
        "a0_req_id",
        "a0_rpc_type",
        "a0_time_mono",
        "a0_time_wall",
        "a0_transport_seq",
        "a0_writer_id",
        "a0_writer_seq",
    ]
    assert resp.json()["payload"] == "success_0"

    # Missing "topic".
    rpc_data.pop("topic")
    resp = requests.post(endpoint, data=json.dumps(rpc_data))
    assert resp.status_code == 400
    assert resp.text == "Request missing required field: topic"
    rpc_data["topic"] = "mytopic"

    # Not JSON.
    resp = requests.post(endpoint, data="not json")
    assert resp.status_code == 400
    assert resp.text == "Request must be json."

    # Not JSON object.
    resp = requests.post(endpoint, data=json.dumps("not object"))
    assert resp.status_code == 400
    assert resp.text == "Request must be a json object."

    # Base64 Request Encoding.
    rpc_data["packet"]["payload"] = btoa("request_1")
    rpc_data["request_encoding"] = "base64"
    resp = requests.post(endpoint, data=json.dumps(rpc_data))
    assert resp.status_code == 200
    assert resp.json()["payload"] == "success_1"
    del rpc_data["request_encoding"]

    # Base64 Response Encoding.
    print("Base64 Response Encoding.", flush=True, file=sys.stderr)
    rpc_data["packet"]["payload"] = "request_2"
    rpc_data["response_encoding"] = "base64"
    resp = requests.post(endpoint, data=json.dumps(rpc_data))
    assert resp.status_code == 200
    assert atob(resp.json()["payload"]) == "success_2"

    assert ns.collected_requests == [b"request_0", b"request_1", b"request_2"]
Example #4
0
import a0
import time


def onrequest(req):
    pkt = req.pkt
    payload = pkt.payload.decode("utf-8")
    print(f"Request (id={pkt.id}): {payload}")
    req.reply(f"echo {payload}")


print("Listening for 60 sec")
server = a0.RpcServer("topic", onrequest, None)
time.sleep(60)
print("Done!")
Example #5
0
import a0
import time

a0.InitGlobalTopicManager('''{
    "container": "stuff_doer"
}''')


def onrequest(req):
    print('Request (id={}):'.format(req.pkt.id), req.pkt.payload)
    req.reply('No path found. Try again later')


def oncancel(id):
    print('Cancel req:', id)


print('Listening for 60 sec')
server = a0.RpcServer('navigate', onrequest, oncancel)
time.sleep(60)
print('Done!')