Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use Testcontainers for Integration Testing #539

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
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: 1 addition & 1 deletion test/YesSql.Tests/CoreTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public CoreTests(ITestOutputHelper output)
_output = output;
}

public async Task InitializeAsync()
public virtual async Task InitializeAsync()
{
// Create the tables only once
if (_configuration == null)
Expand Down
50 changes: 28 additions & 22 deletions test/YesSql.Tests/PostgreSqlLegacyIdentityTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,34 @@

namespace YesSql.Tests
{
// Docker command
// docker run --name postgresql -e POSTGRES_USER=root -e POSTGRES_PASSWORD=Password12! -e POSTGRES_DB=yessql -d -p 5432:5432 postgres:11
public class PostgreSqlLegacyIdentityTests : PostgreSqlTests
{
public PostgreSqlLegacyIdentityTests(ITestOutputHelper output) : base(output)
{
}
// public class PostgreSqlLegacyIdentityTests : PostgreSqlTests
// {
// public PostgreSqlLegacyIdentityTests(ITestOutputHelper output) : base(output)
// {
// }

protected override IConfiguration CreateConfiguration()
{
return new Configuration()
.UsePostgreSql(ConnectionStringBuilder.ConnectionString)
.SetTablePrefix(TablePrefix)
.UseBlockIdGenerator()
.SetIdentityColumnSize(IdentityColumnSize.Int32)
;
}
// public override async Task InitializeAsync()
// {
// await PostgreSqlContainer.StartAsync();
// await base.InitializeAsync();
// }

[Fact(Skip = "Skip to make test faster in this configuration")]
public override Task ShouldGateQuery()
{
return base.ShouldGateQuery();
}
}
// protected override IConfiguration CreateConfiguration()
// {
// return new Configuration()
// .UsePostgreSql(PostgreSqlContainer.GetConnectionString())
// .SetTablePrefix(TablePrefix)
// .UseBlockIdGenerator()
// .SetIdentityColumnSize(IdentityColumnSize.Int32)
// ;
// }

// [Fact(Skip = "Skip to make test faster in this configuration")]
// public override Task ShouldGateQuery()
// {
// return base.ShouldGateQuery();
// }

// public async override Task DisposeAsync() => await PostgreSqlContainer.DisposeAsync();
// }
}
227 changes: 116 additions & 111 deletions test/YesSql.Tests/PostgreSqlTests.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using Npgsql;
using System;
using System.Threading.Tasks;
using Testcontainers.PostgreSql;
using Xunit;
using Xunit.Abstractions;
using YesSql.Provider.PostgreSql;
Expand All @@ -10,113 +9,119 @@

namespace YesSql.Tests
{
// Docker command
// docker run --name postgresql -e POSTGRES_USER=root -e POSTGRES_PASSWORD=Password12! -e POSTGRES_DB=yessql -d -p 5432:5432 postgres:11
public class PostgreSqlTests : CoreTests
{
public static NpgsqlConnectionStringBuilder ConnectionStringBuilder => new NpgsqlConnectionStringBuilder(Environment.GetEnvironmentVariable("POSTGRESQL_CONNECTION_STRING") ?? @"Server=localhost;Port=5432;Database=yessql;User Id=root;Password=Password12!;");

protected override string DecimalColumnDefinitionFormatString => "decimal({0}, {1})";

public PostgreSqlTests(ITestOutputHelper output) : base(output)
{
}

protected override IConfiguration CreateConfiguration()
{
return new Configuration()
.UsePostgreSql(ConnectionStringBuilder.ConnectionString, "BabyYoda")
.SetTablePrefix(TablePrefix)
.UseBlockIdGenerator()
.SetIdentityColumnSize(IdentityColumnSize.Int64)
;
}

[Fact(Skip = "Postgres locks on the table")]
public override Task ShouldReadUncommittedRecords()
{
return base.ShouldReadUncommittedRecords();
}

[Fact]
public async Task ShouldIndexPropertyKeys()
{
await using (var connection = _store.Configuration.ConnectionFactory.CreateConnection())
{
await connection.OpenAsync();

await using (var transaction = await connection.BeginTransactionAsync(_store.Configuration.IsolationLevel))
{
var builder = new SchemaBuilder(_store.Configuration, transaction);

await builder.DropMapIndexTableAsync<PropertyIndex>();

await transaction.CommitAsync();
}

await using (var transaction = await connection.BeginTransactionAsync(_store.Configuration.IsolationLevel))
{
var builder = new SchemaBuilder(_store.Configuration, transaction);
await builder
.CreateMapIndexTableAsync<PropertyIndex>(column => column
.Column<string>(nameof(PropertyIndex.Name), col => col.WithLength(4000))
.Column<bool>(nameof(PropertyIndex.ForRent))
.Column<bool>(nameof(PropertyIndex.IsOccupied))
.Column<string>(nameof(PropertyIndex.Location), col => col.WithLength(4000))
);

await builder
.AlterTableAsync(nameof(PropertyIndex), table => table
.CreateIndex("IDX_Property", "Name", "ForRent", "IsOccupied", "Location"));

await transaction.CommitAsync();
}
}

_store.RegisterIndexes<PropertyIndexProvider>();

await using var session = _store.CreateSession();
var property = new Property
{
Name = new string('*', 4000),
IsOccupied = true,
ForRent = true,
Location = new string('*', 4000)
};

await session.SaveAsync(property);
}

[Fact]
public async Task ShouldCreateHashedIndexKeyName()
{
// NB: Postgres will not throw here when the key is too long. It will simply truncate it.
// This will cause exceptions in other tables when the 'short' key is truncated again.
await _store.InitializeCollectionAsync("LongCollection");

await using var connection = _store.Configuration.ConnectionFactory.CreateConnection();
await connection.OpenAsync();

await using (var transaction = await connection.BeginTransactionAsync(_store.Configuration.IsolationLevel))
{
var builder = new SchemaBuilder(_store.Configuration, transaction);

await builder.CreateReduceIndexTableAsync<PersonsByNameCol>(column => column
.Column<string>(nameof(PersonsByNameCol.Name))
.Column<int>(nameof(PersonsByNameCol.Count)),
"LongCollection"
);

await transaction.CommitAsync();
}

await using (var transaction = await connection.BeginTransactionAsync(_store.Configuration.IsolationLevel))
{
var builder = new SchemaBuilder(_store.Configuration, transaction);

await builder.DropReduceIndexTableAsync<PersonsByNameCol>("LongCollection");
await transaction.CommitAsync();
}
}
}
//public class PostgreSqlTests : CoreTests
//{
// protected override string DecimalColumnDefinitionFormatString => "decimal({0}, {1})";

// protected readonly PostgreSqlContainer PostgreSqlContainer = new PostgreSqlBuilder().Build();

// public PostgreSqlTests(ITestOutputHelper output) : base(output)
// {
// }

// public override async Task InitializeAsync()
// {
// await PostgreSqlContainer.StartAsync();
// await base.InitializeAsync();
// }

// protected override IConfiguration CreateConfiguration()
// {
// return new Configuration()
// .UsePostgreSql(PostgreSqlContainer.GetConnectionString(), "BabyYoda")
// .SetTablePrefix(TablePrefix)
// .UseBlockIdGenerator()
// .SetIdentityColumnSize(IdentityColumnSize.Int64)
// ;
// }

// [Fact(Skip = "Postgres locks on the table")]
// public override Task ShouldReadUncommittedRecords()
// {
// return base.ShouldReadUncommittedRecords();
// }

// [Fact]
// public async Task ShouldIndexPropertyKeys()
// {
// await using (var connection = _store.Configuration.ConnectionFactory.CreateConnection())
// {
// await connection.OpenAsync();

// await using (var transaction = await connection.BeginTransactionAsync(_store.Configuration.IsolationLevel))
// {
// var builder = new SchemaBuilder(_store.Configuration, transaction);

// await builder.DropMapIndexTableAsync<PropertyIndex>();

// await transaction.CommitAsync();
// }

// await using (var transaction = await connection.BeginTransactionAsync(_store.Configuration.IsolationLevel))
// {
// var builder = new SchemaBuilder(_store.Configuration, transaction);
// await builder
// .CreateMapIndexTableAsync<PropertyIndex>(column => column
// .Column<string>(nameof(PropertyIndex.Name), col => col.WithLength(4000))
// .Column<bool>(nameof(PropertyIndex.ForRent))
// .Column<bool>(nameof(PropertyIndex.IsOccupied))
// .Column<string>(nameof(PropertyIndex.Location), col => col.WithLength(4000))
// );

// await builder
// .AlterTableAsync(nameof(PropertyIndex), table => table
// .CreateIndex("IDX_Property", "Name", "ForRent", "IsOccupied", "Location"));

// await transaction.CommitAsync();
// }
// }

// _store.RegisterIndexes<PropertyIndexProvider>();

// await using var session = _store.CreateSession();
// var property = new Property
// {
// Name = new string('*', 4000),
// IsOccupied = true,
// ForRent = true,
// Location = new string('*', 4000)
// };

// await session.SaveAsync(property);
// }

// [Fact]
// public async Task ShouldCreateHashedIndexKeyName()
// {
// // NB: Postgres will not throw here when the key is too long. It will simply truncate it.
// // This will cause exceptions in other tables when the 'short' key is truncated again.
// await _store.InitializeCollectionAsync("LongCollection");

// await using var connection = _store.Configuration.ConnectionFactory.CreateConnection();
// await connection.OpenAsync();

// await using (var transaction = await connection.BeginTransactionAsync(_store.Configuration.IsolationLevel))
// {
// var builder = new SchemaBuilder(_store.Configuration, transaction);

// await builder.CreateReduceIndexTableAsync<PersonsByNameCol>(column => column
// .Column<string>(nameof(PersonsByNameCol.Name))
// .Column<int>(nameof(PersonsByNameCol.Count)),
// "LongCollection"
// );

// await transaction.CommitAsync();
// }

// await using (var transaction = await connection.BeginTransactionAsync(_store.Configuration.IsolationLevel))
// {
// var builder = new SchemaBuilder(_store.Configuration, transaction);

// await builder.DropReduceIndexTableAsync<PersonsByNameCol>("LongCollection");
// await transaction.CommitAsync();
// }
// }

// public async override Task DisposeAsync() => await PostgreSqlContainer.DisposeAsync();
//}
}
21 changes: 14 additions & 7 deletions test/YesSql.Tests/SqlServer2017Tests.cs
Original file line number Diff line number Diff line change
@@ -1,29 +1,36 @@
using Microsoft.Data.SqlClient;
using System;
using System.Threading.Tasks;
using Testcontainers.MsSql;
using Xunit.Abstractions;
using YesSql.Provider.SqlServer;

namespace YesSql.Tests
{
public class SqlServer2017Tests : SqlServerTests
{
// Docker command
// docker run --name sqlserver2017 -e "ACCEPT_EULA=Y" -e "SA_PASSWORD=Password12!" -p 1433:1433 -d mcr.microsoft.com/mssql/server:2017-latest

public override SqlConnectionStringBuilder ConnectionStringBuilder => new(Environment.GetEnvironmentVariable("SQLSERVER_2017_CONNECTION_STRING") ?? @"Server=127.0.0.1;Database=tempdb;User Id=sa;Password=Password12!;Encrypt=False");
private readonly MsSqlContainer _sqlServerContainer = new MsSqlBuilder().WithImage("mcr.microsoft.com/mssql/server:2017-latest").Build();

public SqlServer2017Tests(ITestOutputHelper output) : base(output)
{
}

public override string ConnectionString => _sqlServerContainer.GetConnectionString();

public override async Task InitializeAsync()
{
await _sqlServerContainer.StartAsync();
await base.InitializeAsync();
}

protected override IConfiguration CreateConfiguration()
{
return new Configuration()
.UseSqlServer(ConnectionStringBuilder.ConnectionString, "BobaFett")
.UseSqlServer(ConnectionString, "BobaFett")
.SetTablePrefix(TablePrefix)
.UseBlockIdGenerator()
.SetIdentityColumnSize(IdentityColumnSize.Int64)
;
}

public override async Task DisposeAsync() => await _sqlServerContainer.DisposeAsync();
}
}
20 changes: 14 additions & 6 deletions test/YesSql.Tests/SqlServer2019Tests.cs
Original file line number Diff line number Diff line change
@@ -1,28 +1,36 @@
using Microsoft.Data.SqlClient;
using System;
using System.Threading.Tasks;
using Testcontainers.MsSql;
using Xunit.Abstractions;
using YesSql.Provider.SqlServer;

namespace YesSql.Tests
{
public class SqlServer2019Tests : SqlServerTests
{
// Docker command
// docker run --name sqlserver2019 -e "ACCEPT_EULA=Y" -e "SA_PASSWORD=Password12!" -p 1433:1433 -d mcr.microsoft.com/mssql/server:2019-latest
public override SqlConnectionStringBuilder ConnectionStringBuilder => new(Environment.GetEnvironmentVariable("SQLSERVER_2019_CONNECTION_STRING") ?? @"Server=127.0.0.1;Database=tempdb;User Id=sa;Password=Password12!;Encrypt=False");
private readonly MsSqlContainer _sqlServerContainer = new MsSqlBuilder().WithImage("mcr.microsoft.com/mssql/server:2019-latest").Build();

public SqlServer2019Tests(ITestOutputHelper output) : base(output)
{
}

public override string ConnectionString => _sqlServerContainer.GetConnectionString();

public override async Task InitializeAsync()
{
await _sqlServerContainer.StartAsync();
await base.InitializeAsync();
}

protected override IConfiguration CreateConfiguration()
{
return new Configuration()
.UseSqlServer(ConnectionStringBuilder.ConnectionString, "BobaFett")
.UseSqlServer(_sqlServerContainer.GetConnectionString(), "BobaFett")
.SetTablePrefix(TablePrefix)
.UseBlockIdGenerator()
.SetIdentityColumnSize(IdentityColumnSize.Int64)
;
}

public override async Task DisposeAsync() => await _sqlServerContainer.DisposeAsync();
}
}
Loading
Loading