async def test_pub(sandbox): await sandbox.WaitUntilStartedAsync(timeout=1.0) async with aiohttp.ClientSession() as session: endpoint = "http://localhost:24880/api/pub" pub_data = { "container": "aaa", "topic": "bbb", "packet": { "payload": base64.b64encode(b"Hello, World!").decode("utf-8"), }, } # Normal publish. async with session.post(endpoint, data=json.dumps(pub_data)) as resp: assert resp.status == 200 assert await resp.text() == "success" # Normal publish. pub_data["packet"]["payload"] = base64.b64encode( b"Goodbye, World!").decode("utf-8") async with session.post(endpoint, data=json.dumps(pub_data)) as resp: assert resp.status == 200 assert await resp.text() == "success" # Missing "container". pub_data.pop("container") async with session.post(endpoint, data=json.dumps(pub_data)) as resp: assert resp.status == 400 assert await resp.text() == "Missing required 'container' field." pub_data["container"] = "aaa" # Missing "topic". pub_data.pop("topic") async with session.post(endpoint, data=json.dumps(pub_data)) as resp: assert resp.status == 400 assert await resp.text() == "Missing required 'topic' field." pub_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." tm = a0.TopicManager({"container": "aaa"}) sub = a0.SubscriberSync(tm.publisher_topic("bbb"), a0.INIT_OLDEST, a0.ITER_NEXT) msgs = [] while sub.has_next(): msgs.append(sub.next().payload) assert len(msgs) == 2 assert msgs == [b"Hello, World!", b"Goodbye, World!"]
def start(self): assert not self.api_proc api_ready = a0.SubscriberSync("api_ready") self.api_proc = subprocess.Popen( [ "valgrind", "--leak-check=full", "--error-exitcode=125", "bin/api" ], env=os.environ.copy(), ) api_ready.read_blocking(timeout=10)
def test_pubsub(): a0.File.remove("foo.pubsub.a0") assert not os.path.exists("/dev/shm/alephzero/foo.pubsub.a0") p = a0.Publisher("foo") ss = a0.SubscriberSync("foo", a0.INIT_OLDEST) assert os.path.exists("/dev/shm/alephzero/foo.pubsub.a0") cv = threading.Condition() class State: payloads = [] def callback(pkt): with cv: State.payloads.append(pkt.payload) cv.notify() s = a0.Subscriber("foo", a0.INIT_OLDEST, callback) assert not ss.can_read() p.pub("hello") assert ss.can_read() pkt = ss.read() assert pkt.payload == b"hello" assert sorted(k for k, _ in pkt.headers) == [ "a0_time_mono", "a0_time_wall", "a0_transport_seq", "a0_writer_id", "a0_writer_seq", ] assert not ss.can_read() p.pub(a0.Packet([("key", "val")], "world")) pkt = ss.read() assert pkt.payload == b"world" assert sorted(k for k, _ in pkt.headers) == [ "a0_time_mono", "a0_time_wall", "a0_transport_seq", "a0_writer_id", "a0_writer_seq", "key", ] with cv: cv.wait_for(lambda: len(State.payloads) == 2) assert State.payloads == [b"hello", b"world"] def sleep_write(timeout, pkt): time.sleep(timeout) p.pub(pkt) t = threading.Thread(target=sleep_write, args=(0.1, b"post_sleep")) t.start() assert ss.read_blocking().payload == b"post_sleep" t.join() t = threading.Thread(target=sleep_write, args=(0.1, b"post_sleep")) t.start() assert ss.read_blocking(timeout=0.2).payload == b"post_sleep" t.join() t = threading.Thread(target=sleep_write, args=(0.2, b"post_sleep")) t.start() with pytest.raises(RuntimeError, match="Connection timed out"): ss.read_blocking(timeout=a0.TimeMono.now() + 0.1) t.join()
import a0 a0.InitGlobalTopicManager('''{ "container": "controller", "subscriber_maps": { "where_am_I": { "container": "localizer", "topic": "location" } } }''') sub = a0.SubscriberSync('where_am_I', a0.INIT_OLDEST, a0.ITER_NEXT) print('Starting iteration') while sub.has_next(): print('I am', sub.next().payload) print('Done!')
async def test_ws_pub(sandbox): await sandbox.WaitUntilStartedAsync(timeout=1.0) async with aiohttp.ClientSession() as session: endpoint = "ws://localhost:24880/wsapi/pub" #################### # Basic test case. # #################### handshake_data = { "container": "aaa", "topic": "bbb", } ws = await session.ws_connect(endpoint) await ws.send_str(json.dumps(handshake_data)) async def send_payload(payload): payload_utf8 = payload.encode("utf-8") payload_b64 = base64.b64encode(payload_utf8).decode("utf-8") await ws.send_str(json.dumps({"packet": {"payload": payload_b64}})) await asyncio.gather( send_payload("message_0"), send_payload("message_1"), send_payload("message_2"), ) await asyncio.sleep(0.1) tm = a0.TopicManager({"container": "aaa"}) sub = a0.SubscriberSync(tm.publisher_topic("bbb"), a0.INIT_OLDEST, a0.ITER_NEXT) msgs = set() while sub.has_next(): msgs.add(sub.next().payload) assert len(msgs) == 3 assert msgs == set([b"message_0", b"message_1", b"message_2"]) await ws.close() ################## # Bad handshake. # ################## # Not JSON. ws = await session.ws_connect(endpoint) await ws.send_str("not json") reply = await ws.receive() assert reply.type in [ aiohttp.WSMsgType.CLOSE, aiohttp.WSMsgType.CLOSED ] assert reply.extra == "Message must be json." assert ws.closed # Not JSON object. ws = await session.ws_connect(endpoint) await ws.send_str(json.dumps("not object")) reply = await ws.receive() assert reply.type in [ aiohttp.WSMsgType.CLOSE, aiohttp.WSMsgType.CLOSED ] assert reply.extra == "Message must be a json object." assert ws.closed # Missing "container". ws = await session.ws_connect(endpoint) await ws.send_str(json.dumps({"foo": "bar"})) reply = await ws.receive() assert reply.type in [ aiohttp.WSMsgType.CLOSE, aiohttp.WSMsgType.CLOSED ] assert reply.extra == "Missing required 'container' field." assert ws.closed # Missing "topic". ws = await session.ws_connect(endpoint) await ws.send_str(json.dumps({"container": "aaa"})) reply = await ws.receive() assert reply.type in [ aiohttp.WSMsgType.CLOSE, aiohttp.WSMsgType.CLOSED ] assert reply.extra == "Missing required 'topic' field." assert ws.closed ############### # Bad packet. # ############### # Not JSON. ws = await session.ws_connect(endpoint) await ws.send_str(json.dumps(handshake_data)) await ws.send_str("not json") reply = await ws.receive() assert reply.type in [ aiohttp.WSMsgType.CLOSE, aiohttp.WSMsgType.CLOSED ] assert reply.extra == "Message must be json." assert ws.closed # Not JSON object. ws = await session.ws_connect(endpoint) await ws.send_str(json.dumps(handshake_data)) await ws.send_str(json.dumps("not object")) reply = await ws.receive() assert reply.type in [ aiohttp.WSMsgType.CLOSE, aiohttp.WSMsgType.CLOSED ] assert reply.extra == "Message must be a json object." assert ws.closed
def test_pub(sandbox): endpoint = f"http://localhost:{os.environ['PORT_STR']}/api/pub" pub_data = { "topic": "mytopic", "packet": { "headers": [ ["xyz", "123"], ["zzz", "www"], ], "payload": "Hello, World!", }, } # Normal publish. resp = requests.post(endpoint, data=json.dumps(pub_data)) assert resp.status_code == 200 assert resp.text == "success" # Base64 request_encoding. pub_data["request_encoding"] = "base64" pub_data["packet"]["payload"] = btoa("Goodbye, World!") resp = requests.post(endpoint, data=json.dumps(pub_data)) assert resp.status_code == 200 assert resp.text == "success" pub_data["packet"]["payload"] = "Hello, World!" pub_data.pop("request_encoding") # Missing "topic". pub_data.pop("topic") resp = requests.post(endpoint, data=json.dumps(pub_data)) assert resp.status_code == 400 assert resp.text == "Request missing required field: topic" pub_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." sub = a0.SubscriberSync("mytopic", a0.INIT_OLDEST) hdrs = [] msgs = [] while sub.can_read(): pkt = sub.read() hdrs.append(list(pkt.headers)) # Inspect copies of headers. msgs.append(pkt.payload) assert len(hdrs) == 2 assert len(msgs) == 2 assert msgs == [b"Hello, World!", b"Goodbye, World!"] for hdr in hdrs: for expected in pub_data["packet"]["headers"]: hdr.remove(tuple(expected)) assert sorted([k for k, v in hdr]) == [ "a0_time_mono", "a0_time_wall", "a0_transport_seq", "a0_writer_id", "a0_writer_seq", ]
import a0 sub = a0.SubscriberSync("topic", a0.INIT_OLDEST) while sub.can_read(): pkt = sub.read() print(pkt.payload)
#!/usr/bin/env python # Copyright (c) Facebook, Inc. and its affiliates. # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. import time import a0 if __name__ == "__main__": s = a0.SubscriberSync("latest_robot_state", a0.INIT_MOST_RECENT) seconds = int(s.read().payload) time_diff = time.time() - seconds num_seconds_stale = 10 assert time_diff < num_seconds_stale