async def setUp(self) -> None: await super().setUp() self.feed_manager = FeedManager() self.server = WsServer(constants.LOCALHOST, 8005, self.feed_manager, self.gateway_node) self.ws_uri = f"ws://{constants.LOCALHOST}:8005" await self.server.start()
async def setUp(self) -> None: await super().setUp() self.feed_manager = FeedManager() self.server = IpcServer( "bxgateway.ipc", self.feed_manager, self.gateway_node ) self.ipc_path = self.server.ipc_path await self.server.start()
async def setUp(self) -> None: await super().setUp() self.gateway_node.NODE_TYPE = NodeType.INTERNAL_GATEWAY self.transaction_streamer_peer = OutboundPeerModel( "127.0.0.1", 8006, node_type=NodeType.INTERNAL_GATEWAY) self.feed_manager = FeedManager(self.gateway_node) self.server = IpcServer("bxgateway.ipc", self.feed_manager, self.gateway_node, Case.SNAKE) self.ipc_path = self.server.ipc_path await self.server.start()
class IpcServerTest(AbstractGatewayRpcIntegrationTest): @async_test async def setUp(self) -> None: await super().setUp() self.gateway_node.NODE_TYPE = NodeType.INTERNAL_GATEWAY self.transaction_streamer_peer = OutboundPeerModel( "127.0.0.1", 8006, node_type=NodeType.INTERNAL_GATEWAY) self.feed_manager = FeedManager(self.gateway_node) self.server = IpcServer("bxgateway.ipc", self.feed_manager, self.gateway_node, Case.SNAKE) self.ipc_path = self.server.ipc_path await self.server.start() def get_gateway_opts(self) -> GatewayOpts: super().get_gateway_opts() return gateway_helpers.get_gateway_opts( 8000, blockchain_protocol="Ethereum", account_model=self._account_model) async def request(self, req: BxJsonRpcRequest) -> JsonRpcResponse: async with websockets.unix_connect(self.ipc_path) as ws: await ws.send(req.to_jsons()) return JsonRpcResponse.from_jsons(await ws.recv()) @async_test async def test_startup(self): async with websockets.unix_connect(self.ipc_path) as _ws: await asyncio.sleep(0.01) self.assertEqual(1, len(self.server._connections)) connection = self.server._connections[0] self.assertFalse(connection.request_handler.done()) self.assertFalse(connection.publish_handler.done()) @async_test async def test_subscribe_and_unsubscribe(self): feed = TestFeed("foo") self.feed_manager.register_feed(feed) def publish(): feed.publish(1) feed.publish(2) feed.publish(3) async with websockets.unix_connect(self.ipc_path) as ws: asyncio.get_event_loop().call_later(0.1, publish) await ws.send( BxJsonRpcRequest("2", RpcRequestType.SUBSCRIBE, ["foo", {}]).to_jsons()) response = await ws.recv() parsed_response = JsonRpcResponse.from_jsons(response) self.assertEqual("2", parsed_response.id) self.assertIsNotNone("1", parsed_response.result) subscriber_id = parsed_response.result self._assert_notification(1, subscriber_id, await ws.recv()) self._assert_notification(2, subscriber_id, await ws.recv()) self._assert_notification(3, subscriber_id, await ws.recv()) await ws.send( BxJsonRpcRequest("3", RpcRequestType.UNSUBSCRIBE, [subscriber_id]).to_jsons()) response = await ws.recv() parsed_response = JsonRpcResponse.from_jsons(response) self.assertEqual("3", parsed_response.id) self.assertTrue(parsed_response.result) publish() with self.assertRaises(TimeoutError): await asyncio.wait_for(ws.recv(), 0.1) @async_test async def tearDown(self) -> None: await self.server.stop() @async_test async def test_blxr_tx(self): pass def _assert_notification(self, expected_result: Any, subscriber_id: str, message: str): parsed_notification = BxJsonRpcRequest.from_jsons(message) self.assertIsNone(parsed_notification.id) self.assertEqual(RpcRequestType.SUBSCRIBE, parsed_notification.method) self.assertEqual(subscriber_id, parsed_notification.params["subscription"]) self.assertEqual(expected_result, parsed_notification.params["result"])
class WsServerTest(AbstractGatewayRpcIntegrationTest): @async_test async def setUp(self) -> None: await super().setUp() self.feed_manager = FeedManager() self.server = WsServer(constants.LOCALHOST, 8005, self.feed_manager, self.gateway_node) self.ws_uri = f"ws://{constants.LOCALHOST}:8005" await self.server.start() def get_gateway_opts(self) -> GatewayOpts: super().get_gateway_opts() return gateway_helpers.get_gateway_opts(8000, ) async def request(self, req: BxJsonRpcRequest) -> JsonRpcResponse: async with websockets.connect(self.ws_uri) as ws: await ws.send(req.to_jsons()) return JsonRpcResponse.from_jsons(await ws.recv()) @async_test async def test_startup(self): async with websockets.connect(self.ws_uri) as _ws: await asyncio.sleep(0.01) self.assertEqual(1, len(self.server._connections)) connection = self.server._connections[0] self.assertFalse(connection.request_handler.done()) self.assertFalse(connection.publish_handler.done()) @async_test async def test_subscribe_and_unsubscribe(self): feed = TestFeed("foo") self.feed_manager.register_feed(feed) def publish(): feed.publish(1) feed.publish(2) feed.publish(3) async with websockets.connect(self.ws_uri) as ws: asyncio.get_event_loop().call_later(0.1, publish) await ws.send( BxJsonRpcRequest("2", RpcRequestType.SUBSCRIBE, ["foo", {}]).to_jsons()) response = await ws.recv() parsed_response = JsonRpcResponse.from_jsons(response) self.assertEqual("2", parsed_response.id) self.assertIsNotNone("1", parsed_response.result) subscriber_id = parsed_response.result self._assert_notification(1, subscriber_id, await ws.recv()) self._assert_notification(2, subscriber_id, await ws.recv()) self._assert_notification(3, subscriber_id, await ws.recv()) await ws.send( BxJsonRpcRequest("3", RpcRequestType.UNSUBSCRIBE, [subscriber_id]).to_jsons()) response = await ws.recv() parsed_response = JsonRpcResponse.from_jsons(response) self.assertEqual("3", parsed_response.id) self.assertTrue(parsed_response.result) publish() with self.assertRaises(TimeoutError): await asyncio.wait_for(ws.recv(), 0.1) @async_test async def tearDown(self) -> None: await self.server.stop() @async_test async def test_blxr_tx(self): pass def _assert_notification(self, expected_result: Any, subscriber_id: str, message: str): parsed_notification = BxJsonRpcRequest.from_jsons(message) self.assertIsNone(parsed_notification.id) self.assertEqual(RpcRequestType.SUBSCRIBE, parsed_notification.method) self.assertEqual(subscriber_id, parsed_notification.params["subscription"]) self.assertEqual(expected_result, parsed_notification.params["result"])
def setUp(self) -> None: self.gateway = MockGatewayNode(gateway_helpers.get_gateway_opts(8000)) self.feed_manager = FeedManager(self.gateway) self.rpc = SubscriptionRpcHandler(self.gateway, self.feed_manager, Case.SNAKE)
class FilterDslTest(AbstractTestCase): def setUp(self) -> None: self.gateway = MockGatewayNode(gateway_helpers.get_gateway_opts(8000)) self.feed_manager = FeedManager(self.gateway) self.rpc = SubscriptionRpcHandler(self.gateway, self.feed_manager, Case.SNAKE) @async_test async def test_subscribe_to_feed_with_filters(self): feed = TestFeed("bar") feed.FILTERS = ["field1", "field2"] self.feed_manager.register_feed(feed) subscribe_request1 = BxJsonRpcRequest( "1", RpcRequestType.SUBSCRIBE, ["bar", { "filters": { "AND": [{ "field1": ["bar"] }] } }], ) rpc_handler = self.rpc.get_request_handler(subscribe_request1) result = await rpc_handler.process_request() self.assertTrue(result) @async_test async def test_subscribe_to_feed_with_invalid_filters(self): feed = TestFeed("foo") feed.FILTERS = ["filter1", "OR", "filter2"] self.feed_manager.register_feed(feed) subscribe_request1 = BxJsonRpcRequest( "1", RpcRequestType.SUBSCRIBE, ["foo", { "filters": [{ "field1": [] }, "AND", { "field2": [] }] }], ) with self.assertRaises(RpcInvalidParams): rpc_handler = self.rpc.get_request_handler(subscribe_request1) await rpc_handler.process_request() subscribe_request2 = BxJsonRpcRequest( "1", RpcRequestType.SUBSCRIBE, ["foo", { "filters": [True, False, 1, 2] }]) with self.assertRaises(RpcInvalidParams): rpc_handler = self.rpc.get_request_handler(subscribe_request2) await rpc_handler.process_request() subscribe_request3 = BxJsonRpcRequest("1", RpcRequestType.SUBSCRIBE, ["foo", { "filters": "OR" }]) with self.assertRaises(RpcInvalidParams): rpc_handler = self.rpc.get_request_handler(subscribe_request3) await rpc_handler.process_request() subscribe_request4 = BxJsonRpcRequest( "1", RpcRequestType.SUBSCRIBE, [ "foo", { "filters": { "AND": [{ "field1": ["bar"] }, { "OR": { "field2": ["hi"] } }] } } ], ) with self.assertRaises(RpcInvalidParams): rpc_handler = self.rpc.get_request_handler(subscribe_request4) await rpc_handler.process_request()
class SubscriptionRpcHandlerTest(AbstractTestCase): def setUp(self) -> None: self.gateway = MockGatewayNode(gateway_helpers.get_gateway_opts(8000)) self.feed_manager = FeedManager() self.rpc = SubscriptionRpcHandler(self.gateway, self.feed_manager) @async_test async def test_help(self): print(await self.rpc.help()) @async_test async def test_subscribe_to_feed(self): feed = TestFeed("foo") self.feed_manager.register_feed(feed) subscribe_request = BxJsonRpcRequest("1", RpcRequestType.SUBSCRIBE, ["foo", {}]) rpc_handler = self.rpc.get_request_handler(subscribe_request) self.assertIsInstance(rpc_handler, SubscribeRpcRequest) result = await rpc_handler.process_request() self.assertIsNotNone(result.result) self.assertIsNone(result.error) subscriber_id = result.result self.assertEqual(1, self.feed_manager.feeds["foo"].subscriber_count()) self.assertEqual(1, len(self.rpc.subscriptions)) self.assertIn(subscriber_id, self.rpc.subscriptions) next_message_task: Future[BxJsonRpcRequest] = asyncio.ensure_future( self.rpc.get_next_subscribed_message()) await asyncio.sleep(0) self.assertFalse(next_message_task.done()) feed.publish("foobar") await asyncio.sleep(0) # publish to subscriber await asyncio.sleep(0) # subscriber publishes to queue self.assertTrue(next_message_task.done()) next_message = next_message_task.result() self.assertEqual("2.0", next_message.json_rpc_version) self.assertEqual(RpcRequestType.SUBSCRIBE, next_message.method) self.assertEqual(subscriber_id, next_message.params["subscription"]) self.assertEqual("foobar", next_message.params["result"]) @async_test async def test_subscribe_to_feed_validation(self): feed = TestFeed("foo") feed.FIELDS = ["field1", "field2", "field3"] self.feed_manager.register_feed(feed) subscribe_request = BxJsonRpcRequest( "1", RpcRequestType.SUBSCRIBE, ["foo", { "include": ["field1", "field4"] }]) with self.assertRaises(RpcInvalidParams): rpc_handler = self.rpc.get_request_handler(subscribe_request) await rpc_handler.process_request() @async_test async def test_subscribe_to_feed_with_filter(self): feed = TestFeed("foo") feed.FIELDS = ["field1", "field2", "field3"] self.feed_manager.register_feed(feed) subscribe_request = BxJsonRpcRequest( "1", RpcRequestType.SUBSCRIBE, ["foo", { "include": ["field1", "field2"] }]) rpc_handler = self.rpc.get_request_handler(subscribe_request) result = await rpc_handler.process_request() subscriber_id = result.result next_message_task: Future[BxJsonRpcRequest] = asyncio.ensure_future( self.rpc.get_next_subscribed_message()) feed.publish({"field1": "foo", "field2": "bar", "field3": "baz"}) await asyncio.sleep(0) # publish to subscriber await asyncio.sleep(0) # subscriber publishes to queue self.assertTrue(next_message_task.done()) next_message = next_message_task.result() self.assertEqual("2.0", next_message.json_rpc_version) self.assertEqual(RpcRequestType.SUBSCRIBE, next_message.method) self.assertEqual(subscriber_id, next_message.params["subscription"]) expected_result = { "field1": "foo", "field2": "bar", } self.assertEqual(expected_result, next_message.params["result"]) @async_test async def test_subscribe_to_multiple_feeds(self): feed1 = TestFeed("foo1") feed2 = TestFeed("foo2") feed3 = TestFeed("foo3") for feed in [feed1, feed2, feed3]: self.feed_manager.register_feed(feed) subscribe_requests = [ BxJsonRpcRequest("1", RpcRequestType.SUBSCRIBE, ["foo1", {}]), BxJsonRpcRequest("1", RpcRequestType.SUBSCRIBE, ["foo2", {}]), BxJsonRpcRequest("1", RpcRequestType.SUBSCRIBE, ["foo3", {}]) ] subscriber_ids = [] for subscribe_request in subscribe_requests: rpc_handler = self.rpc.get_request_handler(subscribe_request) result = await rpc_handler.process_request() subscriber_ids.append(result.result) next_message_task: Future[BxJsonRpcRequest] = asyncio.ensure_future( self.rpc.get_next_subscribed_message()) await asyncio.sleep(0) self.assertFalse(next_message_task.done()) feed2.publish("message 1") await asyncio.sleep(0) feed1.publish("message 2") await asyncio.sleep(0) feed2.publish("message 3") await asyncio.sleep(0) feed3.publish("message 4") await asyncio.sleep(0) self.assertTrue(next_message_task.done()) message_1 = next_message_task.result() self.assertEqual(subscriber_ids[1], message_1.params["subscription"]) self.assertEqual("message 1", message_1.params["result"]) message_2 = await self.rpc.get_next_subscribed_message() self.assertEqual(subscriber_ids[0], message_2.params["subscription"]) self.assertEqual("message 2", message_2.params["result"]) message_3 = await self.rpc.get_next_subscribed_message() self.assertEqual(subscriber_ids[1], message_3.params["subscription"]) self.assertEqual("message 3", message_3.params["result"]) message_4 = await self.rpc.get_next_subscribed_message() self.assertEqual(subscriber_ids[2], message_4.params["subscription"]) self.assertEqual("message 4", message_4.params["result"]) @async_test async def test_unsubscribe(self): feed = TestFeed("foo") self.feed_manager.register_feed(feed) subscribe_request = BxJsonRpcRequest("1", RpcRequestType.SUBSCRIBE, ["foo", {}]) rpc_handler = self.rpc.get_request_handler(subscribe_request) result = await rpc_handler.process_request() subscriber_id = result.result # message is received next_message_task: Future[BxJsonRpcRequest] = asyncio.ensure_future( self.rpc.get_next_subscribed_message()) await asyncio.sleep(0) self.assertFalse(next_message_task.done()) feed.publish("foobar") await asyncio.sleep(0) # publish to subscriber await asyncio.sleep(0) # subscriber publishes to queue self.assertTrue(next_message_task.done()) unsubscribe_request = BxJsonRpcRequest("1", RpcRequestType.UNSUBSCRIBE, [subscriber_id]) rpc_handler = self.rpc.get_request_handler(unsubscribe_request) result = await rpc_handler.process_request() self.assertTrue(result.result) next_message_task: Future[BxJsonRpcRequest] = asyncio.ensure_future( self.rpc.get_next_subscribed_message()) feed.publish("foobar_not_received") feed.publish("foobar_not_received_2") await asyncio.sleep(0) # publish to subscriber await asyncio.sleep(0) # subscriber publishes to queue self.assertFalse(next_message_task.done()) # no message self.assertEqual(0, len(self.rpc.subscriptions)) self.assertEqual(0, self.feed_manager.feeds["foo"].subscriber_count()) @async_test async def test_close_bad_subscribers(self): self.rpc.subscribed_messages = asyncio.Queue(5) close_listener = asyncio.create_task(self.rpc.wait_for_close()) feed1 = TestFeed("foo1") self.feed_manager.register_feed(feed1) rpc_request = BxJsonRpcRequest("1", RpcRequestType.SUBSCRIBE, ["foo1", {}]) await self.rpc.get_request_handler(rpc_request).process_request() for i in range(10): feed1.publish(i) await asyncio.sleep(0.1) self.assertTrue(self.rpc.disconnect_event.is_set()) self.assertTrue(close_listener.done()) @async_test async def tearDown(self) -> None: self.rpc.close()