public virtual void TestRandom()
{
int iters = AtLeast(10);
for (int iter = 0; iter < iters; iter++)
{
int numBytes = TestUtil.NextInt32(Random, 1, 200000);
byte[] expected = new byte[numBytes];
int blockBits = TestUtil.NextInt32(Random, 8, 15);
BytesStore bytes = new BytesStore(blockBits);
if (VERBOSE)
{
Console.WriteLine("TEST: iter=" + iter + " numBytes=" + numBytes + " blockBits=" + blockBits);
}
int pos = 0;
while (pos < numBytes)
{
int op = Random.Next(8);
if (VERBOSE)
{
Console.WriteLine(" cycle pos=" + pos);
}
switch (op)
{
case 0:
{
// write random byte
byte b = (byte)Random.Next(256);
if (VERBOSE)
{
Console.WriteLine(" writeByte b=" + b);
}
expected[pos++] = b;
bytes.WriteByte(b);
}
break;
case 1:
{
// write random byte[]
int len = Random.Next(Math.Min(numBytes - pos, 100));
byte[] temp = new byte[len];
Random.NextBytes(temp);
if (VERBOSE)
{
Console.WriteLine(" writeBytes len=" + len + " bytes=" + Arrays.ToString(temp));
}
Array.Copy(temp, 0, expected, pos, temp.Length);
bytes.WriteBytes(temp, 0, temp.Length);
pos += len;
}
break;
case 2:
{
// write int @ absolute pos
if (pos > 4)
{
int x = Random.Next();
int randomPos = Random.Next(pos - 4);
if (VERBOSE)
{
Console.WriteLine(" abs writeInt pos=" + randomPos + " x=" + x);
}
bytes.WriteInt32(randomPos, x);
expected[randomPos++] = (byte)(x >> 24);
expected[randomPos++] = (byte)(x >> 16);
expected[randomPos++] = (byte)(x >> 8);
expected[randomPos++] = (byte)x;
}
}
break;
case 3:
{
// reverse bytes
if (pos > 1)
{
int len = TestUtil.NextInt32(Random, 2, Math.Min(100, pos));
int start;
if (len == pos)
{
start = 0;
}
else
{
start = Random.Next(pos - len);
}
int end = start + len - 1;
if (VERBOSE)
{
Console.WriteLine(" reverse start=" + start + " end=" + end + " len=" + len + " pos=" + pos);
}
bytes.Reverse(start, end);
while (start <= end)
{
byte b = expected[end];
expected[end] = expected[start];
expected[start] = b;
start++;
end--;
}
}
}
break;
case 4:
{
// abs write random byte[]
if (pos > 2)
{
int randomPos = Random.Next(pos - 1);
int len = TestUtil.NextInt32(Random, 1, Math.Min(pos - randomPos - 1, 100));
byte[] temp = new byte[len];
Random.NextBytes(temp);
if (VERBOSE)
{
Console.WriteLine(" abs writeBytes pos=" + randomPos + " len=" + len + " bytes=" + Arrays.ToString(temp));
}
Array.Copy(temp, 0, expected, randomPos, temp.Length);
bytes.WriteBytes(randomPos, temp, 0, temp.Length);
}
}
break;
case 5:
{
// copyBytes
if (pos > 1)
{
int src = Random.Next(pos - 1);
int dest = TestUtil.NextInt32(Random, src + 1, pos - 1);
int len = TestUtil.NextInt32(Random, 1, Math.Min(300, pos - dest));
if (VERBOSE)
{
Console.WriteLine(" copyBytes src=" + src + " dest=" + dest + " len=" + len);
}
Array.Copy(expected, src, expected, dest, len);
bytes.CopyBytes(src, dest, len);
}
}
break;
case 6:
{
// skip
int len = Random.Next(Math.Min(100, numBytes - pos));
if (VERBOSE)
{
Console.WriteLine(" skip len=" + len);
}
pos += len;
bytes.SkipBytes(len);
// NOTE: must fill in zeros in case truncate was
// used, else we get false fails:
if (len > 0)
{
byte[] zeros = new byte[len];
bytes.WriteBytes(pos - len, zeros, 0, len);
}
}
break;
case 7:
{
// absWriteByte
if (pos > 0)
{
int dest = Random.Next(pos);
byte b = (byte)Random.Next(256);
expected[dest] = b;
bytes.WriteByte(dest, b);
}
break;
}
}
Assert.AreEqual(pos, bytes.Position);
if (pos > 0 && Random.Next(50) == 17)
{
// truncate
int len = TestUtil.NextInt32(Random, 1, Math.Min(pos, 100));
bytes.Truncate(pos - len);
pos -= len;
Arrays.Fill(expected, pos, pos + len, (byte)0);
if (VERBOSE)
{
Console.WriteLine(" truncate len=" + len + " newPos=" + pos);
}
}
if ((pos > 0 && Random.Next(200) == 17))
{
Verify(bytes, expected, pos);
}
}
BytesStore bytesToVerify;
if (Random.NextBoolean())
{
if (VERBOSE)
{
Console.WriteLine("TEST: save/load final bytes");
}
Directory dir = NewDirectory();
IndexOutput @out = dir.CreateOutput("bytes", IOContext.DEFAULT);
bytes.WriteTo(@out);
@out.Dispose();
IndexInput @in = dir.OpenInput("bytes", IOContext.DEFAULT);
bytesToVerify = new BytesStore(@in, numBytes, TestUtil.NextInt32(Random, 256, int.MaxValue));
@in.Dispose();
dir.Dispose();
}
else
{
bytesToVerify = bytes;
}
Verify(bytesToVerify, expected, numBytes);
}
}