📄 t_recovery.java
字号:
/* Derby - Class org.apache.derbyTesting.unitTests.store.T_Recovery Copyright 1997, 2005 The Apache Software Foundation or its licensors, as applicable. Licensed 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.derbyTesting.unitTests.store;import org.apache.derbyTesting.unitTests.harness.T_Generic;import org.apache.derbyTesting.unitTests.harness.T_Fail;import org.apache.derby.iapi.store.raw.*;import org.apache.derby.iapi.reference.SQLState;import org.apache.derby.impl.store.raw.log.LogCounter;import org.apache.derby.iapi.services.context.ContextService;import org.apache.derby.iapi.services.context.ContextManager;import org.apache.derby.iapi.services.locks.*;import org.apache.derby.iapi.services.property.PropertyUtil;import org.apache.derby.iapi.services.monitor.Monitor;import org.apache.derby.iapi.services.sanity.SanityManager;import org.apache.derby.iapi.error.StandardException;import org.apache.derby.iapi.store.raw.xact.RawTransaction;import org.apache.derby.iapi.store.raw.data.RawContainerHandle;import org.apache.derby.iapi.store.raw.log.LogInstant;import org.apache.derby.iapi.store.access.conglomerate.LogicalUndo;import org.apache.derby.iapi.store.access.Qualifier;import org.apache.derby.iapi.types.SQLChar;import org.apache.derby.iapi.types.DataValueDescriptor;import org.apache.derby.iapi.services.uuid.UUIDFactory;import org.apache.derby.catalog.UUID;import org.apache.derby.iapi.reference.Property;import org.apache.derby.iapi.reference.Attribute;import org.apache.derby.iapi.services.io.FormatableBitSet;import java.io.*;import java.util.Properties;/** A protocol unit test for recovery. To run, create a derby.properties file in a new directory with the contents derby.module.test.recovery=org.apache.derbyTesting.unitTests.store.T_Recovery Execute java -DSetupRecovery=true org.apache.derbyTesting.unitTests.harness.UnitTestMain java -DTestRecovery=true org.apache.derbyTesting.unitTests.harness.UnitTestMain*/public class T_Recovery extends T_Generic { private static final String testService = "RecoveryTest"; static final String REC_001 = "McLaren"; static final String REC_002 = "Ferrari"; static final String REC_003 = "Benetton"; static final String REC_004 = "Prost"; static final String REC_005 = "Tyrell"; static final String REC_006 = "Derby, Natscape, Goatscape, the popular names"; static final String REC_UNDO = "Lotus"; static final String REC_NULL = "NULL"; static final String SP1 = "savepoint1"; static final String SP2 = "savepoint2"; static final FormatableBitSet BS_COL_0 = new FormatableBitSet(1); private RandomAccessFile filein = null; private RandomAccessFile fileout = null; private boolean setupRecovery; private boolean testRecovery; private static final String infoPath = "extinout/T_Recovery.info"; private static final String SETUP_RECOVERY = "SetupRecovery"; private static final String TEST_RECOVERY = "TestRecovery"; private static final String RECOVERY_TESTPATH = "RecoveryTestPath"; RawStoreFactory factory; LockFactory lf; ContextService contextService; UUIDFactory uuidfactory; T_Util t_util; public T_Recovery() { super(); BS_COL_0.set(0); } /* ** Methods required by T_Generic */ public String getModuleToTestProtocolName() { return RawStoreFactory.MODULE; } /** */ private void getConfig() { String param = PropertyUtil.getSystemProperty(SETUP_RECOVERY); setupRecovery = Boolean.valueOf(param).booleanValue(); param = PropertyUtil.getSystemProperty(TEST_RECOVERY); testRecovery = Boolean.valueOf(param).booleanValue(); } /** Tests in here come in pairs (Snnn Rnnn), one to set it up, one to test it after recovery. Information that needs to be passed from the setup to the recovery should, ideally, be written out to a database. For now, it is written out as a pair of <key,value> long in the file T_Recovery.info. To make sure you don't accidently tramples on someone else's key, encode your test number (nnn) by shifting over 32 bits and then add your key. Multiple invocations which needs paramaters saved should be encoded futher. 001 < nnn < 200 - no recovery undo 200 < nnn < 400 - recovery undo @exception T_Fail Unexpected behaviour from the API */ public void runTests() throws T_Fail { getConfig(); if (!(setupRecovery ^ testRecovery)) throw T_Fail.testFailMsg("One & only one of the SetupRecovery and TestRecovery properties must be set"); try { uuidfactory = Monitor.getMonitor().getUUIDFactory(); if (uuidfactory == null) { throw T_Fail.testFailMsg("UUIDFactory.MODULE not found"); } // see if we are testing encryption startParams = T_Util.setEncryptionParam(startParams); contextService = ContextService.getFactory(); if (testRecovery) { if (!Monitor.startPersistentService(testService, startParams)) throw T_Fail.testFailMsg("Monitor didn't know how to restart service: " + testService); factory = (RawStoreFactory) Monitor.findService(getModuleToTestProtocolName(), testService); } else // setup { // don't automatic boot this service if it gets left around if (startParams == null) startParams = new Properties(); startParams.put(Property.NO_AUTO_BOOT, Boolean.TRUE.toString()); // do not make T_Recovery test a source, or it won't run on a // syncless configuration // // remove the service directory to ensure a clean run startParams.put(Property.DELETE_ON_CREATE, Boolean.TRUE.toString()); // keep all log files for diagnostics startParams.put(RawStoreFactory.KEEP_TRANSACTION_LOG, "true"); factory = (RawStoreFactory) Monitor.createPersistentService(getModuleToTestProtocolName(), testService, startParams); } } catch (StandardException mse) { throw T_Fail.exceptionFail(mse); } if (factory == null) { throw T_Fail.testFailMsg(getModuleToTestProtocolName() + " service not started."); } lf = factory.getLockFactory(); if (lf == null) { throw T_Fail.testFailMsg("LockFactory.MODULE not found"); } // get a utility helper t_util = new T_Util(factory, lf, contextService); try { if (setupRecovery) { // dmls S001(); // insert 1 row S002(); // insert a bunch of rows S003(); // update row S004(); // update field S005(); // purge and delete S006(); // page allocation S007(); // page deallocation S008(); // rollback of page deallocation S009(); // deallocation and reuse of page S010(); // allocation/deallocation with overflow pages S011(); // allocate a lot of pages so that > 1 // allocation pages are needed S012(); // test page estimation // ddls S020(); // create multiple containers S022(); // committed transactions S100(); // multiple intervening transactions S101(); // transaction with rollback to savepoints // aborted transaction // - these transactions are rollback during runtime - // incomplete transaction // - these transactions are rollback during recovery - S200(); // 1 incomplete transaction S201(); // multiple intervening incomplete transaction S202(); // incomplete transaction with rollback to // savepoint S203(); // incomplete and committed and aborted // transaction with intervening rollback to savepoints S204(); // incomplete and committed and aborted // internal transactions // incomplete transaction with ddls S300(); // incomplete transactions with drop containers S301(); // incomplete transactions with create containers S302(); //purging rows with no data logged S303(); //purging long columns with no data logged S304(); //pruging long rows with no data logged. } if (testRecovery || setupRecovery) { // basic recovery R001(); R002(); R003(); R004(); R005(); R006(); R007(); R008(); R009(); R010(); R011(); R012(); R020(); R022(); R100(); R101(); R302(); // the following tests depends on recovery to roll back the // changes. Only test them after recovery and not during setup if (testRecovery) { R200(); R201(); R202(); R203(); R204(); R300(); R301(); R303(); R304(); R999(); } } if (setupRecovery) { S999(); // always run this last, this leaves a 1/2 // written log record at the end of the log // and it leaves a page latched } if (fileout != null) { fileout.close(); fileout = null; } if (filein != null) { filein.close(); filein = null; } } catch (Throwable t) { SanityManager.showTrace(t); System.out.println("caught exception t " + t); t.printStackTrace(); // this test should exit the JVM as abruptly as possible. System.exit(0); } } private long find(long inkey) throws T_Fail { try { if (filein == null) { // make sure it does exist File infoFile = new File(infoPath); if (infoFile.exists()) { try { filein = new RandomAccessFile(infoFile, "r"); } catch (IOException ioe) { System.out.println("Cannot write to temporary file " + infoPath + ". Please make sure it is correct, if not, please set the property " + "RecoveryTestPath=<where temp files should go>"); throw T_Fail.exceptionFail(ioe); } } else return -1; } filein.seek(0); long key; while(true) { key = filein.readLong(); if (key == inkey) { long value = filein.readLong(); // System.out.println("found " + key + " " + value); return value; } filein.readLong(); } } catch (IOException ioe) { // System.out.println("key not found " + inkey); return -1; } } private long key(int test, int param) { long i = test; return ((i << 32) + param); } private void register(long key, long value) throws T_Fail { // System.out.println("registering " + key + " " + value); try { if (fileout == null) { // make sure it does not exist File infofile = new File(infoPath); if (infofile.exists()) infofile.delete(); //if external input output files dir does not exist ,create one File ifdir = new File("extinout"); if(!ifdir.exists()) ifdir.mkdirs(); fileout = new RandomAccessFile(infoPath, "rw"); } fileout.writeLong(key); fileout.writeLong(value); } catch (IOException ioe) { T_Fail.exceptionFail(ioe); } } /* * test 1 - insert 1 row */ protected void S001() throws T_Fail, StandardException { Transaction t = t_util.t_startTransaction(); long cid = t_util.t_addContainer(t, 0); t_util.t_commit(t); ContainerHandle c = t_util.t_openContainer(t, 0, cid, true); Page page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER); try { T_RawStoreRow row1 = new T_RawStoreRow(REC_001); RecordHandle r1 = t_util.t_insertAtSlot(page, 0, row1); page.unlatch(); c.close(); register(key(1, 1), cid); } finally { t_util.t_commit(t); t.close(); } REPORT("setup S001: " + cid); } /* recover test 1 */ protected void R001() throws T_Fail, StandardException { long cid = find(key(1, 1)); if (cid < 0) { REPORT("R001 not run"); return; } Transaction t = t_util.t_startTransaction(); try { ContainerHandle c = t_util.t_openContainer(t, 0, cid, false); Page page = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER); t_util.t_checkRecordCount(page, 1, 1); t_util.t_checkFieldCount(page, 0, 1); t_util.t_checkFetchBySlot(page, 0, REC_001, false, false); page.unlatch(); } finally { t_util.t_commit(t); t.close(); } PASS("R001: containerId " + cid); } /* * test 2 - insert a bunch of rows into one container */ protected void S002() throws T_Fail, StandardException { Transaction t = t_util.t_startTransaction(); long cid = t_util.t_addContainer(t, 0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -