@Test
  public void testIndexDoesNotReturnStaleResultsAfterSplit() {
    String mapName = randomMapName();
    Config config = newConfig(LatestUpdateMapMergePolicy.class.getName(), mapName);
    HazelcastInstance h1 = Hazelcast.newHazelcastInstance(config);
    HazelcastInstance h2 = Hazelcast.newHazelcastInstance(config);

    TestMembershipListener membershipListener = new TestMembershipListener(1);
    h2.getCluster().addMembershipListener(membershipListener);
    TestLifecycleListener lifecycleListener = new TestLifecycleListener(1);
    h2.getLifecycleService().addLifecycleListener(lifecycleListener);

    RealtimeCall call = new RealtimeCall();
    String key = generateKeyOwnedBy(h1);
    call.setId(key);
    call.setClusterUUID(key);

    IMap<PartitionAwareKey<String, String>, RealtimeCall> map1 = h1.getMap(mapName);
    IMap<PartitionAwareKey<String, String>, RealtimeCall> map2 = h2.getMap(mapName);

    map1.put(call.getAffinityKey(), call);

    sleepMillis(1);
    assertNotNull("entry should be in map2 before split", map2.get(call.getAffinityKey()));

    closeConnectionBetween(h1, h2);

    assertOpenEventually(membershipListener.latch);
    assertClusterSizeEventually(1, h1);
    assertClusterSizeEventually(1, h2);

    map1 = h1.getMap(mapName);
    map1.remove(call.getAffinityKey());

    sleepMillis(1);
    map2 = h2.getMap(mapName);
    assertNotNull("entry should be in map2 in split", map2.get(call.getAffinityKey()));

    assertOpenEventually(lifecycleListener.latch);
    assertClusterSizeEventually(2, h1);
    assertClusterSizeEventually(2, h2);

    map1 = h1.getMap(mapName);
    assertNotNull("entry should be in map1", map1.get(call.getAffinityKey()));

    map1.remove(call.getAffinityKey());
    assertNull("map1 should be null", map1.get(call.getAffinityKey()));
    assertNull("map2 should be null", map2.get(call.getAffinityKey()));

    for (int i = 0; i < 100; i++) {
      Collection<RealtimeCall> calls = map1.values(Predicates.equal("id", call.getId()));
      System.out.println("Map 1 query by uuid: " + calls.size());
      assert calls.size() == 0;
      calls = map2.values(Predicates.equal("id", call.getId()));
      System.out.println("Map 2 query by uuid: " + calls.size());
      assert calls.size() == 0;
      sleepMillis(5);
    }
  }
 @Test
 public void null_collection_length_reduced() {
   execute(
       Input.of(HUNT_NULL_LIMB),
       Query.of(Predicates.equal("limbs_[any].fingers_.length", 1), mv),
       Expected.empty());
 }
 @Test
 public void null_collection_length_compared_to_null() {
   execute(
       Input.of(HUNT_NULL_LIMB),
       Query.of(Predicates.equal("limbs_[0].fingers_.length", null), mv),
       Expected.of(HUNT_NULL_LIMB));
 }
 @Test
 public void length_property_atLeaf() {
   execute(
       Input.of(BOND, KRUEGER),
       Query.of(Predicates.equal("limbs_[0].tattoos_.length", 1), mv),
       Expected.of(KRUEGER));
 }
 @Test
 public void length_property() {
   execute(
       Input.of(BOND, KRUEGER),
       Query.of(Predicates.equal("limbs_.length", 2), mv),
       Expected.of(BOND, KRUEGER));
 }
 @Test
 public void null_collection_length_atLeaf_reduced_compared_to_null() {
   execute(
       Input.of(HUNT_NULL_TATTOOS),
       Query.of(Predicates.equal("limbs_[any].tattoos_.length", null), mv),
       Expected.of(HUNT_NULL_TATTOOS));
 }
 @Test
 public void null_collection_length_atLeaf() {
   execute(
       Input.of(HUNT_NULL_TATTOOS),
       Query.of(Predicates.equal("limbs_[0].tattoos_.length", 1), mv),
       Expected.empty());
 }
    @Override
    protected void timeStep(Operation operation) throws Exception {
      int key = getRandomKey();

      switch (operation) {
        case PUT:
          SillySequence sillySequence = new SillySequence(key, nestedValuesCount);
          map.put(key, sillySequence);
          break;
        case QUERY:
          int index = key % nestedValuesCount;
          String query = format("payloadFromExtractor[%d]", index);
          Predicate predicate = Predicates.equal(query, key);
          queryProbe.started();
          Collection<SillySequence> result = null;
          try {
            result = map.values(predicate);
          } finally {
            queryProbe.done();
          }
          THROTTLING_LOGGER.info(
              format(
                  "Query 'payloadFromExtractor[%d]= %d' returned %d results.",
                  index, key, result.size()));
          for (SillySequence resultSillySequence : result) {
            assertValidSequence(key, resultSillySequence);
          }
          break;
        default:
          throw new UnsupportedOperationException("Unsupported operation: " + operation);
      }
    }
  @Test
  public void runFullQuery() throws Exception {
    Predicate predicate = Predicates.equal("this", value);
    QueryResult result = queryRunner.run(map.getName(), predicate, ENTRY);

    assertEquals(1, result.getRows().size());
    assertEquals(map.get(key), toObject(result.getRows().iterator().next().getValue()));
  }
  @Test
  public void runPartitionScanQueryOnSinglePartition() {
    Predicate predicate = Predicates.equal("this", value);
    QueryResult result =
        queryRunner.runUsingPartitionScanOnSinglePartition(
            map.getName(), predicate, partitionId, ENTRY);

    assertEquals(1, result.getRows().size());
    assertEquals(map.get(key), toObject(result.getRows().iterator().next().getValue()));
  }
    private void pagingPredicate() {
      double maxSal = getRandom().nextDouble() * Employee.MAX_SALARY;

      Predicate predicate = Predicates.lessThan("salary", maxSal);
      PagingPredicate pagingPredicate = new PagingPredicate(predicate, pageSize);

      Collection<Employee> employees;
      do {
        employees = map.values(pagingPredicate);
        for (Employee emp : employees) {
          assertTrue(
              basename + ": " + emp + " not matching " + predicate, emp.getSalary() < maxSal);
        }
        pagingPredicate.nextPage();
      } while (!employees.isEmpty());

      operationCounter.pagePredicateCount++;
    }