Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,8 @@ jobs:
- name: Test
run: dotnet test -c ${{ matrix.config }} --logger "GitHubActions;report-warnings=false"
shell: bash
env:
Test__Npgsql__DefaultConnection: Server=localhost;Username=npgsql_tests;Password=npgsql_tests

- id: analyze_tag
name: Analyze tag
Expand Down
1 change: 1 addition & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,6 @@
<PackageVersion Include="xunit.core" Version="2.9.3" />
<PackageVersion Include="xunit.runner.visualstudio" Version="3.1.5" />
<PackageVersion Include="GitHubActionsTestLogger" Version="2.4.1" />
<PackageVersion Include="Testcontainers.PostgreSql" Version="4.10.0" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational.Specification.Tests" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" />
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" />
<PackageReference Include="Testcontainers.PostgreSql" />
</ItemGroup>

<ItemGroup>
<None Update="Northwind.sql" CopyToOutputDirectory="PreserveNewest" />
<None Update="config.json" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ public class Post
public class BloggingContext : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder.UseNpgsql(TestEnvironment.DefaultConnection);
=> optionsBuilder.UseNpgsql(TestEnvironment.ConnectionString);

public DbSet<Blog> Blogs { get; set; }
}
2 changes: 1 addition & 1 deletion test/EFCore.PG.FunctionalTests/Query/NavigationTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ public NavigationTestFixture()
.AddEntityFrameworkNpgsql()
.BuildServiceProvider();

var connStrBuilder = new NpgsqlConnectionStringBuilder(TestEnvironment.DefaultConnection) { Database = "StateManagerBug" };
var connStrBuilder = new NpgsqlConnectionStringBuilder(TestEnvironment.ConnectionString) { Database = "StateManagerBug" };

_options = new DbContextOptionsBuilder()
.UseNpgsql(connStrBuilder.ConnectionString)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -420,7 +420,7 @@ private static DbCommand CreateCommand(

public static string CreateConnectionString(string name, string? options = null)
{
var builder = new NpgsqlConnectionStringBuilder(TestEnvironment.DefaultConnection) { Database = name };
var builder = new NpgsqlConnectionStringBuilder(TestEnvironment.ConnectionString) { Database = name };

if (options is not null)
{
Expand Down
40 changes: 35 additions & 5 deletions test/EFCore.PG.FunctionalTests/TestUtilities/TestEnvironment.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
using System.Globalization;
using Microsoft.Extensions.Configuration;
using Testcontainers.PostgreSql;

namespace Microsoft.EntityFrameworkCore.TestUtilities;

public static class TestEnvironment
{
public static IConfiguration Config { get; }

public static string ConnectionString { get; }

// Keep a reference to prevent GC from collecting (and finalizing/stopping) the container while tests are running.
private static readonly PostgreSqlContainer? _postgreSqlContainer;

static TestEnvironment()
{
var configBuilder = new ConfigurationBuilder()
Expand All @@ -18,13 +24,37 @@ static TestEnvironment()
Config = configBuilder.Build()
.GetSection("Test:Npgsql");

Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
}
if (Config["DefaultConnection"] is { } connectionString)
{
Console.WriteLine("Using connection string configured via Test:Npgsql:DefaultConnection: " + connectionString);
Copy link

Copilot AI Feb 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Console.WriteLine logs the full configured connection string, which may include credentials (e.g., passwords) and can leak secrets in CI logs or developer output. Consider avoiding logging the connection string entirely, or at least redact sensitive keys (Password/Username) before writing to output.

Suggested change
Console.WriteLine("Using connection string configured via Test:Npgsql:DefaultConnection: " + connectionString);
Console.WriteLine("Using connection string configured via Test:Npgsql:DefaultConnection.");

Copilot uses AI. Check for mistakes.

private const string DefaultConnectionString = "Server=localhost;Username=npgsql_tests;Password=npgsql_tests;Port=5432";
ConnectionString = connectionString;
}
Comment on lines +27 to +32
Copy link

Copilot AI Feb 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The presence check Config["DefaultConnection"] is { } connectionString treats an empty/whitespace value as configured, which will set ConnectionString to an invalid value and skip the testcontainer fallback. Consider using !string.IsNullOrWhiteSpace(connectionString) (or trimming) to decide whether to start the container.

Copilot uses AI. Check for mistakes.
else
{
Console.WriteLine("No connection string configured via Test:Npgsql:DefaultConnection, starting up testcontainer...");

public static string DefaultConnection
=> Config["DefaultConnection"] ?? DefaultConnectionString;
_postgreSqlContainer = new PostgreSqlBuilder("postgres:latest")
.WithCommand("-c", "max_connections=200")
.Build();
_postgreSqlContainer.StartAsync().GetAwaiter().GetResult();
ConnectionString = _postgreSqlContainer.GetConnectionString();
Comment on lines +35 to +41
Copy link

Copilot AI Feb 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The testcontainer fallback uses postgres:latest, but this test suite has PostGIS-dependent tests (RequiresPostgisAttribute checks for the postgis extension). Using a plain Postgres image means PostGIS tests will be skipped (or fail if NPGSQL_TEST_POSTGIS is set), reducing parity with CI. Consider switching to a PostGIS-enabled image (e.g., postgis/postgis:*) and/or avoiding the latest tag to keep the fallback reproducible.

Copilot uses AI. Check for mistakes.

AppDomain.CurrentDomain.ProcessExit += (_, _) =>
{
try
{
_postgreSqlContainer?.DisposeAsync().AsTask().GetAwaiter().GetResult();
}
catch
{
// Ignore exceptions during process-exit cleanup.
}
};
}

Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
}

private static Version? _postgresVersion;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public TestNpgsqlRetryingExecutionStrategy()
new DbContext(
new DbContextOptionsBuilder()
.EnableServiceProviderCaching(false)
.UseNpgsql(TestEnvironment.DefaultConnection).Options),
.UseNpgsql(TestEnvironment.ConnectionString).Options),
DefaultMaxRetryCount, DefaultMaxDelay, AdditionalSqlStates)
{
}
Expand Down
7 changes: 0 additions & 7 deletions test/EFCore.PG.FunctionalTests/config.json

This file was deleted.