Frontend gaps fill work. Testing fixes work. Auditing in progress.
This commit is contained in:
@@ -160,33 +160,43 @@ public sealed class PostgresFixture : IAsyncDisposable
|
||||
await using var connection = new NpgsqlConnection(_connectionString);
|
||||
await connection.OpenAsync(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
// Get all tables in the schema
|
||||
// Get all non-system tables so hard-coded schemas (e.g., vuln) are also truncated.
|
||||
await using var getTablesCmd = new NpgsqlCommand(
|
||||
"""
|
||||
SELECT table_name FROM information_schema.tables
|
||||
WHERE table_schema = @schema AND table_type = 'BASE TABLE'
|
||||
AND table_name != 'schema_migrations';
|
||||
SELECT table_schema, table_name
|
||||
FROM information_schema.tables
|
||||
WHERE table_type = 'BASE TABLE'
|
||||
AND table_schema NOT IN ('pg_catalog', 'information_schema')
|
||||
AND table_schema NOT LIKE 'pg_%'
|
||||
AND table_name != 'schema_migrations';
|
||||
""",
|
||||
connection);
|
||||
getTablesCmd.Parameters.AddWithValue("schema", _schemaName);
|
||||
|
||||
var tables = new List<string>();
|
||||
await using (var reader = await getTablesCmd.ExecuteReaderAsync(cancellationToken).ConfigureAwait(false))
|
||||
{
|
||||
while (await reader.ReadAsync(cancellationToken).ConfigureAwait(false))
|
||||
{
|
||||
tables.Add(reader.GetString(0));
|
||||
var schema = reader.GetString(0);
|
||||
var table = reader.GetString(1);
|
||||
tables.Add($"{QuoteIdentifier(schema)}.{QuoteIdentifier(table)}");
|
||||
}
|
||||
}
|
||||
|
||||
if (tables.Count == 0) return;
|
||||
|
||||
// Truncate all tables
|
||||
var truncateSql = $"TRUNCATE TABLE {string.Join(", ", tables.Select(t => $"{_schemaName}.{t}"))} CASCADE;";
|
||||
var truncateSql = $"TRUNCATE TABLE {string.Join(", ", tables)} CASCADE;";
|
||||
await using var truncateCmd = new NpgsqlCommand(truncateSql, connection);
|
||||
await truncateCmd.ExecuteNonQueryAsync(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
_logger.LogDebug("Truncated {Count} tables in schema {Schema}", tables.Count, _schemaName);
|
||||
_logger.LogDebug("Truncated {Count} tables across non-system schemas", tables.Count);
|
||||
}
|
||||
|
||||
private static string QuoteIdentifier(string identifier)
|
||||
{
|
||||
var escaped = identifier.Replace("\"", "\"\"", StringComparison.Ordinal);
|
||||
return $"\"{escaped}\"";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -9,11 +9,11 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="FsCheck.Xunit" />
|
||||
<PackageReference Include="FsCheck.Xunit.v3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\StellaOps.Resolver\StellaOps.Resolver.csproj" />
|
||||
<ProjectReference Include="../StellaOps.TestKit/StellaOps.TestKit.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
||||
@@ -134,19 +134,19 @@ public abstract class ConnectorLiveSchemaTestBase : IAsyncLifetime
|
||||
/// </summary>
|
||||
public IReadOnlyList<FixtureDriftReport> DriftReports => _driftReports.AsReadOnly();
|
||||
|
||||
public Task InitializeAsync()
|
||||
public ValueTask InitializeAsync()
|
||||
{
|
||||
foreach (var (key, value) in RequestHeaders)
|
||||
{
|
||||
_httpClient.DefaultRequestHeaders.TryAddWithoutValidation(key, value);
|
||||
}
|
||||
return Task.CompletedTask;
|
||||
return ValueTask.CompletedTask;
|
||||
}
|
||||
|
||||
public Task DisposeAsync()
|
||||
public ValueTask DisposeAsync()
|
||||
{
|
||||
_httpClient.Dispose();
|
||||
return Task.CompletedTask;
|
||||
return ValueTask.CompletedTask;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -191,3 +191,7 @@ public sealed class LiveTheoryAttribute : TheoryAttribute
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -69,12 +69,12 @@ public sealed class PostgresFixture : IAsyncLifetime
|
||||
/// </summary>
|
||||
public ushort Port => _container.GetMappedPublicPort(5432);
|
||||
|
||||
public async Task InitializeAsync()
|
||||
public async ValueTask InitializeAsync()
|
||||
{
|
||||
await _container.StartAsync();
|
||||
}
|
||||
|
||||
public async Task DisposeAsync()
|
||||
public async ValueTask DisposeAsync()
|
||||
{
|
||||
await _container.DisposeAsync();
|
||||
}
|
||||
@@ -336,3 +336,5 @@ public class PostgresCollection : ICollectionFixture<PostgresFixture>
|
||||
// to be the place to apply [CollectionDefinition] and all the
|
||||
// ICollectionFixture<> interfaces.
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -78,7 +78,7 @@ public sealed class ValkeyFixture : IAsyncLifetime, IDisposable
|
||||
/// <summary>
|
||||
/// Initializes the Valkey container asynchronously.
|
||||
/// </summary>
|
||||
public async Task InitializeAsync()
|
||||
public async ValueTask InitializeAsync()
|
||||
{
|
||||
// Use official Redis image (Valkey is Redis-compatible)
|
||||
// In production deployments, substitute with valkey/valkey image if needed
|
||||
@@ -191,7 +191,7 @@ public sealed class ValkeyFixture : IAsyncLifetime, IDisposable
|
||||
/// <summary>
|
||||
/// Disposes the Valkey container asynchronously.
|
||||
/// </summary>
|
||||
public async Task DisposeAsync()
|
||||
public async ValueTask DisposeAsync()
|
||||
{
|
||||
if (_connection != null)
|
||||
{
|
||||
@@ -263,3 +263,5 @@ public sealed class ValkeyTestSession : IAsyncDisposable
|
||||
await _fixture.FlushDatabaseAsync(DatabaseIndex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -71,9 +71,8 @@ public class WebServiceFixture<TProgram> : WebApplicationFactory<TProgram>, IAsy
|
||||
return client;
|
||||
}
|
||||
|
||||
public virtual Task InitializeAsync() => Task.CompletedTask;
|
||||
public virtual ValueTask InitializeAsync() => ValueTask.CompletedTask;
|
||||
|
||||
Task IAsyncLifetime.DisposeAsync() => Task.CompletedTask;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -178,3 +177,7 @@ public static class WebServiceTestExtensions
|
||||
return await client.GetAsync(url);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<OutputType>Exe</OutputType>
|
||||
<UseAppHost>true</UseAppHost>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<LangVersion>preview</LangVersion>
|
||||
@@ -8,12 +10,11 @@
|
||||
<Description>Testing infrastructure and utilities for StellaOps</Description>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="xunit" PrivateAssets="all" />
|
||||
<PackageReference Include="xunit.extensibility.core" PrivateAssets="all" />
|
||||
<PackageReference Include="xunit.assert" PrivateAssets="all" />
|
||||
<PackageReference Include="xunit.v3.assert" PrivateAssets="all" />
|
||||
<PackageReference Include="xunit.v3.core" PrivateAssets="all" />
|
||||
<PackageReference Include="FluentAssertions" />
|
||||
<PackageReference Include="FsCheck" />
|
||||
<PackageReference Include="FsCheck.Xunit" PrivateAssets="all" />
|
||||
<PackageReference Include="FsCheck.Xunit.v3" PrivateAssets="all" />
|
||||
<PackageReference Include="Testcontainers" />
|
||||
<PackageReference Include="Testcontainers.PostgreSql" />
|
||||
<PackageReference Include="Npgsql" />
|
||||
@@ -26,3 +27,9 @@
|
||||
<ProjectReference Include="..\StellaOps.Canonical.Json\StellaOps.Canonical.Json.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="FsCheck.Xunit" />
|
||||
<PackageReference Include="FsCheck.Xunit.v3" />
|
||||
<PackageReference Include="FluentAssertions" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -14,4 +14,6 @@
|
||||
<ProjectReference Include="..\..\StellaOps.Canonicalization\StellaOps.Canonicalization.csproj" />
|
||||
<ProjectReference Include="../../StellaOps.TestKit/StellaOps.TestKit.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
||||
|
||||
|
||||
@@ -5,9 +5,7 @@
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Using Include="Xunit.Abstractions" />
|
||||
</ItemGroup>
|
||||
<ItemGroup> </ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="FluentAssertions" />
|
||||
|
||||
@@ -39,13 +39,13 @@ public sealed class CrossModuleEvidenceLinkingTests : IAsyncLifetime
|
||||
_output = output;
|
||||
}
|
||||
|
||||
public Task InitializeAsync()
|
||||
public ValueTask InitializeAsync()
|
||||
{
|
||||
_store = _fixture.CreateStore(_tenantId);
|
||||
return Task.CompletedTask;
|
||||
return ValueTask.CompletedTask;
|
||||
}
|
||||
|
||||
public async Task DisposeAsync()
|
||||
public async ValueTask DisposeAsync()
|
||||
{
|
||||
await _fixture.TruncateAllTablesAsync();
|
||||
}
|
||||
@@ -546,3 +546,6 @@ public sealed class CrossModuleEvidenceLinkingTests : IAsyncLifetime
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -34,13 +34,13 @@ public sealed class PostgresEvidenceStoreIntegrationTests : IAsyncLifetime
|
||||
_output = output;
|
||||
}
|
||||
|
||||
public Task InitializeAsync()
|
||||
public ValueTask InitializeAsync()
|
||||
{
|
||||
_store = _fixture.CreateStore(_tenantId);
|
||||
return Task.CompletedTask;
|
||||
return ValueTask.CompletedTask;
|
||||
}
|
||||
|
||||
public async Task DisposeAsync()
|
||||
public async ValueTask DisposeAsync()
|
||||
{
|
||||
await _fixture.TruncateAllTablesAsync();
|
||||
}
|
||||
@@ -551,3 +551,6 @@ public sealed class PostgresEvidenceStoreIntegrationTests : IAsyncLifetime
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ public sealed class StartupMigrationHostTests : IAsyncLifetime
|
||||
private string ConnectionString => _container?.GetConnectionString()
|
||||
?? throw new InvalidOperationException("Container not initialized");
|
||||
|
||||
public async Task InitializeAsync()
|
||||
public async ValueTask InitializeAsync()
|
||||
{
|
||||
_container = new PostgreSqlBuilder()
|
||||
.WithImage("postgres:16-alpine")
|
||||
@@ -29,7 +29,7 @@ public sealed class StartupMigrationHostTests : IAsyncLifetime
|
||||
await _container.StartAsync();
|
||||
}
|
||||
|
||||
public async Task DisposeAsync()
|
||||
public async ValueTask DisposeAsync()
|
||||
{
|
||||
if (_container != null)
|
||||
{
|
||||
@@ -546,3 +546,6 @@ internal sealed class TestMigrationHost : StartupMigrationHost
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ public sealed class PostgresFixtureTests : IAsyncLifetime
|
||||
{
|
||||
private PostgreSqlContainer? _container;
|
||||
|
||||
public async Task InitializeAsync()
|
||||
public async ValueTask InitializeAsync()
|
||||
{
|
||||
_container = new PostgreSqlBuilder()
|
||||
.WithImage("postgres:16-alpine")
|
||||
@@ -24,7 +24,7 @@ public sealed class PostgresFixtureTests : IAsyncLifetime
|
||||
await _container.StartAsync();
|
||||
}
|
||||
|
||||
public async Task DisposeAsync()
|
||||
public async ValueTask DisposeAsync()
|
||||
{
|
||||
if (_container != null)
|
||||
{
|
||||
@@ -104,3 +104,6 @@ public sealed class PostgresFixtureTests : IAsyncLifetime
|
||||
exists.Should().Be(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ public sealed class MinimalApiBindingIntegrationTests : IAsyncLifetime
|
||||
};
|
||||
}
|
||||
|
||||
public async Task InitializeAsync()
|
||||
public async ValueTask InitializeAsync()
|
||||
{
|
||||
// Build a real WebApplication with Minimal APIs
|
||||
var builder = WebApplication.CreateBuilder(new WebApplicationOptions
|
||||
@@ -68,7 +68,7 @@ public sealed class MinimalApiBindingIntegrationTests : IAsyncLifetime
|
||||
NullLogger<AspNetRouterRequestDispatcher>.Instance);
|
||||
}
|
||||
|
||||
public async Task DisposeAsync()
|
||||
public async ValueTask DisposeAsync()
|
||||
{
|
||||
if (_app is not null)
|
||||
{
|
||||
@@ -1002,3 +1002,6 @@ public sealed class MinimalApiBindingIntegrationTests : IAsyncLifetime
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ public sealed class StellaRouterBridgeIntegrationTests : IAsyncLifetime
|
||||
PropertyNameCaseInsensitive = true
|
||||
};
|
||||
|
||||
public async Task InitializeAsync()
|
||||
public async ValueTask InitializeAsync()
|
||||
{
|
||||
// Build a real WebApplication with the Router bridge
|
||||
var builder = WebApplication.CreateBuilder(new WebApplicationOptions
|
||||
@@ -74,7 +74,7 @@ public sealed class StellaRouterBridgeIntegrationTests : IAsyncLifetime
|
||||
NullLogger<AspNetRouterRequestDispatcher>.Instance);
|
||||
}
|
||||
|
||||
public async Task DisposeAsync()
|
||||
public async ValueTask DisposeAsync()
|
||||
{
|
||||
if (_app is not null)
|
||||
{
|
||||
@@ -612,3 +612,6 @@ public sealed class StellaRouterBridgeOptionsValidationTests
|
||||
Assert.NotNull(provider.GetService<StellaRouterBridgeOptions>());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ public sealed class EvidenceApiTests : IAsyncLifetime
|
||||
private Mock<IEvidenceChunkRepository>? _mockChunkRepository;
|
||||
private Mock<IEvidenceChunker>? _mockChunker;
|
||||
|
||||
public async Task InitializeAsync()
|
||||
public async ValueTask InitializeAsync()
|
||||
{
|
||||
_mockChunkRepository = new Mock<IEvidenceChunkRepository>();
|
||||
_mockChunker = new Mock<IEvidenceChunker>();
|
||||
@@ -58,7 +58,7 @@ public sealed class EvidenceApiTests : IAsyncLifetime
|
||||
_client = _host.GetTestClient();
|
||||
}
|
||||
|
||||
public async Task DisposeAsync()
|
||||
public async ValueTask DisposeAsync()
|
||||
{
|
||||
_client?.Dispose();
|
||||
if (_host != null)
|
||||
@@ -385,3 +385,6 @@ public sealed class EvidenceApiTests : IAsyncLifetime
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -35,9 +35,9 @@ public sealed class SignalsTestFactory : WebApplicationFactory<Program>, IAsyncL
|
||||
});
|
||||
}
|
||||
|
||||
public Task InitializeAsync() => Task.CompletedTask;
|
||||
public ValueTask InitializeAsync() => ValueTask.CompletedTask;
|
||||
|
||||
public new async Task DisposeAsync()
|
||||
public new async ValueTask DisposeAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -52,3 +52,6 @@ public sealed class SignalsTestFactory : WebApplicationFactory<Program>, IAsyncL
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -11,11 +11,13 @@
|
||||
<ItemGroup>
|
||||
<PackageReference Include="FluentAssertions" />
|
||||
<PackageReference Include="FsCheck" />
|
||||
<PackageReference Include="FsCheck.Xunit" />
|
||||
<PackageReference Include="FsCheck.Xunit.v3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\StellaOps.VersionComparison\StellaOps.VersionComparison.csproj" />
|
||||
<ProjectReference Include="../../StellaOps.TestKit/StellaOps.TestKit.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user