public void CaptureReader_Correctly_Assigns_Offsets_To_ICaptureState_Instances_When_Read() { var stateController = new WeatherStateController(new WeatherSimulator()); var stateResolver = new StateResolver(); stateResolver.Add(stateController); var ms = VastPark.FrameworkBase.IO.EmbeddedResource.GetMemoryStream("Continuum.Test.Samples.weather-simulation.continuum", Assembly.GetExecutingAssembly()); ms.Position = 0; var stream = new ConcurrentStream(ms); var captureStream = new CaptureStream(stream, FileAccess.Read, stateResolver); var lastOffset = 0d; for (int i = 0; i < captureStream.Count; i++) { var state = captureStream.Read(); Assert.True(state.Offset >= 0); Assert.True(state.Offset >= lastOffset); lastOffset = state.Offset; } }
public void Multiple_IStateRecorders_Are_Written_In_Chronological_Order_Into_A_Shared_Stream() { var guid = Guid.NewGuid(); var stream = new ConcurrentStream(new MemoryStream()); var stateController = new SimpleStateController { Guid = guid }; var stateResolver = new StateResolver(); stateResolver.Add(stateController); var captureService = new CaptureService { Stream = stream, StateResolver = stateResolver }; var recorder1 = new Mock<IStateRecorder>(); var recorder2 = new Mock<IStateRecorder>(); var recorderBuffer1 = new SimpleBuffer<ICaptureState>(); var recorderBuffer2 = new SimpleBuffer<ICaptureState>(); recorder1.Setup(b => b.Buffer).Returns(recorderBuffer1); recorder2.Setup(b => b.Buffer).Returns(recorderBuffer2); //push some dummy states into the buffers var state1 = new Mock<ICaptureState>(); var firstTimestamp = DateTime.Now.AddDays(1); state1.Setup(s => s.Timestamp).Returns(firstTimestamp); state1.Setup(s => s.Guid).Returns(guid); var state2 = new Mock<ICaptureState>(); var secondTimestamp = DateTime.Now.AddDays(2); state2.Setup(s => s.Timestamp).Returns(secondTimestamp); state2.Setup(s => s.Guid).Returns(guid); recorderBuffer1.Enqueue(state1.Object); recorderBuffer2.Enqueue(state2.Object); //add the 2nd recorder in first as it's timestamp is at a time in the future beyond the first recorder's state captureService.Add(recorder2.Object); captureService.Add(recorder1.Object); captureService.Start(); captureService.Flush(); Assert.Equal(2, captureService.CaptureStream.Count); //open the stream for reading now stream.Position = 0; var captureStream = new CaptureStream(stream, FileAccess.Read, stateResolver); //first value read back should be from state1 Assert.Equal(firstTimestamp, captureStream.Read().Timestamp); Assert.Equal(secondTimestamp, captureStream.Read().Timestamp); }
public void CaptureService_Can_Write_A_Capture_To_Disk_When_Backed_By_A_FileStream() { var statesToWrite = 100; var simulator = new WeatherSimulator(); var controller = new WeatherStateController(simulator); var stateResolver = new StateResolver(); stateResolver.Add(controller); var tmpFile = System.IO.Path.GetTempFileName(); try { using (var ms = new FileStream(tmpFile,FileMode.Create)) { var baseStream = new ConcurrentStream(ms); var captureService = new CaptureService { Stream = baseStream, StateResolver = stateResolver }; captureService.Start(); controller.Initialise(captureService.CaptureStream); simulator.Start(); var count = 0; var resetEvent = new SlimResetEvent(20); simulator.NewTemperature += delegate { count++; if (count == statesToWrite) { simulator.Stop(); resetEvent.Set(); } }; resetEvent.Wait(); captureService.Flush(); } Assert.True(File.Exists(tmpFile)); Assert.True(new FileInfo(tmpFile).Length > 0); } finally { File.Delete(tmpFile); } }
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(); } }
public void CaptureStream_Supports_Reading_A_File_For_Playback_Prior_To_The_Entire_File_Becoming_Available() { //base bytes to feed into the stream at random var bytes = VastPark.FrameworkBase.IO.EmbeddedResource.GetBytes("Continuum.Test.Samples.weather-simulation.continuum", Assembly.GetExecutingAssembly()); var endOfHeader = 0L; using (var ms = new MemoryStream(bytes)) { var reader = new CaptureReader(new ConcurrentStream(ms), new StateResolver()); endOfHeader = reader.BaseStream.Position; } var stream = new MemoryStream(); var baseStream = new ConcurrentStream(stream); var binaryWriter = new BinaryWriter(stream); var stateResolver = new StateResolver(); stateResolver.Add(new Continuum.Test.Mock.WeatherStateController(new WeatherSimulator())); //push in some bytes to get it started, enough for the header so that the stream won't throw on construction binaryWriter.Write(bytes, 0, (int)endOfHeader); var offset = baseStream.Position; baseStream.Position = 0; var captureStream = new CaptureStream(baseStream, FileAccess.Read, stateResolver); Assert.Null(captureStream.Peek()); //write some bytes in (not enough for a full state) binaryWriter.Seek((int)offset, SeekOrigin.Begin); binaryWriter.Write(bytes, (int)offset, 10); offset += 10; Assert.Null(captureStream.Peek()); //write some more bytes so that there is now a full state that can be peeked at binaryWriter.Seek((int)offset, SeekOrigin.Begin); binaryWriter.Write(bytes, (int)offset, 200); Assert.NotNull(captureStream.Peek()); }
public void CaptureStream_Instances_Are_Played_Back_In_Chronological_Order() { var resetEvent = new SlimResetEvent(20); var expectedStates = long.MaxValue; var executedStates = 0; var stateController = new WeatherStateController(new WeatherSimulator()); var stateResolver = new StateResolver(); stateResolver.Add(stateController); stateController.StateExecuted += delegate { executedStates++; if (executedStates == expectedStates) { resetEvent.Set(); } }; var playbackService = new PlaybackService(stateResolver); var ms = VastPark.FrameworkBase.IO.EmbeddedResource.GetMemoryStream("Continuum.Test.Samples.weather-simulation.continuum", Assembly.GetExecutingAssembly()); var stream1 = new ConcurrentStream(new MemoryStream(ms.ToArray())); var captureStream1 = new CaptureStream(stream1, System.IO.FileAccess.Read, stateResolver); var stream2 = new ConcurrentStream(new MemoryStream(ms.ToArray())); var captureStream2 = new CaptureStream(stream2, System.IO.FileAccess.Read, stateResolver); expectedStates = captureStream1.Count + captureStream2.Count; playbackService.Add(captureStream1); playbackService.Add(captureStream2); playbackService.Start(); resetEvent.Wait(); }
public void Position_Is_Updated_Correctly_During_Writes() { var count = 100; var ms = new ConcurrentStream(new MemoryStream()); var validGuids = _GenerateCaptureService(count); var captureStream = new CaptureStream(ms, FileAccess.Write, _StateResolver); for (int i = 0; i < count; i++) { var mock = new Mock<ICaptureState>(); mock.Setup(p => p.Guid).Returns(validGuids[i]); mock.Setup(p => p.Data).Returns(Guid.NewGuid().ToByteArray()); captureStream.Write(mock.Object); Assert.Equal(i + 1, captureStream.Position); } }
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 State_Allocation_Table_Is_Correctly_Populated() { var expectedId = (short)123; var expectedGuid = Guid.NewGuid(); var ms = new ConcurrentStream(new MemoryStream()); var idBytes = BitConverter.GetBytes(expectedId); var guidBytes = expectedGuid.ToByteArray(); //write the header var header = _CreateContinuumHeader(1000, 10000); ms.Write(header.ToArray(), 0, header.Length); //write the SAT ms.Write(BitConverter.GetBytes(1), 0, 4); ms.Write(idBytes, 0, idBytes.Length); ms.Write(guidBytes, 0, guidBytes.Length); //rewind the stream ms.Position = 0; var stateController = new Mock<IStateController>(); var stateResolver = new Mock<IStateResolver>(); stateResolver.Setup(s => s.Find(It.IsAny<Guid>())).Returns(stateController.Object); var captureReader = new CaptureReader(ms, stateResolver.Object); Assert.NotEmpty(captureReader.StateAllocationTable); Assert.Equal(expectedId, captureReader.StateAllocationTable.First().Key); Assert.Equal(expectedGuid, captureReader.StateAllocationTable.First().Value); Assert.Equal(1, captureReader.StateAllocationTable.Count); }
public void CaptureReader_Throws_An_Exception_When_Loading_An_Invalid_Continuum_Stream() { //empty stream is considered invalid var baseStream = new ConcurrentStream(new MemoryStream()); var stateController = new Mock<IStateController>(); var stateResolver = new Mock<IStateResolver>(); stateResolver.Setup(s => s.Find(It.IsAny<Guid>())).Returns(stateController.Object); try { var captureReader = new CaptureReader(baseStream, stateResolver.Object); //fail Assert.True(false); } catch { //pass Assert.True(true); } }
public void Selecting_A_Position_Beyond_The_Length_Of_The_Stream_Will_Throw_An_Exception() { _StateResolver = new StateResolver(); var controller = new WeatherStateController(new WeatherSimulator()); _StateResolver.Add(controller); var ms = VastPark.FrameworkBase.IO.EmbeddedResource.GetMemoryStream("Continuum.Test.Samples.weather-simulation.continuum", Assembly.GetExecutingAssembly()); var stream = new ConcurrentStream(new MemoryStream(ms.ToArray())); var captureStream = new CaptureStream(stream, System.IO.FileAccess.Read, _StateResolver); Assert.Throws(typeof(Exception), new Assert.ThrowsDelegate(delegate { captureStream.Position = captureStream.Count + 1; })); }
public void When_A_Filter_Is_Applied_That_Returns_True_The_State_Is_Not_Scheduled_For_Playback() { var stateController = new WeatherStateController(new WeatherSimulator()); var stateResolver = new StateResolver(); stateResolver.Add(stateController); var scheduler = new Mock<IScheduler>(); var taskFactory = new Mock<ITaskFactory>(); var playbackService = new PlaybackService(stateResolver, scheduler.Object, taskFactory.Object); var ms = VastPark.FrameworkBase.IO.EmbeddedResource.GetMemoryStream("Continuum.Test.Samples.weather-simulation.continuum", Assembly.GetExecutingAssembly()); var stream = new ConcurrentStream(new MemoryStream(ms.ToArray())); var captureStream = new CaptureStream(stream, System.IO.FileAccess.Read, stateResolver); playbackService.Add(captureStream); //add in a filter that will always return true to filter out the states playbackService.Add(new StreamFilter(f => true)); playbackService.Start(); //task factory should not have built any tasks taskFactory.Verify(t => t.Create(It.IsAny<ICaptureState>()), Times.Never()); scheduler.Verify(s => s.Add(It.IsAny<ITask>()), Times.Never()); }
public void CaptureStream_Supports_Reading_A_File_While_It_Is_Being_Written_From_Another_Thread() { //base bytes to feed into the stream at random var bytes = VastPark.FrameworkBase.IO.EmbeddedResource.GetBytes("Continuum.Test.Samples.weather-simulation.continuum", Assembly.GetExecutingAssembly()); var endOfHeader = 0L; using(var ms = new MemoryStream(bytes)) { var reader = new CaptureReader(new ConcurrentStream(ms), new StateResolver()); endOfHeader = reader.BaseStream.Position; } var stream = new MemoryStream(); var baseStream = new ConcurrentStream(stream); var binaryWriter = new BinaryWriter(stream); var stateResolver = new StateResolver(); stateResolver.Add(new Continuum.Test.Mock.WeatherStateController(new WeatherSimulator())); //push in some bytes to get it started, enough for the header so that the stream won't throw on construction binaryWriter.Write(bytes, 0, (int)endOfHeader); var offset = baseStream.Position; baseStream.Position = 0; var captureStream = new CaptureStream(baseStream, FileAccess.Read, stateResolver); //write in a little more so we don't have a full state yet binaryWriter.Seek((int)offset, SeekOrigin.Begin); //binaryWriter.Write(bytes, (int)offset, 5); //offset += 5; var readStates = 0; var lockObject = new object(); //create a thread to randomly write chunks of bytes into the base stream ThreadPool.QueueUserWorkItem(w => { while (offset < bytes.LongLength) { var bytesToWrite = new Random().Next(1, 200); if (bytesToWrite > bytes.Length - offset) { bytesToWrite = Convert.ToInt32(bytes.LongLength - offset); } lock (lockObject) { binaryWriter.Seek((int)offset, SeekOrigin.Begin); binaryWriter.Write(bytes, (int)offset, bytesToWrite); offset += bytesToWrite; } Thread.Sleep(200); } Assert.Equal(bytes.LongLength, baseStream.Length); lock (lockObject) { binaryWriter.Seek(0, SeekOrigin.Begin); for (int i = 0; i < bytes.LongLength; i++) { Assert.Equal(bytes[i], (byte)baseStream.ReadByte()); } } }); while (captureStream.Position < captureStream.Count) { lock (lockObject) { if (captureStream.Peek() != null) { captureStream.Read(); readStates++; } } } Assert.Equal(captureStream.Count, readStates); }
public void Custom_Capture_Formats_Are_Recorded_Correctly() { var resetEvent = new SlimResetEvent(20); var desiredStates = 200; var generatedStates = 0; var ms = new MemoryStream(); var stream = new ConcurrentStream(ms); var weatherSimulator = new WeatherSimulator(); _StateResolver = new StateResolver(); //build the controller that manages weather states var controller = new WeatherStateController(weatherSimulator); //watch the simluator for the desired number of states weatherSimulator.NewTemperature += delegate { generatedStates++; if (generatedStates >= desiredStates) { weatherSimulator.Stop(); resetEvent.Set(); } }; //register it with the capture service _StateResolver = new StateResolver(); _StateResolver.Add(controller); //create the capture stream, will create an entry in the SAT for the WeatherStateController var captureStream = new CaptureStream(stream, FileAccess.Write, _StateResolver); //pass the controller the stream so that it can be written to controller.Initialise(captureStream); //start the simulator, the controller will watch for changes internally weatherSimulator.Start(); //wait until the event is raised [desiredStates] number of times resetEvent.Wait(); Assert.Equal(generatedStates, captureStream.Count); //rewind the stream and open it for reading, verify the values match stream.Position = 0; captureStream = new CaptureStream(stream, FileAccess.Read, _StateResolver); for (int i = 0; i < captureStream.Count; i++) { var state = captureStream.Read(); Assert.Equal(weatherSimulator.History[i], (state as WeatherCaptureState).Temperature); } }
public void CaptureReader_Length_Is_Correct_After_Construction() { var ms = VastPark.FrameworkBase.IO.EmbeddedResource.GetMemoryStream("Continuum.Test.Samples.weather-simulation.continuum", Assembly.GetExecutingAssembly()); ms.Position = 0; var stream = new ConcurrentStream(ms); var captureStream = new CaptureStream(stream, FileAccess.Read, new StateResolver()); Assert.NotEqual(TimeSpan.Zero, captureStream.Length); }
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 Selecting_A_Position_Forward_In_The_Stream_When_The_Current_Position_Is_Not_Zero_Will_Read_That_Node() { _StateResolver = new StateResolver(); var controller = new WeatherStateController(new WeatherSimulator()); _StateResolver.Add(controller); var ms = VastPark.FrameworkBase.IO.EmbeddedResource.GetMemoryStream("Continuum.Test.Samples.weather-simulation.continuum", Assembly.GetExecutingAssembly()); var stream = new ConcurrentStream(new MemoryStream(ms.ToArray())); var captureStream = new CaptureStream(stream, System.IO.FileAccess.Read, _StateResolver); var desiredNode = Math.Round(Convert.ToDouble(captureStream.Count) / 2); //read up the number of nodes to move the position pointer forwards in the stream for (int i = 0; i < desiredNode; i++) { captureStream.Read(); } //seek to the new position captureStream.Position += 2; //this node is equivalent to node desiredNode + 3 var seekNode = captureStream.Read(); //manually read nodes, when the desired node is reached it should match the node pulled out previously stream = new ConcurrentStream(new MemoryStream(ms.ToArray())); captureStream = new CaptureStream(stream, FileAccess.Read, _StateResolver); ICaptureState actualNode = null; for (int i = 0; i < desiredNode + 3; i++) { actualNode = captureStream.Read(); } Assert.Equal(actualNode.Guid, seekNode.Guid); Assert.Equal(actualNode.Offset, seekNode.Offset); Assert.Equal(actualNode.Timestamp, seekNode.Timestamp); for (int i = 0; i < actualNode.Data.Length; i++) { Assert.Equal(actualNode.Data[i], seekNode.Data[i]); } }
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); } }
public void When_A_Codec_Is_Not_Available_An_Event_Is_Raised_Giving_The_Caller_An_Opportunity_To_Acquire_It() { var stateController = new WeatherStateController(new WeatherSimulator()); var stateResolver = new StateResolver(); var eventRaised = false; var playbackService = new PlaybackService(stateResolver); playbackService.CodecRequired += delegate { eventRaised = true; }; var ms = VastPark.FrameworkBase.IO.EmbeddedResource.GetMemoryStream("Continuum.Test.Samples.weather-simulation.continuum", Assembly.GetExecutingAssembly()); var stream = new ConcurrentStream(new MemoryStream(ms.ToArray())); var captureStream = new CaptureStream(stream, System.IO.FileAccess.Read, stateResolver); playbackService.Add(captureStream); Assert.True(eventRaised); }
public void CaptureReader_Loads_A_Valid_Continuum_Stream() { var satCount = 5; var header = _CreateContinuumHeader(1000, 10000); var sat = _CreateSAT(satCount); var baseStream = new ConcurrentStream(new MemoryStream()); baseStream.Write(header.ToArray(), 0, header.Length); baseStream.Write(sat, 0, sat.Length); baseStream.Position = 0; var stateController = new Mock<IStateController>(); var stateResolver = new Mock<IStateResolver>(); stateResolver.Setup(s => s.Find(It.IsAny<Guid>())).Returns(stateController.Object); var captureReader = new CaptureReader(baseStream, stateResolver.Object); Assert.Equal(satCount, captureReader.StateAllocationTable.Count); }
public void When_A_Codec_Is_Not_Available_An_Event_Is_Raised_With_The_Guid_Of_The_Required_Codec() { var stateController = new WeatherStateController(new WeatherSimulator()); var stateResolver = new StateResolver(); stateResolver.Add(stateController); var playbackService = new PlaybackService(stateResolver); playbackService.CodecRequired += delegate(object sender, CodecRequiredEventArgs e) { Assert.Equal(stateController.Guid, e.Guid); }; var ms = VastPark.FrameworkBase.IO.EmbeddedResource.GetMemoryStream("Continuum.Test.Samples.weather-simulation.continuum", Assembly.GetExecutingAssembly()); var stream = new ConcurrentStream(new MemoryStream(ms.ToArray())); var captureStream = new CaptureStream(stream, System.IO.FileAccess.Read, stateResolver); playbackService.Add(captureStream); }
public void CaptureReader_Selects_The_Correct_IStateController_During_Reads() { var immlStateController = new Mock<IStateController>(); var immlStateControllerId = (short)100; var immlStateControllerGuid = Guid.NewGuid(); immlStateController.Setup(g => g.Guid).Returns(immlStateControllerGuid); var boneNodeStateController = new Mock<IStateController>(); var boneNodeStateControllerId = (short)123; var boneNodeStateControllerGuid = Guid.NewGuid(); boneNodeStateController.Setup(g => g.Guid).Returns(boneNodeStateControllerGuid); //build 2 different state mappings var ms = new ConcurrentStream(new MemoryStream()); //header var header = _CreateContinuumHeader(1000, 10000); ms.Write(header, 0, header.Length); //sat ms.Write(BitConverter.GetBytes(2), 0, 4); //count //mapping for imml ms.Write(BitConverter.GetBytes(immlStateControllerId), 0, 2); ms.Write(immlStateControllerGuid.ToByteArray(), 0, 16); //mapping for bones ms.Write(BitConverter.GetBytes(boneNodeStateControllerId), 0, 2); ms.Write(boneNodeStateControllerGuid.ToByteArray(), 0, 16); //generate 2 dummy states, one for each controller var firstRandomBytes = new byte[1024]; new Random().NextBytes(firstRandomBytes); ms.Write(BitConverter.GetBytes(immlStateControllerId), 0, 2); ms.Write(BitConverter.GetBytes(DateTime.UtcNow.ToBinary()), 0, 8); ms.Write(BitConverter.GetBytes((int)firstRandomBytes.Length), 0, 4); ms.Write(firstRandomBytes, 0, firstRandomBytes.Length); var secondRandomBytes = new byte[2048]; new Random().NextBytes(secondRandomBytes); ms.Write(BitConverter.GetBytes(boneNodeStateControllerId), 0, 2); ms.Write(BitConverter.GetBytes(DateTime.UtcNow.ToBinary()), 0, 8); ms.Write(BitConverter.GetBytes((int)secondRandomBytes.Length), 0, 4); ms.Write(secondRandomBytes, 0, secondRandomBytes.Length); ms.Position = 0; //perform the reads and verify var stateResolver = new StateResolver(); stateResolver.Add(immlStateController.Object); stateResolver.Add(boneNodeStateController.Object); var captureReader = new CaptureReader(ms, stateResolver); captureReader.Read(); captureReader.Read(); boneNodeStateController.Verify(c => c.Create(It.IsAny<byte[]>(), It.IsAny<DateTime>(), It.IsAny<double>()), Times.Once()); immlStateController.Verify(c => c.Create(It.IsAny<byte[]>(), It.IsAny<DateTime>(), It.IsAny<double>()), Times.Once()); }
public void CaptureStream_Supports_Writing_A_State_And_Then_Reading_It() { var stateController = new WeatherStateController(new WeatherSimulator()); var stateResolver = new StateResolver(); stateResolver.Add(stateController); var baseStream = new ConcurrentStream(new MemoryStream()); var captureStream = new CaptureStream(baseStream, FileAccess.ReadWrite, stateResolver); Assert.True(captureStream.CanRead); Assert.True(captureStream.CanWrite); //write a state then read it back var expectedBytes = Guid.NewGuid().ToByteArray(); captureStream.Write(new WeatherCaptureState(expectedBytes, stateController.Guid, DateTime.UtcNow, 0)); //the read pointer is still at the start of the stream var readState = captureStream.Read(); for (int i = 0; i < readState.Data.Length; i++) { Assert.Equal(expectedBytes[i], readState.Data[i]); } }
public void Selecting_A_Position_When_The_Current_Position_Is_Zero_Will_Read_That_Node() { var controller = new WeatherStateController(new WeatherSimulator()); _StateResolver = new StateResolver(); _StateResolver.Add(controller); var ms = VastPark.FrameworkBase.IO.EmbeddedResource.GetMemoryStream("Continuum.Test.Samples.weather-simulation.continuum", Assembly.GetExecutingAssembly()); var stream = new ConcurrentStream(new MemoryStream(ms.ToArray())); var captureStream = new CaptureStream(stream, System.IO.FileAccess.Read, _StateResolver); var desiredNode = Math.Round(Convert.ToDouble(captureStream.Count) / 2); captureStream.Position = (long)desiredNode - 1; //if the desired node is 50, its required to put the stream at position 49 in order to read it var seekNode = captureStream.Read(); //manually read nodes, when the desired node is reached it should match the node pulled out previously stream = new ConcurrentStream(new MemoryStream(ms.ToArray())); captureStream = new CaptureStream(stream, FileAccess.Read, _StateResolver); ICaptureState actualNode = null; for (int i = 0; i < desiredNode; i++) { actualNode = captureStream.Read(); } Assert.Equal(actualNode.Guid, seekNode.Guid); Assert.Equal(actualNode.Offset, seekNode.Offset); Assert.Equal(actualNode.Timestamp, seekNode.Timestamp); for (int i = 0; i < actualNode.Data.Length; i++) { Assert.Equal(actualNode.Data[i], seekNode.Data[i]); } }