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)
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_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')
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')
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')
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')
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')
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')
def start_acceptor(self, use_ssl, address='127.0.0.1'): self.reactor = Reactor() self.acceptor = MultiProtocolAcceptor( self.reactor, address, 0, sslctx=self.SSLCTX if use_ssl else None) self.acceptor.TIMEOUT = 1 self.acceptor.add_detector(Echo()) self.acceptor.add_detector(Uppercase()) self.acceptor_address = \ self.acceptor._acceptor.socket.getsockname()[0:2] t = threading.Thread(target=self.reactor.process_requests) t.deamon = True t.start()
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')
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')
def constructAcceptor(log, ssl, jsonBridge, dest=LEGACY_SUBSCRIPTION_ID_RESPONSE): sslctx = DEAFAULT_SSL_CONTEXT if ssl else None reactor = Reactor() acceptor = MultiProtocolAcceptor( reactor, "::1", 0, sslctx, ) scheduler = schedule.Scheduler(name="test.Scheduler", clock=utils.monotonic_time) scheduler.start() cif = FakeClientIf(dest) json_binding = BindingJsonRpc(jsonBridge, defaultdict(list), 60, scheduler, cif) json_binding.start() cif.json_binding = json_binding with namedTemporaryDir() as tmp_dir: client_log = os.path.join(tmp_dir, 'client.log') with MonkeyPatchScope([(API.clientIF, 'getInstance', lambda _: cif), (constants, 'P_VDSM_CLIENT_LOG', client_log)]): xml_binding = BindingXMLRPC(cif, cif.log) xml_binding.start() xmlDetector = XmlDetector(xml_binding) acceptor.add_detector(xmlDetector) jsonBridge.cif = cif stompDetector = StompDetector(json_binding) acceptor.add_detector(stompDetector) thread = threading.Thread(target=reactor.process_requests, name='Detector thread') thread.setDaemon(True) thread.start() try: yield acceptor finally: acceptor.stop() json_binding.stop() xml_binding.stop() scheduler.stop(wait=False)
def test_close(self): reactor = Reactor() thread = concurrent.thread(reactor.process_requests, name='test ractor') thread.start() s1, s2 = socket.socketpair() with closing(s2): disp = reactor.create_dispatcher(s1, impl=TestingImpl()) reactor.stop() thread.join(timeout=1) self.assertTrue(disp.closing) self.assertFalse(reactor._wakeupEvent.closing)
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)
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)
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)
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')
def __init__( self, host, port, sslctx=None, ssl_hanshake_timeout=SSLHandshakeDispatcher.SSL_HANDSHAKE_TIMEOUT, ): self._sslctx = sslctx self._reactor = Reactor() sock = _create_socket(host, port) self._host, self._port = sock.getsockname() self.log.info("Listening at %s:%d", self._host, self._port) self._acceptor = self._reactor.create_dispatcher( sock, _AcceptorImpl(self.handle_accept)) self._acceptor.listen(5) self._handlers = [] self.TIMEOUT = ssl_hanshake_timeout
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())
def listener(dummy_register_protocol_detector, key_cert_pair, request): key_file, cert_file = key_cert_pair reactor = Reactor() sslctx = SSLContext(cert_file=cert_file, key_file=key_file, ca_certs=cert_file) acceptor = MultiProtocolAcceptor(reactor, '127.0.0.1', 0, sslctx=sslctx) try: t = concurrent.thread(reactor.process_requests) t.start() (host, port) = acceptor._acceptor.socket.getsockname()[0:2] yield (host, port) finally: acceptor.stop() t.join()
def constructAcceptor(log, ssl, jsonBridge, dest=LEGACY_SUBSCRIPTION_ID_RESPONSE): sslctx = DEAFAULT_SSL_CONTEXT if ssl else None reactor = Reactor() acceptor = MultiProtocolAcceptor( reactor, "127.0.0.1", 0, sslctx, ) scheduler = schedule.Scheduler(name="test.Scheduler", clock=utils.monotonic_time) scheduler.start() json_binding = BindingJsonRpc(jsonBridge, defaultdict(list), 60, scheduler) json_binding.start() cif = FakeClientIf(json_binding, dest) xml_binding = BindingXMLRPC(cif, cif.log) xml_binding.start() xmlDetector = XmlDetector(xml_binding) acceptor.add_detector(xmlDetector) jsonBridge.cif = cif stompDetector = StompDetector(json_binding) acceptor.add_detector(stompDetector) thread = threading.Thread(target=reactor.process_requests, name='Detector thread') thread.setDaemon(True) thread.start() try: yield acceptor finally: acceptor.stop() json_binding.stop() xml_binding.stop() scheduler.stop(wait=False)
def constructAcceptor(log, ssl, jsonBridge, dest=SUBSCRIPTION_ID_RESPONSE): sslctx = DEAFAULT_SSL_CONTEXT if ssl else None reactor = Reactor() acceptor = MultiProtocolAcceptor( reactor, "::1" if ipv6_enabled() else "127.0.0.1", 0, sslctx, ) scheduler = schedule.Scheduler(name="test.Scheduler", clock=time.monotonic_time) scheduler.start() cif = FakeClientIf(dest) json_binding = BindingJsonRpc(jsonBridge, defaultdict(list), 60, scheduler, cif) json_binding.start() cif.json_binding = json_binding with MonkeyPatchScope([ (API.clientIF, 'getInstance', lambda _: cif), (API, 'confirm_connectivity', lambda: None) ]): jsonBridge.cif = cif stompDetector = StompDetector(json_binding) acceptor.add_detector(stompDetector) thread = threading.Thread(target=reactor.process_requests, name='Detector thread') thread.setDaemon(True) thread.start() try: yield acceptor finally: acceptor.stop() json_binding.stop() scheduler.stop(wait=False)
def listener(dummy_register_protocol_detector, request): reactor = Reactor() excludes = getattr(request, 'param', 0) sslctx = SSLContext(cert_file=CRT_FILE, key_file=KEY_FILE, ca_certs=CRT_FILE, excludes=excludes, protocol=CLIENT_PROTOCOL) acceptor = MultiProtocolAcceptor(reactor, '127.0.0.1', 0, sslctx=sslctx) try: t = concurrent.thread(reactor.process_requests) t.start() (host, port) = acceptor._acceptor.socket.getsockname()[0:2] yield (host, port) finally: acceptor.stop() t.join()
def test_multipe_subscriptions(self): frame = Frame(Command.UNSUBSCRIBE, {'id': 'ad052acb-a934-4e10-8ec3-00c7417ef8d1'}) subscription = FakeSubscription('jms.queue.events', 'ad052acb-a934-4e10-8ec3-00c7417ef8d1') subscription2 = FakeSubscription('jms.queue.events', 'e8a93a6-d886-4cfa-97b9-2d54209053ff') destinations = defaultdict(list) destinations['jms.queue.events'].append(subscription) destinations['jms.queue.events'].append(subscription2) 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), 1) self.assertEqual(destinations['jms.queue.events'], [subscription2])
def test_send_batch(self): body = ('[{"jsonrpc":"2.0","method":"Host.getAllVmStats","params":{},' '"id":"e8a936a6-d886-4cfa-97b9-2d54209053ff"},' '{"jsonrpc":"2.0","method":"Host.getAllVmStats","params":{},' '"id":"1202b274-5a06-4671-8b13-1d2715429668"}]') frame = Frame(command=Command.SEND, headers={Headers.DESTINATION: 'jms.topic.vdsm_requests', Headers.REPLY_TO: 'jms.topic.vdsm_responses', Headers.CONTENT_LENGTH: '209'}, body=body ) ids = {} adapter = StompAdapterImpl(Reactor(), defaultdict(list), ids) adapter.handle_frame(FakeAsyncDispatcher(adapter), frame) data = adapter.pop_message() self.assertIsNot(data, None) self.assertEqual(len(ids), 2)
def test_send(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 = {} adapter = StompAdapterImpl(Reactor(), defaultdict(list), 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)
def listen(self, excludes=0, protocol=CLIENT_PROTOCOL): reactor = Reactor() sslctx = SSLContext(cert_file=CRT_FILE, key_file=KEY_FILE, ca_certs=CRT_FILE, excludes=excludes, protocol=protocol) acceptor = MultiProtocolAcceptor(reactor, '127.0.0.1', 0, sslctx=sslctx) try: t = concurrent.thread(reactor.process_requests) t.start() yield self.get_address(acceptor) finally: acceptor.stop() t.join()
def test_send_broker(self): frame = Frame(command=Command.SEND, headers={Headers.DESTINATION: 'jms.topic.destination', Headers.CONTENT_LENGTH: '103'}, body=('{"jsonrpc":"2.0","method":"Host.getAllVmStats",' '"params":{},"id":"e8a936a6-d886-4cfa-97b9-2d54209' '053ff"}' ) ) subscription = FakeSubscription('jms.topic.destination', 'e8a936a6-d886-4cfa-97b9-2d54209053ff') destinations = defaultdict(list) destinations['jms.topic.destination'].append(subscription) adapter = StompAdapterImpl(Reactor(), destinations, {}) subscription.set_client(adapter) adapter.handle_frame(FakeAsyncDispatcher(adapter), frame) resp_frame = adapter.pop_message() self.assertEqual(resp_frame.command, Command.MESSAGE)
def _createAcceptor(self, host, port): sslctx = sslutils.create_ssl_context() self._reactor = Reactor() self._acceptor = MultiProtocolAcceptor(self._reactor, host, port, sslctx)