Exemplo n.º 1
0
    def tearDown(self):
        """
        Setup (called on destroy)
        """

        SolBase.logging_init(log_level='DEBUG', force_reset=True)
        Meters.write_to_logger()
        SolBase.logging_init(log_level='INFO', force_reset=True)
Exemplo n.º 2
0
    def _internal_test(self,
                       client_count,
                       ping_interval_ms,
                       my_run_time_ms=20000):
        """
        Test.
        :param client_count: Client count.
        :param ping_interval_ms: Ping interval in millis.
        :param my_run_time_ms: Run time in millis.
        :return: nothing.
        """
        try:
            # Overrides statics (beuuurk but so gooood)
            self.clientMaxCount = client_count
            self.serverPingIntervalMs = ping_interval_ms
            self.clientPingIntervalMs = ping_interval_ms
            self.runTimeMs = my_run_time_ms

            # Expected server and client ping/src
            self.expectedPps = (float(self.clientMaxCount) /
                                float(self.serverPingIntervalMs)) * 1000.0

            logger.info("starting, client=%s, ping.ms=%s, expected.pps=%s",
                        client_count, ping_interval_ms, self.expectedPps)

            # Instance
            self.tcp_server = None

            try:
                # Start server
                self._start_server_and_check()

                # Start client, check and stop client
                self._start_multi_client_checkallping_stop()

                # Stop server
                self._stop_server_and_check()

            except Exception as e:
                logger.error("Exception in test, ex=%s", SolBase.extostr(e))
                raise
            finally:
                if self.tcp_server:
                    self.tcp_server.stop_server()
        finally:
            # Final stats
            logger.info("Finished, final stats bellow")
            Meters.write_to_logger()

            # Reset
            self.tcp_server = None

            # Sleep
            Utility.test_wait()
Exemplo n.º 3
0
    def test_meters_with_tags_b(self):
        """
        Test
        """

        hca = Meters._tags_hash_compute_and_store({"flag1": "FA"})
        hcb = Meters._tags_hash_compute_and_store({"flag2": "FB"})

        Meters.aii("ai1")
        Meters.aii("ai1", tags={"flag1": "FA"})
        Meters.aii("ai1", tags={"flag1": "FA"})
        Meters.aii("ai1", tags={"flag2": "FB"})
        Meters.aii("ai1", tags={"flag2": "FB"})
        Meters.aii("ai1", tags={"flag2": "FB"})

        Meters.dtci("dtc1", 0)
        Meters.dtci("dtc1", 50)
        Meters.dtci("dtc1", 100)
        self.assertEquals(Meters._hash_meter["dtc"]["dtc1#"]._sorted_dict[0].get(), 1)
        self.assertEquals(Meters._hash_meter["dtc"]["dtc1#"]._sorted_dict[50].get(), 1)
        self.assertEquals(Meters._hash_meter["dtc"]["dtc1#"]._sorted_dict[100].get(), 1)
        self.assertEquals(Meters._hash_meter["dtc"]["dtc1#"]._sorted_dict[500].get(), 0)

        Meters.dtci("dtc1", 0, tags={"flag1": "FA"})
        Meters.dtci("dtc1", 50, tags={"flag1": "FA"})
        Meters.dtci("dtc1", 100, tags={"flag1": "FA"})

        Meters.dtci("dtc1", 0, tags={"flag2": "FB"})
        Meters.dtci("dtc1", 50, tags={"flag2": "FB"})
        Meters.dtci("dtc1", 100, tags={"flag2": "FB"})
        Meters.dtci("dtc1", 0, tags={"flag2": "FB"})
        Meters.dtci("dtc1", 50, tags={"flag2": "FB"})
        Meters.dtci("dtc1", 100, tags={"flag2": "FB"})

        self.assertEquals(Meters._hash_meter["a_int"]["ai1#"].get(), 1)
        self.assertEquals(Meters._hash_meter["a_int"]["ai1#" + hca].get(), 2)
        self.assertEquals(Meters._hash_meter["a_int"]["ai1#" + hcb].get(), 3)

        self.assertEquals(Meters._hash_meter["dtc"]["dtc1#" + hca]._sorted_dict[0].get(), 1)
        self.assertEquals(Meters._hash_meter["dtc"]["dtc1#" + hca]._sorted_dict[50].get(), 1)
        self.assertEquals(Meters._hash_meter["dtc"]["dtc1#" + hca]._sorted_dict[100].get(), 1)
        self.assertEquals(Meters._hash_meter["dtc"]["dtc1#" + hca]._sorted_dict[500].get(), 0)

        self.assertEquals(Meters._hash_meter["dtc"]["dtc1#" + hcb]._sorted_dict[0].get(), 2)
        self.assertEquals(Meters._hash_meter["dtc"]["dtc1#" + hcb]._sorted_dict[50].get(), 2)
        self.assertEquals(Meters._hash_meter["dtc"]["dtc1#" + hcb]._sorted_dict[100].get(), 2)
        self.assertEquals(Meters._hash_meter["dtc"]["dtc1#" + hcb]._sorted_dict[500].get(), 0)

        # Write
        Meters.write_to_logger()
Exemplo n.º 4
0
    def test_meters(self):
        """
        Test
        """

        ai1a = Meters.ai("ai1")
        self.assertIsInstance(ai1a, AtomicIntSafe)
        ai1b = Meters.ai("ai1")
        self.assertEqual(id(ai1a), id(ai1b))

        ai1a = Meters.aii("ai1")
        self.assertEqual(ai1a.get(), 1)
        ai1a = Meters.aii("ai1", 2)
        self.assertEqual(ai1a.get(), 3)
        self.assertEqual(ai1a.get(), Meters.aig("ai1"))

        af1a = Meters.af("af1")
        self.assertIsInstance(af1a, AtomicFloatSafe)
        af1b = Meters.af("af1")
        self.assertEqual(id(af1a), id(af1b))

        af1a = Meters.afi("af1")
        self.assertEqual(af1a.get(), 1.0)
        af1a = Meters.afi("af1", 2.0)
        self.assertEqual(af1a.get(), 3.0)
        self.assertEqual(af1a.get(), Meters.afg("af1"))

        dtc1a = Meters.dtc("dtc1")
        self.assertIsInstance(dtc1a, DelayToCountSafe)
        dtc1b = Meters.dtc("dtc1")
        self.assertEqual(id(dtc1a), id(dtc1b))

        Meters.dtci("dtc1", 0)
        Meters.dtci("dtc1", 50)
        Meters.dtci("dtc1", 100)
        self.assertEquals(Meters._hash_meter["dtc"]["dtc1#"]._sorted_dict[0].get(), 1)
        self.assertEquals(Meters._hash_meter["dtc"]["dtc1#"]._sorted_dict[50].get(), 1)
        self.assertEquals(Meters._hash_meter["dtc"]["dtc1#"]._sorted_dict[100].get(), 1)
        self.assertEquals(Meters._hash_meter["dtc"]["dtc1#"]._sorted_dict[500].get(), 0)

        Meters.dtc("dtc1").to_dict()

        # Write
        Meters.write_to_logger()
Exemplo n.º 5
0
    def test_meters_to_udp(self):
        """
        Test
        """

        ai1a = Meters.ai("ai1")
        self.assertIsInstance(ai1a, AtomicIntSafe)
        ai1b = Meters.ai("ai1")
        self.assertEqual(id(ai1a), id(ai1b))

        ai1a = Meters.aii("ai1")
        self.assertEqual(ai1a.get(), 1)
        ai1a = Meters.aii("ai1", 2)
        self.assertEqual(ai1a.get(), 3)
        self.assertEqual(ai1a.get(), Meters.aig("ai1"))

        af1a = Meters.af("af1")
        self.assertIsInstance(af1a, AtomicFloatSafe)
        af1b = Meters.af("af1")
        self.assertEqual(id(af1a), id(af1b))

        af1a = Meters.afi("af1")
        self.assertEqual(af1a.get(), 1.0)
        af1a = Meters.afi("af1", 2.0)
        self.assertEqual(af1a.get(), 3.0)
        self.assertEqual(af1a.get(), Meters.afg("af1"))

        dtc1a = Meters.dtc("dtc1")
        self.assertIsInstance(dtc1a, DelayToCountSafe)
        dtc1b = Meters.dtc("dtc1")
        self.assertEqual(id(dtc1a), id(dtc1b))

        Meters.dtci("dtc1", 0)
        Meters.dtci("dtc1", 50)
        Meters.dtci("dtc1", 100)
        self.assertEquals(Meters._hash_meter["dtc"]["dtc1#"]._sorted_dict[0].get(), 1)
        self.assertEquals(Meters._hash_meter["dtc"]["dtc1#"]._sorted_dict[50].get(), 1)
        self.assertEquals(Meters._hash_meter["dtc"]["dtc1#"]._sorted_dict[100].get(), 1)
        self.assertEquals(Meters._hash_meter["dtc"]["dtc1#"]._sorted_dict[500].get(), 0)

        # Write
        Meters.write_to_logger()

        # Serialize
        ar_json = Meters.meters_to_udp_format(send_pid=True, send_dtc=True)
        logger.info("Got ar_json=%s", ar_json)
        for cur_ar in ar_json:
            logger.info("Got cur_ar=%s", cur_ar)

        # Serialize, no dtc
        ar_json = Meters.meters_to_udp_format(send_pid=True, send_dtc=False)
        logger.info("Got ar_json=%s", ar_json)
        for cur_ar in ar_json:
            logger.info("Got cur_ar=%s", cur_ar)

        # Send to daemon (assuming its up locally)
        Meters.send_udp_to_knockdaemon()
        Meters.send_udp_to_knockdaemon(send_dtc=True)
        Meters.send_udp_to_knockdaemon(send_dtc=False)

        # ------------------------
        # UDP Scheduler test
        # ------------------------

        # Check
        self.assertIsNone(Meters.UDP_SCHEDULER_GREENLET)
        self.assertFalse(Meters.UDP_SCHEDULER_STARTED)

        # Start
        Meters.udp_scheduler_start(send_interval_ms=500)

        # Check
        self.assertIsNotNone(Meters.UDP_SCHEDULER_GREENLET)
        self.assertTrue(Meters.UDP_SCHEDULER_STARTED)

        # Start again
        Meters.udp_scheduler_start(send_interval_ms=500)

        # Check again
        self.assertIsNotNone(Meters.UDP_SCHEDULER_GREENLET)
        self.assertTrue(Meters.UDP_SCHEDULER_STARTED)

        # Interval is 500 => we sleep 3.250 sec, we assume we must have at least 500, 1000, 1500, 2000, 2500, 3000 run => 6 runs
        SolBase.sleep(3250)

        # Check
        self.assertGreaterEqual(Meters.aig("k.meters.udp.run.ok"), 6)
        self.assertEqual(Meters.aig("k.meters.udp.run.ex"), 0)
        self.assertIsNotNone(Meters.UDP_SCHEDULER_GREENLET)
        self.assertTrue(Meters.UDP_SCHEDULER_STARTED)

        # We stop
        Meters.udp_scheduler_stop()
        self.assertIsNone(Meters.UDP_SCHEDULER_GREENLET)
        self.assertFalse(Meters.UDP_SCHEDULER_STARTED)

        # Sleep again and check no more running
        cur_run = Meters.aig("k.meters.udp.run.ok")
        SolBase.sleep(2000)
        self.assertEqual(cur_run, Meters.aig("k.meters.udp.run.ok"))
Exemplo n.º 6
0
    def test_meters_with_tags_a_with_udp_check(self):
        """
        Test
        """

        hca = Meters._tags_hash_compute_and_store({"flag": "FA"})
        hcb = Meters._tags_hash_compute_and_store({"flag": "FB"})

        Meters.aii("ai1")
        Meters.aii("ai1", tags={"flag": "FA"})
        Meters.aii("ai1", tags={"flag": "FA"})
        Meters.aii("ai1", tags={"flag": "FB"})
        Meters.aii("ai1", tags={"flag": "FB"})
        Meters.aii("ai1", tags={"flag": "FB"})

        Meters.dtci("dtc1", 0)
        Meters.dtci("dtc1", 50)
        Meters.dtci("dtc1", 100)
        self.assertEquals(Meters._hash_meter["dtc"]["dtc1#"]._sorted_dict[0].get(), 1)
        self.assertEquals(Meters._hash_meter["dtc"]["dtc1#"]._sorted_dict[50].get(), 1)
        self.assertEquals(Meters._hash_meter["dtc"]["dtc1#"]._sorted_dict[100].get(), 1)
        self.assertEquals(Meters._hash_meter["dtc"]["dtc1#"]._sorted_dict[500].get(), 0)

        Meters.dtci("dtc1", 0, tags={"flag": "FA"})
        Meters.dtci("dtc1", 50, tags={"flag": "FA"})
        Meters.dtci("dtc1", 100, tags={"flag": "FA"})

        Meters.dtci("dtc1", 0, tags={"flag": "FB"})
        Meters.dtci("dtc1", 50, tags={"flag": "FB"})
        Meters.dtci("dtc1", 100, tags={"flag": "FB"})
        Meters.dtci("dtc1", 0, tags={"flag": "FB"})
        Meters.dtci("dtc1", 50, tags={"flag": "FB"})
        Meters.dtci("dtc1", 100, tags={"flag": "FB"})

        self.assertEquals(Meters._hash_meter["a_int"]["ai1#"].get(), 1)
        self.assertEquals(Meters._hash_meter["a_int"]["ai1#" + hca].get(), 2)
        self.assertEquals(Meters._hash_meter["a_int"]["ai1#" + hcb].get(), 3)

        self.assertEquals(Meters._hash_meter["dtc"]["dtc1#" + hca]._sorted_dict[0].get(), 1)
        self.assertEquals(Meters._hash_meter["dtc"]["dtc1#" + hca]._sorted_dict[50].get(), 1)
        self.assertEquals(Meters._hash_meter["dtc"]["dtc1#" + hca]._sorted_dict[100].get(), 1)
        self.assertEquals(Meters._hash_meter["dtc"]["dtc1#" + hca]._sorted_dict[500].get(), 0)

        self.assertEquals(Meters._hash_meter["dtc"]["dtc1#" + hcb]._sorted_dict[0].get(), 2)
        self.assertEquals(Meters._hash_meter["dtc"]["dtc1#" + hcb]._sorted_dict[50].get(), 2)
        self.assertEquals(Meters._hash_meter["dtc"]["dtc1#" + hcb]._sorted_dict[100].get(), 2)
        self.assertEquals(Meters._hash_meter["dtc"]["dtc1#" + hcb]._sorted_dict[500].get(), 0)

        # Write
        Meters.write_to_logger()

        # Upd check
        ar_udp = Meters.meters_to_udp_format(send_pid=True, send_tags=True, send_dtc=True)

        total_check = 0
        total_ok = 0
        total_ko_not_found = 0
        total_ko_multiple_found = 0
        for s_key, d_tag, v in [
            ("ai1", {}, 1),
            ("ai1", {"flag": "FA", }, 2),
            ("ai1", {"flag": "FB", }, 3),

            ("dtc1_0-50", {}, 1),
            ("dtc1_50-100", {}, 1),
            ("dtc1_100-500", {}, 1),
            ("dtc1_500-1000", {}, 0),
            ("dtc1_1000-2500", {}, 0),
            ("dtc1_2500-5000", {}, 0),
            ("dtc1_5000-10000", {}, 0),
            ("dtc1_10000-30000", {}, 0),
            ("dtc1_30000-60000", {}, 0),
            ("dtc1_60000-MAX", {}, 0),

            ("dtc1_0-50", {"flag": "FA", }, 1),
            ("dtc1_50-100", {"flag": "FA", }, 1),
            ("dtc1_100-500", {"flag": "FA", }, 1),
            ("dtc1_500-1000", {"flag": "FA", }, 0),
            ("dtc1_1000-2500", {"flag": "FA", }, 0),
            ("dtc1_2500-5000", {"flag": "FA", }, 0),
            ("dtc1_5000-10000", {"flag": "FA", }, 0),
            ("dtc1_10000-30000", {"flag": "FA", }, 0),
            ("dtc1_30000-60000", {"flag": "FA", }, 0),
            ("dtc1_60000-MAX", {"flag": "FA", }, 0),

            ("dtc1_0-50", {"flag": "FB", }, 2),
            ("dtc1_50-100", {"flag": "FB", }, 2),
            ("dtc1_100-500", {"flag": "FB", }, 2),
            ("dtc1_500-1000", {"flag": "FB", }, 0),
            ("dtc1_1000-2500", {"flag": "FB", }, 0),
            ("dtc1_2500-5000", {"flag": "FB", }, 0),
            ("dtc1_5000-10000", {"flag": "FB", }, 0),
            ("dtc1_10000-30000", {"flag": "FB", }, 0),
            ("dtc1_30000-60000", {"flag": "FB", }, 0),
            ("dtc1_60000-MAX", {"flag": "FB", }, 0),

        ]:
            total_check += 1

            # Locate it
            found = 0
            for check_key, check_tag, check_v, _, _ in ar_udp:
                if check_key == s_key and check_tag == d_tag and check_v == v:
                    found += 1

            # Check
            if found == 0:
                total_ko_not_found += 1
            elif found > 1:
                total_ko_multiple_found += 1
            else:
                total_ok += 1

        # Final
        self.assertEquals(total_ko_multiple_found, 0)
        self.assertEquals(total_ko_multiple_found, 0)
        self.assertEquals(total_ok, total_check)
        self.assertEquals(len(ar_udp), total_check)
Exemplo n.º 7
0
    def _go_greenlet(self, greenlet_count, put_count, get_count,
                     bench_item_count):
        """
        Doc
        :param greenlet_count: greenlet_count
        :param put_count: put_count
        :param get_count: get_count
        :param bench_item_count: bench_item_count
        """

        g_event = None
        g_array = None
        try:
            # Settings
            g_count = greenlet_count
            g_ms = 10000

            # Continue callback loop
            self.callback_return = True

            # Go
            self.redis_cache = RedisCache()

            # Item count
            self.bench_item_count = bench_item_count
            self.bench_put_weight = put_count
            self.bench_get_weight = get_count
            self.bench_ttl_min_ms = 1000
            self.bench_ttl_max_ms = int(g_ms / 2)

            # Go
            self.run_event = Event()
            self.exception_raised = 0
            self.open_count = 0
            self.thread_running = AtomicIntSafe()
            self.thread_running_ok = AtomicIntSafe()

            # Item per greenlet
            item_per_greenlet = self.bench_item_count / g_count

            # Signal
            self.gorun_event = Event()

            # Alloc greenlet
            g_array = list()
            g_event = list()
            for _ in range(0, g_count):
                greenlet = Greenlet()
                g_array.append(greenlet)
                g_event.append(Event())

            # Run them
            cur_idx = 0
            for idx in range(0, len(g_array)):
                greenlet = g_array[idx]
                event = g_event[idx]
                greenlet.spawn(self._run_cache_bench, event, cur_idx,
                               cur_idx + item_per_greenlet)
                cur_idx += item_per_greenlet
                SolBase.sleep(0)

            # Signal
            self.gorun_event.set()

            # Wait a bit
            dt = SolBase.mscurrent()
            while SolBase.msdiff(dt) < g_ms:
                SolBase.sleep(500)
                # Stat
                ms = SolBase.msdiff(dt)
                sec = float(ms / 1000.0)
                total_put = Meters.aig("rcs.cache_put")
                per_sec_put = round(float(total_put) / sec, 2)
                total_get = Meters.aig("rcs.cache_get_hit") + Meters.aig(
                    "rcs.cache_get_miss")
                per_sec_get = round(float(total_get) / sec, 2)

                logger.info(
                    "Running..., count=%s, run=%s, ok=%s, put/sec=%s get/sec=%s, cache=%s",
                    self.open_count, self.thread_running.get(),
                    self.thread_running_ok.get(), per_sec_put, per_sec_get,
                    self.redis_cache)
                self.assertEqual(self.exception_raised, 0)

            # Over, signal
            logger.info("Signaling, count=%s", self.open_count)
            self.run_event.set()

            # Wait
            for g in g_event:
                g.wait(30.0)
                self.assertTrue(g.isSet())

            g_event = None
            g_array = None

            # Log
            Meters.write_to_logger()
        finally:
            self.run_event.set()
            if g_event:
                for g in g_event:
                    g.set()

            if g_array:
                for g in g_array:
                    g.kill()

            if self.redis_cache:
                self.redis_cache.stop_cache()
                self.redis_cache = None
Exemplo n.º 8
0
    def _start_multi_client_checkallping_stop(self):
        """
        Test

        """

        # Start
        self._start_multi_client(self.clientMaxCount)

        # Here we must wait
        # 1) Client : already connected, must
        #       - send hello, have a reply
        #       - send a ping, have a reply
        #       - reply to one server ping
        # 2) Server
        #       - receive a hello and reply
        #       - send a ping, have a reply
        #       - reply to one client ping
        # => We check using the static PingStatXXX

        flush_stat_inloop = False
        dt = SolBase.datecurrent()
        dt_stat = SolBase.datecurrent()
        dt_loop = SolBase.datecurrent()
        client_prev_completed_ping = 0
        server_prev_completed_ping = 0
        while SolBase.datediff(dt) < self.runTimeMs:
            # Wait
            SolBase.sleep(1000)

            # Client
            client_ko = PingTestTools.get_client_ko_count(
                False, self.clientMaxCount)

            # Server
            server_ko = PingTestTools.get_server_ko_count(
                False, self.clientMaxCount)

            # Total ping
            client_total_completed_ping = Meters.aig(
                "ping.client.client_ping_server_reply")
            server_total_completed_ping = Meters.aig(
                "ping.server.serverPingClientReply")

            # Current ping
            client_local_completed_ping = client_total_completed_ping - client_prev_completed_ping
            server_local_completed_ping = server_total_completed_ping - server_prev_completed_ping

            # Store prev
            client_prev_completed_ping = client_total_completed_ping
            server_prev_completed_ping = server_total_completed_ping

            # Elapsed ms
            elapsed_ms = SolBase.datediff(dt_loop)
            elapsed_total_ms = SolBase.datediff(dt)

            # Ping per sec.
            client_local_pps = (client_local_completed_ping /
                                (elapsed_ms / 1000.0))
            server_local_pps = (server_local_completed_ping /
                                (elapsed_ms / 1000.0))

            client_avg_pps = (client_total_completed_ping /
                              (elapsed_total_ms / 1000.0))
            server_avg_pps = (server_total_completed_ping /
                              (elapsed_total_ms / 1000.0))

            # Reset date
            dt_loop = SolBase.datecurrent()

            # Wait
            logger.info(
                "Running : ko=%s:%s, sec=%s/%s, cli.ping=%s, svr.ping=%s, exp.pps=%.2f, "
                "cli.pps=%.2f, svr.pps=%.2f, cli.aps=%.2f, svr.aps=%.2f",
                client_ko, server_ko, int(SolBase.datediff(dt) / 1000),
                int(self.runTimeMs / 1000), client_local_completed_ping,
                server_local_completed_ping, self.expectedPps,
                client_local_pps, server_local_pps, client_avg_pps,
                server_avg_pps)

            # Stat
            if flush_stat_inloop and SolBase.datediff(
                    dt_stat) > self.statEveryMs:
                Meters.write_to_logger()
                dt_stat = SolBase.datecurrent()

        # Final check
        client_ko = PingTestTools.get_client_ko_count(True,
                                                      self.clientMaxCount)
        server_ko = PingTestTools.get_server_ko_count(True,
                                                      self.clientMaxCount)
        self.assertEqual(client_ko, 0)
        self.assertEqual(server_ko, 0)

        # Stop
        self._stop_multi_client()
Exemplo n.º 9
0
    def _go_greenlet(self,
                     greenlet_count,
                     put_count,
                     get_count,
                     bench_item_count,
                     watchdog_interval_ms=60000,
                     max_item=128000,
                     max_bytes=32 * 1024 * 1024,
                     max_single_item_bytes=1 * 1024 * 1024,
                     purge_min_bytes=8 * 1024 * 1024,
                     purge_min_count=1000):
        """
        Doc
        :param greenlet_count: greenlet_count
        :param put_count: put_count
        :param get_count: get_count
        :param bench_item_count: bench_item_count
        :param watchdog_interval_ms: watchdog_interval_ms
        :param max_item: max_item
        :param max_bytes: max_bytes
        :param max_single_item_bytes: max_single_item_bytes
        :param purge_min_bytes: purge_min_bytes
        :param purge_min_count: purge_min_count
        """

        g_event = None
        g_array = None
        try:
            # Settings
            g_count = greenlet_count
            g_ms = 10000

            # Continue callback loop
            self.callback_return = True

            # Go
            self.mem_cache = MemoryCache(
                watchdog_interval_ms=watchdog_interval_ms,
                max_item=max_item,
                max_bytes=max_bytes,
                max_single_item_bytes=max_single_item_bytes,
                purge_min_bytes=purge_min_bytes,
                purge_min_count=purge_min_count)

            # Item count
            self.bench_item_count = bench_item_count
            self.bench_put_weight = put_count
            self.bench_get_weight = get_count
            self.bench_ttl_min_ms = 1000
            self.bench_ttl_max_ms = int(g_ms / 2)

            # Go
            self.run_event = Event()
            self.exception_raised = 0
            self.open_count = 0
            self.thread_running = AtomicIntSafe()
            self.thread_running_ok = AtomicIntSafe()

            # Item per greenlet
            item_per_greenlet = self.bench_item_count / g_count

            # Signal
            self.gorun_event = Event()

            # Alloc greenlet
            g_array = list()
            g_event = list()
            for _ in range(0, g_count):
                greenlet = Greenlet()
                g_array.append(greenlet)
                g_event.append(Event())

            # Run them
            cur_idx = 0
            for idx in range(0, len(g_array)):
                greenlet = g_array[idx]
                event = g_event[idx]
                greenlet.spawn(self._run_cache_bench, event, cur_idx,
                               cur_idx + item_per_greenlet)
                cur_idx += item_per_greenlet
                SolBase.sleep(0)

            # Signal
            self.gorun_event.set()

            # Wait a bit
            dt = SolBase.mscurrent()
            while SolBase.msdiff(dt) < g_ms:
                SolBase.sleep(500)
                # Stat
                ms = SolBase.msdiff(dt)
                sec = float(ms / 1000.0)
                total_put = Meters.aig("mcs.cache_put")
                per_sec_put = round(float(total_put) / sec, 2)
                total_get = Meters.aig("mcs.cache_get_hit") + Meters.aig(
                    "mcs.cache_get_miss")
                per_sec_get = round(float(total_get) / sec, 2)

                logger.info(
                    "Running..., count=%s, run=%s, ok=%s, put/sec=%s get/sec=%s, cache=%s",
                    self.open_count, self.thread_running.get(),
                    self.thread_running_ok.get(), per_sec_put, per_sec_get,
                    self.mem_cache)
                self.assertEqual(self.exception_raised, 0)

            # Over, signal
            logger.info("Signaling, count=%s", self.open_count)
            self.run_event.set()

            # Wait
            for g in g_event:
                g.wait(30.0)
                self.assertTrue(g.isSet())

            g_event = None
            g_array = None

            # Log
            Meters.write_to_logger()
        finally:
            self.run_event.set()
            if g_event:
                for g in g_event:
                    g.set()

            if g_array:
                for g in g_array:
                    g.kill()

            if self.mem_cache:
                max_count = 0
                total_size = 0
                i = 0
                for (k, v) in self.mem_cache._hash_key.items():
                    i += 1
                    total_size += len(k) + len(v[1])
                    if i < max_count:
                        logger.info("%s => %s", k, v)
                self.assertEqual(total_size,
                                 self.mem_cache._current_data_bytes.get())

                self.mem_cache.stop_cache()
                self.mem_cache = None