blob: 9124b123afc0b86a75f7aabb1a0883ca84c567dd [file] [log] [blame]
/*
* 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.
*/
using System;
using NUnit.Framework;
using Document = Lucene.Net.Documents.Document;
using Field = Lucene.Net.Documents.Field;
using Directory = Lucene.Net.Store.Directory;
using FSDirectory = Lucene.Net.Store.FSDirectory;
using WhitespaceAnalyzer = Lucene.Net.Analysis.WhitespaceAnalyzer;
using Hits = Lucene.Net.Search.Hits;
using IndexSearcher = Lucene.Net.Search.IndexSearcher;
using TermQuery = Lucene.Net.Search.TermQuery;
using LuceneTestCase = Lucene.Net.Util.LuceneTestCase;
namespace Lucene.Net.Index
{
/*
Verify we can read the pre-2.1 file format, do searches
against it, and add documents to it.*/
[TestFixture]
public class TestBackwardsCompatibility : LuceneTestCase
{
// Uncomment these cases & run in a pre-lockless checkout
// to create indices:
/*
public void testCreatePreLocklessCFS() throws IOException {
CreateIndex("src/test/org/apache/lucene/index/index.prelockless.cfs", true);
}
public void testCreatePreLocklessNoCFS() throws IOException {
CreateIndex("src/test/org/apache/lucene/index/index.prelockless.nocfs", false);
}
*/
/* Unzips dirName + ".zip" --> dirName, removing dirName
first */
public virtual void Unzip(System.String zipName, System.String destDirName)
{
#if SHARP_ZIP_LIB
// get zip input stream
ICSharpCode.SharpZipLib.Zip.ZipInputStream zipFile;
zipFile = new ICSharpCode.SharpZipLib.Zip.ZipInputStream(System.IO.File.OpenRead(zipName + ".zip"));
// get dest directory name
System.String dirName = FullDir(destDirName);
System.IO.FileInfo fileDir = new System.IO.FileInfo(dirName);
// clean up old directory (if there) and create new directory
RmDir(fileDir.FullName);
System.IO.Directory.CreateDirectory(fileDir.FullName);
// copy file entries from zip stream to directory
ICSharpCode.SharpZipLib.Zip.ZipEntry entry;
while ((entry = zipFile.GetNextEntry()) != null)
{
System.IO.Stream streamout = new System.IO.BufferedStream(new System.IO.FileStream(new System.IO.FileInfo(System.IO.Path.Combine(fileDir.FullName, entry.Name)).FullName, System.IO.FileMode.Create));
byte[] buffer = new byte[8192];
int len;
while ((len = zipFile.Read(buffer, 0, buffer.Length)) > 0)
{
streamout.Write(buffer, 0, len);
}
streamout.Close();
}
zipFile.Close();
#else
Assert.Fail("Needs integration with SharpZipLib");
#endif
}
[Test]
public virtual void TestCreateCFS()
{
System.String dirName = "testindex.cfs";
CreateIndex(dirName, true);
RmDir(dirName);
}
[Test]
public virtual void TestCreateNoCFS()
{
System.String dirName = "testindex.nocfs";
CreateIndex(dirName, true);
RmDir(dirName);
}
internal System.String[] oldNames = new System.String[]{"prelockless.cfs", "prelockless.nocfs", "presharedstores.cfs", "presharedstores.nocfs"};
[Test]
public virtual void TestSearchOldIndex()
{
for (int i = 0; i < oldNames.Length; i++)
{
System.String dirName = @"Index\index." + oldNames[i];
Unzip(dirName, oldNames[i]);
SearchIndex(oldNames[i]);
RmDir(oldNames[i]);
}
}
[Test]
public virtual void TestIndexOldIndexNoAdds()
{
for (int i = 0; i < oldNames.Length; i++)
{
System.String dirName = @"Index\index." + oldNames[i];
Unzip(dirName, oldNames[i]);
ChangeIndexNoAdds(oldNames[i], true);
RmDir(oldNames[i]);
Unzip(dirName, oldNames[i]);
ChangeIndexNoAdds(oldNames[i], false);
RmDir(oldNames[i]);
}
}
[Test]
public virtual void TestIndexOldIndex()
{
for (int i = 0; i < oldNames.Length; i++)
{
System.String dirName = @"Index\index." + oldNames[i];
Unzip(dirName, oldNames[i]);
ChangeIndexWithAdds(oldNames[i], true);
RmDir(oldNames[i]);
Unzip(dirName, oldNames[i]);
ChangeIndexWithAdds(oldNames[i], false);
RmDir(oldNames[i]);
}
}
public virtual void SearchIndex(System.String dirName)
{
//QueryParser parser = new QueryParser("contents", new WhitespaceAnalyzer());
//Query query = parser.parse("handle:1");
dirName = FullDir(dirName);
Directory dir = FSDirectory.GetDirectory(dirName);
IndexSearcher searcher = new IndexSearcher(dir);
Hits hits = searcher.Search(new TermQuery(new Term("content", "aaa")));
Assert.AreEqual(34, hits.Length());
Document d = hits.Doc(0);
// First document should be #21 since it's norm was increased:
Assert.AreEqual("21", d.Get("id"), "didn't get the right document first");
searcher.Close();
dir.Close();
}
/* Open pre-lockless index, add docs, do a delete &
* setNorm, and search */
public virtual void ChangeIndexWithAdds(System.String dirName, bool autoCommit)
{
dirName = FullDir(dirName);
Directory dir = FSDirectory.GetDirectory(dirName);
// open writer
IndexWriter writer = new IndexWriter(dir, autoCommit, new WhitespaceAnalyzer(), false);
// add 10 docs
for (int i = 0; i < 10; i++)
{
AddDoc(writer, 35 + i);
}
// make sure writer sees right total -- writer seems not to know about deletes in .del?
Assert.AreEqual(45, writer.DocCount(), "wrong doc count");
writer.Close();
// make sure searching sees right # hits
IndexSearcher searcher = new IndexSearcher(dir);
Hits hits = searcher.Search(new TermQuery(new Term("content", "aaa")));
Assert.AreEqual(44, hits.Length(), "wrong number of hits");
Document d = hits.Doc(0);
Assert.AreEqual("21", d.Get("id"), "wrong first document");
searcher.Close();
// make sure we can do delete & setNorm against this
// pre-lockless segment:
IndexReader reader = IndexReader.Open(dir);
Term searchTerm = new Term("id", "6");
int delCount = reader.DeleteDocuments(searchTerm);
Assert.AreEqual(1, delCount, "wrong delete count");
reader.SetNorm(22, "content", (float) 2.0);
reader.Close();
// make sure they "took":
searcher = new IndexSearcher(dir);
hits = searcher.Search(new TermQuery(new Term("content", "aaa")));
Assert.AreEqual(43, hits.Length(), "wrong number of hits");
d = hits.Doc(0);
Assert.AreEqual("22", d.Get("id"), "wrong first document");
searcher.Close();
// optimize
writer = new IndexWriter(dir, autoCommit, new WhitespaceAnalyzer(), false);
writer.Optimize();
writer.Close();
searcher = new IndexSearcher(dir);
hits = searcher.Search(new TermQuery(new Term("content", "aaa")));
Assert.AreEqual(43, hits.Length(), "wrong number of hits");
d = hits.Doc(0);
Assert.AreEqual("22", d.Get("id"), "wrong first document");
searcher.Close();
dir.Close();
}
/* Open pre-lockless index, add docs, do a delete &
* setNorm, and search */
public virtual void ChangeIndexNoAdds(System.String dirName, bool autoCommit)
{
dirName = FullDir(dirName);
Directory dir = FSDirectory.GetDirectory(dirName);
// make sure searching sees right # hits
IndexSearcher searcher = new IndexSearcher(dir);
Hits hits = searcher.Search(new TermQuery(new Term("content", "aaa")));
Assert.AreEqual(34, hits.Length(), "wrong number of hits");
Document d = hits.Doc(0);
Assert.AreEqual("21", d.Get("id"), "wrong first document");
searcher.Close();
// make sure we can do a delete & setNorm against this
// pre-lockless segment:
IndexReader reader = IndexReader.Open(dir);
Term searchTerm = new Term("id", "6");
int delCount = reader.DeleteDocuments(searchTerm);
Assert.AreEqual(1, delCount, "wrong delete count");
reader.SetNorm(22, "content", (float) 2.0);
reader.Close();
// make sure they "took":
searcher = new IndexSearcher(dir);
hits = searcher.Search(new TermQuery(new Term("content", "aaa")));
Assert.AreEqual(33, hits.Length(), "wrong number of hits");
d = hits.Doc(0);
Assert.AreEqual("22", d.Get("id"), "wrong first document");
searcher.Close();
// optimize
IndexWriter writer = new IndexWriter(dir, autoCommit, new WhitespaceAnalyzer(), false);
writer.Optimize();
writer.Close();
searcher = new IndexSearcher(dir);
hits = searcher.Search(new TermQuery(new Term("content", "aaa")));
Assert.AreEqual(33, hits.Length(), "wrong number of hits");
d = hits.Doc(0);
Assert.AreEqual("22", d.Get("id"), "wrong first document");
searcher.Close();
dir.Close();
}
public virtual void CreateIndex(System.String dirName, bool doCFS)
{
RmDir(dirName);
dirName = FullDir(dirName);
Directory dir = FSDirectory.GetDirectory(dirName);
IndexWriter writer = new IndexWriter(dir, new WhitespaceAnalyzer(), true);
writer.SetUseCompoundFile(doCFS);
for (int i = 0; i < 35; i++)
{
AddDoc(writer, i);
}
Assert.AreEqual(35, writer.DocCount(), "wrong doc count");
writer.Close();
// Delete one doc so we get a .del file:
IndexReader reader = IndexReader.Open(dir);
Term searchTerm = new Term("id", "7");
int delCount = reader.DeleteDocuments(searchTerm);
Assert.AreEqual(1, delCount, "didn't delete the right number of documents");
// Set one norm so we get a .s0 file:
reader.SetNorm(21, "content", (float) 1.5);
reader.Close();
}
/* Verifies that the expected file names were produced */
[Test]
public virtual void TestExactFileNames()
{
for (int pass = 0; pass < 2; pass++)
{
System.String outputDir = "lucene.backwardscompat0.index";
RmDir(outputDir);
try
{
Directory dir = FSDirectory.GetDirectory(FullDir(outputDir));
bool autoCommit = 0 == pass;
IndexWriter writer = new IndexWriter(dir, autoCommit, new WhitespaceAnalyzer(), true);
writer.SetRAMBufferSizeMB(16.0);
//IndexWriter writer = new IndexWriter(dir, new WhitespaceAnalyzer(), true);
for (int i = 0; i < 35; i++)
{
AddDoc(writer, i);
}
Assert.AreEqual(35, writer.DocCount());
writer.Close();
// Delete one doc so we get a .del file:
IndexReader reader = IndexReader.Open(dir);
Term searchTerm = new Term("id", "7");
int delCount = reader.DeleteDocuments(searchTerm);
Assert.AreEqual(1, delCount, "didn't delete the right number of documents");
// Set one norm so we get a .s0 file:
reader.SetNorm(21, "content", (float) 1.5);
reader.Close();
// The numbering of fields can vary depending on which
// JRE is in use. On some JREs we see content bound to
// field 0; on others, field 1. So, here we have to
// figure out which field number corresponds to
// "content", and then set our expected file names below
// accordingly:
CompoundFileReader cfsReader = new CompoundFileReader(dir, "_0.cfs");
FieldInfos fieldInfos = new FieldInfos(cfsReader, "_0.fnm");
int contentFieldIndex = - 1;
for (int i = 0; i < fieldInfos.Size(); i++)
{
FieldInfo fi = fieldInfos.FieldInfo(i);
if (fi.Name_ForNUnitTest.Equals("content"))
{
contentFieldIndex = i;
break;
}
}
cfsReader.Close();
Assert.IsTrue(contentFieldIndex != - 1, "could not locate the 'content' field number in the _2.cfs segment");
// Now verify file names:
System.String[] expected;
expected = new System.String[]{"_0.cfs", "_0_1.del", "_0_1.s" + contentFieldIndex, "segments_4", "segments.gen"};
if (!autoCommit)
expected[3] = "segments_3";
System.String[] actual = dir.List();
System.Array.Sort(expected);
System.Array.Sort(actual);
if (!ArrayEquals(expected, actual))
{
Assert.Fail("incorrect filenames in index: expected:\n " + AsString(expected) + "\n actual:\n " + AsString(actual));
}
dir.Close();
}
finally
{
RmDir(outputDir);
}
}
}
private System.String AsString(System.String[] l)
{
System.String s = "";
for (int i = 0; i < l.Length; i++)
{
if (i > 0)
{
s += "\n ";
}
s += l[i];
}
return s;
}
private void AddDoc(IndexWriter writer, int id)
{
Lucene.Net.Documents.Document doc = new Lucene.Net.Documents.Document();
doc.Add(new Field("content", "aaa", Field.Store.NO, Field.Index.TOKENIZED));
doc.Add(new Field("id", System.Convert.ToString(id), Field.Store.YES, Field.Index.UN_TOKENIZED));
writer.AddDocument(doc);
}
private void RmDir(System.String dir)
{
System.IO.FileInfo fileDir = new System.IO.FileInfo(FullDir(dir));
bool tmpBool;
if (System.IO.File.Exists(fileDir.FullName))
tmpBool = true;
else
tmpBool = System.IO.Directory.Exists(fileDir.FullName);
if (tmpBool)
{
System.String[] files = System.IO.Directory.GetFileSystemEntries(fileDir.FullName);
if (files != null)
{
for (int i = 0; i < files.Length; i++)
{
bool tmpBool2;
if (System.IO.File.Exists(files[i]))
{
System.IO.File.Delete(files[i]);
tmpBool2 = true;
}
else if (System.IO.Directory.Exists(files[i]))
{
System.IO.Directory.Delete(files[i]);
tmpBool2 = true;
}
else
tmpBool2 = false;
bool generatedAux = tmpBool2;
}
}
bool tmpBool3;
if (System.IO.File.Exists(fileDir.FullName))
{
System.IO.File.Delete(fileDir.FullName);
tmpBool3 = true;
}
else if (System.IO.Directory.Exists(fileDir.FullName))
{
System.IO.Directory.Delete(fileDir.FullName);
tmpBool3 = true;
}
else
tmpBool3 = false;
bool generatedAux2 = tmpBool3;
}
}
public static System.String FullDir(System.String dirName)
{
return new System.IO.FileInfo(System.IO.Path.Combine(SupportClass.AppSettings.Get("tempDir", ""), dirName)).FullName;
}
public static bool ArrayEquals(System.Array array1, System.Array array2)
{
bool result = false;
if ((array1 == null) && (array2 == null))
result = true;
else if ((array1 != null) && (array2 != null))
{
if (array1.Length == array2.Length)
{
int length = array1.Length;
result = true;
for (int index = 0; index < length; index++)
{
if (!(array1.GetValue(index).Equals(array2.GetValue(index))))
{
result = false;
break;
}
}
}
}
return result;
}
}
}