@Test
  public void testTxRemoveAll() {
    Host host = Host.getHost(0);
    VM acc = host.getVM(0);
    VM datastore = host.getVM(1);
    initAccessorAndDataStore(acc, datastore, 0);
    VM accessor = getVMForTransactions(acc, datastore);

    final CustId custId1 = new CustId(1);
    final CustId custId2 = new CustId(2);
    final CustId custId20 = new CustId(20);
    final TXId txId = (TXId) accessor.invoke(new SerializableCallable<Object>() {
      @Override
      public Object call() {
        Region<CustId, Customer> cust = getCache().getRegion(CUSTOMER);
        Region<CustId, Customer> ref = getCache().getRegion(D_REFERENCE);
        TXManagerImpl mgr = getCache().getTxManager();
        mgr.begin();
        Customer customer = new Customer("customer1", "address1");
        Customer customer2 = new Customer("customer2", "address2");
        Customer fakeCust = new Customer("foo2", "bar2");
        cust.removeAll(Arrays.asList(custId1, custId2, custId20));
        ref.removeAll(Arrays.asList(custId1, custId2, custId20));
        TXStateProxy tx = mgr.pauseTransaction();
        assertThat(cust.get(custId1)).isNotNull();
        assertThat(ref.get(custId2)).isNotNull();
        mgr.unpauseTransaction(tx);
        return mgr.suspend();
      }
    });
    datastore.invoke(new SerializableCallable<Object>() {
      @Override
      public Object call() {
        TXManagerImpl mgr = getCache().getTxManager();
        assertThat(mgr.isHostedTxInProgress(txId)).isTrue();
        TXStateProxy tx = mgr.getHostedTXState(txId);
        assertThat(tx.getRegions().size()).isEqualTo(4);// 2 buckets for the two puts we
        // did in the accessor one dist. region, and one more bucket if Cust1 and Cust10 resolve to
        // different buckets
        for (InternalRegion r : tx.getRegions()) {
          assertThat(r instanceof DistributedRegion).isTrue();
          TXRegionState rs = tx.readRegion(r);
          for (Object key : rs.getEntryKeys()) {
            TXEntryState es = rs.readEntry(key);
            assertThat(es.getValue(key, r, false)).isNull();
            // custId20 won't be dirty because it doesn't exist.
            assertThat(key.equals(custId20) || es.isDirty())
                .as("key:" + key + " r:" + r.getFullPath()).isTrue();
          }
        }
        return null;
      }
    });
    accessor.invoke(new SerializableCallable<Object>() {
      @Override
      public Object call() {
        TXManagerImpl mgr = getCache().getTxManager();
        mgr.resume(txId);
        mgr.commit();
        Region<CustId, Customer> cust = getCache().getRegion(CUSTOMER);
        Region<CustId, Customer> rr = getCache().getRegion(D_REFERENCE);
        assertThat(cust.get(custId1)).isNull();
        assertThat(rr.get(custId2)).isNull();
        // check conflict
        mgr.begin();
        CustId custId3 = new CustId(3);
        CustId custId4 = new CustId(4);
        getCache().getLogger().fine("SWAP:removeConflict");
        cust.removeAll(Arrays.asList(custId3, custId20, custId4));
        TXStateProxy tx = mgr.pauseTransaction();
        // cust.put(custId3, new Customer("foo", "bar"));
        cust.put(custId20, new Customer("foo", "bar"));
        assertThat(cust.get(custId20)).isNotNull();
        cust.put(custId4, new Customer("foo", "bar"));
        mgr.unpauseTransaction(tx);
        assertThatThrownBy(mgr::commit).isInstanceOf(CommitConflictException.class);
        assertThat(cust.get(custId3)).isNotNull();
        assertThat(cust.get(custId4)).isNotNull();
        assertThat(cust.get(custId20)).isNotNull();

        // Test a removeall an already missing key.
        // custId2 has already been removed
        mgr.begin();
        getCache().getLogger().fine("SWAP:removeConflict");
        cust.removeAll(Arrays.asList(custId2, custId3));
        tx = mgr.pauseTransaction();
        cust.put(custId2, new Customer("foo", "bar"));
        mgr.unpauseTransaction(tx);
        mgr.commit();
        assertThat(cust.get(custId2)).isNotNull();
        assertThat(cust.get(custId3)).isNull();
        return null;
      }
    });
  }
Make sure that getEntry returns null properly and values when it should
geode-core/src/distributedTest/java/org/apache/geode/internal/cache/RemoteTransactionDUnitTest.java