def test_01_unsolicited_response(self): """ Create a server that sends an immediate Request Timeout response without first waiting for a request to arrive. """ class UnsolicitedResponse(FakeHttpServerBase): def __init__(self, host, port): self.request_sent = False super(UnsolicitedResponse, self).__init__(host, port) def do_connect(self): self.conn.sendall(b'HTTP/1.1 408 Request Timeout\r\n' + b'Content-Length: 10\r\n' + b'\r\n' + b'Bad Server') self.request_sent = True count, error = http1_ping(self.http_server_port, self.http_listener_port) self.assertIsNone(error) self.assertEqual(1, count) server = UnsolicitedResponse('127.0.0.1', self.http_server_port) self.assertTrue(server.request_sent) count, error = http1_ping(self.http_server_port, self.http_listener_port) self.assertIsNone(error) self.assertEqual(1, count)
def test_01_mgmt(self): """ Create and delete HTTP1 connectors and listeners """ LISTENER_TYPE = 'org.apache.qpid.dispatch.httpListener' CONNECTOR_TYPE = 'org.apache.qpid.dispatch.httpConnector' CONNECTION_TYPE = 'org.apache.qpid.dispatch.connection' mgmt = self.router.management self.assertEqual(0, len(mgmt.query(type=LISTENER_TYPE).results)) self.assertEqual(0, len(mgmt.query(type=CONNECTOR_TYPE).results)) mgmt.create(type=CONNECTOR_TYPE, name="ServerConnector", attributes={ 'address': 'http1', 'port': self.http_server_port, 'protocolVersion': 'HTTP1' }) mgmt.create(type=LISTENER_TYPE, name="ClientListener", attributes={ 'address': 'http1', 'port': self.http_listener_port, 'protocolVersion': 'HTTP1' }) # verify the entities have been created and http traffic works self.assertEqual(1, len(mgmt.query(type=LISTENER_TYPE).results)) self.assertEqual(1, len(mgmt.query(type=CONNECTOR_TYPE).results)) count, error = http1_ping(sport=self.http_server_port, cport=self.http_listener_port) self.assertIsNone(error) self.assertEqual(1, count) # # delete the connector and wait for the associated connection to be # removed # mgmt.delete(type=CONNECTOR_TYPE, name="ServerConnector") self.assertEqual(0, len(mgmt.query(type=CONNECTOR_TYPE).results)) retry = 20 # 20 * 0.25 = 5 sec hconns = 0 while retry: obj = mgmt.query(type=CONNECTION_TYPE, attribute_names=["protocol"]) for item in obj.get_dicts(): if "http/1.x" in item["protocol"]: hconns += 1 if hconns == 0: break sleep(0.25) retry -= 1 hconns = 0 self.assertEqual(0, hconns, msg="HTTP connection not deleted") # When a connector is configured the router will periodically attempt # to connect to the server address. To prove that the connector has # been completely removed listen for connection attempts on the server # port. s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) s.bind(("", self.http_server_port)) s.setblocking(True) s.settimeout(3) # reconnect attempts every 2.5 seconds s.listen(1) with self.assertRaises(socket.timeout): conn, addr = s.accept() s.close() # # re-create the connector and verify it works # mgmt.create(type=CONNECTOR_TYPE, name="ServerConnector", attributes={ 'address': 'http1', 'port': self.http_server_port, 'protocolVersion': 'HTTP1' }) self.assertEqual(1, len(mgmt.query(type=CONNECTOR_TYPE).results)) count, error = http1_ping(sport=self.http_server_port, cport=self.http_listener_port) self.assertIsNone(error) self.assertEqual(1, count)
def test_03_bad_response_message(self): """ Test various improperly constructed response messages """ DUMMY_TESTS = { "GET": [ ( RequestMsg("GET", "/GET/test_03_bad_response_message", headers={"Content-Length": "000"}), None, None, ), ] } body_filler = "?" * 1024 * 300 # Q2 # fake server - just to create a sink for the "fakeServer" address so # credit will be granted. rx = AsyncTestReceiver(self.INT_A.listener, source="fakeServer") # no correlation id: client = ThreadedTestClient(DUMMY_TESTS, self.http_fake_port) req = rx.queue.get(timeout=TIMEOUT) resp = Message(body="NO CORRELATION ID " + body_filler) resp.to = req.reply_to ts = AsyncTestSender(address=self.INT_A.listener, target=req.reply_to, message=resp) ts.wait() self.assertEqual(1, ts.rejected) client.wait() self.assertIsNotNone(client.error) # missing application properties client = ThreadedTestClient(DUMMY_TESTS, self.http_fake_port) req = rx.queue.get(timeout=TIMEOUT) resp = Message(body="NO APPLICATION PROPS " + body_filler) resp.to = req.reply_to resp.correlation_id = req.id ts = AsyncTestSender(address=self.INT_A.listener, target=req.reply_to, message=resp) ts.wait() self.assertEqual(1, ts.rejected) client.wait() self.assertIsNotNone(client.error) # no status application property client = ThreadedTestClient(DUMMY_TESTS, self.http_fake_port) req = rx.queue.get(timeout=TIMEOUT) resp = Message(body="MISSING STATUS HEADER " + body_filler) resp.to = req.reply_to resp.correlation_id = req.id resp.properties = {"stuff": "value"} ts = AsyncTestSender(address=self.INT_A.listener, target=req.reply_to, message=resp) ts.wait() self.assertEqual(1, ts.rejected) client.wait() self.assertIsNotNone(client.error) # TODO: fix body parsing (returns NEED_MORE) # # invalid body format # client = ThreadedTestClient(DUMMY_TESTS, # self.http_fake_port) # req = rx.queue.get(timeout=TIMEOUT) # resp = Message(body="INVALID BODY FORMAT " + body_filler) # resp.to = req.reply_to # resp.correlation_id = req.id # resp.properties = {"http:status": 200} # ts = AsyncTestSender(address=self.INT_A.listener, # target=req.reply_to, # message=resp) # ts.wait() # self.assertEqual(1, ts.rejected); # client.wait() # self.assertIsNotNone(client.error) rx.stop() sleep(0.5) # fudge factor allow socket close to complete # verify router is still sane: count, error = http1_ping(self.http_server_port, self.http_listener_port) self.assertIsNone(error) self.assertEqual(1, count)
def test_02_bad_request_message(self): """ Test various improperly constructed request messages """ server = TestServer(server_port=self.http_server_port, client_port=self.http_listener_port, tests={}) body_filler = "?" * 1024 * 300 # Q2 msg = Message(body="NOMSGID " + body_filler) ts = AsyncTestSender(address=self.INT_A.listener, target="testServer", message=msg) ts.wait() self.assertEqual(1, ts.rejected) msg = Message(body="NO REPLY TO " + body_filler) msg.id = 1 ts = AsyncTestSender(address=self.INT_A.listener, target="testServer", message=msg) ts.wait() self.assertEqual(1, ts.rejected) msg = Message(body="NO SUBJECT " + body_filler) msg.id = 1 msg.reply_to = "amqp://fake/reply_to" ts = AsyncTestSender(address=self.INT_A.listener, target="testServer", message=msg) ts.wait() self.assertEqual(1, ts.rejected) msg = Message(body="NO APP PROPERTIES " + body_filler) msg.id = 1 msg.reply_to = "amqp://fake/reply_to" msg.subject = "GET" ts = AsyncTestSender(address=self.INT_A.listener, target="testServer", message=msg) ts.wait() self.assertEqual(1, ts.rejected) # TODO: fix body parsing (returns NEED_MORE) # msg = Message(body="INVALID BODY " + body_filler) # msg.id = 1 # msg.reply_to = "amqp://fake/reply_to" # msg.subject = "GET" # msg.properties = {"http:target": "/Some/target"} # ts = AsyncTestSender(address=self.INT_A.listener, # target="testServer", # message=msg) # ts.wait() # self.assertEqual(1, ts.rejected); server.wait() # verify router is still sane: count, error = http1_ping(self.http_server_port, self.http_listener_port) self.assertIsNone(error) self.assertEqual(1, count)
def test_01_create_delete(self): """ Create and delete HTTP1 connectors and listeners. The connectors/listeners are created on the edge router. Verify that the adaptor properly notifies the interior of the subscribers/producers. """ e_mgmt = self.e_router.management self.assertEqual(0, len(e_mgmt.query(type=self.LISTENER_TYPE).results)) self.assertEqual(0, len(e_mgmt.query(type=self.CONNECTOR_TYPE).results)) e_mgmt.create(type=self.CONNECTOR_TYPE, name="ServerConnector", attributes={ 'address': 'closest/http1Service', 'port': self.http_server_port, 'protocolVersion': 'HTTP1' }) e_mgmt.create(type=self.LISTENER_TYPE, name="ClientListener", attributes={ 'address': 'closest/http1Service', 'port': self.http_listener_port, 'protocolVersion': 'HTTP1' }) # verify the entities have been created and http traffic works self.assertEqual(1, len(e_mgmt.query(type=self.LISTENER_TYPE).results)) self.assertEqual(1, len(e_mgmt.query(type=self.CONNECTOR_TYPE).results)) count, error = http1_ping(sport=self.http_server_port, cport=self.http_listener_port) self.assertIsNone(error) self.assertEqual(1, count) # now check the interior router for the closest/http1Service address self.i_router.wait_address("closest/http1Service", subscribers=1) # # delete the connector and listener; wait for the associated connection # to be removed # e_mgmt.delete(type=self.CONNECTOR_TYPE, name="ServerConnector") self.assertEqual(0, len(e_mgmt.query(type=self.CONNECTOR_TYPE).results)) e_mgmt.delete(type=self.LISTENER_TYPE, name="ClientListener") self.assertEqual(0, len(e_mgmt.query(type=self.LISTENER_TYPE).results)) # will hit test timeout on failure: while True: hconns = 0 obj = e_mgmt.query(type=self.CONNECTION_TYPE, attribute_names=["protocol"]) for item in obj.get_dicts(): if "http/1.x" in item["protocol"]: hconns += 1 if hconns == 0: break sleep(0.25) # When a connector is configured the router will periodically attempt # to connect to the server address. To prove that the connector has # been completely removed listen for connection attempts on the server # port. s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) s.bind(("", self.http_server_port)) s.setblocking(True) s.settimeout(3) # reconnect attempts every 2.5 seconds s.listen(1) with self.assertRaises(socket.timeout): conn, addr = s.accept() s.close() # Verify that the address is no longer bound on the interior self.i_router.wait_address_unsubscribed("closest/http1Service") # # re-create the connector and listener; verify it works # e_mgmt.create(type=self.CONNECTOR_TYPE, name="ServerConnector", attributes={ 'address': 'closest/http1Service', 'port': self.http_server_port, 'protocolVersion': 'HTTP1' }) e_mgmt.create(type=self.LISTENER_TYPE, name="ClientListener", attributes={ 'address': 'closest/http1Service', 'port': self.http_listener_port, 'protocolVersion': 'HTTP1' }) self.assertEqual(1, len(e_mgmt.query(type=self.LISTENER_TYPE).results)) self.assertEqual(1, len(e_mgmt.query(type=self.CONNECTOR_TYPE).results)) count, error = http1_ping(sport=self.http_server_port, cport=self.http_listener_port) self.assertIsNone(error) self.assertEqual(1, count) self.i_router.wait_address("closest/http1Service", subscribers=1) e_mgmt.delete(type=self.CONNECTOR_TYPE, name="ServerConnector") self.assertEqual(0, len(e_mgmt.query(type=self.CONNECTOR_TYPE).results)) e_mgmt.delete(type=self.LISTENER_TYPE, name="ClientListener") self.assertEqual(0, len(e_mgmt.query(type=self.LISTENER_TYPE).results))