@Test
  public void testClientDoesNotExpireEntryPrematurely() throws Exception {
    Host host = Host.getHost(0);
    VM vm0 = host.getVM(0);
    VM vm1 = host.getVM(1);
    final String name = getUniqueName() + "Region";
    final String key = "testKey";

    int port = createServerRegion(vm0, name, true);

    vm0.invoke(new SerializableCallable("create old entry") {
      @Override
      public Object call() throws Exception {
        LocalRegion r = (LocalRegion) basicGetCache().getRegion(name);
        r.put(key, "value");
        AbstractRegionEntry entry = (AbstractRegionEntry) r.basicGetEntry(key);
        // set an old timestamp in the entry - thirty minutes ago
        entry.getVersionStamp().setVersionTimeStamp(System.currentTimeMillis() - 1800000L);
        return null;
      }
    });

    createClientRegion(vm1, name, port, true, ClientRegionShortcut.CACHING_PROXY, false);

    vm1.invoke(new SerializableCallable("fetch entry and validate") {
      @Override
      public Object call() throws Exception {
        final Long[] expirationTimeMillis = new Long[1];
        int expirationSeconds = 1;

        LocalRegion r = (LocalRegion) basicGetCache().getRegion(name);
        AttributesMutator mutator = r.getAttributesMutator();
        mutator.setEntryIdleTimeout(
            new ExpirationAttributes(expirationSeconds, ExpirationAction.LOCAL_DESTROY));
        mutator.addCacheListener(new CacheListenerAdapter() {
          @Override
          public void afterDestroy(EntryEvent event) {
            expirationTimeMillis[0] = System.currentTimeMillis();
          }
        });

        final long expirationTime = System.currentTimeMillis() + (expirationSeconds * 1000);
        // Set the expiration time on the client entry.
        r.get(key);

        await("waiting for object to expire").until(() -> {
          return expirationTimeMillis[0] != null;
        });

        disconnectFromDS();

        assertTrue(
            "entry expired " + (expirationTime - expirationTimeMillis[0]) + " milliseconds early",
            expirationTimeMillis[0] >= expirationTime);

        return null;
      }
    });

    vm0.invoke(new SerializableRunnable() {
      @Override
      public void run() {
        disconnectFromDS();
      }
    });

  }
GEODE-3519 servers are not locking on remove or invalidate ops initiated by clients
<p>
This test sets up two servers each with a client attached. The clients perform operations on
the same key in a region which, in the servers, has Scope.GLOBAL. There should be no conflation
and each operation should obtain a lock.
geode-core/src/distributedTest/java/org/apache/geode/cache30/ClientServerCCEDUnitTest.java