blob: 903c44ac05f54891a43f462a0274786463233935 [file] [log] [blame]
using Lucene.Net.Index.Extensions;
using Lucene.Net.Support;
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.IO;
using Assert = Lucene.Net.TestFramework.Assert;
using JCG = J2N.Collections.Generic;
namespace Lucene.Net.Store
{
/*
* 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 Codec = Lucene.Net.Codecs.Codec;
using DirectoryReader = Lucene.Net.Index.DirectoryReader;
using IndexReader = Lucene.Net.Index.IndexReader;
using IndexWriter = Lucene.Net.Index.IndexWriter;
using IndexWriterConfig = Lucene.Net.Index.IndexWriterConfig;
using Lucene40StoredFieldsWriter = Lucene.Net.Codecs.Lucene40.Lucene40StoredFieldsWriter;
using LuceneTestCase = Lucene.Net.Util.LuceneTestCase;
using MockAnalyzer = Lucene.Net.Analysis.MockAnalyzer;
using TestIndexWriterReader = Lucene.Net.Index.TestIndexWriterReader;
[TestFixture]
public class TestFileSwitchDirectory : LuceneTestCase
{
/// <summary>
/// Test if writing doc stores to disk and everything else to ram works.
/// </summary>
[Test]
public virtual void TestBasic()
{
ISet<string> fileExtensions = new JCG.HashSet<string>();
fileExtensions.Add(Lucene40StoredFieldsWriter.FIELDS_EXTENSION);
fileExtensions.Add(Lucene40StoredFieldsWriter.FIELDS_INDEX_EXTENSION);
MockDirectoryWrapper primaryDir = new MockDirectoryWrapper(Random, new RAMDirectory());
primaryDir.CheckIndexOnDispose = false; // only part of an index
MockDirectoryWrapper secondaryDir = new MockDirectoryWrapper(Random, new RAMDirectory());
secondaryDir.CheckIndexOnDispose = false; // only part of an index
FileSwitchDirectory fsd = new FileSwitchDirectory(fileExtensions, primaryDir, secondaryDir, true);
// for now we wire Lucene40Codec because we rely upon its specific impl
bool oldValue = OldFormatImpersonationIsActive;
OldFormatImpersonationIsActive = true;
IndexWriter writer = new IndexWriter(fsd, (new IndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(Random))).SetMergePolicy(NewLogMergePolicy(false)).SetCodec(Codec.ForName("Lucene40")).SetUseCompoundFile(false));
TestIndexWriterReader.CreateIndexNoClose(true, "ram", writer);
IndexReader reader = DirectoryReader.Open(writer, true);
Assert.AreEqual(100, reader.MaxDoc);
writer.Commit();
// we should see only fdx,fdt files here
string[] files = primaryDir.ListAll();
Assert.IsTrue(files.Length > 0);
for (int x = 0; x < files.Length; x++)
{
string ext = FileSwitchDirectory.GetExtension(files[x]);
Assert.IsTrue(fileExtensions.Contains(ext));
}
files = secondaryDir.ListAll();
Assert.IsTrue(files.Length > 0);
// we should not see fdx,fdt files here
for (int x = 0; x < files.Length; x++)
{
string ext = FileSwitchDirectory.GetExtension(files[x]);
Assert.IsFalse(fileExtensions.Contains(ext));
}
reader.Dispose();
writer.Dispose();
files = fsd.ListAll();
for (int i = 0; i < files.Length; i++)
{
Assert.IsNotNull(files[i]);
}
fsd.Dispose();
OldFormatImpersonationIsActive = oldValue;
}
private Directory NewFSSwitchDirectory(ISet<string> primaryExtensions)
{
DirectoryInfo primDir = CreateTempDir("foo");
DirectoryInfo secondDir = CreateTempDir("bar");
return NewFSSwitchDirectory(primDir, secondDir, primaryExtensions);
}
private Directory NewFSSwitchDirectory(DirectoryInfo aDir, DirectoryInfo bDir, ISet<string> primaryExtensions)
{
Directory a = new SimpleFSDirectory(aDir);
Directory b = new SimpleFSDirectory(bDir);
FileSwitchDirectory switchDir = new FileSwitchDirectory(primaryExtensions, a, b, true);
return new MockDirectoryWrapper(Random, switchDir);
}
// LUCENE-3380 -- make sure we get exception if the directory really does not exist.
[Test]
public virtual void TestNoDir()
{
DirectoryInfo primDir = CreateTempDir("foo");
DirectoryInfo secondDir = CreateTempDir("bar");
System.IO.Directory.Delete(primDir.FullName, true);
System.IO.Directory.Delete(secondDir.FullName, true);
using Directory dir = NewFSSwitchDirectory(primDir, secondDir, Collections.EmptySet<string>());
try
{
DirectoryReader.Open(dir);
Assert.Fail("did not hit expected exception");
}
catch (DirectoryNotFoundException)
{
// expected
}
}
private static bool ContainsFile(Directory directory, string file) // LUCENENET specific method to prevent having to use Arrays.AsList(), which creates unnecessary memory allocations
{
return Array.IndexOf(directory.ListAll(), file) > -1;
}
// LUCENE-3380 test that we can add a file, and then when we call list() we get it back
[Test]
public virtual void TestDirectoryFilter()
{
Directory dir = NewFSSwitchDirectory(Collections.EmptySet<string>());
string name = "file";
try
{
dir.CreateOutput(name, NewIOContext(Random)).Dispose();
Assert.IsTrue(SlowFileExists(dir, name));
Assert.IsTrue(ContainsFile(dir, name));
}
finally
{
dir.Dispose();
}
}
// LUCENE-3380 test that delegate compound files correctly.
[Test]
public virtual void TestCompoundFileAppendTwice()
{
Directory newDir = NewFSSwitchDirectory(new JCG.HashSet<string> { "cfs" });
var csw = new CompoundFileDirectory(newDir, "d.cfs", NewIOContext(Random), true);
CreateSequenceFile(newDir, "d1", (sbyte)0, 15);
IndexOutput @out = csw.CreateOutput("d.xyz", NewIOContext(Random));
@out.WriteInt32(0);
@out.Dispose();
Assert.AreEqual(1, csw.ListAll().Length);
Assert.AreEqual("d.xyz", csw.ListAll()[0]);
csw.Dispose();
CompoundFileDirectory cfr = new CompoundFileDirectory(newDir, "d.cfs", NewIOContext(Random), false);
Assert.AreEqual(1, cfr.ListAll().Length);
Assert.AreEqual("d.xyz", cfr.ListAll()[0]);
cfr.Dispose();
newDir.Dispose();
}
/// <summary>
/// Creates a file of the specified size with sequential data. The first
/// byte is written as the start byte provided. All subsequent bytes are
/// computed as start + offset where offset is the number of the byte.
/// </summary>
private void CreateSequenceFile(Directory dir, string name, sbyte start, int size)
{
IndexOutput os = dir.CreateOutput(name, NewIOContext(Random));
for (int i = 0; i < size; i++)
{
os.WriteByte((byte)start);
start++;
}
os.Dispose();
}
}
}