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 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);
        }
Exemple #4
0
        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 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());
        }