private void testHitsAndLastAccessTimeAreSetWithSingleNode(Config config) throws Exception {
    final TestHazelcastInstanceFactory nodeFactory = createHazelcastInstanceFactory(1);
    final HazelcastInstance instance1 = nodeFactory.newHazelcastInstance(config);

    final ReplicatedMap<Integer, Integer> map = instance1.getReplicatedMap(randomMapName());
    final int operations = 100;
    execute(
        new Runnable() {
          @Override
          public void run() {
            for (int i = 0; i < operations; i++) {
              map.put(i, i);
            }
          }
        },
        ADDED,
        operations,
        1,
        map);

    for (int i = 0; i < operations; i++) {
      map.containsKey(i);
    }

    for (int i = 0; i < operations; i++) {
      final ReplicatedRecord<Integer, Integer> replicatedRecord = getReplicatedRecord(map, i);
      assertEquals(1, replicatedRecord.getHits());
      assertTrue(
          "Last access time should be set for " + i, replicatedRecord.getLastAccessTime() > 0);
    }
  }
  private void testHitsAreZeroInitiallyWithSingleNode(Config config) throws Exception {
    final TestHazelcastInstanceFactory nodeFactory = createHazelcastInstanceFactory(1);
    final HazelcastInstance instance1 = nodeFactory.newHazelcastInstance(config);

    final ReplicatedMap<Integer, Integer> map = instance1.getReplicatedMap(randomMapName());
    final int operations = 100;
    execute(
        new Runnable() {
          @Override
          public void run() {
            for (int i = 0; i < operations; i++) {
              map.put(i, i);
            }
          }
        },
        ADDED,
        operations,
        1,
        map);

    for (int i = 0; i < operations; i++) {
      final ReplicatedRecord<Integer, Integer> replicatedRecord = getReplicatedRecord(map, i);
      assertEquals(0, replicatedRecord.getHits());
    }
  }
 private void assertRecord(ReplicatedRecord<Integer, Integer> record, long startTime) {
   long hits = record.getHits();
   long lastAccessTime = record.getLastAccessTime();
   long now = Clock.currentTimeMillis();
   assertTrue(String.format("Hits should be greater than 0: %d > %d", hits, 0), hits > 0);
   assertTrue(String.format("Hits should be less than 1000: %d < %d", hits, 1000), hits < 1000);
   assertTrue(
       String.format(
           "LastAccessTime should be greater than startTime: %d > %d", lastAccessTime, startTime),
       lastAccessTime > startTime);
   assertTrue(
       String.format(
           "LastAccessTime should be less or equal than current time: %d <= %d",
           lastAccessTime, now),
       lastAccessTime <= now);
 }
  private void testUpdateTtl(Config config) throws Exception {
    TestHazelcastInstanceFactory nodeFactory = createHazelcastInstanceFactory(2);

    HazelcastInstance instance1 = nodeFactory.newHazelcastInstance(config);
    HazelcastInstance instance2 = nodeFactory.newHazelcastInstance(config);

    final ReplicatedMap<String, String> map1 = instance1.getReplicatedMap("default");
    final ReplicatedMap<String, String> map2 = instance2.getReplicatedMap("default");

    final int operations = 100;
    WatchedOperationExecutor executor = new WatchedOperationExecutor();
    executor.execute(
        new Runnable() {
          @Override
          public void run() {
            for (int i = 0; i < operations; i++) {
              map1.put("foo-" + i, "bar");
            }
          }
        },
        60,
        EntryEventType.ADDED,
        operations,
        1,
        map1,
        map2);

    for (Entry<String, String> entry : map2.entrySet()) {
      assertStartsWith("foo-", entry.getKey());
      assertEquals("bar", entry.getValue());
    }
    for (Entry<String, String> entry : map1.entrySet()) {
      assertStartsWith("foo-", entry.getKey());
      assertEquals("bar", entry.getValue());
    }

    executor.execute(
        new Runnable() {
          @Override
          public void run() {
            for (int i = 0; i < operations; i++) {
              map2.put("foo-" + i, "bar", 10, TimeUnit.MINUTES);
            }
          }
        },
        60,
        EntryEventType.UPDATED,
        operations,
        1,
        map1,
        map2);

    int map2Updated = 0;
    for (Entry<String, String> entry : map2.entrySet()) {
      ReplicatedRecord record = getReplicatedRecord(map2, entry.getKey());
      if (record.getTtlMillis() > 0) {
        map2Updated++;
      }
    }
    int map1Updated = 0;
    for (Entry<String, String> entry : map1.entrySet()) {
      ReplicatedRecord record = getReplicatedRecord(map1, entry.getKey());
      if (record.getTtlMillis() > 0) {
        map1Updated++;
      }
    }

    assertMatchSuccessfulOperationQuota(1, operations, map1Updated, map2Updated);
  }
  private void testAddTtl(Config config) throws Exception {
    TestHazelcastInstanceFactory nodeFactory = createHazelcastInstanceFactory(2);

    HazelcastInstance instance1 = nodeFactory.newHazelcastInstance(config);
    HazelcastInstance instance2 = nodeFactory.newHazelcastInstance(config);

    final ReplicatedMap<String, String> map1 = instance1.getReplicatedMap("default");
    final ReplicatedMap<String, String> map2 = instance2.getReplicatedMap("default");

    final int operations = 100;
    WatchedOperationExecutor executor = new WatchedOperationExecutor();
    executor.execute(
        new Runnable() {
          @Override
          public void run() {
            for (int i = 0; i < operations; i++) {
              map1.put("foo-" + i, "bar", 10, TimeUnit.MINUTES);
            }
          }
        },
        60,
        EntryEventType.ADDED,
        operations,
        1,
        map1,
        map2);

    // Give a bit of time to process last batch of updates
    TimeUnit.SECONDS.sleep(2);

    Set<Entry<String, String>> map2entries = map2.entrySet();
    for (Entry<String, String> entry : map2entries) {
      assertStartsWith("foo-", entry.getKey());
      assertEquals("bar", entry.getValue());

      ReplicatedRecord<String, String> record = getReplicatedRecord(map2, entry.getKey());
      assertNotEquals(0, record.getTtlMillis());

      // Kill the record by setting timeout
      record.setValue(record.getValue(), 1);
    }

    Set<Entry<String, String>> map1entries = map1.entrySet();
    for (Entry<String, String> entry : map1entries) {
      assertStartsWith("foo-", entry.getKey());
      assertEquals("bar", entry.getValue());

      ReplicatedRecord<String, String> record = getReplicatedRecord(map1, entry.getKey());
      assertNotEquals(0, record.getTtlMillis());

      // Kill the record by setting timeout
      record.setValue(record.getValue(), 1);
    }

    TimeUnit.SECONDS.sleep(1);

    int map2Updated = 0;
    for (Entry<String, String> entry : map2entries) {
      if (map2.get(entry.getKey()) == null) {
        map2Updated++;
      }
    }

    int map1Updated = 0;
    for (Entry<String, String> entry : map1entries) {
      if (map1.get(entry.getKey()) == null) {
        map1Updated++;
      }
    }

    assertMatchSuccessfulOperationQuota(1, operations, map1Updated, map2Updated);
  }