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_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); }