1 /*- 2 * See the file LICENSE for redistribution information. 3 * 4 * Copyright (c) 2000, 2010 Oracle and/or its affiliates. All rights reserved. 5 * 6 */ 7 package com.sleepycat.persist.test; 8 9 import static org.junit.Assert.assertEquals; 10 import static org.junit.Assert.assertTrue; 11 12 import org.junit.After; 13 import org.junit.Before; 14 import org.junit.Test; 15 16 import com.sleepycat.persist.evolve.EvolveConfig; 17 import com.sleepycat.persist.evolve.EvolveEvent; 18 import com.sleepycat.persist.evolve.EvolveListener; 19 import com.sleepycat.persist.evolve.EvolveStats; 20 import com.sleepycat.persist.impl.PersistCatalog; 21 import com.sleepycat.util.test.SharedTestUtils; 22 23 /** 24 * Runs part two of the EvolveTest. This part is run with the new/updated 25 * version of EvolveClasses in the classpath. It uses the environment and 26 * store created by EvolveTestInit. It verifies that it can read/write/evolve 27 * objects serialized using the old class format, and that it can create new 28 * objects with the new class format. 29 * 30 * @author Mark Hayes 31 */ 32 public class EvolveTest extends EvolveTestBase { 33 EvolveTest(String originalClsName, String evolvedClsName)34 public EvolveTest(String originalClsName, String evolvedClsName) 35 throws Exception { 36 super(originalClsName, evolvedClsName); 37 } 38 39 /* Toggle to use listener every other test case. */ 40 private static boolean useEvolveListener; 41 42 private int evolveNRead; 43 private int evolveNConverted; 44 useEvolvedClass()45 boolean useEvolvedClass() { 46 return true; 47 } 48 49 @Before setUp()50 public void setUp() 51 throws Exception { 52 53 super.setUp(); 54 55 /* Copy the log files created by EvolveTestInit. */ 56 envHome = getTestInitHome(true /*evolved*/); 57 envHome.mkdirs(); 58 SharedTestUtils.emptyDir(envHome); 59 SharedTestUtils.copyFiles(getTestInitHome(false /*evolved*/), envHome); 60 } 61 62 @After tearDown()63 public void tearDown() { 64 try { super.tearDown(); } catch (Throwable e) { } 65 } 66 67 @Test testLazyEvolve()68 public void testLazyEvolve() 69 throws Exception { 70 71 openEnv(); 72 73 /* 74 * Open in raw mode to check unevolved raw object and formats. This 75 * is possible whether or not we can open the store further below to 76 * evolve formats without errors. 77 */ 78 openRawStore(); 79 caseObj.checkUnevolvedModel(rawStore.getModel(), env); 80 caseObj.readRawObjects 81 (rawStore, false /*expectEvolved*/, false /*expectUpdated*/); 82 closeRawStore(); 83 84 /* 85 * Check evolution in read-only mode. Since Replica upgrade mode is 86 * effectively read-only mode, this also helps to test evolution during 87 * replication group upgrades. [#18690] 88 */ 89 if (openStoreReadOnly()) { 90 caseObj.checkEvolvedModel 91 (store.getModel(), env, true /*oldTypesExist*/); 92 caseObj.readObjects(store, false /*doUpdate*/); 93 closeStore(); 94 } 95 96 if (openStoreReadWrite()) { 97 98 /* 99 * When opening read-write, formats are evolved lazily. Check by 100 * reading evolved objects. 101 */ 102 caseObj.checkEvolvedModel 103 (store.getModel(), env, true /*oldTypesExist*/); 104 caseObj.readObjects(store, false /*doUpdate*/); 105 closeStore(); 106 107 /* 108 * Read raw objects again to check that the evolved objects are 109 * returned even though the stored objects were not evolved. 110 */ 111 openRawStore(); 112 caseObj.checkEvolvedModel 113 (rawStore.getModel(), env, true /*oldTypesExist*/); 114 caseObj.readRawObjects 115 (rawStore, true /*expectEvolved*/, false /*expectUpdated*/); 116 closeRawStore(); 117 118 /* 119 * Open read-only to ensure that the catalog does not need to 120 * change (evolve formats) unnecessarily. 121 */ 122 PersistCatalog.expectNoClassChanges = true; 123 try { 124 assertTrue(openStoreReadOnly()); 125 } finally { 126 PersistCatalog.expectNoClassChanges = false; 127 } 128 caseObj.checkEvolvedModel 129 (store.getModel(), env, true /*oldTypesExist*/); 130 caseObj.readObjects(store, false /*doUpdate*/); 131 closeStore(); 132 133 /* 134 * Open read-write to update objects and store them in evolved 135 * format. 136 */ 137 openStoreReadWrite(); 138 caseObj.checkEvolvedModel 139 (store.getModel(), env, true /*oldTypesExist*/); 140 caseObj.readObjects(store, true /*doUpdate*/); 141 caseObj.checkEvolvedModel 142 (store.getModel(), env, true /*oldTypesExist*/); 143 closeStore(); 144 145 /* 146 * Check raw objects again after the evolved objects were stored. 147 */ 148 openRawStore(); 149 caseObj.checkEvolvedModel 150 (rawStore.getModel(), env, true /*oldTypesExist*/); 151 caseObj.readRawObjects 152 (rawStore, true /*expectEvolved*/, true /*expectUpdated*/); 153 closeRawStore(); 154 } 155 156 closeAll(); 157 } 158 159 @Test testEagerEvolve()160 public void testEagerEvolve() 161 throws Exception { 162 163 /* If the store cannot be opened, this test is not appropriate. */ 164 if (caseObj.getStoreOpenException() != null) { 165 return; 166 } 167 168 EvolveConfig config = new EvolveConfig(); 169 170 /* 171 * Use listener every other time to ensure that the stats are returned 172 * correctly when no listener is configured. [#17024] 173 */ 174 useEvolveListener = !useEvolveListener; 175 if (useEvolveListener) { 176 config.setEvolveListener(new EvolveListener() { 177 public boolean evolveProgress(EvolveEvent event) { 178 EvolveStats stats = event.getStats(); 179 evolveNRead = stats.getNRead(); 180 evolveNConverted = stats.getNConverted(); 181 return true; 182 } 183 }); 184 } 185 186 openEnv(); 187 188 openStoreReadWrite(); 189 190 /* 191 * Evolve and expect that the expected number of entities are 192 * converted. 193 */ 194 int nExpected = caseObj.getNRecordsExpected(); 195 evolveNRead = 0; 196 evolveNConverted = 0; 197 PersistCatalog.unevolvedFormatsEncountered = false; 198 EvolveStats stats = store.evolve(config); 199 if (nExpected > 0) { 200 assertTrue(PersistCatalog.unevolvedFormatsEncountered); 201 } 202 assertTrue(stats.getNRead() == nExpected); 203 assertTrue(stats.getNConverted() == nExpected); 204 assertTrue(stats.getNConverted() >= stats.getNRead()); 205 if (useEvolveListener) { 206 assertEquals(evolveNRead, stats.getNRead()); 207 assertEquals(evolveNConverted, stats.getNConverted()); 208 } 209 210 /* Evolve again and expect that no entities are converted. */ 211 evolveNRead = 0; 212 evolveNConverted = 0; 213 PersistCatalog.unevolvedFormatsEncountered = false; 214 stats = store.evolve(config); 215 assertTrue(!PersistCatalog.unevolvedFormatsEncountered); 216 assertEquals(0, stats.getNRead()); 217 assertEquals(0, stats.getNConverted()); 218 if (useEvolveListener) { 219 assertTrue(evolveNRead == 0); 220 assertTrue(evolveNConverted == 0); 221 } 222 223 /* Ensure that we can read all entities without evolution. */ 224 PersistCatalog.unevolvedFormatsEncountered = false; 225 caseObj.readObjects(store, false /*doUpdate*/); 226 assertTrue(!PersistCatalog.unevolvedFormatsEncountered); 227 228 /* 229 * When automatic unused type deletion is implemented in the future the 230 * oldTypesExist parameters below should be changed to false. 231 */ 232 233 /* Open again and try an update. */ 234 caseObj.checkEvolvedModel 235 (store.getModel(), env, true /*oldTypesExist*/); 236 caseObj.readObjects(store, true /*doUpdate*/); 237 caseObj.checkEvolvedModel 238 (store.getModel(), env, true /*oldTypesExist*/); 239 closeStore(); 240 241 /* Open read-only and double check that everything is OK. */ 242 assertTrue(openStoreReadOnly()); 243 caseObj.checkEvolvedModel 244 (store.getModel(), env, true /*oldTypesExist*/); 245 caseObj.readObjects(store, false /*doUpdate*/); 246 caseObj.checkEvolvedModel 247 (store.getModel(), env, true /*oldTypesExist*/); 248 closeStore(); 249 250 /* Check raw objects. */ 251 openRawStore(); 252 caseObj.checkEvolvedModel 253 (rawStore.getModel(), env, true /*oldTypesExist*/); 254 caseObj.readRawObjects 255 (rawStore, true /*expectEvolved*/, true /*expectUpdated*/); 256 257 /* 258 * Test copy raw object to new store via convertRawObject. In this 259 * test we can pass false for oldTypesExist because newStore starts 260 * with the new/evolved class model. 261 */ 262 openNewStore(); 263 caseObj.copyRawObjects(rawStore, newStore); 264 caseObj.readObjects(newStore, true /*doUpdate*/); 265 caseObj.checkEvolvedModel 266 (newStore.getModel(), env, false /*oldTypesExist*/); 267 closeNewStore(); 268 closeRawStore(); 269 270 closeAll(); 271 } 272 } 273