Bind startup migrations to module schema search path

This commit is contained in:
master
2026-03-10 01:37:02 +02:00
parent 1df79ac75e
commit 6b7168ca3c
4 changed files with 176 additions and 5 deletions

View File

@@ -33,6 +33,29 @@ public sealed partial class StartupMigrationHostTests
return result is true;
}
private async Task<bool> ColumnExistsAsync(string schemaName, string tableName, string columnName)
{
await using var conn = new NpgsqlConnection(ConnectionString);
await conn.OpenAsync();
await using var cmd = new NpgsqlCommand(
"""
SELECT EXISTS(
SELECT 1
FROM information_schema.columns
WHERE table_schema = @schema
AND table_name = @table
AND column_name = @column)
""",
conn);
cmd.Parameters.AddWithValue("schema", schemaName);
cmd.Parameters.AddWithValue("table", tableName);
cmd.Parameters.AddWithValue("column", columnName);
var result = await cmd.ExecuteScalarAsync();
return result is true;
}
private async Task CorruptChecksumAsync(string schemaName, string migrationName)
{
await using var conn = new NpgsqlConnection(ConnectionString);

View File

@@ -0,0 +1,53 @@
using FluentAssertions;
using Npgsql;
using StellaOps.Infrastructure.Postgres.Migrations;
using Xunit;
namespace StellaOps.Infrastructure.Postgres.Tests.Migrations;
public sealed partial class StartupMigrationHostTests
{
[Fact]
public async Task StartAsync_WithPublicNameCollision_AppliesMigrationsInTargetSchema()
{
// Arrange
var schemaName = $"test_{Guid.NewGuid():N}"[..20];
var options = new StartupMigrationOptions { FailOnPendingReleaseMigrations = false };
await using (var conn = new NpgsqlConnection(ConnectionString))
{
await conn.OpenAsync();
await using var seed = new NpgsqlCommand(
"""
DROP TABLE IF EXISTS public.test_table;
CREATE TABLE public.test_table (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
""",
conn);
await seed.ExecuteNonQueryAsync();
}
try
{
var host = CreateTestHost(schemaName, options: options);
// Act
await host.StartAsync(CancellationToken.None);
// Assert
(await TableExistsAsync(schemaName, "test_table")).Should().BeTrue();
(await ColumnExistsAsync(schemaName, "test_table", "description")).Should().BeTrue();
(await ColumnExistsAsync("public", "test_table", "description")).Should().BeFalse();
}
finally
{
await using var conn = new NpgsqlConnection(ConnectionString);
await conn.OpenAsync();
await using var cleanup = new NpgsqlCommand("DROP TABLE IF EXISTS public.test_table;", conn);
await cleanup.ExecuteNonQueryAsync();
}
}
}