Skip to content

Commit

Permalink
feat: Add Flyway example (#1002)
Browse files Browse the repository at this point in the history
  • Loading branch information
HofmeisterAn authored Sep 17, 2023
1 parent c798c81 commit 5317240
Show file tree
Hide file tree
Showing 18 changed files with 226 additions and 5 deletions.
2 changes: 1 addition & 1 deletion .config/dotnet-tools.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"isRoot": true,
"tools": {
"cake.tool": {
"version": "3.0.0",
"version": "3.1.0",
"commands": [
"dotnet-cake"
]
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/cicd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ jobs:
uses: actions/setup-java@v3
with:
distribution: temurin
java-version: 11
java-version: 17

- name: Setup .NET
uses: actions/setup-dotnet@v3
Expand Down
4 changes: 2 additions & 2 deletions build.cake
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#tool nuget:?package=dotnet-sonarscanner&version=5.13.0
#tool nuget:?package=dotnet-sonarscanner&version=5.13.1

#addin nuget:?package=Cake.Sonar&version=1.1.31
#addin nuget:?package=Cake.Sonar&version=1.1.32

#addin nuget:?package=Cake.Git&version=3.0.0

Expand Down
1 change: 1 addition & 0 deletions examples/Flyway/.editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
root = true
1 change: 1 addition & 0 deletions examples/Flyway/.gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* text=auto
28 changes: 28 additions & 0 deletions examples/Flyway/Directory.Build.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<Project>
<PropertyGroup>
<SolutionDir Condition=" '$(SolutionDir)' == '' ">$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), Flyway.sln))/</SolutionDir>
</PropertyGroup>
<PropertyGroup>
<Version>0.1.0</Version>
<PackageId>$(AssemblyName)</PackageId>
<AssemblyVersion>$(Version)</AssemblyVersion>
<FileVersion>$(Version)</FileVersion>
<InformationalVersion>$(Version)</InformationalVersion>
<NeutralLanguage>en-US</NeutralLanguage>
<Authors>Andre Hofmeister</Authors>
<Company></Company>
<Description></Description>
<Summary></Summary>
<PackageIconUrl></PackageIconUrl>
<PackageLicenseExpression></PackageLicenseExpression>
<PackageProjectUrl></PackageProjectUrl>
<PackageTags></PackageTags>
<RepositoryType>git</RepositoryType>
<RepositoryUrl>https://github.com/testcontainers/testcontainers-dotnet-sample</RepositoryUrl>
</PropertyGroup>
<PropertyGroup>
<LangVersion>10.0</LangVersion>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
26 changes: 26 additions & 0 deletions examples/Flyway/Flyway.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{424CFC36-D6F7-4DBB-BD1C-0C84FE30E665}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Flyway.Tests", "tests\Flyway.Tests\Flyway.Tests.csproj", "{1E882BFE-4A5E-4E58-A533-81E1BE9E9BFD}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{1E882BFE-4A5E-4E58-A533-81E1BE9E9BFD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1E882BFE-4A5E-4E58-A533-81E1BE9E9BFD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1E882BFE-4A5E-4E58-A533-81E1BE9E9BFD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1E882BFE-4A5E-4E58-A533-81E1BE9E9BFD}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{1E882BFE-4A5E-4E58-A533-81E1BE9E9BFD} = {424CFC36-D6F7-4DBB-BD1C-0C84FE30E665}
EndGlobalSection
EndGlobal
11 changes: 11 additions & 0 deletions examples/Flyway/Packages.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<Project>
<ItemGroup>
<PackageReference Update="JetBrains.Annotations" Version="2023.2.0" PrivateAssets="all"/>
<PackageReference Update="Testcontainers.PostgreSql" Version="3.5.0"/>
<PackageReference Update="Microsoft.NET.Test.Sdk" Version="17.7.2"/>
<PackageReference Update="xunit.runner.visualstudio" Version="2.5.0"/>
<PackageReference Update="xunit" Version="2.5.0"/>
<PackageReference Update="Npgsql" Version="6.0.10"/>
</ItemGroup>
</Project>
9 changes: 9 additions & 0 deletions examples/Flyway/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Testcontainers for .NET Flyway example

This example demonstrates how to use Testcontainers in conjunction with Flyway to execute database migrations and prepare a dependent database before running tests. The `FlywayTest` test class executes its tests against the pre-configured PostgreSQL database, interacting with the table that is created, altered, and seeded beforehand. This test class receives a class fixture, which provides access to the prepared database through the `DbConnection` property. The database is started, created, and seeded once and is shared across the tests within the `FlywayTest` test collection. Checkout and run the tests on your machine:

```console
git clone --branch develop [email protected]:testcontainers/testcontainers-dotnet.git
cd ./testcontainers-dotnet/examples/Flyway/
dotnet test Flyway.sln --configuration=Release
```
Empty file added examples/Flyway/src/.gitkeep
Empty file.
74 changes: 74 additions & 0 deletions examples/Flyway/tests/Flyway.Tests/DbFixture.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
namespace Flyway.Tests;

[UsedImplicitly]
public sealed class DbFixture : IAsyncLifetime
{
private readonly INetwork _network = new NetworkBuilder().Build();

private readonly IContainer _postgreSqlContainer;

private readonly IContainer _flywayContainer;

public DbFixture()
{
// Testcontainers starts the dependent database (PostgreSQL) and the database
// migration tool Flyway. It establishes a network connection between these two
// containers. Before starting the Flyway container, Testcontainers copies the SQL
// migration files into it. When the Flyway container starts, it initiates the
// dependent database container, connects to it, and begins the database migration
// as soon as the database is ready. Once the migration is finished, the Flyway
// container exits, and the database container becomes available for tests.

_postgreSqlContainer = new PostgreSqlBuilder()
.WithImage("postgres:15-alpine")
.WithNetwork(_network)
.WithNetworkAliases(nameof(_postgreSqlContainer))
.Build();

// The member `WithResourceMapping(string, string)` copies the SQL migration files
// from the test host into the Flyway container before it starts. This ensures that
// the files are available as soon as the container starts. Flyway will
// automatically pick them up and start the database migration process.

_flywayContainer = new ContainerBuilder()
.WithImage("flyway/flyway:9-alpine")
.WithResourceMapping("migrate/", "/flyway/sql/")
.WithCommand("-url=jdbc:postgresql://" + nameof(_postgreSqlContainer) + "/")
.WithCommand("-user=" + PostgreSqlBuilder.DefaultUsername)
.WithCommand("-password=" + PostgreSqlBuilder.DefaultPassword)
.WithCommand("-connectRetries=3")
.WithCommand("migrate")
.WithNetwork(_network)
.DependsOn(_postgreSqlContainer)
.WithWaitStrategy(Wait.ForUnixContainer().AddCustomWaitStrategy(new MigrationCompleted()))
.Build();
}

public DbConnection DbConnection => new NpgsqlConnection(((PostgreSqlContainer)_postgreSqlContainer).GetConnectionString());

public Task InitializeAsync()
{
return _flywayContainer.StartAsync();
}

public Task DisposeAsync()
{
// We do not need to manually dispose Docker resources. If resources depend on each
// other, it is necessary to dispose them in the correct order. Testcontainers'
// Resource Reaper (Ryuk) will reliably take care of these resources and dispose
// them after the test automatically.
return Task.CompletedTask;
}

private sealed class MigrationCompleted : IWaitUntil
{
// The Flyway container will exit after executing the database migration. We do not
// check if the migration was successful. To verify its success, we can either
// check the exit code of the container or the console output, respectively the
// standard output (stdout) or error output (stderr).
public Task<bool> UntilAsync(IContainer container)
{
return Task.FromResult(TestcontainersStates.Exited.Equals(container.State));
}
}
}
17 changes: 17 additions & 0 deletions examples/Flyway/tests/Flyway.Tests/Flyway.Tests.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<Sdk Name="Microsoft.Build.CentralPackageVersions" Version="2.1.3"/>
<PropertyGroup>
<TargetFrameworks>net6.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="JetBrains.Annotations"/>
<PackageReference Include="Testcontainers.PostgreSql"/>
<PackageReference Include="Microsoft.NET.Test.Sdk"/>
<PackageReference Include="xunit.runner.visualstudio"/>
<PackageReference Include="xunit"/>
<PackageReference Include="Npgsql"/>
</ItemGroup>
<ItemGroup>
<None Include="migrate/*.sql" CopyToOutputDirectory="PreserveNewest"/>
</ItemGroup>
</Project>
34 changes: 34 additions & 0 deletions examples/Flyway/tests/Flyway.Tests/FlywayTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
namespace Flyway.Tests;

public sealed class FlywayTest : IClassFixture<DbFixture>, IDisposable
{
private readonly DbConnection _dbConnection;

public FlywayTest(DbFixture db)
{
_dbConnection = db.DbConnection;
_dbConnection.Open();
}

public void Dispose()
{
_dbConnection.Dispose();
}

[Fact]
public void UsersTableContainsJohnDoe()
{
// Given
using var command = _dbConnection.CreateCommand();
command.CommandText = "SELECT username, email, age FROM users;";

// When
using var dataReader = command.ExecuteReader();

// Then
Assert.True(dataReader.Read());
Assert.Equal("john_doe", dataReader.GetString(0));
Assert.Equal("[email protected]", dataReader.GetString(1));
Assert.Equal(30, dataReader.GetInt32(2));
}
}
11 changes: 11 additions & 0 deletions examples/Flyway/tests/Flyway.Tests/Usings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
global using System;
global using System.Data.Common;
global using System.Threading.Tasks;
global using DotNet.Testcontainers.Builders;
global using DotNet.Testcontainers.Configurations;
global using DotNet.Testcontainers.Containers;
global using DotNet.Testcontainers.Networks;
global using JetBrains.Annotations;
global using Npgsql;
global using Testcontainers.PostgreSql;
global using Xunit;
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
CREATE TABLE users
(
id SERIAL PRIMARY KEY,
username VARCHAR(50) NOT NULL,
email VARCHAR(100) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE users ADD COLUMN age INT;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
INSERT INTO users (username, email, age) VALUES ('john_doe', '[email protected]', 30);
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<PackageReference Include="coverlet.collector" Version="6.0.0"/>
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.0"/>
<PackageReference Include="xunit" Version="2.5.0"/>
<PackageReference Include="Npgsql" Version="6.0.9"/>
<PackageReference Include="Npgsql" Version="6.0.10"/>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="$(SolutionDir)src/Testcontainers.PostgreSql/Testcontainers.PostgreSql.csproj"/>
Expand Down

0 comments on commit 5317240

Please sign in to comment.