def test_default_config(self): logger_config = LoggerConfig() self.assertEqual(logging.INFO, logger_config.level) self.assertIsNone(logger_config.config_file) config = ClientConfig() config.cluster_name = self.cluster.id config.logger = logger_config client = HazelcastClient(config) self.assertEqual(logging.INFO, client.logger.level) self.assertTrue(client.logger.isEnabledFor(logging.INFO)) self.assertTrue(client.logger.isEnabledFor(logging.WARNING)) self.assertTrue(client.logger.isEnabledFor(logging.ERROR)) self.assertTrue(client.logger.isEnabledFor(logging.CRITICAL)) out = StringIO() default_handler = client.logger.handlers[0] default_handler.stream = out client.logger.debug("DEBUG_TEST") client.logger.info("INFO_TEST") client.logger.error("ERROR_TEST") client.logger.critical("CRITICAL_TEST") out.flush() out_str = out.getvalue() self.assertEqual(0, out_str.count("DEBUG_TEST")) self.assertEqual(1, out_str.count("INFO_TEST")) self.assertEqual(1, out_str.count("ERROR_TEST")) self.assertEqual(1, out_str.count("CRITICAL_TEST")) client.shutdown()
def test_off_reconnect_mode(self): self.cluster = self.rc.createCluster(None, None) member = self.rc.startMember(self.cluster.id) def collector(): events = [] def on_state_change(event): if event == LifecycleState.SHUTDOWN: events.append(event) on_state_change.events = events return on_state_change event_collector = collector() self.client = HazelcastClient( cluster_members=["localhost:5701"], cluster_name=self.cluster.id, reconnect_mode=ReconnectMode.OFF, lifecycle_listeners=[event_collector], ) m = self.client.get_map(random_string()).blocking() # no exception at this point m.put(1, 1) self.rc.shutdownMember(self.cluster.id, member.uuid) self.assertTrueEventually(lambda: self.assertEqual(1, len(event_collector.events))) with self.assertRaises(HazelcastClientNotActiveError): m.put(1, 1)
def test_default_logger_output(self): config = ClientConfig() config.cluster_name = self.cluster.id client = HazelcastClient(config) out = StringIO() client.logger.handlers[0].stream = out version_message = "[" + CLIENT_VERSION + "]" client.logger.info("TEST_MSG") out.flush() out_str = out.getvalue() self.assertTrue("TEST_MSG" in out_str) for line in out_str.split("\n"): if "TEST_MSG" in line: level_name, version, message = line.split(" ") self.assertEqual("INFO:", level_name) self.assertEqual(version_message, version) self.assertEqual("TEST_MSG", message) client.shutdown()
def setUp(self): self.rc = self.create_rc() self.cluster = self.create_cluster(self.rc, self.configure_cluster()) self.cluster.start_member() self.cluster.start_member() self.client = HazelcastClient(cluster_name=self.cluster.id) self.pn_counter = self.client.get_pn_counter("pn-counter").blocking()
def test_off_reconnect_mode(self): self.cluster = self.rc.createCluster(None, None) member = self.rc.startMember(self.cluster.id) config = ClientConfig() config.cluster_name = self.cluster.id config.network.addresses.append("localhost:5701") config.connection_strategy.reconnect_mode = RECONNECT_MODE.OFF config.connection_strategy.connection_retry.cluster_connect_timeout = six.MAXSIZE def collector(): events = [] def on_state_change(event): if event == LifecycleState.SHUTDOWN: events.append(event) on_state_change.events = events return on_state_change event_collector = collector() config.add_lifecycle_listener(event_collector) self.client = HazelcastClient(config) m = self.client.get_map(random_string()).blocking() # no exception at this point m.put(1, 1) self.rc.shutdownMember(self.cluster.id, member.uuid) self.assertTrueEventually(lambda: self.assertEqual(1, len(event_collector.events))) with self.assertRaises(HazelcastClientNotActiveError): m.put(1, 1)
class HeartbeatTest(HazelcastTestCase): @classmethod def setUpClass(cls): cls.rc = cls.create_rc() @classmethod def tearDownClass(cls): cls.rc.exit() def setUp(self): self.cluster = self.create_cluster(self.rc) self.member = self.rc.startMember(self.cluster.id) self.client = HazelcastClient(cluster_name=self.cluster.id, heartbeat_interval=0.5, heartbeat_timeout=2) def tearDown(self): self.client.shutdown() self.rc.shutdownCluster(self.cluster.id) def test_heartbeat_stopped_and_restored(self): member2 = self.rc.startMember(self.cluster.id) addr = Address(member2.host, member2.port) wait_for_partition_table(self.client) open_connection_to_address(self.client, member2.uuid) def connection_collector(): connections = [] def collector(c, *_): connections.append(c) collector.connections = connections return collector connection_added_collector = connection_collector() connection_removed_collector = connection_collector() self.client._connection_manager.add_listener( connection_added_collector, connection_removed_collector) self.simulate_heartbeat_lost(self.client, addr, 2) def assert_heartbeat_stopped_and_restored(): self.assertEqual(1, len(connection_added_collector.connections)) self.assertEqual(1, len(connection_removed_collector.connections)) stopped_connection = connection_added_collector.connections[0] restored_connection = connection_removed_collector.connections[0] self.assertEqual(stopped_connection.connected_address, Address(member2.host, member2.port)) self.assertEqual(restored_connection.connected_address, Address(member2.host, member2.port)) self.assertTrueEventually(assert_heartbeat_stopped_and_restored) @staticmethod def simulate_heartbeat_lost(client, address, timeout): connection = client._connection_manager.get_connection_from_address( address) connection.last_read_time -= timeout
def test_async_start_with_no_cluster(self): config = ClientConfig() config.connection_strategy.async_start = True self.client = HazelcastClient(config) with self.assertRaises(ClientOfflineError): self.client.get_map(random_string())
def test_async_start_with_partition_specific_proxies(self): config = ClientConfig() config.connection_strategy.async_start = True self.client = HazelcastClient(config) with self.assertRaises(ClientOfflineError): self.client.get_list(random_string())
def test_async_start(self): self.cluster = self.rc.createCluster(None, None) self.rc.startMember(self.cluster.id) def collector(): events = [] def on_state_change(event): if event == LifecycleState.CONNECTED: events.append(event) on_state_change.events = events return on_state_change event_collector = collector() self.client = HazelcastClient( cluster_name=self.cluster.id, cluster_members=["localhost:5701"], async_start=True, lifecycle_listeners=[event_collector], ) self.assertTrueEventually(lambda: self.assertEqual(1, len(event_collector.events))) self.client.get_map(random_string())
class HeartbeatTest(HazelcastTestCase): @classmethod def setUpClass(cls): configure_logging() cls.rc = cls.create_rc() @classmethod def tearDownClass(cls): cls.rc.exit() def setUp(self): self.cluster = self.create_cluster(self.rc) self.member = self.rc.startMember(self.cluster.id) self.config = ClientConfig() self.config.set_property(ClientProperties.HEARTBEAT_INTERVAL.name, 500) self.config.set_property(ClientProperties.HEARTBEAT_TIMEOUT.name, 2000) self.client = HazelcastClient(self.config) def tearDown(self): self.client.shutdown() self.rc.shutdownCluster(self.cluster.id) def test_heartbeat_stopped(self): def connection_collector(): connections = [] def collector(c): connections.append(c) collector.connections = connections return collector heartbeat_stopped_collector = connection_collector() heartbeat_restored_collector = connection_collector() self.client.heartbeat.add_listener(on_heartbeat_stopped=heartbeat_stopped_collector, on_heartbeat_restored=heartbeat_restored_collector) member2 = self.rc.startMember(self.cluster.id) addr = Address(member2.host, member2.port) open_connection_to_address(self.client, addr) self.simulate_heartbeat_lost(self.client, addr, 2) def assert_heartbeat_stopped_and_restored(): self.assertEqual(1, len(heartbeat_stopped_collector.connections)) self.assertEqual(1, len(heartbeat_restored_collector.connections)) connection_stopped = heartbeat_stopped_collector.connections[0] connection_restored = heartbeat_restored_collector.connections[0] self.assertEqual(connection_stopped._address, (member2.host, member2.port)) self.assertEqual(connection_restored._address, (member2.host, member2.port)) self.assertTrueEventually(assert_heartbeat_stopped_and_restored) @staticmethod def simulate_heartbeat_lost(client, address, timeout): client.connection_manager.connections[address].last_read_in_seconds -= timeout
def test_async_start_with_no_cluster_throws_after_shutdown(self): config = ClientConfig() config.connection_strategy.async_start = True self.client = HazelcastClient(config) self.client.shutdown() with self.assertRaises(HazelcastClientNotActiveError): self.client.get_map(random_string())
def setUp(self): self.cluster = self.create_cluster(self.rc) self.member = self.rc.startMember(self.cluster.id) self.client = HazelcastClient( cluster_name=self.cluster.id, heartbeat_interval=0.5, heartbeat_timeout=2, )
def test_unisocket_mode(self): self.client = HazelcastClient( cluster_name=self.cluster.id, smart_routing=False, ) m = self.client.get_map("test") # it's enough for this operation to succeed m.set(1, 2).result()
def test_backup_acks_disabled(self): self.client = HazelcastClient( cluster_name=self.cluster.id, backup_ack_to_client_enabled=False, ) m = self.client.get_map("test") # it's enough for this operation to succeed m.set(1, 2).result()
def setUp(self): self.cluster = self.create_cluster(self.rc) self.member = self.rc.startMember(self.cluster.id) self.config = ClientConfig() self.config.set_property(ClientProperties.HEARTBEAT_INTERVAL.name, 500) self.config.set_property(ClientProperties.HEARTBEAT_TIMEOUT.name, 2000) self.client = HazelcastClient(self.config)
def test_unisocket_mode_with_disabled_backup_acks(self): self.client = HazelcastClient( cluster_name=self.cluster.id, smart_routing=False, backup_ack_to_client_enabled=False, ) m = self.client.get_map("test") # it's enough for this operation to succeed m.set(1, 2).result()
def test_custom_configuration_output(self): config = ClientConfig() config.cluster_name = self.cluster.id config_file = get_abs_path(self.CUR_DIR, "detailed_config.json") config.logger.config_file = config_file client = HazelcastClient(config) std_out = StringIO() std_err = StringIO() for handler in client.logger.handlers: if handler.get_name() == "StdoutHandler": handler.stream = std_out else: handler.stream = std_err frame_info = getframeinfo(currentframe()) client.logger.info("TEST_MSG") # These two statements above should # follow each other without a white space. # Otherwise, arrange the line number in # the assert statements accordingly. std_out.flush() std_err.flush() std_out_str = std_out.getvalue() std_err_str = std_err.getvalue() self.assertTrue("TEST_MSG" in std_out_str) self.assertTrue("TEST_MSG" in std_err_str) for line in std_out_str.split("\n"): if "TEST_MSG" in line: print(line) asc_time, name, level_name, message = line.split("*") self.assertTrue(self._is_valid_date_string(asc_time)) self.assertEqual("HazelcastClient", name) self.assertEqual("INFO", level_name) self.assertEqual("TEST_MSG", message) for line in std_err_str.split("\n"): if "TEST_MSG" in line: asc_time, name, func, line_no, level_name, message = line.split( "*") self.assertTrue(self._is_valid_date_string(asc_time)) self.assertEqual("HazelcastClient", name) self.assertEqual(frame_info.function, func) self.assertEqual(str(frame_info.lineno + 1), line_no) self.assertEqual("INFO", level_name) self.assertEqual("TEST_MSG", message) client.shutdown()
def test_release_when_acquired_by_another_client_sessionless(self): semaphore = self.get_semaphore("sessionless") another_client = HazelcastClient(cluster_name=self.cluster.id) another_semaphore = another_client.cp_subsystem.get_semaphore(semaphore._proxy_name).blocking() self.assertTrue(another_semaphore.init(1)) another_semaphore.acquire() try: semaphore.release(1) self.assertEqual(1, semaphore.available_permits()) finally: another_client.shutdown()
def test_lock_after_client_shutdown(self): another_client = HazelcastClient(cluster_name=self.cluster.id) another_lock = another_client.cp_subsystem.get_lock( self.lock._proxy_name).blocking() self.assert_valid_fence(another_lock.lock()) self.assertTrue(another_lock.is_locked()) self.assertTrue(self.lock.is_locked()) another_client.shutdown() def assertion(): self.assertFalse(self.lock.is_locked()) self.assertTrueEventually(assertion)
def test_smart_mode(self): self.client = HazelcastClient( cluster_name=self.cluster.id, fail_on_indeterminate_operation_state=True, ) m = self.client.get_map("test").blocking() # TODO: Remove the next line once # https://github.com/hazelcast/hazelcast/issues/9398 is fixed m.get(1) # it's enough for this operation to succeed m.set(1, 2)
def test_session_aware_semaphore_after_client_shutdown(self): semaphore = self.get_semaphore("sessionaware", 1) another_client = HazelcastClient(cluster_name=self.cluster.id) another_semaphore = another_client.cp_subsystem.get_semaphore(semaphore._proxy_name).blocking() another_semaphore.acquire(1) self.assertEqual(0, another_semaphore.available_permits()) self.assertEqual(0, semaphore.available_permits()) another_client.shutdown() def assertion(): self.assertEqual(1, semaphore.available_permits()) self.assertTrueEventually(assertion)
def test_random_load_balancer(self): client = HazelcastClient(cluster_name=self.cluster.id, load_balancer=RandomLB()) self.assertTrue(client.lifecycle_service.is_running()) lb = client._load_balancer self.assertTrue(isinstance(lb, RandomLB)) six.assertCountEqual(self, self.addresses, list(map(lambda m: m.address, lb._members))) for _ in range(10): self.assertTrue(lb.next().address in self.addresses) client.shutdown()
def test_lost_backups_on_smart_mode_with_fail_on_indeterminate_operation_state( self): self.client = HazelcastClient( cluster_name=self.cluster.id, operation_backup_timeout=0.3, fail_on_indeterminate_operation_state=True, ) client = self.client # replace backup ack handler with a mock to emulate backup acks loss client._invocation_service._backup_event_handler = MagicMock() m = client.get_map("test") with self.assertRaises(IndeterminateOperationStateError): m.set(1, 2).result()
def test_when_member_started_with_the_same_address(self): skip_if_client_version_older_than(self, "4.2") old_member = self.cluster.start_member() self.client = HazelcastClient(cluster_name=self.cluster.id) members_added = [] members_removed = [] self.client.cluster_service.add_listener( lambda m: members_added.append(m), lambda m: members_removed.append(m)) self.rc.shutdownMember(self.cluster.id, old_member.uuid) new_member = self.cluster.start_member() def assertion(): self.assertEqual(1, len(members_added)) self.assertEqual(new_member.uuid, str(members_added[0].uuid)) self.assertEqual(1, len(members_removed)) self.assertEqual(old_member.uuid, str(members_removed[0].uuid)) self.assertTrueEventually(assertion) members = self.client.cluster_service.get_members() self.assertEqual(1, len(members)) self.assertEqual(new_member.uuid, str(members[0].uuid))
def test_when_member_started_with_another_port_and_the_same_uuid(self): member = self.cluster.start_member() self.client = HazelcastClient(cluster_name=self.cluster.id) added_listener = event_collector() removed_listener = event_collector() self.client.cluster_service.add_listener( member_added=added_listener, member_removed=removed_listener) self.rc.shutdownCluster(self.cluster.id) # now stop cluster, restart it with the same name and then start member with port 5702 self.cluster = self.create_cluster_keep_cluster_name( self.rc, self.get_config(5702)) self.cluster.start_member() def assertion(): self.assertEqual(1, len(added_listener.events)) self.assertEqual(1, len(removed_listener.events)) self.assertTrueEventually(assertion) members = self.client.cluster_service.get_members() self.assertEqual(1, len(members)) self.assertEqual(member.uuid, str(members[0].uuid))
def test_round_robin_load_balancer(self): client = HazelcastClient(cluster_name=self.cluster.id, load_balancer=RoundRobinLB()) self.assertTrue(client.lifecycle_service.is_running()) lb = client._load_balancer self.assertTrue(isinstance(lb, RoundRobinLB)) self.assertCountEqual( self.addresses, list(map(lambda m: m.address, self._get_members_from_lb(lb)))) for i in range(10): self.assertEqual(self.addresses[i % len(self.addresses)], lb.next().address) client.shutdown()
def setUpClass(cls): cls.rc = cls.create_rc() cls.cluster = cls.create_cluster(cls.rc, cls.configure_cluster()) cls.cluster.start_member() cls.cluster.start_member() cls.client = HazelcastClient(cluster_name=cls.cluster.id) cls.map = cls.client.get_map(random_string()).blocking()
def test_lost_backups_on_smart_mode_without_fail_on_indeterminate_operation_state( self): self.client = HazelcastClient( cluster_name=self.cluster.id, operation_backup_timeout=0.3, fail_on_indeterminate_operation_state=False, ) client = self.client # replace backup ack handler with a mock to emulate backup acks loss client._invocation_service._backup_event_handler = MagicMock() m = client.get_map("test") # it's enough for this operation to succeed m.set(1, 2).result()
def setUpClass(cls): cls.rc = cls.create_rc() cls.cluster = cls.create_cluster(cls.rc, cls.configure_cluster()) cls.cluster.start_member() cls.cluster.start_member() cls.cluster.start_member() cls.client = HazelcastClient(cluster_name=cls.cluster.id)
class PNCounterConsistencyTest(HazelcastTestCase): @classmethod def setUpClass(cls): configure_logging() def setUp(self): self.rc = self.create_rc() self.cluster = self.create_cluster(self.rc, self._configure_cluster()) self.cluster.start_member() self.cluster.start_member() config = ClientConfig() config.cluster_name = self.cluster.id self.client = HazelcastClient(config) self.pn_counter = self.client.get_pn_counter("pn-counter").blocking() def tearDown(self): self.client.shutdown() self.rc.terminateCluster(self.cluster.id) self.rc.exit() def test_consistency_lost_error_raised_when_target_terminates(self): self.pn_counter.add_and_get(3) replica_address = self.pn_counter._current_target_replica_address self.rc.terminateMember(self.cluster.id, str(replica_address.uuid)) with self.assertRaises(ConsistencyLostError): self.pn_counter.add_and_get(5) def test_counter_can_continue_session_by_calling_reset(self): self.pn_counter.add_and_get(3) replica_address = self.pn_counter._current_target_replica_address self.rc.terminateMember(self.cluster.id, str(replica_address.uuid)) self.pn_counter.reset() self.pn_counter.add_and_get(5) def _configure_cluster(self): current_directory = os.path.dirname(__file__) with open( get_abs_path(current_directory, "hazelcast_crdtreplication_delayed.xml"), "r") as f: return f.read()