chore: add hrynco common library solution
- add the standalone HrynCo.Common solution and projects - include the shared common library source and tests - add package metadata and a repo gitignore
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
namespace HrynCo.Common.Tests;
|
||||
|
||||
using System.Collections.Concurrent;
|
||||
using HrynCo.Common;
|
||||
using FluentAssertions;
|
||||
using Serilog;
|
||||
using Serilog.Core;
|
||||
using Serilog.Events;
|
||||
using Xunit;
|
||||
|
||||
public sealed class ProfilerTests
|
||||
{
|
||||
[Fact]
|
||||
public async Task MeasureExecutionAsync_ShouldReturnResultAndWriteStartAndEndEvents()
|
||||
{
|
||||
var sink = new CollectingSink();
|
||||
ILogger logger = new LoggerConfiguration()
|
||||
.MinimumLevel.Verbose()
|
||||
.WriteTo.Sink(sink)
|
||||
.CreateLogger();
|
||||
|
||||
var profiler = new Profiler(logger);
|
||||
|
||||
int result = await profiler.MeasureExecutionAsync(async () =>
|
||||
{
|
||||
await Task.Delay(1);
|
||||
return 42;
|
||||
}, "LoadItems");
|
||||
|
||||
result.Should().Be(42);
|
||||
sink.Events.Count.Should().BeGreaterThan(1);
|
||||
sink.Events.Should().ContainSingle(e =>
|
||||
e.Level == LogEventLevel.Information
|
||||
&& e.MessageTemplate.Text.Contains("Start", StringComparison.Ordinal)
|
||||
&& e.Properties["BlockName"].ToString().Contains("LoadItems", StringComparison.Ordinal));
|
||||
sink.Events.Should().ContainSingle(e =>
|
||||
e.Level == LogEventLevel.Information
|
||||
&& e.MessageTemplate.Text.Contains("End", StringComparison.Ordinal)
|
||||
&& e.Properties["Measurements"].ToString().Contains("True", StringComparison.Ordinal));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task MeasureExecutionAsync_ActionOverload_ShouldInvokeAction()
|
||||
{
|
||||
var sink = new CollectingSink();
|
||||
ILogger logger = new LoggerConfiguration()
|
||||
.MinimumLevel.Verbose()
|
||||
.WriteTo.Sink(sink)
|
||||
.CreateLogger();
|
||||
|
||||
var profiler = new Profiler(logger);
|
||||
bool invoked = false;
|
||||
|
||||
await profiler.MeasureExecutionAsync(async () =>
|
||||
{
|
||||
invoked = true;
|
||||
await Task.CompletedTask;
|
||||
}, "ActionBlock");
|
||||
|
||||
invoked.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task MeasureExecutionAsync_ShouldLogErrorAndRethrow()
|
||||
{
|
||||
var sink = new CollectingSink();
|
||||
ILogger logger = new LoggerConfiguration()
|
||||
.MinimumLevel.Verbose()
|
||||
.WriteTo.Sink(sink)
|
||||
.CreateLogger();
|
||||
|
||||
var profiler = new Profiler(logger);
|
||||
|
||||
Func<Task> act = async () =>
|
||||
{
|
||||
await profiler.MeasureExecutionAsync<int>(() => throw new InvalidOperationException("boom"), "FailBlock");
|
||||
};
|
||||
|
||||
await act.Should().ThrowAsync<InvalidOperationException>();
|
||||
sink.Events.Should().Contain(e =>
|
||||
e.Level == LogEventLevel.Error
|
||||
&& e.MessageTemplate.Text.Contains("An error occurred", StringComparison.Ordinal));
|
||||
}
|
||||
|
||||
private sealed class CollectingSink : ILogEventSink
|
||||
{
|
||||
public ConcurrentQueue<LogEvent> Events { get; } = new();
|
||||
|
||||
public void Emit(LogEvent logEvent)
|
||||
{
|
||||
Events.Enqueue(logEvent);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user