Example #1
0
    async def setUp(self) -> None:
        pub_key = "a04f30a45aae413d0ca0f219b4dcb7049857bc3f91a6351288cce603a2c9646294a02b987bf6586b370b2c22d74662355677007a14238bb037aedf41c2d08866"
        opts = gateway_helpers.get_gateway_opts(
            8000,
            include_default_eth_args=True,
            pub_key=pub_key,
        )
        if opts.use_extensions:
            helpers.set_extensions_parallelism()
        node_ssl_service = MockNodeSSLService(EthGatewayNode.NODE_TYPE,
                                              MagicMock())
        self.node = EthGatewayNode(opts, node_ssl_service)
        self.feed_manager = FeedManager(self.node)
        self.node.feed_manager = self.feed_manager
        self.rpc = SubscriptionRpcHandler(self.node, self.feed_manager,
                                          Case.SNAKE)
        self.feed_name = NewTransactionFeed.NAME
        self.node.init_live_feeds()

        self.feed_service_model = FeedServiceModelBase(
            allow_filtering=True, available_fields=["all"])
        self.base_feed_service_model = BdnFeedServiceModelConfigBase(
            expire_date="2999-01-01", feed=self.feed_service_model)
        self.node.account_model = BdnAccountModelBase(
            account_id="account_id",
            certificate="",
            logical_account_name="test",
            new_transaction_streaming=self.base_feed_service_model,
        )
Example #2
0
 async def handle_connection(self, websocket: WebSocketServerProtocol,
                             path: str) -> None:
     logger.trace("Accepting new IPC connection...")
     connection = WsConnection(
         websocket, path,
         SubscriptionRpcHandler(self.node, self.feed_manager))
     self._connections.append(connection)
     await connection.handle()
     self._connections.remove(connection)
Example #3
0
    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)

        self.feed_service_model = FeedServiceModelBase(
            allow_filtering=True, available_fields=["all"])
        self.base_feed_service_model = BdnFeedServiceModelConfigBase(
            expire_date="2999-01-01", feed=self.feed_service_model)
        self.gateway.account_model = BdnAccountModelBase(
            account_id="account_id",
            certificate="",
            logical_account_name="test",
            new_transaction_streaming=self.base_feed_service_model,
        )
        self.gateway.account_model.get_feed_service_config_by_name = MagicMock(
            return_value=self.gateway.account_model.new_transaction_streaming)
Example #4
0
class FilterParsingTest(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)

        self.feed_service_model = FeedServiceModelBase(
            allow_filtering=True,
            available_fields=["all"]
        )
        self.base_feed_service_model = BdnFeedServiceModelConfigBase(
            expire_date="2999-01-01",
            feed=self.feed_service_model
        )
        self.gateway.account_model = BdnAccountModelBase(
            account_id="account_id",
            certificate="",
            logical_account_name="test",
            new_transaction_streaming=self.base_feed_service_model,
        )
        self.gateway.account_model.get_feed_service_config_by_name = MagicMock(
            return_value=self.gateway.account_model.new_transaction_streaming
        )

    @async_test
    async def test_subscribe_to_feed_with_filters_all(self):
        feed = TestFeed("bar")
        feed.FILTERS = ["field1", "field2"]

        self.feed_manager.register_feed(feed)
        subscribe_request1 = BxJsonRpcRequest(
            "1", RpcRequestType.SUBSCRIBE, ["bar", {"filters": "field1 == 2"}],
        )

        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_filters2(self):
        feed = TestFeed("bar")
        feed.FILTERS = ["to", "field2"]

        self.feed_manager.register_feed(feed)
        subscribe_request1 = BxJsonRpcRequest(
            "1", RpcRequestType.SUBSCRIBE, ["bar", {"filters": "to = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"}],
        )

        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", "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": {"a": 1}}]
        )
        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": "hello === r and i"}],
        )
        with self.assertRaises(RpcInvalidParams):
            rpc_handler = self.rpc.get_request_handler(subscribe_request4)
            await rpc_handler.process_request()

        subscribe_request4 = BxJsonRpcRequest(
            "1", RpcRequestType.SUBSCRIBE, ["foo", {"filters": "hello > 1"}],
        )
        with self.assertRaises(RpcInvalidParams):
            rpc_handler = self.rpc.get_request_handler(subscribe_request4)
            await rpc_handler.process_request()

    @async_test
    async def test_subscribe_to_feed_with_filtering_not_allowed(self):
        feed_service_model = FeedServiceModelBase(
            allow_filtering=False,
            available_fields=["all"]
        )
        base_feed_service_model = BdnFeedServiceModelConfigBase(
            expire_date="2999-01-01",
            feed=feed_service_model
        )
        self.gateway.account_model.new_transaction_streaming = base_feed_service_model

        self.gateway.account_model.get_feed_service_config_by_name = MagicMock(
            return_value=self.gateway.account_model.new_transaction_streaming
        )

        feed = TestFeed("bar")
        feed.FILTERS = ["to", "field2"]

        self.feed_manager.register_feed(feed)
        subscribe_request1 = BxJsonRpcRequest(
            "1", RpcRequestType.SUBSCRIBE, ["bar", {"filters": "to = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"}],
        )

        with self.assertRaises(RpcAccountIdError):
            rpc_handler = self.rpc.get_request_handler(subscribe_request1)
            await rpc_handler.process_request()

    @async_test
    async def test_filters1(self):
        t2 = "value > 5534673480000000000 or from = 0xbd4e113ee68bcbbf768ba1d6c7a14e003362979a"
        validator = filter_parsing.get_validator(t2)
        self.assertTrue(validator({"value": 6534673480000000000, "from": "a"}))
        self.assertFalse(validator({"value": 50, "from": "a"}))
        self.assertTrue(validator({"value": 50, "from": "0xbd4e113ee68bcbbf768ba1d6c7a14e003362979a"}))

    @async_test
    async def test_filters2(self):
        t2 = "from = 0xbd4e113ee68bcbbf768ba1d6c7a14e003362979a or value > 5534673480000000000"

        f = {"value": 1.3467348e+18, "to": "0xd7bec4d6bf6fc371eb51611a50540f0b59b5f896",
             "from": "0xbd4e113ee68bcbbf768ba1d6c7a14e003362979a"}
        validator = filter_parsing.get_validator(t2)
        self.assertTrue(validator({"value": 6534673480000000000, "from": "a"}))
        self.assertFalse(validator({"value": 50, "from": "a"}))
        self.assertTrue(validator({"value": 50, "from": "0xbd4e113ee68bcbbf768ba1d6c7a14e003362979a"}))
        self.assertTrue(validator(f))

    @async_test
    async def test_filters3(self):
        t3 = "value > 5534673480000000000 or (to = 0x3f5ce5fbfe3e9af3971dd833d26ba9b5c936f0be or to = 0xbd4e113ee68bcbbf768ba1d6c7a14e0033629792)"
        validator = filter_parsing.get_validator(t3)
        f = {"value": 1.3467348e+18, "to": "0x3f5ce5fbfe3e9af3971dd833d26ba9b5c936f0be",
             "from": "0xbd4e113ee68bcbbf768ba1d6c7a14e003362979a"}
        self.assertTrue(validator(f))

    @async_test
    async def test_filters4(self):
        t4 = "to = 0x1111111111111111111111111111111111111111 or to = aaaa"
        validator = filter_parsing.get_validator(t4)
        f = {"value": 1.3467348e+18, "to": "0x3f5ce5fbfe3e9af3971dd833d26ba9b5c936f0be",
             "from": "0xbd4e113ee68bcbbf768ba1d6c7a14e003362979a"}
        self.assertFalse(validator(f))

    @async_test
    async def test_filters5(self):
        t5 = "gas_price < 100"
        validator = filter_parsing.get_validator(t5)
        f = {"gas_price": 200}
        self.assertFalse(validator(f))

    @async_test
    async def test_filters6(self):
        t6 = "gas_price > 100"
        validator = filter_parsing.get_validator(t6)
        f = {"gas_price": 200}
        self.assertTrue(validator(f))
Example #5
0
class GatewaySubscribeRpcRequestTest(AbstractTestCase):
    @async_test
    async def setUp(self) -> None:
        pub_key = "a04f30a45aae413d0ca0f219b4dcb7049857bc3f91a6351288cce603a2c9646294a02b987bf6586b370b2c22d74662355677007a14238bb037aedf41c2d08866"
        opts = gateway_helpers.get_gateway_opts(
            8000,
            include_default_eth_args=True,
            pub_key=pub_key,
        )
        if opts.use_extensions:
            helpers.set_extensions_parallelism()
        node_ssl_service = MockNodeSSLService(EthGatewayNode.NODE_TYPE,
                                              MagicMock())
        self.node = EthGatewayNode(opts, node_ssl_service)
        self.feed_manager = FeedManager(self.node)
        self.node.feed_manager = self.feed_manager
        self.rpc = SubscriptionRpcHandler(self.node, self.feed_manager,
                                          Case.SNAKE)
        self.feed_name = NewTransactionFeed.NAME
        self.node.init_live_feeds()

        self.feed_service_model = FeedServiceModelBase(
            allow_filtering=True, available_fields=["all"])
        self.base_feed_service_model = BdnFeedServiceModelConfigBase(
            expire_date="2999-01-01", feed=self.feed_service_model)
        self.node.account_model = BdnAccountModelBase(
            account_id="account_id",
            certificate="",
            logical_account_name="test",
            new_transaction_streaming=self.base_feed_service_model,
        )

    @async_test
    async def tearDown(self) -> None:
        pass

    @async_test
    async def test_subscribe_to_feed_with_no_includes_specified(self):
        subscribe_request1 = BxJsonRpcRequest(
            "1",
            RpcRequestType.SUBSCRIBE,
            [self.feed_name, {}],
        )

        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_all_available_fields(self):
        subscribe_request1 = BxJsonRpcRequest(
            "1",
            RpcRequestType.SUBSCRIBE,
            [
                self.feed_name, {
                    "include": ["tx_hash", "tx_contents.gas_price"]
                }
            ],
        )

        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_specific_available_field(self):
        feed_service_model = FeedServiceModelBase(
            allow_filtering=True, available_fields=["tx_contents.nonce"])
        base_feed_service_model = BdnFeedServiceModelConfigBase(
            expire_date="2999-01-01", feed=feed_service_model)
        self.node.account_model.new_transaction_streaming = base_feed_service_model

        subscribe_request1 = BxJsonRpcRequest(
            "1",
            RpcRequestType.SUBSCRIBE,
            [self.feed_name, {
                "include": ["tx_contents.nonce"]
            }],
        )

        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_unavailable_field(self):
        feed_service_model = FeedServiceModelBase(
            allow_filtering=True,
            available_fields=["tx_hash", "tx_contents.nonce"])
        base_feed_service_model = BdnFeedServiceModelConfigBase(
            expire_date="2999-01-01", feed=feed_service_model)
        self.node.account_model.new_transaction_streaming = base_feed_service_model

        subscribe_request1 = BxJsonRpcRequest(
            "1",
            RpcRequestType.SUBSCRIBE,
            [
                self.feed_name, {
                    "include": ["tx_hash", "tx_contents.gas_price"]
                }
            ],
        )

        with self.assertRaises(RpcInvalidParams):
            rpc_handler = self.rpc.get_request_handler(subscribe_request1)
            await rpc_handler.process_request()

    @async_test
    async def test_subscribe_to_feed_with_feed_not_set_in_account(self):
        subscribe_request1 = BxJsonRpcRequest(
            "1",
            RpcRequestType.SUBSCRIBE,
            ["pendingTxs", {}],
        )

        with self.assertRaises(RpcAccountIdError):
            rpc_handler = self.rpc.get_request_handler(subscribe_request1)
            await rpc_handler.process_request()

    @async_test
    async def test_subscribe_to_feed_no_feed_service(self):
        # allow feed if service is not defined (old account)
        self.node.account_model.new_transaction_streaming = BdnFeedServiceModelConfigBase(
            expire_date="2999-01-01")

        subscribe_request1 = BxJsonRpcRequest(
            "1",
            RpcRequestType.SUBSCRIBE,
            [self.feed_name, {}],
        )
        subscribe_request2 = BxJsonRpcRequest(
            "1",
            RpcRequestType.SUBSCRIBE,
            [
                self.feed_name, {
                    "include": ["tx_hash", "tx_contents.gas_price"]
                }
            ],
        )

        rpc_handler = self.rpc.get_request_handler(subscribe_request1)
        result = await rpc_handler.process_request()
        self.assertTrue(result)
        rpc_handler = self.rpc.get_request_handler(subscribe_request2)
        result = await rpc_handler.process_request()
        self.assertTrue(result)
Example #6
0
 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)
Example #7
0
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.gateway)
        self.rpc = SubscriptionRpcHandler(self.gateway, self.feed_manager,
                                          Case.SNAKE)

    @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.get_feed(FeedKey("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_fields(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.get_feed(FeedKey("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()