lucene-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From uschind...@apache.org
Subject 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/...
Date Mon, 21 Apr 2014 14:50:55 GMT
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



Mime
View raw message