@Test
  public void testCollections() throws CacheException {
    Region<String, String> reg1 = region;

    checkSubRegionCollection(reg1);

    {
      Collection nonTxKeys = reg1.keySet();
      Collection nonTxValues = reg1.values();
      txMgr.begin();
      reg1.create("key1", "value1");
      Collection txKeys = reg1.keySet();
      Collection txValues = reg1.values();
      /*
       * [sumedh] No longer fail this scenario to avoid the overhead of ThreadLocal lookup in every
       * iteration. Besides does not look to be a harmful usage in any case.
       */
      try {
        nonTxKeys.size();
        fail();
      } catch (IllegalStateException expected) {
        TransactionId txid = txMgr.getTransactionId();
        assertEquals(
            String.format(
                "The Region collection is not transactional but is being used in a transaction %s.",
                txid),
            expected.getMessage());
      }
      assertEquals(1, txKeys.size());
      try {
        nonTxValues.size();
        fail();
      } catch (IllegalStateException expected) {
        TransactionId txid = txMgr.getTransactionId();
        assertEquals(
            String.format(
                "The Region collection is not transactional but is being used in a transaction %s.",
                txid),
            expected.getMessage());
      }
      assertEquals(1, txValues.size());
      assertTrue(txKeys.contains("key1"));
      {
        Iterator txIt = txKeys.iterator();
        assertTrue(txIt.hasNext());
        assertTrue(txIt.hasNext());
        assertEquals("key1", txIt.next());
        assertTrue(!txIt.hasNext());
      }
      assertTrue(txValues.contains("value1"));
      {
        Iterator txIt = txValues.iterator();
        assertTrue(txIt.hasNext());
        assertTrue(txIt.hasNext());
        assertEquals("value1", txIt.next());
        assertTrue(!txIt.hasNext());
      }
      reg1.invalidate("key1");
      assertEquals(1, txKeys.size());
      assertEquals(0, txValues.size());
      assertTrue(txKeys.contains("key1"));
      assertTrue(!txValues.contains("value1"));
      reg1.create("key2", "value2");
      reg1.create("key3", "value3");
      assertEquals(3, txKeys.size());
      assertEquals(2, txValues.size());
      reg1.put("key1", "value1");
      assertEquals(3, txKeys.size());
      assertEquals(3, txValues.size());
      reg1.localInvalidate("key2");
      assertEquals(2, txValues.size());
      reg1.invalidate("key1");
      assertEquals(1, txValues.size());
      reg1.destroy("key2");
      reg1.destroy("key3");
      assertEquals(1, txKeys.size());

      reg1.destroy("key1");
      assertEquals(0, txKeys.size());
      assertTrue(!txKeys.contains("key1"));
      Iterator txIt = txKeys.iterator();
      assertTrue(!txIt.hasNext());
      txMgr.rollback();
      try {
        txKeys.size();
        fail("expected IllegalStateException");
      } catch (IllegalStateException ignored) {
      }
      try {
        txKeys.isEmpty();
        fail("expected IllegalStateException");
      } catch (IllegalStateException ignored) {
      }
      try {
        txKeys.contains("key1");
        fail("expected IllegalStateException");
      } catch (IllegalStateException ignored) {
      }
      try {
        txKeys.iterator();
        fail("expected IllegalStateException");
      } catch (IllegalStateException ignored) {
      }
      txIt.hasNext();
    }
    {
      txMgr.begin();
      reg1.create("key1", "value1");
      Collection txValues = reg1.values();
      assertEquals(1, txValues.size());
      assertTrue(txValues.contains("value1"));
      {
        Iterator txIt = txValues.iterator();
        assertTrue(txIt.hasNext());
        assertEquals("value1", txIt.next());
        assertTrue(!txIt.hasNext());
      }
      reg1.destroy("key1");
      assertEquals(0, txValues.size());
      assertTrue(!txValues.contains("value1"));
      assertTrue(!txValues.iterator().hasNext());
      assertTrue(!txValues.iterator().hasNext());
      txMgr.rollback();
    }
    {
      Collection nonTxEntries = reg1.entrySet(false);
      txMgr.begin();
      reg1.create("key1", "value1");
      Collection txEntries = reg1.entrySet(false);
      // non-TX collections can now be used in a transactional context
      try {
        nonTxEntries.size();
        fail();
      } catch (IllegalStateException expected) {
        TransactionId txid = txMgr.getTransactionId();
        assertEquals(
            String.format(
                "The Region collection is not transactional but is being used in a transaction %s.",
                txid),
            expected.getMessage());
      }
      assertEquals(1, txEntries.size());
      assertTrue(txEntries.contains(reg1.getEntry("key1")));
      {
        Iterator txIt = txEntries.iterator();
        assertTrue(txIt.hasNext());
        assertTrue(txIt.hasNext());
        assertEquals(reg1.getEntry("key1"), txIt.next());
        assertTrue(!txIt.hasNext());
        assertTrue(!txIt.hasNext());
      }
      reg1.destroy("key1");
      assertEquals(0, txEntries.size());
      assertTrue(!txEntries.iterator().hasNext());
      txMgr.rollback();
    }
    {
      Collection nonTxKeys = reg1.keySet();
      Collection nonTxValues = reg1.values();

      assertEquals(0, nonTxKeys.size());
      assertEquals(0, nonTxValues.size());
      reg1.create("key1", "value1");
      assertEquals(1, nonTxKeys.size());
      assertEquals(1, nonTxValues.size());
      reg1.invalidate("key1");
      assertEquals(1, nonTxKeys.size());
      assertEquals(0, nonTxValues.size());

      txMgr.begin();
      Collection txKeys = reg1.keySet();
      Collection txValues = reg1.values();
      assertEquals(1, txKeys.size());
      assertEquals(0, txValues.size());
      reg1.put("key1", "txValue1");
      assertEquals(1, txKeys.size());
      assertEquals(1, txValues.size());
      assertTrue(txValues.iterator().hasNext());
      assertEquals("txValue1", txValues.iterator().next());
      // non-TX collections can now be used in a transactional context
      try {
        nonTxValues.iterator().hasNext();
      } catch (IllegalStateException expected) {
        TransactionId txid = txMgr.getTransactionId();
        assertEquals(
            String.format(
                "The Region collection is not transactional but is being used in a transaction %s.",
                txid),
            expected.getMessage());
      }

      reg1.localInvalidate("key1");
      assertEquals(0, txValues.size());
      assertTrue(!txValues.iterator().hasNext());
      txMgr.rollback();
    }
  }
Test to make sure CacheListener callbacks are called in place with the CacheEvents properly
constructed
geode-core/src/integrationTest/java/org/apache/geode/TXJUnitTest.java