Index: lucene/core/src/test/org/apache/lucene/index/TestCodecs.java =================================================================== --- lucene/core/src/test/org/apache/lucene/index/TestCodecs.java (revision 1519139) +++ lucene/core/src/test/org/apache/lucene/index/TestCodecs.java (working copy) @@ -30,10 +30,14 @@ import org.apache.lucene.codecs.PostingsConsumer; import org.apache.lucene.codecs.TermStats; import org.apache.lucene.codecs.TermsConsumer; +import org.apache.lucene.codecs.lucene40.Lucene40RWCodec; +import org.apache.lucene.codecs.lucene41.Lucene41RWCodec; +import org.apache.lucene.codecs.lucene42.Lucene42RWCodec; import org.apache.lucene.codecs.mocksep.MockSepPostingsFormat; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field.Store; import org.apache.lucene.document.FieldType; +import org.apache.lucene.document.NumericDocValuesField; import org.apache.lucene.document.StringField; import org.apache.lucene.document.TextField; import org.apache.lucene.index.FieldInfo.DocValuesType; @@ -695,4 +699,33 @@ dir.close(); } + + public void testDisableImpersonation() throws Exception { + Codec[] oldCodecs = new Codec[] { new Lucene40RWCodec(), new Lucene41RWCodec(), new Lucene42RWCodec() }; + Directory dir = newDirectory(); + IndexWriterConfig conf = newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random())); + conf.setCodec(oldCodecs[random().nextInt(oldCodecs.length)]); + IndexWriter writer = new IndexWriter(dir, conf); + + Document doc = new Document(); + if (random().nextBoolean()) { // fail on either posting or DV + doc.add(new StringField("f", "bar", Store.YES)); + } else { + doc.add(new NumericDocValuesField("n", 18L)); + } + writer.addDocument(doc); + + OLD_FORMAT_IMPERSONATION_IS_ACTIVE = false; + try { + writer.close(); + fail("should not have succeeded to impersonate an old format!"); + } catch (UnsupportedOperationException e) { + writer.rollback(); + } finally { + OLD_FORMAT_IMPERSONATION_IS_ACTIVE = true; + } + + dir.close(); + } + } Index: lucene/test-framework/src/java/org/apache/lucene/codecs/lucene40/Lucene40RWCodec.java =================================================================== --- lucene/test-framework/src/java/org/apache/lucene/codecs/lucene40/Lucene40RWCodec.java (revision 1519139) +++ lucene/test-framework/src/java/org/apache/lucene/codecs/lucene40/Lucene40RWCodec.java (working copy) @@ -6,6 +6,7 @@ import org.apache.lucene.codecs.FieldInfosFormat; import org.apache.lucene.codecs.FieldInfosWriter; import org.apache.lucene.codecs.NormsFormat; +import org.apache.lucene.util.LuceneTestCase; /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -25,11 +26,17 @@ */ /** Read-write version of Lucene40Codec for testing */ +@SuppressWarnings("deprecation") public final class Lucene40RWCodec extends Lucene40Codec { + private final FieldInfosFormat fieldInfos = new Lucene40FieldInfosFormat() { @Override public FieldInfosWriter getFieldInfosWriter() throws IOException { - return new Lucene40FieldInfosWriter(); + if (!LuceneTestCase.OLD_FORMAT_IMPERSONATION_IS_ACTIVE) { + return super.getFieldInfosWriter(); + } else { + return new Lucene40FieldInfosWriter(); + } } }; Index: lucene/test-framework/src/java/org/apache/lucene/codecs/lucene40/Lucene40RWDocValuesFormat.java =================================================================== --- lucene/test-framework/src/java/org/apache/lucene/codecs/lucene40/Lucene40RWDocValuesFormat.java (revision 1519139) +++ lucene/test-framework/src/java/org/apache/lucene/codecs/lucene40/Lucene40RWDocValuesFormat.java (working copy) @@ -22,15 +22,21 @@ import org.apache.lucene.codecs.DocValuesConsumer; import org.apache.lucene.index.IndexFileNames; import org.apache.lucene.index.SegmentWriteState; +import org.apache.lucene.util.LuceneTestCase; /** Read-write version of {@link Lucene40DocValuesFormat} for testing */ +@SuppressWarnings("deprecation") public class Lucene40RWDocValuesFormat extends Lucene40DocValuesFormat { @Override public DocValuesConsumer fieldsConsumer(SegmentWriteState state) throws IOException { - String filename = IndexFileNames.segmentFileName(state.segmentInfo.name, - "dv", - IndexFileNames.COMPOUND_FILE_EXTENSION); - return new Lucene40DocValuesWriter(state, filename, Lucene40FieldInfosReader.LEGACY_DV_TYPE_KEY); + if (!LuceneTestCase.OLD_FORMAT_IMPERSONATION_IS_ACTIVE) { + return super.fieldsConsumer(state); + } else { + String filename = IndexFileNames.segmentFileName(state.segmentInfo.name, + "dv", + IndexFileNames.COMPOUND_FILE_EXTENSION); + return new Lucene40DocValuesWriter(state, filename, Lucene40FieldInfosReader.LEGACY_DV_TYPE_KEY); + } } } Index: lucene/test-framework/src/java/org/apache/lucene/codecs/lucene40/Lucene40RWNormsFormat.java =================================================================== --- lucene/test-framework/src/java/org/apache/lucene/codecs/lucene40/Lucene40RWNormsFormat.java (revision 1519139) +++ lucene/test-framework/src/java/org/apache/lucene/codecs/lucene40/Lucene40RWNormsFormat.java (working copy) @@ -22,15 +22,21 @@ import org.apache.lucene.codecs.DocValuesConsumer; import org.apache.lucene.index.IndexFileNames; import org.apache.lucene.index.SegmentWriteState; +import org.apache.lucene.util.LuceneTestCase; /** Read-write version of {@link Lucene40NormsFormat} for testing */ +@SuppressWarnings("deprecation") public class Lucene40RWNormsFormat extends Lucene40NormsFormat { @Override public DocValuesConsumer normsConsumer(SegmentWriteState state) throws IOException { - String filename = IndexFileNames.segmentFileName(state.segmentInfo.name, - "nrm", - IndexFileNames.COMPOUND_FILE_EXTENSION); - return new Lucene40DocValuesWriter(state, filename, Lucene40FieldInfosReader.LEGACY_NORM_TYPE_KEY); + if (!LuceneTestCase.OLD_FORMAT_IMPERSONATION_IS_ACTIVE) { + return super.normsConsumer(state); + } else { + String filename = IndexFileNames.segmentFileName(state.segmentInfo.name, + "nrm", + IndexFileNames.COMPOUND_FILE_EXTENSION); + return new Lucene40DocValuesWriter(state, filename, Lucene40FieldInfosReader.LEGACY_NORM_TYPE_KEY); + } } } Index: lucene/test-framework/src/java/org/apache/lucene/codecs/lucene40/Lucene40RWPostingsFormat.java =================================================================== --- lucene/test-framework/src/java/org/apache/lucene/codecs/lucene40/Lucene40RWPostingsFormat.java (revision 1519139) +++ lucene/test-framework/src/java/org/apache/lucene/codecs/lucene40/Lucene40RWPostingsFormat.java (working copy) @@ -6,6 +6,7 @@ import org.apache.lucene.codecs.FieldsConsumer; import org.apache.lucene.codecs.PostingsWriterBase; import org.apache.lucene.index.SegmentWriteState; +import org.apache.lucene.util.LuceneTestCase; /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -27,23 +28,29 @@ /** * Read-write version of {@link Lucene40PostingsFormat} for testing. */ +@SuppressWarnings("deprecation") public class Lucene40RWPostingsFormat extends Lucene40PostingsFormat { + @Override public FieldsConsumer fieldsConsumer(SegmentWriteState state) throws IOException { - PostingsWriterBase docs = new Lucene40PostingsWriter(state); - - // TODO: should we make the terms index more easily - // pluggable? Ie so that this codec would record which - // index impl was used, and switch on loading? - // Or... you must make a new Codec for this? - boolean success = false; - try { - FieldsConsumer ret = new BlockTreeTermsWriter(state, docs, minBlockSize, maxBlockSize); - success = true; - return ret; - } finally { - if (!success) { - docs.close(); + if (!LuceneTestCase.OLD_FORMAT_IMPERSONATION_IS_ACTIVE) { + return super.fieldsConsumer(state); + } else { + PostingsWriterBase docs = new Lucene40PostingsWriter(state); + + // TODO: should we make the terms index more easily + // pluggable? Ie so that this codec would record which + // index impl was used, and switch on loading? + // Or... you must make a new Codec for this? + boolean success = false; + try { + FieldsConsumer ret = new BlockTreeTermsWriter(state, docs, minBlockSize, maxBlockSize); + success = true; + return ret; + } finally { + if (!success) { + docs.close(); + } } } } Index: lucene/test-framework/src/java/org/apache/lucene/codecs/lucene41/Lucene41RWCodec.java =================================================================== --- lucene/test-framework/src/java/org/apache/lucene/codecs/lucene41/Lucene41RWCodec.java (revision 1519139) +++ lucene/test-framework/src/java/org/apache/lucene/codecs/lucene41/Lucene41RWCodec.java (working copy) @@ -11,6 +11,7 @@ import org.apache.lucene.codecs.lucene40.Lucene40FieldInfosWriter; import org.apache.lucene.codecs.lucene40.Lucene40RWDocValuesFormat; import org.apache.lucene.codecs.lucene40.Lucene40RWNormsFormat; +import org.apache.lucene.util.LuceneTestCase; /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -32,12 +33,17 @@ /** * Read-write version of {@link Lucene41Codec} for testing. */ +@SuppressWarnings("deprecation") public class Lucene41RWCodec extends Lucene41Codec { private final StoredFieldsFormat fieldsFormat = new Lucene41StoredFieldsFormat(); private final FieldInfosFormat fieldInfos = new Lucene40FieldInfosFormat() { @Override public FieldInfosWriter getFieldInfosWriter() throws IOException { - return new Lucene40FieldInfosWriter(); + if (!LuceneTestCase.OLD_FORMAT_IMPERSONATION_IS_ACTIVE) { + return super.getFieldInfosWriter(); + } else { + return new Lucene40FieldInfosWriter(); + } } }; Index: lucene/test-framework/src/java/org/apache/lucene/codecs/lucene42/Lucene42RWDocValuesFormat.java =================================================================== --- lucene/test-framework/src/java/org/apache/lucene/codecs/lucene42/Lucene42RWDocValuesFormat.java (revision 1519139) +++ lucene/test-framework/src/java/org/apache/lucene/codecs/lucene42/Lucene42RWDocValuesFormat.java (working copy) @@ -21,15 +21,21 @@ import org.apache.lucene.codecs.DocValuesConsumer; import org.apache.lucene.index.SegmentWriteState; +import org.apache.lucene.util.LuceneTestCase; /** * Read-write version of {@link Lucene42DocValuesFormat} for testing. */ +@SuppressWarnings("deprecation") public class Lucene42RWDocValuesFormat extends Lucene42DocValuesFormat { @Override public DocValuesConsumer fieldsConsumer(SegmentWriteState state) throws IOException { - // note: we choose DEFAULT here (its reasonably fast, and for small bpv has tiny waste) - return new Lucene42DocValuesConsumer(state, DATA_CODEC, DATA_EXTENSION, METADATA_CODEC, METADATA_EXTENSION, acceptableOverheadRatio); + if (!LuceneTestCase.OLD_FORMAT_IMPERSONATION_IS_ACTIVE) { + return super.fieldsConsumer(state); + } else { + // note: we choose DEFAULT here (its reasonably fast, and for small bpv has tiny waste) + return new Lucene42DocValuesConsumer(state, DATA_CODEC, DATA_EXTENSION, METADATA_CODEC, METADATA_EXTENSION, acceptableOverheadRatio); + } } } Index: lucene/test-framework/src/java/org/apache/lucene/util/LuceneTestCase.java =================================================================== --- lucene/test-framework/src/java/org/apache/lucene/util/LuceneTestCase.java (revision 1519139) +++ lucene/test-framework/src/java/org/apache/lucene/util/LuceneTestCase.java (working copy) @@ -332,9 +332,13 @@ // ----------------------------------------------------------------- /** - * @lucene.internal + * When {@code true}, Codecs for old Lucene version will support writing + * indexes in that format. Defaults to {@code true}, can be disabled by + * spdecific tests on demand. + * + * @lucene.internal */ - public static boolean PREFLEX_IMPERSONATION_IS_ACTIVE; + public static boolean OLD_FORMAT_IMPERSONATION_IS_ACTIVE = true; // -----------------------------------------------------------------