KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sleepycat > je > cleaner > ReadOnlyLockingTest


1 /*-
2  * See the file LICENSE for redistribution information.
3  *
4  * Copyright (c) 2002,2006 Oracle. All rights reserved.
5  *
6  * $Id: ReadOnlyLockingTest.java,v 1.9 2006/11/22 23:54:49 mark Exp $
7  */

8
9 package com.sleepycat.je.cleaner;
10
11 import java.io.File JavaDoc;
12 import java.io.IOException JavaDoc;
13 import java.io.InputStream JavaDoc;
14
15 import junit.framework.TestCase;
16
17 import com.sleepycat.je.CheckpointConfig;
18 import com.sleepycat.je.Database;
19 import com.sleepycat.je.DatabaseConfig;
20 import com.sleepycat.je.DatabaseEntry;
21 import com.sleepycat.je.DatabaseException;
22 import com.sleepycat.je.DbInternal;
23 import com.sleepycat.je.Environment;
24 import com.sleepycat.je.EnvironmentConfig;
25 import com.sleepycat.je.config.EnvironmentParams;
26 import com.sleepycat.je.dbi.EnvironmentImpl;
27 import com.sleepycat.je.log.FileManager;
28 import com.sleepycat.je.util.TestUtils;
29
30 /**
31  * Verifies that opening an environment read-only will prevent cleaned files
32  * from being deleted in a read-write environment. Uses the ReadOnlyProcess
33  * class to open the environment read-only in a separate process.
34  */

35 public class ReadOnlyLockingTest extends TestCase {
36
37     private static final int FILE_SIZE = 4096;
38     private static final int READER_STARTUP_SECS = 30;
39
40     private static final CheckpointConfig forceConfig = new CheckpointConfig();
41     static {
42         forceConfig.setForce(true);
43     }
44
45     private File JavaDoc envHome;
46     private Environment env;
47     private EnvironmentImpl envImpl;
48     private Database db;
49     private Process JavaDoc readerProcess;
50
51     private static File JavaDoc getProcessFile() {
52         return new File JavaDoc(System.getProperty(TestUtils.DEST_DIR),
53                         "ReadOnlyProcessFile");
54     }
55
56     private static void deleteProcessFile() {
57         File JavaDoc file = getProcessFile();
58         file.delete();
59         TestCase.assertTrue(!file.exists());
60     }
61
62     static void createProcessFile()
63         throws IOException JavaDoc {
64             
65         File JavaDoc file = getProcessFile();
66         TestCase.assertTrue(file.createNewFile());
67         TestCase.assertTrue(file.exists());
68     }
69
70     public ReadOnlyLockingTest() {
71         envHome = new File JavaDoc(System.getProperty(TestUtils.DEST_DIR));
72     }
73
74     public void setUp()
75         throws IOException JavaDoc, DatabaseException {
76
77         deleteProcessFile();
78
79         TestUtils.removeLogFiles("Setup", envHome, false);
80         TestUtils.removeFiles("Setup", envHome, FileManager.DEL_SUFFIX);
81     }
82
83     public void tearDown()
84         throws IOException JavaDoc, DatabaseException {
85
86         deleteProcessFile();
87
88         try {
89             stopReaderProcess();
90         } catch (Throwable JavaDoc e) {
91             System.out.println("tearDown: " + e);
92         }
93
94         try {
95             if (env != null) {
96                 env.close();
97             }
98         } catch (Throwable JavaDoc e) {
99             System.out.println("tearDown: " + e);
100         }
101                 
102         try {
103             TestUtils.removeLogFiles("tearDown", envHome, true);
104             TestUtils.removeFiles("tearDown", envHome, FileManager.DEL_SUFFIX);
105         } catch (Throwable JavaDoc e) {
106             System.out.println("tearDown: " + e);
107         }
108
109         db = null;
110         env = null;
111         envImpl = null;
112         envHome = null;
113         readerProcess = null;
114     }
115
116     private void openEnv()
117         throws DatabaseException {
118
119         EnvironmentConfig envConfig = TestUtils.initEnvConfig();
120     DbInternal.disableParameterValidation(envConfig);
121         envConfig.setTransactional(true);
122         envConfig.setAllowCreate(true);
123         envConfig.setTxnNoSync(Boolean.getBoolean(TestUtils.NO_SYNC));
124         envConfig.setConfigParam
125             (EnvironmentParams.CLEANER_MIN_UTILIZATION.getName(), "80");
126         envConfig.setConfigParam
127             (EnvironmentParams.LOG_FILE_MAX.getName(),
128              Integer.toString(FILE_SIZE));
129         envConfig.setConfigParam
130             (EnvironmentParams.ENV_RUN_CLEANER.getName(), "false");
131         envConfig.setConfigParam
132         (EnvironmentParams.ENV_RUN_CHECKPOINTER.getName(), "false");
133
134         env = new Environment(envHome, envConfig);
135         envImpl = DbInternal.envGetEnvironmentImpl(env);
136
137         DatabaseConfig dbConfig = new DatabaseConfig();
138         dbConfig.setTransactional(true);
139         dbConfig.setAllowCreate(true);
140         db = env.openDatabase(null, "ReadOnlyLockingTest", dbConfig);
141     }
142
143     private void closeEnv()
144         throws DatabaseException {
145
146         if (db != null) {
147             db.close();
148             db = null;
149         }
150         if (env != null) {
151             env.close();
152             env = null;
153         }
154     }
155
156     /**
157      * Tests that cleaned files are deleted when there is no reader process.
158      */

159     public void testBaseline()
160         throws DatabaseException {
161
162         openEnv();
163         writeAndDeleteData();
164         env.checkpoint(forceConfig);
165
166         int nFilesCleaned = env.cleanLog();
167         assertTrue(nFilesCleaned > 0);
168         assertTrue(!areAnyFilesDeleted());
169
170         /* Files are deleted during the checkpoint. */
171         env.checkpoint(forceConfig);
172         assertTrue(areAnyFilesDeleted());
173
174         closeEnv();
175     }
176
177     /**
178      * Tests that cleaned files are not deleted when there is a reader process.
179      */

180     public void testReadOnlyLocking()
181         throws Exception JavaDoc {
182
183         openEnv();
184         writeAndDeleteData();
185         env.checkpoint(forceConfig);
186         int nFilesCleaned = env.cleanLog();
187         assertTrue(nFilesCleaned > 0);
188         assertTrue(!areAnyFilesDeleted());
189
190         /*
191          * No files are deleted after cleaning when the reader process is
192          * running.
193          */

194         startReaderProcess();
195         env.cleanLog();
196         env.checkpoint(forceConfig);
197         assertTrue(!areAnyFilesDeleted());
198
199         /*
200          * Files are deleted when a checkpoint occurs after the reader
201          * process stops.
202          */

203         stopReaderProcess();
204         env.cleanLog();
205         env.checkpoint(forceConfig);
206         assertTrue(areAnyFilesDeleted());
207
208         closeEnv();
209     }
210
211     private void writeAndDeleteData()
212         throws DatabaseException {
213
214         DatabaseEntry key = new DatabaseEntry(new byte[1]);
215         DatabaseEntry data = new DatabaseEntry(new byte[FILE_SIZE]);
216         for (int i = 0; i < 5; i += 1) {
217             db.put(null, key, data);
218         }
219     }
220
221     private boolean areAnyFilesDeleted() {
222         long lastNum = envImpl.getFileManager().getLastFileNum().longValue();
223         for (long i = 0; i <= lastNum; i += 1) {
224             String JavaDoc name = envImpl.getFileManager().getFullFileName
225                 (i, FileManager.JE_SUFFIX);
226             if (!(new File JavaDoc(name).exists())) {
227                 return true;
228             }
229         }
230         return false;
231     }
232
233     private void startReaderProcess()
234         throws Exception JavaDoc {
235
236         String JavaDoc[] cmd = {
237             "java",
238             "-cp",
239             System.getProperty("java.class.path"),
240             "-D" + TestUtils.DEST_DIR + '=' +
241                 System.getProperty(TestUtils.DEST_DIR),
242             ReadOnlyProcess.class.getName(),
243         };
244
245         /* Start it and wait for it to open the environment. */
246         readerProcess = Runtime.getRuntime().exec(cmd);
247         long startTime = System.currentTimeMillis();
248         boolean running = false;
249         while (!running &&
250                ((System.currentTimeMillis() - startTime) <
251                 (READER_STARTUP_SECS * 1000))) {
252             if (getProcessFile().exists()) {
253                 running = true;
254             } else {
255                 Thread.sleep(10);
256             }
257         }
258         //printReaderStatus();
259
assertTrue("ReadOnlyProcess did not start after " +
260                    READER_STARTUP_SECS + " + secs",
261                    running);
262     }
263
264     private void stopReaderProcess()
265         throws Exception JavaDoc {
266
267         if (readerProcess != null) {
268             printReaderErrors();
269             readerProcess.destroy();
270             Thread.sleep(2000);
271             readerProcess = null;
272         }
273     }
274
275     private void printReaderStatus()
276         throws IOException JavaDoc {
277
278         try {
279             int status = readerProcess.exitValue();
280             System.out.println("Process status=" + status);
281         } catch (IllegalThreadStateException JavaDoc e) {
282             System.out.println("Process is still running");
283         }
284     }
285
286     private void printReaderErrors()
287         throws IOException JavaDoc {
288
289         InputStream JavaDoc err = readerProcess.getErrorStream();
290         int len = err.available();
291         if (len > 0) {
292             byte[] data = new byte[len];
293             err.read(data);
294             System.out.println("[ReadOnlyProcess] " + new String JavaDoc(data));
295         }
296     }
297 }
298
Popular Tags