/
MiddlewareLoggerIntegration.cs
121 lines (103 loc) · 4.53 KB
/
MiddlewareLoggerIntegration.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#if NETCOREAPP2_1 || NET461
using IHostingEnvironment = Microsoft.AspNetCore.Hosting.IHostingEnvironment;
#else
using IHostingEnvironment = Microsoft.AspNetCore.Hosting.IWebHostEnvironment;
#endif
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.Extensions.Logging;
using Sentry.Extensions.Logging;
using Sentry.Testing;
namespace Sentry.AspNetCore.Tests;
// Uses a shared Hub between the Middleware and the LoggerProvider
// Tests the integration of these 3 objects
public class MiddlewareLoggerIntegration : IDisposable
{
private class Fixture : IDisposable
{
public RequestDelegate RequestDelegate { get; set; } = _ => Task.CompletedTask;
public IHub Hub { get; set; }
public Func<IHub> HubAccessor { get; set; }
public ISentryClient Client { get; set; } = Substitute.For<ISentryClient>();
public SentryAspNetCoreOptions Options { get; set; } = new();
public IHostingEnvironment HostingEnvironment { get; set; } = Substitute.For<IHostingEnvironment>();
public ILogger<SentryMiddleware> MiddlewareLogger { get; set; } = Substitute.For<ILogger<SentryMiddleware>>();
public ILogger SentryLogger { get; set; }
public HttpContext HttpContext { get; set; } = Substitute.For<HttpContext>();
public IFeatureCollection FeatureCollection { get; set; } = Substitute.For<IFeatureCollection>();
private readonly IDisposable _disposable;
public Fixture()
{
HubAccessor = () => Hub;
var loggingOptions = new SentryLoggingOptions
{
InitializeSdk = false,
};
loggingOptions.InitializeSdk = false;
Client.When(client => client.CaptureEvent(Arg.Any<SentryEvent>(), Arg.Any<Scope>()))
.Do(callback => callback.Arg<Scope>().Evaluate());
var hub = new Hub(new SentryOptions { Dsn = ValidDsn });
hub.BindClient(Client);
Hub = hub;
var provider = new SentryLoggerProvider(hub, new MockClock(), loggingOptions);
_disposable = provider;
SentryLogger = provider.CreateLogger(nameof(SentryLogger));
_ = HttpContext.Features.Returns(FeatureCollection);
}
public SentryMiddleware GetSut()
=> new(
RequestDelegate,
HubAccessor,
Microsoft.Extensions.Options.Options.Create(Options),
HostingEnvironment,
MiddlewareLogger);
public void Dispose() => _disposable.Dispose();
}
private readonly Fixture _fixture = new();
[Fact]
public async Task InvokeAsync_LoggerMessage_AsBreadcrumb()
{
const string expectedCrumb = "expect this";
_fixture.RequestDelegate = _ =>
{
_fixture.SentryLogger.LogInformation(expectedCrumb);
throw new Exception();
};
var sut = _fixture.GetSut();
_ = await Assert.ThrowsAsync<Exception>(async () => await sut.InvokeAsync(_fixture.HttpContext));
_ = _fixture.Client.Received(1).CaptureEvent(
Arg.Any<SentryEvent>(),
Arg.Is<Scope>(e => e.Breadcrumbs.Any(b => b.Message == expectedCrumb)));
}
[Fact]
public async Task InvokeAsync_LoggerPushesScope_LoggerMessage_AsBreadcrumb()
{
const string expectedCrumb = "expect this";
_fixture.RequestDelegate = _ =>
{
using (_fixture.SentryLogger.BeginScope("scope"))
{
_fixture.SentryLogger.LogInformation(expectedCrumb);
}
throw new Exception();
};
var sut = _fixture.GetSut();
_ = await Assert.ThrowsAsync<Exception>(async () => await sut.InvokeAsync(_fixture.HttpContext));
_ = _fixture.Client.Received(1).CaptureEvent(
Arg.Any<SentryEvent>(),
Arg.Is<Scope>(e => e.Breadcrumbs.Any(b => b.Message == expectedCrumb)));
}
[Fact]
public async Task InvokeAsync_OptionsConfigureScope_AffectsAllRequests()
{
const SentryLevel expected = SentryLevel.Debug;
_fixture.Options.ConfigureScope(s => s.Level = expected);
_fixture.RequestDelegate = _ => throw new Exception();
var sut = _fixture.GetSut();
_ = await Assert.ThrowsAsync<Exception>(async () => await sut.InvokeAsync(_fixture.HttpContext));
_ = _fixture.Client.Received(1).CaptureEvent(
Arg.Any<SentryEvent>(),
Arg.Is<Scope>(e => e.Level == expected));
}
public void Dispose() => _fixture.Dispose();
}