diff --git a/Ductus.FluentDocker.XUnit/Ductus.FluentDocker.XUnit.csproj b/Ductus.FluentDocker.XUnit/Ductus.FluentDocker.XUnit.csproj new file mode 100644 index 0000000..69e0137 --- /dev/null +++ b/Ductus.FluentDocker.XUnit/Ductus.FluentDocker.XUnit.csproj @@ -0,0 +1,31 @@ + + + netstandard1.6;net461 + 1.0.0 + 1.0.0.0 + 1.0.0.0 + $(VersionSuffix) + false + Ductus.FluentDocker.XUnit + Mario Toffia + Apache-2.0 + https://github.com/mariotoffia/FluentDocker + https://pbs.twimg.com/profile_images/378800000124779041/fbbb494a7eef5f9278c6967b6072ca3e.png + Ductus.FluentDocker.XUnit + false + Docker;Docker-Compose;Docker Compose;Docker-Machine;Docker Machine;Linux;Windows;Mac;Test;NET Core + git + https://github.com/mariotoffia/FluentDocker + + XUnit Support to allow for create, run one or more docker images while testing using docker, compose, machine (Linux, Windows, Mac) using netcore or full framework. + Documentation: https://github.com/mariotoffia/FluentDocker + + © 2016 - 2021 Mario Toffia + ..\keypair.snk + true + true + + + + + diff --git a/Ductus.FluentDocker.XUnit/FluentDockerTestBase.cs b/Ductus.FluentDocker.XUnit/FluentDockerTestBase.cs new file mode 100644 index 0000000..543585e --- /dev/null +++ b/Ductus.FluentDocker.XUnit/FluentDockerTestBase.cs @@ -0,0 +1,59 @@ +using System; +using Ductus.FluentDocker.Builders; +using Ductus.FluentDocker.Services; + +namespace Ductus.FluentDocker.XUnit +{ + public abstract class FluentDockerTestBase : IDisposable + { + protected IContainerService Container; + + protected abstract ContainerBuilder Build(); + + public FluentDockerTestBase() + { + Container = Build().Build(); + try + { + Container.Start(); + } + catch + { + Container.Dispose(); + throw; + } + + OnContainerInitialized(); + } + + public void Dispose() + { + OnContainerTearDown(); + + var c = Container; + Container = null; + try + { + c?.Dispose(); + } + catch + { + // Ignore + } + } + + /// + /// Invoked just before the container is teared down. + /// + protected virtual void OnContainerTearDown() + { + } + + /// + /// Invoked after a container has been created and started. + /// + protected virtual void OnContainerInitialized() + { + } + } +} diff --git a/Ductus.FluentDocker.XUnit/PostgresTestBase.cs b/Ductus.FluentDocker.XUnit/PostgresTestBase.cs new file mode 100644 index 0000000..c2402e9 --- /dev/null +++ b/Ductus.FluentDocker.XUnit/PostgresTestBase.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Ductus.FluentDocker.Builders; +using Ductus.FluentDocker.Services.Extensions; + +namespace Ductus.FluentDocker.XUnit +{ + public abstract class PostgresTestBase : FluentDockerTestBase + { + protected const string PostgresConnectionString = + "Server={0};Port={1};Userid={2};Password={3};" + + "Pooling=false;MinPoolSize=1;MaxPoolSize=20;" + + "Timeout=15;SslMode=Disable;Database={4}"; + + protected const string PostgresUser = "postgres"; + protected const string PostgresDb = "postgres"; + protected readonly string DockerImage; + protected readonly string PostgresPassword; + + protected string ConnectionString; + + protected PostgresTestBase(string password = "mysecretpassword", string image = "postgres:alpine") + { + PostgresPassword = password; + DockerImage = image; + } + + protected override ContainerBuilder Build() + { + return new Builder().UseContainer() + .UseImage("postgres:alpine") + .WithEnvironment( + $"POSTGRES_PASSWORD={PostgresPassword}", + "POSTGRES_HOST_AUTH_METHOD=trust") + .ExposePort(5432) + .WaitForPort("5432/tcp", 30000 /*30s*/); + } + + protected override void OnContainerInitialized() + { + var ep = Container.ToHostExposedEndpoint("5432/tcp"); + ConnectionString = string.Format(PostgresConnectionString, ep.Address, ep.Port, PostgresUser, + PostgresPassword, PostgresDb); + } + } +} diff --git a/FluentDocker.sln b/FluentDocker.sln index 43089fe..c2bac81 100644 --- a/FluentDocker.sln +++ b/FluentDocker.sln @@ -28,6 +28,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "data", "data", "{60257CD9-E data\docker_network_inspect.json = data\docker_network_inspect.json EndProjectSection EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ductus.FluentDocker.XUnit", "Ductus.FluentDocker.XUnit\Ductus.FluentDocker.XUnit.csproj", "{F8020BBA-78F7-426A-BE28-13716CC17966}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -46,6 +48,10 @@ Global {FA836F5A-6361-4042-9B12-E38EB057CD41}.Debug|Any CPU.Build.0 = Debug|Any CPU {FA836F5A-6361-4042-9B12-E38EB057CD41}.Release|Any CPU.ActiveCfg = Release|Any CPU {FA836F5A-6361-4042-9B12-E38EB057CD41}.Release|Any CPU.Build.0 = Release|Any CPU + {F8020BBA-78F7-426A-BE28-13716CC17966}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F8020BBA-78F7-426A-BE28-13716CC17966}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F8020BBA-78F7-426A-BE28-13716CC17966}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F8020BBA-78F7-426A-BE28-13716CC17966}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/README.md b/README.md index 2835f1b..92663c3 100644 --- a/README.md +++ b/README.md @@ -982,7 +982,23 @@ using ( ``` ## Test Support -This repo contains two nuget packages, one for the fluent access and the other is a ms-test base classes to be used while testing. For example in a unit-test it is possible to fire up a postgres container and wait when the the db has booted. +This repo contains three nuget packages, one for the fluent access, one for ms-test base classes and another for xunit base classes to be used while testing. For example in a unit-test it is possible to fire up a postgres container and wait when the the db has booted. + +### XUnit +```cs + public class PostgresXUnitTests : IClassFixture + { + [Fact] + public void Test() + { + // We now have a running postgres + // and a valid connection string to use. + } + } +``` + + +### MSTest ```cs using ( var container =