You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by us...@apache.org on 2014/04/21 16:50:55 UTC
svn commit: r1588891 - in /lucene/dev/branches/lucene_solr_4_8: ./ lucene/
lucene/core/ lucene/core/src/java/org/apache/lucene/store/
lucene/core/src/test/org/apache/lucene/index/ lucene/test-framework/
lucene/test-framework/src/java/org/apache/lucene/...
Author: uschindler
Date: Mon Apr 21 14:50:55 2014
New Revision: 1588891
URL: http://svn.apache.org/r1588891
Log:
Merged revision(s) 1588871, 1588890 from lucene/dev/branches/branch_4x:
LUCENE-5612: fix NativeFSLockFactory to pass LockStressTest
Modified:
lucene/dev/branches/lucene_solr_4_8/ (props changed)
lucene/dev/branches/lucene_solr_4_8/lucene/ (props changed)
lucene/dev/branches/lucene_solr_4_8/lucene/CHANGES.txt (contents, props changed)
lucene/dev/branches/lucene_solr_4_8/lucene/core/ (props changed)
lucene/dev/branches/lucene_solr_4_8/lucene/core/build.xml
lucene/dev/branches/lucene_solr_4_8/lucene/core/src/java/org/apache/lucene/store/Lock.java
lucene/dev/branches/lucene_solr_4_8/lucene/core/src/java/org/apache/lucene/store/LockFactory.java
lucene/dev/branches/lucene_solr_4_8/lucene/core/src/java/org/apache/lucene/store/LockStressTest.java
lucene/dev/branches/lucene_solr_4_8/lucene/core/src/java/org/apache/lucene/store/LockVerifyServer.java
lucene/dev/branches/lucene_solr_4_8/lucene/core/src/java/org/apache/lucene/store/NativeFSLockFactory.java
lucene/dev/branches/lucene_solr_4_8/lucene/core/src/java/org/apache/lucene/store/SimpleFSLockFactory.java
lucene/dev/branches/lucene_solr_4_8/lucene/core/src/java/org/apache/lucene/store/VerifyingLockFactory.java
lucene/dev/branches/lucene_solr_4_8/lucene/core/src/test/org/apache/lucene/index/TestAllFilesHaveChecksumFooter.java
lucene/dev/branches/lucene_solr_4_8/lucene/core/src/test/org/apache/lucene/index/TestAllFilesHaveCodecHeader.java
lucene/dev/branches/lucene_solr_4_8/lucene/core/src/test/org/apache/lucene/index/TestBackwardsCompatibility.java (contents, props changed)
lucene/dev/branches/lucene_solr_4_8/lucene/core/src/test/org/apache/lucene/index/TestBackwardsCompatibility3x.java
lucene/dev/branches/lucene_solr_4_8/lucene/core/src/test/org/apache/lucene/index/TestIndexWriter.java
lucene/dev/branches/lucene_solr_4_8/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterExceptions.java
lucene/dev/branches/lucene_solr_4_8/lucene/test-framework/ (props changed)
lucene/dev/branches/lucene_solr_4_8/lucene/test-framework/src/java/org/apache/lucene/index/BaseIndexFileFormatTestCase.java
lucene/dev/branches/lucene_solr_4_8/solr/ (props changed)
lucene/dev/branches/lucene_solr_4_8/solr/core/ (props changed)
lucene/dev/branches/lucene_solr_4_8/solr/core/src/test/org/apache/solr/core/SolrCoreCheckLockOnStartupTest.java
Modified: lucene/dev/branches/lucene_solr_4_8/lucene/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene_solr_4_8/lucene/CHANGES.txt?rev=1588891&r1=1588890&r2=1588891&view=diff
==============================================================================
--- lucene/dev/branches/lucene_solr_4_8/lucene/CHANGES.txt (original)
+++ lucene/dev/branches/lucene_solr_4_8/lucene/CHANGES.txt Mon Apr 21 14:50:55 2014
@@ -203,6 +203,11 @@ Bug fixes
* LUCENE-5615: Validate per-segment delete counts at write time, to
help catch bugs that might otherwise cause corruption (Mike McCandless)
+* LUCENE-5612: NativeFSLockFactory no longer deletes its lock file. This cannot be done
+ safely without the risk of deleting someone else's lock file. If you use NativeFSLockFactory,
+ you may see write.lock hanging around from time to time: its harmless.
+ (Uwe Schindler, Mike McCandless, Robert Muir)
+
Test Framework
* LUCENE-5592: Incorrectly reported uncloseable files. (Dawid Weiss)
@@ -229,6 +234,12 @@ Build
* LUCENE-5614: Enable building on Java 8 using Apache Ant 1.8.3 or 1.8.4
by adding a workaround for the Ant bug. (Uwe Schindler)
+* LUCENE-5612: Add a new Ant target in lucene/core to test LockFactory
+ implementations: "ant test-lock-factory". By default it is ran
+ after the core testsuite on NativeFSLockFactory. To test another one,
+ pass -Dlock.factory.impl to Ant. (Uwe Schindler, Mike McCandless,
+ Robert Muir)
+
Documentation
* LUCENE-5534: Add javadocs to GreekStemmer methods.
Modified: lucene/dev/branches/lucene_solr_4_8/lucene/core/build.xml
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene_solr_4_8/lucene/core/build.xml?rev=1588891&r1=1588890&r2=1588891&view=diff
==============================================================================
--- lucene/dev/branches/lucene_solr_4_8/lucene/core/build.xml (original)
+++ lucene/dev/branches/lucene_solr_4_8/lucene/core/build.xml Mon Apr 21 14:50:55 2014
@@ -145,5 +145,81 @@
</target>
<target name="regenerate" depends="createLevAutomata,createPackedIntSources"/>
+
+ <macrodef name="startLockStressTestClient">
+ <attribute name="clientId"/>
+ <sequential>
+ <local name="lockverifyserver.port"/>
+ <groovy><![CDATA[
+ String port;
+ while ((port = System.getProperty("lockverifyserver.port")) == null) {
+ Thread.sleep(10L);
+ }
+ properties["lockverifyserver.port"] = port;
+ ]]></groovy>
+ <java taskname="LockStressTest@{clientId}" fork="true" classpathref="test-lock.classpath" classname="org.apache.lucene.store.LockStressTest" failOnError="true">
+ <arg value="@{clientId}"/>
+ <arg value="${lockverifyserver.host}"/>
+ <arg value="${lockverifyserver.port}"/>
+ <arg value="${lock.factory.impl}"/>
+ <arg value="${lock.factory.dir}"/>
+ <arg value="${lockverify.delay}"/>
+ <arg value="${lockverify.count}"/>
+ </java>
+ </sequential>
+ </macrodef>
+
+ <!-- we ignore our ant-based lock factory test, if user applies test filtering: -->
+ <condition property="-ignore-test-lock-factory">
+ <or>
+ <isset property="tests.class" />
+ <isset property="tests.method" />
+ </or>
+ </condition>
+
+ <target name="test-lock-factory" depends="resolve-groovy,compile-core" unless="-ignore-test-lock-factory"
+ description="Run LockStressTest with multiple JVMs">
+ <property name="lockverifyserver.host" value="127.0.0.1"/>
+ <property name="lock.factory.impl" value="org.apache.lucene.store.NativeFSLockFactory"/>
+ <property name="lock.factory.dir" location="${build.dir}/lockfactorytest"/>
+ <property name="lockverify.delay" value="1"/>
+ <groovy taskname="LockVerifySetup"><![CDATA[
+ System.clearProperty("lockverifyserver.port"); // make sure it is undefined
+
+ if (!properties["lockverify.count"]) {
+ int count = Boolean.parseBoolean(properties["tests.nightly"]) ?
+ 20000 : 2000;
+ count *= Integer.parseInt(properties["tests.multiplier"]);
+ properties["lockverify.count"] = count;
+ }
+
+ task.log("Configuration properties:");
+ ["lock.factory.impl", "lockverify.delay", "lockverify.count"].each {
+ k -> task.log(" " + k + "=" + properties[k]);
+ }
+ ]]></groovy>
+ <path id="test-lock.classpath">
+ <path refid="classpath"/>
+ <pathelement location="${build.dir}/classes/java"/>
+ </path>
+ <mkdir dir="${lock.factory.dir}"/>
+ <parallel threadCount="3" failonany="false">
+ <sequential>
+ <!-- the server runs in-process, so we can wait for the sysproperty -->
+ <java taskname="LockVerifyServer" fork="false" classpathref="test-lock.classpath" classname="org.apache.lucene.store.LockVerifyServer" failOnError="true">
+ <arg value="${lockverifyserver.host}"/>
+ <arg value="2"/>
+ </java>
+ </sequential>
+ <sequential>
+ <startLockStressTestClient clientId="1"/>
+ </sequential>
+ <sequential>
+ <startLockStressTestClient clientId="2"/>
+ </sequential>
+ </parallel>
+ </target>
+
+ <target name="test" depends="common.test, test-lock-factory"/>
</project>
Modified: lucene/dev/branches/lucene_solr_4_8/lucene/core/src/java/org/apache/lucene/store/Lock.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene_solr_4_8/lucene/core/src/java/org/apache/lucene/store/Lock.java?rev=1588891&r1=1588890&r2=1588891&view=diff
==============================================================================
--- lucene/dev/branches/lucene_solr_4_8/lucene/core/src/java/org/apache/lucene/store/Lock.java (original)
+++ lucene/dev/branches/lucene_solr_4_8/lucene/core/src/java/org/apache/lucene/store/Lock.java Mon Apr 21 14:50:55 2014
@@ -72,7 +72,7 @@ public abstract class Lock implements Cl
* out of bounds
* @throws IOException if obtain() throws IOException
*/
- public boolean obtain(long lockWaitTimeout) throws IOException {
+ public final boolean obtain(long lockWaitTimeout) throws IOException {
failureReason = null;
boolean locked = obtain();
if (lockWaitTimeout < 0 && lockWaitTimeout != LOCK_OBTAIN_WAIT_FOREVER)
Modified: lucene/dev/branches/lucene_solr_4_8/lucene/core/src/java/org/apache/lucene/store/LockFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene_solr_4_8/lucene/core/src/java/org/apache/lucene/store/LockFactory.java?rev=1588891&r1=1588890&r2=1588891&view=diff
==============================================================================
--- lucene/dev/branches/lucene_solr_4_8/lucene/core/src/java/org/apache/lucene/store/LockFactory.java (original)
+++ lucene/dev/branches/lucene_solr_4_8/lucene/core/src/java/org/apache/lucene/store/LockFactory.java Mon Apr 21 14:50:55 2014
@@ -23,10 +23,21 @@ import java.io.IOException;
* <p>Base class for Locking implementation. {@link Directory} uses
* instances of this class to implement locking.</p>
*
- * <p>Note that there are some useful tools to verify that
- * your LockFactory is working correctly: {@link
- * VerifyingLockFactory}, {@link LockStressTest}, {@link
- * LockVerifyServer}.</p>
+ * <p>Lucene uses {@link NativeFSLockFactory} by default for
+ * {@link FSDirectory}-based index directories.</p>
+ *
+ * <p>Special care needs to be taken if you change the locking
+ * implementation: First be certain that no writer is in fact
+ * writing to the index otherwise you can easily corrupt
+ * your index. Be sure to do the LockFactory change on all Lucene
+ * instances and clean up all leftover lock files before starting
+ * the new configuration for the first time. Different implementations
+ * can not work together!</p>
+ *
+ * <p>If you suspect that some LockFactory implementation is
+ * not working properly in your environment, you can easily
+ * test it by using {@link VerifyingLockFactory}, {@link
+ * LockVerifyServer} and {@link LockStressTest}.</p>
*
* @see LockVerifyServer
* @see LockStressTest
Modified: lucene/dev/branches/lucene_solr_4_8/lucene/core/src/java/org/apache/lucene/store/LockStressTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene_solr_4_8/lucene/core/src/java/org/apache/lucene/store/LockStressTest.java?rev=1588891&r1=1588890&r2=1588891&view=diff
==============================================================================
--- lucene/dev/branches/lucene_solr_4_8/lucene/core/src/java/org/apache/lucene/store/LockStressTest.java (original)
+++ lucene/dev/branches/lucene_solr_4_8/lucene/core/src/java/org/apache/lucene/store/LockStressTest.java Mon Apr 21 14:50:55 2014
@@ -19,6 +19,11 @@ package org.apache.lucene.store;
import java.io.IOException;
import java.io.File;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.util.Random;
/**
* Simple standalone tool that forever acquires & releases a
@@ -33,49 +38,45 @@ public class LockStressTest {
public static void main(String[] args) throws Exception {
- if (args.length != 6) {
- System.out.println("\nUsage: java org.apache.lucene.store.LockStressTest myID verifierHostOrIP verifierPort lockFactoryClassName lockDirName sleepTime\n" +
+ if (args.length != 7) {
+ System.out.println("Usage: java org.apache.lucene.store.LockStressTest myID verifierHost verifierPort lockFactoryClassName lockDirName sleepTimeMS count\n" +
"\n" +
" myID = int from 0 .. 255 (should be unique for test process)\n" +
- " verifierHostOrIP = host name or IP address where LockVerifyServer is running\n" +
+ " verifierHost = hostname that LockVerifyServer is listening on\n" +
" verifierPort = port that LockVerifyServer is listening on\n" +
" lockFactoryClassName = primary LockFactory class that we will use\n" +
" lockDirName = path to the lock directory (only set for Simple/NativeFSLockFactory\n" +
" sleepTimeMS = milliseconds to pause betweeen each lock obtain/release\n" +
+ " count = number of locking tries\n" +
"\n" +
"You should run multiple instances of this process, each with its own\n" +
"unique ID, and each pointing to the same lock directory, to verify\n" +
"that locking is working correctly.\n" +
"\n" +
- "Make sure you are first running LockVerifyServer.\n" +
- "\n");
+ "Make sure you are first running LockVerifyServer.");
System.exit(1);
}
- final int myID = Integer.parseInt(args[0]);
+ int arg = 0;
+ final int myID = Integer.parseInt(args[arg++]);
if (myID < 0 || myID > 255) {
System.out.println("myID must be a unique int 0..255");
System.exit(1);
}
- final String verifierHost = args[1];
- final int verifierPort = Integer.parseInt(args[2]);
- final String lockFactoryClassName = args[3];
- final String lockDirName = args[4];
- final int sleepTimeMS = Integer.parseInt(args[5]);
+ final String verifierHost = args[arg++];
+ final int verifierPort = Integer.parseInt(args[arg++]);
+ final String lockFactoryClassName = args[arg++];
+ final String lockDirName = args[arg++];
+ final int sleepTimeMS = Integer.parseInt(args[arg++]);
+ final int count = Integer.parseInt(args[arg++]);
LockFactory lockFactory;
try {
lockFactory = Class.forName(lockFactoryClassName).asSubclass(LockFactory.class).newInstance();
- } catch (IllegalAccessException e) {
- throw new IOException("IllegalAccessException when instantiating LockClass " + lockFactoryClassName);
- } catch (InstantiationException e) {
- throw new IOException("InstantiationException when instantiating LockClass " + lockFactoryClassName);
- } catch (ClassCastException e) {
- throw new IOException("unable to cast LockClass " + lockFactoryClassName + " instance to a LockFactory");
- } catch (ClassNotFoundException e) {
- throw new IOException("unable to find LockClass " + lockFactoryClassName);
+ } catch (IllegalAccessException | InstantiationException | ClassCastException | ClassNotFoundException e) {
+ throw new IOException("Cannot instantiate lock factory " + lockFactoryClassName);
}
File lockDir = new File(lockDirName);
@@ -84,27 +85,49 @@ public class LockStressTest {
((FSLockFactory) lockFactory).setLockDir(lockDir);
}
- lockFactory.setLockPrefix("test");
-
- LockFactory verifyLF = new VerifyingLockFactory((byte) myID, lockFactory, verifierHost, verifierPort);
-
- Lock l = verifyLF.makeLock("test.lock");
-
- while(true) {
-
- boolean obtained = false;
-
- try {
- obtained = l.obtain(10);
- } catch (LockObtainFailedException e) {
- System.out.print("x");
- }
-
- if (obtained) {
- System.out.print("l");
- l.close();
+ final InetSocketAddress addr = new InetSocketAddress(verifierHost, verifierPort);
+ System.out.println("Connecting to server " + addr +
+ " and registering as client " + myID + "...");
+ try (Socket socket = new Socket()) {
+ socket.setReuseAddress(true);
+ socket.connect(addr, 500);
+ final OutputStream out = socket.getOutputStream();
+ final InputStream in = socket.getInputStream();
+
+ out.write(myID);
+ out.flush();
+
+ lockFactory.setLockPrefix("test");
+ final LockFactory verifyLF = new VerifyingLockFactory(lockFactory, in, out);
+ final Lock l = verifyLF.makeLock("test.lock");
+ final Random rnd = new Random();
+
+ // wait for starting gun
+ if (in.read() != 43) {
+ throw new IOException("Protocol violation");
}
- Thread.sleep(sleepTimeMS);
+
+ for (int i = 0; i < count; i++) {
+ boolean obtained = false;
+
+ try {
+ obtained = l.obtain(rnd.nextInt(100) + 10);
+ } catch (LockObtainFailedException e) {
+ }
+
+ if (obtained) {
+ Thread.sleep(sleepTimeMS);
+ l.close();
+ }
+
+ if (i % 500 == 0) {
+ System.out.println((i * 100. / count) + "% done.");
+ }
+
+ Thread.sleep(sleepTimeMS);
+ }
}
+
+ System.out.println("Finished " + count + " tries.");
}
}
Modified: lucene/dev/branches/lucene_solr_4_8/lucene/core/src/java/org/apache/lucene/store/LockVerifyServer.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene_solr_4_8/lucene/core/src/java/org/apache/lucene/store/LockVerifyServer.java?rev=1588891&r1=1588890&r2=1588891&view=diff
==============================================================================
--- lucene/dev/branches/lucene_solr_4_8/lucene/core/src/java/org/apache/lucene/store/LockVerifyServer.java (original)
+++ lucene/dev/branches/lucene_solr_4_8/lucene/core/src/java/org/apache/lucene/store/LockVerifyServer.java Mon Apr 21 14:50:55 2014
@@ -17,11 +17,15 @@ package org.apache.lucene.store;
* limitations under the License.
*/
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
-import java.io.OutputStream;
-import java.io.InputStream;
-import java.io.IOException;
+import java.util.concurrent.CountDownLatch;
+
+import org.apache.lucene.util.IOUtils;
/**
* Simple standalone server that must be running when you
@@ -35,62 +39,108 @@ import java.io.IOException;
public class LockVerifyServer {
- private static String getTime(long startTime) {
- return "[" + ((System.currentTimeMillis()-startTime)/1000) + "s] ";
- }
-
- public static void main(String[] args) throws IOException {
+ public static void main(String[] args) throws Exception {
- if (args.length != 1) {
- System.out.println("\nUsage: java org.apache.lucene.store.LockVerifyServer port\n");
+ if (args.length != 2) {
+ System.out.println("Usage: java org.apache.lucene.store.LockVerifyServer bindToIp clients\n");
System.exit(1);
}
- final int port = Integer.parseInt(args[0]);
+ int arg = 0;
+ final String hostname = args[arg++];
+ final int maxClients = Integer.parseInt(args[arg++]);
+
+ try (final ServerSocket s = new ServerSocket()) {
+ s.setReuseAddress(true);
+ s.setSoTimeout(30000); // initially 30 secs to give clients enough time to startup
+ s.bind(new InetSocketAddress(hostname, 0));
+ final InetSocketAddress localAddr = (InetSocketAddress) s.getLocalSocketAddress();
+ System.out.println("Listening on " + localAddr + "...");
+
+ // we set the port as a sysprop, so the ANT task can read it. For that to work, this server must run in-process:
+ System.setProperty("lockverifyserver.port", Integer.toString(localAddr.getPort()));
+
+ final Object localLock = new Object();
+ final int[] lockedID = new int[1];
+ lockedID[0] = -1;
+ final CountDownLatch startingGun = new CountDownLatch(1);
+ final Thread[] threads = new Thread[maxClients];
+
+ for (int count = 0; count < maxClients; count++) {
+ final Socket cs = s.accept();
+ threads[count] = new Thread() {
+ @Override
+ public void run() {
+ try (InputStream in = cs.getInputStream(); OutputStream os = cs.getOutputStream()) {
+ final int id = in.read();
+ if (id < 0) {
+ throw new IOException("Client closed connection before communication started.");
+ }
+
+ startingGun.await();
+ os.write(43);
+ os.flush();
+
+ while(true) {
+ final int command = in.read();
+ if (command < 0) {
+ return; // closed
+ }
+
+ synchronized(localLock) {
+ final int currentLock = lockedID[0];
+ if (currentLock == -2) {
+ return; // another thread got error, so we exit, too!
+ }
+ switch (command) {
+ case 1:
+ // Locked
+ if (currentLock != -1) {
+ lockedID[0] = -2;
+ throw new IllegalStateException("id " + id + " got lock, but " + currentLock + " already holds the lock");
+ }
+ lockedID[0] = id;
+ break;
+ case 0:
+ // Unlocked
+ if (currentLock != id) {
+ lockedID[0] = -2;
+ throw new IllegalStateException("id " + id + " released the lock, but " + currentLock + " is the one holding the lock");
+ }
+ lockedID[0] = -1;
+ break;
+ default:
+ throw new RuntimeException("Unrecognized command: " + command);
+ }
+ os.write(command);
+ os.flush();
+ }
+ }
+ } catch (RuntimeException | Error e) {
+ throw e;
+ } catch (Exception ioe) {
+ throw new RuntimeException(ioe);
+ } finally {
+ IOUtils.closeWhileHandlingException(cs);
+ }
+ }
+ };
+ threads[count].start();
+ }
+
+ // start
+ System.out.println("All clients started, fire gun...");
+ startingGun.countDown();
+
+ // wait for all threads to finish
+ for (Thread t : threads) {
+ t.join();
+ }
+
+ // cleanup sysprop
+ System.clearProperty("lockverifyserver.port");
- ServerSocket s = new ServerSocket(port);
- s.setReuseAddress(true);
- System.out.println("\nReady on port " + port + "...");
-
- int lockedID = 0;
- long startTime = System.currentTimeMillis();
-
- while(true) {
- Socket cs = s.accept();
- OutputStream out = cs.getOutputStream();
- InputStream in = cs.getInputStream();
-
- int id = in.read();
- int command = in.read();
-
- boolean err = false;
-
- if (command == 1) {
- // Locked
- if (lockedID != 0) {
- err = true;
- System.out.println(getTime(startTime) + " ERROR: id " + id + " got lock, but " + lockedID + " already holds the lock");
- }
- lockedID = id;
- } else if (command == 0) {
- if (lockedID != id) {
- err = true;
- System.out.println(getTime(startTime) + " ERROR: id " + id + " released the lock, but " + lockedID + " is the one holding the lock");
- }
- lockedID = 0;
- } else
- throw new RuntimeException("unrecognized command " + command);
-
- System.out.print(".");
-
- if (err)
- out.write(1);
- else
- out.write(0);
-
- out.close();
- in.close();
- cs.close();
+ System.out.println("Server terminated.");
}
}
}
Modified: lucene/dev/branches/lucene_solr_4_8/lucene/core/src/java/org/apache/lucene/store/NativeFSLockFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene_solr_4_8/lucene/core/src/java/org/apache/lucene/store/NativeFSLockFactory.java?rev=1588891&r1=1588890&r2=1588891&view=diff
==============================================================================
--- lucene/dev/branches/lucene_solr_4_8/lucene/core/src/java/org/apache/lucene/store/NativeFSLockFactory.java (original)
+++ lucene/dev/branches/lucene_solr_4_8/lucene/core/src/java/org/apache/lucene/store/NativeFSLockFactory.java Mon Apr 21 14:50:55 2014
@@ -19,10 +19,12 @@ package org.apache.lucene.store;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
+import java.nio.channels.OverlappingFileLockException;
+import java.nio.file.StandardOpenOption;
import java.io.File;
-import java.io.RandomAccessFile;
import java.io.IOException;
-import java.util.HashSet;
+
+import org.apache.lucene.util.IOUtils;
/**
* <p>Implements {@link LockFactory} using native OS file
@@ -38,13 +40,22 @@ import java.util.HashSet;
* could be left when the JVM exits abnormally.</p>
*
* <p>The primary benefit of {@link NativeFSLockFactory} is
- * that lock files will be properly removed (by the OS) if
- * the JVM has an abnormal exit.</p>
+ * that locks (not the lock file itsself) will be properly
+ * removed (by the OS) if the JVM has an abnormal exit.</p>
*
* <p>Note that, unlike {@link SimpleFSLockFactory}, the existence of
- * leftover lock files in the filesystem on exiting the JVM
- * is fine because the OS will free the locks held against
- * these files even though the files still remain.</p>
+ * leftover lock files in the filesystem is fine because the OS
+ * will free the locks held against these files even though the
+ * files still remain. Lucene will never actively remove the lock
+ * files, so although you see them, the index may not be locked.</p>
+ *
+ * <p>Special care needs to be taken if you change the locking
+ * implementation: First be certain that no writer is in fact
+ * writing to the index otherwise you can easily corrupt
+ * your index. Be sure to do the LockFactory change on all Lucene
+ * instances and clean up all leftover lock files before starting
+ * the new configuration for the first time. Different implementations
+ * can not work together!</p>
*
* <p>If you suspect that this or any other LockFactory is
* not working properly in your environment, you can easily
@@ -96,58 +107,17 @@ public class NativeFSLockFactory extends
@Override
public void clearLock(String lockName) throws IOException {
- // Note that this isn't strictly required anymore
- // because the existence of these files does not mean
- // they are locked, but, still do this in case people
- // really want to see the files go away:
- if (lockDir.exists()) {
-
- // Try to release the lock first - if it's held by another process, this
- // method should not silently fail.
- // NOTE: makeLock fixes the lock name by prefixing it w/ lockPrefix.
- // Therefore it should be called before the code block next which prefixes
- // the given name.
- makeLock(lockName).close();
-
- if (lockPrefix != null) {
- lockName = lockPrefix + "-" + lockName;
- }
-
- // As mentioned above, we don't care if the deletion of the file failed.
- new File(lockDir, lockName).delete();
- }
+ makeLock(lockName).close();
}
}
class NativeFSLock extends Lock {
- private RandomAccessFile f;
private FileChannel channel;
private FileLock lock;
private File path;
private File lockDir;
- /*
- * The javadocs for FileChannel state that you should have
- * a single instance of a FileChannel (per JVM) for all
- * locking against a given file (locks are tracked per
- * FileChannel instance in Java 1.4/1.5). Even using the same
- * FileChannel instance is not completely thread-safe with Java
- * 1.4/1.5 though. To work around this, we have a single (static)
- * HashSet that contains the file paths of all currently
- * locked locks. This protects against possible cases
- * where different Directory instances in one JVM (each
- * with their own NativeFSLockFactory instance) have set
- * the same lock dir and lock prefix. However, this will not
- * work when LockFactorys are created by different
- * classloaders (eg multiple webapps).
- *
- * TODO: Java 1.6 tracks system wide locks in a thread safe manner
- * (same FileChannel instance or not), so we may want to
- * change this when Lucene moves to Java 1.6.
- */
- private static HashSet<String> LOCK_HELD = new HashSet<>();
-
public NativeFSLock(File lockDir, String lockFileName) {
this.lockDir = lockDir;
path = new File(lockDir, lockFileName);
@@ -169,89 +139,35 @@ class NativeFSLock extends Lock {
if (!lockDir.exists()) {
if (!lockDir.mkdirs())
throw new IOException("Cannot create directory: " +
- lockDir.getAbsolutePath());
+ lockDir.getAbsolutePath());
} else if (!lockDir.isDirectory()) {
// TODO: NoSuchDirectoryException instead?
throw new IOException("Found regular file where directory expected: " +
- lockDir.getAbsolutePath());
+ lockDir.getAbsolutePath());
}
-
- String canonicalPath = path.getCanonicalPath();
-
- boolean markedHeld = false;
-
+
+ channel = FileChannel.open(path.toPath(), StandardOpenOption.CREATE, StandardOpenOption.WRITE);
+ boolean success = false;
try {
-
- // Make sure nobody else in-process has this lock held
- // already, and, mark it held if not:
-
- synchronized(LOCK_HELD) {
- if (LOCK_HELD.contains(canonicalPath)) {
- // Someone else in this JVM already has the lock:
- return false;
- } else {
- // This "reserves" the fact that we are the one
- // thread trying to obtain this lock, so we own
- // the only instance of a channel against this
- // file:
- LOCK_HELD.add(canonicalPath);
- markedHeld = true;
- }
- }
-
- try {
- f = new RandomAccessFile(path, "rw");
- } catch (IOException e) {
- // On Windows, we can get intermittent "Access
- // Denied" here. So, we treat this as failure to
- // acquire the lock, but, store the reason in case
- // there is in fact a real error case.
- failureReason = e;
- f = null;
- }
-
- if (f != null) {
+ lock = channel.tryLock();
+ success = true;
+ } catch (IOException | OverlappingFileLockException e) {
+ // At least on OS X, we will sometimes get an
+ // intermittent "Permission Denied" IOException,
+ // which seems to simply mean "you failed to get
+ // the lock". But other IOExceptions could be
+ // "permanent" (eg, locking is not supported via
+ // the filesystem). So, we record the failure
+ // reason here; the timeout obtain (usually the
+ // one calling us) will use this as "root cause"
+ // if it fails to get the lock.
+ failureReason = e;
+ } finally {
+ if (!success) {
try {
- channel = f.getChannel();
- try {
- lock = channel.tryLock();
- } catch (IOException e) {
- // At least on OS X, we will sometimes get an
- // intermittent "Permission Denied" IOException,
- // which seems to simply mean "you failed to get
- // the lock". But other IOExceptions could be
- // "permanent" (eg, locking is not supported via
- // the filesystem). So, we record the failure
- // reason here; the timeout obtain (usually the
- // one calling us) will use this as "root cause"
- // if it fails to get the lock.
- failureReason = e;
- } finally {
- if (lock == null) {
- try {
- channel.close();
- } finally {
- channel = null;
- }
- }
- }
+ IOUtils.closeWhileHandlingException(channel);
} finally {
- if (channel == null) {
- try {
- f.close();
- } finally {
- f = null;
- }
- }
- }
- }
-
- } finally {
- if (markedHeld && !lockExists()) {
- synchronized(LOCK_HELD) {
- if (LOCK_HELD.contains(canonicalPath)) {
- LOCK_HELD.remove(canonicalPath);
- }
+ channel = null;
}
}
}
@@ -269,20 +185,8 @@ class NativeFSLock extends Lock {
channel.close();
} finally {
channel = null;
- try {
- f.close();
- } finally {
- f = null;
- synchronized(LOCK_HELD) {
- LOCK_HELD.remove(path.getCanonicalPath());
- }
- }
}
}
- // LUCENE-2421: we don't care anymore if the file cannot be deleted
- // because it's held up by another process (e.g. AntiVirus). NativeFSLock
- // does not depend on the existence/absence of the lock file
- path.delete();
} else {
// if we don't hold the lock, and somebody still called release(), for
// example as a result of calling IndexWriter.unlock(), we should attempt
Modified: lucene/dev/branches/lucene_solr_4_8/lucene/core/src/java/org/apache/lucene/store/SimpleFSLockFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene_solr_4_8/lucene/core/src/java/org/apache/lucene/store/SimpleFSLockFactory.java?rev=1588891&r1=1588890&r2=1588891&view=diff
==============================================================================
--- lucene/dev/branches/lucene_solr_4_8/lucene/core/src/java/org/apache/lucene/store/SimpleFSLockFactory.java (original)
+++ lucene/dev/branches/lucene_solr_4_8/lucene/core/src/java/org/apache/lucene/store/SimpleFSLockFactory.java Mon Apr 21 14:50:55 2014
@@ -42,6 +42,14 @@ import java.io.IOException;
* writing to the index otherwise you can easily corrupt
* your index.</p>
*
+ * <p>Special care needs to be taken if you change the locking
+ * implementation: First be certain that no writer is in fact
+ * writing to the index otherwise you can easily corrupt
+ * your index. Be sure to do the LockFactory change all Lucene
+ * instances and clean up all leftover lock files before starting
+ * the new configuration for the first time. Different implementations
+ * can not work together!</p>
+ *
* <p>If you suspect that this or any other LockFactory is
* not working properly in your environment, you can easily
* test it by using {@link VerifyingLockFactory}, {@link
Modified: lucene/dev/branches/lucene_solr_4_8/lucene/core/src/java/org/apache/lucene/store/VerifyingLockFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene_solr_4_8/lucene/core/src/java/org/apache/lucene/store/VerifyingLockFactory.java?rev=1588891&r1=1588890&r2=1588891&view=diff
==============================================================================
--- lucene/dev/branches/lucene_solr_4_8/lucene/core/src/java/org/apache/lucene/store/VerifyingLockFactory.java (original)
+++ lucene/dev/branches/lucene_solr_4_8/lucene/core/src/java/org/apache/lucene/store/VerifyingLockFactory.java Mon Apr 21 14:50:55 2014
@@ -17,7 +17,6 @@ package org.apache.lucene.store;
* limitations under the License.
*/
-import java.net.Socket;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@@ -38,50 +37,38 @@ import java.io.OutputStream;
public class VerifyingLockFactory extends LockFactory {
- LockFactory lf;
- byte id;
- String host;
- int port;
+ final LockFactory lf;
+ final InputStream in;
+ final OutputStream out;
private class CheckedLock extends Lock {
- private Lock lock;
+ private final Lock lock;
public CheckedLock(Lock lock) {
this.lock = lock;
}
- private void verify(byte message) {
- try {
- Socket s = new Socket(host, port);
- OutputStream out = s.getOutputStream();
- out.write(id);
- out.write(message);
- InputStream in = s.getInputStream();
- int result = in.read();
- in.close();
- out.close();
- s.close();
- if (result != 0)
- throw new RuntimeException("lock was double acquired");
- } catch (Exception e) {
- throw new RuntimeException(e);
+ private void verify(byte message) throws IOException {
+ out.write(message);
+ out.flush();
+ final int ret = in.read();
+ if (ret < 0) {
+ throw new IllegalStateException("Lock server died because of locking error.");
+ }
+ if (ret != message) {
+ throw new IOException("Protocol violation.");
}
}
@Override
- public synchronized boolean obtain(long lockWaitTimeout) throws IOException {
- boolean obtained = lock.obtain(lockWaitTimeout);
+ public synchronized boolean obtain() throws IOException {
+ boolean obtained = lock.obtain();
if (obtained)
verify((byte) 1);
return obtained;
}
@Override
- public synchronized boolean obtain() throws IOException {
- return lock.obtain();
- }
-
- @Override
public synchronized boolean isLocked() throws IOException {
return lock.isLocked();
}
@@ -96,18 +83,14 @@ public class VerifyingLockFactory extend
}
/**
- * @param id should be a unique id across all clients
* @param lf the LockFactory that we are testing
- * @param host host or IP where {@link LockVerifyServer}
- is running
- * @param port the port {@link LockVerifyServer} is
- listening on
+ * @param in the socket's input to {@link LockVerifyServer}
+ * @param out the socket's output to {@link LockVerifyServer}
*/
- public VerifyingLockFactory(byte id, LockFactory lf, String host, int port) {
- this.id = id;
+ public VerifyingLockFactory(LockFactory lf, InputStream in, OutputStream out) throws IOException {
this.lf = lf;
- this.host = host;
- this.port = port;
+ this.in = in;
+ this.out = out;
}
@Override
Modified: lucene/dev/branches/lucene_solr_4_8/lucene/core/src/test/org/apache/lucene/index/TestAllFilesHaveChecksumFooter.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene_solr_4_8/lucene/core/src/test/org/apache/lucene/index/TestAllFilesHaveChecksumFooter.java?rev=1588891&r1=1588890&r2=1588891&view=diff
==============================================================================
--- lucene/dev/branches/lucene_solr_4_8/lucene/core/src/test/org/apache/lucene/index/TestAllFilesHaveChecksumFooter.java (original)
+++ lucene/dev/branches/lucene_solr_4_8/lucene/core/src/test/org/apache/lucene/index/TestAllFilesHaveChecksumFooter.java Mon Apr 21 14:50:55 2014
@@ -67,6 +67,9 @@ public class TestAllFilesHaveChecksumFoo
private void checkHeaders(Directory dir) throws IOException {
for (String file : dir.listAll()) {
+ if (file.equals(IndexWriter.WRITE_LOCK_NAME)) {
+ continue; // write.lock has no footer, thats ok
+ }
if (file.endsWith(IndexFileNames.COMPOUND_FILE_EXTENSION)) {
CompoundFileDirectory cfsDir = new CompoundFileDirectory(dir, file, newIOContext(random()), false);
checkHeaders(cfsDir); // recurse into cfs
Modified: lucene/dev/branches/lucene_solr_4_8/lucene/core/src/test/org/apache/lucene/index/TestAllFilesHaveCodecHeader.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene_solr_4_8/lucene/core/src/test/org/apache/lucene/index/TestAllFilesHaveCodecHeader.java?rev=1588891&r1=1588890&r2=1588891&view=diff
==============================================================================
--- lucene/dev/branches/lucene_solr_4_8/lucene/core/src/test/org/apache/lucene/index/TestAllFilesHaveCodecHeader.java (original)
+++ lucene/dev/branches/lucene_solr_4_8/lucene/core/src/test/org/apache/lucene/index/TestAllFilesHaveCodecHeader.java Mon Apr 21 14:50:55 2014
@@ -68,6 +68,9 @@ public class TestAllFilesHaveCodecHeader
private void checkHeaders(Directory dir) throws IOException {
for (String file : dir.listAll()) {
+ if (file.equals(IndexWriter.WRITE_LOCK_NAME)) {
+ continue; // write.lock has no header, thats ok
+ }
if (file.equals(IndexFileNames.SEGMENTS_GEN)) {
continue; // segments.gen has no header, thats ok
}
Modified: lucene/dev/branches/lucene_solr_4_8/lucene/core/src/test/org/apache/lucene/index/TestBackwardsCompatibility.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene_solr_4_8/lucene/core/src/test/org/apache/lucene/index/TestBackwardsCompatibility.java?rev=1588891&r1=1588890&r2=1588891&view=diff
==============================================================================
--- lucene/dev/branches/lucene_solr_4_8/lucene/core/src/test/org/apache/lucene/index/TestBackwardsCompatibility.java (original)
+++ lucene/dev/branches/lucene_solr_4_8/lucene/core/src/test/org/apache/lucene/index/TestBackwardsCompatibility.java Mon Apr 21 14:50:55 2014
@@ -632,85 +632,6 @@ public class TestBackwardsCompatibility
return indexDir;
}
- /* Verifies that the expected file names were produced */
-
- public void testExactFileNames() throws IOException {
-
- String outputDirName = "lucene.backwardscompat0.index";
- File outputDir = createTempDir(outputDirName);
- TestUtil.rm(outputDir);
-
- try {
- Directory dir = newFSDirectory(outputDir);
-
- MergePolicy mergePolicy = newLogMergePolicy(true, 10);
-
- // This test expects all of its segments to be in CFS:
- mergePolicy.setNoCFSRatio(1.0);
- mergePolicy.setMaxCFSSegmentSizeMB(Double.POSITIVE_INFINITY);
-
- IndexWriter writer = new IndexWriter(
- dir,
- newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random())).
- setMaxBufferedDocs(-1).
- setRAMBufferSizeMB(16.0).
- setMergePolicy(mergePolicy).setUseCompoundFile(true)
- );
- for(int i=0;i<35;i++) {
- addDoc(writer, i);
- }
- assertEquals("wrong doc count", 35, writer.maxDoc());
- writer.close();
-
- // Delete one doc so we get a .del file:
- writer = new IndexWriter(
- dir,
- newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random()))
- .setMergePolicy(NoMergePolicy.NO_COMPOUND_FILES).setUseCompoundFile(true)
- );
- Term searchTerm = new Term("id", "7");
- writer.deleteDocuments(searchTerm);
- writer.close();
-
- // Now verify file names... TODO: fix this test better, we could populate from
- // separateFiles() or something.
- String[] expected = new String[] {"_0.cfs", "_0.cfe",
- "_0_1.del",
- "_0.si",
- "segments_2",
- "segments.gen"};
-
- String[] expectedSimpleText = new String[] {"_0.cfs", "_0.cfe",
- "_0_1.liv",
- "_0.si",
- "segments_2",
- "segments.gen"};
-
- String[] actual = dir.listAll();
- Arrays.sort(expected);
- Arrays.sort(expectedSimpleText);
- Arrays.sort(actual);
- if (!Arrays.equals(expected, actual) && !Arrays.equals(expectedSimpleText, actual)) {
- fail("incorrect filenames in index: expected:\n " + asString(expected)
- + "\n or " + asString(expectedSimpleText) + "\n actual:\n " + asString(actual));
- }
- dir.close();
- } finally {
- TestUtil.rm(outputDir);
- }
- }
-
- private String asString(String[] l) {
- String s = "";
- for(int i=0;i<l.length;i++) {
- if (i > 0) {
- s += "\n ";
- }
- s += l[i];
- }
- return s;
- }
-
private void addDoc(IndexWriter writer, int id) throws IOException
{
Document doc = new Document();
Modified: lucene/dev/branches/lucene_solr_4_8/lucene/core/src/test/org/apache/lucene/index/TestBackwardsCompatibility3x.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene_solr_4_8/lucene/core/src/test/org/apache/lucene/index/TestBackwardsCompatibility3x.java?rev=1588891&r1=1588890&r2=1588891&view=diff
==============================================================================
--- lucene/dev/branches/lucene_solr_4_8/lucene/core/src/test/org/apache/lucene/index/TestBackwardsCompatibility3x.java (original)
+++ lucene/dev/branches/lucene_solr_4_8/lucene/core/src/test/org/apache/lucene/index/TestBackwardsCompatibility3x.java Mon Apr 21 14:50:55 2014
@@ -592,79 +592,6 @@ public class TestBackwardsCompatibility3
return indexDir;
}
- /* Verifies that the expected file names were produced */
-
- public void testExactFileNames() throws IOException {
- String outputDirName = "lucene.backwardscompat0.index";
- File outputDir = createTempDir(outputDirName);
-
- Directory dir = newFSDirectory(outputDir);
-
- MergePolicy mergePolicy = newLogMergePolicy(true, 10);
-
- // This test expects all of its segments to be in CFS:
- mergePolicy.setNoCFSRatio(1.0);
- mergePolicy.setMaxCFSSegmentSizeMB(Double.POSITIVE_INFINITY);
-
- IndexWriter writer = new IndexWriter(
- dir,
- newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random())).
- setMaxBufferedDocs(-1).
- setRAMBufferSizeMB(16.0).
- setMergePolicy(mergePolicy).setUseCompoundFile(true)
- );
- for(int i=0;i<35;i++) {
- addDoc(writer, i);
- }
- assertEquals("wrong doc count", 35, writer.maxDoc());
- writer.close();
-
- // Delete one doc so we get a .del file:
- writer = new IndexWriter(
- dir,
- newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random()))
- .setMergePolicy(NoMergePolicy.NO_COMPOUND_FILES)
- );
- Term searchTerm = new Term("id", "7");
- writer.deleteDocuments(searchTerm);
- writer.close();
-
- // Now verify file names... TODO: fix this test better, we could populate from
- // separateFiles() or something.
- String[] expected = new String[] {"_0.cfs", "_0.cfe",
- "_0_1.del",
- "_0.si",
- "segments_2",
- "segments.gen"};
-
- String[] expectedSimpleText = new String[] {"_0.cfs", "_0.cfe",
- "_0_1.liv",
- "_0.si",
- "segments_2",
- "segments.gen"};
-
- String[] actual = dir.listAll();
- Arrays.sort(expected);
- Arrays.sort(expectedSimpleText);
- Arrays.sort(actual);
- if (!Arrays.equals(expected, actual) && !Arrays.equals(expectedSimpleText, actual)) {
- fail("incorrect filenames in index: expected:\n " + asString(expected)
- + "\n or " + asString(expectedSimpleText) + "\n actual:\n " + asString(actual));
- }
- dir.close();
- }
-
- private String asString(String[] l) {
- String s = "";
- for(int i=0;i<l.length;i++) {
- if (i > 0) {
- s += "\n ";
- }
- s += l[i];
- }
- return s;
- }
-
private void addDoc(IndexWriter writer, int id) throws IOException
{
Document doc = new Document();
Modified: lucene/dev/branches/lucene_solr_4_8/lucene/core/src/test/org/apache/lucene/index/TestIndexWriter.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene_solr_4_8/lucene/core/src/test/org/apache/lucene/index/TestIndexWriter.java?rev=1588891&r1=1588890&r2=1588891&view=diff
==============================================================================
--- lucene/dev/branches/lucene_solr_4_8/lucene/core/src/test/org/apache/lucene/index/TestIndexWriter.java (original)
+++ lucene/dev/branches/lucene_solr_4_8/lucene/core/src/test/org/apache/lucene/index/TestIndexWriter.java Mon Apr 21 14:50:55 2014
@@ -1562,11 +1562,13 @@ public class TestIndexWriter extends Luc
// After rollback, IW should remove all files
writer.rollback();
- assertEquals("no files should exist in the directory after rollback", 0, dir.listAll().length);
+ String allFiles[] = dir.listAll();
+ assertTrue("no files should exist in the directory after rollback", allFiles.length == 0 || Arrays.equals(allFiles, new String[] { IndexWriter.WRITE_LOCK_NAME }));
// Since we rolled-back above, that close should be a no-op
writer.close();
- assertEquals("expected a no-op close after IW.rollback()", 0, dir.listAll().length);
+ allFiles = dir.listAll();
+ assertTrue("expected a no-op close after IW.rollback()", allFiles.length == 0 || Arrays.equals(allFiles, new String[] { IndexWriter.WRITE_LOCK_NAME }));
dir.close();
}
Modified: lucene/dev/branches/lucene_solr_4_8/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterExceptions.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene_solr_4_8/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterExceptions.java?rev=1588891&r1=1588890&r2=1588891&view=diff
==============================================================================
--- lucene/dev/branches/lucene_solr_4_8/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterExceptions.java (original)
+++ lucene/dev/branches/lucene_solr_4_8/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterExceptions.java Mon Apr 21 14:50:55 2014
@@ -23,6 +23,7 @@ import java.io.Reader;
import java.io.StringReader;
import java.nio.file.NoSuchFileException;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
@@ -947,7 +948,8 @@ public class TestIndexWriterExceptions e
}
assertTrue(failure.failOnCommit && failure.failOnDeleteFile);
w.rollback();
- assertEquals(0, dir.listAll().length);
+ String files[] = dir.listAll();
+ assertTrue(files.length == 0 || Arrays.equals(files, new String[] { IndexWriter.WRITE_LOCK_NAME }));
dir.close();
}
}
Modified: lucene/dev/branches/lucene_solr_4_8/lucene/test-framework/src/java/org/apache/lucene/index/BaseIndexFileFormatTestCase.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene_solr_4_8/lucene/test-framework/src/java/org/apache/lucene/index/BaseIndexFileFormatTestCase.java?rev=1588891&r1=1588890&r2=1588891&view=diff
==============================================================================
--- lucene/dev/branches/lucene_solr_4_8/lucene/test-framework/src/java/org/apache/lucene/index/BaseIndexFileFormatTestCase.java (original)
+++ lucene/dev/branches/lucene_solr_4_8/lucene/test-framework/src/java/org/apache/lucene/index/BaseIndexFileFormatTestCase.java Mon Apr 21 14:50:55 2014
@@ -18,9 +18,11 @@ package org.apache.lucene.index;
*/
import java.io.IOException;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Map;
import org.apache.lucene.analysis.MockAnalyzer;
@@ -71,10 +73,13 @@ abstract class BaseIndexFileFormatTestCa
* comparing indices that store the same content.
*/
protected Collection<String> excludedExtensionsFromByteCounts() {
+ return new HashSet<String>(Arrays.asList(new String[] {
// segment infos store various pieces of information that don't solely depend
// on the content of the index in the diagnostics (such as a timestamp) so we
// exclude this file from the bytes counts
- return Collections.singleton("si");
+ "si",
+ // lock files are 0 bytes (one directory in the test could be RAMDir, the other FSDir)
+ "lock" }));
}
/** The purpose of this test is to make sure that bulk merge doesn't accumulate useless data over runs. */
Modified: lucene/dev/branches/lucene_solr_4_8/solr/core/src/test/org/apache/solr/core/SolrCoreCheckLockOnStartupTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene_solr_4_8/solr/core/src/test/org/apache/solr/core/SolrCoreCheckLockOnStartupTest.java?rev=1588891&r1=1588890&r2=1588891&view=diff
==============================================================================
--- lucene/dev/branches/lucene_solr_4_8/solr/core/src/test/org/apache/solr/core/SolrCoreCheckLockOnStartupTest.java (original)
+++ lucene/dev/branches/lucene_solr_4_8/solr/core/src/test/org/apache/solr/core/SolrCoreCheckLockOnStartupTest.java Mon Apr 21 14:50:55 2014
@@ -38,15 +38,10 @@ public class SolrCoreCheckLockOnStartupT
super.setUp();
System.setProperty("solr.directoryFactory", "org.apache.solr.core.SimpleFSDirectoryFactory");
-
- IndexWriterConfig indexWriterConfig = new IndexWriterConfig(TEST_VERSION_CURRENT, null);
- Directory directory = newFSDirectory(createTempDir("index"));
- //creates a new index on the known location
- new IndexWriter(
- directory,
- indexWriterConfig.setOpenMode(IndexWriterConfig.OpenMode.CREATE)
- ).close();
- directory.close();
+ // test tests native and simple in the same jvm in the same exact directory:
+ // the file will remain after the native test (it cannot safely be deleted without the risk of deleting another guys lock)
+ // its ok, these aren't "compatible" anyway: really this test should not re-use the same directory at all.
+ new File(new File(initCoreDataDir, "index"), IndexWriter.WRITE_LOCK_NAME).delete();
}
@Test