From 8d600829fcdf117304c12057428dc6888debccff Mon Sep 17 00:00:00 2001 From: Michal Gajek Date: Fri, 5 Jan 2024 15:49:06 +0100 Subject: [PATCH] more tests --- samples/PicoSampleApp/PicoSampleApp.sln | 6 + .../PicoProfiler.Tests.csproj | 2 + ...filerTests.cs => PicoProfilerCoreTests.cs} | 2 +- .../PicoProfilerLoggerTests.cs | 115 ++++++++++++++++++ .../TestLogger/TestLogger.cs | 22 ++++ .../TestLogger/TestLoggerFixture.cs | 32 +++++ .../TestLogger/TestLoggerProvider.cs | 21 ++++ 7 files changed, 199 insertions(+), 1 deletion(-) rename src/PicoProfiler.Tests/{PicoProfilerTests.cs => PicoProfilerCoreTests.cs} (97%) create mode 100644 src/PicoProfiler.Tests/PicoProfilerLoggerTests.cs create mode 100644 src/PicoProfiler.Tests/TestLogger/TestLogger.cs create mode 100644 src/PicoProfiler.Tests/TestLogger/TestLoggerFixture.cs create mode 100644 src/PicoProfiler.Tests/TestLogger/TestLoggerProvider.cs diff --git a/samples/PicoSampleApp/PicoSampleApp.sln b/samples/PicoSampleApp/PicoSampleApp.sln index 035ef8b..9b37a3f 100644 --- a/samples/PicoSampleApp/PicoSampleApp.sln +++ b/samples/PicoSampleApp/PicoSampleApp.sln @@ -9,6 +9,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PicoProfiler.Logging", "..\ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PicoProfiler", "..\..\src\PicoProfiler\PicoProfiler.csproj", "{F56EF65C-0B2B-4364-9ADB-092FD1BDF715}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PicoProfiler.Tests", "..\..\src\PicoProfiler.Tests\PicoProfiler.Tests.csproj", "{FC17C1B7-D16A-44DD-A791-401E86B08402}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -27,6 +29,10 @@ Global {F56EF65C-0B2B-4364-9ADB-092FD1BDF715}.Debug|Any CPU.Build.0 = Debug|Any CPU {F56EF65C-0B2B-4364-9ADB-092FD1BDF715}.Release|Any CPU.ActiveCfg = Release|Any CPU {F56EF65C-0B2B-4364-9ADB-092FD1BDF715}.Release|Any CPU.Build.0 = Release|Any CPU + {FC17C1B7-D16A-44DD-A791-401E86B08402}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FC17C1B7-D16A-44DD-A791-401E86B08402}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FC17C1B7-D16A-44DD-A791-401E86B08402}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FC17C1B7-D16A-44DD-A791-401E86B08402}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/PicoProfiler.Tests/PicoProfiler.Tests.csproj b/src/PicoProfiler.Tests/PicoProfiler.Tests.csproj index 6c96d30..611ec6f 100644 --- a/src/PicoProfiler.Tests/PicoProfiler.Tests.csproj +++ b/src/PicoProfiler.Tests/PicoProfiler.Tests.csproj @@ -11,6 +11,7 @@ + @@ -24,6 +25,7 @@ + diff --git a/src/PicoProfiler.Tests/PicoProfilerTests.cs b/src/PicoProfiler.Tests/PicoProfilerCoreTests.cs similarity index 97% rename from src/PicoProfiler.Tests/PicoProfilerTests.cs rename to src/PicoProfiler.Tests/PicoProfilerCoreTests.cs index a9b5287..ddd806c 100644 --- a/src/PicoProfiler.Tests/PicoProfilerTests.cs +++ b/src/PicoProfiler.Tests/PicoProfilerCoreTests.cs @@ -3,7 +3,7 @@ namespace PicoProfiler.Tests; -public class PicoProfilerTests +public class PicoProfilerCoreTests { private static readonly TimeSpan DelayTime = TimeSpan.FromMilliseconds(50); diff --git a/src/PicoProfiler.Tests/PicoProfilerLoggerTests.cs b/src/PicoProfiler.Tests/PicoProfilerLoggerTests.cs new file mode 100644 index 0000000..cba6ce2 --- /dev/null +++ b/src/PicoProfiler.Tests/PicoProfilerLoggerTests.cs @@ -0,0 +1,115 @@ +using Microsoft.Extensions.Logging; +using PicoProfiler.Logging; +using PicoProfiler.Tests.TestLogger; + +namespace PicoProfiler.Tests; + +public class PicoProfilerLoggerTests +{ + [Fact] + public void Outputs_To_Log() + { + var fixture = new TestLoggerFixture(); + + var logger = fixture.CreateLogger(); + using (logger.StartProfiler()) + { + } + + Assert.Equal(1, fixture.LogEntries.Count); + } + + [Fact] + public void Uses_Provided_LogLevel() + { + var fixture = new TestLoggerFixture(); + + var logger = fixture.CreateLogger(); + using (logger.StartProfiler(logLevel: LogLevel.Debug)) + { + } + + Assert.Equal(LogLevel.Debug, fixture.LogEntries.Single().Level); + } + + [Fact] + public void Uses_Default_ActionName() + { + var fixture = new TestLoggerFixture(); + + var logger = fixture.CreateLogger(); + using (logger.StartProfiler()) + { + } + + Assert.Contains(nameof(Uses_Default_ActionName), fixture.LogEntries.Single().Message); + } + + [Fact] + public void Uses_Provided_ActionName() + { + var fixture = new TestLoggerFixture(); + + var logger = fixture.CreateLogger(); + using (logger.StartProfiler("fetching")) + { + } + + Assert.Contains("fetching", fixture.LogEntries.Single().Message); + } + + [Fact] + public void Uses_Configured_ActionName() + { + var fixture = new TestLoggerFixture(); + LoggerOutputConfiguration.Instance.DefaultLogLevel = LogLevel.Critical; + + var logger = fixture.CreateLogger(); + using (logger.StartProfiler()) + { + } + + Assert.Equal(LogLevel.Critical, fixture.LogEntries.Single().Level); + } + + [Fact] + public void Uses_Default_Message() + { + var fixture = new TestLoggerFixture(); + + var logger = fixture.CreateLogger(); + using (logger.StartProfiler()) + { + } + + Assert.StartsWith($"{nameof(Uses_Default_Message)} finished in", fixture.LogEntries.Single().Message); + } + + [Fact] + public void Uses_Provided_Message() + { + var fixture = new TestLoggerFixture(); + + var logger = fixture.CreateLogger(); + using (logger.StartProfiler(messageFactory: (name, time) => ("action {act} done!", new object[]{name}))) + { + } + + Assert.Equal($"action {nameof(Uses_Provided_Message)} done!", fixture.LogEntries.Single().Message); + } + + [Fact] + public void Uses_Configured_Message() + { + var fixture = new TestLoggerFixture(); + LoggerOutputConfiguration.Instance.DefaultActionMessageFactory = + (name, time) => ("action {act} done!", new object[] { name }); + + var logger = fixture.CreateLogger(); + using (logger.StartProfiler()) + { + } + + Assert.Equal($"action {nameof(Uses_Configured_Message)} done!", fixture.LogEntries.Single().Message); + } +} \ No newline at end of file diff --git a/src/PicoProfiler.Tests/TestLogger/TestLogger.cs b/src/PicoProfiler.Tests/TestLogger/TestLogger.cs new file mode 100644 index 0000000..48c9654 --- /dev/null +++ b/src/PicoProfiler.Tests/TestLogger/TestLogger.cs @@ -0,0 +1,22 @@ +using Microsoft.Extensions.Logging; + +namespace PicoProfiler.Tests.TestLogger; + +internal class TestLogger : ILogger +{ + private readonly TestLoggerProvider _provider; + + public TestLogger(TestLoggerProvider provider) + { + _provider = provider; + } + + public void Log(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func formatter) + { + _provider.Add(logLevel, formatter(state, exception)); + } + + public bool IsEnabled(LogLevel logLevel) => true; + + public IDisposable BeginScope(TState state) => default; +} \ No newline at end of file diff --git a/src/PicoProfiler.Tests/TestLogger/TestLoggerFixture.cs b/src/PicoProfiler.Tests/TestLogger/TestLoggerFixture.cs new file mode 100644 index 0000000..e6bf054 --- /dev/null +++ b/src/PicoProfiler.Tests/TestLogger/TestLoggerFixture.cs @@ -0,0 +1,32 @@ +using Microsoft.Extensions.Logging; + +namespace PicoProfiler.Tests.TestLogger; + +internal class TestLoggerFixture +{ + private readonly TestLoggerProvider _provider = new(); + private ILoggerFactory _factory = null!; + + public IReadOnlyCollection LogEntries + { + get + { + // disposing of factory is the only way to flush. + RecreateFactory(); + return _provider.LogEntries.AsReadOnly(); + } + } + + public TestLoggerFixture() + { + RecreateFactory(); + } + + private void RecreateFactory() + { + _factory?.Dispose(); + _factory = LoggerFactory.Create(x => x.SetMinimumLevel(LogLevel.Trace).AddProvider(_provider)); + } + + public ILogger CreateLogger() => _factory.CreateLogger(); +} \ No newline at end of file diff --git a/src/PicoProfiler.Tests/TestLogger/TestLoggerProvider.cs b/src/PicoProfiler.Tests/TestLogger/TestLoggerProvider.cs new file mode 100644 index 0000000..9b00862 --- /dev/null +++ b/src/PicoProfiler.Tests/TestLogger/TestLoggerProvider.cs @@ -0,0 +1,21 @@ +using Microsoft.Extensions.Logging; + +namespace PicoProfiler.Tests.TestLogger; + +internal class TestLoggerProvider : ILoggerProvider +{ + public record struct LogEntry(LogLevel Level, string Message); + + public List LogEntries { get; } = new(); + + public void Add(LogLevel level, string message) => LogEntries.Add(new LogEntry(level, message)); + + public void Dispose() + { + } + + public ILogger CreateLogger(string categoryName) + { + return new TestLogger(this); + } +} \ No newline at end of file