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 WhatIfTheHeadStateWrapsAround() { var ss = new StateSource { PaddingData = new byte[400 * 1000] }; using var zw = new ZwinderBuffer(new RewindConfig { BufferSize = 1, TargetFrameLength = 1 }); // Need to get data in the zwinderbuffer so that the last state, and the last state in particular, wraps around ss.Frame = 1; zw.Capture(1, s => ss.SaveStateBinary(new BinaryWriter(s)), null, true); ss.Frame = 2; zw.Capture(2, s => ss.SaveStateBinary(new BinaryWriter(s)), null, true); ss.Frame = 3; zw.Capture(3, s => ss.SaveStateBinary(new BinaryWriter(s)), null, true); zw.SaveStateBinary(new BinaryWriter(new MemoryStream())); }
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"); } } } }
public void CountEvictWorks() { using var zb = new ZwinderBuffer(new RewindConfig { BufferSize = 1, TargetFrameLength = 1 }); var ss = new StateSource { PaddingData = new byte[10] }; var stateCount = 0; for (int i = 0; i < 1000000; i++) { zb.Capture(i, s => ss.SaveStateBinary(new BinaryWriter(s)), j => stateCount--, true); stateCount++; } Assert.AreEqual(zb.Count, stateCount); }
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); }