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

docs: Add Flyway example #1002

Merged
merged 1 commit into from
Sep 17, 2023
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: 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 git@github.com: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("john@example.com", 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', 'john@example.com', 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