79 lines
2.9 KiB
C#
79 lines
2.9 KiB
C#
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Microsoft.Extensions.Options;
|
|
using Nexus.Api.Data;
|
|
using Nexus.Api.Services;
|
|
using Testcontainers.PostgreSql;
|
|
using Xunit;
|
|
|
|
namespace Nexus.Api.Tests;
|
|
|
|
[Collection(DockerIntegrationTestEnvironment.CollectionName)]
|
|
public sealed class PostgresOpenClawOperationAuditStoreIntegrationTests
|
|
{
|
|
[PostgreSqlIntegrationFact]
|
|
[Trait("Category", "DockerIntegration")]
|
|
public async Task Concurrent_store_instances_create_one_claim_and_one_in_doubt_result()
|
|
{
|
|
await using var postgres = new PostgreSqlBuilder("postgres:17-alpine")
|
|
.WithDatabase("nexus_claims")
|
|
.WithUsername("nexus_test")
|
|
.WithPassword("nexus_test_password")
|
|
.Build();
|
|
await postgres.StartAsync();
|
|
var connectionString = postgres.GetConnectionString();
|
|
|
|
await using (var db = CreateDatabase(connectionString))
|
|
await db.Database.MigrateAsync();
|
|
|
|
await using var firstProvider = CreateProvider(connectionString);
|
|
await using var secondProvider = CreateProvider(connectionString);
|
|
var first = CreateStore(firstProvider);
|
|
var second = CreateStore(secondProvider);
|
|
var context = OpenClawInvocationContext.Create(
|
|
"owner",
|
|
"postgres-race-key",
|
|
"postgres-race-correlation");
|
|
var operation = new OpenClawOperationDescriptor(
|
|
"cron.run",
|
|
"cron-job",
|
|
"job-1",
|
|
OpenClawInvocationContextFactory.Hash("same-intent"));
|
|
|
|
var results = await Task.WhenAll(
|
|
first.ClaimAsync(context, operation),
|
|
second.ClaimAsync(context, operation));
|
|
|
|
Assert.Single(
|
|
results,
|
|
item => item.Disposition ==
|
|
OpenClawOperationClaimDisposition.Started);
|
|
Assert.Single(
|
|
results,
|
|
item => item.Disposition ==
|
|
OpenClawOperationClaimDisposition.InDoubt);
|
|
|
|
await using var verification = CreateDatabase(connectionString);
|
|
Assert.Single(await verification.OperationClaims.ToArrayAsync());
|
|
}
|
|
|
|
private static NexusDbContext CreateDatabase(string connectionString)
|
|
=> new(new DbContextOptionsBuilder<NexusDbContext>()
|
|
.UseNpgsql(connectionString)
|
|
.Options);
|
|
|
|
private static ServiceProvider CreateProvider(string connectionString)
|
|
{
|
|
var services = new ServiceCollection();
|
|
services.AddDbContext<NexusDbContext>(options =>
|
|
options.UseNpgsql(connectionString));
|
|
return services.BuildServiceProvider();
|
|
}
|
|
|
|
private static PostgresOpenClawOperationAuditStore CreateStore(
|
|
ServiceProvider provider)
|
|
=> new(
|
|
provider.GetRequiredService<IServiceScopeFactory>(),
|
|
Options.Create(new GatewayConnectorOptions()));
|
|
}
|