@Test
  public void testTwoDurableClientsStartStopUpdate() throws InterruptedException {
    // Start a server
    server1Port = server1VM
        .invoke(() -> createCacheServer(regionName, true));

    // Start a durable client that is kept alive on the server when it stops
    // normally
    final String durableClientId = getName() + "_client";
    final int durableClientTimeout = 60; // keep the client alive for 60 seconds
    // final boolean durableClientKeepAlive = true; // keep the client alive when it stops normally
    durableClientVM.invoke(() -> createCacheClient(
        getClientPool(getServerHostName(), server1Port, true), regionName,
        getClientDistributedSystemProperties(durableClientId, durableClientTimeout),
        true));

    // Send clientReady message
    sendClientReady(durableClientVM);

    registerInterest(durableClientVM, regionName, true, NONE);

    // Start another durable client that is not kept alive on the server when
    // it stops normally. Use the 'server2VM' as the second durable client.
    VM durableClient2VM = server2VM;
    final String durableClientId2 = getName() + "_client2";
    durableClient2VM.invoke(() -> createCacheClient(
        getClientPool(getServerHostName(), server1Port, true), regionName,
        getClientDistributedSystemProperties(durableClientId2, durableClientTimeout),
        true));

    // Send clientReady message
    sendClientReady(durableClient2VM);

    registerInterest(durableClient2VM, regionName, true, NONE);

    // Verify durable clients on server
    verifyMultupleDurableClients(durableClientId, durableClientId2);

    // Start normal publisher client
    publisherClientVM.invoke(() -> createCacheClient(
        getClientPool(getServerHostName(), server1Port, false),
        regionName));

    // Publish some entries
    final int numberOfEntries = 10;
    publishEntries(publisherClientVM, 0, numberOfEntries);

    // Verify durable client 1 received the updates
    checkListenerEvents(numberOfEntries, 1, -1, durableClientVM);

    // Verify durable client 2 received the updates
    checkListenerEvents(numberOfEntries, 1, -1, durableClient2VM);

    // ARB: Wait for queue ack to arrive at server.
    sleep(1000);

    // Stop the durable clients
    durableClientVM.invoke(() -> CacheServerTestUtil.closeCache(true));
    durableClient2VM.invoke(() -> CacheServerTestUtil.closeCache(true));

    // Verify the durable clients still exist on the server
    verifyMultupleDurableClients(durableClientId, durableClientId2);

    // Publish some more entries
    publishEntries(publisherClientVM, 10, numberOfEntries);

    sleep(1000);

    // Verify the durable clients' queues contain the entries
    server1VM.invoke("Verify durable client", new CacheSerializableRunnable() {
      @Override
      public void run2() throws CacheException {
        // Get the CacheClientNotifier
        CacheClientNotifier notifier = getBridgeServer().getAcceptor().getCacheClientNotifier();

        // Iterate the CacheClientProxies and verify the queue sizes
        checkNumberOfClientProxies(2);
        for (CacheClientProxy proxy : notifier.getClientProxies()) {
          assertThat(proxy.getQueueSize()).isEqualTo(numberOfEntries);
        }
      }
    });

    // Re-start durable client 1
    durableClientVM.invoke(() -> createCacheClient(
        getClientPool(getServerHostName(), server1Port, true), regionName,
        getClientDistributedSystemProperties(durableClientId), true));

    // Send clientReady message
    sendClientReady(durableClientVM);

    // Re-start durable client 2
    durableClient2VM.invoke(() -> createCacheClient(
        getClientPool(getServerHostName(), server1Port, true), regionName,
        getClientDistributedSystemProperties(durableClientId2), true));

    // Send clientReady message
    sendClientReady(durableClient2VM);

    // Verify durable client 1 received the updates held for it on the server
    checkListenerEvents(numberOfEntries, 1, -1, durableClientVM);

    // Verify durable client 2 received the updates held for it on the server
    checkListenerEvents(numberOfEntries, 1, -1, durableClientVM);

    // Stop durable client 1
    durableClientVM.invoke((SerializableRunnableIF) CacheServerTestUtil::closeCache);

    // Stop durable client 2
    durableClient2VM.invoke((SerializableRunnableIF) CacheServerTestUtil::closeCache);

    // Stop the publisher client
    publisherClientVM.invoke((SerializableRunnableIF) CacheServerTestUtil::closeCache);

    // Stop the server
    server1VM.invoke((SerializableRunnableIF) CacheServerTestUtil::closeCache);
  }
Test that updates to two durable clients are processed correctly.
geode-cq/src/distributedTest/java/org/apache/geode/internal/cache/tier/sockets/DurableClientSimpleDUnitTest.java