+++ /dev/null
-package org.apache.lucene.index;
-
-/**
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import java.io.IOException;
-
-import org.apache.lucene.analysis.MockAnalyzer;
-import org.apache.lucene.document.Document;
-import org.apache.lucene.document.Field;
-import org.apache.lucene.search.DefaultSimilarity;
-import org.apache.lucene.search.IndexSearcher;
-import org.apache.lucene.search.ScoreDoc;
-import org.apache.lucene.search.Similarity;
-import org.apache.lucene.search.TermQuery;
-import org.apache.lucene.store.MockDirectoryWrapper;
-import org.apache.lucene.store.RAMDirectory;
-import org.apache.lucene.util.LuceneTestCase;
-import org.apache.lucene.util._TestUtil;
-
-public class TestIndexReaderOnDiskFull extends LuceneTestCase {
- /**
- * Make sure if reader tries to commit but hits disk
- * full that reader remains consistent and usable.
- */
- public void testDiskFull() throws IOException {
-
- Term searchTerm = new Term("content", "aaa");
- int START_COUNT = 157;
- int END_COUNT = 144;
-
- // First build up a starting index:
- MockDirectoryWrapper startDir = newDirectory();
- IndexWriter writer = new IndexWriter(startDir, newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random)));
- if (VERBOSE) {
- System.out.println("TEST: create initial index");
- writer.setInfoStream(System.out);
- }
- for(int i=0;i<157;i++) {
- Document d = new Document();
- d.add(newField("id", Integer.toString(i), Field.Store.YES, Field.Index.NOT_ANALYZED));
- d.add(newField("content", "aaa " + i, Field.Store.NO, Field.Index.ANALYZED));
- writer.addDocument(d);
- if (0==i%10)
- writer.commit();
- }
- writer.close();
-
- {
- IndexReader r = IndexReader.open(startDir);
- IndexSearcher searcher = newSearcher(r);
- ScoreDoc[] hits = null;
- try {
- hits = searcher.search(new TermQuery(searchTerm), null, 1000).scoreDocs;
- } catch (IOException e) {
- e.printStackTrace();
- fail("exception when init searching: " + e);
- }
- searcher.close();
- r.close();
- }
-
- long diskUsage = startDir.getRecomputedActualSizeInBytes();
- long diskFree = diskUsage+_TestUtil.nextInt(random, 50, 200);
-
- IOException err = null;
-
- boolean done = false;
- boolean gotExc = false;
-
- // Iterate w/ ever increasing free disk space:
- while(!done) {
- MockDirectoryWrapper dir = new MockDirectoryWrapper(random, new RAMDirectory(startDir));
-
- // If IndexReader hits disk full, it can write to
- // the same files again.
- dir.setPreventDoubleWrite(false);
-
- IndexReader reader = IndexReader.open(dir, false);
-
- // For each disk size, first try to commit against
- // dir that will hit random IOExceptions & disk
- // full; after, give it infinite disk space & turn
- // off random IOExceptions & retry w/ same reader:
- boolean success = false;
-
- for(int x=0;x<2;x++) {
-
- double rate = 0.05;
- double diskRatio = ((double) diskFree)/diskUsage;
- long thisDiskFree;
- String testName;
-
- if (0 == x) {
- thisDiskFree = diskFree;
- if (diskRatio >= 2.0) {
- rate /= 2;
- }
- if (diskRatio >= 4.0) {
- rate /= 2;
- }
- if (diskRatio >= 6.0) {
- rate = 0.0;
- }
- if (VERBOSE) {
- System.out.println("\ncycle: " + diskFree + " bytes");
- }
- testName = "disk full during reader.close() @ " + thisDiskFree + " bytes";
- } else {
- thisDiskFree = 0;
- rate = 0.0;
- if (VERBOSE) {
- System.out.println("\ncycle: same writer: unlimited disk space");
- }
- testName = "reader re-use after disk full";
- }
-
- dir.setMaxSizeInBytes(thisDiskFree);
- dir.setRandomIOExceptionRate(rate);
- Similarity sim = new DefaultSimilarity();
- try {
- if (0 == x) {
- int docId = 12;
- for(int i=0;i<13;i++) {
- reader.deleteDocument(docId);
- reader.setNorm(docId, "content", sim.encodeNormValue(2.0f));
- docId += 12;
- }
- }
- reader.close();
- success = true;
- if (0 == x) {
- done = true;
- }
- } catch (IOException e) {
- if (VERBOSE) {
- System.out.println(" hit IOException: " + e);
- e.printStackTrace(System.out);
- }
- err = e;
- gotExc = true;
- if (1 == x) {
- e.printStackTrace();
- fail(testName + " hit IOException after disk space was freed up");
- }
- }
-
- // Finally, verify index is not corrupt, and, if
- // we succeeded, we see all docs changed, and if
- // we failed, we see either all docs or no docs
- // changed (transactional semantics):
- IndexReader newReader = null;
- try {
- newReader = IndexReader.open(dir, false);
- } catch (IOException e) {
- e.printStackTrace();
- fail(testName + ":exception when creating IndexReader after disk full during close: " + e);
- }
- /*
- int result = newReader.docFreq(searchTerm);
- if (success) {
- if (result != END_COUNT) {
- fail(testName + ": method did not throw exception but docFreq('aaa') is " + result + " instead of expected " + END_COUNT);
- }
- } else {
- // On hitting exception we still may have added
- // all docs:
- if (result != START_COUNT && result != END_COUNT) {
- err.printStackTrace();
- fail(testName + ": method did throw exception but docFreq('aaa') is " + result + " instead of expected " + START_COUNT + " or " + END_COUNT);
- }
- }
- */
-
- IndexSearcher searcher = newSearcher(newReader);
- ScoreDoc[] hits = null;
- try {
- hits = searcher.search(new TermQuery(searchTerm), null, 1000).scoreDocs;
- } catch (IOException e) {
- e.printStackTrace();
- fail(testName + ": exception when searching: " + e);
- }
- int result2 = hits.length;
- if (success) {
- if (result2 != END_COUNT) {
- fail(testName + ": method did not throw exception but hits.length for search on term 'aaa' is " + result2 + " instead of expected " + END_COUNT);
- }
- } else {
- // On hitting exception we still may have added
- // all docs:
- if (result2 != START_COUNT && result2 != END_COUNT) {
- err.printStackTrace();
- fail(testName + ": method did throw exception but hits.length for search on term 'aaa' is " + result2 + " instead of expected " + START_COUNT);
- }
- }
-
- searcher.close();
- newReader.close();
-
- if (result2 == END_COUNT) {
- if (!gotExc)
- fail("never hit disk full");
- break;
- }
- }
-
- dir.close();
-
- // Try again with more bytes of free space:
- diskFree += TEST_NIGHTLY ? _TestUtil.nextInt(random, 5, 20) : _TestUtil.nextInt(random, 50, 200);
- }
-
- startDir.close();
- }
-}