Skip to content

Commit 7653525

Browse files
committed
test cleanup
1 parent d5d7126 commit 7653525

30 files changed

+313
-216
lines changed
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1-
<Project Sdk="Microsoft.NET.Sdk">
1+
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
44
<TargetFramework>netstandard1.4</TargetFramework>
55
</PropertyGroup>
66

77
<ItemGroup>
88
<PackageReference Include="Docker.DotNet" Version="2.124.3" />
9+
<PackageReference Include="System.Diagnostics.Process" Version="4.3.0" />
10+
<PackageReference Include="System.Net.NetworkInformation" Version="4.3.0" />
911
<PackageReference Include="System.Threading.Thread" Version="4.3.0" />
1012
</ItemGroup>
1113
</Project>

test/Docker.Testify/DockerSetup.cs

Lines changed: 98 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -2,87 +2,127 @@
22
using Docker.DotNet.Models;
33
using System;
44
using System.Collections.Generic;
5+
using System.Diagnostics;
6+
using System.Linq;
7+
using System.Net.NetworkInformation;
58
using System.Runtime.InteropServices;
69
using System.Text;
710
using System.Threading;
11+
using System.Threading.Tasks;
812

913
namespace Docker.Testify
1014
{
1115
public abstract class DockerSetup : IDisposable
12-
{
13-
public abstract string ImageName { get; }
14-
public abstract string ContainerName { get; }
15-
public abstract int ExternalPort { get; }
16+
{
17+
public abstract string ImageName { get; }
18+
public virtual string ContainerPrefix => "tests";
1619
public abstract int InternalPort { get; }
1720

1821
public virtual string ImageTag => "latest";
1922
public virtual TimeSpan TimeOut => TimeSpan.FromSeconds(30);
2023
public virtual IList<string> EnvironmentVariables => new List<string>();
24+
public int ExternalPort { get; }
2125

22-
public abstract bool TestReady();
23-
public abstract void ContainerReady();
26+
public abstract bool TestReady();
27+
public abstract void PublishConnectionInfo();
2428

25-
protected DockerClient docker;
29+
protected readonly DockerClient docker;
2630
protected string containerId;
2731

28-
public DockerSetup()
29-
{
30-
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
32+
protected DockerSetup()
33+
{
34+
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
3135
docker = new DockerClientConfiguration(new Uri("npipe://./pipe/docker_engine")).CreateClient();
3236
else
3337
docker = new DockerClientConfiguration(new Uri("unix:///var/run/docker.sock")).CreateClient();
3438

35-
HostConfig hostCfg = new HostConfig();
36-
PortBinding pb = new PortBinding();
37-
pb.HostIP = "0.0.0.0";
38-
pb.HostPort = ExternalPort.ToString();
39-
hostCfg.PortBindings = new Dictionary<string, IList<PortBinding>>();
40-
hostCfg.PortBindings.Add($"{InternalPort}/tcp", new PortBinding[] { pb });
41-
42-
docker.Images.PullImageAsync(new ImagesPullParameters() { Parent = ImageName, Tag = ImageTag }, null).Wait();
43-
44-
var container = docker.Containers.CreateContainerAsync(new CreateContainerParameters()
45-
{
46-
Image = $"{ImageName}:{ImageTag}",
47-
Name = $"{ContainerName}-{Guid.NewGuid()}",
48-
HostConfig = hostCfg,
49-
Env = EnvironmentVariables
50-
}).Result;
51-
52-
Console.WriteLine("Starting docker container...");
53-
bool started = docker.Containers.StartContainerAsync(container.ID, new ContainerStartParameters()).Result;
54-
if (started)
55-
{
56-
Console.WriteLine("Waiting service to start in the docker container...");
57-
58-
var counter = 0;
59-
var ready = false;
60-
61-
while ((counter < (TimeOut.TotalSeconds)) && (!ready))
62-
{
63-
Thread.Sleep(1000);
64-
ready = TestReady();
65-
}
66-
if (ready)
67-
{
68-
Console.WriteLine($"Docker container started: {container.ID}");
69-
ContainerReady();
70-
}
71-
else
72-
{
73-
Console.WriteLine("Docker container timeout waiting for service");
74-
}
75-
}
76-
else
77-
{
78-
Console.WriteLine("Docker container failed");
79-
}
39+
ExternalPort = GetFreePort();
40+
41+
Debug.WriteLine($"Selected port {ExternalPort}");
42+
43+
StartContainer().Wait();
8044
}
8145

46+
public async Task StartContainer()
47+
{
48+
var hostCfg = new HostConfig();
49+
var pb = new PortBinding
50+
{
51+
HostIP = "0.0.0.0",
52+
HostPort = ExternalPort.ToString()
53+
};
54+
55+
hostCfg.PortBindings = new Dictionary<string, IList<PortBinding>>();
56+
hostCfg.PortBindings.Add($"{InternalPort}/tcp", new PortBinding[] { pb });
57+
58+
//await docker.Images.PullImageAsync(new ImagesPullParameters() { Parent = ImageName, Tag = ImageTag }, null);
59+
Process.Start("docker", $"pull {ImageName}:{ImageTag}").WaitForExit();
60+
61+
var container = await docker.Containers.CreateContainerAsync(new CreateContainerParameters()
62+
{
63+
Image = $"{ImageName}:{ImageTag}",
64+
Name = $"{ContainerPrefix}-{Guid.NewGuid()}",
65+
HostConfig = hostCfg,
66+
Env = EnvironmentVariables
67+
});
68+
69+
Debug.WriteLine("Starting docker container...");
70+
var started = await docker.Containers.StartContainerAsync(container.ID, new ContainerStartParameters());
71+
if (started)
72+
{
73+
containerId = container.ID;
74+
PublishConnectionInfo();
75+
76+
Debug.WriteLine("Waiting service to start in the docker container...");
77+
78+
var ready = false;
79+
var expiryTime = DateTime.Now.Add(TimeOut);
80+
81+
while ((DateTime.Now < expiryTime) && (!ready))
82+
{
83+
await Task.Delay(1000);
84+
ready = TestReady();
85+
}
86+
87+
if (ready)
88+
{
89+
Debug.WriteLine($"Docker container started: {container.ID}");
90+
}
91+
else
92+
{
93+
Debug.WriteLine("Docker container timeout waiting for service");
94+
throw new TimeoutException();
95+
}
96+
}
97+
else
98+
{
99+
Debug.WriteLine("Docker container failed");
100+
}
101+
}
102+
82103
public void Dispose()
83104
{
84-
docker.Containers.KillContainerAsync(containerId, new ContainerKillParameters()).Wait();
85-
docker.Containers.RemoveContainerAsync(containerId, new ContainerRemoveParameters() { Force = true }).Wait();
105+
docker.Containers.KillContainerAsync(containerId, new ContainerKillParameters()).Wait();
106+
docker.Containers.RemoveContainerAsync(containerId, new ContainerRemoveParameters() { Force = true }).Wait();
86107
}
87-
}
108+
109+
private int GetFreePort()
110+
{
111+
const int startRange = 1000;
112+
const int endRange = 10000;
113+
var ipGlobalProperties = IPGlobalProperties.GetIPGlobalProperties();
114+
var tcpPorts = ipGlobalProperties.GetActiveTcpListeners();
115+
var udpPorts = ipGlobalProperties.GetActiveUdpListeners();
116+
117+
var result = startRange;
118+
119+
while (((tcpPorts.Any(x => x.Port == result)) || (udpPorts.Any(x => x.Port == result))) && result <= endRange)
120+
result++;
121+
122+
if (result > endRange)
123+
throw new PortsInUseException();
124+
125+
return result;
126+
}
127+
}
88128
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
5+
namespace Docker.Testify
6+
{
7+
public class PortsInUseException : Exception
8+
{
9+
public PortsInUseException()
10+
: base("Ports in range are not available")
11+
{
12+
}
13+
}
14+
}

test/WorkflowCore.IntegrationTests/WorkflowCore.IntegrationTests.csproj

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,8 @@
1919
</ItemGroup>
2020

2121
<ItemGroup>
22-
<PackageReference Include="Machine.Specifications.Runner.Console" Version="0.9.3" />
23-
<PackageReference Include="Machine.Specifications.Runner.VisualStudio" Version="2.2.2" />
2422
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0" />
25-
<PackageReference Include="dotnet-test-mspec" Version="0.2.0" />
2623
<PackageReference Include="FluentAssertions" Version="4.19.2" />
27-
<PackageReference Include="Machine.Fakes" Version="2.8.0" />
28-
<PackageReference Include="Machine.Fakes.Moq" Version="2.8.0" />
29-
<PackageReference Include="Machine.Specifications" Version="0.11.0" />
30-
<PackageReference Include="Machine.Specifications.Should" Version="0.11.0" />
3124
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="1.1.1" />
3225
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="1.1.1" />
3326
<PackageReference Include="Moq" Version="4.7.1" />

test/WorkflowCore.TestAssets/WorkflowCore.TestAssets.csproj

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,6 @@
1717

1818
<ItemGroup>
1919
<PackageReference Include="FluentAssertions" Version="4.19.0" />
20-
<PackageReference Include="Machine.Fakes" Version="2.8.0" />
21-
<PackageReference Include="Machine.Fakes.Moq" Version="2.8.0" />
22-
<PackageReference Include="Machine.Specifications" Version="0.11.0" />
23-
<PackageReference Include="Machine.Specifications.Should" Version="0.11.0" />
2420
<PackageReference Include="Moq" Version="4.7.1" />
2521
<PackageReference Include="Newtonsoft.Json" Version="9.0.1" />
2622
<PackageReference Include="NUnit" Version="3.6.1" />

test/WorkflowCore.Tests.MongoDB/MongoDockerSetup.cs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,12 @@ namespace WorkflowCore.Tests.MongoDB
1212
{
1313
public class MongoDockerSetup : DockerSetup
1414
{
15-
1615
public static string ConnectionString { get; set; }
1716

1817
public override string ImageName => "mongo";
19-
public override string ContainerName => "mongo-workflow-tests";
20-
public override int ExternalPort => 28017;
2118
public override int InternalPort => 27017;
2219

23-
public override void ContainerReady()
20+
public override void PublishConnectionInfo()
2421
{
2522
ConnectionString = $"mongodb://localhost:{ExternalPort}";
2623
}

test/WorkflowCore.Tests.MongoDB/WorkflowCore.Tests.MongoDB.csproj

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,9 @@
2323

2424
<ItemGroup>
2525
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0" />
26-
<PackageReference Include="dotnet-test-mspec" Version="0.2.0" />
27-
<PackageReference Include="FluentAssertions" Version="4.19.2" />
28-
<PackageReference Include="Machine.Specifications" Version="0.11.0" />
29-
<PackageReference Include="Machine.Specifications.Should" Version="0.11.0" />
3026
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="1.1.1" />
3127
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="1.1.1" />
32-
<PackageReference Include="Moq" Version="4.7.1" />
3328
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="1.1.1" />
34-
<PackageReference Include="Docker.DotNet" Version="2.124.3" />
3529
<PackageReference Include="xunit" Version="2.2.0" />
3630
<PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
3731
<PackageReference Include="MongoDB.Driver" Version="2.4.4" />

test/WorkflowCore.Tests.PostgreSQL/DockerSetup.cs

Lines changed: 23 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -5,59 +5,45 @@
55
using System.Runtime.InteropServices;
66
using System.Text;
77
using System.Threading;
8+
using Docker.Testify;
9+
using Npgsql;
810
using Xunit;
911

1012
namespace WorkflowCore.Tests.PostgreSQL
1113
{
12-
public class DockerSetup : IDisposable
14+
public class PostgresDockerSetup : DockerSetup
1315
{
14-
public static int Port = 5433;
15-
DockerClient docker;
16-
string containerId;
16+
public static string ConnectionString { get; set; }
17+
public static string ScenarioConnectionString { get; set; }
1718

18-
public string ConnectionString { get; private set; }
19+
public override string ImageName => "postgres";
20+
public override int InternalPort => 5432;
1921

20-
public DockerSetup()
22+
public override void PublishConnectionInfo()
2123
{
22-
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
23-
docker = new DockerClientConfiguration(new Uri("npipe://./pipe/docker_engine")).CreateClient();
24-
else
25-
docker = new DockerClientConfiguration(new Uri("unix:///var/run/docker.sock")).CreateClient();
26-
27-
HostConfig hostCfg = new HostConfig();
28-
PortBinding pb = new PortBinding();
29-
pb.HostIP = "0.0.0.0";
30-
pb.HostPort = Port.ToString();
31-
hostCfg.PortBindings = new Dictionary<string, IList<PortBinding>>();
32-
hostCfg.PortBindings.Add("5432/tcp", new PortBinding[] { pb });
24+
ConnectionString = $"Server=127.0.0.1;Port={ExternalPort};Database=workflow;User Id=postgres;";
25+
ScenarioConnectionString = $"Server=127.0.0.1;Port={ExternalPort};Database=workflow-scenarios;User Id=postgres;";
26+
}
3327

34-
docker.Images.PullImageAsync(new ImagesPullParameters() { Parent = "postgres", Tag = "latest" }, null).Wait();
35-
var container = docker.Containers.CreateContainerAsync(new CreateContainerParameters() { Image = "postgres:latest", Name = "workflow-postgres-tests", HostConfig = hostCfg }).Result;
36-
bool started = docker.Containers.StartContainerAsync(container.ID, new ContainerStartParameters()).Result;
37-
if (started)
28+
public override bool TestReady()
29+
{
30+
try
3831
{
39-
containerId = container.ID;
40-
Console.WriteLine("Docker container started: " + containerId);
41-
Console.Write("Waiting 10 seconds for Postgres to start in the docker container...");
42-
Thread.Sleep(10000); //allow time for PG to start
43-
Console.WriteLine("10 seconds are up.");
44-
ConnectionString = $"Server=127.0.0.1;Port={Port};Database=workflow;User Id=postgres;";
32+
var connection = new NpgsqlConnection($"Server=127.0.0.1;Port={ExternalPort};Database=postgres;User Id=postgres;");
33+
connection.Open();
34+
connection.Close();
35+
return true;
4536
}
46-
else
37+
catch
4738
{
48-
Console.WriteLine("Docker container failed");
39+
return false;
4940
}
50-
}
5141

52-
public void Dispose()
53-
{
54-
docker.Containers.KillContainerAsync(containerId, new ContainerKillParameters()).Wait();
55-
docker.Containers.RemoveContainerAsync(containerId, new ContainerRemoveParameters() { Force = true }).Wait();
56-
}
42+
}
5743
}
58-
44+
5945
[CollectionDefinition("Postgres collection")]
60-
public class PostgresCollection : ICollectionFixture<DockerSetup>
46+
public class PostgresCollection : ICollectionFixture<PostgresDockerSetup>
6147
{
6248
}
6349

test/WorkflowCore.Tests.PostgreSQL/PostgresPersistenceProviderFixture.cs

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,27 +5,21 @@
55
using WorkflowCore.Persistence.PostgreSQL;
66
using WorkflowCore.UnitTests;
77
using Xunit;
8+
using Xunit.Abstractions;
89

910
namespace WorkflowCore.Tests.PostgreSQL
1011
{
1112
[Collection("Postgres collection")]
1213
public class PostgresPersistenceProviderFixture : BasePersistenceFixture
1314
{
14-
DockerSetup _dockerSetup;
15+
private readonly IPersistenceProvider _subject;
16+
protected override IPersistenceProvider Subject => _subject;
1517

16-
public PostgresPersistenceProviderFixture(DockerSetup dockerSetup)
18+
public PostgresPersistenceProviderFixture(PostgresDockerSetup dockerSetup, ITestOutputHelper output)
1719
{
18-
_dockerSetup = dockerSetup;
19-
}
20-
21-
protected override IPersistenceProvider Subject
22-
{
23-
get
24-
{
25-
var db = new PostgresPersistenceProvider(_dockerSetup.ConnectionString, true, true);
26-
db.EnsureStoreExists();
27-
return db;
28-
}
20+
output.WriteLine($"Connecting on {PostgresDockerSetup.ConnectionString}");
21+
_subject = new PostgresPersistenceProvider(PostgresDockerSetup.ConnectionString, true, true);
22+
_subject.EnsureStoreExists();
2923
}
3024
}
3125
}

0 commit comments

Comments
 (0)