001: /*-
002: * See the file LICENSE for redistribution information.
003: *
004: * Copyright (c) 2002,2008 Oracle. All rights reserved.
005: *
006: * $Id: FSyncManagerTest.java,v 1.10.2.3 2008/01/07 15:14:29 cwl Exp $
007: */
008:
009: package com.sleepycat.je.log;
010:
011: import java.io.File;
012:
013: import junit.framework.TestCase;
014:
015: import com.sleepycat.je.DatabaseException;
016: import com.sleepycat.je.DbInternal;
017: import com.sleepycat.je.Environment;
018: import com.sleepycat.je.EnvironmentConfig;
019: import com.sleepycat.je.config.EnvironmentParams;
020: import com.sleepycat.je.dbi.EnvironmentImpl;
021: import com.sleepycat.je.junit.JUnitThread;
022: import com.sleepycat.je.util.TestUtils;
023:
024: /**
025: * Exercise the synchronization aspects of the sync manager.
026: */
027: public class FSyncManagerTest extends TestCase {
028: private File envHome;
029:
030: public FSyncManagerTest() {
031: super ();
032: envHome = new File(System.getProperty(TestUtils.DEST_DIR));
033: }
034:
035: protected void setUp() throws Exception {
036: /* Remove files to start with a clean slate. */
037: TestUtils.removeLogFiles("Setup", envHome, false);
038: }
039:
040: protected void tearDown() throws Exception {
041:
042: TestUtils.removeLogFiles("TearDown", envHome, false);
043: }
044:
045: public void testBasic() throws Throwable {
046: Environment env = null;
047:
048: try {
049: EnvironmentConfig envConfig = TestUtils.initEnvConfig();
050: envConfig.setConfigParam(
051: EnvironmentParams.LOG_FSYNC_TIMEOUT.getName(),
052: "50000000");
053: envConfig.setAllowCreate(true);
054: env = new Environment(envHome, envConfig);
055:
056: WaitVal waitVal = new WaitVal(0);
057:
058: FSyncManager syncManager = new TestSyncManager(DbInternal
059: .envGetEnvironmentImpl(env), waitVal);
060: JUnitThread t1 = new TestSyncThread(syncManager);
061: JUnitThread t2 = new TestSyncThread(syncManager);
062: JUnitThread t3 = new TestSyncThread(syncManager);
063: t1.start();
064: t2.start();
065: t3.start();
066:
067: /* Wait for all threads to request a sync, so they form a group.*/
068: Thread.sleep(500);
069:
070: /* Free thread 1. */
071: synchronized (waitVal) {
072: waitVal.value = 1;
073: waitVal.notify();
074: }
075:
076: t1.join();
077: t2.join();
078: t3.join();
079:
080: /*
081: * All three threads ask for fsyncs.
082: * 2 do fsyncs -- the initial leader, and the leader of the
083: * waiting group of 2.
084: * The last thread gets a free ride.
085: */
086: assertEquals(3, syncManager.getNFSyncRequests());
087: assertEquals(2, syncManager.getNFSyncs());
088: assertEquals(0, syncManager.getNTimeouts());
089: } finally {
090: if (env != null) {
091: env.close();
092: }
093: }
094: }
095:
096: /* This test class waits for an object instead of executing a sync.
097: * This way, we can manipulate grouping behavior.
098: */
099: class TestSyncManager extends FSyncManager {
100: private WaitVal waitVal;
101:
102: TestSyncManager(EnvironmentImpl env, WaitVal waitVal)
103: throws DatabaseException {
104: super (env);
105: this .waitVal = waitVal;
106: }
107:
108: protected void executeFSync() throws DatabaseException {
109: try {
110: synchronized (waitVal) {
111: if (waitVal.value < 1) {
112: waitVal.wait();
113: }
114: }
115: } catch (InterruptedException e) {
116: // woken up.
117: }
118: }
119: }
120:
121: class TestSyncThread extends JUnitThread {
122: private FSyncManager syncManager;
123:
124: TestSyncThread(FSyncManager syncManager) {
125: super ("syncThread");
126: this .syncManager = syncManager;
127: }
128:
129: public void testBody() throws Throwable {
130: syncManager.fsync();
131: }
132: }
133:
134: class WaitVal {
135: public int value;
136:
137: WaitVal(int value) {
138: this.value = value;
139: }
140: }
141: }
|