part #2
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
using System.Reflection;
|
||||
using Npgsql;
|
||||
using StellaOps.AirGap.Persistence.Postgres;
|
||||
using StellaOps.Infrastructure.Postgres.Testing;
|
||||
using Xunit;
|
||||
@@ -10,118 +9,11 @@ namespace StellaOps.AirGap.Persistence.Tests;
|
||||
/// PostgreSQL integration test fixture for the AirGap module.
|
||||
/// Runs migrations from embedded resources and provides test isolation.
|
||||
/// </summary>
|
||||
public sealed class AirGapPostgresFixture : PostgresIntegrationFixture, ICollectionFixture<AirGapPostgresFixture>
|
||||
public sealed partial class AirGapPostgresFixture : PostgresIntegrationFixture, ICollectionFixture<AirGapPostgresFixture>
|
||||
{
|
||||
protected override Assembly? GetMigrationAssembly()
|
||||
=> typeof(AirGapDataSource).Assembly;
|
||||
protected override Assembly? GetMigrationAssembly() => typeof(AirGapDataSource).Assembly;
|
||||
|
||||
protected override string GetModuleName() => "AirGap";
|
||||
|
||||
protected override string? GetResourcePrefix() => null;
|
||||
|
||||
/// <summary>
|
||||
/// Gets all table names in the test schema.
|
||||
/// </summary>
|
||||
public async Task<IReadOnlyList<string>> GetTableNamesAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
await using var connection = new NpgsqlConnection(ConnectionString);
|
||||
await connection.OpenAsync(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
await using var cmd = new NpgsqlCommand(
|
||||
"""
|
||||
SELECT table_name FROM information_schema.tables
|
||||
WHERE table_schema = @schema AND table_type = 'BASE TABLE';
|
||||
""",
|
||||
connection);
|
||||
cmd.Parameters.AddWithValue("schema", SchemaName);
|
||||
|
||||
var tables = new List<string>();
|
||||
await using var reader = await cmd.ExecuteReaderAsync(cancellationToken).ConfigureAwait(false);
|
||||
while (await reader.ReadAsync(cancellationToken).ConfigureAwait(false))
|
||||
{
|
||||
tables.Add(reader.GetString(0));
|
||||
}
|
||||
|
||||
return tables;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all column names for a specific table in the test schema.
|
||||
/// </summary>
|
||||
public async Task<IReadOnlyList<string>> GetColumnNamesAsync(string tableName, CancellationToken cancellationToken = default)
|
||||
{
|
||||
await using var connection = new NpgsqlConnection(ConnectionString);
|
||||
await connection.OpenAsync(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
await using var cmd = new NpgsqlCommand(
|
||||
"""
|
||||
SELECT column_name FROM information_schema.columns
|
||||
WHERE table_schema = @schema AND table_name = @table;
|
||||
""",
|
||||
connection);
|
||||
cmd.Parameters.AddWithValue("schema", SchemaName);
|
||||
cmd.Parameters.AddWithValue("table", tableName);
|
||||
|
||||
var columns = new List<string>();
|
||||
await using var reader = await cmd.ExecuteReaderAsync(cancellationToken).ConfigureAwait(false);
|
||||
while (await reader.ReadAsync(cancellationToken).ConfigureAwait(false))
|
||||
{
|
||||
columns.Add(reader.GetString(0));
|
||||
}
|
||||
|
||||
return columns;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all index names for a specific table in the test schema.
|
||||
/// </summary>
|
||||
public async Task<IReadOnlyList<string>> GetIndexNamesAsync(string tableName, CancellationToken cancellationToken = default)
|
||||
{
|
||||
await using var connection = new NpgsqlConnection(ConnectionString);
|
||||
await connection.OpenAsync(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
await using var cmd = new NpgsqlCommand(
|
||||
"""
|
||||
SELECT indexname FROM pg_indexes
|
||||
WHERE schemaname = @schema AND tablename = @table;
|
||||
""",
|
||||
connection);
|
||||
cmd.Parameters.AddWithValue("schema", SchemaName);
|
||||
cmd.Parameters.AddWithValue("table", tableName);
|
||||
|
||||
var indexes = new List<string>();
|
||||
await using var reader = await cmd.ExecuteReaderAsync(cancellationToken).ConfigureAwait(false);
|
||||
while (await reader.ReadAsync(cancellationToken).ConfigureAwait(false))
|
||||
{
|
||||
indexes.Add(reader.GetString(0));
|
||||
}
|
||||
|
||||
return indexes;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ensures migrations have been run. This is idempotent and safe to call multiple times.
|
||||
/// </summary>
|
||||
public async Task EnsureMigrationsRunAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
var migrationAssembly = GetMigrationAssembly();
|
||||
if (migrationAssembly != null)
|
||||
{
|
||||
await Fixture.RunMigrationsFromAssemblyAsync(
|
||||
migrationAssembly,
|
||||
GetModuleName(),
|
||||
GetResourcePrefix(),
|
||||
cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Collection definition for AirGap PostgreSQL integration tests.
|
||||
/// Tests in this collection share a single PostgreSQL container instance.
|
||||
/// </summary>
|
||||
[CollectionDefinition(Name)]
|
||||
public sealed class AirGapPostgresCollection : ICollectionFixture<AirGapPostgresFixture>
|
||||
{
|
||||
public const string Name = "AirGapPostgres";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user