From 2197a31dace433ec99b811df52cdf8fc9001c96a Mon Sep 17 00:00:00 2001 From: Eamon Hetherton Date: Fri, 11 Nov 2016 12:42:49 +1000 Subject: [PATCH 1/2] Added tests to demonstrate issue with appending to file sink when using an encoding with preamble and a file size limit --- .../Serilog.Sinks.File.Tests/FileSinkTests.cs | 71 +++++++++++++++++++ .../FixedOutputFormatter.cs | 25 +++++++ 2 files changed, 96 insertions(+) create mode 100644 test/Serilog.Sinks.File.Tests/FixedOutputFormatter.cs diff --git a/test/Serilog.Sinks.File.Tests/FileSinkTests.cs b/test/Serilog.Sinks.File.Tests/FileSinkTests.cs index b900f73..747b40f 100644 --- a/test/Serilog.Sinks.File.Tests/FileSinkTests.cs +++ b/test/Serilog.Sinks.File.Tests/FileSinkTests.cs @@ -4,6 +4,8 @@ using Serilog.Formatting.Json; using Serilog.Sinks.File.Tests.Support; using Serilog.Tests.Support; +using System.Text; +using Serilog.Tests; namespace Serilog.Sinks.File.Tests { @@ -99,6 +101,75 @@ public void WhenLimitIsNotSpecifiedFileSizeIsNotRestricted() Assert.True(size > maxBytes * 2); } } + + + [Fact] + public void WhenLimitIsSpecifiedAndEncodingHasPreambleDataIsCorrectlyAppendedToFileSink() + { + long? maxBytes = 5000; + var encoding = Encoding.UTF8; + + Assert.True(encoding.GetPreamble().Length > 0); + WriteTwoEventsAndCheckOutputFileLength(maxBytes, encoding); + } + + [Fact] + public void WhenLimitIsNotSpecifiedAndEncodingHasPreambleDataIsCorrectlyAppendedToFileSink() + { + long? maxBytes = null; + var encoding = Encoding.UTF8; + + Assert.True(encoding.GetPreamble().Length > 0); + WriteTwoEventsAndCheckOutputFileLength(maxBytes, encoding); + } + + [Fact] + public void WhenLimitIsSpecifiedAndEncodingHasNoPreambleDataIsCorrectlyAppendedToFileSink() + { + long? maxBytes = 5000; + var encoding = new UTF8Encoding(false); + + Assert.Equal(0, encoding.GetPreamble().Length); + WriteTwoEventsAndCheckOutputFileLength(maxBytes, encoding); + } + + [Fact] + public void WhenLimitIsNotSpecifiedAndEncodingHasNoPreambleDataIsCorrectlyAppendedToFileSink() + { + long? maxBytes = null; + var encoding = new UTF8Encoding(false); + + Assert.Equal(0, encoding.GetPreamble().Length); + WriteTwoEventsAndCheckOutputFileLength(maxBytes, encoding); + } + + private static void WriteTwoEventsAndCheckOutputFileLength(long? maxBytes, Encoding encoding) + { + using (var tmp = TempFolder.ForCaller()) + { + var path = tmp.AllocateFilename("txt"); + var evt = Some.LogEvent("Irelevant as it will be replaced by the formatter "); + var actualEventOutput = "x"; + var formatter = new FixedOutputFormatter(actualEventOutput); + var eventOuputLength = encoding.GetByteCount(actualEventOutput); + + using (var sink = new FileSink(path, formatter, maxBytes, encoding: encoding)) + { + sink.Emit(evt); + } + var size = new FileInfo(path).Length; + Assert.Equal(encoding.GetPreamble().Length + eventOuputLength, size); + + //write a second event to the same file + using (var sink = new FileSink(path, formatter, maxBytes, encoding: encoding)) + { + sink.Emit(evt); + } + + size = new FileInfo(path).Length; + Assert.Equal(encoding.GetPreamble().Length + eventOuputLength * 2, size); + } + } } } diff --git a/test/Serilog.Sinks.File.Tests/FixedOutputFormatter.cs b/test/Serilog.Sinks.File.Tests/FixedOutputFormatter.cs new file mode 100644 index 0000000..0e14e13 --- /dev/null +++ b/test/Serilog.Sinks.File.Tests/FixedOutputFormatter.cs @@ -0,0 +1,25 @@ +using Serilog.Formatting; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Serilog.Events; +using System.IO; + +namespace Serilog.Tests +{ + public class FixedOutputFormatter : ITextFormatter + { + string _substitutionText; + + public FixedOutputFormatter(string substitutionText) + { + _substitutionText = substitutionText; + } + + public void Format(LogEvent logEvent, TextWriter output) + { + output.Write(_substitutionText); + } + } +} From 2fa2921ccf9f1f8890e42bed52591adfa744f4b5 Mon Sep 17 00:00:00 2001 From: Eamon Hetherton Date: Fri, 11 Nov 2016 16:02:02 +1000 Subject: [PATCH 2/2] Made the WriteCountingStream seekable --- src/Serilog.Sinks.File/Sinks/File/WriteCountingStream.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Serilog.Sinks.File/Sinks/File/WriteCountingStream.cs b/src/Serilog.Sinks.File/Sinks/File/WriteCountingStream.cs index f0ec6a9..2693fc4 100644 --- a/src/Serilog.Sinks.File/Sinks/File/WriteCountingStream.cs +++ b/src/Serilog.Sinks.File/Sinks/File/WriteCountingStream.cs @@ -47,7 +47,7 @@ public override void Write(byte[] buffer, int offset, int count) public override void Flush() => _stream.Flush(); public override bool CanRead => false; - public override bool CanSeek => false; + public override bool CanSeek => _stream.CanSeek; public override bool CanWrite => true; public override long Length => _stream.Length; @@ -60,7 +60,7 @@ public override long Position public override long Seek(long offset, SeekOrigin origin) { - throw new NotSupportedException(); + return _stream.Seek(offset, origin); } public override void SetLength(long value)