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_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 test_statistics_enabled(self):
        config = ClientConfig()
        config.cluster_name = self.cluster.id
        config.set_property(ClientProperties.STATISTICS_ENABLED.name, True)
        client = HazelcastClient(config)
        client_uuid = client._connection_manager.client_uuid

        time.sleep(2 * self.DEFAULT_STATS_PERIOD)
        self._wait_for_statistics_collection(client_uuid)

        client.shutdown()
    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_statistics_disabled_by_default(self):
        config = ClientConfig()
        config.cluster_name = self.cluster.id
        client = HazelcastClient(config)
        time.sleep(2 * self.DEFAULT_STATS_PERIOD)
        client_uuid = client._connection_manager.client_uuid

        response = self._get_client_stats_from_server(client_uuid)

        self.assertTrue(response.success)
        self.assertIsNone(response.result)
        client.shutdown()
    def test_statistics_content(self):
        config = ClientConfig()
        config.cluster_name = self.cluster.id
        config.set_property(ClientProperties.STATISTICS_ENABLED.name, True)
        config.set_property(ClientProperties.STATISTICS_PERIOD_SECONDS.name, self.STATS_PERIOD)

        map_name = random_string()

        near_cache_config = NearCacheConfig(map_name)
        config.near_caches[map_name] = near_cache_config

        client = HazelcastClient(config)
        client_uuid = client._connection_manager.client_uuid

        client.get_map(map_name).blocking()

        time.sleep(2 * self.STATS_PERIOD)
        response = self._wait_for_statistics_collection(client_uuid)

        result = response.result.decode("utf-8")
        info = client._internal_cluster_service.get_local_client()
        local_address = "%s:%s" % (info.address.host, info.address.port)

        # Check near cache and client statistics
        self.assertEqual(1, result.count("clientName=" + client.name))
        self.assertEqual(1, result.count("lastStatisticsCollectionTime="))
        self.assertEqual(1, result.count("enterprise=false"))
        self.assertEqual(1, result.count("clientType=" + CLIENT_TYPE))
        self.assertEqual(1, result.count("clientVersion=" + CLIENT_VERSION))
        self.assertEqual(1, result.count("clusterConnectionTimestamp="))
        self.assertEqual(1, result.count("clientAddress=" + local_address))
        self.assertEqual(1, result.count("nc." + map_name + ".creationTime"))
        self.assertEqual(1, result.count("nc." + map_name + ".evictions"))
        self.assertEqual(1, result.count("nc." + map_name + ".hits"))
        self.assertEqual(1, result.count("nc." + map_name + ".misses"))
        self.assertEqual(1, result.count("nc." + map_name + ".ownedEntryCount"))
        self.assertEqual(1, result.count("nc." + map_name + ".expirations"))
        self.assertEqual(1, result.count("nc." + map_name + ".invalidations"))
        self.assertEqual(1, result.count("nc." + map_name + ".invalidationRequests"))
        self.assertEqual(1, result.count("nc." + map_name + ".ownedEntryMemoryCost"))

        # Check OS and runtime statistics. We cannot know what kind of statistics will be available
        # in different platforms. So, first try to get these statistics and then check the
        # response content

        s = Statistics(client, None, None, None, None, None)
        psutil_stats = s._get_os_and_runtime_stats()
        for stat_name in psutil_stats:
            self.assertEqual(1, result.count(stat_name))

        client.shutdown()
    def test_statistics_disabled_with_wrong_value(self):
        config = ClientConfig()
        config.cluster_name = self.cluster.id
        config.set_property(ClientProperties.STATISTICS_ENABLED.name, "truee")
        config.set_property(ClientProperties.STATISTICS_PERIOD_SECONDS.name, self.STATS_PERIOD)
        client = HazelcastClient(config)
        client_uuid = client._connection_manager.client_uuid

        time.sleep(2 * self.STATS_PERIOD)
        response = self._get_client_stats_from_server(client_uuid)

        self.assertTrue(response.success)
        self.assertIsNone(response.result)
        client.shutdown()
    def test_statistics_period(self):
        config = ClientConfig()
        config.cluster_name = self.cluster.id
        config.set_property(ClientProperties.STATISTICS_ENABLED.name, True)
        config.set_property(ClientProperties.STATISTICS_PERIOD_SECONDS.name, self.STATS_PERIOD)
        client = HazelcastClient(config)
        client_uuid = client._connection_manager.client_uuid

        time.sleep(2 * self.STATS_PERIOD)
        response1 = self._wait_for_statistics_collection(client_uuid)

        time.sleep(2 * self.STATS_PERIOD)
        response2 = self._wait_for_statistics_collection(client_uuid)

        self.assertNotEqual(response1, response2)
        client.shutdown()
    def test_statistics_enabled_with_environment_variable(self):
        environ = os.environ
        environ[ClientProperties.STATISTICS_ENABLED.name] = "true"
        environ[ClientProperties.STATISTICS_PERIOD_SECONDS.name] = str(self.STATS_PERIOD)

        config = ClientConfig()
        config.cluster_name = self.cluster.id
        client = HazelcastClient(config)
        client_uuid = client._connection_manager.client_uuid

        time.sleep(2 * self.STATS_PERIOD)
        self._wait_for_statistics_collection(client_uuid)

        os.unsetenv(ClientProperties.STATISTICS_ENABLED.name)
        os.unsetenv(ClientProperties.STATISTICS_PERIOD_SECONDS.name)
        client.shutdown()
    def test_near_cache_stats(self):
        config = ClientConfig()
        config.cluster_name = self.cluster.id
        config.set_property(ClientProperties.STATISTICS_ENABLED.name, True)
        config.set_property(ClientProperties.STATISTICS_PERIOD_SECONDS.name, self.STATS_PERIOD)

        map_name = random_string()

        near_cache_config = NearCacheConfig(map_name)
        config.near_caches[map_name] = near_cache_config

        client = HazelcastClient(config)
        client_uuid = client._connection_manager.client_uuid

        test_map = client.get_map(map_name).blocking()

        time.sleep(2 * self.STATS_PERIOD)
        response = self._wait_for_statistics_collection(client_uuid)

        result = response.result.decode("utf-8")
        self.assertEqual(1, result.count("nc." + map_name + ".evictions=0"))
        self.assertEqual(1, result.count("nc." + map_name + ".hits=0"))
        self.assertEqual(1, result.count("nc." + map_name + ".misses=0"))
        self.assertEqual(1, result.count("nc." + map_name + ".ownedEntryCount=0"))
        self.assertEqual(1, result.count("nc." + map_name + ".expirations=0"))
        self.assertEqual(1, result.count("nc." + map_name + ".invalidations=0"))
        self.assertEqual(1, result.count("nc." + map_name + ".invalidationRequests=0"))

        test_map.put(1, 2)  # invalidation request
        test_map.get(1)  # cache miss
        test_map.get(1)  # cache hit
        test_map.put(1, 3)  # invalidation + invalidation request
        test_map.get(1)  # cache miss

        time.sleep(2 * self.STATS_PERIOD)
        response = self._wait_for_statistics_collection(client_uuid)

        result = response.result.decode("utf-8")
        self.assertEqual(1, result.count("nc." + map_name + ".evictions=0"))
        self.assertEqual(1, result.count("nc." + map_name + ".hits=1"))
        self.assertEqual(1, result.count("nc." + map_name + ".misses=2"))
        self.assertEqual(1, result.count("nc." + map_name + ".ownedEntryCount=1"))
        self.assertEqual(1, result.count("nc." + map_name + ".expirations=0"))
        self.assertEqual(1, result.count("nc." + map_name + ".invalidations=1"))
        self.assertEqual(1, result.count("nc." + map_name + ".invalidationRequests=2"))

        client.shutdown()
    def test_new_id_with_at_least_one_suitable_member(self):
        response = self._assign_out_of_range_node_id(self.cluster.id,
                                                     random.randint(0, 1))
        self.assertTrueEventually(
            lambda: response.success and response.result is not None)

        config = ClientConfig()
        config.cluster_name = self.cluster.id
        config.network.smart_routing = False
        client = HazelcastClient(config)

        generator = client.get_flake_id_generator("test").blocking()

        for i in range(100):
            generator.new_id()

        generator.destroy()
        client.shutdown()
    def test_new_id_fails_when_all_members_are_out_of_node_id_range(self):
        response1 = self._assign_out_of_range_node_id(self.cluster.id, 0)
        self.assertTrueEventually(
            lambda: response1.success and response1.result is not None)

        response2 = self._assign_out_of_range_node_id(self.cluster.id, 1)
        self.assertTrueEventually(
            lambda: response2.success and response2.result is not None)

        config = ClientConfig()
        config.cluster_name = self.cluster.id
        client = HazelcastClient(config)
        generator = client.get_flake_id_generator("test").blocking()

        with self.assertRaises(HazelcastError):
            generator.new_id()

        generator.destroy()
        client.shutdown()
    def test_default_configuration_multiple_clients(self):
        config = ClientConfig()
        config.cluster_name = self.cluster.id
        client1 = HazelcastClient(config)
        client2 = HazelcastClient(config)

        out = StringIO()

        client1.logger.handlers[0].stream = out
        client2.logger.handlers[0].stream = out

        client1.logger.info("TEST_MSG")
        client2.logger.info("TEST_MSG")

        out.flush()
        out_str = out.getvalue()

        self.assertEqual(2, out_str.count("TEST_MSG"))

        client1.shutdown()
        client2.shutdown()
    def test_simple_custom_logging_configuration(self):
        logger_config = LoggerConfig()

        # Outputs to stdout with the level of error
        config_path = get_abs_path(self.CUR_DIR, "simple_config.json")
        logger_config.config_file = config_path

        self.assertEqual(config_path, logger_config.config_file)

        config = ClientConfig()
        config.cluster_name = self.cluster.id
        config.logger = logger_config

        client = HazelcastClient(config)
        self.assertEqual(logging.ERROR, client.logger.getEffectiveLevel())
        self.assertFalse(client.logger.isEnabledFor(logging.INFO))
        self.assertFalse(client.logger.isEnabledFor(logging.WARNING))
        self.assertTrue(client.logger.isEnabledFor(logging.ERROR))
        self.assertTrue(client.logger.isEnabledFor(logging.CRITICAL))

        out = StringIO()
        handler = logging.getLogger("HazelcastClient").handlers[0]
        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(0, 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_same_custom_configuration_file_with_multiple_clients(self):
        config = ClientConfig()
        config.cluster_name = self.cluster.id

        config_file = get_abs_path(self.CUR_DIR, "simple_config.json")
        config.logger.configuration_file = config_file

        client1 = HazelcastClient(config)
        client2 = HazelcastClient(config)

        out = StringIO()

        logging.getLogger("HazelcastClient").handlers[0].stream = out

        client1.logger.critical("TEST_MSG")
        client2.logger.critical("TEST_MSG")

        out.flush()
        out_str = out.getvalue()

        self.assertEqual(2, out_str.count("TEST_MSG"))

        client1.shutdown()
        client2.shutdown()
    def test_special_characters(self):
        config = ClientConfig()
        config.cluster_name = self.cluster.id
        config.set_property(ClientProperties.STATISTICS_ENABLED.name, True)
        config.set_property(ClientProperties.STATISTICS_PERIOD_SECONDS.name, self.STATS_PERIOD)

        map_name = random_string() + ",t=es\\t"

        near_cache_config = NearCacheConfig(map_name)
        config.near_caches[map_name] = near_cache_config

        client = HazelcastClient(config)
        client_uuid = client._connection_manager.client_uuid

        client.get_map(map_name).blocking()

        time.sleep(2 * self.STATS_PERIOD)
        response = self._wait_for_statistics_collection(client_uuid)

        result = response.result.decode("utf-8")
        unescaped_result = self._unescape_special_chars(result)
        self.assertEqual(-1, result.find(map_name))
        self.assertNotEqual(-1, unescaped_result.find(map_name))
        client.shutdown()
 def setUp(self):
     client_config = ClientConfig()
     client_config.cluster_name = self.cluster.id
     client_config.network.smart_routing = True
     self.client = self.create_client(client_config)
     self.collector = event_collector()