示例#1
0
    def test_no_subscriptions(self):
        adapter = StompAdapterImpl(Reactor(), defaultdict(list), {})
        dispatcher = AsyncDispatcher(FakeConnection(adapter), adapter)

        frame1 = Frame(
            Command.SUBSCRIBE, {
                Headers.DESTINATION: 'jms.queue.events',
                'ack': 'auto',
                'id': 'ad052acb-a934-4e10-8ec3-00c7417ef8d1'
            })

        frame2 = Frame(
            Command.SUBSCRIBE, {
                Headers.DESTINATION: 'jms.queue.events',
                'ack': 'auto',
                'id': 'ad052acb-a934-4e10-8ec3-00c7417ef8d2'
            })

        destinations = defaultdict(list)

        adapter = StompAdapterImpl(Reactor(), destinations, {})
        adapter.handle_frame(dispatcher, frame1)
        adapter.handle_frame(dispatcher, frame2)

        adapter.handle_timeout(dispatcher)

        self.assertEqual(len(adapter._sub_ids), 0)
        self.assertEqual(len(destinations), 0)
示例#2
0
def test_parsing_frame_with_headers(headers):
    parser = Parser()
    frame = Frame(Command.CONNECT, headers)
    parser.parse(frame.encode())
    parsed_frame = parser.pop_frame()

    assert parsed_frame.command == Command.CONNECT
    assert parsed_frame.headers == headers
    assert parsed_frame.body == b""
示例#3
0
def test_frame_should_have_a_copy_method():
    original = Frame(Command.SEND, {"abc": "def"}, "zorro")
    original_encoded = original.encode()

    copy = original.copy()
    copy.command = Command.CONNECT
    copy.body = "batman"
    copy.headers["geh"] = "xyz"

    assert original.encode() == original_encoded
示例#4
0
def test_parsing_frame_with_headers_and_body(body):
    parser = Parser()
    frame = Frame(Command.CONNECT, {"abc": "def"}, body)
    parser.parse(frame.encode())
    parsed_frame = parser.pop_frame()

    assert parsed_frame.command == Command.CONNECT
    assert "abc" in parsed_frame.headers
    assert parsed_frame.headers["abc"] == "def"
    assert "content-length" in parsed_frame.headers
    assert int(parsed_frame.headers["content-length"]) == len(body)
    assert parsed_frame.body == body
示例#5
0
def test_parser_should_accept_frames_with_crlf_eols():
    parser = Parser()
    frame = Frame(Command.CONNECT, {"abc": "def"}, b"zorro")
    encoded_frame = frame.encode().replace(b"\n", b"\r\n")
    parser.parse(encoded_frame)
    parsed_frame = parser.pop_frame()

    assert parsed_frame.command == Command.CONNECT
    assert "abc" in parsed_frame.headers
    assert parsed_frame.headers["abc"] == "def"
    assert "content-length" in parsed_frame.headers
    assert int(parsed_frame.headers["content-length"]) == 5
    assert parsed_frame.body == b"zorro"
示例#6
0
def test_parsing_multiple_frames_with_headers_and_body():
    parser = Parser()
    frame = Frame(Command.CONNECT, {"abc": "def"}, b"zorro")
    parser.parse(frame.encode() * 2)

    for _ in range(2):
        parsed_frame = parser.pop_frame()

        assert parsed_frame.command == Command.CONNECT
        assert "abc" in parsed_frame.headers
        assert parsed_frame.headers["abc"] == "def"
        assert "content-length" in parsed_frame.headers
        assert int(parsed_frame.headers["content-length"]) == len(b"zorro")
        assert parsed_frame.body == b"zorro"
示例#7
0
    def subscribe(self,
                  destination,
                  ack=None,
                  sub_id=None,
                  message_handler=None):
        if ack is None:
            ack = AckMode.AUTO

        if message_handler is None:
            message_handler = lambda sub, frame: None

        if sub_id is None:
            sub_id = str(uuid4())

        self.queue_frame(
            Frame(Command.SUBSCRIBE, {
                "destination": destination,
                "ack": ack,
                "id": sub_id
            }))

        sub = Subscription(self, destination, sub_id, ack, message_handler)
        self._subscriptions[sub_id] = sub

        return sub
示例#8
0
    def test_send_internal_and_broker(self):
        frame = Frame(command=Command.SEND,
                      headers={Headers.DESTINATION: 'jms.topic.vdsm_requests',
                               Headers.REPLY_TO: 'jms.topic.vdsm_responses',
                               Headers.CONTENT_LENGTH: '103'},
                      body=('{"jsonrpc":"2.0","method":"Host.getAllVmStats",'
                            '"params":{},"id":"e8a936a6-d886-4cfa-97b9-2d54209'
                            '053ff"}'
                            )
                      )

        ids = {}

        subscription = FakeSubscription('jms.topic.vdsm_requests',
                                        'e8a936a6-d886-4cfa-97b9-2d54209053ff')
        client = FakeAsyncClient()
        subscription.set_client(client)

        destinations = defaultdict(list)
        destinations['jms.topic.vdsm_requests'].append(subscription)

        adapter = StompAdapterImpl(Reactor(), destinations, ids)
        adapter.handle_frame(FakeAsyncDispatcher(adapter), frame)

        data = adapter.pop_message()
        self.assertIsNot(data, None)
        request = JsonRpcRequest.decode(data)
        self.assertEqual(request.method, 'Host.getAllVmStats')
        self.assertEqual(len(ids), 1)

        resp_frame = client.pop_message()
        self.assertIsNot(resp_frame, None)
        self.assertEqual(resp_frame.command, Command.MESSAGE)
        self.assertEqual(resp_frame.body, data)
    def test_handle_read(self):
        frame_handler = FakeFrameHandler()
        headers = {Headers.CONTENT_LENGTH: '78',
                   Headers.DESTINATION: 'jms.topic.vdsm_responses',
                   Headers.CONTENT_TYPE: 'application/json',
                   Headers.SUBSCRIPTION: 'ad052acb-a934-4e10-8ec3-00c7417ef8d'}
        body = ('{"jsonrpc": "2.0", "id": "e8a936a6-d886-4cfa-97b9-2d54209053f'
                'f", "result": []}')
        frame = Frame(command=Command.MESSAGE, headers=headers, body=body)
        dispatcher = AsyncDispatcher(FakeConnection(), frame_handler)
        dispatcher.handle_read(FakeAsyncDispatcher(None, data=frame.encode()))

        self.assertTrue(frame_handler.has_outgoing_messages)
        recv_frame = frame_handler.pop_message()
        self.assertEqual(Command.MESSAGE, recv_frame.command)
        self.assertEqual(body, recv_frame.body)
示例#10
0
 def unsubscribe(self, sub):
     try:
         del self._subscriptions[sub.id]
     except KeyError:
         self.log.warning('No subscription with %s id', sub.id)
     else:
         self.queue_frame(Frame(Command.UNSUBSCRIBE, {"id": sub.id}))
    def test_handle_read(self):
        frame_handler = TestFrameHandler()
        headers = {Headers.CONTENT_LENGTH: '78',
                   Headers.DESTINATION: 'jms.topic.vdsm_responses',
                   Headers.CONTENT_TYPE: 'application/json',
                   Headers.SUBSCRIPTION: 'ad052acb-a934-4e10-8ec3-00c7417ef8d'}
        body = ('{"jsonrpc": "2.0", "id": "e8a936a6-d886-4cfa-97b9-2d54209053f'
                'f", "result": []}')
        frame = Frame(command=Command.MESSAGE, headers=headers, body=body)
        dispatcher = AsyncDispatcher(TestConnection(), frame_handler)

        dispatcher.handle_read(TestDispatcher(frame.encode()))

        self.assertTrue(frame_handler.has_outgoing_messages)
        recv_frame = frame_handler.pop_message()
        self.assertEquals(Command.MESSAGE, recv_frame.command)
        self.assertEquals(body, recv_frame.body)
示例#12
0
    def test_receive_connected(self):
        client = AsyncClient()
        frame = Frame(Command.CONNECTED,
                      {'version': '1.2', Headers.HEARTBEAT: '8000,0'})

        client.handle_frame(None, frame)

        self.assertTrue(client.connected)
示例#13
0
def test_parsing_simple_frame(command):
    parser = Parser()
    parser.parse(Frame(command).encode())
    parsed_frame = parser.pop_frame()

    assert parsed_frame.command == command
    assert parsed_frame.headers == {}
    assert parsed_frame.body == b""
示例#14
0
    def test_send_no_destination(self):
        frame = Frame(Command.SEND, {Headers.DESTINATION: 'jms.topic.unknown'})

        adapter = StompAdapterImpl(Reactor(), defaultdict(list), {})
        adapter.handle_frame(FakeAsyncDispatcher(adapter), frame)

        resp_frame = adapter.pop_message()
        self.assertEqual(resp_frame.command, Command.ERROR)
        self.assertEqual(resp_frame.body, 'Subscription not available')
示例#15
0
    def test_unsuported_version(self):
        frame = Frame(Command.CONNECT, {Headers.ACCEPT_VERSION: '1.0'})

        adapter = StompAdapterImpl(Reactor(), defaultdict(list), {})
        adapter.handle_frame(FakeAsyncDispatcher(adapter), frame)

        resp_frame = adapter.pop_message()
        self.assertEqual(resp_frame.command, Command.ERROR)
        self.assertEqual(resp_frame.body, 'Version unsupported')
示例#16
0
    def test_no_id(self):
        frame = Frame(Command.UNSUBSCRIBE)

        adapter = StompAdapterImpl(Reactor(), defaultdict(list), {})
        adapter.handle_frame(FakeAsyncDispatcher(adapter), frame)

        resp_frame = adapter.pop_message()
        self.assertEqual(resp_frame.command, Command.ERROR)
        self.assertEqual(resp_frame.body, b'Missing id header')
示例#17
0
    def test_no_headers(self):
        frame = Frame(Command.CONNECT)

        adapter = StompAdapterImpl(Reactor(), defaultdict(list), {})
        adapter.handle_frame(FakeAsyncDispatcher(adapter), frame)

        resp_frame = adapter.pop_message()
        self.assertEqual(resp_frame.command, Command.ERROR)
        self.assertEqual(resp_frame.body, b'Version unsupported')
示例#18
0
    def _process_disconnect(self, frame, dispatcher):
        r_id = frame.headers[Headers.RECEIPT]
        if not r_id:
            self.log.debug("No receipt id for disconnect frame")
            # it is not mandatory to send receipt frame
            return

        headers = {Headers.RECEIPT_ID: r_id}
        self.queue_frame(Frame(Command.RECEIPT, headers))
示例#19
0
def test_handle_read():
    frame_handler = FakeFrameHandler()
    headers = {Headers.CONTENT_LENGTH: '78',
               Headers.DESTINATION: 'jms.topic.vdsm_responses',
               Headers.CONTENT_TYPE: 'application/json',
               Headers.SUBSCRIPTION: 'ad052acb-a934-4e10-8ec3-00c7417ef8d'}
    body = json.dumps({
        "jsonrpc": "2.0",
        "id": "e8a936a6-d886-4cfa-97b9-2d54209053ff",
        "result": [],
    }).encode("utf-8")
    frame = Frame(command=Command.MESSAGE, headers=headers, body=body)
    dispatcher = AsyncDispatcher(FakeConnection(), frame_handler)
    dispatcher.handle_read(FakeAsyncDispatcher(None, data=frame.encode()))

    assert frame_handler.has_outgoing_messages
    recv_frame = frame_handler.pop_message()
    assert Command.MESSAGE == recv_frame.command
    assert body == recv_frame.body
示例#20
0
    def test_no_heartbeat(self):
        frame = Frame(Command.CONNECT, {Headers.ACCEPT_VERSION: '1.2'})

        adapter = StompAdapterImpl(Reactor(), defaultdict(list), {})
        adapter.handle_frame(FakeAsyncDispatcher(adapter), frame)

        resp_frame = adapter.pop_message()
        self.assertEqual(resp_frame.command, Command.CONNECTED)
        self.assertEqual(resp_frame.headers['version'], '1.2')
        self.assertEqual(resp_frame.headers[Headers.HEARTBEAT], '0,0')
示例#21
0
def test_parser_should_skip_heartbeat_frames():
    parser = Parser()
    heartbeats = b"\n\n\n\n\n"
    encoded_frame = Frame(Command.CONNECT).encode()

    parser.parse(heartbeats + encoded_frame)
    assert parser.pending == 1

    decoded_frame = parser.pop_frame()
    assert decoded_frame is not None
    assert decoded_frame.command == Command.CONNECT
示例#22
0
    def test_connect(self):
        frame = Frame(Command.CONNECT,
                      {Headers.ACCEPT_VERSION: '1.2',
                       Headers.HEARTEBEAT: '0,8000'})

        adapter = StompAdapterImpl(Reactor(), defaultdict(list), {})
        adapter.handle_frame(TestDispatcher(adapter), frame)

        resp_frame = adapter.pop_message()
        self.assertEquals(resp_frame.command, Command.CONNECTED)
        self.assertEquals(resp_frame.headers['version'], '1.2')
        self.assertEquals(resp_frame.headers[Headers.HEARTEBEAT], '8000,0')
示例#23
0
    def test_no_id(self):
        frame = Frame(Command.SUBSCRIBE,
                      {'ack': 'auto',
                       Headers.DESTINATION: 'jms.queue.events'})

        adapter = StompAdapterImpl(Reactor(), defaultdict(list), {})
        adapter.handle_frame(FakeAsyncDispatcher(adapter), frame)

        resp_frame = adapter.pop_message()
        self.assertEqual(resp_frame.command, Command.ERROR)
        self.assertEqual(resp_frame.body,
                         b'Missing destination or subscription id header')
示例#24
0
    def test_no_destination(self):
        frame = Frame(Command.SUBSCRIBE,
                      {'ack': 'auto',
                       'id': 'ad052acb-a934-4e10-8ec3-00c7417ef8d1'})

        adapter = StompAdapterImpl(Reactor(), defaultdict(list), {})
        adapter.handle_frame(FakeAsyncDispatcher(adapter), frame)

        resp_frame = adapter.pop_message()
        self.assertEqual(resp_frame.command, Command.ERROR)
        self.assertEqual(resp_frame.body,
                         b'Missing destination or subscription id header')
示例#25
0
    def test_incoming_heartbeat(self):
        frame = Frame(Command.CONNECT,
                      {Headers.ACCEPT_VERSION: '1.2',
                       Headers.HEARTBEAT: '6000,5000'})

        adapter = StompAdapterImpl(Reactor(), defaultdict(list), {})
        dispatcher = AsyncDispatcher(FakeConnection(adapter), adapter)
        adapter.handle_frame(dispatcher, frame)

        resp_frame = adapter.pop_message()
        self.assertEqual(resp_frame.command, Command.CONNECTED)
        self.assertEqual(resp_frame.headers['version'], '1.2')
        self.assertEqual(resp_frame.headers[Headers.HEARTBEAT], '5000,6000')
        self.assertEqual(dispatcher._incoming_heartbeat_in_milis, 6000)
        self.assertEqual(dispatcher._outgoing_heartbeat_in_milis, 5000)
示例#26
0
    def test_unsubscribe(self):
        frame = Frame(Command.UNSUBSCRIBE,
                      {'id': 'ad052acb-a934-4e10-8ec3-00c7417ef8d1'})

        subscription = FakeSubscription('jms.queue.events',
                                        'ad052acb-a934-4e10-8ec3-00c7417ef8d1')

        destinations = defaultdict(list)
        destinations['jms.queue.events'].append(subscription)

        adapter = StompAdapterImpl(Reactor(), destinations, {})
        adapter._sub_ids['ad052acb-a934-4e10-8ec3-00c7417ef8d1'] = subscription
        adapter.handle_frame(FakeAsyncDispatcher(adapter), frame)

        self.assertEqual(len(adapter._sub_ids), 0)
        self.assertEqual(len(destinations), 0)
示例#27
0
    def test_subscribe(self):
        frame = Frame(Command.SUBSCRIBE,
                      {Headers.DESTINATION: 'jms.queue.events',
                       'ack': 'auto',
                       'id': 'ad052acb-a934-4e10-8ec3-00c7417ef8d1'})

        destinations = defaultdict(list)

        adapter = StompAdapterImpl(Reactor(), destinations, {})
        adapter.handle_frame(FakeAsyncDispatcher(adapter), frame)

        subscription = destinations['jms.queue.events'][0]
        self.assertEqual(subscription.id,
                         'ad052acb-a934-4e10-8ec3-00c7417ef8d1')
        self.assertEqual(subscription.destination,
                         'jms.queue.events')
示例#28
0
    def handle_connect(self):
        self._outbox.clear()
        outgoing_heartbeat = \
            int(self._outgoing_heartbeat * (1 + GRACE_PERIOD_FACTOR))
        incoming_heartbeat = \
            int(self._incoming_heartbeat * (1 - GRACE_PERIOD_FACTOR))

        self._outbox.appendleft(
            Frame(
                Command.CONNECT, {
                    Headers.ACCEPT_VERSION:
                    "1.2",
                    Headers.HEARTBEAT:
                    "%d,%d" % (outgoing_heartbeat, incoming_heartbeat),
                }))
        self.restore_subscriptions()
示例#29
0
    def test_handle_write(self):
        headers = {Headers.CONTENT_LENGTH: '78',
                   Headers.DESTINATION: 'jms.topic.vdsm_responses',
                   Headers.CONTENT_TYPE: 'application/json',
                   Headers.SUBSCRIPTION: 'ad052acb-a934-4e10-8ec3-00c7417ef8d'}
        body = ('{"jsonrpc": "2.0", "id": "e8a936a6-d886-4cfa-97b9-2d54209053f'
                'f", "result": []}')
        frame = Frame(command=Command.MESSAGE, headers=headers, body=body)
        frame_handler = FakeFrameHandler()
        frame_handler.handle_frame(None, frame)

        dispatcher = AsyncDispatcher(FakeConnection(), frame_handler)
        self.assertTrue(dispatcher.writable(None))

        dispatcher.handle_write(FakeAsyncDispatcher(''))
        self.assertFalse(frame_handler.has_outgoing_messages)
示例#30
0
    def test_no_flow_header(self):
        frame = Frame(command=Command.SEND,
                      headers={Headers.DESTINATION: SUBSCRIPTION_ID_REQUEST,
                               Headers.REPLY_TO: 'jms.topic.vdsm_responses',
                               Headers.CONTENT_LENGTH: '103'},
                      body=('{"jsonrpc":"2.0","method":"Host.getAllVmStats",'
                            '"params":{},"id":"e8a936a6-d886-4cfa-97b9-2d54209'
                            '053ff"}'
                            )
                      )

        adapter = StompAdapterImpl(Reactor(), defaultdict(list), {})
        dispatcher = FakeAsyncDispatcher(adapter)
        adapter.handle_frame(dispatcher, frame)

        self.assertIsNone(dispatcher.connection.flow_id)
示例#31
0
    def test_send_broker_parent_topic(self):
        frame = Frame(command=Command.SEND,
                      headers={Headers.DESTINATION:
                               'jms.topic.vdsm_requests.getAllVmStats',
                               Headers.REPLY_TO:
                               'jms.topic.vdsm_responses.getAllVmStats',
                               Headers.CONTENT_LENGTH: '103'},
                      body=('{"jsonrpc":"2.0","method":"Host.getAllVmStats",'
                            '"params":{},"id":"e8a936a6-d886-4cfa-97b9-2d54209'
                            '053ff"}'
                            )
                      )

        ids = {}

        subscription = TestSubscription('jms.topic.vdsm_requests',
                                        'e8a936a6-d886-4cfa-97b9-2d54209053ff')
        client = TestClient()
        subscription.set_client(client)

        destinations = defaultdict(list)
        destinations['jms'].append(subscription)
        destinations['jms.topic'].append(subscription)
        destinations['jms.topic.vdsm_requests'].append(subscription)

        # Topics that should not match
        destinations['jms.other'].append(subscription)
        destinations['jms.top'].append(subscription)

        adapter = StompAdapterImpl(Reactor(), destinations, ids)
        adapter.handle_frame(TestDispatcher(adapter), frame)

        data = adapter.pop_message()
        self.assertIsNot(data, None)
        request = JsonRpcRequest.decode(data)
        self.assertEqual(request.method, 'Host.getAllVmStats')
        self.assertEqual(len(ids), 1)

        for i in range(3):
            resp_frame = client.pop_message()
            self.assertIsNot(resp_frame, None)
            self.assertEqual(resp_frame.command, Command.MESSAGE)
            self.assertEqual(resp_frame.body, data)

        # The last two subscriptions do not match
        self.assertTrue(client.empty())