Created
August 29, 2024 15:04
-
-
Save Aaronontheweb/77cd8736c7b1739bcf8086a3a3fe70c8 to your computer and use it in GitHub Desktop.
Akka.NET Integration Testing with WebApplicationFactory
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
// ----------------------------------------------------------------------- | |
// <copyright file="AspDotNetClusteredRouterIntegrationSpec.cs" company="Petabridge, LLC"> | |
// Copyright (C) 2021 - 2021 Petabridge, LLC <https://petabridge.com> | |
// </copyright> | |
// ----------------------------------------------------------------------- | |
using System.Threading.Tasks; | |
using Phobos.Actor.Cluster.Integration.Tests.Services; | |
using Xunit; | |
using Xunit.Abstractions; | |
namespace Phobos.Actor.Cluster.Integration.Tests | |
{ | |
[Collection("AspNet")] | |
public class AspDotNetClusteredRouterIntegrationSpec : IClassFixture<CustomWebApplicationFactory<ClusterStartup>> | |
{ | |
private readonly CustomWebApplicationFactory<ClusterStartup> _factory; | |
private readonly ITestOutputHelper _output; | |
public AspDotNetClusteredRouterIntegrationSpec(CustomWebApplicationFactory<ClusterStartup> factory, | |
ITestOutputHelper output) | |
{ | |
_factory = factory; | |
_output = output; | |
} | |
/// <summary> | |
/// Bug reproduction for https://github.com/petabridge/phobos/issues/619 | |
/// </summary> | |
[Fact] | |
public async Task ShouldTraceFromControllerToChr() | |
{ | |
// Arrange | |
using var client = _factory.CreateClient(); | |
// Act | |
var response = await client.GetAsync("test/cluster-router"); | |
// Assert | |
response.EnsureSuccessStatusCode(); // Status Code 200-299 | |
var sp = _factory.Services; | |
await TestHelpers.AwaitSingleTrace(sp, 3, _output); | |
} | |
} | |
} |
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
// ----------------------------------------------------------------------- | |
// <copyright file="ClusterStartup.cs" company="Petabridge, LLC"> | |
// Copyright (C) 2021 - 2021 Petabridge, LLC <https://petabridge.com> | |
// </copyright> | |
// ----------------------------------------------------------------------- | |
using System.Collections.Generic; | |
using System.Diagnostics; | |
using Microsoft.AspNetCore.Builder; | |
using Microsoft.AspNetCore.Hosting; | |
using Microsoft.Extensions.Configuration; | |
using Microsoft.Extensions.DependencyInjection; | |
using OpenTelemetry; | |
using OpenTelemetry.Exporter; | |
using OpenTelemetry.Metrics; | |
using OpenTelemetry.Trace; | |
using Phobos.Tracing; | |
namespace Phobos.Actor.Cluster.Integration.Tests.Services | |
{ | |
public class ClusterStartup | |
{ | |
public ClusterStartup(IConfiguration configuration, IWebHostEnvironment env) | |
{ | |
Configuration = configuration; | |
Env = env; | |
} | |
public IConfiguration Configuration { get; } | |
public IWebHostEnvironment Env { get; } | |
// This method gets called by the runtime. Use this method to add services to the container. | |
public void ConfigureServices(IServiceCollection services) | |
{ | |
services.AddSingleton<List<Activity>>(); | |
services.AddSingleton<List<Metric>>(); | |
services.AddOpenTelemetry() | |
.WithTracing(builder => | |
{ | |
builder | |
.AddAspNetCoreInstrumentation() | |
.AddHttpClientInstrumentation() | |
.AddPhobosInstrumentation(); | |
}) | |
.WithMetrics(builder => | |
{ | |
builder.AddPhobosInstrumentation(); | |
}); | |
services.ConfigureOpenTelemetryTracerProvider((provider, providerBuilder) => | |
{ | |
var traces = provider.GetRequiredService<List<Activity>>(); | |
providerBuilder.AddInMemoryExporter(traces); | |
}); | |
services.ConfigureOpenTelemetryMeterProvider((provider, providerBuilder) => | |
{ | |
var metrics = provider.GetRequiredService<List<Metric>>(); | |
providerBuilder.AddReader(new BaseExportingMetricReader(new InMemoryExporter<Metric>(metrics)) | |
{ | |
TemporalityPreference = MetricReaderTemporalityPreference.Cumulative | |
}); | |
}); | |
services.AddSingleton(serviceProvider => | |
{ | |
var traces = serviceProvider.GetRequiredService<List<Activity>>(); | |
var providerBuilder = serviceProvider.GetRequiredService<TracerProvider>(); | |
var tracer = providerBuilder.GetTracer(ActorTracing.PhobosActivitySourceName); | |
return new TracerPayload(traces, providerBuilder, tracer); | |
}); | |
services.AddSingleton<IClusterTestService, AkkaClusterService>(); | |
services.AddHostedService(sp => (AkkaClusterService)sp.GetRequiredService<IClusterTestService>()); | |
services.AddControllers(); | |
} | |
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. | |
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) | |
{ | |
app.UseRouting(); | |
app.UseEndpoints(c => c.MapControllers()); | |
// workaround for https://github.com/open-telemetry/opentelemetry-dotnet/issues/2806 | |
using (var scope = app.ApplicationServices.CreateScope()) | |
{ | |
var services = scope.ServiceProvider; | |
// BUGFIX | |
var context = services.GetRequiredService<TracerPayload>(); | |
using (var trace = context.Tracer.StartRootSpan("TEST")) | |
{ | |
} | |
context.Provider.ForceFlush(); | |
context.Reset(); | |
} | |
} | |
} | |
} |
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
// ----------------------------------------------------------------------- | |
// <copyright file="CustomWebApplicationFactory.cs" company="Petabridge, LLC"> | |
// Copyright (C) 2021 - 2021 Petabridge, LLC <https://petabridge.com> | |
// </copyright> | |
// ----------------------------------------------------------------------- | |
using System.IO; | |
using Microsoft.AspNetCore.Hosting; | |
using Microsoft.AspNetCore.Mvc.Testing; | |
using Microsoft.AspNetCore.TestHost; | |
using Microsoft.Extensions.Hosting; | |
namespace Phobos.Actor.Cluster.Integration.Tests | |
{ | |
public class CustomWebApplicationFactory<TStartup> : WebApplicationFactory<TStartup> where TStartup : class | |
{ | |
protected override IHostBuilder CreateHostBuilder() | |
{ | |
var builder = Host.CreateDefaultBuilder() | |
.ConfigureWebHostDefaults(x => { x.UseTestServer(); }) | |
.UseContentRoot(Path.Combine(Directory.GetCurrentDirectory(), "src", "core", | |
"Phobos.Actor.Cluster.Integration.Tests")); | |
return builder; | |
} | |
protected override void ConfigureWebHost(IWebHostBuilder builder) | |
{ | |
builder.UseStartup<TStartup>().UseSolutionRelativeContentRoot(""); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Worth noting: this code pre-dates the creation of Akka.Hosting, which is a better way to try and do this. This is still part of our active test suite for Phobos using ASP.NET Core 8.0 at the time of writing.