public void TestReadBytesCorruption() { using var zw = new ZwinderBuffer(new RewindConfig { BufferSize = 1, TargetFrameLength = 1 }); zw.Capture(0, s => { s.Write(new byte[] { 1, 2, 3, 4 }); }); zw.Capture(1, s => { s.Write(new byte[] { 5, 6, 7, 8 }); }); var state = zw.GetState(0); Assert.AreEqual(0, state.Frame); Assert.AreEqual(4, state.Size); var bb = new byte[2]; state.GetReadStream().Read(bb, 0, 2); Assert.AreEqual(1, bb[0]); Assert.AreEqual(2, bb[1]); }
public void SaveCreateBufferRoundTrip() { RewindConfig config = new RewindConfig { BufferSize = 1, TargetFrameLength = 10 }; var buff = new ZwinderBuffer(config); var ss = new StateSource { PaddingData = new byte[500] }; for (var frame = 0; frame < 2090; frame++) { ss.Frame = frame; buff.Capture(frame, (s) => ss.SaveStateBinary(new BinaryWriter(s))); } // states are 504 bytes large, buffer is 1048576 bytes large Assert.AreEqual(buff.Count, 2080); Assert.AreEqual(buff.GetState(0).Frame, 10); Assert.AreEqual(buff.GetState(2079).Frame, 2089); Assert.AreEqual(StateSource.GetFrameNumberInState(buff.GetState(0).GetReadStream()), 10); Assert.AreEqual(StateSource.GetFrameNumberInState(buff.GetState(2079).GetReadStream()), 2089); var ms = new MemoryStream(); buff.SaveStateBinary(new BinaryWriter(ms)); ms.Position = 0; var buff2 = ZwinderBuffer.Create(new BinaryReader(ms), config); Assert.AreEqual(buff.Size, buff2.Size); Assert.AreEqual(buff.Used, buff2.Used); Assert.AreEqual(buff2.Count, 2080); Assert.AreEqual(buff2.GetState(0).Frame, 10); Assert.AreEqual(buff2.GetState(2079).Frame, 2089); Assert.AreEqual(StateSource.GetFrameNumberInState(buff2.GetState(0).GetReadStream()), 10); Assert.AreEqual(StateSource.GetFrameNumberInState(buff2.GetState(2079).GetReadStream()), 2089); }
public void TestWriteByteCorruption() { using var zw = new ZwinderBuffer(new RewindConfig { BufferSize = 1, TargetFrameLength = 1 }); zw.Capture(0, s => { s.WriteByte(1); s.WriteByte(2); s.WriteByte(3); s.WriteByte(4); }); zw.Capture(1, s => { s.WriteByte(5); s.WriteByte(6); s.WriteByte(7); s.WriteByte(8); }); zw.GetState(0).GetReadStream(); // Rewinds the backing store zw.Capture(2, s => { s.WriteByte(9); s.WriteByte(10); s.WriteByte(11); s.WriteByte(12); }); var state = zw.GetState(0); Assert.AreEqual(0, state.Frame); Assert.AreEqual(4, state.Size); Assert.AreEqual(1, state.GetReadStream().ReadByte()); }
public void BufferStressTest() { var r = new Random(8675309); using var zw = new ZwinderBuffer(new RewindConfig { BufferSize = 1, TargetFrameLength = 1 }); var buff = new byte[40000]; for (int round = 0; round < 10; round++) { for (int i = 0; i < 500; i++) { zw.Capture(i, s => { var length = r.Next(40000); var bw = new BinaryWriter(s); var bytes = buff.AsSpan(0, length); r.NextBytes(bytes); bw.Write(length); bw.Write(bytes); bw.Write(CRC32.Calculate(bytes)); }); } for (int i = 0; i < zw.Count; i++) { var info = zw.GetState(i); var s = info.GetReadStream(); var br = new BinaryReader(s); var length = info.Size; if (length != br.ReadInt32() + 8) { throw new Exception("Length field corrupted"); } var bytes = buff.AsSpan(0, length - 8); br.Read(bytes); if (br.ReadUInt32() != CRC32.Calculate(bytes)) { throw new Exception("Data or CRC field corrupted"); } } } }