fix: fix ci failed

This commit is contained in:
Meysam Hadeli 2026-02-20 00:25:48 +03:30
parent 2a5909bdbd
commit a62177a6c4
4 changed files with 25 additions and 155 deletions

View File

@ -19,6 +19,12 @@
"commands": [ "commands": [
"aspire" "aspire"
] ]
},
"csharpier": {
"version": "0.30.6",
"commands": [
"dotnet-csharpier"
]
} }
} }
} }

View File

@ -7,8 +7,8 @@
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {
"prepare": "husky && dotnet tool restore", "prepare": "husky && dotnet tool restore",
"format": "dotnet format booking-microservices.sln --severity error --verbosity detailed", "format": "dotnet tool run dotnet-csharpier booking-microservices.sln",
"ci-format": "dotnet format booking-microservices.sln --verify-no-changes --severity error --verbosity detailed", "ci-format": "dotnet tool run dotnet-csharpier booking-microservices.sln --check",
"upgrade-packages": "dotnet outdated --upgrade" "upgrade-packages": "dotnet outdated --upgrade"
}, },
"devDependencies": { "devDependencies": {

View File

@ -136,23 +136,10 @@ public class TestFixture<TEntryPoint> : IAsyncLifetime
{ {
CancellationTokenSource = new CancellationTokenSource(); CancellationTokenSource = new CancellationTokenSource();
await StartTestContainerAsync(); await StartTestContainerAsync();
if (ServiceProvider.GetService<ITestHarness>() is { } harness)
{
await harness.Start();
// Add a small delay to ensure harness is ready
await Task.Delay(1000);
}
} }
public async Task DisposeAsync() public async Task DisposeAsync()
{ {
if (ServiceProvider.GetService<ITestHarness>() is { } harness)
{
await harness.Stop();
}
await StopTestContainerAsync(); await StopTestContainerAsync();
await _factory.DisposeAsync(); await _factory.DisposeAsync();
await CancellationTokenSource.CancelAsync(); await CancellationTokenSource.CancelAsync();
@ -312,13 +299,6 @@ public class TestFixture<TEntryPoint> : IAsyncLifetime
// Start RabbitMQ last and wait extra time // Start RabbitMQ last and wait extra time
await RabbitMqTestContainer.StartAsync(); await RabbitMqTestContainer.StartAsync();
await Task.Delay(5000); // Give RabbitMQ extra time to initialize await Task.Delay(5000); // Give RabbitMQ extra time to initialize
// Verify RabbitMQ is healthy
var healthCheck = await RabbitMqTestContainer.ExecAsync(new[] { "rabbitmq-diagnostics", "ping" });
if (healthCheck.ExitCode != 0)
{
await Task.Delay(5000); // Wait more if not healthy
}
} }
private async Task StopTestContainerAsync() private async Task StopTestContainerAsync()

View File

@ -2,154 +2,38 @@ using BuildingBlocks.Contracts.EventBus.Messages;
using BuildingBlocks.TestBase; using BuildingBlocks.TestBase;
using FluentAssertions; using FluentAssertions;
using Integration.Test.Fakes; using Integration.Test.Fakes;
using Microsoft.Extensions.Logging;
using Passenger.Data; using Passenger.Data;
using Xunit; using Xunit;
using Xunit.Abstractions;
namespace Integration.Test.Passenger.Features; namespace Integration.Test.Passenger.Features;
public class CompleteRegisterPassengerTests : PassengerIntegrationTestBase public class CompleteRegisterPassengerTests : PassengerIntegrationTestBase
{ {
public CompleteRegisterPassengerTests( public CompleteRegisterPassengerTests(
TestFixture<Program, PassengerDbContext, PassengerReadDbContext> integrationTestFactory, TestFixture<Program, PassengerDbContext, PassengerReadDbContext> integrationTestFactory
ITestOutputHelper outputHelper
) )
: base(integrationTestFactory) : base(integrationTestFactory) { }
{
Fixture.Logger = Fixture.CreateLogger(outputHelper);
}
[Fact] [Fact]
public async Task should_complete_register_passenger_and_update_to_db() public async Task should_complete_register_passenger_and_update_to_db()
{ {
// Arrange // Arrange
Fixture.Logger?.LogInformation("Starting CompleteRegisterPassenger test at {Time}", DateTime.UtcNow); var userCreated = new FakeUserCreated().Generate();
try await Fixture.Publish(userCreated);
{ (await Fixture.WaitForPublishing<UserCreated>()).Should().Be(true);
// Generate and publish UserCreated event (await Fixture.WaitForConsuming<UserCreated>()).Should().Be(true);
var userCreated = new FakeUserCreated().Generate();
Fixture.Logger?.LogInformation(
"Generated UserCreated event with PassportNumber: {PassportNumber}",
userCreated.PassportNumber
);
await Fixture.Publish(userCreated); var command = new FakeCompleteRegisterPassengerCommand(userCreated.PassportNumber).Generate();
Fixture.Logger?.LogInformation("Published UserCreated event");
// Wait for publishing with retry logic // Act
var published = await WaitForWithRetry( var response = await Fixture.SendAsync(command);
async () => await Fixture.WaitForPublishing<UserCreated>(),
"publishing",
maxRetries: 3
);
published.Should().BeTrue("UserCreated event should be published to message broker"); // Assert
Fixture.Logger?.LogInformation("UserCreated event published successfully"); response.Should().NotBeNull();
response?.PassengerDto?.Name.Should().Be(userCreated.Name);
// Wait for consuming with retry logic response?.PassengerDto?.PassportNumber.Should().Be(command.PassportNumber);
var consumed = await WaitForWithRetry( response?.PassengerDto?.PassengerType.ToString().Should().Be(command.PassengerType.ToString());
async () => await Fixture.WaitForConsuming<UserCreated>(), response?.PassengerDto?.Age.Should().Be(command.Age);
"consuming",
maxRetries: 5
);
consumed.Should().BeTrue("UserCreated event should be consumed by the passenger service");
Fixture.Logger?.LogInformation("UserCreated event consumed successfully");
// Small delay to ensure event processing is complete
await Task.Delay(1000);
// Generate and send complete registration command
var command = new FakeCompleteRegisterPassengerCommand(userCreated.PassportNumber).Generate();
Fixture.Logger?.LogInformation(
"Sending CompleteRegisterPassenger command for PassportNumber: {PassportNumber}",
command.PassportNumber
);
// Act
var response = await Fixture.SendAsync(command);
Fixture.Logger?.LogInformation("Received response for CompleteRegisterPassenger command");
// Assert with detailed logging
response.Should().NotBeNull("Response should not be null");
Fixture.Logger?.LogInformation("Response is not null");
response?.PassengerDto.Should().NotBeNull("PassengerDto should not be null");
response
?.PassengerDto?.Name.Should()
.Be(
userCreated.Name,
$"Passenger name should be '{userCreated.Name}' but was '{response?.PassengerDto?.Name}'"
);
response
?.PassengerDto?.PassportNumber.Should()
.Be(
command.PassportNumber,
$"Passport number should be '{command.PassportNumber}' but was '{response?.PassengerDto?.PassportNumber}'"
);
response
?.PassengerDto?.PassengerType.ToString()
.Should()
.Be(
command.PassengerType.ToString(),
$"Passenger type should be '{command.PassengerType}' but was '{response?.PassengerDto?.PassengerType}'"
);
response
?.PassengerDto?.Age.Should()
.Be(command.Age, $"Age should be {command.Age} but was {response?.PassengerDto?.Age}");
Fixture.Logger?.LogInformation("All assertions passed successfully");
}
catch (Exception ex)
{
Fixture.Logger?.LogError(ex, "Test failed with exception: {Message}", ex.Message);
throw;
}
finally
{
Fixture.Logger?.LogInformation("Test completed at {Time}", DateTime.UtcNow);
}
}
private async Task<bool> WaitForWithRetry(Func<Task<bool>> waitCondition, string operation, int maxRetries = 3)
{
for (int i = 0; i < maxRetries; i++)
{
Fixture.Logger?.LogInformation(
"Attempt {Attempt}/{MaxRetries} for {Operation}",
i + 1,
maxRetries,
operation
);
var result = await waitCondition();
if (result)
{
Fixture.Logger?.LogInformation("{Operation} successful on attempt {Attempt}", operation, i + 1);
return true;
}
if (i < maxRetries - 1)
{
var delaySeconds = (i + 1) * 2; // Exponential backoff: 2, 4, 6 seconds
Fixture.Logger?.LogWarning(
"{Operation} failed on attempt {Attempt}, waiting {Delay}s before retry",
operation,
i + 1,
delaySeconds
);
await Task.Delay(TimeSpan.FromSeconds(delaySeconds));
}
}
Fixture.Logger?.LogError("{Operation} failed after {MaxRetries} attempts", operation, maxRetries);
return false;
} }
} }