From 1bbac3489bb654963ba8629a5f3194e7ea56b23c Mon Sep 17 00:00:00 2001 From: Alan Conway Date: Thu, 9 Jan 2014 22:30:26 +0000 Subject: QPID-5428: Heartbeats not in use when attempting to connect with python client. Heartbeats ignored when opening a connection, could hang indefinitely Need to cover 3 cases (test included): - Connect sucessful but then broker stalls. - Connect to a stalled broker that never responds. - Fail-over to a stalled broker that never responds All cases are handled by the following fixes to driver.py: - Check for heartbeats even before engine._connected since we may time out before receiving open-ok if the peer is stalled and never sends data. - Set _last_in and _last_out so that we time heartbeats from the start of the connection if no data is ever sent or received. - Call self.update_status in Driver.timeout to detect connection closed due to heartbeat timeout (rather than a readable or writeable event.) Make update_status a no-op if engine or transport are not yet set up. - Don't consider reconnect complete in connect(), wait till we get the open-ok. See the comment on Driver._check_retry_ok() git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1556971 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/src/tests/ha_tests.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'qpid/cpp/src') diff --git a/qpid/cpp/src/tests/ha_tests.py b/qpid/cpp/src/tests/ha_tests.py index 7a292f177a..b8644ab0fa 100755 --- a/qpid/cpp/src/tests/ha_tests.py +++ b/qpid/cpp/src/tests/ha_tests.py @@ -233,6 +233,33 @@ class ReplicationTests(HaBrokerTest): c.close() finally: l.restore() + + def test_heartbeat_python(self): + """Verify that a python client with a heartbeat specified disconnects + from a stalled broker and does not hang indefinitely.""" + + broker = Broker(self) + broker_addr = broker.host_port() + + # Case 1: Connect before stalling the broker, use the connection after stalling. + c = Connection(broker_addr, heartbeat=1) + c.open() + os.kill(broker.pid, signal.SIGSTOP) # Stall the broker + self.assertRaises(ConnectionError, c.session().sender, "foo") + + # Case 2: Connect to a stalled broker + c = Connection(broker_addr, heartbeat=1) + self.assertRaises(ConnectionError, c.open) + + # Case 3: Re-connect to a stalled broker. + broker2 = Broker(self) + c = Connection(broker2.host_port(), heartbeat=1, reconnect_limit=1, + reconnect=True, reconnect_urls=[broker_addr], + reconnect_log=False) # Hide expected warnings + c.open() + broker2.kill() # Cause re-connection to broker + self.assertRaises(ConnectionError, c.session().sender, "foo") + def test_failover_cpp(self): """Verify that failover works in the C++ client.""" cluster = HaCluster(self, 2) -- cgit v1.2.1