-
Notifications
You must be signed in to change notification settings - Fork 123
Open
Description
In api project i use Microsoft.FeatureManagement library and it works until i want to run tests in parallel.
to fix the problem i tried to put lock and it works, but it's the same that run then tests sequentially
// Static lock to prevent concurrent host/server initialization across factory instances
// This prevents race conditions in service registration (e.g., AddFeatureManagement)
// while still allowing each test class to have its own factory instance
private static readonly object _hostCreationLock = new object();
/// <summary>
/// Override CreateHost to synchronize host creation across parallel factory instances.
/// This ensures service registration (including AddFeatureManagement) happens sequentially,
/// preventing race conditions while still allowing parallel test execution.
/// </summary>
protected override IHost CreateHost(IHostBuilder builder)
{
lock (_hostCreationLock)
{
return base.CreateHost(builder);
}
}using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
public class CustomWebApplicationFactory : WebApplicationFactory<AssemblyMarker>
{
private HttpMessageHandler? _optiConfigHttpMessageHandler;
public void SetOptiConfigHttpMessageHandler(HttpMessageHandler handler)
{
_optiConfigHttpMessageHandler = handler;
}
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
builder.ConfigureServices(services =>
{
// Configure logging for tests
services.AddLogging(logging =>
{
logging.ClearProviders();
logging.AddSimpleConsole(options =>
{
options.SingleLine = true;
options.TimestampFormat = "HH:mm:ss.fff ";
options.UseUtcTimestamp = true;
options.IncludeScopes = false;
});
logging.SetMinimumLevel(LogLevel.Debug);
});
});
}
}
using Api.Private.IntegrationTests.Infrastructure;
using Identity.Tests.Shared.Mocking.ExternalIdentityProvider;
using Microsoft.Extensions.DependencyInjection;
using Shouldly;
namespace Api.Private.IntegrationTests.GraphQL.Dashboards.OptiLeads;
public class GetSalesRealisedTests : IClassFixture<CustomWebApplicationFactory>, IDisposable
{
private readonly IServiceScope _scope;
private readonly IPrivateClient _client;
private readonly HttpClient _httpClient;
private readonly ITestContextAccessor _testContextAccessor;
public GetSalesRealisedTests(
CustomWebApplicationFactory factory,
ITestContextAccessor testContextAccessor)
{
_testContextAccessor = testContextAccessor;
// Create a scope from the factory's services
_scope = factory.Services.CreateScope();
// Configure the test HttpClient with the correct BaseAddress
_httpClient = factory.CreateClient();
_httpClient.BaseAddress =
new Uri(_httpClient.BaseAddress ?? new Uri("http://localhost"), "/graphql-private");
factory.Server.PreserveExecutionContext = true;
// Register the TestHttpClientFactory in the scope
var services = new ServiceCollection();
services.AddSingleton<IHttpClientFactory>(_ => new TestHttpClientFactory(_httpClient));
services.AddPrivateClient();
var serviceProvider = services.BuildServiceProvider();
_client = serviceProvider.GetRequiredService<IPrivateClient>();
}
[Fact]
public async Task GetSalesRealised_ReturnsDataForUserWithPermissions()
{
}
public void Dispose()
{
_scope.Dispose();
_httpClient.Dispose();
}
}at System.Collections.Generic.List`1.Enumerator.MoveNext()
at System.Linq.Enumerable.Any[TSource](IEnumerable`1 source, Func`2 predicate)
at Microsoft.FeatureManagement.FeatureManagementBuilder.AddFeatureFilter[T]()
at Microsoft.FeatureManagement.ServiceCollectionExtensions.GetFeatureManagementBuilder(IServiceCollection services)
at Microsoft.FeatureManagement.ServiceCollectionExtensions.AddFeatureManagement(IServiceCollection services)
at API.CompositionRoot.addFeatureManagements(IServiceCollection services) in /Users/admin/Works/NewOne/backend/src/API/CompositionRoot.fs:line 373
at API.CompositionRoot.compose(IConfiguration cfg, IServiceCollection services) in /Users/admin/Works/NewOne/backend/src/API/CompositionRoot.fs:line 399
at <StartupCode$API>.$Program.main@() in /Users/admin/Works/NewOne/backend/src/API/Program.fs:line 43
at InvokeStub_$Program.main@(Object, Object, IntPtr*)
at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
massimilianokraus-kappas and PoojaRameshDalvi
Metadata
Metadata
Assignees
Labels
No labels