public void CaptureReader_Can_Read_Back_A_Stream_That_Was_Written_By_A_CaptureWriter()
        {
            var writeOperations = 100;
            var ms = new ConcurrentStream(new MemoryStream());

            var sat = new Dictionary<Guid, short>();
            sat.Add(Guid.NewGuid(), 24);
            sat.Add(Guid.NewGuid(), 25);
            sat.Add(Guid.NewGuid(), 26);

            var stateResolver = new Mock<IStateResolver>();
            stateResolver.SetupGet(s => s.AllocationTable).Returns(sat);
            stateResolver.Setup(s => s.IsAllocated(It.IsAny<Guid>())).Returns<Guid>(g => sat.ContainsKey(g));
            stateResolver.Setup(s => s.GetAllocatedId(It.IsAny<Guid>())).Returns<Guid>(g => sat[g]);

            //write operations
            var captureWriter = new CaptureWriter(ms, stateResolver.Object);

            for (int i = 0; i < writeOperations; i++)
            {
                var timestamp = DateTime.UtcNow;
                var randomData = new byte[1024];
                new Random().NextBytes(randomData);

                var randomSat = (short)new Random().Next(24, 26);

                var captureState = new Mock<ICaptureState>();
                captureState.Setup(c => c.Data).Returns(randomData);
                captureState.Setup(c => c.Guid).Returns(sat.Where(f => f.Value == randomSat).First().Key);
                captureState.Setup(c => c.Timestamp).Returns(timestamp);

                captureWriter.Write(captureState.Object);
            }

            //rewind the stream to the beginning
            ms.Position = 0;

            //read operations
            var readStateResolver = new StateResolver();
            readStateResolver.Add(new SimpleStateController { Guid = sat.Where(f => f.Value == 24).First().Key });
            readStateResolver.Add(new SimpleStateController { Guid = sat.Where(f => f.Value == 25).First().Key });
            readStateResolver.Add(new SimpleStateController { Guid = sat.Where(f => f.Value == 26).First().Key });

            var captureReader = new CaptureReader(ms, readStateResolver);

            while (captureReader.Position < captureReader.Count)
            {
                captureReader.Read();
            }
        }
Example #2
0
        /// <summary>
        /// Creates a new instance of the CaptureStream with the specified base stream and mode
        /// </summary>
        /// <param name="stream"></param>
        public CaptureStream(IStream baseStream, System.IO.FileAccess fileAccess, IStateResolver stateResolver)
        {
            switch (fileAccess)
            {
                case System.IO.FileAccess.Read:
                    {
                        _CaptureReader = new CaptureReader(baseStream, stateResolver);

                        this.Timestamp = _CaptureReader.Timestamp;
                        break;
                    }
                case System.IO.FileAccess.Write:
                    {
                        _CaptureWriter = new CaptureWriter(baseStream, stateResolver);

                        this.Timestamp = _CaptureWriter.Timestamp;
                        break;
                    }
                default:
                    {
                        var streamPosition = baseStream.Position;

                        //important to create writer first, it will create the header the reader expects (if required)
                        _CaptureWriter = new CaptureWriter(baseStream, stateResolver);

                        //put the position back to the original position
                        baseStream.Position = streamPosition;

                        //reader now has a valid continuum file to play
                        _CaptureReader = new CaptureReader(baseStream, stateResolver);

                        this.Timestamp = _CaptureWriter.Timestamp;

                        break;
                    }
            }

            this.StateResolver = stateResolver;

            //store the read/write pointers
            _ReadPointer = baseStream.Position;
            _WritePointer = baseStream.Position;
            _Lock = new object();
        }
        public void Peek_Does_Not_Advance_The_Read_Pointer()
        {
            var writeOperations = 100;
            var ms = new ConcurrentStream(new MemoryStream());

            var sat = new Dictionary<Guid, short>();
            sat.Add(Guid.NewGuid(), 24);
            sat.Add(Guid.NewGuid(), 25);
            sat.Add(Guid.NewGuid(), 26);

            var stateResolver = new Mock<IStateResolver>();
            stateResolver.SetupGet(s => s.AllocationTable).Returns(sat);
            stateResolver.Setup(s => s.IsAllocated(It.IsAny<Guid>())).Returns<Guid>(g => sat.ContainsKey(g));
            stateResolver.Setup(s => s.GetAllocatedId(It.IsAny<Guid>())).Returns<Guid>(g => sat[g]);

            //write operations
            var captureWriter = new CaptureWriter(ms, stateResolver.Object);

            for (int i = 0; i < writeOperations; i++)
            {
                var timestamp = DateTime.UtcNow;
                var randomData = new byte[1024];
                new Random().NextBytes(randomData);

                var randomSat = (short)new Random().Next(24, 27);

                var captureState = new Mock<ICaptureState>();
                captureState.Setup(c => c.Data).Returns(randomData);
                captureState.Setup(c => c.Guid).Returns(sat.Where(f => f.Value == randomSat).First().Key);
                captureState.Setup(c => c.Timestamp).Returns(timestamp);

                captureWriter.Write(captureState.Object);
            }

            //rewind the stream to the beginning
            ms.Position = 0;

            //read operations
            var readStateResolver = new StateResolver();
            readStateResolver.Add(new SimpleStateController { Guid = sat.Where(f => f.Value == 24).First().Key });
            readStateResolver.Add(new SimpleStateController { Guid = sat.Where(f => f.Value == 25).First().Key });
            readStateResolver.Add(new SimpleStateController { Guid = sat.Where(f => f.Value == 26).First().Key });

            var captureReader = new CaptureReader(ms, readStateResolver);

            var position = captureReader.Position;
            var state = captureReader.Peek(sat.Where(f => f.Value == (short)26).First().Key);

            Assert.NotNull(state);
            Assert.Equal(position, captureReader.Position);
        }
        public void CaptureWriter_Inserts_The_Correct_Data_Into_The_Stream_During_Multiple_Write_Operations()
        {
            var writeOperations = 100;
            var ms = new ConcurrentStream(new MemoryStream());

            var sat = new Dictionary<Guid, short>();
            sat.Add(Guid.NewGuid(), 24);
            sat.Add(Guid.NewGuid(), 25);
            sat.Add(Guid.NewGuid(), 26);

            var stateResolver = new Mock<IStateResolver>();
            stateResolver.SetupGet(s => s.AllocationTable).Returns(sat);
            stateResolver.Setup(s => s.IsAllocated(It.IsAny<Guid>())).Returns<Guid>(g => sat.ContainsKey(g));
            stateResolver.Setup(s => s.GetAllocatedId(It.IsAny<Guid>())).Returns<Guid>(g => sat[g]);

            var captureWriter = new CaptureWriter(ms, stateResolver.Object);

            for (int i = 0; i < writeOperations; i++)
            {
                var timestamp = DateTime.UtcNow;
                var rewindPosition = ms.Position;

                var randomData = new byte[1024];
                new Random().NextBytes(randomData);

                var randomSat = (short)new Random().Next(24, 26);

                var captureState = new Mock<ICaptureState>();
                captureState.Setup(c => c.Data).Returns(randomData);
                captureState.Setup(c => c.Guid).Returns(sat.Where(f => f.Value == randomSat).First().Key);
                captureState.Setup(c => c.Timestamp).Returns(timestamp);

                captureWriter.Write(captureState.Object);

                //rewind the stream and check the correct data length was written
                ms.Position = rewindPosition + 2 + 8;

                var dataLengthBuffer = new byte[4];
                ms.Read(dataLengthBuffer, 0, 4);
                var dataLength = BitConverter.ToInt32(dataLengthBuffer, 0);

                var dataBuffer = new byte[dataLength];
                ms.Read(dataBuffer, 0, dataLength);

                for (int j = 0; j < dataBuffer.Length; j++)
                {
                    Assert.Equal(randomData[j], dataBuffer[j]);
                }
            }
        }
        public void CaptureWriter_Updates_The_Length_Of_The_Stream_During_Writes()
        {
            var ms = new ConcurrentStream(new MemoryStream());

            var sat = new Dictionary<Guid, short>();
            sat.Add(Guid.NewGuid(), 24);
            sat.Add(Guid.NewGuid(), 25);
            sat.Add(Guid.NewGuid(), 26);

            var stateResolver = new Mock<IStateResolver>();
            stateResolver.SetupGet(s => s.AllocationTable).Returns(sat);
            stateResolver.Setup(s => s.IsAllocated(It.IsAny<Guid>())).Returns<Guid>(g => sat.ContainsKey(g));
            stateResolver.Setup(s => s.GetAllocatedId(It.IsAny<Guid>())).Returns<Guid>(g => sat[g]);

            var captureWriter = new CaptureWriter(ms, stateResolver.Object);

            var lastLength = TimeSpan.Zero;

            for (int i = 0; i < 20; i++)
            {
                var timestamp = DateTime.UtcNow.AddSeconds(i * 10);
                var randomData = new byte[10000];
                new Random().NextBytes(randomData);

                var captureState = new Mock<ICaptureState>();
                captureState.Setup(c => c.Data).Returns(randomData);
                captureState.Setup(c => c.Guid).Returns(sat.Where(f => f.Value == 24).First().Key);
                captureState.Setup(c => c.Timestamp).Returns(timestamp);

                captureWriter.Write(captureState.Object);

                Assert.True(captureWriter.Length > lastLength);

                lastLength = captureWriter.Length;
            }
        }
        public void CaptureWriter_Inserts_The_Correct_Timestamp_Into_The_Stream_During_Write_Operations()
        {
            var ms = new ConcurrentStream(new MemoryStream());

            var sat = new Dictionary<Guid, short>();
            sat.Add(Guid.NewGuid(), 24);
            sat.Add(Guid.NewGuid(), 25);
            sat.Add(Guid.NewGuid(), 26);

            var stateResolver = new Mock<IStateResolver>();
            stateResolver.SetupGet(s => s.AllocationTable).Returns(sat);
            stateResolver.Setup(s => s.IsAllocated(It.IsAny<Guid>())).Returns<Guid>(g => sat.ContainsKey(g));
            stateResolver.Setup(s => s.GetAllocatedId(It.IsAny<Guid>())).Returns<Guid>(g => sat[g]);

            var captureWriter = new CaptureWriter(ms, stateResolver.Object);
            var timestamp = DateTime.UtcNow;
            var rewindPosition = ms.Position;
            var captureState = new Mock<ICaptureState>();
            captureState.Setup(c => c.Data).Returns(Guid.NewGuid().ToByteArray());
            captureState.Setup(c => c.Guid).Returns(sat.Where(f => f.Value == 24).First().Key);
            captureState.Setup(c => c.Timestamp).Returns(timestamp);

            captureWriter.Write(captureState.Object);

            //rewind the stream and check the correct timestamp was written
            ms.Position = rewindPosition + 2;

            var timestampBuffer = new byte[8];
            ms.Read(timestampBuffer, 0, 8);

            Assert.Equal(timestamp, DateTime.FromBinary(BitConverter.ToInt64(timestampBuffer, 0)));
        }
        public void CaptureWriter_Buids_A_Valid_Continuum_Header()
        {
            var baseStream = new ConcurrentStream(new MemoryStream());
            var stateResolver = new StateResolver();

            var stateController = new WeatherStateController(new WeatherSimulator());

            stateResolver.Add(stateController);

            var captureWriter = new CaptureWriter(baseStream, stateResolver);

            baseStream.Position = 0;

            byte[] header = new byte[Constants.CONTINUUM_HEADER_SIGNATURE.Length];
            baseStream.Read(header, 0, header.Length);

            for (int i = 0; i < Constants.CONTINUUM_HEADER_SIGNATURE.Length; i++)
            {
                Assert.Equal(Constants.CONTINUUM_HEADER_SIGNATURE[i], header[i]);
            }

            //dont worry about 4 bytes reserved for version info at the moment
            baseStream.Position = baseStream.Position + 4;

            //ignore the timestamp for now
            baseStream.Position = baseStream.Position + 8;

            //ignore the count property for now
            baseStream.Position = baseStream.Position + 8;

            //ignore the length property for now
            baseStream.Position = baseStream.Position + 8;

            //read the SAT, there should be at least one entry for it to be valid
            //the SAT looks like this:
            //<lengthOfSac><firstId of type short><delimiter>

            var lengthOfSatBuffer = new byte[4];
            baseStream.Read(lengthOfSatBuffer, 0, lengthOfSatBuffer.Length);

            var lengthOfSat = BitConverter.ToInt32(lengthOfSatBuffer, 0);

            Assert.True(lengthOfSat > 0);

            //read back the sat
            var readSat = new Dictionary<short, Guid>();

            for (int i = 0; i < lengthOfSat; i++)
            {
                var idBuffer = new byte[2];
                baseStream.Read(idBuffer, 0, idBuffer.Length);

                var guid = new byte[16]; //guids are 16-bytes
                baseStream.Read(guid, 0, guid.Length);

                readSat.Add(BitConverter.ToInt16(idBuffer, 0), new Guid(guid));
            }

            //match the sat
            foreach (var kvp in stateResolver.AllocationTable)
            {
                Assert.True(readSat.ContainsKey(kvp.Value));
                Assert.True(readSat[kvp.Value] == kvp.Key);
            }
        }