| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more contributor license |
| * agreements. See the NOTICE file distributed with this work for additional information regarding |
| * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance with the License. You may obtain a |
| * copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software distributed under the License |
| * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express |
| * or implied. See the License for the specific language governing permissions and limitations under |
| * the License. |
| */ |
| package org.apache.geode.internal.cache; |
| |
| import static org.apache.geode.test.awaitility.GeodeAwaitility.await; |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.assertFalse; |
| import static org.junit.Assert.assertNotNull; |
| import static org.junit.Assert.assertTrue; |
| import static org.junit.Assert.fail; |
| |
| import java.io.BufferedInputStream; |
| import java.io.DataInputStream; |
| import java.io.File; |
| import java.io.FileInputStream; |
| import java.io.FileNotFoundException; |
| import java.io.FileOutputStream; |
| import java.io.IOException; |
| import java.util.Arrays; |
| |
| import org.junit.Test; |
| |
| import org.apache.geode.cache.DiskStore; |
| import org.apache.geode.cache.EntryNotFoundException; |
| import org.apache.geode.cache.Region; |
| import org.apache.geode.cache.Scope; |
| import org.apache.geode.internal.Assert; |
| import org.apache.geode.internal.cache.entries.DiskEntry; |
| |
| /** |
| * Disk region recovery tests |
| * |
| * @since GemFire 5.1 |
| */ |
| public class DiskRegRecoveryJUnitTest extends DiskRegionTestingBase { |
| |
| private static int EMPTY_RVV_SIZE = 6; |
| private static int ENTRY_SIZE = 1024; |
| |
| private static boolean oplogsIDsNotifiedToRoll; |
| |
| private boolean proceedWithRolling; |
| private boolean rollingDone; |
| private boolean verifiedOplogs; |
| private final Object verifiedSync = new Object(); |
| |
| private DiskRegionProperties diskProps = new DiskRegionProperties(); |
| |
| @Override |
| protected final void postSetUp() throws Exception { |
| diskProps.setDiskDirs(dirs); |
| } |
| |
| /** |
| * Disk region recovery test for Persist only with sync writes. Test has four steps : STEP 1: |
| * Create cache. Create Region. Put entries. Close cache. STEP 2: Create cache. Create Region with |
| * the same name as that of in STEP 1. Put few more entries. Get and verify the entries put in |
| * STEP 1 and STEP 2 STEP 3: Again Create cache. Create Region with the same name as that of in |
| * STEP 1. Get and verify the entries put in STEP 1 and STEP 2. STEP 4: Create cache. Create |
| * Region with the same name as that of in STEP 1. Get and verify the entries put in STEP 1 and |
| * STEP 2. |
| */ |
| @Test |
| public void testDiskRegRecovery() { |
| /** |
| * STEP 1 |
| */ |
| diskProps.setPersistBackup(true); |
| diskProps.setRegionName("RecoveryTestRegion"); |
| region = DiskRegionHelperFactory.getSyncPersistOnlyRegion(cache, diskProps, Scope.LOCAL); |
| verifyOplogSizeZeroAfterRecovery(region); |
| final byte[] value = new byte[ENTRY_SIZE]; |
| Arrays.fill(value, (byte) 77); |
| for (int i = 0; i < 100; i++) { |
| region.put(new Integer(i), value); |
| } |
| // for recovery test: |
| try { |
| region.put("100", new byte[1024]); |
| region.put("101", "101"); |
| region.put("102", new Character('a')); |
| region.put("103", new Byte("103")); |
| region.put("104", Boolean.TRUE); |
| region.put("105", new Short("105")); |
| region.put("106", new Integer(106)); |
| region.put("107", new Long(107L)); |
| region.put("108", new Float(108F)); |
| region.put("109", new Double(109d)); |
| } catch (Exception ex) { |
| ex.printStackTrace(); |
| fail("FAILED WHILE PUT:" + ex.toString()); |
| } |
| // Verifying the get operation: |
| getByteArrVal("100", region); |
| assertEquals("101", region.get("101")); |
| assertEquals(new Character('a'), region.get("102")); |
| assertEquals(new Byte("103"), region.get("103")); |
| assertEquals(Boolean.TRUE, region.get("104")); |
| assertEquals(new Short("105"), region.get("105")); |
| assertEquals(new Integer(106), region.get("106")); |
| assertEquals(new Long(107L), region.get("107")); |
| assertEquals(new Float(108F), region.get("108")); |
| assertEquals(new Double(109d), region.get("109")); |
| int origSize = region.size(); |
| /** |
| * close the cache after that create it again and then put few more values |
| */ |
| if (cache != null) { |
| cache.close(); |
| } |
| |
| /** |
| * STEP 2: create the cache and region with the same name |
| */ |
| try { |
| try { |
| cache = createCache(); |
| } catch (Exception e) { |
| fail(" failure in creation of cache due to " + e); |
| } |
| // Create region |
| diskProps.setPersistBackup(true); |
| diskProps.setRegionName("RecoveryTestRegion"); |
| region = DiskRegionHelperFactory.getSyncPersistOnlyRegion(cache, diskProps, Scope.LOCAL); |
| assertEquals(origSize, region.size()); |
| // Verifying the get operation: |
| getByteArrVal("100", region); |
| assertEquals("101", region.get("101")); |
| assertEquals(new Character('a'), region.get("102")); |
| assertEquals(new Byte("103"), region.get("103")); |
| assertEquals(Boolean.TRUE, region.get("104")); |
| assertEquals(new Short("105"), region.get("105")); |
| assertEquals(new Integer(106), region.get("106")); |
| assertEquals(new Long(107L), region.get("107")); |
| assertEquals(new Float(108F), region.get("108")); |
| assertEquals(new Double(109d), region.get("109")); |
| // put few more entries |
| region.put("110", new String("110")); |
| region.put("111", new Character('b')); |
| region.put("112", new Byte("112")); |
| region.put("113", new Boolean(false)); |
| region.put("114", new Short("114")); |
| region.put("115", new Integer(115)); |
| region.put("116", new Long(116L)); |
| region.put("117", new Float(117F)); |
| region.put("118", new Double(118d)); |
| region.put("119", new byte[0]); |
| } catch (Exception e) { |
| logWriter.error("exception not expected", e); |
| fail("failed while (in STEP 2) creating the cache and/or region" + e.toString()); |
| } |
| // Verifying the get operation: |
| getByteArrVal("100", region); |
| assertTrue(region.get("101").equals(new String("101"))); |
| assertTrue(region.get("102").equals(new Character('a'))); |
| assertTrue(region.get("103").equals(new Byte("103"))); |
| assertTrue(region.get("104").equals(new Boolean(true))); |
| assertTrue(region.get("105").equals(new Short("105"))); |
| assertTrue(region.get("106").equals(new Integer(106))); |
| assertTrue(region.get("107").equals(new Long(107L))); |
| assertTrue(region.get("108").equals(new Float(108F))); |
| assertTrue(region.get("109").equals(new Double(109d))); |
| assertTrue(region.get("110").equals(new String("110"))); |
| assertTrue(region.get("111").equals(new Character('b'))); |
| assertTrue(region.get("112").equals(new Byte("112"))); |
| assertTrue(region.get("113").equals(new Boolean(false))); |
| assertTrue(region.get("114").equals(new Short("114"))); |
| assertTrue(region.get("115").equals(new Integer(115))); |
| assertTrue(region.get("116").equals(new Long(116L))); |
| assertTrue(region.get("117").equals(new Float(117F))); |
| assertTrue(region.get("118").equals(new Double(118d))); |
| getByteArrValZeroLnth("119", region); |
| /** |
| * close the cache after that create it again |
| */ |
| if (cache != null) { |
| cache.close(); |
| if (logWriter.fineEnabled()) |
| logWriter.fine("Cache closed"); |
| } |
| |
| /** |
| * STEP 3: Create the cache and region And close the cache |
| */ |
| try { |
| try { |
| cache = createCache(); |
| } catch (Exception e) { |
| fail(" failure in creation of cache due to " + e); |
| } |
| if (logWriter.fineEnabled()) |
| logWriter.fine("Cache created to test the recovery.."); |
| // Create region |
| diskProps.setPersistBackup(true); |
| diskProps.setRegionName("RecoveryTestRegion"); |
| region = DiskRegionHelperFactory.getSyncPersistOnlyRegion(cache, diskProps, Scope.LOCAL); |
| } catch (Exception e) { |
| e.printStackTrace(); |
| fail("failed while (in STEP 3) creating the cache and/or region" + e.toString()); |
| } |
| // Verifying the get operation: |
| getByteArrVal("100", region); |
| assertTrue(region.get("101").equals(new String("101"))); |
| assertTrue(region.get("102").equals(new Character('a'))); |
| assertTrue(region.get("103").equals(new Byte("103"))); |
| assertTrue(region.get("104").equals(new Boolean(true))); |
| assertTrue(region.get("105").equals(new Short("105"))); |
| assertTrue(region.get("106").equals(new Integer(106))); |
| assertTrue(region.get("107").equals(new Long(107L))); |
| assertTrue(region.get("108").equals(new Float(108F))); |
| assertTrue(region.get("109").equals(new Double(109d))); |
| assertTrue(region.get("110").equals(new String("110"))); |
| assertTrue(region.get("111").equals(new Character('b'))); |
| assertTrue(region.get("112").equals(new Byte("112"))); |
| assertTrue(region.get("113").equals(new Boolean(false))); |
| assertTrue(region.get("114").equals(new Short("114"))); |
| assertTrue(region.get("115").equals(new Integer(115))); |
| assertTrue(region.get("116").equals(new Long(116L))); |
| assertTrue(region.get("117").equals(new Float(117F))); |
| assertTrue(region.get("118").equals(new Double(118d))); |
| getByteArrValZeroLnth("119", region); |
| /** |
| * close the cache after that create it again |
| */ |
| if (cache != null) { |
| cache.close(); |
| if (logWriter.fineEnabled()) |
| logWriter.fine("Cache closed"); |
| } |
| |
| /** |
| * STEP 4: Create the cache and region verify disk reg recovery And close the cache |
| */ |
| try { |
| try { |
| cache = createCache(); |
| } catch (Exception e) { |
| fail(" failure in creation of cache due to " + e); |
| } |
| if (logWriter.fineEnabled()) |
| logWriter.fine("Cache created to test the recovery.."); |
| // Create region |
| diskProps.setPersistBackup(true); |
| diskProps.setRegionName("RecoveryTestRegion"); |
| region = DiskRegionHelperFactory.getSyncPersistOnlyRegion(cache, diskProps, Scope.LOCAL); |
| } catch (Exception e) { |
| e.printStackTrace(); |
| fail("failed while (in STEP 4) creating the cache and/or region" + e.toString()); |
| } |
| // Get all the test values, put in STEP 1 & 2: |
| // Verifying the get operation: |
| getByteArrVal("100", region); |
| assertTrue(region.get("101").equals(new String("101"))); |
| assertTrue(region.get("102").equals(new Character('a'))); |
| assertTrue(region.get("103").equals(new Byte("103"))); |
| assertTrue(region.get("104").equals(new Boolean(true))); |
| assertTrue(region.get("105").equals(new Short("105"))); |
| assertTrue(region.get("106").equals(new Integer(106))); |
| assertTrue(region.get("107").equals(new Long(107L))); |
| assertTrue(region.get("108").equals(new Float(108F))); |
| assertTrue(region.get("109").equals(new Double(109d))); |
| assertTrue(region.get("110").equals(new String("110"))); |
| assertTrue(region.get("111").equals(new Character('b'))); |
| assertTrue(region.get("112").equals(new Byte("112"))); |
| assertTrue(region.get("113").equals(new Boolean(false))); |
| assertTrue(region.get("114").equals(new Short("114"))); |
| assertTrue(region.get("115").equals(new Integer(115))); |
| assertTrue(region.get("116").equals(new Long(116L))); |
| assertTrue(region.get("117").equals(new Float(117F))); |
| assertTrue(region.get("118").equals(new Double(118d))); |
| getByteArrValZeroLnth("119", region); |
| |
| closeDown(); // closes disk file which will flush all buffers |
| } |
| |
| /** |
| * Disk region recovery test for Persist only with sync writes. Test has four steps : STEP 1: |
| * Create cache. Create Region. Put entries. Close cache. STEP 2: Create cache. Create Region with |
| * the same name as that of in STEP 1. Delete some entries. Close the Cache * 3: Again Create |
| * cache. Create Region with the same name as that of in STEP 4) Verify that the entries got |
| * deleted |
| */ |
| @Test |
| public void testBug39989_1() { |
| /** |
| * STEP 1 |
| */ |
| diskProps.setPersistBackup(true); |
| diskProps.setRegionName("RecoveryTestRegion"); |
| region = DiskRegionHelperFactory.getSyncPersistOnlyRegion(cache, diskProps, Scope.LOCAL); |
| verifyOplogSizeZeroAfterRecovery(region); |
| final byte[] value = new byte[ENTRY_SIZE]; |
| Arrays.fill(value, (byte) 77); |
| for (int i = 0; i < 10; i++) { |
| |
| region.put(new Integer(i), value); |
| } |
| |
| /** |
| * close the cache after that create it again and then put few more values |
| */ |
| if (cache != null) { |
| cache.close(); |
| } |
| |
| /** |
| * STEP 2: create the cache and region with the same name |
| */ |
| try { |
| try { |
| cache = createCache(); |
| } catch (Exception e) { |
| fail(" failure in creation of cache due to " + e); |
| } |
| // Create region |
| diskProps.setPersistBackup(true); |
| diskProps.setRegionName("RecoveryTestRegion"); |
| region = DiskRegionHelperFactory.getSyncPersistOnlyRegion(cache, diskProps, Scope.LOCAL); |
| // Remove the recovered entries |
| for (int i = 0; i < 10; i++) { |
| region.remove(new Integer(i)); |
| } |
| |
| |
| } catch (Exception e) { |
| logWriter.error("exception not expected", e); |
| fail("failed while (in STEP 2) creating the cache and/or region" + e.toString()); |
| } |
| /** |
| * close the cache after that create it again |
| */ |
| if (cache != null) { |
| cache.close(); |
| if (logWriter.fineEnabled()) |
| logWriter.fine("Cache closed"); |
| } |
| |
| /** |
| * STEP 3: Create the cache and region And close the cache |
| */ |
| try { |
| try { |
| cache = createCache(); |
| } catch (Exception e) { |
| fail(" failure in creation of cache due to " + e); |
| } |
| if (logWriter.fineEnabled()) |
| logWriter.fine("Cache created to test the recovery.."); |
| // Create region |
| diskProps.setPersistBackup(true); |
| diskProps.setRegionName("RecoveryTestRegion"); |
| region = DiskRegionHelperFactory.getSyncPersistOnlyRegion(cache, diskProps, Scope.LOCAL); |
| // Size should be zero |
| assertEquals(0, region.size()); |
| } catch (Exception e) { |
| e.printStackTrace(); |
| fail("failed while (in STEP 3) creating the cache and/or region" + e.toString()); |
| } |
| |
| closeDown(); // closes disk file which will flush all buffers |
| } |
| |
| /** |
| * Disk region recovery test for Persist only with sync writes. Test has four steps : STEP 1: |
| * Create cache. Create Region. Put entries. Close cache. STEP 2: Create cache. Create Region with |
| * the same name as that of in STEP 1. Delete some entries. 3) Recreate the deleted entries Close |
| * the Cache * 3: Again Create cache. 4) check if the region creation is successful |
| */ |
| @Test |
| public void testBug39989_2() { |
| /** |
| * STEP 1 |
| */ |
| diskProps.setPersistBackup(true); |
| diskProps.setRegionName("RecoveryTestRegion"); |
| region = DiskRegionHelperFactory.getSyncPersistOnlyRegion(cache, diskProps, Scope.LOCAL); |
| verifyOplogSizeZeroAfterRecovery(region); |
| final byte[] value = new byte[ENTRY_SIZE]; |
| final byte[] value2 = new byte[ENTRY_SIZE + 1]; |
| Arrays.fill(value, (byte) 77); |
| Arrays.fill(value2, (byte) 77); |
| for (int i = 0; i < 10; i++) { |
| region.put(new Integer(i), value); |
| } |
| |
| /** |
| * close the cache after that create it again and then put few more values |
| */ |
| if (cache != null) { |
| cache.close(); |
| } |
| |
| /** |
| * STEP 2: create the cache and region with the same name |
| */ |
| try { |
| try { |
| cache = createCache(); |
| } catch (Exception e) { |
| fail(" failure in creation of cache due to " + e); |
| } |
| // Create region |
| diskProps.setPersistBackup(true); |
| diskProps.setRegionName("RecoveryTestRegion"); |
| region = DiskRegionHelperFactory.getSyncPersistOnlyRegion(cache, diskProps, Scope.LOCAL); |
| assertEquals(10, region.size()); |
| // Remove the recovered entries |
| for (int i = 0; i < 10; i++) { |
| region.remove(new Integer(i)); |
| } |
| |
| // add new entries |
| for (int i = 0; i < 10; i++) { |
| region.put(new Integer(i), value2); |
| } |
| |
| |
| } catch (Exception e) { |
| logWriter.error("exception not expected", e); |
| fail("failed while (in STEP 2) creating the cache and/or region" + e.toString()); |
| } |
| /** |
| * close the cache after that create it again |
| */ |
| if (cache != null) { |
| cache.close(); |
| if (logWriter.fineEnabled()) |
| logWriter.fine("Cache closed"); |
| } |
| |
| /** |
| * STEP 3: Create the cache and region And close the cache |
| */ |
| try { |
| try { |
| cache = createCache(); |
| } catch (Exception e) { |
| fail(" failure in creation of cache due to " + e); |
| } |
| if (logWriter.fineEnabled()) |
| logWriter.fine("Cache created to test the recovery.."); |
| // Create region |
| diskProps.setPersistBackup(true); |
| diskProps.setRegionName("RecoveryTestRegion"); |
| region = DiskRegionHelperFactory.getSyncPersistOnlyRegion(cache, diskProps, Scope.LOCAL); |
| assertEquals(10, region.size()); |
| } catch (Exception e) { |
| e.printStackTrace(); |
| fail("failed while (in STEP 3) creating the cache and/or region" + e.toString()); |
| } |
| |
| closeDown(); // closes disk file which will flush all buffers |
| } |
| |
| /** |
| * To validate the get operation performed on a byte array. |
| */ |
| private void getByteArrVal(String key, Region region) { |
| byte[] val = (byte[]) region.get(key); |
| // verify that the retrieved byte[] equals to the value put initially. |
| // val should be an unitialized array of bytes of length 1024 |
| assertEquals(1024, val.length); |
| for (int i = 0; i < 1024; i++) { |
| assertEquals(0, val[i]); |
| } |
| } |
| |
| /** |
| * to validate the get operation performed on a byte array of length zero |
| */ |
| private boolean getByteArrValZeroLnth(String key, Region region) { |
| Object val0 = null; |
| byte[] val2 = new byte[0]; |
| try { |
| val0 = region.get(key); |
| } catch (Exception ex) { |
| ex.printStackTrace(); |
| fail("Failed to get the value on disk"); |
| } |
| // verify that the retrieved byte[] equals to the value put initially. |
| boolean result = false; |
| byte[] x = null; |
| x = (byte[]) val0; |
| // verify that the value of the entry is an instance of byte [] |
| assertTrue("the value of the entry having key 119 is NOT an" + " instance of byte []", |
| val0 instanceof byte[]); |
| |
| result = x.length == val2.length; |
| |
| if (!result) { |
| fail("The lenghth of byte[] put at 119th key obtained from disk " |
| + "is not euqal to the lenght of byte[] put initially"); |
| } |
| return result; |
| } |
| |
| private void verifyOplogSizeZeroAfterRecovery(Region region) { |
| assertEquals( |
| Oplog.OPLOG_MAGIC_SEQ_REC_SIZE * 2 + Oplog.OPLOG_DISK_STORE_REC_SIZE * 2 + EMPTY_RVV_SIZE |
| + Oplog.OPLOG_GEMFIRE_VERSION_REC_SIZE * 2, |
| ((LocalRegion) region).getDiskRegion().testHook_getChild().getOplogSize()); |
| } |
| |
| @Test |
| public void testNoEvictionDuringRecoveryIfNoGIIRecoverValuesTrue() { |
| String oldValue = System.getProperty(DiskStoreImpl.RECOVER_VALUE_PROPERTY_NAME); |
| String oldLruValue = System.getProperty(DiskStoreImpl.RECOVER_LRU_VALUES_PROPERTY_NAME); |
| System.setProperty(DiskStoreImpl.RECOVER_VALUE_PROPERTY_NAME, "true"); |
| System.setProperty(DiskStoreImpl.RECOVER_LRU_VALUES_PROPERTY_NAME, "true"); |
| try { |
| diskProps.setDiskDirs(dirs); |
| diskProps.setPersistBackup(true); |
| int overflowCapacity = 5; |
| diskProps.setOverFlowCapacity(overflowCapacity); |
| diskProps.setRegionName("RecoveryTestRegion"); |
| region = DiskRegionHelperFactory.getSyncOverFlowAndPersistRegion(cache, diskProps); |
| |
| int size = 1000; |
| |
| for (int i = 0; i < size; i++) { |
| region.put(new Integer(i), new Integer(i)); |
| } |
| region.close(); |
| region = DiskRegionHelperFactory.getSyncOverFlowAndPersistRegion(cache, diskProps); |
| |
| int serilizedValuesInVm = 0; |
| for (int i = 0; i < size; i++) { |
| try { |
| Object value = ((LocalRegion) region).getValueInVM(new Integer(i)); |
| if (value instanceof CachedDeserializable) { |
| serilizedValuesInVm++; |
| } |
| } catch (EntryNotFoundException e) { |
| fail("Entry not found not expected but occurred "); |
| } |
| } |
| // Test to see if values are in serialized form, when disk recovery is performed. |
| if (serilizedValuesInVm != overflowCapacity) { |
| // overflowCapacity - number of max items region will hold. |
| fail("Values are not in default Serialized form, when it was loaded from disk."); |
| } |
| |
| // verifyOplogSizeZeroAfterRecovery(region); |
| for (int i = 0; i < size; i++) { |
| Assert.assertTrue(region.get(new Integer(i)).equals(new Integer(i))); |
| } |
| // region.close(); |
| } finally { |
| if (oldValue != null) { |
| System.setProperty(DiskStoreImpl.RECOVER_VALUE_PROPERTY_NAME, oldValue); |
| } else { |
| System.clearProperty(DiskStoreImpl.RECOVER_VALUE_PROPERTY_NAME); |
| } |
| |
| if (oldLruValue != null) { |
| System.setProperty(DiskStoreImpl.RECOVER_LRU_VALUES_PROPERTY_NAME, oldLruValue); |
| } else { |
| System.clearProperty(DiskStoreImpl.RECOVER_LRU_VALUES_PROPERTY_NAME); |
| } |
| } |
| } |
| |
| @Test |
| public void testNoEvictionDuringRecoveryIfNoGIIRecoverValuesFalse() { |
| String oldValue = System.getProperty(DiskStoreImpl.RECOVER_VALUE_PROPERTY_NAME); |
| System.setProperty(DiskStoreImpl.RECOVER_VALUE_PROPERTY_NAME, "false"); |
| try { |
| diskProps.setDiskDirs(dirs); |
| diskProps.setPersistBackup(true); |
| diskProps.setOverFlowCapacity(1); |
| diskProps.setRegionName("RecoveryTestRegion"); |
| region = DiskRegionHelperFactory.getSyncOverFlowAndPersistRegion(cache, diskProps); |
| |
| for (int i = 0; i < 1000; i++) { |
| region.put(new Integer(i), new Integer(i)); |
| } |
| |
| region.close(); |
| |
| region = DiskRegionHelperFactory.getSyncOverFlowAndPersistRegion(cache, diskProps); |
| |
| for (int i = 0; i < 1000; i++) { |
| try { |
| ((LocalRegion) region).getValueInVM(new Integer(i)); |
| } catch (EntryNotFoundException e) { |
| fail("Entry not found not expected but occurred "); |
| } |
| } |
| |
| // verifyOplogSizeZeroAfterRecovery(region); |
| for (int i = 0; i < 1000; i++) { |
| try { |
| Assert.assertTrue(((LocalRegion) region).getValueInVM(new Integer(i)) == null); |
| } catch (EntryNotFoundException e) { |
| fail("Entry not found not expected but occurred "); |
| } |
| } |
| for (int i = 0; i < 1000; i++) { |
| try { |
| Assert.assertTrue( |
| ((LocalRegion) region).getValueOnDisk(new Integer(i)).equals(new Integer(i))); |
| } catch (EntryNotFoundException e) { |
| fail("Entry not found not expected but occurred "); |
| } |
| } |
| // region.close(); |
| } finally { |
| if (oldValue != null) { |
| System.setProperty(DiskStoreImpl.RECOVER_VALUE_PROPERTY_NAME, oldValue); |
| } else { |
| System.clearProperty(DiskStoreImpl.RECOVER_VALUE_PROPERTY_NAME); |
| } |
| } |
| } |
| |
| @Test |
| public void testEmptyRegionRecover() { |
| diskProps.setDiskDirs(dirs); |
| region = DiskRegionHelperFactory.getSyncPersistOnlyRegion(cache, diskProps, Scope.LOCAL); |
| Assert.assertTrue(region.size() == 0); |
| verifyOplogSizeZeroAfterRecovery(region); |
| region.close(); |
| region = DiskRegionHelperFactory.getSyncPersistOnlyRegion(cache, diskProps, Scope.LOCAL); |
| Assert.assertTrue(region.size() == 0); |
| verifyOplogSizeZeroAfterRecovery(region); |
| region.close(); |
| region = DiskRegionHelperFactory.getSyncPersistOnlyRegion(cache, diskProps, Scope.LOCAL); |
| Assert.assertTrue(region.size() == 0); |
| verifyOplogSizeZeroAfterRecovery(region); |
| region.close(); |
| region = DiskRegionHelperFactory.getSyncPersistOnlyRegion(cache, diskProps, Scope.LOCAL); |
| Assert.assertTrue(region.size() == 0); |
| verifyOplogSizeZeroAfterRecovery(region); |
| region.close(); |
| region = DiskRegionHelperFactory.getSyncPersistOnlyRegion(cache, diskProps, Scope.LOCAL); |
| Assert.assertTrue(region.size() == 0); |
| verifyOplogSizeZeroAfterRecovery(region); |
| // region.close(); |
| } |
| |
| @Test |
| public void testReadCorruptedFile() { |
| diskProps.setDiskDirs(dirs); |
| region = DiskRegionHelperFactory.getSyncPersistOnlyRegion(cache, diskProps, Scope.LOCAL); |
| |
| byte[] value = new byte[1024]; |
| |
| region.put("1", value); |
| region.put("2", value); |
| region.put("3", value); |
| File oplogFile = null; |
| try { |
| oplogFile = ((LocalRegion) region).getDiskRegion().testHook_getChild().getOplogFileForTest(); |
| } catch (Exception e) { |
| logWriter.error( |
| "Exception in synching data present in the buffers of RandomAccessFile of Oplog, to the disk", |
| e); |
| fail("Test failed because synching of data present in buffer of RandomAccesFile "); |
| } |
| region.close(); |
| try { |
| FileInputStream fis = new FileInputStream(oplogFile); |
| DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 1024 * 1024)); |
| byte[] values = new byte[1000 * 3]; |
| dis.read(values); |
| dis.close(); |
| fis.close(); |
| FileOutputStream fos = new FileOutputStream(oplogFile); |
| fos.write(values); |
| fos.close(); |
| |
| } catch (FileNotFoundException e) { |
| fail(" file expected to be there but not found"); |
| } catch (IOException e) { |
| fail(" exception due to" + e); |
| } |
| |
| region = DiskRegionHelperFactory.getSyncPersistOnlyRegion(cache, diskProps, Scope.LOCAL); |
| |
| Assert.assertTrue(region.size() == 2, "Expected size to be 2 but it is " + region.size()); |
| // region.close(); |
| } |
| |
| @Test |
| public void testForceCompactionForRegionWithRollingDisabled() throws Exception { |
| diskProps.setDiskDirs(dirs); |
| diskProps.setMaxOplogSize(2048 + (18 * 2) + 15 * 7); |
| diskProps.setRolling(false); |
| diskProps.setAllowForceCompaction(true); |
| region = DiskRegionHelperFactory.getSyncPersistOnlyRegion(cache, diskProps, Scope.LOCAL); |
| // region created |
| |
| LocalRegion.ISSUE_CALLBACKS_TO_CACHE_OBSERVER = false; |
| |
| // set cache observer to check oplogs rolling |
| CacheObserver co = CacheObserverHolder.setInstance(new CacheObserverAdapter() { |
| @Override |
| public void afterHavingCompacted() { |
| synchronized (region) { |
| if (!rollingDone) { |
| rollingDone = true; |
| } else { |
| fail("rollingDone was set before actually rolling"); |
| } |
| } |
| } |
| }); |
| |
| byte[] value = new byte[900]; // two values per oplog |
| region.put("0", value); |
| region.put("1", value); |
| region.put("2", value); |
| region.put("3", value); |
| region.put("4", value); |
| region.put("5", value); |
| region.put("6", value); |
| region.put("7", value); |
| region.put("8", value); |
| region.put("9", value); |
| |
| LocalRegion.ISSUE_CALLBACKS_TO_CACHE_OBSERVER = true; |
| |
| // Should have nothing to roll because each oplog still has |
| // both entries in it as live. |
| // start force rolling on the region |
| // get array of oplog IDs being picked up for rolling |
| oplogsIDsNotifiedToRoll = ((LocalRegion) region).getDiskStore().forceCompaction(); |
| assertEquals(false, oplogsIDsNotifiedToRoll); |
| |
| // now destroy all "odd" entries; This should allow each oplog to be compacted |
| region.remove("1"); |
| region.remove("3"); |
| region.remove("5"); |
| region.remove("7"); |
| region.remove("9"); |
| oplogsIDsNotifiedToRoll = ((LocalRegion) region).getDiskStore().forceCompaction(); |
| assertEquals(true, oplogsIDsNotifiedToRoll); |
| assertEquals(true, rollingDone); |
| |
| synchronized (region) { |
| boolean condition = ((LocalRegion) region).getDiskRegion().getOplogToBeCompacted() == null; |
| Assert.assertTrue(condition, "Oplogs still remain after having compacted"); |
| } |
| LocalRegion.ISSUE_CALLBACKS_TO_CACHE_OBSERVER = false; |
| } |
| |
| /** |
| * This tests the case where potential of writing a dummy byte was there. The case would be |
| * compactor terminating early. The create is present in both Htree as well as Oplog. When |
| * recovery is done, the create is added to the Oplog createdEntrySet. Now while compactor |
| * iterates over the entries in the region, it skips the created entry because its Htree Offset is |
| * > -1. As a result it leaves it in created set & so when the compactor processes the created Set |
| * it thinks that the entry is now referenced in the any of the subsequent oplogs & thus |
| * overwrites it with a byte[]. |
| */ |
| @Test |
| public void testVestigialCreatesInOplog() throws Exception { |
| diskProps.setDiskDirs(dirs); |
| diskProps.setMaxOplogSize(40); |
| diskProps.setPersistBackup(true); |
| diskProps.setRegionName("VestigialCreatesTestRegion"); |
| diskProps.setRolling(true); |
| |
| // create sync persist region. |
| region = DiskRegionHelperFactory.getSyncPersistOnlyRegion(cache, diskProps, Scope.LOCAL); |
| System.err.println( |
| "<ExpectedException action=add>" + "KillCompactorException" + "</ExpectedException>"); |
| logWriter |
| .info("<ExpectedException action=add>" + "KillCompactorException" + "</ExpectedException>"); |
| try { |
| CacheObserver cob = CacheObserverHolder.setInstance(new CacheObserverAdapter() { |
| @Override |
| public void beforeDeletingCompactedOplog(Oplog compactedOplog) { |
| // killed compactor after rolling but before deleting oplogs |
| throw new DiskStoreImpl.KillCompactorException(); |
| } |
| }); |
| LocalRegion.ISSUE_CALLBACKS_TO_CACHE_OBSERVER = true; |
| region.put("key1", "Testing"); |
| region.put("key2", "Vestigial"); |
| region.put("key3", "Creates"); |
| region.put("key4", "Into"); |
| region.put("key5", "Oplog"); |
| |
| // ((LocalRegion)region).getDiskStore().forceCompaction(); |
| |
| if (cache != null) { |
| cache.close(); |
| } |
| LocalRegion.ISSUE_CALLBACKS_TO_CACHE_OBSERVER = false; |
| CacheObserverHolder.setInstance(new CacheObserverAdapter()); |
| } finally { |
| System.err.println( |
| "<ExpectedException action=remove>" + "KillCompactorException" + "</ExpectedException>"); |
| logWriter.info( |
| "<ExpectedException action=remove>" + "KillCompactorException" + "</ExpectedException>"); |
| } |
| |
| cache = createCache(); |
| region = DiskRegionHelperFactory.getSyncPersistOnlyRegion(cache, diskProps, Scope.LOCAL); |
| assertTrue("Expected region size is 5 but got it as " + region.entrySet().size(), |
| region.entrySet().size() == 5); |
| assertEquals(region.get("key1"), "Testing"); |
| Thread.sleep(5); |
| if (cache != null) { |
| cache.close(); |
| } |
| LocalRegion.ISSUE_CALLBACKS_TO_CACHE_OBSERVER = false; |
| CacheObserverHolder.setInstance(new CacheObserverAdapter()); |
| cache = createCache(); |
| region = DiskRegionHelperFactory.getSyncPersistOnlyRegion(cache, diskProps, Scope.LOCAL); |
| assertTrue("Expected region size is 5 but got it as " + region.entrySet().size(), |
| region.entrySet().size() == 5); |
| assertTrue(region.get("key1").equals("Testing")); |
| } |
| |
| @Test |
| public void testDiskIDFieldsForPersistOnlyRecoverValuesTrue() throws Exception { |
| String oldValue = System.getProperty(DiskStoreImpl.RECOVER_VALUE_PROPERTY_NAME); |
| System.setProperty(DiskStoreImpl.RECOVER_VALUE_PROPERTY_NAME, "true"); |
| try { |
| diskProps.setDiskDirs(dirs); |
| diskProps.setMaxOplogSize(1024); |
| diskProps.setPersistBackup(true); |
| diskProps.setRegionName("testDiskIDFieldsForPersistOnlyRecoverValuesTrue"); |
| diskProps.setRolling(false); |
| // create sync persist region. |
| region = DiskRegionHelperFactory.getSyncPersistOnlyRegion(cache, diskProps, Scope.LOCAL); |
| |
| // the creates which will go in first oplog |
| for (int i = 0; i < 3; ++i) { |
| region.put("" + i, "" + i); |
| } |
| // Ensure that next few entries go in the second oplog while the first set |
| // of entries go in the first oplog |
| region.forceRolling(); |
| for (int i = 3; i < 6; ++i) { |
| region.put("" + i, "" + i); |
| } |
| |
| region.close(); |
| |
| diskProps.setRolling(false); |
| region = DiskRegionHelperFactory.getSyncPersistOnlyRegion(cache, diskProps, Scope.LOCAL); |
| // Now verify the DiskIds of each of the siz entries & the values. |
| LocalRegion rgn = (LocalRegion) region; |
| byte b = 0; |
| b = EntryBits.setSerialized(b, true); |
| b = EntryBits.setRecoveredFromDisk(b, true); |
| b = EntryBits.setWithVersions(b, true); |
| |
| // TODO need to wait for async recovery |
| for (int i = 0; i < 3; ++i) { |
| DiskEntry de = (DiskEntry) rgn.basicGetEntry("" + i); |
| DiskId did = de.getDiskId(); |
| assertTrue(did.getKeyId() > 0); |
| assertEquals(1, did.getOplogId()); |
| assertTrue(did.getOffsetInOplog() > -1); |
| assertEquals(b, did.getUserBits()); |
| assertTrue(did.getValueLength() > 0); |
| assertEquals("" + i, rgn.get("" + i)); |
| assertTrue(did.getKeyId() > 0); |
| assertFalse(de.isValueNull()); |
| } |
| // this last oplog does not have a krf because this disk store has not |
| // been closed. So its value should be in memory now. |
| for (int i = 3; i < 6; ++i) { |
| DiskEntry de = (DiskEntry) rgn.basicGetEntry("" + i); |
| DiskId did = de.getDiskId(); |
| assertTrue(did.getKeyId() > 0); |
| assertFalse(de.isValueNull()); |
| assertEquals(2, did.getOplogId()); |
| assertTrue(did.getOffsetInOplog() > -1); |
| assertEquals(b, did.getUserBits()); |
| assertTrue(did.getValueLength() > 0); |
| assertEquals("" + i, rgn.get("" + i)); |
| } |
| |
| if (cache != null) { |
| cache.close(); |
| } |
| } finally { |
| if (oldValue != null) { |
| System.setProperty(DiskStoreImpl.RECOVER_VALUE_PROPERTY_NAME, oldValue); |
| } else { |
| System.clearProperty(DiskStoreImpl.RECOVER_VALUE_PROPERTY_NAME); |
| } |
| } |
| } |
| |
| @Test |
| public void testDiskIDFieldsForPersistOverFlowRecoverValuesTrue() throws Exception { |
| String oldValue = System.getProperty(DiskStoreImpl.RECOVER_VALUE_PROPERTY_NAME); |
| System.setProperty(DiskStoreImpl.RECOVER_VALUE_PROPERTY_NAME, "true"); |
| try { |
| diskProps.setDiskDirs(dirs); |
| diskProps.setMaxOplogSize(1024); |
| diskProps.setPersistBackup(true); |
| diskProps.setRegionName("testDiskIDFieldsForPersistOverFlowRecoverValuesTrue"); |
| diskProps.setOverFlowCapacity(2); |
| diskProps.setRolling(false); |
| // create sync persist region. |
| region = DiskRegionHelperFactory.getSyncOverFlowAndPersistRegion(cache, diskProps); |
| |
| // the creates which will go in first oplog |
| for (int i = 0; i < 3; ++i) { |
| region.put("" + i, "" + i); |
| } |
| // Ensure that next few entries go in the second oplog while the first set |
| // of entries go in the first oplog |
| region.forceRolling(); |
| |
| for (int i = 3; i < 6; ++i) { |
| region.put("" + i, "" + i); |
| } |
| |
| region.close(); |
| |
| diskProps.setRolling(false); |
| region = DiskRegionHelperFactory.getSyncOverFlowAndPersistRegion(cache, diskProps); |
| // Now verify the DiskIds of each of the siz entries & the values. |
| LocalRegion rgn = (LocalRegion) region; |
| byte b = 0; |
| b = EntryBits.setSerialized(b, true); |
| b = EntryBits.setRecoveredFromDisk(b, true); |
| b = EntryBits.setWithVersions(b, true); |
| |
| for (int i = 0; i < 3; ++i) { |
| DiskEntry de = (DiskEntry) rgn.basicGetEntry("" + i); |
| DiskId did = de.getDiskId(); |
| assertEquals(1, did.getOplogId()); |
| assertTrue(did.getOffsetInOplog() > -1); |
| assertEquals(b, did.getUserBits()); |
| assertTrue(did.getValueLength() > 0); |
| assertEquals("" + i, rgn.get("" + i)); |
| assertTrue(did.getKeyId() > 0); |
| } |
| for (int i = 3; i < 6; ++i) { |
| DiskEntry de = (DiskEntry) rgn.basicGetEntry("" + i); |
| DiskId did = de.getDiskId(); |
| assertEquals(2, did.getOplogId()); |
| assertTrue(did.getOffsetInOplog() > -1); |
| assertEquals(b, did.getUserBits()); |
| assertTrue(did.getValueLength() > 0); |
| assertEquals("" + i, rgn.get("" + i)); |
| assertTrue(did.getKeyId() > 0); |
| } |
| |
| // ((LocalRegion)region).getDiskStore().forceCompaction(); |
| |
| if (cache != null) { |
| cache.close(); |
| } |
| } finally { |
| if (oldValue != null) { |
| System.setProperty(DiskStoreImpl.RECOVER_VALUE_PROPERTY_NAME, oldValue); |
| } else { |
| System.clearProperty(DiskStoreImpl.RECOVER_VALUE_PROPERTY_NAME); |
| } |
| } |
| } |
| |
| @Test |
| public void testDiskIDFieldsForPersistOnlyRecoverValuesFalse() throws Exception { |
| String oldValue = System.getProperty(DiskStoreImpl.RECOVER_VALUE_PROPERTY_NAME); |
| System.setProperty(DiskStoreImpl.RECOVER_VALUE_PROPERTY_NAME, "false"); |
| try { |
| diskProps.setDiskDirs(dirs); |
| diskProps.setMaxOplogSize(1024); |
| diskProps.setPersistBackup(true); |
| diskProps.setRegionName("testDiskIDFieldsForPersistOnlyRecoverValuesFalse"); |
| diskProps.setRolling(false); |
| // create sync persist region. |
| region = DiskRegionHelperFactory.getSyncPersistOnlyRegion(cache, diskProps, Scope.LOCAL); |
| |
| // the creates which will go in first oplog |
| for (int i = 0; i < 3; ++i) { |
| region.put("" + i, "" + i); |
| } |
| |
| // Ensure that next few entries go in the second oplog while the first set |
| // of entries go in the first oplog |
| region.forceRolling(); |
| |
| for (int i = 3; i < 6; ++i) { |
| region.put("" + i, "" + i); |
| } |
| |
| region.close(); |
| |
| diskProps.setRolling(false); |
| region = DiskRegionHelperFactory.getSyncPersistOnlyRegion(cache, diskProps, Scope.LOCAL); |
| // Now verify the DiskIds of each of the siz entries & the values. |
| LocalRegion rgn = (LocalRegion) region; |
| byte b = 0; |
| b = EntryBits.setSerialized(b, true); |
| b = EntryBits.setRecoveredFromDisk(b, true); |
| b = EntryBits.setWithVersions(b, true); |
| |
| for (int i = 0; i < 3; ++i) { |
| DiskEntry de = (DiskEntry) rgn.basicGetEntry("" + i); |
| DiskId did = de.getDiskId(); |
| assertTrue(did.getKeyId() > 0); |
| assertTrue(de.isValueNull()); |
| assertEquals(1, did.getOplogId()); |
| assertTrue(did.getOffsetInOplog() > -1); |
| assertEquals(b, did.getUserBits()); |
| assertTrue(did.getValueLength() > 0); |
| assertEquals("" + i, rgn.get("" + i)); |
| assertFalse(de.isValueNull()); |
| assertTrue(did.getKeyId() > 0); |
| } |
| for (int i = 3; i < 6; ++i) { |
| DiskEntry de = (DiskEntry) rgn.basicGetEntry("" + i); |
| DiskId did = de.getDiskId(); |
| assertTrue(de.isValueNull()); |
| assertTrue(did.getKeyId() > 0); |
| assertEquals(2, did.getOplogId()); |
| assertTrue(did.getOffsetInOplog() > -1); |
| assertEquals(b, did.getUserBits()); |
| assertTrue(did.getValueLength() > 0); |
| assertEquals("" + i, rgn.get("" + i)); |
| assertFalse(de.isValueNull()); |
| assertTrue(did.getKeyId() > 0); |
| } |
| // ((LocalRegion)region).getDiskStore().forceCompaction(); |
| |
| if (cache != null) { |
| cache.close(); |
| } |
| } finally { |
| if (oldValue != null) { |
| System.setProperty(DiskStoreImpl.RECOVER_VALUE_PROPERTY_NAME, oldValue); |
| } else { |
| System.clearProperty(DiskStoreImpl.RECOVER_VALUE_PROPERTY_NAME); |
| } |
| } |
| } |
| |
| @Test |
| public void testDiskIDFieldsForPersistOverFlowRecoverValuesFalse() throws Exception { |
| String oldValue = System.getProperty(DiskStoreImpl.RECOVER_VALUE_PROPERTY_NAME); |
| System.setProperty(DiskStoreImpl.RECOVER_VALUE_PROPERTY_NAME, "false"); |
| try { |
| diskProps.setDiskDirs(dirs); |
| diskProps.setMaxOplogSize(1024); |
| diskProps.setPersistBackup(true); |
| diskProps.setRegionName("testDiskIDFieldsForPersistOverFlowRecoverValuesFalse"); |
| diskProps.setOverFlowCapacity(2); |
| diskProps.setRolling(false); |
| // create sync persist region. |
| region = DiskRegionHelperFactory.getSyncOverFlowAndPersistRegion(cache, diskProps); |
| |
| // the creates which will go in first oplog |
| for (int i = 0; i < 3; ++i) { |
| region.put("" + i, "" + i); |
| } |
| // Ensure that next few entries go in the second oplog while the first set |
| // of entries go in the first oplog |
| region.forceRolling(); |
| |
| for (int i = 3; i < 6; ++i) { |
| region.put("" + i, "" + i); |
| } |
| |
| region.close(); |
| |
| diskProps.setRolling(false); |
| region = DiskRegionHelperFactory.getSyncOverFlowAndPersistRegion(cache, diskProps); |
| // Now verify the DiskIds of each of the siz entries & the values. |
| LocalRegion rgn = (LocalRegion) region; |
| byte b = 0; |
| b = EntryBits.setSerialized(b, true); |
| b = EntryBits.setRecoveredFromDisk(b, true); |
| b = EntryBits.setWithVersions(b, true); |
| |
| for (int i = 0; i < 3; ++i) { |
| DiskEntry de = (DiskEntry) rgn.basicGetEntry("" + i); |
| DiskId did = de.getDiskId(); |
| assertEquals(1, did.getOplogId()); |
| assertTrue(did.getOffsetInOplog() > -1); |
| assertEquals(b, did.getUserBits()); |
| assertTrue(did.getValueLength() > 0); |
| assertEquals("" + i, rgn.get("" + i)); |
| assertTrue(did.getKeyId() > 0); |
| } |
| for (int i = 3; i < 6; ++i) { |
| DiskEntry de = (DiskEntry) rgn.basicGetEntry("" + i); |
| DiskId did = de.getDiskId(); |
| assertEquals(2, did.getOplogId()); |
| assertTrue(did.getOffsetInOplog() > -1); |
| assertEquals(b, did.getUserBits()); |
| assertTrue(did.getValueLength() > 0); |
| assertEquals("" + i, rgn.get("" + i)); |
| assertTrue(did.getKeyId() > 0); |
| } |
| |
| // ((LocalRegion)region).getDiskStore().forceCompaction(); |
| |
| if (cache != null) { |
| cache.close(); |
| } |
| } finally { |
| if (oldValue != null) { |
| System.setProperty(DiskStoreImpl.RECOVER_VALUE_PROPERTY_NAME, oldValue); |
| } else { |
| System.clearProperty(DiskStoreImpl.RECOVER_VALUE_PROPERTY_NAME); |
| } |
| } |
| |
| } |
| |
| @Test |
| public void testBug40375() throws Exception { |
| try { |
| diskProps.setDiskDirs(dirs); |
| diskProps.setPersistBackup(true); |
| diskProps.setSynchronous(true); |
| diskProps.setRolling(true); |
| System.setProperty(DiskStoreImpl.COMPLETE_COMPACTION_BEFORE_TERMINATION_PROPERTY_NAME, |
| "true"); |
| diskProps.setRegionName("testBug"); |
| region = DiskRegionHelperFactory.getSyncPersistOnlyRegion(cache, diskProps, Scope.LOCAL); |
| assertEquals(0, region.size()); |
| region.put("1", "1"); |
| region.put("2", "2"); |
| region.forceRolling(); |
| // Thread.sleep(4000); why did we sleep for 4 seconds? |
| region.close(); |
| region = DiskRegionHelperFactory.getSyncPersistOnlyRegion(cache, diskProps, Scope.LOCAL); |
| assertEquals(2, region.size()); |
| region.put("1", "1`"); |
| region.put("2", "2`"); |
| region.put("3", "3"); |
| region.put("4", "4"); |
| assertEquals(4, region.size()); |
| region.close(); |
| region = DiskRegionHelperFactory.getSyncPersistOnlyRegion(cache, diskProps, Scope.LOCAL); |
| assertEquals(4, region.size()); |
| region.close(); |
| } finally { |
| System.setProperty(DiskStoreImpl.COMPLETE_COMPACTION_BEFORE_TERMINATION_PROPERTY_NAME, ""); |
| } |
| } |
| |
| @Test |
| public void testBug41340() throws Exception { |
| diskProps.setDiskDirs(dirs); |
| diskProps.setPersistBackup(true); |
| diskProps.setSynchronous(true); |
| diskProps.setRolling(true); |
| diskProps.setRegionName("testBug41340"); |
| region = DiskRegionHelperFactory.getSyncPersistOnlyRegion(cache, diskProps, Scope.LOCAL); |
| assertEquals(0, region.size()); |
| // put some entries |
| region.put("0", "0"); |
| region.put("1", "1"); |
| region.put("2", "2"); |
| region.put("3", "3"); |
| |
| |
| // Create another oplog |
| DiskStore store = cache.findDiskStore(region.getAttributes().getDiskStoreName()); |
| store.forceRoll(); |
| |
| // Now create and destroy all of the entries in the new |
| // oplog. This should cause us to remove the CRF but leave |
| // the DRF, which has creates in reverse order. Now we have |
| // garbage destroys which have higher IDs than any crate |
| region.put("4", "1"); |
| region.put("5", "2"); |
| region.put("6", "3"); |
| region.destroy("0"); |
| region.destroy("6"); |
| region.destroy("5"); |
| region.destroy("4"); |
| |
| store.forceRoll(); |
| |
| // Force a recovery |
| GemFireCacheImpl.getInstance().close(); |
| cache = createCache(); |
| region = DiskRegionHelperFactory.getSyncPersistOnlyRegion(cache, diskProps, Scope.LOCAL); |
| assertEquals(3, region.size()); |
| |
| // With bug 41340, this is reusing an oplog id. |
| region.put("7", "7"); |
| // region.close(); |
| |
| // Force another recovery |
| GemFireCacheImpl.getInstance().close(); |
| cache = createCache(); |
| region = DiskRegionHelperFactory.getSyncPersistOnlyRegion(cache, diskProps, Scope.LOCAL); |
| |
| // Make sure we didn't lose the entry |
| assertEquals(4, region.size()); |
| assertEquals("7", region.get("7")); |
| region.close(); |
| } |
| |
| @Test |
| public void testRecoverValuesFalse() { |
| String oldValue = System.getProperty(DiskStoreImpl.RECOVER_VALUE_PROPERTY_NAME); |
| System.setProperty(DiskStoreImpl.RECOVER_VALUE_PROPERTY_NAME, "false"); |
| try { |
| diskProps.setDiskDirs(dirs); |
| diskProps.setPersistBackup(true); |
| diskProps.setRegionName("testRecoverValuesFalse"); |
| region = DiskRegionHelperFactory.getSyncPersistOnlyRegion(cache, diskProps, Scope.LOCAL); |
| region.put(new Integer(1), new Integer(1)); |
| assertEquals(1, region.size()); |
| region.close(); |
| |
| region = DiskRegionHelperFactory.getSyncPersistOnlyRegion(cache, diskProps, Scope.LOCAL); |
| |
| assertEquals(null, ((LocalRegion) region).getValueInVM(new Integer(1))); |
| assertEquals(new Integer(1), region.get(new Integer(1))); |
| } finally { |
| if (oldValue != null) { |
| System.setProperty(DiskStoreImpl.RECOVER_VALUE_PROPERTY_NAME, oldValue); |
| } else { |
| System.clearProperty(DiskStoreImpl.RECOVER_VALUE_PROPERTY_NAME); |
| } |
| } |
| } |
| |
| @Test |
| public void testRecoverValuesTrue() { |
| String oldValue = System.getProperty(DiskStoreImpl.RECOVER_VALUE_PROPERTY_NAME); |
| System.setProperty(DiskStoreImpl.RECOVER_VALUE_PROPERTY_NAME, "true"); |
| try { |
| diskProps.setDiskDirs(dirs); |
| diskProps.setPersistBackup(true); |
| diskProps.setRegionName("testRecoverValuesTrue"); |
| region = DiskRegionHelperFactory.getSyncPersistOnlyRegion(cache, diskProps, Scope.LOCAL); |
| region.put(new Integer(1), new Integer(1)); |
| assertEquals(1, region.size()); |
| region.close(); |
| |
| region = DiskRegionHelperFactory.getSyncPersistOnlyRegion(cache, diskProps, Scope.LOCAL); |
| |
| assertNotNull(((LocalRegion) region).getValueInVM(new Integer(1))); |
| assertEquals(new Integer(1), region.get(new Integer(1))); |
| } finally { |
| if (oldValue != null) { |
| System.setProperty(DiskStoreImpl.RECOVER_VALUE_PROPERTY_NAME, oldValue); |
| } else { |
| System.clearProperty(DiskStoreImpl.RECOVER_VALUE_PROPERTY_NAME); |
| } |
| } |
| } |
| |
| @Test |
| public void testBug41119() { |
| String oldValue = System.getProperty(DiskStoreImpl.RECOVER_VALUE_PROPERTY_NAME); |
| System.setProperty(DiskStoreImpl.RECOVER_VALUE_PROPERTY_NAME, "false"); |
| try { |
| diskProps.setDiskDirs(dirs); |
| diskProps.setPersistBackup(true); |
| diskProps.setRegionName("testRecoverValuesFalse"); |
| region = DiskRegionHelperFactory.getSyncPersistOnlyRegion(cache, diskProps, Scope.LOCAL); |
| region.put(new Integer(1), new Integer(1)); |
| region.invalidate(new Integer(1)); |
| region.put(new Integer(1), new Integer(2)); |
| region.close(); |
| |
| region = DiskRegionHelperFactory.getSyncPersistOnlyRegion(cache, diskProps, Scope.LOCAL); |
| |
| assertEquals(null, ((LocalRegion) region).getValueInVM(new Integer(1))); |
| assertEquals(new Integer(2), region.get(new Integer(1))); |
| } finally { |
| if (oldValue != null) { |
| System.setProperty(DiskStoreImpl.RECOVER_VALUE_PROPERTY_NAME, oldValue); |
| } else { |
| System.clearProperty(DiskStoreImpl.RECOVER_VALUE_PROPERTY_NAME); |
| } |
| } |
| } |
| |
| /** |
| * Make sure recovery correctly sets stats. Currently this test only checks inVM vs onDisk. It |
| * could be enhanced to also check bucketStats. See bug 41849 for the bug that motivated this unit |
| * test. |
| */ |
| private void basicVerifyStats(boolean recovValues) { |
| String oldValue = System.getProperty(DiskStoreImpl.RECOVER_VALUE_PROPERTY_NAME); |
| System.setProperty(DiskStoreImpl.RECOVER_VALUE_PROPERTY_NAME, "" + recovValues); |
| try { |
| diskProps.setDiskDirs(dirs); |
| diskProps.setPersistBackup(true); |
| diskProps.setRegionName("basicVerifyStats"); |
| region = DiskRegionHelperFactory.getSyncPersistOnlyRegion(cache, diskProps, Scope.LOCAL); |
| region.put(new Integer(1), new Integer(1)); |
| region.put(new Integer(1), new Integer(2)); |
| region.close(); |
| |
| region = DiskRegionHelperFactory.getSyncPersistOnlyRegion(cache, diskProps, Scope.LOCAL); |
| |
| DiskRegion dr = ((LocalRegion) region).getDiskRegion(); |
| if (recovValues) { |
| waitForInVMToBe(dr, 1); |
| assertEquals(0, dr.getNumOverflowOnDisk()); |
| } else { |
| assertEquals(0, dr.getNumEntriesInVM()); |
| assertEquals(1, dr.getNumOverflowOnDisk()); |
| } |
| |
| region.clear(); |
| assertEquals(0, dr.getNumEntriesInVM()); |
| assertEquals(0, dr.getNumOverflowOnDisk()); |
| |
| region.put(new Integer(1), new Integer(1)); |
| region.put(new Integer(1), new Integer(2)); |
| region.localInvalidate(new Integer(1)); |
| region.close(); |
| region = DiskRegionHelperFactory.getSyncPersistOnlyRegion(cache, diskProps, Scope.LOCAL); |
| dr = ((LocalRegion) region).getDiskRegion(); |
| assertEquals(1, region.size()); |
| // invalid entries are not inVM since they have no value |
| assertEquals(0, dr.getNumEntriesInVM()); |
| assertEquals(0, dr.getNumOverflowOnDisk()); |
| |
| region.clear(); |
| assertEquals(0, dr.getNumEntriesInVM()); |
| assertEquals(0, dr.getNumOverflowOnDisk()); |
| |
| region.create(new Integer(1), null); |
| region.put(new Integer(1), new Integer(2)); |
| region.close(); |
| region = DiskRegionHelperFactory.getSyncPersistOnlyRegion(cache, diskProps, Scope.LOCAL); |
| dr = ((LocalRegion) region).getDiskRegion(); |
| if (recovValues) { |
| waitForInVMToBe(dr, 1); |
| assertEquals(0, dr.getNumOverflowOnDisk()); |
| } else { |
| assertEquals(0, dr.getNumEntriesInVM()); |
| assertEquals(1, dr.getNumOverflowOnDisk()); |
| } |
| |
| region.clear(); |
| assertEquals(0, dr.getNumEntriesInVM()); |
| assertEquals(0, dr.getNumOverflowOnDisk()); |
| |
| region.create(new Integer(1), null); |
| region.localInvalidate(new Integer(1)); |
| region.close(); |
| region = DiskRegionHelperFactory.getSyncPersistOnlyRegion(cache, diskProps, Scope.LOCAL); |
| dr = ((LocalRegion) region).getDiskRegion(); |
| // invalid entries have not value so the are not inVM or onDisk |
| assertEquals(0, dr.getNumEntriesInVM()); |
| assertEquals(0, dr.getNumOverflowOnDisk()); |
| |
| region.clear(); |
| assertEquals(0, dr.getNumEntriesInVM()); |
| assertEquals(0, dr.getNumOverflowOnDisk()); |
| |
| region.create(new Integer(1), null); |
| region.put(new Integer(1), new Integer(2)); |
| region.destroy(new Integer(1)); |
| region.close(); // No KRF generated, force multiple reads from CRF for same key |
| region = DiskRegionHelperFactory.getSyncPersistOnlyRegion(cache, diskProps, Scope.LOCAL); |
| dr = ((LocalRegion) region).getDiskRegion(); |
| // entry destroyed so not inVM or onDisk |
| assertEquals(0, dr.getNumEntriesInVM()); |
| assertEquals(0, dr.getNumOverflowOnDisk()); |
| |
| region.clear(); |
| assertEquals(0, dr.getNumEntriesInVM()); |
| assertEquals(0, dr.getNumOverflowOnDisk()); |
| |
| region.create(new Integer(1), null); |
| region.put(new Integer(1), new Integer(2)); |
| region.destroy(new Integer(1)); |
| region.put(new Integer(1), new Integer(2)); // recreate |
| region.invalidate(new Integer(1)); |
| region.close(); // No KRF generated, force multiple reads from CRF for same key |
| region = DiskRegionHelperFactory.getSyncPersistOnlyRegion(cache, diskProps, Scope.LOCAL); |
| dr = ((LocalRegion) region).getDiskRegion(); |
| // entry invalidated so not inVM or onDisk |
| assertEquals(0, dr.getNumEntriesInVM()); |
| assertEquals(0, dr.getNumOverflowOnDisk()); |
| } finally { |
| if (oldValue != null) { |
| System.setProperty(DiskStoreImpl.RECOVER_VALUE_PROPERTY_NAME, oldValue); |
| } else { |
| System.clearProperty(DiskStoreImpl.RECOVER_VALUE_PROPERTY_NAME); |
| } |
| } |
| } |
| |
| private void waitForInVMToBe(final DiskRegion dr, final int expected) { |
| // values are recovered async from disk |
| await() |
| .untilAsserted(() -> assertEquals(expected, dr.getNumEntriesInVM())); |
| } |
| |
| @Test |
| public void testVerifyStatsWithValues() { |
| basicVerifyStats(true); |
| } |
| |
| @Test |
| public void testVerifyStatsNoValues() { |
| basicVerifyStats(false); |
| } |
| |
| } |