KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sleepycat > je > log > FileEdgeCaseTest


1 /*-
2  * See the file LICENSE for redistribution information.
3  *
4  * Copyright (c) 2002,2006 Oracle. All rights reserved.
5  *
6  * $Id: FileEdgeCaseTest.java,v 1.1 2006/11/27 18:38:28 linda Exp $
7  */

8
9 package com.sleepycat.je.log;
10
11 import java.io.File JavaDoc;
12 import java.io.IOException JavaDoc;
13 import java.io.RandomAccessFile JavaDoc;
14
15 import junit.framework.TestCase;
16
17 import com.sleepycat.je.DatabaseException;
18 import com.sleepycat.je.DbInternal;
19 import com.sleepycat.je.Environment;
20 import com.sleepycat.je.EnvironmentConfig;
21 import com.sleepycat.je.dbi.EnvironmentImpl;
22 import com.sleepycat.je.recovery.NoRootException;
23 import com.sleepycat.je.util.TestUtils;
24
25 public class FileEdgeCaseTest extends TestCase {
26
27     private File JavaDoc envHome;
28     private Environment env;
29     private String JavaDoc firstFile;
30
31     public FileEdgeCaseTest() {
32         envHome = new File JavaDoc(System.getProperty(TestUtils.DEST_DIR));
33     }
34
35     public void setUp()
36         throws IOException JavaDoc {
37
38         TestUtils.removeLogFiles("Setup", envHome, false);
39     }
40     
41     public void tearDown()
42         throws Exception JavaDoc {
43
44         /*
45      * Close down environments in case the unit test failed so that the log
46      * files can be removed.
47          */

48         try {
49             if (env != null) {
50                 env.close();
51                 env = null;
52             }
53         } catch (DatabaseException e) {
54             e.printStackTrace();
55             // ok, the test closed it
56
}
57        TestUtils.removeLogFiles("TearDown", envHome, false);
58     }
59
60     /**
61      * SR #15133
62      * Create a JE environment with a single log file and a checksum
63      * exception in the second entry in the log file.
64      *
65      * When an application attempts to open this JE environment, JE truncates
66      * the log file at the point before the bad checksum, because it assumes
67      * that bad entries at the end of the log are the result of incompletely
68      * flushed writes from the last environment use. However, the truncated
69      * log doesn't have a valid environment root, so JE complains and asks the
70      * application to move aside the existing log file (via the exception
71      * message). The resulting environment has a single log file, with
72      * a single valid entry, which is the file header.
73      *
74      * Any subsequent attempts to open the environment should also fail at the
75      * same point. In the error case reported by this SR, we didn't handle this
76      * single log file/single file header case right, and subsequent opens
77      * first truncated before the file header, leaving a 0 length log, and
78      * then proceeded to write error trace messages into the log. This
79      * resulted in a log file with no file header, (but with trace messages)
80      * and any following opens got unpredictable errors like
81      * ClassCastExceptions and BufferUnderflows.
82      *
83      * The correct situation is to continue to get the same exception.
84      */

85     public void testPostChecksumError()
86         throws IOException JavaDoc, DatabaseException {
87
88         EnvironmentConfig config = new EnvironmentConfig();
89         config.setAllowCreate(true);
90         env = new Environment(envHome, config);
91
92         EnvironmentImpl envImpl = DbInternal.envGetEnvironmentImpl(env);
93         FileManager fm = envImpl.getFileManager();
94         firstFile = fm.getFullFileName(0, FileManager.JE_SUFFIX);
95
96         env.close();
97         env = null;
98         
99         /* Intentionally corrupt the second entry. */
100         corruptSecondEntry();
101
102         /*
103          * Next attempt to open the environment should fail with a
104          * NoRootException
105          */

106         try {
107             env = new Environment(envHome, config);
108         } catch (NoRootException expected) {
109         }
110
111         /*
112          * Next attempt to open the environment should fail with a
113          * NoRootException
114          */

115         try {
116             env = new Environment(envHome, config);
117         } catch (NoRootException expected) {
118         }
119     }
120
121     /**
122      * Write junk into the second log entry, after the file header.
123      */

124     private void corruptSecondEntry()
125         throws IOException JavaDoc {
126
127         RandomAccessFile JavaDoc file =
128             new RandomAccessFile JavaDoc(firstFile,
129                                  FileManager.FileMode.
130                                  READWRITE_MODE.getModeValue());
131         
132         int headerSize = FileHeader.entrySize();
133         try {
134             byte [] junk = new byte[20];
135             file.seek(headerSize + LogManager.HEADER_BYTES + 2);
136             file.write(junk);
137         } catch (Exception JavaDoc e) {
138             e.printStackTrace();
139         } finally {
140             file.close();
141         }
142     }
143 }
144
Popular Tags