@Test
  public void testTokenCleanup() {
    final String dlsName = getUniqueName();

    final VM vmGrantor = VM.getVM(0);
    final VM vm1 = VM.getVM(1);
    // final VM vm2 =VM.getVM(2);

    final String key1 = "key1";

    // vmGrantor creates grantor
    vmGrantor.invoke(new SerializableRunnable() {
      @Override
      public void run() {
        logger.info("[testTokenCleanup] vmGrantor creates grantor");
        connectDistributedSystem();
        DLockService dls = (DLockService) DistributedLockService.create(dlsName, getSystem());

        assertThat(dls.lock(key1, -1, -1)).isTrue();
        assertThat(dls.isLockGrantor()).isTrue();
        assertThat(dls.getToken(key1)).isNotNull();

        dls.unlock(key1);
        assertThat(dls.getToken(key1)).isNotNull();

        // token should be removed when freeResources is called
        dls.freeResources(key1);
        // assertThat(dls.getToken(key1)).isNull();

        DLockToken token = dls.getToken(key1);
        assertThat(token).withFailMessage("Failed with bug 38180: " + token).isNull();

        // make sure there are NO tokens at all
        Collection tokens = dls.getTokens();
        assertThat(tokens.size()).isEqualTo(0)
            .withFailMessage("Failed with bug 38180: tokens=" + tokens);
      }
    });

    // vm1 locks and frees key1
    vm1.invoke(new SerializableRunnable() {
      @Override
      public void run() {
        logger.info("[testTokenCleanup] vm1 locks key1");
        connectDistributedSystem();
        DLockService dls = (DLockService) DistributedLockService.create(dlsName, getSystem());

        assertThat(dls.lock(key1, -1, -1)).isTrue();
        assertThat(dls.isLockGrantor()).isFalse();
        assertThat(dls.getToken(key1)).isNotNull();

        dls.unlock(key1);
        assertThat(dls.getToken(key1)).isNotNull();

        dls.freeResources(key1);
        // assertThat(dls.getToken(key1)).isNull();

        DLockToken token = dls.getToken(key1);
        assertThat(token).withFailMessage("Failed with bug 38180: " + token).isNull();

        // make sure there are NO tokens at all
        Collection tokens = dls.getTokens();
        assertThat(tokens.size()).isEqualTo(0)
            .withFailMessage("Failed with bug 38180: tokens=" + tokens);
      }
    });

    // vm1 tests recursion
    vm1.invoke(new SerializableRunnable() {
      @Override
      public void run() {
        logger.info("[testTokenCleanup] vm1 tests recursion");
        connectDistributedSystem();
        DLockService dls = (DLockService) DistributedLockService.getServiceNamed(dlsName);

        assertThat(dls.lock(key1, -1, -1)).isTrue(); // 1
        assertThat(dls.getToken(key1).getUsageCount()).isEqualTo(1);
        assertThat(dls.lock(key1, -1, -1)).isTrue(); // 2
        assertThat(dls.getToken(key1).getUsageCount()).isEqualTo(2);
        assertThat(dls.lock(key1, -1, -1)).isTrue(); // 3
        assertThat(dls.getToken(key1).getUsageCount()).isEqualTo(3);

        DLockToken token0 = dls.getToken(key1);
        assertThat(token0).isNotNull();
        Collection tokens = dls.getTokens();
        assertThat(tokens.contains(token0)).isTrue();
        assertThat(tokens.size()).isEqualTo(1);

        dls.unlock(key1); // 1
        assertThat(dls.getToken(key1).getUsageCount()).isEqualTo(2);
        dls.freeResources(key1);

        DLockToken token1 = dls.getToken(key1);
        assertThat(token1).isNotNull();
        assertThat(token1).isEqualTo(token0);
        tokens = dls.getTokens();
        assertThat(tokens.contains(token1)).isTrue();
        assertThat(tokens.size()).isEqualTo(1);

        dls.unlock(key1); // 2
        assertThat(dls.getToken(key1).getUsageCount()).isEqualTo(1);
        dls.freeResources(key1);
        assertThat(dls.getToken(key1)).isNotNull();

        DLockToken token2 = dls.getToken(key1);
        assertThat(token2).isNotNull();
        assertThat(token2).isEqualTo(token0);
        tokens = dls.getTokens();
        assertThat(tokens.contains(token2)).isTrue();
        assertThat(tokens.size()).isEqualTo(1);

        dls.unlock(key1); // 3
        assertThat(dls.getToken(key1).getUsageCount()).isEqualTo(0);
        dls.freeResources(key1);

        DLockToken token3 = dls.getToken(key1);
        assertThat(token3).withFailMessage("Failed with bug 38180: " + token3).isNull();

        // make sure there are NO tokens at all
        tokens = dls.getTokens();
        assertThat(tokens.size()).isEqualTo(0)
            .withFailMessage("Failed with bug 38180: tokens=" + tokens);
      }
    });
  }
Client requests lock and then interrupts lock request before processing the grant reply. This
causes the Client to send a release msg to the grantor.
geode-core/src/distributedTest/java/org/apache/geode/distributed/DistributedLockServiceDUnitTest.java