Skip to content

Commit 283d785

Browse files
Merge pull request #20 from devjoes/fix-docker-teardown-on-start
Updates detection of already-running docker compose instances
2 parents 0b852cb + ee24f86 commit 283d785

6 files changed

Lines changed: 53 additions & 42 deletions

File tree

DockerComposeFixture.Tests/DockerFixtureTests.cs

Lines changed: 27 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -22,25 +22,24 @@ public void Init_StopsDocker_IfAlreadyRunning()
2222
{
2323
var compose = new Mock<IDockerCompose>();
2424
compose.Setup(c => c.PauseMs).Returns(NumberOfMsInOneSec);
25-
compose.Setup(c => c.Ps())
26-
.Returns(new[] { "--------", " Up ", " Up " });
25+
compose.Setup(c => c.PsWithJsonFormat())
26+
.Returns(new[] { "non-json-message", "{ \"Status\": \"Up 3 seconds\" }", "{ \"Status\": \"Up 15 seconds\" }" });
2727
compose.Setup(c => c.Up()).Returns(Task.Delay(ComposeUpRunDurationMs));
2828

2929
new DockerFixture(null)
3030
.Init(new[] { Path.GetTempFileName() }, "up", "down", 120, null, compose.Object);
3131
compose.Verify(c => c.Init(It.IsAny<string>(), "up", "down"), Times.Once);
3232
compose.Verify(c => c.Down(), Times.Once);
33-
3433
}
3534

3635
[Fact]
3736
public void Init_InitialisesDocker_WhenCalled()
3837
{
3938
var compose = new Mock<IDockerCompose>();
4039
compose.Setup(c => c.PauseMs).Returns(NumberOfMsInOneSec);
41-
compose.SetupSequence(c => c.Ps())
42-
.Returns(new[] { "--------" })
43-
.Returns(new[] { "--------", " Up ", " Up " });
40+
compose.SetupSequence(c => c.PsWithJsonFormat())
41+
.Returns(new[] { "non-json-message" })
42+
.Returns(new[] { "non-json-message", "{ \"Status\": \"Up 3 seconds\" }", "{ \"Status\": \"Up 15 seconds\" }" });
4443
compose.Setup(c => c.Up()).Returns(Task.Delay(ComposeUpRunDurationMs));
4544

4645
var tmp = Path.GetTempFileName();
@@ -56,9 +55,9 @@ public void InitOnce_InitialisesDockerOnce_WhenCalledTwice()
5655
var compose = new Mock<IDockerCompose>();
5756
compose.Setup(c => c.PauseMs).Returns(NumberOfMsInOneSec);
5857
compose.Setup(c => c.Up()).Returns(Task.Delay(ComposeUpRunDurationMs));
59-
compose.SetupSequence(c => c.Ps())
60-
.Returns(new[] { "--------" })
61-
.Returns(new[] { "--------", " Up ", " Up " });
58+
compose.SetupSequence(c => c.PsWithJsonFormat())
59+
.Returns(new[] { "non-json-message" })
60+
.Returns(new[] { "non-json-message", "{ \"Status\": \"Up 3 seconds\" }", "{ \"Status\": \"Up 15 seconds\" }" });
6261

6362
var tmp = Path.GetTempFileName();
6463
var fixture = new DockerFixture(null);
@@ -75,8 +74,8 @@ public void Init_Waits_UntilUpTestIsTrue()
7574
var compose = new Mock<IDockerCompose>();
7675
compose.Setup(c => c.PauseMs).Returns(NumberOfMsInOneSec);
7776
compose.Setup(c => c.Up()).Returns(Task.Delay(5000));
78-
compose.Setup(c => c.Ps())
79-
.Returns(new[] { "--------", " Up ", " Up " });
77+
compose.Setup(c => c.PsWithJsonFormat())
78+
.Returns(new[] { "non-json-message", "{ \"Status\": \"Up 3 seconds\" }", "{ \"Status\": \"Up 15 seconds\" }" });
8079
const string successText = "Everything is up";
8180

8281
var logger = new ListLogger();
@@ -100,8 +99,8 @@ public void Init_Throws_IfTestIsNeverTrue()
10099
{
101100
var compose = new Mock<IDockerCompose>();
102101
compose.Setup(c => c.PauseMs).Returns(NumberOfMsInOneSec);
103-
compose.Setup(c => c.Ps())
104-
.Returns(new[] { "--------", " Up ", " Up " });
102+
compose.Setup(c => c.PsWithJsonFormat())
103+
.Returns(new[] { "non-json-message", "{ \"Status\": \"Up 3 seconds\" }", "{ \"Status\": \"Up 15 seconds\" }" });
105104
const string successText = "Everything is up";
106105
var logger = new ListLogger();
107106
compose.SetupGet(c => c.Logger).Returns(new []{ logger});
@@ -132,27 +131,26 @@ public void Init_MonitorsServices_WhenTheyStartSlowly()
132131
compose.Setup(c => c.Up())
133132
.Returns(Task.Delay(ComposeUpRunDurationMs))
134133
.Callback(() => stopwatch.Start());
135-
compose.Setup(c => c.Ps()).Returns(() =>
134+
compose.Setup(c => c.PsWithJsonFormat()).Returns(() =>
136135
{
137136
if (!stopwatch.IsRunning)
138137
{
139-
return new[] { "--------" };
138+
return new[] { "non-json-message" };
140139
}
141-
string firstServiceStatus = stopwatch.ElapsedMilliseconds < 1000 ? " Starting " : " Up ";
142-
string secondServiceStatus = stopwatch.ElapsedMilliseconds < 3000 ? " Starting " : " Up ";
140+
var firstServiceStatus = stopwatch.ElapsedMilliseconds < 1000 ? "Starting" : "Up 2 seconds";
141+
var secondServiceStatus = stopwatch.ElapsedMilliseconds < 3000 ? "Starting" : "Up 4 seconds";
143142
return new[]
144143
{
145144
"blah",
146-
"--------",
147-
$"14f227387e7c\ttestservice1\t\"dotnet TestService...\"\t20 seconds ago\t{firstServiceStatus}\t0.0.0.0:32769->80/tcp\ttestservice_testservice_1",
148-
$"14f227387e7d\ttestservice2\t\"dotnet TestService...\"\t20 seconds ago\t{secondServiceStatus}\t0.0.0.0:32769->89/tcp\ttestservice_testservice_2"
145+
$"{{ \"Status\": \"{firstServiceStatus}\" }}",
146+
$"{{ \"Status\": \"{secondServiceStatus}\" }}"
149147
};
150148
});
151149

152150
new DockerFixture(null).Init(new[] { Path.GetTempFileName() }, "up", "down", 120, null, compose.Object);
153151

154152
compose.Verify(c => c.Up(), Times.Once);
155-
compose.Verify(c => c.Ps(), Times.AtLeast(5));
153+
compose.Verify(c => c.PsWithJsonFormat(), Times.AtLeast(5));
156154
}
157155

158156

@@ -162,10 +160,10 @@ public void Init_Throws_WhenServicesFailToStart()
162160
var compose = new Mock<IDockerCompose>();
163161
compose.Setup(c => c.PauseMs).Returns(NumberOfMsInOneSec);
164162
bool firstTime = true;
165-
compose.Setup(c => c.Ps())
163+
compose.Setup(c => c.PsWithJsonFormat())
166164
.Returns(() =>
167165
{
168-
var data = firstTime ? new[] { "--------" } : new[] { "--------", " Down ", " Down " };
166+
var data = firstTime ? new[] { "non-json-message" } : new[] { "--------", " Down ", " Down " };
169167
firstTime = false;
170168
return data;
171169
});
@@ -184,16 +182,16 @@ public void Init_Throws_DockerComposeExitsPrematurely()
184182

185183
Assert.Throws<DockerComposeException>(() =>
186184
new DockerFixture(null).Init(new[] { Path.GetTempFileName() }, "up", "down", 120, null, compose.Object));
187-
compose.Verify(c => c.Ps(), Times.Once);
185+
compose.Verify(c => c.PsWithJsonFormat(), Times.Once);
188186
}
189187

190188
[Fact]
191189
public void Init_Throws_WhenYmlFileDoesntExist()
192190
{
193191
var compose = new Mock<IDockerCompose>();
194192
compose.Setup(c => c.PauseMs).Returns(NumberOfMsInOneSec);
195-
compose.Setup(c => c.Ps())
196-
.Returns(new[] { "--------", " Up ", " Up " });
193+
compose.Setup(c => c.PsWithJsonFormat())
194+
.Returns(new[] { "non-json-message", "{ \"Status\": \"Up 3 seconds\" }", "{ \"Status\": \"Up 15 seconds\" }" });
197195

198196
string fileDoesntExist = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
199197
Assert.Throws<ArgumentException>(() =>
@@ -238,9 +236,9 @@ public void Dispose_CallsDown_WhenRun()
238236
var compose = new Mock<IDockerCompose>();
239237
compose.Setup(c => c.PauseMs).Returns(NumberOfMsInOneSec);
240238
compose.Setup(c => c.Up()).Returns(Task.Delay(ComposeUpRunDurationMs));
241-
compose.SetupSequence(c => c.Ps())
242-
.Returns(new[] { "--------" })
243-
.Returns(new[] { "--------", " Up ", " Up " });
239+
compose.SetupSequence(c => c.PsWithJsonFormat())
240+
.Returns(new[] { "non-json-output" })
241+
.Returns(new[] { "non-json-message", "{ \"Status\": \"Up 3 seconds\" }", "{ \"Status\": \"Up 15 seconds\" }" });
244242

245243
var fixture = new DockerFixture(null);
246244
fixture.Init(new[] { Path.GetTempFileName() }, "up", "down", 120, null, compose.Object);

DockerComposeFixture/Compose/DockerCompose.cs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ public void Down()
4545
var down = new ProcessStartInfo("docker", $"compose {this.dockerComposeArgs} down {this.dockerComposeDownArgs}");
4646
this.RunProcess(down);
4747
}
48-
48+
4949
public IEnumerable<string> Ps()
5050
{
5151
var ps = new ProcessStartInfo("docker", $"compose {this.dockerComposeArgs} ps");
@@ -60,6 +60,21 @@ public IEnumerable<string> Ps()
6060
runner.Execute();
6161
return observerToQueue.Queue.ToArray();
6262
}
63+
64+
public IEnumerable<string> PsWithJsonFormat()
65+
{
66+
var ps = new ProcessStartInfo("docker", $"compose {this.dockerComposeArgs} ps --format json");
67+
var runner = new ProcessRunner(ps);
68+
var observerToQueue = new ObserverToQueue<string>();
69+
70+
foreach (var logger in this.Logger)
71+
{
72+
runner.Subscribe(logger);
73+
}
74+
runner.Subscribe(observerToQueue);
75+
runner.Execute();
76+
return observerToQueue.Queue.ToArray();
77+
}
6378
}
6479
}
6580

DockerComposeFixture/Compose/IDockerCompose.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@ public interface IDockerCompose
99
void Init(string dockerComposeArgs, string dockerComposeUpArgs, string dockerComposeDownArgs);
1010
void Down();
1111
IEnumerable<string> Ps();
12+
IEnumerable<string> PsWithJsonFormat();
1213
Task Up();
1314
int PauseMs { get; }
1415
ILogger[] Logger { get; }
1516
}
16-
}
17+
}

DockerComposeFixture/DockerComposeFixture.csproj

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<PropertyGroup>
44
<TargetFramework>netstandard2.1</TargetFramework>
5-
<Version>1.2.0</Version>
5+
<Version>1.2.1</Version>
66
<IsTestProject>false</IsTestProject>
77
<Authors>Joe Shearn</Authors>
88
<Product>Docker Compose Fixture</Product>
@@ -13,9 +13,8 @@
1313
<PackageLicenseUrl>https://github.com/devjoes/DockerComposeFixture/blob/master/LICENSE</PackageLicenseUrl>
1414
<RepositoryUrl>https://github.com/devjoes/DockerComposeFixture</RepositoryUrl>
1515
<PackageTags>docker docker-compose xunit</PackageTags>
16-
<PackageReleaseNotes>Capture standard error as well as standard out
17-
Update to use 'docker compose' instead of 'docker-compose' command to run docker compose files</PackageReleaseNotes>
18-
<AssemblyVersion>1.2.0.0</AssemblyVersion>
16+
<PackageReleaseNotes>Fix issue whereby currently running docker compose was not detected</PackageReleaseNotes>
17+
<AssemblyVersion>1.2.1.0</AssemblyVersion>
1918
</PropertyGroup>
2019

2120
<ItemGroup>

DockerComposeFixture/DockerComposeFixture.nuspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<metadata minClientVersion="2.12">
44
<id>dockercomposefixture</id>
55
<title>docker-compose Fixture</title>
6-
<version>1.2.0</version>
6+
<version>1.2.1</version>
77
<authors>Joe Shearn</authors>
88
<owners>Joe Shearn</owners>
99
<requireLicenseAcceptance>false</requireLicenseAcceptance>

DockerComposeFixture/DockerFixture.cs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -235,17 +235,15 @@ private void Start()
235235
}
236236
throw new DockerComposeException(this.loggers.GetLoggedLines());
237237
}
238-
238+
239239
private (bool hasContainers, bool containersAreUp) CheckIfRunning()
240240
{
241-
var lines = this.dockerCompose.Ps().ToList()
242-
.Where(l => l != null)
243-
.SkipWhile(l => !l.Contains("--------"))
244-
.Skip(1)
241+
var lines = dockerCompose.PsWithJsonFormat()
242+
.Where(l => l != null && l.StartsWith("{"))
245243
.ToList();
246244
return (
247245
lines.Any(),
248-
lines.Count(l => Regex.IsMatch(l, @"\s+Up\s+")) == lines.Count());
246+
lines.Count(l => l.Contains("\"Status\": \"Up")) == lines.Count);
249247
}
250248

251249
private void Stop()

0 commit comments

Comments
 (0)