diff --git a/src/Testcontainers/Builders/ContainerBuilder`3.cs b/src/Testcontainers/Builders/ContainerBuilder`3.cs
index 9f3c6cf81..599274644 100644
--- a/src/Testcontainers/Builders/ContainerBuilder`3.cs
+++ b/src/Testcontainers/Builders/ContainerBuilder`3.cs
@@ -80,7 +80,7 @@ public TBuilderEntity WithImage(IImage image)
return Clone(new ContainerConfiguration(image: image));
}
- return Clone(new ContainerConfiguration(image: new DockerImage(image.Repository, image.Name, image.Tag, TestcontainersSettings.HubImageNamePrefix)));
+ return Clone(new ContainerConfiguration(image: new DockerImage(image.Registry, image.Repository, image.Tag, TestcontainersSettings.HubImageNamePrefix)));
}
///
diff --git a/src/Testcontainers/Builders/ImageFromDockerfileBuilder.cs b/src/Testcontainers/Builders/ImageFromDockerfileBuilder.cs
index c48a0f4f3..0221e2312 100644
--- a/src/Testcontainers/Builders/ImageFromDockerfileBuilder.cs
+++ b/src/Testcontainers/Builders/ImageFromDockerfileBuilder.cs
@@ -109,7 +109,7 @@ public override IFutureDockerImage Build()
///
protected sealed override ImageFromDockerfileBuilder Init()
{
- return base.Init().WithImageBuildPolicy(PullPolicy.Always).WithDockerfile("Dockerfile").WithDockerfileDirectory(Directory.GetCurrentDirectory()).WithName(new DockerImage("localhost/testcontainers", Guid.NewGuid().ToString("D"), string.Empty));
+ return base.Init().WithImageBuildPolicy(PullPolicy.Always).WithDockerfile("Dockerfile").WithDockerfileDirectory(Directory.GetCurrentDirectory()).WithName(new DockerImage("localhost", $"testcontainers/{Guid.NewGuid():D}", string.Empty));
}
///
diff --git a/src/Testcontainers/Images/DockerImage.cs b/src/Testcontainers/Images/DockerImage.cs
index 3ce296fdf..6d3493917 100644
--- a/src/Testcontainers/Images/DockerImage.cs
+++ b/src/Testcontainers/Images/DockerImage.cs
@@ -17,7 +17,7 @@ public sealed class DockerImage : IImage
///
/// The image.
public DockerImage(IImage image)
- : this(image.Repository, image.Name, image.Tag)
+ : this(image.Registry, image.Repository, image.Tag)
{
}
@@ -35,39 +35,39 @@ public DockerImage(string image)
///
/// Initializes a new instance of the class.
///
+ /// The registry.
/// The repository.
- /// The name.
/// The tag.
/// The Docker Hub image name prefix.
/// Thrown when any argument is null.
- /// "fedora/httpd:version1.0" where "fedora" is the repository, "httpd" the name and "version1.0" the tag.
+ /// "docker.io/fedora/httpd:version1.0" where "docker.io" is the registry, "fedora/httpd" is the repository and "version1.0" the tag.
public DockerImage(
+ string registry,
string repository,
- string name,
string tag,
string hubImageNamePrefix = null)
{
- _ = Guard.Argument(repository, nameof(repository))
+ _ = Guard.Argument(registry, nameof(registry))
.NotNull()
.NotUppercase();
- _ = Guard.Argument(name, nameof(name))
+ _ = Guard.Argument(repository, nameof(repository))
.NotNull()
.NotEmpty()
.NotUppercase();
_hubImageNamePrefix = hubImageNamePrefix;
+ Registry = registry;
Repository = repository;
- Name = name;
Tag = string.IsNullOrEmpty(tag) ? "latest" : tag;
}
///
- public string Repository { get; }
+ public string Registry { get; }
///
- public string Name { get; }
+ public string Repository { get; }
///
public string Tag { get; }
@@ -77,7 +77,7 @@ public string FullName
{
get
{
- var imageComponents = new[] { _hubImageNamePrefix, Repository, Name }
+ var imageComponents = new[] { _hubImageNamePrefix, Registry, Repository }
.Where(imageComponent => !string.IsNullOrEmpty(imageComponent))
.Select(imageComponent => imageComponent.Trim('/', ':'))
.Where(imageComponent => !string.IsNullOrEmpty(imageComponent));
@@ -88,8 +88,8 @@ public string FullName
///
public string GetHostname()
{
- var firstSegmentOfRepository = (string.IsNullOrEmpty(_hubImageNamePrefix) ? Repository : _hubImageNamePrefix).Split('/')[0];
- return firstSegmentOfRepository.IndexOfAny(new[] { '.', ':' }) >= 0 ? firstSegmentOfRepository : null;
+ var firstSegmentOfRegistry = (string.IsNullOrEmpty(_hubImageNamePrefix) ? Registry : _hubImageNamePrefix).Split('/')[0];
+ return firstSegmentOfRegistry.IndexOfAny(new[] { '.', ':' }) >= 0 ? firstSegmentOfRegistry : null;
}
}
}
diff --git a/src/Testcontainers/Images/FutureDockerImage.cs b/src/Testcontainers/Images/FutureDockerImage.cs
index 4352f6f15..703f032d0 100644
--- a/src/Testcontainers/Images/FutureDockerImage.cs
+++ b/src/Testcontainers/Images/FutureDockerImage.cs
@@ -30,22 +30,22 @@ public FutureDockerImage(IImageFromDockerfileConfiguration configuration, ILogge
}
///
- public string Repository
+ public string Registry
{
get
{
ThrowIfResourceNotFound();
- return _configuration.Image.Repository;
+ return _configuration.Image.Registry;
}
}
///
- public string Name
+ public string Repository
{
get
{
ThrowIfResourceNotFound();
- return _configuration.Image.Name;
+ return _configuration.Image.Repository;
}
}
diff --git a/src/Testcontainers/Images/IImage.cs b/src/Testcontainers/Images/IImage.cs
index b9badc5d3..c1b5d17a3 100644
--- a/src/Testcontainers/Images/IImage.cs
+++ b/src/Testcontainers/Images/IImage.cs
@@ -9,16 +9,16 @@ namespace DotNet.Testcontainers.Images
public interface IImage
{
///
- /// Gets the repository.
+ /// Gets the registry.
///
[NotNull]
- string Repository { get; }
+ string Registry { get; }
///
- /// Gets the name.
+ /// Gets the repository.
///
[NotNull]
- string Name { get; }
+ string Repository { get; }
///
/// Gets the tag.
diff --git a/src/Testcontainers/Images/MatchImage.cs b/src/Testcontainers/Images/MatchImage.cs
index 8819cdcc7..507780c31 100644
--- a/src/Testcontainers/Images/MatchImage.cs
+++ b/src/Testcontainers/Images/MatchImage.cs
@@ -1,36 +1,24 @@
namespace DotNet.Testcontainers.Images
{
- using System;
- using System.Linq;
+ using System.Text.RegularExpressions;
internal static class MatchImage
{
+ private static readonly Regex _imagePattern = new Regex(@"^((?[^\.\/\:]+(\.[^\.\/\:]*)+(\:[^\/]+)?|[^\:\/]+(\:[^\/]+)|localhost)\/)?(?[^\:\n]*)(\:(?.+)?)?$", RegexOptions.Compiled | RegexOptions.ExplicitCapture);
+
public static IImage Match(string image)
{
_ = Guard.Argument(image, nameof(image))
.NotNull()
.NotEmpty();
- var imageComponents = image
- .Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
-
- var repository = string.Join("/", imageComponents
- .Take(imageComponents.Length - 1));
-
- var name = imageComponents
- .Last()
- .Split(':')
- .DefaultIfEmpty(string.Empty)
- .First();
+ var match = _imagePattern.Match(image);
- var tag = imageComponents
- .Last()
- .Split(':')
- .Skip(1)
- .DefaultIfEmpty(string.Empty)
- .First();
+ var registry = match.Groups[1].Value;
+ var repository = match.Groups[2].Value;
+ var tag = match.Groups[3].Value;
- return new DockerImage(repository, name, tag);
+ return new DockerImage(registry, repository, tag);
}
}
}
diff --git a/tests/Testcontainers.Tests/Fixtures/Images/DockerImageFixture.cs b/tests/Testcontainers.Tests/Fixtures/Images/DockerImageFixture.cs
index 1b8404ad9..36c77f381 100644
--- a/tests/Testcontainers.Tests/Fixtures/Images/DockerImageFixture.cs
+++ b/tests/Testcontainers.Tests/Fixtures/Images/DockerImageFixture.cs
@@ -7,20 +7,22 @@ public sealed class DockerImageFixture : TheoryData("Repository");
- var name = info.GetValue("Name");
- var tag = info.GetValue("Tag");
- Image = new DockerImage(repository, name, tag);
+ var registry = info.GetValue(nameof(IImage.Registry));
+ var repository = info.GetValue(nameof(IImage.Repository));
+ var tag = info.GetValue(nameof(IImage.Tag));
+ Image = new DockerImage(registry, repository, tag);
}
public void Serialize(IXunitSerializationInfo info)
{
- info.AddValue("Repository", Image.Repository);
- info.AddValue("Name", Image.Name);
- info.AddValue("Tag", Image.Tag);
+ info.AddValue(nameof(IImage.Registry), Image.Registry);
+ info.AddValue(nameof(IImage.Repository), Image.Repository);
+ info.AddValue(nameof(IImage.Tag), Image.Tag);
}
}
}
diff --git a/tests/Testcontainers.Tests/Fixtures/Images/HealthCheckFixture.cs b/tests/Testcontainers.Tests/Fixtures/Images/HealthCheckFixture.cs
index db4034d3e..2685d0f86 100644
--- a/tests/Testcontainers.Tests/Fixtures/Images/HealthCheckFixture.cs
+++ b/tests/Testcontainers.Tests/Fixtures/Images/HealthCheckFixture.cs
@@ -14,9 +14,9 @@ public sealed class HealthCheckFixture : IImage, IAsyncLifetime
.WithDockerfileDirectory(Path.Combine(Directory.GetCurrentDirectory(), "Assets", "healthWaitStrategy"))
.Build();
- public string Repository => _image.Repository;
+ public string Registry => _image.Registry;
- public string Name => _image.Name;
+ public string Repository => _image.Repository;
public string Tag => _image.Tag;
diff --git a/tests/Testcontainers.Tests/Unit/Configurations/DockerRegistryAuthenticationProviderTest.cs b/tests/Testcontainers.Tests/Unit/Configurations/DockerRegistryAuthenticationProviderTest.cs
index 11a080559..977946a58 100644
--- a/tests/Testcontainers.Tests/Unit/Configurations/DockerRegistryAuthenticationProviderTest.cs
+++ b/tests/Testcontainers.Tests/Unit/Configurations/DockerRegistryAuthenticationProviderTest.cs
@@ -44,12 +44,12 @@ public void GetHostnameFromDockerImage(string dockerImageName, string hostname)
[Theory]
[InlineData("", "docker", "stable")]
- [InlineData("fedora", "httpd", "1.0")]
- [InlineData("foo/bar", "baz", "1.0.0")]
- public void GetHostnameFromHubImageNamePrefix(string repository, string name, string tag)
+ [InlineData("", "fedora/httpd", "1.0")]
+ [InlineData("", "foo/bar/baz", "1.0.0")]
+ public void GetHostnameFromHubImageNamePrefix(string registry, string repository, string tag)
{
const string hubImageNamePrefix = "myregistry.azurecr.io";
- IImage image = new DockerImage(repository, name, tag, hubImageNamePrefix);
+ IImage image = new DockerImage(registry, repository, tag, hubImageNamePrefix);
Assert.Equal(hubImageNamePrefix, image.GetHostname());
}
diff --git a/tests/Testcontainers.Tests/Unit/Configurations/ResourcePropertiesTest.cs b/tests/Testcontainers.Tests/Unit/Configurations/ResourcePropertiesTest.cs
index 2e39f06ef..06b62f26d 100644
--- a/tests/Testcontainers.Tests/Unit/Configurations/ResourcePropertiesTest.cs
+++ b/tests/Testcontainers.Tests/Unit/Configurations/ResourcePropertiesTest.cs
@@ -126,8 +126,8 @@ await Task.CompletedTask
.ConfigureAwait(false);
// Then
+ Assert.Throws(() => image.Registry);
Assert.Throws(() => image.Repository);
- Assert.Throws(() => image.Name);
Assert.Throws(() => image.Tag);
Assert.Throws(() => image.FullName);
Assert.Throws(() => image.GetHostname());
diff --git a/tests/Testcontainers.Tests/Unit/Images/ImageFromDockerfileTest.cs b/tests/Testcontainers.Tests/Unit/Images/ImageFromDockerfileTest.cs
index eba21b75e..c036d51d6 100644
--- a/tests/Testcontainers.Tests/Unit/Images/ImageFromDockerfileTest.cs
+++ b/tests/Testcontainers.Tests/Unit/Images/ImageFromDockerfileTest.cs
@@ -18,7 +18,7 @@ public sealed class ImageFromDockerfileTest
public async Task DockerfileArchiveTar()
{
// Given
- var image = new DockerImage("testcontainers", "test", "0.1.0");
+ var image = new DockerImage(string.Empty, "testcontainers/test", "0.1.0");
var expected = new SortedSet { ".dockerignore", "Dockerfile", "setup/setup.sh" };
@@ -84,9 +84,9 @@ public async Task ThrowsDockerfileDirectoryDoesNotExist()
public async Task BuildsDockerImage()
{
// Given
- IImage tag1 = new DockerImage("localhost/testcontainers", Guid.NewGuid().ToString("D"), string.Empty);
+ IImage tag1 = new DockerImage("localhost", $"testcontainers/{Guid.NewGuid():D}", string.Empty);
- IImage tag2 = new DockerImage("localhost/testcontainers", Guid.NewGuid().ToString("D"), string.Empty);
+ IImage tag2 = new DockerImage("localhost", $"testcontainers/{Guid.NewGuid():D}", string.Empty);
var imageFromDockerfileBuilder = new ImageFromDockerfileBuilder()
.WithName(tag1)
@@ -106,8 +106,8 @@ await imageFromDockerfileBuilder.CreateAsync()
// Then
Assert.True(DockerCli.ResourceExists(DockerCli.DockerResource.Image, tag1.FullName));
Assert.True(DockerCli.ResourceExists(DockerCli.DockerResource.Image, tag2.FullName));
+ Assert.NotNull(imageFromDockerfileBuilder.Registry);
Assert.NotNull(imageFromDockerfileBuilder.Repository);
- Assert.NotNull(imageFromDockerfileBuilder.Name);
Assert.NotNull(imageFromDockerfileBuilder.Tag);
Assert.NotNull(imageFromDockerfileBuilder.FullName);
Assert.Null(imageFromDockerfileBuilder.GetHostname());
diff --git a/tests/Testcontainers.Tests/Unit/Images/TestcontainersImageTest.cs b/tests/Testcontainers.Tests/Unit/Images/TestcontainersImageTest.cs
index 40a47743e..d8b81c914 100644
--- a/tests/Testcontainers.Tests/Unit/Images/TestcontainersImageTest.cs
+++ b/tests/Testcontainers.Tests/Unit/Images/TestcontainersImageTest.cs
@@ -12,7 +12,7 @@ public void ShouldThrowArgumentNullExceptionWhenInstantiateDockerImage()
{
Assert.Throws(() => new DockerImage((string)null));
Assert.Throws(() => new DockerImage(null, null, null));
- Assert.Throws(() => new DockerImage("fedora", null, null));
+ Assert.Throws(() => new DockerImage(null, "fedora", null));
}
[Fact]
@@ -54,8 +54,8 @@ public void WhenImageNameGetsAssigned(DockerImageFixtureSerializable serializabl
IImage dockerImage = new DockerImage(fullName);
// Then
+ Assert.Equal(expected.Registry, dockerImage.Registry);
Assert.Equal(expected.Repository, dockerImage.Repository);
- Assert.Equal(expected.Name, dockerImage.Name);
Assert.Equal(expected.Tag, dockerImage.Tag);
Assert.Equal(expected.FullName, dockerImage.FullName);
}