You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by si...@apache.org on 2012/10/25 15:10:51 UTC

svn commit: r1402140 [9/17] - in /lucene/dev/branches/LUCENE-2878: ./ dev-tools/ dev-tools/eclipse/ dev-tools/eclipse/dot.settings/ dev-tools/idea/.idea/libraries/ dev-tools/idea/lucene/classification/ dev-tools/maven/ dev-tools/maven/lucene/classifica...

Modified: lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/index/TestPostingsFormat.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/index/TestPostingsFormat.java?rev=1402140&r1=1402139&r2=1402140&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/index/TestPostingsFormat.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/index/TestPostingsFormat.java Thu Oct 25 13:10:25 2012
@@ -17,939 +17,15 @@ package org.apache.lucene.index;
  * limitations under the License.
  */
 
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.NoSuchElementException;
-import java.util.Set;
-import java.util.TreeMap;
-
 import org.apache.lucene.codecs.Codec;
-import org.apache.lucene.codecs.FieldsConsumer;
-import org.apache.lucene.codecs.FieldsProducer;
-import org.apache.lucene.codecs.PostingsConsumer;
-import org.apache.lucene.codecs.TermStats;
-import org.apache.lucene.codecs.TermsConsumer;
-import org.apache.lucene.index.FieldInfo.IndexOptions;
-import org.apache.lucene.store.Directory;
-import org.apache.lucene.store.FlushInfo;
-import org.apache.lucene.store.IOContext;
-import org.apache.lucene.util.Bits;
-import org.apache.lucene.util.BytesRef;
-import org.apache.lucene.util.Constants;
-import org.apache.lucene.util.FixedBitSet;
-import org.apache.lucene.util.LuceneTestCase;
-import org.apache.lucene.util._TestUtil;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-
-/* NOTE: This test focuses on the postings
- * (docs/freqs/positions/payloads/offsets) impl, not the
- * terms dict.  The [stretch] goal is for this test to be
- * so thorough in testing a new PostingsFormat that if this
- * test passes, then all Lucene/Solr tests should also pass.  Ie,
- * if there is some bug in a given PostingsFormat that this
- * test fails to catch then this test needs to be improved! */
-
-// TODO can we make it easy for testing to pair up a "random terms dict impl" with your postings base format...
-
-// TODO test when you reuse after skipping a term or two, eg the block reuse case
-
-// TODO hmm contract says .doc() can return NO_MORE_DOCS
-// before nextDoc too...?
-
-/* TODO
-  - threads
-  - assert doc=-1 before any nextDoc
-  - if a PF passes this test but fails other tests then this
-    test has a bug!!
-  - test tricky reuse cases, eg across fields
-  - verify you get null if you pass needFreq/needOffset but
-    they weren't indexed
-*/
-
-public class TestPostingsFormat extends LuceneTestCase {
-
-  private enum Option {
-    // Sometimes use .advance():
-    SKIPPING,
-
-    // Sometimes reuse the Docs/AndPositionsEnum across terms:
-    REUSE_ENUMS,
-
-    // Sometimes pass non-null live docs:
-    LIVE_DOCS,
-
-    // Sometimes seek to term using previously saved TermState:
-    TERM_STATE,
-
-    // Sometimes don't fully consume docs from the enum
-    PARTIAL_DOC_CONSUME,
-
-    // Sometimes don't fully consume positions at each doc
-    PARTIAL_POS_CONSUME,
-
-    // Sometimes check payloads
-    PAYLOADS,
-
-    // Test w/ multiple threads
-    THREADS};
-
-  private static class FieldAndTerm {
-    String field;
-    BytesRef term;
-
-    public FieldAndTerm(String field, BytesRef term) {
-      this.field = field;
-      this.term = BytesRef.deepCopyOf(term);
-    }
-  }
-
-  private static class Position {
-    int position;
-    byte[] payload;
-    int startOffset;
-    int endOffset;
-  }
-
-  private static class Posting implements Comparable<Posting> {
-    int docID;
-    List<Position> positions;
-
-    public int compareTo(Posting other) {
-      return docID - other.docID;
-    }
-  }
-
-  // Holds all postings:
-  private static Map<String,Map<BytesRef,List<Posting>>> fields = new TreeMap<String,Map<BytesRef,List<Posting>>>();
-
-  // Holds only live doc postings:
-  private static Map<String,Map<BytesRef,List<Posting>>> fieldsLive = new TreeMap<String,Map<BytesRef,List<Posting>>>();
-
-  private static FieldInfos fieldInfos;
-
-  private static int maxDocID;
-
-  private static FixedBitSet globalLiveDocs;
-
-  private static List<FieldAndTerm> allTerms;
-
-  private static long totalPostings;
-  private static long totalPayloadBytes;
-
-  @BeforeClass
-  public static void createPostings() throws IOException {
-
-    final int numFields = _TestUtil.nextInt(random(), 1, 5);
-    if (VERBOSE) {
-      System.out.println("TEST: " + numFields + " fields");
-    }
-
-    FieldInfo[] fieldInfoArray = new FieldInfo[numFields];
-    int fieldUpto = 0;
-    int numMediumTerms = 0;
-    int numBigTerms = 0;
-    int numManyPositions = 0;
-    totalPostings = 0;
-    totalPayloadBytes = 0;
-    while (fieldUpto < numFields) {
-      String field = _TestUtil.randomSimpleString(random());
-      if (fields.containsKey(field)) {
-        continue;
-      }
-
-      boolean fieldHasPayloads = random().nextBoolean();
-
-      fieldInfoArray[fieldUpto] = new FieldInfo(field, true, fieldUpto, false, false, fieldHasPayloads,
-                                                IndexOptions.DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS,
-                                                null, DocValues.Type.FIXED_INTS_8, null);
-      fieldUpto++;
-
-      Map<BytesRef,List<Posting>> postings = new TreeMap<BytesRef,List<Posting>>();
-      fields.put(field, postings);
-      Set<String> seenTerms = new HashSet<String>();
-
-      // TODO
-      //final int numTerms = atLeast(10);
-      final int numTerms = 4;
-      for(int termUpto=0;termUpto<numTerms;termUpto++) {
-        String term = _TestUtil.randomSimpleString(random());
-        if (seenTerms.contains(term)) {
-          continue;
-        }
-        seenTerms.add(term);
-
-        int numDocs;
-        if (random().nextInt(10) == 3 && numBigTerms < 2) {
-          // 10% of the time make a highish freq term:
-          numDocs = RANDOM_MULTIPLIER * _TestUtil.nextInt(random(), 50000, 70000);
-          numBigTerms++;
-          term = "big_" + term;
-        } else if (random().nextInt(10) == 3 && numMediumTerms < 5) {
-          // 10% of the time make a medium freq term:
-          // TODO not high enough to test level 1 skipping:
-          numDocs = RANDOM_MULTIPLIER * _TestUtil.nextInt(random(), 3000, 6000);
-          numMediumTerms++;
-          term = "medium_" + term;
-        } else if (random().nextBoolean()) {
-          // Low freq term:
-          numDocs = RANDOM_MULTIPLIER * _TestUtil.nextInt(random(), 1, 40);
-          term = "low_" + term;
-        } else {
-          // Very low freq term (don't multiply by RANDOM_MULTIPLIER):
-          numDocs = _TestUtil.nextInt(random(), 1, 3);
-          term = "verylow_" + term;
-        }
-
-        List<Posting> termPostings = new ArrayList<Posting>();
-        postings.put(new BytesRef(term), termPostings);
-
-        int docID = 0;
-
-        // TODO: more realistic to inversely tie this to numDocs:
-        int maxDocSpacing = _TestUtil.nextInt(random(), 1, 100);
-
-        // 10% of the time create big payloads:
-        int payloadSize;
-        if (!fieldHasPayloads) {
-          payloadSize = 0;
-        } else if (random().nextInt(10) == 7) {
-          payloadSize = random().nextInt(50);
-        } else {
-          payloadSize = random().nextInt(10);
-        }
-
-        boolean fixedPayloads = random().nextBoolean();
-
-        for(int docUpto=0;docUpto<numDocs;docUpto++) {
-          if (docUpto == 0 && random().nextBoolean()) {
-            // Sometimes index docID = 0
-          } else if (maxDocSpacing == 1) {
-            docID++;
-          } else {
-            // TODO: sometimes have a biggish gap here!
-            docID += _TestUtil.nextInt(random(), 1, maxDocSpacing);
-          }
-
-          Posting posting = new Posting();
-          posting.docID = docID;
-          maxDocID = Math.max(docID, maxDocID);
-          posting.positions = new ArrayList<Position>();
-          termPostings.add(posting);
-
-          int freq;
-          if (random().nextInt(30) == 17 && numManyPositions < 10) {
-            freq = _TestUtil.nextInt(random(), 1, 1000);
-            numManyPositions++;
-          } else {
-            freq = _TestUtil.nextInt(random(), 1, 20);
-          }
-          int pos = 0;
-          int offset = 0;
-          int posSpacing = _TestUtil.nextInt(random(), 1, 100);
-          totalPostings += freq;
-          for(int posUpto=0;posUpto<freq;posUpto++) {
-            if (posUpto == 0 && random().nextBoolean()) {
-              // Sometimes index pos = 0
-            } else if (posSpacing == 1) {
-              pos++;
-            } else {
-              pos += _TestUtil.nextInt(random(), 1, posSpacing);
-            }
-
-            Position position = new Position();
-            posting.positions.add(position);
-            position.position = pos;
-            if (payloadSize != 0) {
-              if (fixedPayloads) {
-                position.payload = new byte[payloadSize];
-              } else {
-                int thisPayloadSize = random().nextInt(payloadSize);
-                if (thisPayloadSize != 0) {
-                  position.payload = new byte[thisPayloadSize];
-                }
-              }
-            }
-
-            if (position.payload != null) {
-              random().nextBytes(position.payload); 
-              totalPayloadBytes += position.payload.length;
-            }
-
-            position.startOffset = offset + random().nextInt(5);
-            position.endOffset = position.startOffset + random().nextInt(10);
-            offset = position.endOffset;
-          }
-        }
-      }
-    }
-
-    fieldInfos = new FieldInfos(fieldInfoArray);
-
-    globalLiveDocs = new FixedBitSet(1+maxDocID);
-    double liveRatio = random().nextDouble();
-    for(int i=0;i<1+maxDocID;i++) {
-      if (random().nextDouble() <= liveRatio) {
-        globalLiveDocs.set(i);
-      }
-    }
-
-    // Pre-filter postings by globalLiveDocs:
-    for(Map.Entry<String,Map<BytesRef,List<Posting>>> fieldEnt : fields.entrySet()) {
-      Map<BytesRef,List<Posting>> postingsLive = new TreeMap<BytesRef,List<Posting>>();
-      fieldsLive.put(fieldEnt.getKey(), postingsLive);
-      for(Map.Entry<BytesRef,List<Posting>> termEnt : fieldEnt.getValue().entrySet()) {
-        List<Posting> termPostingsLive = new ArrayList<Posting>();
-        postingsLive.put(termEnt.getKey(), termPostingsLive);
-        for(Posting posting : termEnt.getValue()) {
-          if (globalLiveDocs.get(posting.docID)) {
-            termPostingsLive.add(posting);
-          }
-        }
-      }
-    }
-
-    allTerms = new ArrayList<FieldAndTerm>();
-    for(Map.Entry<String,Map<BytesRef,List<Posting>>> fieldEnt : fields.entrySet()) {
-      String field = fieldEnt.getKey();
-      for(Map.Entry<BytesRef,List<Posting>> termEnt : fieldEnt.getValue().entrySet()) {
-        allTerms.add(new FieldAndTerm(field, termEnt.getKey()));
-      }
-    }
-
-    if (VERBOSE) {
-      System.out.println("TEST: done init postings; maxDocID=" + maxDocID + "; " + allTerms.size() + " total terms, across " + fieldInfos.size() + " fields");
-    }
-  }
-  
-  @AfterClass
-  public static void afterClass() throws Exception {
-    allTerms = null;
-    fieldInfos = null;
-    fields = null;
-    fieldsLive = null;
-    globalLiveDocs = null;
-  }
-
-  // TODO maybe instead of @BeforeClass just make a single test run: build postings & index & test it?
-
-  private FieldInfos currentFieldInfos;
-
-  // maxAllowed = the "highest" we can index, but we will still
-  // randomly index at lower IndexOption
-  private FieldsProducer buildIndex(Directory dir, IndexOptions maxAllowed, boolean allowPayloads) throws IOException {
-    SegmentInfo segmentInfo = new SegmentInfo(dir, Constants.LUCENE_MAIN_VERSION, "_0", 1+maxDocID, false, Codec.getDefault(), null, null);
-
-    int maxIndexOption = Arrays.asList(IndexOptions.values()).indexOf(maxAllowed);
-    if (VERBOSE) {
-      System.out.println("\nTEST: now build index");
-    }
-
-    int maxIndexOptionNoOffsets = Arrays.asList(IndexOptions.values()).indexOf(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS);
-
-    // TODO use allowPayloads
-
-    FieldInfo[] newFieldInfoArray = new FieldInfo[fields.size()];
-    for(int fieldUpto=0;fieldUpto<fields.size();fieldUpto++) {
-      FieldInfo oldFieldInfo = fieldInfos.fieldInfo(fieldUpto);
-
-      String pf = _TestUtil.getPostingsFormat(oldFieldInfo.name);
-      int fieldMaxIndexOption;
-      if (doesntSupportOffsets.contains(pf)) {
-        fieldMaxIndexOption = Math.min(maxIndexOptionNoOffsets, maxIndexOption);
-      } else {
-        fieldMaxIndexOption = maxIndexOption;
-      }
-    
-      // Randomly picked the IndexOptions to index this
-      // field with:
-      IndexOptions indexOptions = IndexOptions.values()[random().nextInt(1+fieldMaxIndexOption)];
-      boolean doPayloads = indexOptions.compareTo(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS) >= 0 && allowPayloads;
-
-      newFieldInfoArray[fieldUpto] = new FieldInfo(oldFieldInfo.name,
-                                                   true,
-                                                   fieldUpto,
-                                                   false,
-                                                   false,
-                                                   doPayloads,
-                                                   indexOptions,
-                                                   null,
-                                                   DocValues.Type.FIXED_INTS_8,
-                                                   null);
-    }
-
-    FieldInfos newFieldInfos = new FieldInfos(newFieldInfoArray);
-
-    // Estimate that flushed segment size will be 25% of
-    // what we use in RAM:
-    long bytes =  totalPostings * 8 + totalPayloadBytes;
-
-    SegmentWriteState writeState = new SegmentWriteState(null, dir,
-                                                         segmentInfo, newFieldInfos,
-                                                         32, null, new IOContext(new FlushInfo(maxDocID, bytes)));
-    FieldsConsumer fieldsConsumer = Codec.getDefault().postingsFormat().fieldsConsumer(writeState);
-
-    for(Map.Entry<String,Map<BytesRef,List<Posting>>> fieldEnt : fields.entrySet()) {
-      String field = fieldEnt.getKey();
-      Map<BytesRef,List<Posting>> terms = fieldEnt.getValue();
-
-      FieldInfo fieldInfo = newFieldInfos.fieldInfo(field);
-
-      IndexOptions indexOptions = fieldInfo.getIndexOptions();
-
-      if (VERBOSE) {
-        System.out.println("field=" + field + " indexOtions=" + indexOptions);
-      }
-
-      boolean doFreq = indexOptions.compareTo(IndexOptions.DOCS_AND_FREQS) >= 0;
-      boolean doPos = indexOptions.compareTo(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS) >= 0;
-      boolean doPayloads = indexOptions.compareTo(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS) >= 0 && allowPayloads;
-      boolean doOffsets = indexOptions.compareTo(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS) >= 0;
-      
-      TermsConsumer termsConsumer = fieldsConsumer.addField(fieldInfo);
-      long sumTotalTF = 0;
-      long sumDF = 0;
-      FixedBitSet seenDocs = new FixedBitSet(maxDocID+1);
-      for(Map.Entry<BytesRef,List<Posting>> termEnt : terms.entrySet()) {
-        BytesRef term = termEnt.getKey();
-        List<Posting> postings = termEnt.getValue();
-        if (VERBOSE) {
-          System.out.println("  term=" + field + ":" + term.utf8ToString() + " docFreq=" + postings.size());
-        }
-        
-        PostingsConsumer postingsConsumer = termsConsumer.startTerm(term);
-        long totalTF = 0;
-        int docCount = 0;
-        for(Posting posting : postings) {
-          if (VERBOSE) {
-            System.out.println("    " + docCount + ": docID=" + posting.docID + " freq=" + posting.positions.size());
-          }
-          postingsConsumer.startDoc(posting.docID, doFreq ? posting.positions.size() : -1);
-          seenDocs.set(posting.docID);
-          if (doPos) {
-            totalTF += posting.positions.size();
-            for(Position pos : posting.positions) {
-              if (VERBOSE) {
-                if (doPayloads) {
-                  System.out.println("      pos=" + pos.position + " payload=" + (pos.payload == null ? "null" : pos.payload.length + " bytes"));
-                } else {
-                  System.out.println("      pos=" + pos.position);
-                }
-              }
-              postingsConsumer.addPosition(pos.position, (doPayloads && pos.payload != null) ? new BytesRef(pos.payload) : null, doOffsets ? pos.startOffset : -1, doOffsets ? pos.endOffset : -1);
-            }
-          } else if (doFreq) {
-            totalTF += posting.positions.size();
-          } else {
-            totalTF++;
-          }
-          postingsConsumer.finishDoc();
-          docCount++;
-        }
-        termsConsumer.finishTerm(term, new TermStats(postings.size(), doFreq ? totalTF : -1));
-        sumTotalTF += totalTF;
-        sumDF += postings.size();
-      }
 
-      termsConsumer.finish(doFreq ? sumTotalTF : -1, sumDF, seenDocs.cardinality());
-    }
-
-    fieldsConsumer.close();
-
-    if (VERBOSE) {
-      System.out.println("TEST: after indexing: files=");
-      for(String file : dir.listAll()) {
-        System.out.println("  " + file + ": " + dir.fileLength(file) + " bytes");
-      }
-    }
-
-    currentFieldInfos = newFieldInfos;
-
-    SegmentReadState readState = new SegmentReadState(dir, segmentInfo, newFieldInfos, IOContext.DEFAULT, 1);
-
-    return Codec.getDefault().postingsFormat().fieldsProducer(readState);
-  }
-
-  private static class ThreadState {
-    // Only used with REUSE option:
-    public DocsEnum reuseDocsEnum;
-    public DocsAndPositionsEnum reuseDocsAndPositionsEnum;
-  }
-
-  private void verifyEnum(ThreadState threadState,
-                          String field,
-                          BytesRef term,
-                          TermsEnum termsEnum,
-
-                          // Maximum options (docs/freqs/positions/offsets) to test:
-                          IndexOptions maxIndexOptions,
-
-                          EnumSet<Option> options) throws IOException {
-        
-    if (VERBOSE) {
-      System.out.println("  verifyEnum: options=" + options + " maxIndexOptions=" + maxIndexOptions);
-    }
-
-    // 50% of the time time pass liveDocs:
-    Bits liveDocs;
-    Map<String,Map<BytesRef,List<Posting>>> fieldsToUse;
-    if (options.contains(Option.LIVE_DOCS) && random().nextBoolean()) {
-      liveDocs = globalLiveDocs;
-      fieldsToUse = fieldsLive;
-      if (VERBOSE) {
-        System.out.println("  use liveDocs");
-      }
-    } else {
-      liveDocs = null;
-      fieldsToUse = fields;
-      if (VERBOSE) {
-        System.out.println("  no liveDocs");
-      }
-    }
-
-    FieldInfo fieldInfo = currentFieldInfos.fieldInfo(field);
-
-    assertEquals(fields.get(field).get(term).size(), termsEnum.docFreq());
-
-    // NOTE: can be empty list if we are using liveDocs:
-    List<Posting> expected = fieldsToUse.get(field).get(term);
-    
-    boolean allowFreqs = fieldInfo.getIndexOptions().compareTo(IndexOptions.DOCS_AND_FREQS) >= 0 &&
-      maxIndexOptions.compareTo(IndexOptions.DOCS_AND_FREQS) >= 0;
-    boolean doCheckFreqs = allowFreqs && random().nextInt(3) <= 2;
-
-    boolean allowPositions = fieldInfo.getIndexOptions().compareTo(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS) >= 0 &&
-      maxIndexOptions.compareTo(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS) >= 0;
-    boolean doCheckPositions = allowPositions && random().nextInt(3) <= 2;
-
-    boolean allowOffsets = fieldInfo.getIndexOptions().compareTo(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS) >= 0 &&
-      maxIndexOptions.compareTo(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS) >= 0;
-    boolean doCheckOffsets = allowOffsets && random().nextInt(3) <= 2;
-
-    boolean doCheckPayloads = options.contains(Option.PAYLOADS) && allowPositions && fieldInfo.hasPayloads() && random().nextInt(3) <= 2;
-
-    DocsEnum prevDocsEnum = null;
-
-    DocsEnum docsEnum;
-    DocsAndPositionsEnum docsAndPositionsEnum;
-
-    if (!doCheckPositions) {
-      if (allowPositions && random().nextInt(10) == 7) {
-        // 10% of the time, even though we will not check positions, pull a DocsAndPositions enum
-        
-        if (options.contains(Option.REUSE_ENUMS) && random().nextInt(10) < 9) {
-          prevDocsEnum = threadState.reuseDocsAndPositionsEnum;
-        }
-
-        int flags = 0;
-        if (random().nextBoolean()) {
-          flags |= DocsAndPositionsEnum.FLAG_OFFSETS;
-        }
-        if (random().nextBoolean()) {
-          flags |= DocsAndPositionsEnum.FLAG_PAYLOADS;
-        }
-
-        if (VERBOSE) {
-          System.out.println("  get DocsAndPositionsEnum (but we won't check positions) flags=" + flags);
-        }
-
-        threadState.reuseDocsAndPositionsEnum = termsEnum.docsAndPositions(liveDocs, (DocsAndPositionsEnum) prevDocsEnum, flags);
-        docsEnum = threadState.reuseDocsAndPositionsEnum;
-        docsAndPositionsEnum = threadState.reuseDocsAndPositionsEnum;
-      } else {
-        if (VERBOSE) {
-          System.out.println("  get DocsEnum");
-        }
-        if (options.contains(Option.REUSE_ENUMS) && random().nextInt(10) < 9) {
-          prevDocsEnum = threadState.reuseDocsEnum;
-        }
-        threadState.reuseDocsEnum = termsEnum.docs(liveDocs, prevDocsEnum, doCheckFreqs ? DocsEnum.FLAG_FREQS : 0);
-        docsEnum = threadState.reuseDocsEnum;
-        docsAndPositionsEnum = null;
-      }
-    } else {
-      if (options.contains(Option.REUSE_ENUMS) && random().nextInt(10) < 9) {
-        prevDocsEnum = threadState.reuseDocsAndPositionsEnum;
-      }
-
-      int flags = 0;
-      if (doCheckOffsets || random().nextInt(3) == 1) {
-        flags |= DocsAndPositionsEnum.FLAG_OFFSETS;
-      }
-      if (doCheckPayloads|| random().nextInt(3) == 1) {
-        flags |= DocsAndPositionsEnum.FLAG_PAYLOADS;
-      }
-
-      if (VERBOSE) {
-        System.out.println("  get DocsAndPositionsEnum flags=" + flags);
-      }
-
-      threadState.reuseDocsAndPositionsEnum = termsEnum.docsAndPositions(liveDocs, (DocsAndPositionsEnum) prevDocsEnum, flags);
-      docsEnum = threadState.reuseDocsAndPositionsEnum;
-      docsAndPositionsEnum = threadState.reuseDocsAndPositionsEnum;
-    }
-
-    assertNotNull("null DocsEnum", docsEnum);
-    int initialDocID = docsEnum.docID();
-    assertTrue("inital docID should be -1 or NO_MORE_DOCS: " + docsEnum, initialDocID == -1 || initialDocID == DocsEnum.NO_MORE_DOCS);
-
-    if (VERBOSE) {
-      if (prevDocsEnum == null) {
-        System.out.println("  got enum=" + docsEnum);
-      } else if (prevDocsEnum == docsEnum) {
-        System.out.println("  got reuse enum=" + docsEnum);
-      } else {
-        System.out.println("  got enum=" + docsEnum + " (reuse of " + prevDocsEnum + " failed)");
-      }
-    }
-
-    // 10% of the time don't consume all docs:
-    int stopAt;
-    if (options.contains(Option.PARTIAL_DOC_CONSUME) && expected.size() > 1 && random().nextInt(10) == 7) {
-      stopAt = random().nextInt(expected.size()-1);
-      if (VERBOSE) {
-        System.out.println("  will not consume all docs (" + stopAt + " vs " + expected.size() + ")");
-      }
-    } else {
-      stopAt = expected.size();
-      if (VERBOSE) {
-        System.out.println("  consume all docs");
-      }
-    }
-
-    double skipChance = random().nextDouble();
-    int numSkips = expected.size() < 3 ? 1 : _TestUtil.nextInt(random(), 1, Math.min(20, expected.size()/3));
-    int skipInc = expected.size()/numSkips;
-    int skipDocInc = (1+maxDocID)/numSkips;
-
-    // Sometimes do 100% skipping:
-    boolean doAllSkipping = options.contains(Option.SKIPPING) && random().nextInt(7) == 1;
-
-    double freqAskChance = random().nextDouble();
-    double payloadCheckChance = random().nextDouble();
-    double offsetCheckChance = random().nextDouble();
-
-    if (VERBOSE) {
-      if (options.contains(Option.SKIPPING)) {
-        System.out.println("  skipChance=" + skipChance + " numSkips=" + numSkips);
-      } else {
-        System.out.println("  no skipping");
-      }
-      if (doCheckFreqs) {
-        System.out.println("  freqAskChance=" + freqAskChance);
-      }
-      if (doCheckPayloads) {
-        System.out.println("  payloadCheckChance=" + payloadCheckChance);
-      }
-      if (doCheckOffsets) {
-        System.out.println("  offsetCheckChance=" + offsetCheckChance);
-      }
-    }
-
-    int nextPosting = 0;
-    while (nextPosting <= stopAt) {
-      if (nextPosting == stopAt) {
-        if (stopAt == expected.size()) {
-          assertEquals("DocsEnum should have ended but didn't", DocsEnum.NO_MORE_DOCS, docsEnum.nextDoc());
-
-          // Common bug is to forget to set this.doc=NO_MORE_DOCS in the enum!:
-          assertEquals("DocsEnum should have ended but didn't", DocsEnum.NO_MORE_DOCS, docsEnum.docID());
-        }
-        break;
-      }
-
-      Posting posting;
-      if (options.contains(Option.SKIPPING) && (doAllSkipping || random().nextDouble() <= skipChance)) {
-        int targetDocID = -1;
-        if (nextPosting < stopAt && random().nextBoolean()) {
-          // Pick target we know exists:
-          nextPosting = _TestUtil.nextInt(random(), nextPosting, nextPosting+skipInc);
-        } else {
-          // Pick random target (might not exist):
-          Posting target = new Posting();
-          target.docID = _TestUtil.nextInt(random(), expected.get(nextPosting).docID, expected.get(nextPosting).docID+skipDocInc);
-          targetDocID = target.docID;
-          int loc = Collections.binarySearch(expected.subList(nextPosting, expected.size()), target);
-          if (loc < 0) {
-            loc = -loc-1;
-          }
-          nextPosting = nextPosting + loc;
-        }
-
-        if (nextPosting >= stopAt) {
-          int target = random().nextBoolean() ? (maxDocID+1) : DocsEnum.NO_MORE_DOCS;
-          if (VERBOSE) {
-            System.out.println("  now advance to end (target=" + target + ")");
-          }
-          assertEquals("DocsEnum should have ended but didn't", DocsEnum.NO_MORE_DOCS, docsEnum.advance(target));
-          break;
-        } else {
-          posting = expected.get(nextPosting++);
-          if (VERBOSE) {
-            if (targetDocID != -1) {
-              System.out.println("  now advance to random target=" + targetDocID + " (" + nextPosting + " of " + stopAt + ")");
-            } else {
-              System.out.println("  now advance to known-exists target=" + posting.docID + " (" + nextPosting + " of " + stopAt + ")");
-            }
-          }
-          int docID = docsEnum.advance(targetDocID != -1 ? targetDocID : posting.docID);
-          assertEquals("docID is wrong", posting.docID, docID);
-        }
-      } else {
-        posting = expected.get(nextPosting++);
-        if (VERBOSE) {
-          System.out.println("  now nextDoc to " + posting.docID + " (" + nextPosting + " of " + stopAt + ")");
-        }
-        int docID = docsEnum.nextDoc();
-        assertEquals("docID is wrong", posting.docID, docID);
-      }
-
-      if (doCheckFreqs && random().nextDouble() <= freqAskChance) {
-        if (VERBOSE) {
-          System.out.println("    now freq()=" + posting.positions.size());
-        }
-        int freq = docsEnum.freq();
-        assertEquals("freq is wrong", posting.positions.size(), freq);
-      }
-
-      if (doCheckPositions) {
-        int freq = docsEnum.freq();
-        int numPosToConsume;
-        if (options.contains(Option.PARTIAL_POS_CONSUME) && random().nextInt(5) == 1) {
-          numPosToConsume = random().nextInt(freq);
-        } else {
-          numPosToConsume = freq;
-        }
-
-        for(int i=0;i<numPosToConsume;i++) {
-          Position position = posting.positions.get(i);
-          if (VERBOSE) {
-            System.out.println("    now nextPosition to " + position.position);
-          }
-          assertEquals("position is wrong", position.position, docsAndPositionsEnum.nextPosition());
-
-          // TODO sometimes don't pull the payload even
-          // though we pulled the position
-
-          if (doCheckPayloads) {
-            if (random().nextDouble() <= payloadCheckChance) {
-              if (VERBOSE) {
-                System.out.println("      now check payload length=" + (position.payload == null ? 0 : position.payload.length));
-              }
-              if (position.payload == null || position.payload.length == 0) {
-                assertNull("should not have payload", docsAndPositionsEnum.getPayload());
-              } else {
-                BytesRef payload = docsAndPositionsEnum.getPayload();
-                assertNotNull("should have payload but doesn't", payload);
-
-                assertEquals("payload length is wrong", position.payload.length, payload.length);
-                for(int byteUpto=0;byteUpto<position.payload.length;byteUpto++) {
-                  assertEquals("payload bytes are wrong",
-                               position.payload[byteUpto],
-                               payload.bytes[payload.offset+byteUpto]);
-                }
-                
-                // make a deep copy
-                payload = BytesRef.deepCopyOf(payload);
-                assertEquals("2nd call to getPayload returns something different!", payload, docsAndPositionsEnum.getPayload());
-              }
-            } else {
-              if (VERBOSE) {
-                System.out.println("      skip check payload length=" + (position.payload == null ? 0 : position.payload.length));
-              }
-            }
-          }
-
-          if (doCheckOffsets) {
-            if (random().nextDouble() <= offsetCheckChance) {
-              if (VERBOSE) {
-                System.out.println("      now check offsets: startOff=" + position.startOffset + " endOffset=" + position.endOffset);
-              }
-              assertEquals("startOffset is wrong", position.startOffset, docsAndPositionsEnum.startOffset());
-              assertEquals("endOffset is wrong", position.endOffset, docsAndPositionsEnum.endOffset());
-            } else {
-              if (VERBOSE) {
-                System.out.println("      skip check offsets");
-              }
-            }
-          } else {
-            if (VERBOSE) {
-              System.out.println("      now check offsets are -1");
-            }
-            assertEquals("startOffset isn't -1", -1, docsAndPositionsEnum.startOffset());
-            assertEquals("endOffset isn't -1", -1, docsAndPositionsEnum.endOffset());
-          }
-        }
-      }
-    }
-  }
-
-  private void testTerms(final Fields fieldsSource, final EnumSet<Option> options, final IndexOptions maxIndexOptions) throws Exception {
-
-    if (options.contains(Option.THREADS)) {
-      int numThreads = _TestUtil.nextInt(random(), 2, 5);
-      Thread[] threads = new Thread[numThreads];
-      for(int threadUpto=0;threadUpto<numThreads;threadUpto++) {
-        threads[threadUpto] = new Thread() {
-            @Override
-            public void run() {
-              try {
-                testTermsOneThread(fieldsSource, options, maxIndexOptions);
-              } catch (Throwable t) {
-                throw new RuntimeException(t);
-              }
-            }
-          };
-        threads[threadUpto].start();
-      }
-      for(int threadUpto=0;threadUpto<numThreads;threadUpto++) {
-        threads[threadUpto].join();
-      }
-    } else {
-      testTermsOneThread(fieldsSource, options, maxIndexOptions);
-    }
-  }
-
-  private void testTermsOneThread(Fields fieldsSource, EnumSet<Option> options, IndexOptions maxIndexOptions) throws IOException {
-
-    ThreadState threadState = new ThreadState();
-
-    // Test random terms/fields:
-    List<TermState> termStates = new ArrayList<TermState>();
-    List<FieldAndTerm> termStateTerms = new ArrayList<FieldAndTerm>();
-    
-    Collections.shuffle(allTerms, random());
-    int upto = 0;
-    while (upto < allTerms.size()) {
-
-      boolean useTermState = termStates.size() != 0 && random().nextInt(5) == 1;
-      FieldAndTerm fieldAndTerm;
-      TermsEnum termsEnum;
-
-      TermState termState = null;
-
-      if (!useTermState) {
-        // Seek by random field+term:
-        fieldAndTerm = allTerms.get(upto++);
-        if (VERBOSE) {
-          System.out.println("\nTEST: seek to term=" + fieldAndTerm.field + ":" + fieldAndTerm.term.utf8ToString() );
-        }
-      } else {
-        // Seek by previous saved TermState
-        int idx = random().nextInt(termStates.size());
-        fieldAndTerm = termStateTerms.get(idx);
-        if (VERBOSE) {
-          System.out.println("\nTEST: seek using TermState to term=" + fieldAndTerm.field + ":" + fieldAndTerm.term.utf8ToString());
-        }
-        termState = termStates.get(idx);
-      }
-
-      Terms terms = fieldsSource.terms(fieldAndTerm.field);
-      assertNotNull(terms);
-      termsEnum = terms.iterator(null);
-
-      if (!useTermState) {
-        assertTrue(termsEnum.seekExact(fieldAndTerm.term, true));
-      } else {
-        termsEnum.seekExact(fieldAndTerm.term, termState);
-      }
-
-      boolean savedTermState = false;
-
-      if (options.contains(Option.TERM_STATE) && !useTermState && random().nextInt(5) == 1) {
-        // Save away this TermState:
-        termStates.add(termsEnum.termState());
-        termStateTerms.add(fieldAndTerm);
-        savedTermState = true;
-      }
-
-      verifyEnum(threadState,
-                 fieldAndTerm.field,
-                 fieldAndTerm.term,
-                 termsEnum,
-                 maxIndexOptions,
-                 options);
-
-      // Sometimes save term state after pulling the enum:
-      if (options.contains(Option.TERM_STATE) && !useTermState && !savedTermState && random().nextInt(5) == 1) {
-        // Save away this TermState:
-        termStates.add(termsEnum.termState());
-        termStateTerms.add(fieldAndTerm);
-        useTermState = true;
-      }
-
-      // 10% of the time make sure you can pull another enum
-      // from the same term:
-      if (random().nextInt(10) == 7) {
-        // Try same term again
-        if (VERBOSE) {
-          System.out.println("TEST: try enum again on same term");
-        }
-
-        verifyEnum(threadState,
-                   fieldAndTerm.field,
-                   fieldAndTerm.term,
-                   termsEnum,
-                   maxIndexOptions,
-                   options);
-      }
-    }
-  }
-  
-  private void testFields(Fields fields) throws Exception {
-    Iterator<String> iterator = fields.iterator();
-    while (iterator.hasNext()) {
-      String field = iterator.next();
-      try {
-        iterator.remove();
-        fail("Fields.iterator() allows for removal");
-      } catch (UnsupportedOperationException expected) {
-        // expected;
-      }
-    }
-    assertFalse(iterator.hasNext());
-    try {
-      iterator.next();
-      fail("Fields.iterator() doesn't throw NoSuchElementException when past the end");
-    } catch (NoSuchElementException expected) {
-      // expected
-    }
-  }
-
-  public void test() throws Exception {
-    Directory dir = newFSDirectory(_TestUtil.getTempDir("testPostingsFormat"));
-
-    boolean indexPayloads = random().nextBoolean();
-    // TODO test thread safety of buildIndex too
-
-    FieldsProducer fieldsProducer = buildIndex(dir, IndexOptions.DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS, indexPayloads);
-
-    testFields(fieldsProducer);
-    //testTerms(fieldsProducer, EnumSet.noneOf(Option.class), IndexOptions.DOCS_AND_FREQS_AND_POSITIONS);
-    //testTerms(fieldsProducer, EnumSet.of(Option.LIVE_DOCS), IndexOptions.DOCS_AND_FREQS_AND_POSITIONS);
-    //testTerms(fieldsProducer, EnumSet.of(Option.TERM_STATE, Option.LIVE_DOCS, Option.PARTIAL_DOC_CONSUME, Option.PARTIAL_POS_CONSUME), IndexOptions.DOCS_AND_FREQS_AND_POSITIONS);
-
-    //testTerms(fieldsProducer, EnumSet.of(Option.SKIPPING), IndexOptions.DOCS_AND_FREQS_AND_POSITIONS);
-    //testTerms(fieldsProducer, EnumSet.of(Option.THREADS, Option.TERM_STATE, Option.SKIPPING, Option.PARTIAL_DOC_CONSUME, Option.PARTIAL_POS_CONSUME), IndexOptions.DOCS_AND_FREQS_AND_POSITIONS);
-    //testTerms(fieldsProducer, EnumSet.of(Option.TERM_STATE, Option.SKIPPING, Option.PARTIAL_DOC_CONSUME, Option.PARTIAL_POS_CONSUME), IndexOptions.DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS);
-    //testTerms(fieldsProducer, EnumSet.of(Option.TERM_STATE, Option.PAYLOADS, Option.PARTIAL_DOC_CONSUME, Option.PARTIAL_POS_CONSUME, Option.SKIPPING), IndexOptions.DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS);
-
-    // NOTE: you can also test "weaker" index options than
-    // you indexed with:
-    testTerms(fieldsProducer, EnumSet.allOf(Option.class), IndexOptions.DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS);
-    //testTerms(fieldsProducer, EnumSet.complementOf(EnumSet.of(Option.THREADS)), IndexOptions.DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS);
+/** Tests the codec configuration defined by LuceneTestCase randomly
+ *  (typically a mix across different fields).
+ */
+public class TestPostingsFormat extends BasePostingsFormatTestCase {
 
-    fieldsProducer.close();
-    dir.close();
+  @Override
+  protected Codec getCodec() {
+    return Codec.getDefault();
   }
 }
-
-// TODO test that start/endOffset return -1 if field has
-// no offsets

Modified: lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/index/TestRollingUpdates.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/index/TestRollingUpdates.java?rev=1402140&r1=1402139&r2=1402140&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/index/TestRollingUpdates.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/index/TestRollingUpdates.java Thu Oct 25 13:10:25 2012
@@ -39,7 +39,6 @@ public class TestRollingUpdates extends 
   public void testRollingUpdates() throws Exception {
     Random random = new Random(random().nextLong());
     final BaseDirectoryWrapper dir = newDirectory();
-    dir.setCheckIndexOnClose(false); // we use a custom codec provider
     final LineFileDocs docs = new LineFileDocs(random, true);
 
     //provider.register(new MemoryCodec());
@@ -130,9 +129,25 @@ public class TestRollingUpdates extends 
     assertEquals(SIZE, w.numDocs());
 
     w.close();
+
+    TestIndexWriter.assertNoUnreferencedFiles(dir, "leftover files after rolling updates");
+
     docs.close();
     
-    _TestUtil.checkIndex(dir);
+    // LUCENE-4455:
+    SegmentInfos infos = new SegmentInfos();
+    infos.read(dir);
+    long totalBytes = 0;
+    for(SegmentInfoPerCommit sipc : infos) {
+      totalBytes += sipc.sizeInBytes();
+    }
+    long totalBytes2 = 0;
+    for(String fileName : dir.listAll()) {
+      if (!fileName.startsWith(IndexFileNames.SEGMENTS)) {
+        totalBytes2 += dir.fileLength(fileName);
+      }
+    }
+    assertEquals(totalBytes2, totalBytes);
     dir.close();
   }
   

Modified: lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/index/TestSegmentTermEnum.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/index/TestSegmentTermEnum.java?rev=1402140&r1=1402139&r2=1402140&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/index/TestSegmentTermEnum.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/index/TestSegmentTermEnum.java Thu Oct 25 13:10:25 2012
@@ -24,7 +24,7 @@ import org.apache.lucene.util.LuceneTest
 import org.apache.lucene.util.BytesRef;
 import org.apache.lucene.util._TestUtil;
 import org.apache.lucene.analysis.MockAnalyzer;
-import org.apache.lucene.codecs.lucene40.Lucene40PostingsFormat;
+import org.apache.lucene.codecs.lucene41.Lucene41PostingsFormat;
 import org.apache.lucene.document.Document;
 import org.apache.lucene.index.IndexWriterConfig.OpenMode;
 import org.apache.lucene.store.Directory;
@@ -75,7 +75,7 @@ public class TestSegmentTermEnum extends
 
   public void testPrevTermAtEnd() throws IOException
   {
-    IndexWriter writer  = new IndexWriter(dir, newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random())).setCodec(_TestUtil.alwaysPostingsFormat(new Lucene40PostingsFormat())));
+    IndexWriter writer  = new IndexWriter(dir, newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random())).setCodec(_TestUtil.alwaysPostingsFormat(new Lucene41PostingsFormat())));
     addDoc(writer, "aaa bbb");
     writer.close();
     SegmentReader reader = getOnlySegmentReader(DirectoryReader.open(dir));

Modified: lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/index/TestSnapshotDeletionPolicy.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/index/TestSnapshotDeletionPolicy.java?rev=1402140&r1=1402139&r2=1402140&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/index/TestSnapshotDeletionPolicy.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/index/TestSnapshotDeletionPolicy.java Thu Oct 25 13:10:25 2012
@@ -17,17 +17,18 @@ package org.apache.lucene.index;
  * limitations under the License.
  */
 
+import java.io.IOException;
 import java.util.Collection;
 import java.util.Map;
 import java.util.Random;
-import java.io.IOException;
 
+import org.apache.lucene.analysis.MockAnalyzer;
 import org.apache.lucene.document.Document;
 import org.apache.lucene.document.FieldType;
 import org.apache.lucene.document.TextField;
 import org.apache.lucene.store.Directory;
 import org.apache.lucene.store.IndexInput;
-import org.apache.lucene.analysis.MockAnalyzer;
+import org.apache.lucene.store.MockDirectoryWrapper;
 import org.apache.lucene.util.LuceneTestCase;
 import org.apache.lucene.util.ThreadInterruptedException;
 import org.junit.Test;
@@ -313,6 +314,7 @@ public class TestSnapshotDeletionPolicy 
   public void testRollbackToOldSnapshot() throws Exception {
     int numSnapshots = 2;
     Directory dir = newDirectory();
+
     SnapshotDeletionPolicy sdp = getDeletionPolicy();
     IndexWriter writer = new IndexWriter(dir, getConfig(random(), sdp));
     prepareIndexAndSnapshots(sdp, writer, numSnapshots, "snapshot");
@@ -325,10 +327,11 @@ public class TestSnapshotDeletionPolicy 
     writer.deleteUnusedFiles();
     assertSnapshotExists(dir, sdp, numSnapshots - 1);
     writer.close();
-    
+
     // but 'snapshot1' files will still exist (need to release snapshot before they can be deleted).
     String segFileName = sdp.getSnapshot("snapshot1").getSegmentsFileName();
     assertTrue("snapshot files should exist in the directory: " + segFileName, dir.fileExists(segFileName));
+
     dir.close();
   }
 
@@ -385,6 +388,7 @@ public class TestSnapshotDeletionPolicy 
   @Test
   public void testSnapshotLastCommitTwice() throws Exception {
     Directory dir = newDirectory();
+
     SnapshotDeletionPolicy sdp = getDeletionPolicy();
     IndexWriter writer = new IndexWriter(dir, getConfig(random(), sdp));
     writer.addDocument(new Document());

Modified: lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/index/TestTransactionRollback.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/index/TestTransactionRollback.java?rev=1402140&r1=1402139&r2=1402140&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/index/TestTransactionRollback.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/index/TestTransactionRollback.java Thu Oct 25 13:10:25 2012
@@ -21,17 +21,18 @@ package org.apache.lucene.index;
 import java.io.IOException;
 import java.util.BitSet;
 import java.util.Collection;
+import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.HashMap;
 
-import org.apache.lucene.document.Field;
-import org.apache.lucene.util.LuceneTestCase;
 import org.apache.lucene.analysis.MockAnalyzer;
 import org.apache.lucene.document.Document;
+import org.apache.lucene.document.Field;
 import org.apache.lucene.store.Directory;
+import org.apache.lucene.store.MockDirectoryWrapper;
 import org.apache.lucene.util.Bits;
+import org.apache.lucene.util.LuceneTestCase;
 
 /**
  * Test class to illustrate using IndexDeletionPolicy to provide multi-level rollback capability.
@@ -55,13 +56,16 @@ public class TestTransactionRollback ext
     for (Iterator<IndexCommit> iterator = commits.iterator(); iterator.hasNext();) {
       IndexCommit commit =  iterator.next();
       Map<String,String> ud=commit.getUserData();
-      if (ud.size() > 0)
-        if (ud.get("index").endsWith(ids))
-          last=commit;
+      if (ud.size() > 0) {
+        if (ud.get("index").endsWith(ids)) {
+          last = commit;
+        }
+      }
     }
 
-    if (last==null)
+    if (last==null) {
       throw new RuntimeException("Couldn't find commit point "+id);
+    }
 
     IndexWriter w = new IndexWriter(dir, newIndexWriterConfig(
         TEST_VERSION_CURRENT, new MockAnalyzer(random())).setIndexDeletionPolicy(
@@ -74,13 +78,13 @@ public class TestTransactionRollback ext
 
   public void testRepeatedRollBacks() throws Exception {
 
-    int expectedLastRecordId=100;
+    int expectedLastRecordId = 100;
     while (expectedLastRecordId>10) {
-      expectedLastRecordId -=10;
+      expectedLastRecordId -= 10;
       rollBackLast(expectedLastRecordId);
       
       BitSet expecteds = new BitSet(100);
-      expecteds.set(1,(expectedLastRecordId+1),true);
+      expecteds.set(1, (expectedLastRecordId+1), true);
       checkExpecteds(expecteds);
     }
   }
@@ -125,6 +129,7 @@ public class TestTransactionRollback ext
   public void setUp() throws Exception {
     super.setUp();
     dir = newDirectory();
+
     //Build index, of records 1 to 100, committing after each batch of 10
     IndexDeletionPolicy sdp=new KeepAllDeletionPolicy();
     IndexWriter w=new IndexWriter(dir, newIndexWriterConfig( TEST_VERSION_CURRENT, new MockAnalyzer(random())).setIndexDeletionPolicy(sdp));
@@ -199,6 +204,7 @@ public class TestTransactionRollback ext
   }
 
   public void testRollbackDeletionPolicy() throws Exception {
+
     for(int i=0;i<2;i++) {
       // Unless you specify a prior commit point, rollback
       // should not work:

Modified: lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/index/TestTransactions.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/index/TestTransactions.java?rev=1402140&r1=1402139&r2=1402140&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/index/TestTransactions.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/index/TestTransactions.java Thu Oct 25 13:10:25 2012
@@ -215,6 +215,11 @@ public class TestTransactions extends Lu
     dir1.setFailOnOpenInput(false);
     dir2.setFailOnOpenInput(false);
 
+    // We throw exceptions in deleteFile, which creates
+    // leftover files:
+    dir1.setAssertNoUnrefencedFilesOnClose(false);
+    dir2.setAssertNoUnrefencedFilesOnClose(false);
+
     initIndex(dir1);
     initIndex(dir2);
 

Modified: lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/search/TestBooleanOr.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/search/TestBooleanOr.java?rev=1402140&r1=1402139&r2=1402140&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/search/TestBooleanOr.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/search/TestBooleanOr.java Thu Oct 25 13:10:25 2012
@@ -60,8 +60,6 @@ public class TestBooleanOr extends Lucen
   /**
    * <code>T:files T:deleting C:production C:optimize </code>
    * it works.
-   *
-   * @throws IOException
    */
   public void testFlat() throws IOException {
     BooleanQuery q = new BooleanQuery();
@@ -75,8 +73,6 @@ public class TestBooleanOr extends Lucen
   /**
    * <code>(T:files T:deleting) (+C:production +C:optimize)</code>
    * it works.
-   *
-   * @throws IOException
    */
   public void testParenthesisMust() throws IOException {
     BooleanQuery q3 = new BooleanQuery();
@@ -94,8 +90,6 @@ public class TestBooleanOr extends Lucen
   /**
    * <code>(T:files T:deleting) +(C:production C:optimize)</code>
    * not working. results NO HIT.
-   *
-   * @throws IOException
    */
   public void testParenthesisMust2() throws IOException {
     BooleanQuery q3 = new BooleanQuery();
@@ -113,8 +107,6 @@ public class TestBooleanOr extends Lucen
   /**
    * <code>(T:files T:deleting) (C:production C:optimize)</code>
    * not working. results NO HIT.
-   *
-   * @throws IOException
    */
   public void testParenthesisShould() throws IOException {
     BooleanQuery q3 = new BooleanQuery();

Modified: lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/search/TestBooleanQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/search/TestBooleanQuery.java?rev=1402140&r1=1402139&r2=1402140&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/search/TestBooleanQuery.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/search/TestBooleanQuery.java Thu Oct 25 13:10:25 2012
@@ -25,11 +25,15 @@ import java.util.concurrent.ExecutorServ
 import java.util.concurrent.Executors;
 import java.util.concurrent.TimeUnit;
 
+import org.apache.lucene.analysis.Analyzer;
 import org.apache.lucene.analysis.MockAnalyzer;
 import org.apache.lucene.document.Document;
 import org.apache.lucene.document.Field;
 import org.apache.lucene.document.TextField;
+import org.apache.lucene.index.DirectoryReader;
 import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.index.IndexWriter;
+import org.apache.lucene.index.IndexWriterConfig;
 import org.apache.lucene.index.MultiReader;
 import org.apache.lucene.index.RandomIndexWriter;
 import org.apache.lucene.index.Term;
@@ -39,6 +43,8 @@ import org.apache.lucene.search.position
 import org.apache.lucene.search.positions.RangeIntervalIterator;
 import org.apache.lucene.search.positions.WithinIntervalIterator;
 import org.apache.lucene.search.similarities.DefaultSimilarity;
+import org.apache.lucene.search.spans.SpanQuery;
+import org.apache.lucene.search.spans.SpanTermQuery;
 import org.apache.lucene.store.Directory;
 import org.apache.lucene.util.LuceneTestCase;
 import org.apache.lucene.util.NamedThreadFactory;
@@ -341,4 +347,40 @@ public class TestBooleanQuery extends Lu
      reader.close();
      directory.close();
    }
+
+  // LUCENE-4477 / LUCENE-4401:
+  public void testBooleanSpanQuery() throws Exception {
+    boolean failed = false;
+    int hits = 0;
+    Directory directory = newDirectory();
+    Analyzer indexerAnalyzer = new MockAnalyzer(random());
+
+    IndexWriterConfig config = new IndexWriterConfig(TEST_VERSION_CURRENT, indexerAnalyzer);
+    IndexWriter writer = new IndexWriter(directory, config);
+    String FIELD = "content";
+    Document d = new Document();
+    d.add(new TextField(FIELD, "clockwork orange", Field.Store.YES));
+    writer.addDocument(d);
+    writer.close();
+
+    IndexReader indexReader = DirectoryReader.open(directory);
+    IndexSearcher searcher = new IndexSearcher(indexReader);
+
+    BooleanQuery query = new BooleanQuery();
+    SpanQuery sq1 = new SpanTermQuery(new Term(FIELD, "clockwork"));
+    SpanQuery sq2 = new SpanTermQuery(new Term(FIELD, "clckwork"));
+    query.add(sq1, BooleanClause.Occur.SHOULD);
+    query.add(sq2, BooleanClause.Occur.SHOULD);
+    TopScoreDocCollector collector = TopScoreDocCollector.create(1000, true);
+    searcher.search(query, collector);
+    hits = collector.topDocs().scoreDocs.length;
+    for (ScoreDoc scoreDoc : collector.topDocs().scoreDocs){
+      System.out.println(scoreDoc.doc);
+    }
+    indexReader.close();
+    assertEquals("Bug in boolean query composed of span queries", failed, false);
+    assertEquals("Bug in boolean query composed of span queries", hits, 1);
+    directory.close();
+  }
+
 }

Modified: lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/search/TestCustomSearcherSort.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/search/TestCustomSearcherSort.java?rev=1402140&r1=1402139&r2=1402140&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/search/TestCustomSearcherSort.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/search/TestCustomSearcherSort.java Thu Oct 25 13:10:25 2012
@@ -152,8 +152,6 @@ public class TestCustomSearcherSort exte
   
   /**
    * Check the hits for duplicates.
-   * 
-   * @param hits
    */
   private void checkHits(ScoreDoc[] hits, String prefix) {
     if (hits != null) {
@@ -186,9 +184,6 @@ public class TestCustomSearcherSort exte
   public class CustomSearcher extends IndexSearcher {
     private int switcher;
     
-    /**
-     * @param r
-     */
     public CustomSearcher(IndexReader r, int switcher) {
       super(r);
       this.switcher = switcher;

Modified: lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/search/TestTermQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/search/TestTermQuery.java?rev=1402140&r1=1402139&r2=1402140&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/search/TestTermQuery.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/search/TestTermQuery.java Thu Oct 25 13:10:25 2012
@@ -215,7 +215,7 @@ public class TestTermQuery extends Lucen
             scorer.advance(docID + 1 + random().nextInt((maxDoc - docID)));
           }
 
-        } while (scorer.nextDoc() != Scorer.NO_MORE_DOCS);
+        } while (scorer.docID() != Scorer.NO_MORE_DOCS && scorer.nextDoc() != Scorer.NO_MORE_DOCS);
       }
 
     }

Modified: lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/search/TestWildcard.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/search/TestWildcard.java?rev=1402140&r1=1402139&r2=1402140&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/search/TestWildcard.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/search/TestWildcard.java Thu Oct 25 13:10:25 2012
@@ -269,7 +269,6 @@ public class TestWildcard
    * This test looks at both parsing and execution of wildcard queries.
    * Although placed here, it also tests prefix queries, verifying that
    * prefix queries are not parsed into wild card queries, and viceversa.
-   * @throws Exception
    */
   public void testParsingAndSearching() throws Exception {
     String field = "content";

Modified: lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/search/payloads/PayloadHelper.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/search/payloads/PayloadHelper.java?rev=1402140&r1=1402139&r2=1402140&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/search/payloads/PayloadHelper.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/search/payloads/PayloadHelper.java Thu Oct 25 13:10:25 2012
@@ -113,7 +113,6 @@ public class PayloadHelper {
    * @param similarity The Similarity class to use in the Searcher
    * @param numDocs The num docs to add
    * @return An IndexSearcher
-   * @throws IOException
    */
   // TODO: randomize
   public IndexSearcher setUp(Random random, Similarity similarity, int numDocs) throws IOException {

Modified: lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/search/positions/TestPositionsAndOffsets.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/search/positions/TestPositionsAndOffsets.java?rev=1402140&r1=1402139&r2=1402140&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/search/positions/TestPositionsAndOffsets.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/search/positions/TestPositionsAndOffsets.java Thu Oct 25 13:10:25 2012
@@ -21,10 +21,10 @@ import java.util.List;
 
 import org.apache.lucene.analysis.MockAnalyzer;
 import org.apache.lucene.codecs.Codec;
-import org.apache.lucene.codecs.lucene40.Lucene40PostingsFormat;
+import org.apache.lucene.codecs.lucene41.Lucene41PostingsFormat;
 import org.apache.lucene.codecs.memory.MemoryPostingsFormat;
 import org.apache.lucene.codecs.nestedpulsing.NestedPulsingPostingsFormat;
-import org.apache.lucene.codecs.pulsing.Pulsing40PostingsFormat;
+import org.apache.lucene.codecs.pulsing.Pulsing41PostingsFormat;
 import org.apache.lucene.document.Document;
 import org.apache.lucene.document.FieldType;
 import org.apache.lucene.document.TextField;
@@ -57,10 +57,10 @@ public class TestPositionsAndOffsets ext
     if (codecName.equals("Lucene40")) {
       // Sep etc are not implemented
       switch(random().nextInt(4)) {
-        case 0: iwc.setCodec(_TestUtil.alwaysPostingsFormat(new Lucene40PostingsFormat())); break;
+        case 0: iwc.setCodec(_TestUtil.alwaysPostingsFormat(new Lucene41PostingsFormat())); break;
         case 1: iwc.setCodec(_TestUtil.alwaysPostingsFormat(new MemoryPostingsFormat())); break;
         case 2: iwc.setCodec(_TestUtil.alwaysPostingsFormat(
-            new Pulsing40PostingsFormat(_TestUtil.nextInt(random(), 1, 3)))); break;
+            new Pulsing41PostingsFormat(_TestUtil.nextInt(random(), 1, 3)))); break;
         case 3: iwc.setCodec(_TestUtil.alwaysPostingsFormat(new NestedPulsingPostingsFormat())); break;
       }
     }
@@ -100,7 +100,7 @@ public class TestPositionsAndOffsets ext
     List<AtomicReaderContext> leaves = topReaderContext.leaves();
     assertEquals(1, leaves.size());
     Scorer scorer = weight.scorer(leaves.get(0),
-        true, true, PostingFeatures.POSITIONS, leaves.get(0).reader().getLiveDocs());
+        true, true, PostingFeatures.OFFSETS, leaves.get(0).reader().getLiveDocs());
 
     int nextDoc = scorer.nextDoc();
     assertEquals(0, nextDoc);

Modified: lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/search/spans/TestSpansAdvanced.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/search/spans/TestSpansAdvanced.java?rev=1402140&r1=1402139&r2=1402140&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/search/spans/TestSpansAdvanced.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/search/spans/TestSpansAdvanced.java Thu Oct 25 13:10:25 2012
@@ -86,7 +86,6 @@ public class TestSpansAdvanced extends L
    * @param writer the Lucene index writer
    * @param id the unique id of the document
    * @param text the text of the document
-   * @throws IOException
    */
   protected void addDocument(final RandomIndexWriter writer, final String id,
       final String text) throws IOException {
@@ -99,8 +98,6 @@ public class TestSpansAdvanced extends L
   
   /**
    * Tests two span queries.
-   * 
-   * @throws IOException
    */
   public void testBooleanQueryWithSpanQueries() throws IOException {
     
@@ -109,8 +106,6 @@ public class TestSpansAdvanced extends L
   
   /**
    * Tests two span queries.
-   * 
-   * @throws IOException
    */
   protected void doTestBooleanQueryWithSpanQueries(IndexSearcher s,
       final float expectedScore) throws IOException {
@@ -132,8 +127,6 @@ public class TestSpansAdvanced extends L
    * @param description the description of the search
    * @param expectedIds the expected document ids of the hits
    * @param expectedScores the expected scores of the hits
-   * 
-   * @throws IOException
    */
   protected static void assertHits(IndexSearcher s, Query query,
       final String description, final String[] expectedIds,

Modified: lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/search/spans/TestSpansAdvanced2.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/search/spans/TestSpansAdvanced2.java?rev=1402140&r1=1402139&r2=1402140&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/search/spans/TestSpansAdvanced2.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/search/spans/TestSpansAdvanced2.java Thu Oct 25 13:10:25 2012
@@ -72,8 +72,6 @@ public class TestSpansAdvanced2 extends 
   
   /**
    * Verifies that the index has the correct number of documents.
-   * 
-   * @throws Exception
    */
   public void testVerifyIndex() throws Exception {
     final IndexReader reader = DirectoryReader.open(mDirectory);
@@ -83,8 +81,6 @@ public class TestSpansAdvanced2 extends 
   
   /**
    * Tests a single span query that matches multiple documents.
-   * 
-   * @throws IOException
    */
   public void testSingleSpanQuery() throws IOException {
     
@@ -99,8 +95,6 @@ public class TestSpansAdvanced2 extends 
   
   /**
    * Tests a single span query that matches multiple documents.
-   * 
-   * @throws IOException
    */
   public void testMultipleDifferentSpanQueries() throws IOException {
     
@@ -119,8 +113,6 @@ public class TestSpansAdvanced2 extends 
   
   /**
    * Tests two span queries.
-   * 
-   * @throws IOException
    */
   @Override
   public void testBooleanQueryWithSpanQueries() throws IOException {

Modified: lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/store/TestFileSwitchDirectory.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/store/TestFileSwitchDirectory.java?rev=1402140&r1=1402139&r2=1402140&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/store/TestFileSwitchDirectory.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/store/TestFileSwitchDirectory.java Thu Oct 25 13:10:25 2012
@@ -37,7 +37,6 @@ import org.apache.lucene.util._TestUtil;
 public class TestFileSwitchDirectory extends LuceneTestCase {
   /**
    * Test if writing doc stores to disk and everything else to ram works.
-   * @throws IOException
    */
   public void testBasic() throws IOException {
     Set<String> fileExtensions = new HashSet<String>();

Modified: lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/util/TestNamedSPILoader.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/util/TestNamedSPILoader.java?rev=1402140&r1=1402139&r2=1402140&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/util/TestNamedSPILoader.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/util/TestNamedSPILoader.java Thu Oct 25 13:10:25 2012
@@ -25,8 +25,8 @@ import org.apache.lucene.codecs.Codec;
 // enough to test the basics via Codec
 public class TestNamedSPILoader extends LuceneTestCase {
   public void testLookup() {
-    Codec codec = Codec.forName("Lucene40");
-    assertEquals("Lucene40", codec.getName());
+    Codec codec = Codec.forName("Lucene41");
+    assertEquals("Lucene41", codec.getName());
   }
   
   // we want an exception if its not found.
@@ -39,6 +39,6 @@ public class TestNamedSPILoader extends 
   
   public void testAvailableServices() {
     Set<String> codecs = Codec.availableCodecs();
-    assertTrue(codecs.contains("Lucene40"));
+    assertTrue(codecs.contains("Lucene41"));
   }
 }

Modified: lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/util/TestPagedBytes.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/util/TestPagedBytes.java?rev=1402140&r1=1402139&r2=1402140&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/util/TestPagedBytes.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/util/TestPagedBytes.java Thu Oct 25 13:10:25 2012
@@ -31,7 +31,7 @@ public class TestPagedBytes extends Luce
       final int blockSize = 1 << blockBits;
       final PagedBytes p = new PagedBytes(blockBits);
       final DataOutput out = p.getDataOutput();
-      final int numBytes = random().nextInt(10000000);
+      final int numBytes = _TestUtil.nextInt(random(), 2, 10000000);
 
       final byte[] answer = new byte[numBytes];
       random().nextBytes(answer);

Modified: lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/util/TestWeakIdentityMap.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/util/TestWeakIdentityMap.java?rev=1402140&r1=1402139&r2=1402140&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/util/TestWeakIdentityMap.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/util/TestWeakIdentityMap.java Thu Oct 25 13:10:25 2012
@@ -122,13 +122,16 @@ public class TestWeakIdentityMap extends
     for (int i = 0; size > 0 && i < 10; i++) try {
       System.runFinalization();
       System.gc();
+      int newSize = map.size();
+      assertTrue("previousSize("+size+")>=newSize("+newSize+")", size >= newSize);
+      size = newSize;
       Thread.sleep(100L);
       c = 0;
       for (Iterator<String> it = map.keyIterator(); it.hasNext();) {
         assertNotNull(it.next());
         c++;
       }
-      final int newSize = map.size();
+      newSize = map.size();
       assertTrue("previousSize("+size+")>=iteratorSize("+c+")", size >= c);
       assertTrue("iteratorSize("+c+")>=newSize("+newSize+")", c >= newSize);
       size = newSize;
@@ -223,13 +226,16 @@ public class TestWeakIdentityMap extends
     for (int i = 0; size > 0 && i < 10; i++) try {
       System.runFinalization();
       System.gc();
+      int newSize = map.size();
+      assertTrue("previousSize("+size+")>=newSize("+newSize+")", size >= newSize);
+      size = newSize;
       Thread.sleep(100L);
       int c = 0;
       for (Iterator<Object> it = map.keyIterator(); it.hasNext();) {
         assertNotNull(it.next());
         c++;
       }
-      final int newSize = map.size();
+      newSize = map.size();
       assertTrue("previousSize("+size+")>=iteratorSize("+c+")", size >= c);
       assertTrue("iteratorSize("+c+")>=newSize("+newSize+")", c >= newSize);
       size = newSize;

Modified: lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/util/automaton/TestSpecialOperations.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/util/automaton/TestSpecialOperations.java?rev=1402140&r1=1402139&r2=1402140&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/util/automaton/TestSpecialOperations.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/util/automaton/TestSpecialOperations.java Thu Oct 25 13:10:25 2012
@@ -1,6 +1,11 @@
 package org.apache.lucene.util.automaton;
 
+import java.util.Set;
+
+import org.apache.lucene.util.BytesRef;
+import org.apache.lucene.util.IntsRef;
 import org.apache.lucene.util.LuceneTestCase;
+import org.apache.lucene.util.fst.Util;
 
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -31,4 +36,20 @@ public class TestSpecialOperations exten
       assertEquals(AutomatonTestUtil.isFiniteSlow(a), SpecialOperations.isFinite(b));
     }
   }
+  
+  /**
+   * Basic test for getFiniteStrings
+   */
+  public void testFiniteStrings() {
+    Automaton a = BasicOperations.union(BasicAutomata.makeString("dog"), BasicAutomata.makeString("duck"));
+    MinimizationOperations.minimize(a);
+    Set<IntsRef> strings = SpecialOperations.getFiniteStrings(a, -1);
+    assertEquals(2, strings.size());
+    IntsRef dog = new IntsRef();
+    Util.toIntsRef(new BytesRef("dog"), dog);
+    assertTrue(strings.contains(dog));
+    IntsRef duck = new IntsRef();
+    Util.toIntsRef(new BytesRef("duck"), duck);
+    assertTrue(strings.contains(duck));
+  }
 }