diff --git a/lucene/replicator/src/test/org/apache/lucene/replicator/IndexAndTaxonomyReplicationClientTest.java b/lucene/replicator/src/test/org/apache/lucene/replicator/IndexAndTaxonomyReplicationClientTest.java index 3ae2719db8a..12ef20aacf7 100644 --- a/lucene/replicator/src/test/org/apache/lucene/replicator/IndexAndTaxonomyReplicationClientTest.java +++ b/lucene/replicator/src/test/org/apache/lucene/replicator/IndexAndTaxonomyReplicationClientTest.java @@ -17,11 +17,14 @@ package org.apache.lucene.replicator; * limitations under the License. */ +import java.io.ByteArrayOutputStream; import java.io.Closeable; import java.io.File; import java.io.IOException; +import java.io.PrintStream; import java.util.HashMap; import java.util.concurrent.Callable; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import org.apache.lucene.document.Document; @@ -35,9 +38,11 @@ import org.apache.lucene.facet.taxonomy.TaxonomyReader; import org.apache.lucene.facet.taxonomy.TaxonomyWriter; import org.apache.lucene.facet.taxonomy.directory.DirectoryTaxonomyReader; import org.apache.lucene.facet.taxonomy.directory.DirectoryTaxonomyWriter; +import org.apache.lucene.index.CheckIndex; import org.apache.lucene.index.DirectoryReader; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexWriterConfig; +import org.apache.lucene.index.SegmentInfos; import org.apache.lucene.index.SnapshotDeletionPolicy; import org.apache.lucene.replicator.IndexAndTaxonomyRevision.SnapshotDirectoryTaxonomyWriter; import org.apache.lucene.replicator.ReplicationClient.ReplicationHandler; @@ -180,7 +185,7 @@ public class IndexAndTaxonomyReplicationClientTest extends ReplicatorTestCase { private Document newDocument(TaxonomyWriter taxoWriter, int id) throws IOException { Document doc = new Document(); doc.add(new FacetField("A", Integer.toString(id, 16))); - return config.build(publishTaxoWriter, doc); + return config.build(taxoWriter, doc); } @Override @@ -378,6 +383,8 @@ public class IndexAndTaxonomyReplicationClientTest extends ReplicatorTestCase { } }); + final AtomicBoolean failed = new AtomicBoolean(); + // wrap handleUpdateException so we can act on the thrown exception client = new ReplicationClient(replicator, handler, sourceDirFactory) { @SuppressWarnings("synthetic-access") @@ -403,10 +410,42 @@ public class IndexAndTaxonomyReplicationClientTest extends ReplicatorTestCase { TestUtil.checkIndex(handlerIndexDir.getDelegate()); // verify taxonomy index is fully consistent (since we only add one - // category to all documents, there's nothing much more to validate - TestUtil.checkIndex(handlerTaxoDir.getDelegate()); + // category to all documents, there's nothing much more to validate. + ByteArrayOutputStream bos = new ByteArrayOutputStream(1024); + CheckIndex checker = new CheckIndex(handlerTaxoDir.getDelegate()); + checker.setFailFast(true); + checker.setInfoStream(new PrintStream(bos, false, IOUtils.UTF_8), false); + CheckIndex.Status indexStatus = null; + try { + indexStatus = checker.checkIndex(null); + } catch (IOException ioe) { + // ok: we fallback below + } catch (RuntimeException re) { + // ok: we fallback below + } + + if (indexStatus == null || indexStatus.clean == false) { + + // Because segments file for taxo index is replicated after + // main index's segments file, if there's an error while replicating + // main index's segments file and if virus checker prevents + // deletion of taxo index's segments file, it can look like corruption. + // But it should be "false" meaning if we remove the latest segments + // file then the index is intact. It's like pulling a hideous + // looking rock out of the ground, but then you pull the cruft + // off the outside of it and discover it's actually a beautiful + // diamond: + String segmentsFileName = SegmentInfos.getLastCommitSegmentsFileName(handlerTaxoDir); + assertTrue(handlerTaxoDir.didTryToDelete(segmentsFileName)); + handlerTaxoDir.getDelegate().deleteFile(segmentsFileName); + TestUtil.checkIndex(handlerTaxoDir.getDelegate()); + } } catch (IOException e) { + failed.set(true); throw new RuntimeException(e); + } catch (RuntimeException e) { + failed.set(true); + throw e; } finally { // count-down number of failures failures.decrementAndGet(); @@ -420,7 +459,10 @@ public class IndexAndTaxonomyReplicationClientTest extends ReplicatorTestCase { } } } else { - if (t instanceof RuntimeException) throw (RuntimeException) t; + failed.set(true); + if (t instanceof RuntimeException) { + throw (RuntimeException) t; + } throw new RuntimeException(t); } } @@ -430,7 +472,7 @@ public class IndexAndTaxonomyReplicationClientTest extends ReplicatorTestCase { final Directory baseHandlerIndexDir = handlerIndexDir.getDelegate(); int numRevisions = atLeast(20) + 2; - for (int i = 2; i < numRevisions; i++) { + for (int i = 2; i < numRevisions && failed.get() == false; i++) { replicator.publish(createRevision(i)); assertHandlerRevision(i, baseHandlerIndexDir); }