+++ /dev/null
-package org.apache.lucene.store;
-
-/**
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.
- */
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.lucene.analysis.MockAnalyzer;
-import org.apache.lucene.document.Document;
-import org.apache.lucene.document.Field;
-import org.apache.lucene.index.IndexWriter;
-import org.apache.lucene.index.IndexWriterConfig;
-import org.apache.lucene.index.Term;
-import org.apache.lucene.index.IndexWriterConfig.OpenMode;
-import org.apache.lucene.search.IndexSearcher;
-import org.apache.lucene.search.Query;
-import org.apache.lucene.search.TermQuery;
-import org.apache.lucene.util.LuceneTestCase;
-import org.apache.lucene.util._TestUtil;
-
-public class TestLockFactory extends LuceneTestCase {
-
- // Verify: we can provide our own LockFactory implementation, the right
- // methods are called at the right time, locks are created, etc.
-
- public void testCustomLockFactory() throws IOException {
- Directory dir = new MockDirectoryWrapper(random, new RAMDirectory());
- MockLockFactory lf = new MockLockFactory();
- dir.setLockFactory(lf);
-
- // Lock prefix should have been set:
- assertTrue("lock prefix was not set by the RAMDirectory", lf.lockPrefixSet);
-
- IndexWriter writer = new IndexWriter(dir, new IndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random)));
-
- // add 100 documents (so that commit lock is used)
- for (int i = 0; i < 100; i++) {
- addDoc(writer);
- }
-
- // Both write lock and commit lock should have been created:
- assertEquals("# of unique locks created (after instantiating IndexWriter)",
- 1, lf.locksCreated.size());
- assertTrue("# calls to makeLock is 0 (after instantiating IndexWriter)",
- lf.makeLockCount >= 1);
-
- for(final String lockName : lf.locksCreated.keySet()) {
- MockLockFactory.MockLock lock = (MockLockFactory.MockLock) lf.locksCreated.get(lockName);
- assertTrue("# calls to Lock.obtain is 0 (after instantiating IndexWriter)",
- lock.lockAttempts > 0);
- }
-
- writer.close();
- }
-
- // Verify: we can use the NoLockFactory with RAMDirectory w/ no
- // exceptions raised:
- // Verify: NoLockFactory allows two IndexWriters
- public void testRAMDirectoryNoLocking() throws IOException {
- Directory dir = new MockDirectoryWrapper(random, new RAMDirectory());
- dir.setLockFactory(NoLockFactory.getNoLockFactory());
-
- assertTrue("RAMDirectory.setLockFactory did not take",
- NoLockFactory.class.isInstance(dir.getLockFactory()));
-
- IndexWriter writer = new IndexWriter(dir, new IndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random)));
- writer.commit(); // required so the second open succeed
- // Create a 2nd IndexWriter. This is normally not allowed but it should run through since we're not
- // using any locks:
- IndexWriter writer2 = null;
- try {
- writer2 = new IndexWriter(dir, new IndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random)).setOpenMode(OpenMode.APPEND));
- } catch (Exception e) {
- e.printStackTrace(System.out);
- fail("Should not have hit an IOException with no locking");
- }
-
- writer.close();
- if (writer2 != null) {
- writer2.close();
- }
- }
-
- // Verify: SingleInstanceLockFactory is the default lock for RAMDirectory
- // Verify: RAMDirectory does basic locking correctly (can't create two IndexWriters)
- public void testDefaultRAMDirectory() throws IOException {
- Directory dir = new RAMDirectory();
-
- assertTrue("RAMDirectory did not use correct LockFactory: got " + dir.getLockFactory(),
- SingleInstanceLockFactory.class.isInstance(dir.getLockFactory()));
-
- IndexWriter writer = new IndexWriter(dir, new IndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random)));
-
- // Create a 2nd IndexWriter. This should fail:
- IndexWriter writer2 = null;
- try {
- writer2 = new IndexWriter(dir, new IndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random)).setOpenMode(OpenMode.APPEND));
- fail("Should have hit an IOException with two IndexWriters on default SingleInstanceLockFactory");
- } catch (IOException e) {
- }
-
- writer.close();
- if (writer2 != null) {
- writer2.close();
- }
- }
-
- public void testSimpleFSLockFactory() throws IOException {
- // test string file instantiation
- new SimpleFSLockFactory("test");
- }
-
- // Verify: do stress test, by opening IndexReaders and
- // IndexWriters over & over in 2 threads and making sure
- // no unexpected exceptions are raised:
- public void testStressLocks() throws Exception {
- _testStressLocks(null, _TestUtil.getTempDir("index.TestLockFactory6"));
- }
-
- // Verify: do stress test, by opening IndexReaders and
- // IndexWriters over & over in 2 threads and making sure
- // no unexpected exceptions are raised, but use
- // NativeFSLockFactory:
- public void testStressLocksNativeFSLockFactory() throws Exception {
- File dir = _TestUtil.getTempDir("index.TestLockFactory7");
- _testStressLocks(new NativeFSLockFactory(dir), dir);
- }
-
- public void _testStressLocks(LockFactory lockFactory, File indexDir) throws Exception {
- Directory dir = newFSDirectory(indexDir, lockFactory);
-
- // First create a 1 doc index:
- IndexWriter w = new IndexWriter(dir, new IndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random)).setOpenMode(OpenMode.CREATE));
- addDoc(w);
- w.close();
-
- WriterThread writer = new WriterThread(100, dir);
- SearcherThread searcher = new SearcherThread(100, dir);
- writer.start();
- searcher.start();
-
- while(writer.isAlive() || searcher.isAlive()) {
- Thread.sleep(1000);
- }
-
- assertTrue("IndexWriter hit unexpected exceptions", !writer.hitException);
- assertTrue("IndexSearcher hit unexpected exceptions", !searcher.hitException);
-
- dir.close();
- // Cleanup
- _TestUtil.rmDir(indexDir);
- }
-
- // Verify: NativeFSLockFactory works correctly
- public void testNativeFSLockFactory() throws IOException {
-
- NativeFSLockFactory f = new NativeFSLockFactory(TEMP_DIR);
-
- f.setLockPrefix("test");
- Lock l = f.makeLock("commit");
- Lock l2 = f.makeLock("commit");
-
- assertTrue("failed to obtain lock", l.obtain());
- assertTrue("succeeded in obtaining lock twice", !l2.obtain());
- l.release();
-
- assertTrue("failed to obtain 2nd lock after first one was freed", l2.obtain());
- l2.release();
-
- // Make sure we can obtain first one again, test isLocked():
- assertTrue("failed to obtain lock", l.obtain());
- assertTrue(l.isLocked());
- assertTrue(l2.isLocked());
- l.release();
- assertFalse(l.isLocked());
- assertFalse(l2.isLocked());
- }
-
-
- // Verify: NativeFSLockFactory works correctly if the lock file exists
- public void testNativeFSLockFactoryLockExists() throws IOException {
-
- File lockFile = new File(TEMP_DIR, "test.lock");
- lockFile.createNewFile();
-
- Lock l = new NativeFSLockFactory(TEMP_DIR).makeLock("test.lock");
- assertTrue("failed to obtain lock", l.obtain());
- l.release();
- assertFalse("failed to release lock", l.isLocked());
- if (lockFile.exists()) {
- lockFile.delete();
- }
- }
-
- public void testNativeFSLockReleaseByOtherLock() throws IOException {
-
- NativeFSLockFactory f = new NativeFSLockFactory(TEMP_DIR);
-
- f.setLockPrefix("test");
- Lock l = f.makeLock("commit");
- Lock l2 = f.makeLock("commit");
-
- assertTrue("failed to obtain lock", l.obtain());
- try {
- assertTrue(l2.isLocked());
- l2.release();
- fail("should not have reached here. LockReleaseFailedException should have been thrown");
- } catch (LockReleaseFailedException e) {
- // expected
- } finally {
- l.release();
- }
- }
-
- // Verify: NativeFSLockFactory assigns null as lockPrefix if the lockDir is inside directory
- public void testNativeFSLockFactoryPrefix() throws IOException {
- File fdir1 = _TestUtil.getTempDir("TestLockFactory.8");
- File fdir2 = _TestUtil.getTempDir("TestLockFactory.8.Lockdir");
- Directory dir1 = newFSDirectory(fdir1, new NativeFSLockFactory(fdir1));
- // same directory, but locks are stored somewhere else. The prefix of the lock factory should != null
- Directory dir2 = newFSDirectory(fdir1, new NativeFSLockFactory(fdir2));
-
- String prefix1 = dir1.getLockFactory().getLockPrefix();
- assertNull("Lock prefix for lockDir same as directory should be null", prefix1);
-
- String prefix2 = dir2.getLockFactory().getLockPrefix();
- assertNotNull("Lock prefix for lockDir outside of directory should be not null", prefix2);
-
- dir1.close();
- dir2.close();
-
- _TestUtil.rmDir(fdir1);
- _TestUtil.rmDir(fdir2);
- }
-
- // Verify: default LockFactory has no prefix (ie
- // write.lock is stored in index):
- public void testDefaultFSLockFactoryPrefix() throws IOException {
- // Make sure we get null prefix, which wont happen if setLockFactory is ever called.
- File dirName = _TestUtil.getTempDir("TestLockFactory.10");
-
- Directory dir = new SimpleFSDirectory(dirName);
- assertNull("Default lock prefix should be null", dir.getLockFactory().getLockPrefix());
- dir.close();
-
- dir = new MMapDirectory(dirName);
- assertNull("Default lock prefix should be null", dir.getLockFactory().getLockPrefix());
- dir.close();
-
- dir = new NIOFSDirectory(dirName);
- assertNull("Default lock prefix should be null", dir.getLockFactory().getLockPrefix());
- dir.close();
-
- _TestUtil.rmDir(dirName);
- }
-
- private class WriterThread extends Thread {
- private Directory dir;
- private int numIteration;
- public boolean hitException = false;
- public WriterThread(int numIteration, Directory dir) {
- this.numIteration = numIteration;
- this.dir = dir;
- }
- @Override
- public void run() {
- IndexWriter writer = null;
- for(int i=0;i<this.numIteration;i++) {
- try {
- writer = new IndexWriter(dir, new IndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random)).setOpenMode(OpenMode.APPEND));
- } catch (IOException e) {
- if (e.toString().indexOf(" timed out:") == -1) {
- hitException = true;
- System.out.println("Stress Test Index Writer: creation hit unexpected IOException: " + e.toString());
- e.printStackTrace(System.out);
- } else {
- // lock obtain timed out
- // NOTE: we should at some point
- // consider this a failure? The lock
- // obtains, across IndexReader &
- // IndexWriters should be "fair" (ie
- // FIFO).
- }
- } catch (Exception e) {
- hitException = true;
- System.out.println("Stress Test Index Writer: creation hit unexpected exception: " + e.toString());
- e.printStackTrace(System.out);
- break;
- }
- if (writer != null) {
- try {
- addDoc(writer);
- } catch (IOException e) {
- hitException = true;
- System.out.println("Stress Test Index Writer: addDoc hit unexpected exception: " + e.toString());
- e.printStackTrace(System.out);
- break;
- }
- try {
- writer.close();
- } catch (IOException e) {
- hitException = true;
- System.out.println("Stress Test Index Writer: close hit unexpected exception: " + e.toString());
- e.printStackTrace(System.out);
- break;
- }
- writer = null;
- }
- }
- }
- }
-
- private class SearcherThread extends Thread {
- private Directory dir;
- private int numIteration;
- public boolean hitException = false;
- public SearcherThread(int numIteration, Directory dir) {
- this.numIteration = numIteration;
- this.dir = dir;
- }
- @Override
- public void run() {
- IndexSearcher searcher = null;
- Query query = new TermQuery(new Term("content", "aaa"));
- for(int i=0;i<this.numIteration;i++) {
- try{
- searcher = new IndexSearcher(dir, false);
- } catch (Exception e) {
- hitException = true;
- System.out.println("Stress Test Index Searcher: create hit unexpected exception: " + e.toString());
- e.printStackTrace(System.out);
- break;
- }
- try {
- searcher.search(query, null, 1000);
- } catch (IOException e) {
- hitException = true;
- System.out.println("Stress Test Index Searcher: search hit unexpected exception: " + e.toString());
- e.printStackTrace(System.out);
- break;
- }
- // System.out.println(hits.length() + " total results");
- try {
- searcher.close();
- } catch (IOException e) {
- hitException = true;
- System.out.println("Stress Test Index Searcher: close hit unexpected exception: " + e.toString());
- e.printStackTrace(System.out);
- break;
- }
- }
- }
- }
-
- public class MockLockFactory extends LockFactory {
-
- public boolean lockPrefixSet;
- public Map<String,Lock> locksCreated = Collections.synchronizedMap(new HashMap<String,Lock>());
- public int makeLockCount = 0;
-
- @Override
- public void setLockPrefix(String lockPrefix) {
- super.setLockPrefix(lockPrefix);
- lockPrefixSet = true;
- }
-
- @Override
- synchronized public Lock makeLock(String lockName) {
- Lock lock = new MockLock();
- locksCreated.put(lockName, lock);
- makeLockCount++;
- return lock;
- }
-
- @Override
- public void clearLock(String specificLockName) {}
-
- public class MockLock extends Lock {
- public int lockAttempts;
-
- @Override
- public boolean obtain() {
- lockAttempts++;
- return true;
- }
- @Override
- public void release() {
- // do nothing
- }
- @Override
- public boolean isLocked() {
- return false;
- }
- }
- }
-
- private void addDoc(IndexWriter writer) throws IOException {
- Document doc = new Document();
- doc.add(newField("content", "aaa", Field.Store.NO, Field.Index.ANALYZED));
- writer.addDocument(doc);
- }
-}