-
-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'master' into parcel-babel-jest
- Loading branch information
Showing
57 changed files
with
1,319 additions
and
432 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
using System.Threading.Tasks; | ||
using BackendFramework.Interfaces; | ||
using BackendFramework.Otel; | ||
|
||
namespace Backend.Tests.Mocks | ||
{ | ||
sealed internal class LocationProviderMock : ILocationProvider | ||
{ | ||
public Task<LocationApi?> GetLocation() | ||
{ | ||
LocationApi location = new LocationApi | ||
{ | ||
Country = "test country", | ||
RegionName = "test region", | ||
City = "city" | ||
}; | ||
return Task.FromResult<LocationApi?>(location); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
using System; | ||
using System.Net; | ||
using System.Net.Http; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using BackendFramework.Otel; | ||
using Microsoft.AspNetCore.Http; | ||
using Microsoft.Extensions.Caching.Memory; | ||
using Microsoft.Extensions.DependencyInjection; | ||
using Moq; | ||
using Moq.Protected; | ||
using NUnit.Framework; | ||
|
||
namespace Backend.Tests.Otel | ||
{ | ||
public class LocationProviderTests | ||
{ | ||
private readonly IPAddress TestIpAddress = new(new byte[] { 100, 0, 0, 0 }); | ||
private IHttpContextAccessor _contextAccessor = null!; | ||
private IMemoryCache _memoryCache = null!; | ||
private Mock<HttpMessageHandler> _handlerMock = null!; | ||
private Mock<IHttpClientFactory> _httpClientFactory = null!; | ||
private LocationProvider _locationProvider = null!; | ||
|
||
[SetUp] | ||
public void Setup() | ||
{ | ||
// Set up HttpContextAccessor with mocked IP | ||
_contextAccessor = new HttpContextAccessor(); | ||
var httpContext = new DefaultHttpContext() | ||
{ | ||
Connection = | ||
{ | ||
RemoteIpAddress = TestIpAddress | ||
} | ||
}; | ||
_contextAccessor.HttpContext = httpContext; | ||
|
||
// Set up MemoryCache | ||
var services = new ServiceCollection(); | ||
services.AddMemoryCache(); | ||
var serviceProvider = services.BuildServiceProvider(); | ||
_memoryCache = serviceProvider.GetService<IMemoryCache>()!; | ||
|
||
var result = new HttpResponseMessage() | ||
{ | ||
StatusCode = HttpStatusCode.OK, | ||
Content = new StringContent("{}") | ||
}; | ||
|
||
// Set up HttpClientFactory mock using httpClient with mocked HttpMessageHandler | ||
_handlerMock = new Mock<HttpMessageHandler>(); | ||
_handlerMock.Protected() | ||
.Setup<Task<HttpResponseMessage>>( | ||
"SendAsync", | ||
ItExpr.IsAny<HttpRequestMessage>(), | ||
ItExpr.IsAny<CancellationToken>() | ||
) | ||
.ReturnsAsync(result) | ||
.Verifiable(); | ||
|
||
var httpClient = new HttpClient(_handlerMock.Object); | ||
_httpClientFactory = new Mock<IHttpClientFactory>(); | ||
_httpClientFactory | ||
.Setup(x => x.CreateClient(It.IsAny<string>())) | ||
.Returns(httpClient); | ||
|
||
_locationProvider = new LocationProvider(_contextAccessor, _memoryCache, _httpClientFactory.Object); | ||
} | ||
|
||
public static void Verify(Mock<HttpMessageHandler> mock, Func<HttpRequestMessage, bool> match) | ||
{ | ||
mock.Protected() | ||
.Verify( | ||
"SendAsync", | ||
Times.Exactly(1), | ||
ItExpr.Is<HttpRequestMessage>(req => match(req)), | ||
ItExpr.IsAny<CancellationToken>() | ||
); | ||
} | ||
|
||
[Test] | ||
public async Task GetLocationHttpClientUsesIp() | ||
{ | ||
// Act | ||
await _locationProvider.GetLocationFromIp(TestIpAddress.ToString()); | ||
|
||
// Assert | ||
Verify(_handlerMock, r => r.RequestUri!.AbsoluteUri.Contains(TestIpAddress.ToString())); | ||
Verify(_handlerMock, r => !r.RequestUri!.AbsoluteUri.Contains("123.1.2.3")); | ||
} | ||
|
||
[Test] | ||
public async Task GetLocationUsesHttpContextIp() | ||
{ | ||
// Act | ||
await _locationProvider.GetLocation(); | ||
|
||
// Assert | ||
Verify(_handlerMock, r => r.RequestUri!.AbsoluteUri.Contains(TestIpAddress.ToString())); | ||
Verify(_handlerMock, r => !r.RequestUri!.AbsoluteUri.Contains("123.1.2.3")); | ||
} | ||
|
||
[Test] | ||
public async Task GetLocationUsesCache() | ||
{ | ||
// Act | ||
// call getLocation twice and verify async method is called only once | ||
await _locationProvider.GetLocation(); | ||
await _locationProvider.GetLocation(); | ||
|
||
// Assert | ||
Verify(_handlerMock, r => r.RequestUri!.AbsoluteUri.Contains(TestIpAddress.ToString())); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Diagnostics; | ||
using System.Linq; | ||
using Backend.Tests.Mocks; | ||
using BackendFramework.Otel; | ||
using Microsoft.AspNetCore.Http; | ||
using NUnit.Framework; | ||
using static BackendFramework.Otel.OtelKernel; | ||
|
||
namespace Backend.Tests.Otel | ||
{ | ||
public class OtelKernelTests : IDisposable | ||
{ | ||
private const string FrontendSessionIdKey = "sessionId"; | ||
private const string OtelSessionIdKey = "sessionId"; | ||
private const string OtelSessionBaggageKey = "sessionBaggage"; | ||
private LocationEnricher _locationEnricher = null!; | ||
|
||
public void Dispose() | ||
{ | ||
Dispose(true); | ||
GC.SuppressFinalize(this); | ||
} | ||
|
||
protected virtual void Dispose(bool disposing) | ||
{ | ||
if (disposing) | ||
{ | ||
_locationEnricher?.Dispose(); | ||
} | ||
} | ||
|
||
[Test] | ||
public void BuildersSetSessionBaggageFromHeader() | ||
{ | ||
// Arrange | ||
var httpContext = new DefaultHttpContext(); | ||
httpContext.Request.Headers[FrontendSessionIdKey] = "123"; | ||
var activity = new Activity("testActivity").Start(); | ||
|
||
// Act | ||
TrackSession(activity, httpContext.Request); | ||
|
||
// Assert | ||
Assert.That(activity.Baggage.Any(_ => _.Key == OtelSessionBaggageKey)); | ||
} | ||
|
||
[Test] | ||
public void OnEndSetsSessionTagFromBaggage() | ||
{ | ||
// Arrange | ||
var activity = new Activity("testActivity").Start(); | ||
activity.SetBaggage(OtelSessionBaggageKey, "test session id"); | ||
|
||
// Act | ||
_locationEnricher.OnEnd(activity); | ||
|
||
// Assert | ||
Assert.That(activity.Tags.Any(_ => _.Key == OtelSessionIdKey)); | ||
} | ||
|
||
|
||
[Test] | ||
public void OnEndSetsLocationTags() | ||
{ | ||
// Arrange | ||
_locationEnricher = new LocationEnricher(new LocationProviderMock()); | ||
var activity = new Activity("testActivity").Start(); | ||
|
||
// Act | ||
_locationEnricher.OnEnd(activity); | ||
|
||
// Assert | ||
var testLocation = new Dictionary<string, string> | ||
{ | ||
{"country", "test country"}, | ||
{"regionName", "test region"}, | ||
{"city", "city"} | ||
}; | ||
Assert.That(activity.Tags, Is.SupersetOf(testLocation)); | ||
} | ||
|
||
public void OnEndRedactsIp() | ||
{ | ||
// Arrange | ||
_locationEnricher = new LocationEnricher(new LocationProviderMock()); | ||
var activity = new Activity("testActivity").Start(); | ||
activity.SetTag("url.full", $"{LocationProvider.locationGetterUri}100.0.0.0"); | ||
|
||
// Act | ||
_locationEnricher.OnEnd(activity); | ||
|
||
// Assert | ||
Assert.That(activity.Tags.Any(_ => _.Key == "url.full" && _.Value == "")); | ||
Assert.That(activity.Tags.Any(_ => _.Key == "url.redacted.ip" && _.Value == LocationProvider.locationGetterUri)); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
using System.Diagnostics; | ||
using BackendFramework.Otel; | ||
using Microsoft.Extensions.DependencyInjection; | ||
using NUnit.Framework; | ||
|
||
namespace Backend.Tests.Otel | ||
{ | ||
public class OtelServiceTests | ||
{ | ||
[Test] | ||
public static void TestStartActivityWithTag() | ||
{ | ||
// Arrange | ||
var services = new ServiceCollection(); | ||
services.AddOpenTelemetryInstrumentation(); | ||
AddActivityListener(); | ||
|
||
// Act | ||
var activity = OtelService.StartActivityWithTag("test key", "test val"); | ||
var tag = activity?.GetTagItem("test key"); | ||
var wrongTag = activity?.GetTagItem("wrong key"); | ||
|
||
// Assert | ||
Assert.That(activity, Is.Not.Null); | ||
Assert.That(tag, Is.Not.Null); | ||
Assert.That(wrongTag, Is.Null); | ||
} | ||
|
||
private static void AddActivityListener() | ||
{ | ||
var activityListener = new ActivityListener | ||
{ | ||
ShouldListenTo = _ => true, | ||
Sample = (ref ActivityCreationOptions<ActivityContext> _) => ActivitySamplingResult.AllData | ||
}; | ||
ActivitySource.AddActivityListener(activityListener); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.