Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d39ec60e2c | |||
| a025655b4d |
+4
-3
@@ -45,9 +45,8 @@ steps:
|
|||||||
# testcontainers, and a postgres service container deadlocks the step because the backend mounts
|
# testcontainers, and a postgres service container deadlocks the step because the backend mounts
|
||||||
# the ReadWriteOnce workspace volume into service pods and schedules them on another node.
|
# the ReadWriteOnce workspace volume into service pods and schedules them on another node.
|
||||||
# Its data directory lives on the step's ephemeral storage, not on the workspace volume.
|
# Its data directory lives on the step's ephemeral storage, not on the workspace volume.
|
||||||
# Scoped to Jellyfin.Server.Tests: the three classes in Jellyfin.Database.Tests.PostgreSQL still
|
# Both projects attach to it through JELLYFIN_TEST_POSTGRES and give every test a database of
|
||||||
# start their own container, and PostgreSqlProviderTests already fails on main - on an EF 10
|
# its own, so nothing here depends on a docker daemon.
|
||||||
# scalar query and on its own data - which a third test in the class then inherits.
|
|
||||||
- name: postgres-migration-chain
|
- name: postgres-migration-chain
|
||||||
image: mcr.microsoft.com/dotnet/sdk:10.0
|
image: mcr.microsoft.com/dotnet/sdk:10.0
|
||||||
depends_on:
|
depends_on:
|
||||||
@@ -64,7 +63,9 @@ steps:
|
|||||||
- su postgres -c "$PGBIN/initdb -D /tmp/pgdata -A trust -U postgres"
|
- su postgres -c "$PGBIN/initdb -D /tmp/pgdata -A trust -U postgres"
|
||||||
- su postgres -c "$PGBIN/pg_ctl -D /tmp/pgdata -o \"-c listen_addresses=127.0.0.1 -k /tmp/pgrun\" -l /tmp/pg.log -w start"
|
- su postgres -c "$PGBIN/pg_ctl -D /tmp/pgdata -o \"-c listen_addresses=127.0.0.1 -k /tmp/pgrun\" -l /tmp/pg.log -w start"
|
||||||
- dotnet build tests/Jellyfin.Server.Tests/Jellyfin.Server.Tests.csproj -c Release
|
- dotnet build tests/Jellyfin.Server.Tests/Jellyfin.Server.Tests.csproj -c Release
|
||||||
|
- dotnet build tests/Jellyfin.Database.Tests.PostgreSQL/Jellyfin.Database.Tests.PostgreSQL.csproj -c Release
|
||||||
- dotnet test tests/Jellyfin.Server.Tests/Jellyfin.Server.Tests.csproj -c Release --no-build --verbosity minimal --filter "Category=RequiresDocker"
|
- dotnet test tests/Jellyfin.Server.Tests/Jellyfin.Server.Tests.csproj -c Release --no-build --verbosity minimal --filter "Category=RequiresDocker"
|
||||||
|
- dotnet test tests/Jellyfin.Database.Tests.PostgreSQL/Jellyfin.Database.Tests.PostgreSQL.csproj -c Release --no-build --verbosity minimal --filter "Category=RequiresDocker"
|
||||||
backend_options:
|
backend_options:
|
||||||
kubernetes:
|
kubernetes:
|
||||||
serviceAccountName: jellyfin-ha-src
|
serviceAccountName: jellyfin-ha-src
|
||||||
|
|||||||
@@ -18,6 +18,11 @@
|
|||||||
<PackageReference Include="coverlet.collector" />
|
<PackageReference Include="coverlet.collector" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<!-- Linked, not project-referenced: Jellyfin.Server.Tests drags the whole server into this output. -->
|
||||||
|
<Compile Include="..\Jellyfin.Server.Tests\Migrations\PostgreSqlTestServer.cs" Link="Migrations\PostgreSqlTestServer.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\..\src\Jellyfin.Database\Jellyfin.Database.Providers.PostgreSQL\Jellyfin.Database.Providers.PostgreSQL.csproj" />
|
<ProjectReference Include="..\..\src\Jellyfin.Database\Jellyfin.Database.Providers.PostgreSQL\Jellyfin.Database.Providers.PostgreSQL.csproj" />
|
||||||
<ProjectReference Include="..\..\src\Jellyfin.Database\Jellyfin.Database.Implementations\Jellyfin.Database.Implementations.csproj" />
|
<ProjectReference Include="..\..\src\Jellyfin.Database\Jellyfin.Database.Implementations\Jellyfin.Database.Implementations.csproj" />
|
||||||
|
|||||||
@@ -1,71 +1,68 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using DotNet.Testcontainers.Builders;
|
|
||||||
using Jellyfin.Database.Implementations;
|
using Jellyfin.Database.Implementations;
|
||||||
using Jellyfin.Database.Implementations.DbConfiguration;
|
using Jellyfin.Database.Implementations.DbConfiguration;
|
||||||
using Jellyfin.Database.Implementations.Entities;
|
using Jellyfin.Database.Implementations.Entities;
|
||||||
using Jellyfin.Database.Implementations.Locking;
|
using Jellyfin.Database.Implementations.Locking;
|
||||||
using Jellyfin.Database.Providers.PostgreSQL;
|
using Jellyfin.Database.Providers.PostgreSQL;
|
||||||
|
using Jellyfin.Server.Tests.Migrations;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.Logging.Abstractions;
|
using Microsoft.Extensions.Logging.Abstractions;
|
||||||
using Npgsql;
|
using Npgsql;
|
||||||
using Testcontainers.PostgreSql;
|
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Jellyfin.Database.Tests.PostgreSQL;
|
namespace Jellyfin.Database.Tests.PostgreSQL;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Integration tests that verify concurrent access patterns against a real PostgreSQL 16 container.
|
/// Integration tests that verify concurrent access patterns against a real PostgreSQL server.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Xunit.Trait("Category", "RequiresDocker")]
|
[Xunit.Trait("Category", "RequiresDocker")]
|
||||||
public sealed class PostgreSqlConcurrencyTests : IAsyncLifetime
|
public sealed class PostgreSqlConcurrencyTests : IAsyncLifetime
|
||||||
{
|
{
|
||||||
private readonly PostgreSqlContainer _container;
|
private static int _databaseSequence;
|
||||||
|
|
||||||
|
private PostgreSqlTestServer? _server;
|
||||||
private NpgsqlDataSource? _dataSource;
|
private NpgsqlDataSource? _dataSource;
|
||||||
private PostgreSqlDatabaseProvider? _provider;
|
private PostgreSqlDatabaseProvider? _provider;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="PostgreSqlConcurrencyTests"/> class.
|
/// Attaches to the test server, hands this test a database of its own and applies migrations to it.
|
||||||
/// </summary>
|
|
||||||
public PostgreSqlConcurrencyTests()
|
|
||||||
{
|
|
||||||
_container = new PostgreSqlBuilder("postgres:16-alpine")
|
|
||||||
.WithWaitStrategy(Wait.ForUnixContainer().UntilCommandIsCompleted("pg_isready"))
|
|
||||||
.Build();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Starts the PostgreSQL container and applies migrations before any tests in the class run.
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>A <see cref="ValueTask"/> representing the asynchronous operation.</returns>
|
/// <returns>A <see cref="ValueTask"/> representing the asynchronous operation.</returns>
|
||||||
public async ValueTask InitializeAsync()
|
public async ValueTask InitializeAsync()
|
||||||
{
|
{
|
||||||
await _container.StartAsync().ConfigureAwait(false);
|
_server = await PostgreSqlTestServer.StartAsync().ConfigureAwait(false);
|
||||||
|
|
||||||
_dataSource = new NpgsqlDataSourceBuilder(_container.GetConnectionString()).Build();
|
var databaseName = FormattableString.Invariant($"pg_concurrency_{Interlocked.Increment(ref _databaseSequence)}");
|
||||||
|
var connectionString = await _server.CreateDatabaseAsync(databaseName, TestContext.Current.CancellationToken).ConfigureAwait(false);
|
||||||
|
_dataSource = new NpgsqlDataSourceBuilder(connectionString).Build();
|
||||||
_provider = new PostgreSqlDatabaseProvider(_dataSource);
|
_provider = new PostgreSqlDatabaseProvider(_dataSource);
|
||||||
|
|
||||||
// Apply migrations once for the whole test class.
|
|
||||||
var context = CreateContext();
|
var context = CreateContext();
|
||||||
await using (context.ConfigureAwait(false))
|
await using (context.ConfigureAwait(false))
|
||||||
{
|
{
|
||||||
await context.Database.MigrateAsync().ConfigureAwait(false);
|
await context.Database.MigrateAsync(TestContext.Current.CancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Stops and removes the PostgreSQL container after all tests in the class have run.
|
/// Releases the data source and the test server.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>A <see cref="ValueTask"/> representing the asynchronous operation.</returns>
|
/// <returns>A <see cref="ValueTask"/> representing the asynchronous operation.</returns>
|
||||||
public async ValueTask DisposeAsync()
|
public async ValueTask DisposeAsync()
|
||||||
{
|
{
|
||||||
|
// InitializeAsync can fail before the data source exists; its error must not be masked by an NRE here.
|
||||||
if (_dataSource is not null)
|
if (_dataSource is not null)
|
||||||
{
|
{
|
||||||
await _dataSource.DisposeAsync().ConfigureAwait(false);
|
await _dataSource.DisposeAsync().ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
await _container.DisposeAsync().ConfigureAwait(false);
|
if (_server is not null)
|
||||||
|
{
|
||||||
|
await _server.DisposeAsync().ConfigureAwait(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -1,62 +1,68 @@
|
|||||||
|
using System;
|
||||||
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using DotNet.Testcontainers.Builders;
|
|
||||||
using Jellyfin.Database.Implementations;
|
using Jellyfin.Database.Implementations;
|
||||||
using Jellyfin.Database.Implementations.DbConfiguration;
|
using Jellyfin.Database.Implementations.DbConfiguration;
|
||||||
using Jellyfin.Database.Implementations.Locking;
|
using Jellyfin.Database.Implementations.Locking;
|
||||||
using Jellyfin.Database.Providers.PostgreSQL;
|
using Jellyfin.Database.Providers.PostgreSQL;
|
||||||
|
using Jellyfin.Server.Tests.Migrations;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.Logging.Abstractions;
|
using Microsoft.Extensions.Logging.Abstractions;
|
||||||
using Npgsql;
|
using Npgsql;
|
||||||
using Testcontainers.PostgreSql;
|
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Jellyfin.Database.Tests.PostgreSQL;
|
namespace Jellyfin.Database.Tests.PostgreSQL;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Integration tests that validate PostgreSQL migrations against a real container.
|
/// Integration tests that validate PostgreSQL migrations against a real server.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Xunit.Trait("Category", "RequiresDocker")]
|
[Xunit.Trait("Category", "RequiresDocker")]
|
||||||
public sealed class PostgreSqlMigrationTests : IAsyncLifetime
|
public sealed class PostgreSqlMigrationTests : IAsyncLifetime
|
||||||
{
|
{
|
||||||
private readonly PostgreSqlContainer _container;
|
private static int _databaseSequence;
|
||||||
|
|
||||||
|
private PostgreSqlTestServer? _server;
|
||||||
|
private NpgsqlDataSource? _dataSource;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="PostgreSqlMigrationTests"/> class.
|
/// Attaches to the test server and hands this test an empty database of its own.
|
||||||
/// </summary>
|
|
||||||
public PostgreSqlMigrationTests()
|
|
||||||
{
|
|
||||||
_container = new PostgreSqlBuilder("postgres:16-alpine")
|
|
||||||
.WithWaitStrategy(Wait.ForUnixContainer().UntilCommandIsCompleted("pg_isready"))
|
|
||||||
.Build();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Starts the PostgreSQL container before any tests in the class run.
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>A <see cref="ValueTask"/> representing the asynchronous operation.</returns>
|
/// <returns>A <see cref="ValueTask"/> representing the asynchronous operation.</returns>
|
||||||
public async ValueTask InitializeAsync()
|
public async ValueTask InitializeAsync()
|
||||||
{
|
{
|
||||||
await _container.StartAsync().ConfigureAwait(false);
|
_server = await PostgreSqlTestServer.StartAsync().ConfigureAwait(false);
|
||||||
|
|
||||||
|
var databaseName = FormattableString.Invariant($"pg_migration_{Interlocked.Increment(ref _databaseSequence)}");
|
||||||
|
var connectionString = await _server.CreateDatabaseAsync(databaseName, TestContext.Current.CancellationToken).ConfigureAwait(false);
|
||||||
|
_dataSource = new NpgsqlDataSourceBuilder(connectionString).Build();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Stops and removes the PostgreSQL container after all tests in the class have run.
|
/// Releases the data source and the test server.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>A <see cref="ValueTask"/> representing the asynchronous operation.</returns>
|
/// <returns>A <see cref="ValueTask"/> representing the asynchronous operation.</returns>
|
||||||
public async ValueTask DisposeAsync()
|
public async ValueTask DisposeAsync()
|
||||||
{
|
{
|
||||||
await _container.DisposeAsync().ConfigureAwait(false);
|
// InitializeAsync can fail before the data source exists; its error must not be masked by an NRE here.
|
||||||
|
if (_dataSource is not null)
|
||||||
|
{
|
||||||
|
await _dataSource.DisposeAsync().ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_server is not null)
|
||||||
|
{
|
||||||
|
await _server.DisposeAsync().ConfigureAwait(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Verifies that the <c>InitialPostgreSql</c> migration applies cleanly to a fresh PostgreSQL 16 container.
|
/// Verifies that the <c>InitialPostgreSql</c> migration applies cleanly to a fresh database.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
|
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task MigrateAsync_AppliesInitialMigrationCleanly()
|
public async Task MigrateAsync_AppliesInitialMigrationCleanly()
|
||||||
{
|
{
|
||||||
await using var dataSource = new NpgsqlDataSourceBuilder(_container.GetConnectionString()).Build();
|
var context = CreateContext(_dataSource!);
|
||||||
var context = CreateContext(dataSource);
|
|
||||||
await using (context)
|
await using (context)
|
||||||
{
|
{
|
||||||
await context.Database.MigrateAsync(TestContext.Current.CancellationToken);
|
await context.Database.MigrateAsync(TestContext.Current.CancellationToken);
|
||||||
@@ -73,11 +79,7 @@ public sealed class PostgreSqlMigrationTests : IAsyncLifetime
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void CheckForUnappliedMigrations_PostgreSql()
|
public void CheckForUnappliedMigrations_PostgreSql()
|
||||||
{
|
{
|
||||||
// Use a dummy connection string; HasPendingModelChanges() is a purely in-memory check
|
using var context = CreateContext(_dataSource!);
|
||||||
// that compares the current compiled model with the migration snapshots — no real DB needed.
|
|
||||||
const string dummyConnectionString = "Host=localhost;Database=jellyfin;Username=postgres;Password=postgres";
|
|
||||||
using var dataSource = new NpgsqlDataSourceBuilder(dummyConnectionString).Build();
|
|
||||||
using var context = CreateContext(dataSource);
|
|
||||||
|
|
||||||
Assert.False(
|
Assert.False(
|
||||||
context.Database.HasPendingModelChanges(),
|
context.Database.HasPendingModelChanges(),
|
||||||
|
|||||||
@@ -2,71 +2,67 @@ using System;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using DotNet.Testcontainers.Builders;
|
|
||||||
using Jellyfin.Database.Implementations;
|
using Jellyfin.Database.Implementations;
|
||||||
using Jellyfin.Database.Implementations.DbConfiguration;
|
using Jellyfin.Database.Implementations.DbConfiguration;
|
||||||
using Jellyfin.Database.Implementations.Entities;
|
using Jellyfin.Database.Implementations.Entities;
|
||||||
using Jellyfin.Database.Implementations.Locking;
|
using Jellyfin.Database.Implementations.Locking;
|
||||||
using Jellyfin.Database.Providers.PostgreSQL;
|
using Jellyfin.Database.Providers.PostgreSQL;
|
||||||
|
using Jellyfin.Server.Tests.Migrations;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.Logging.Abstractions;
|
using Microsoft.Extensions.Logging.Abstractions;
|
||||||
using Npgsql;
|
using Npgsql;
|
||||||
using Testcontainers.PostgreSql;
|
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Jellyfin.Database.Tests.PostgreSQL;
|
namespace Jellyfin.Database.Tests.PostgreSQL;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Integration tests for CRUD operations, optimisation, and purge against a real PostgreSQL 16 container.
|
/// Integration tests for CRUD operations, optimisation, and purge against a real PostgreSQL server.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Xunit.Trait("Category", "RequiresDocker")]
|
[Xunit.Trait("Category", "RequiresDocker")]
|
||||||
public sealed class PostgreSqlProviderTests : IAsyncLifetime
|
public sealed class PostgreSqlProviderTests : IAsyncLifetime
|
||||||
{
|
{
|
||||||
private readonly PostgreSqlContainer _container;
|
private static int _databaseSequence;
|
||||||
|
|
||||||
|
private PostgreSqlTestServer? _server;
|
||||||
private NpgsqlDataSource? _dataSource;
|
private NpgsqlDataSource? _dataSource;
|
||||||
private PostgreSqlDatabaseProvider? _provider;
|
private PostgreSqlDatabaseProvider? _provider;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="PostgreSqlProviderTests"/> class.
|
/// Attaches to the test server, hands this test a database of its own and applies migrations to it.
|
||||||
/// </summary>
|
|
||||||
public PostgreSqlProviderTests()
|
|
||||||
{
|
|
||||||
_container = new PostgreSqlBuilder("postgres:16-alpine")
|
|
||||||
.WithWaitStrategy(Wait.ForUnixContainer().UntilCommandIsCompleted("pg_isready"))
|
|
||||||
.Build();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Starts the PostgreSQL container and applies migrations before any tests in the class run.
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>A <see cref="ValueTask"/> representing the asynchronous operation.</returns>
|
/// <returns>A <see cref="ValueTask"/> representing the asynchronous operation.</returns>
|
||||||
public async ValueTask InitializeAsync()
|
public async ValueTask InitializeAsync()
|
||||||
{
|
{
|
||||||
await _container.StartAsync().ConfigureAwait(false);
|
_server = await PostgreSqlTestServer.StartAsync().ConfigureAwait(false);
|
||||||
|
|
||||||
_dataSource = new NpgsqlDataSourceBuilder(_container.GetConnectionString()).Build();
|
var databaseName = FormattableString.Invariant($"pg_provider_{Interlocked.Increment(ref _databaseSequence)}");
|
||||||
|
var connectionString = await _server.CreateDatabaseAsync(databaseName, TestContext.Current.CancellationToken).ConfigureAwait(false);
|
||||||
|
_dataSource = new NpgsqlDataSourceBuilder(connectionString).Build();
|
||||||
_provider = new PostgreSqlDatabaseProvider(_dataSource);
|
_provider = new PostgreSqlDatabaseProvider(_dataSource);
|
||||||
|
|
||||||
// Apply migrations once for the whole test class.
|
|
||||||
var context = CreateContext();
|
var context = CreateContext();
|
||||||
await using (context.ConfigureAwait(false))
|
await using (context.ConfigureAwait(false))
|
||||||
{
|
{
|
||||||
await context.Database.MigrateAsync().ConfigureAwait(false);
|
await context.Database.MigrateAsync(TestContext.Current.CancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Stops and removes the PostgreSQL container after all tests in the class have run.
|
/// Releases the data source and the test server.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>A <see cref="ValueTask"/> representing the asynchronous operation.</returns>
|
/// <returns>A <see cref="ValueTask"/> representing the asynchronous operation.</returns>
|
||||||
public async ValueTask DisposeAsync()
|
public async ValueTask DisposeAsync()
|
||||||
{
|
{
|
||||||
|
// InitializeAsync can fail before the data source exists; its error must not be masked by an NRE here.
|
||||||
if (_dataSource is not null)
|
if (_dataSource is not null)
|
||||||
{
|
{
|
||||||
await _dataSource.DisposeAsync().ConfigureAwait(false);
|
await _dataSource.DisposeAsync().ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
await _container.DisposeAsync().ConfigureAwait(false);
|
if (_server is not null)
|
||||||
|
{
|
||||||
|
await _server.DisposeAsync().ConfigureAwait(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -155,11 +151,15 @@ public sealed class PostgreSqlProviderTests : IAsyncLifetime
|
|||||||
var ctx = CreateContext();
|
var ctx = CreateContext();
|
||||||
await using (ctx)
|
await using (ctx)
|
||||||
{
|
{
|
||||||
var userId = Guid.NewGuid();
|
// DisplayPreferences.UserId is a foreign key onto Users, which PostgreSQL enforces and SQLite does not.
|
||||||
|
var user = new User("prefsuser", "Jellyfin.Server.Implementations.Users.DefaultAuthenticationProvider", "Jellyfin.Server.Implementations.Users.DefaultPasswordResetProvider");
|
||||||
|
ctx.Users.Add(user);
|
||||||
|
await ctx.SaveChangesAsync(TestContext.Current.CancellationToken);
|
||||||
|
|
||||||
var itemId = Guid.NewGuid();
|
var itemId = Guid.NewGuid();
|
||||||
|
|
||||||
// Create
|
// Create
|
||||||
var prefs = new DisplayPreferences(userId, itemId, "TestClient");
|
var prefs = new DisplayPreferences(user.Id, itemId, "TestClient");
|
||||||
ctx.DisplayPreferences.Add(prefs);
|
ctx.DisplayPreferences.Add(prefs);
|
||||||
await ctx.SaveChangesAsync(TestContext.Current.CancellationToken);
|
await ctx.SaveChangesAsync(TestContext.Current.CancellationToken);
|
||||||
|
|
||||||
@@ -278,7 +278,7 @@ public sealed class PostgreSqlProviderTests : IAsyncLifetime
|
|||||||
|
|
||||||
// session_replication_role should be reset to 'origin' (default)
|
// session_replication_role should be reset to 'origin' (default)
|
||||||
var role = await ctx.Database
|
var role = await ctx.Database
|
||||||
.SqlQueryRaw<string>("SELECT current_setting('session_replication_role')")
|
.SqlQueryRaw<string>("SELECT current_setting('session_replication_role') AS \"Value\"")
|
||||||
.FirstAsync(TestContext.Current.CancellationToken);
|
.FirstAsync(TestContext.Current.CancellationToken);
|
||||||
Assert.Equal("origin", role);
|
Assert.Equal("origin", role);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user