def setUp(self): super(WatchDeliveryConnectionFailedTest, self).setUp() self.proxy = ProxyFactory("127.0.0.1", 2181) self.proxy_port = reactor.listenTCP(0, self.proxy) host = self.proxy_port.getHost() self.proxied_client = ZookeeperClient( "%s:%s" % (host.host, host.port)) self.direct_client = ZookeeperClient("127.0.0.1:2181", 3000) self.session_events = [] def session_event_collector(conn, event): self.session_events.append(event) self.proxied_client.set_session_callback(session_event_collector) return self.direct_client.connect()
def setUp(self): super(RetryClientConnectionLossTest, self).setUp() from twisted.internet import reactor self.proxy = ProxyFactory("127.0.0.1", 2181) self.proxy_port = reactor.listenTCP(0, self.proxy) host = self.proxy_port.getHost() self.proxied_client = RetryClient(ZookeeperClient( "%s:%s" % (host.host, host.port))) self.direct_client = ZookeeperClient("127.0.0.1:2181", 3000) self.session_events = [] def session_event_collector(conn, event): self.session_events.append(event) self.proxied_client.set_session_callback(session_event_collector) return self.direct_client.connect()
class WatchDeliveryConnectionFailedTest(ZookeeperTestCase): """Watches are still sent on reconnect. """ def setUp(self): super(WatchDeliveryConnectionFailedTest, self).setUp() self.proxy = ProxyFactory("127.0.0.1", 2181) self.proxy_port = reactor.listenTCP(0, self.proxy) host = self.proxy_port.getHost() self.proxied_client = ZookeeperClient( "%s:%s" % (host.host, host.port)) self.direct_client = ZookeeperClient("127.0.0.1:2181", 3000) self.session_events = [] def session_event_collector(conn, event): self.session_events.append(event) self.proxied_client.set_session_callback(session_event_collector) return self.direct_client.connect() @inlineCallbacks def tearDown(self): zookeeper.set_debug_level(0) if self.proxied_client.connected: yield self.proxied_client.close() if not self.direct_client.connected: yield self.direct_client.connect() utils.deleteTree(handle=self.direct_client.handle) yield self.direct_client.close() self.proxy.lose_connection() yield self.proxy_port.stopListening() def verify_events(self, events, expected): """Verify the state of the session events encountered. """ for value, state in zip([e.state_name for e in events], expected): self.assertEqual(value, state) @inlineCallbacks def test_child_watch_fires_upon_reconnect(self): yield self.proxied_client.connect() # Setup tree cpath = "/test-tree" yield self.direct_client.create(cpath) # Setup watch child_d, watch_d = self.proxied_client.get_children_and_watch(cpath) self.assertEqual((yield child_d), []) # Kill the connection and fire the watch self.proxy.lose_connection() yield self.direct_client.create( cpath + "/abc", flags=zookeeper.SEQUENCE) # We should still get the child event. yield watch_d # We get two pairs of (connecting, connected) for the conn and watch self.assertEqual(len(self.session_events), 4) self.verify_events( self.session_events, ("connecting", "connecting", "connected", "connected")) @inlineCallbacks def test_exists_watch_fires_upon_reconnect(self): yield self.proxied_client.connect() cpath = "/test" # Setup watch exists_d, watch_d = self.proxied_client.exists_and_watch(cpath) self.assertEqual((yield exists_d), None) # Kill the connection and fire the watch self.proxy.lose_connection() yield self.direct_client.create(cpath) # We should still get the exists event. yield watch_d # We get two pairs of (connecting, connected) for the conn and watch self.assertEqual(len(self.session_events), 4) self.verify_events( self.session_events, ("connecting", "connecting", "connected", "connected")) @inlineCallbacks def test_get_watch_fires_upon_reconnect(self): yield self.proxied_client.connect() # Setup tree cpath = "/test" yield self.direct_client.create(cpath, "abc") # Setup watch get_d, watch_d = self.proxied_client.get_and_watch(cpath) content, stat = yield get_d self.assertEqual(content, "abc") # Kill the connection and fire the watch self.proxy.lose_connection() yield self.direct_client.set(cpath, "xyz") # We should still get the exists event. yield watch_d # We also two pairs of (connecting, connected) for the conn and watch self.assertEqual(len(self.session_events), 4) self.verify_events( self.session_events, ("connecting", "connecting", "connected", "connected")) @inlineCallbacks def test_watch_delivery_failure_resends(self): """Simulate a network failure for the watch delivery The zk server effectively sends the watch delivery to the client, but the client never recieves it. """ yield self.proxied_client.connect() cpath = "/test" # Setup watch exists_d, watch_d = self.proxied_client.exists_and_watch(cpath) self.assertEqual((yield exists_d), None) # Pause the connection fire the watch, and blackhole the data. self.proxy.set_blocked(True) yield self.direct_client.create(cpath) self.proxy.set_blocked(False) self.proxy.lose_connection() # We should still get the exists event. yield watch_d @inlineCallbacks def xtest_binding_bug_session_exception(self): """This test triggers an exception in the python-zookeeper binding. File "txzookeeper/client.py", line 491, in create self.handle, path, data, acls, flags, callback) exceptions.SystemError: error return without exception set """ yield self.proxied_client.connect() data_d, watch_d = yield self.proxied_client.exists_and_watch("/") self.assertTrue((yield data_d)) self.proxy.set_blocked(True) # Wait for session expiration, on a single server options are limited yield self.sleep(15) # Unblock the proxy for next connect, and then drop the connection. self.proxy.set_blocked(False) self.proxy.lose_connection() # Wait for a reconnect yield self.assertFailure(watch_d, zookeeper.SessionExpiredException) # Leads to bindings bug failure yield self.assertFailure( self.proxied_client.get("/a"), zookeeper.SessionExpiredException) self.assertEqual(self.session_events[-1].state_name, "expired")
class RetryClientConnectionLossTest(ZookeeperTestCase): def setUp(self): super(RetryClientConnectionLossTest, self).setUp() from twisted.internet import reactor self.proxy = ProxyFactory("127.0.0.1", 2181) self.proxy_port = reactor.listenTCP(0, self.proxy) host = self.proxy_port.getHost() self.proxied_client = RetryClient(ZookeeperClient( "%s:%s" % (host.host, host.port))) self.direct_client = ZookeeperClient("127.0.0.1:2181", 3000) self.session_events = [] def session_event_collector(conn, event): self.session_events.append(event) self.proxied_client.set_session_callback(session_event_collector) return self.direct_client.connect() @inlineCallbacks def tearDown(self): import zookeeper zookeeper.set_debug_level(0) if self.proxied_client.connected: yield self.proxied_client.close() if not self.direct_client.connected: yield self.direct_client.connect() utils.deleteTree(handle=self.direct_client.handle) yield self.direct_client.close() self.proxy.lose_connection() yield self.proxy_port.stopListening() @inlineCallbacks def test_get_children_and_watch(self): yield self.proxied_client.connect() # Setup tree cpath = "/test-tree" yield self.direct_client.create(cpath) # Block the request (drops all packets.) self.proxy.set_blocked(True) child_d, watch_d = self.proxied_client.get_children_and_watch(cpath) # Unblock and disconnect self.proxy.set_blocked(False) self.proxy.lose_connection() # Call goes through self.assertEqual((yield child_d), []) self.assertEqual(len(self.session_events), 2) # And we have reconnect events self.assertEqual(self.session_events[-1].state_name, "connected") yield self.direct_client.create(cpath + "/abc") # The original watch is still active yield watch_d @inlineCallbacks def test_exists_and_watch(self): yield self.proxied_client.connect() cpath = "/test-tree" # Block the request self.proxy.set_blocked(True) exists_d, watch_d = self.proxied_client.exists_and_watch(cpath) # Create the node yield self.direct_client.create(cpath) # Unblock and disconnect self.proxy.set_blocked(False) self.proxy.lose_connection() # Call gets retried, see the latest state self.assertTrue((yield exists_d)) self.assertEqual(len(self.session_events), 2) # And we have reconnect events self.assertEqual(self.session_events[-1].state_name, "connected") yield self.direct_client.delete(cpath) # The original watch is still active yield watch_d @inlineCallbacks def test_get_and_watch(self): yield self.proxied_client.connect() # Setup tree cpath = "/test-tree" yield self.direct_client.create(cpath) # Block the request (drops all packets.) self.proxy.set_blocked(True) get_d, watch_d = self.proxied_client.get_and_watch(cpath) # Unblock and disconnect self.proxy.set_blocked(False) self.proxy.lose_connection() # Call goes through content, stat = yield get_d self.assertEqual(content, '') self.assertEqual(len(self.session_events), 2) # And we have reconnect events self.assertEqual(self.session_events[-1].state_name, "connected") yield self.direct_client.delete(cpath) # The original watch is still active yield watch_d @inlineCallbacks def test_set(self): yield self.proxied_client.connect() # Setup tree cpath = "/test-tree" yield self.direct_client.create(cpath, json.dumps({"a": 1, "c": 2})) def update_node(content, stat): data = json.loads(content) data["a"] += 1 data["b"] = 0 return json.dumps(data) # Block the request (drops all packets.) self.proxy.set_blocked(True) mod_d = retry_change(self.proxied_client, cpath, update_node) # Unblock and disconnect self.proxy.set_blocked(False) self.proxy.lose_connection() # Call goes through, contents verified. yield mod_d content, stat = yield self.direct_client.get(cpath) self.assertEqual(json.loads(content), {"a": 2, "b": 0, "c": 2})