Skip to content

Commit

Permalink
Merge pull request #22 from ktmitton/containerLabels
Browse files Browse the repository at this point in the history
Container labels
  • Loading branch information
ktmitton authored Apr 6, 2022
2 parents 64fd0a1 + b06f956 commit d87f365
Show file tree
Hide file tree
Showing 9 changed files with 192 additions and 55 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text.Json;
Expand Down Expand Up @@ -124,6 +123,31 @@ public void ExpectAlpineContainerToBeConnectedToNetwork1()
}
}

[Fact]
public void ExpectAlpineContainerToHaveRunLabel()
{
Assert.NotNull(_dockerEnvironmentFixture.AlpineContainer);

if (_dockerEnvironmentFixture.AlpineContainer is not null)
{
using var proc = new Process();
proc.StartInfo.FileName = "docker";
proc.StartInfo.Arguments = $"inspect {_dockerEnvironmentFixture.AlpineContainer.Id} --format \"{{{{json .Config.Labels}}}}\"";
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardOutput = true;

proc.Start();
proc.WaitForExit();

var output = proc.StandardOutput.ReadToEnd();

var labels = JsonSerializer.Deserialize<Dictionary<string, string>>(output) ?? new Dictionary<string, string>();

Assert.True(labels.ContainsKey("mittons.fixtures.run.id"));
Assert.Equal(Run.DefaultId, labels["mittons.fixtures.run.id"]);
}
}

[Fact]
public void ExpectSftpContainerToBeCreated()
{
Expand Down Expand Up @@ -207,5 +231,30 @@ public void ExpectSftpContainerToBeConnectedToNetwork2()
Assert.Contains(connectedNetworks, x => x.StartsWith($"network2-"));
}
}

[Fact]
public void ExpectSftpContainerToHaveRunLabel()
{
Assert.NotNull(_dockerEnvironmentFixture.SftpContainer);

if (_dockerEnvironmentFixture.SftpContainer is not null)
{
using var proc = new Process();
proc.StartInfo.FileName = "docker";
proc.StartInfo.Arguments = $"inspect {_dockerEnvironmentFixture.SftpContainer.Id} --format \"{{{{json .Config.Labels}}}}\"";
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardOutput = true;

proc.Start();
proc.WaitForExit();

var output = proc.StandardOutput.ReadToEnd();

var labels = JsonSerializer.Deserialize<Dictionary<string, string>>(output) ?? new Dictionary<string, string>();

Assert.True(labels.ContainsKey("mittons.fixtures.run.id"));
Assert.Equal(Run.DefaultId, labels["mittons.fixtures.run.id"]);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,46 @@ public void Dispose()
}
}

[Fact]
public void ContainerRun_WhenCalledWithLabels_ExpectContainerToHaveTheLabelsApplied()
{
// Arrange
var imageName = "alpine:3.15";
var gateway = new DefaultDockerGateway();

// Act
var containerId = gateway.ContainerRun(
imageName,
string.Empty,
new Dictionary<string, string>
{
{ "first", "second" },
{ "third", "fourth" }
}
);

_containerIds.Add(containerId);

// Assert
using var proc = new Process();
proc.StartInfo.FileName = "docker";
proc.StartInfo.Arguments = $"inspect {containerId} --format \"{{{{json .Config.Labels}}}}\"";
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardOutput = true;

proc.Start();
proc.WaitForExit();

var output = proc.StandardOutput.ReadToEnd();

var actualLabels = JsonSerializer.Deserialize<Dictionary<string, string>>(output) ?? new Dictionary<string, string>();

Assert.True(actualLabels.ContainsKey("first"));
Assert.True(actualLabels.ContainsKey("third"));
Assert.Equal("second", actualLabels["first"]);
Assert.Equal("fourth", actualLabels["third"]);
}

[Theory]
[InlineData("alpine:3.15")]
[InlineData("alpine:3.14")]
Expand All @@ -47,7 +87,7 @@ public void ContainerRun_WhenCalledWithAnImage_ExpectContainerToBeForTheRequeste
var gateway = new DefaultDockerGateway();

// Act
var containerId = gateway.ContainerRun(imageName, string.Empty);
var containerId = gateway.ContainerRun(imageName, string.Empty, new Dictionary<string, string>());
_containerIds.Add(containerId);

// Assert
Expand Down Expand Up @@ -78,7 +118,7 @@ public void ContainerRun_WhenCalledForAlpineWithNoCommand_ExpectContainerToHaveS
var gateway = new DefaultDockerGateway();

// Act
var containerId = gateway.ContainerRun("alpine:3.15", string.Empty);
var containerId = gateway.ContainerRun("alpine:3.15", string.Empty, new Dictionary<string, string>());
_containerIds.Add(containerId);

// Assert
Expand Down Expand Up @@ -109,7 +149,7 @@ public void ContainerRun_WhenCalledForAlpineWithACommand_ExpectContainerToHaveSt
var gateway = new DefaultDockerGateway();

// Act
var containerId = gateway.ContainerRun("alpine:3.15", "/bin/bash");
var containerId = gateway.ContainerRun("alpine:3.15", "/bin/bash", new Dictionary<string, string>());
_containerIds.Add(containerId);

// Assert
Expand Down Expand Up @@ -150,7 +190,7 @@ public void ContainerRemove_WhenTheContainerExists_ExpectTheContainerToBeRemoved
// Arrange
var gateway = new DefaultDockerGateway();

var containerId = gateway.ContainerRun("alpine:3.15", string.Empty);
var containerId = gateway.ContainerRun("alpine:3.15", string.Empty, new Dictionary<string, string>());
_containerIds.Add(containerId);

// Act
Expand All @@ -177,7 +217,7 @@ public void ContainerGetDefaultNetworkIpAddress_WhenTheContainerIsOnOneNetwork_R
// Arrange
var gateway = new DefaultDockerGateway();

var containerId = gateway.ContainerRun("atmoz/sftp:alpine", "guest:guest");
var containerId = gateway.ContainerRun("atmoz/sftp:alpine", "guest:guest", new Dictionary<string, string>());
_containerIds.Add(containerId);

// Act
Expand Down Expand Up @@ -213,7 +253,7 @@ public void ContainerAddFile_WhenCalled_ExpectFileToBeCopiedToTheContainer(strin

var gateway = new DefaultDockerGateway();

var containerId = gateway.ContainerRun("atmoz/sftp:alpine", "guest:guest");
var containerId = gateway.ContainerRun("atmoz/sftp:alpine", "guest:guest", new Dictionary<string, string>());
_containerIds.Add(containerId);

// Act
Expand Down Expand Up @@ -249,7 +289,7 @@ public void ContainerAddFile_WhenCalledWithPermissions_ExpectThePermissionsToBeS

var gateway = new DefaultDockerGateway();

var containerId = gateway.ContainerRun("atmoz/sftp:alpine", "guest:guest");
var containerId = gateway.ContainerRun("atmoz/sftp:alpine", "guest:guest", new Dictionary<string, string>());
_containerIds.Add(containerId);

// Act
Expand Down Expand Up @@ -285,7 +325,7 @@ public void ContainerAddFile_WhenCalledWithAnOwner_ExpectThePermissionsToBeSet(s

var gateway = new DefaultDockerGateway();

var containerId = gateway.ContainerRun("atmoz/sftp:alpine", "guest:guest tester:tester");
var containerId = gateway.ContainerRun("atmoz/sftp:alpine", "guest:guest tester:tester", new Dictionary<string, string>());
_containerIds.Add(containerId);

// Act
Expand Down Expand Up @@ -321,7 +361,7 @@ public void ContainerRemoveFile_WhenCalled_ExpectFileToBeRemoved(string containe

var gateway = new DefaultDockerGateway();

var containerId = gateway.ContainerRun("atmoz/sftp:alpine", "guest:guest tester:tester");
var containerId = gateway.ContainerRun("atmoz/sftp:alpine", "guest:guest tester:tester", new Dictionary<string, string>());
_containerIds.Add(containerId);

gateway.ContainerAddFile(containerId, temporaryFilename, containerFilename, default(string), default(string));
Expand Down Expand Up @@ -487,7 +527,7 @@ public void NetworkConnect_WhenCalled_ExpectContainerToBeConnectedToNetwork()

var gateway = new DefaultDockerGateway();

var containerId = gateway.ContainerRun("atmoz/sftp:alpine", "guest:guest");
var containerId = gateway.ContainerRun("atmoz/sftp:alpine", "guest:guest", new Dictionary<string, string>());
_containerIds.Add(containerId);

_networkNames.Add(uniqueName);
Expand Down
63 changes: 40 additions & 23 deletions Mittons.Fixtures.Tests.Unit/Docker/Containers/ContainerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System.Net;
using System.IO;
using System.Text;
using System.Collections.Generic;

namespace Mittons.Fixtures.Tests.Unit.Docker.Containers
{
Expand All @@ -24,7 +25,7 @@ public void Ctor_WhenInitializedWithAnImageName_ExpectTheImageNameToBePassedToTh
using var container = new Container(gatewayMock.Object, new Attribute[] { new Image(imageName), new Command(string.Empty) });

// Assert
gatewayMock.Verify(x => x.ContainerRun(imageName, string.Empty), Times.Once);
gatewayMock.Verify(x => x.ContainerRun(imageName, string.Empty, It.Is<Dictionary<string, string>>(x => x.Count == 1 && x.ContainsKey("mittons.fixtures.run.id"))), Times.Once);
}

[Theory]
Expand All @@ -39,7 +40,40 @@ public void Ctor_WhenInitializedWithACommand_ExpectTheCommandToBePassedToTheDock
using var container = new Container(gatewayMock.Object, new Attribute[] { new Image(string.Empty), new Command(command) });

// Assert
gatewayMock.Verify(x => x.ContainerRun(string.Empty, command), Times.Once);
gatewayMock.Verify(x => x.ContainerRun(string.Empty, command, It.Is<Dictionary<string, string>>(x => x.Count == 1 && x.ContainsKey("mittons.fixtures.run.id"))), Times.Once);
}

[Theory]
[InlineData("192.168.0.0")]
[InlineData("192.168.0.1")]
[InlineData("127.0.0.1")]
public void Ctor_WhenCreated_ExpectTheDefaultIpAddressToBeSet(string ipAddress)
{
// Arrange
var parsed = IPAddress.Parse(ipAddress);

var gatewayMock = new Mock<IDockerGateway>();
gatewayMock.Setup(x => x.ContainerGetDefaultNetworkIpAddress(It.IsAny<string>())).Returns(parsed);

// Act
using var container = new Container(gatewayMock.Object, new Attribute[] { new Image(string.Empty), new Command(string.Empty) });

// Assert
Assert.Equal(parsed, container.IpAddress);
}

[Fact]
public void Ctor_WhenCreatedWithARun_ExpectLabelsToBePassedToTheGateway()
{
// Arrange
var gatewayMock = new Mock<IDockerGateway>();
var run = new Run();

// Act
using var container = new Container(gatewayMock.Object, new Attribute[] { new Image(string.Empty), new Command(string.Empty), run });

// Assert
gatewayMock.Verify(x => x.ContainerRun(string.Empty, string.Empty, It.Is<Dictionary<string, string>>(x => x.ContainsKey("mittons.fixtures.run.id") && x["mittons.fixtures.run.id"] == run.Id)));
}

[Fact]
Expand All @@ -62,8 +96,10 @@ public void Dispose_WhenCalledWhileAnotherContainerIsRunning_ExpectOnlyTheCalled
{
// Arrange
var gatewayMock = new Mock<IDockerGateway>();
gatewayMock.Setup(x => x.ContainerRun("runningimage", string.Empty)).Returns("runningid");
gatewayMock.Setup(x => x.ContainerRun("disposingimage", string.Empty)).Returns("disposingid");
gatewayMock.Setup(x => x.ContainerRun("runningimage", string.Empty, It.Is<Dictionary<string, string>>(x => x.Count == 1 && x.ContainsKey("mittons.fixtures.run.id"))))
.Returns("runningid");
gatewayMock.Setup(x => x.ContainerRun("disposingimage", string.Empty, It.Is<Dictionary<string, string>>(x => x.Count == 1 && x.ContainsKey("mittons.fixtures.run.id"))))
.Returns("disposingid");

using var runningContainer = new Container(gatewayMock.Object, new Attribute[] { new Image("runningimage"), new Command(string.Empty) });
using var disposingContainer = new Container(gatewayMock.Object, new Attribute[] { new Image("disposingimage"), new Command(string.Empty) });
Expand All @@ -76,25 +112,6 @@ public void Dispose_WhenCalledWhileAnotherContainerIsRunning_ExpectOnlyTheCalled
gatewayMock.Verify(x => x.ContainerRemove(runningContainer.Id), Times.Never);
}

[Theory]
[InlineData("192.168.0.0")]
[InlineData("192.168.0.1")]
[InlineData("127.0.0.1")]
public void Ctor_WhenCreated_ExpectTheDefaultIpAddressToBeSet(string ipAddress)
{
// Arrange
var parsed = IPAddress.Parse(ipAddress);

var gatewayMock = new Mock<IDockerGateway>();
gatewayMock.Setup(x => x.ContainerGetDefaultNetworkIpAddress(It.IsAny<string>())).Returns(parsed);

// Act
using var container = new Container(gatewayMock.Object, new Attribute[] { new Image(string.Empty), new Command(string.Empty) });

// Assert
Assert.Equal(parsed, container.IpAddress);
}

[Theory]
[InlineData("file/one", "destination/one", "testowner", "testpermissions")]
[InlineData("two", "two", "owner", "permissions")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Linq;
using System;
using Mittons.Fixtures.Docker.Attributes;
using System.Collections.Generic;

namespace Mittons.Fixtures.Tests.Unit.Docker.Containers
{
Expand All @@ -22,7 +23,7 @@ public void Ctor_WhenCalled_ExpectTheContainerToUseTheAtmozImage()
using var container = new SftpContainer(gatewayMock.Object, Enumerable.Empty<Attribute>());

// Assert
gatewayMock.Verify(x => x.ContainerRun(sftpImageName, It.IsAny<string>()), Times.Once);
gatewayMock.Verify(x => x.ContainerRun(sftpImageName, It.IsAny<string>(), It.Is<Dictionary<string, string>>(x => x.Count == 1 && x.ContainsKey("mittons.fixtures.run.id"))), Times.Once);
}

[Fact]
Expand All @@ -35,7 +36,7 @@ public void Ctor_InitializedWithNoCredentials_ExpectTheCommandToSetupTheGuestAcc
using var container = new SftpContainer(gatewayMock.Object, Enumerable.Empty<Attribute>());

// Assert
gatewayMock.Verify(x => x.ContainerRun(sftpImageName, "guest:guest"), Times.Once);
gatewayMock.Verify(x => x.ContainerRun(sftpImageName, "guest:guest", It.Is<Dictionary<string, string>>(x => x.Count == 1 && x.ContainsKey("mittons.fixtures.run.id"))), Times.Once);
}

[Theory]
Expand All @@ -57,7 +58,7 @@ public void Ctor_InitializedWithOneSetOfCredentials_ExpectTheCommandToSetupTheCr
);

// Assert
gatewayMock.Verify(x => x.ContainerRun(sftpImageName, $"{username}:{password}"), Times.Once);
gatewayMock.Verify(x => x.ContainerRun(sftpImageName, $"{username}:{password}", It.Is<Dictionary<string, string>>(x => x.Count == 1 && x.ContainsKey("mittons.fixtures.run.id"))), Times.Once);
}

[Fact]
Expand All @@ -78,7 +79,7 @@ public void Ctor_InitializedWithMultipleSetOfCredentials_ExpectTheCommandToSetup
);

// Assert
gatewayMock.Verify(x => x.ContainerRun(sftpImageName, $"testuser1:testpassword1 testuser2:testpassword2 guest:guest"), Times.Once);
gatewayMock.Verify(x => x.ContainerRun(sftpImageName, $"testuser1:testpassword1 testuser2:testpassword2 guest:guest", It.Is<Dictionary<string, string>>(x => x.Count == 1 && x.ContainsKey("mittons.fixtures.run.id"))), Times.Once);
}
}
}
Loading

0 comments on commit d87f365

Please sign in to comment.