public void Crash()
{
lock (this)
{
Crashed = true;
OpenFiles = new Dictionary<string, int>();
OpenFilesForWrite = new HashSet<string>();
OpenFilesDeleted = new HashSet<string>();
IEnumerator<string> it = UnSyncedFiles.GetEnumerator();
UnSyncedFiles = new HashSet<string>();
// first force-close all files, so we can corrupt on windows etc.
// clone the file map, as these guys want to remove themselves on close.
IDictionary<IDisposable, Exception> m = new HashMap<IDisposable, Exception>(OpenFileHandles);
foreach (IDisposable f in m.Keys)
{
try
{
f.Dispose();
}
catch (Exception)
{
}
}
while (it.MoveNext())
{
string name = it.Current;
int damage = RandomState.Next(5);
string action = null;
if (damage == 0)
{
action = "deleted";
DeleteFile(name, true);
}
else if (damage == 1)
{
action = "zeroed";
// Zero out file entirely
long length = FileLength(name);
var zeroes = new byte[256]; // LUCENENET TODO: Don't we want to fill the array before writing from it?
long upto = 0;
IndexOutput @out = @in.CreateOutput(name, LuceneTestCase.NewIOContext(RandomState));
while (upto < length)
{
var limit = (int)Math.Min(length - upto, zeroes.Length);
@out.WriteBytes(zeroes, 0, limit);
upto += limit;
}
@out.Dispose();
}
else if (damage == 2)
{
action = "partially truncated";
// Partially Truncate the file:
// First, make temp file and copy only half this
// file over:
string tempFileName;
while (true)
{
tempFileName = "" + RandomState.Next();
if (!LuceneTestCase.SlowFileExists(@in, tempFileName))
{
break;
}
}
IndexOutput tempOut = @in.CreateOutput(tempFileName, LuceneTestCase.NewIOContext(RandomState));
IndexInput ii = @in.OpenInput(name, LuceneTestCase.NewIOContext(RandomState));
tempOut.CopyBytes(ii, ii.Length() / 2);
tempOut.Dispose();
ii.Dispose();
// Delete original and copy bytes back:
DeleteFile(name, true);
IndexOutput @out = @in.CreateOutput(name, LuceneTestCase.NewIOContext(RandomState));
ii = @in.OpenInput(tempFileName, LuceneTestCase.NewIOContext(RandomState));
@out.CopyBytes(ii, ii.Length());
@out.Dispose();
ii.Dispose();
DeleteFile(tempFileName, true);
}
else if (damage == 3)
{
// The file survived intact:
action = "didn't change";
}
else
{
action = "fully truncated";
// Totally truncate the file to zero bytes
DeleteFile(name, true);
IndexOutput @out = @in.CreateOutput(name, LuceneTestCase.NewIOContext(RandomState));
@out.Length = 0;
@out.Dispose();
}
if (LuceneTestCase.VERBOSE)
{
Console.WriteLine("MockDirectoryWrapper: " + action + " unsynced file: " + name);
}
}
}
}