public void VirtualNetworkStream_MultiThreadIntegrityTest_Ok()
{
int maxFrameSize = 2048;
Assert.True(maxFrameSize > sizeof(int) + 1);
var rnd = new Random();
var rndLock = new object();
var network = new VirtualNetwork();
var checksumAndLengths = new ConcurrentDictionary <int, Tuple <uint, int> >();
object readLock = new object();
using (var client = new VirtualNetworkStream(network, isServer: false))
using (var server = new VirtualNetworkStream(network, isServer: true))
{
Parallel.For(0, 100, (int i) =>
{
int bufferSize;
int delayMilliseconds;
byte[] writeFrame;
lock (rndLock)
{
bufferSize = rnd.Next(sizeof(int) + 1, maxFrameSize);
delayMilliseconds = rnd.Next(0, 10);
writeFrame = new byte[bufferSize];
rnd.NextBytes(writeFrame);
}
// First 4 bytes represent the sequence number.
byte[] sequenceNo = BitConverter.GetBytes(i);
sequenceNo.CopyTo(writeFrame, 0);
uint writeChecksum = Fletcher32.Checksum(writeFrame, 0, writeFrame.Length);
var writeFrameInfo = new Tuple <uint, int>(writeChecksum, writeFrame.Length);
checksumAndLengths.AddOrUpdate(i, writeFrameInfo, (seq, checkSum) => { Debug.Fail("Attempt to update checksum."); return(new Tuple <uint, int>(0, 0)); });
client.WriteAsync(writeFrame, 0, writeFrame.Length).GetAwaiter().GetResult();
Task.Delay(delayMilliseconds).GetAwaiter().GetResult();
// First read the index to know how much data to read from this frame.
var readFrame = new byte[maxFrameSize];
int readLen = server.ReadAsync(readFrame, 0, maxFrameSize).GetAwaiter().GetResult();
int idx = BitConverter.ToInt32(readFrame, 0);
Tuple <uint, int> expectedFrameInfo = checksumAndLengths[idx];
Assert.Equal(expectedFrameInfo.Item2, readLen);
uint readChecksum = Fletcher32.Checksum(readFrame, 0, readLen);
Assert.Equal(expectedFrameInfo.Item1, readChecksum);
});
}
}