From f5ea4ffc2b15211d83d4773599fc862082ad7f10 Mon Sep 17 00:00:00 2001 From: Andre Hofmeister <9199345+HofmeisterAn@users.noreply.github.com> Date: Sun, 5 Nov 2023 15:39:42 +0100 Subject: [PATCH] refactor: Cache Docker image full and host name --- docs/modules/index.md | 5 +- src/Testcontainers/Images/DockerImage.cs | 64 +++++++++++++------ .../Unit/Images/TestcontainersImageTest.cs | 4 +- 3 files changed, 51 insertions(+), 22 deletions(-) diff --git a/docs/modules/index.md b/docs/modules/index.md index 33f861030..50c6b065a 100644 --- a/docs/modules/index.md +++ b/docs/modules/index.md @@ -25,11 +25,13 @@ await moduleNameContainer.StartAsync(); | Azure SQL Edge | `mcr.microsoft.com/azure-sql-edge:1.0.7` | [NuGet](https://www.nuget.org/packages/Testcontainers.SqlEdge) | [Source](https://github.com/testcontainers/testcontainers-dotnet/tree/develop/src/Testcontainers.SqlEdge) | | Azurite | `mcr.microsoft.com/azure-storage/azurite:3.24.0` | [NuGet](https://www.nuget.org/packages/Testcontainers.Azurite) | [Source](https://github.com/testcontainers/testcontainers-dotnet/tree/develop/src/Testcontainers.Azurite) | | ClickHouse | `clickhouse/clickhouse-server:23.6-alpine` | [NuGet](https://www.nuget.org/packages/Testcontainers.ClickHouse) | [Source](https://github.com/testcontainers/testcontainers-dotnet/tree/develop/src/Testcontainers.ClickHouse) | +| Consul | `consul:1.15` | [NuGet](https://www.nuget.org/packages/Testcontainers.Consul) | [Source](https://github.com/testcontainers/testcontainers-dotnet/tree/develop/src/Testcontainers.Consul) | | Couchbase | `couchbase:community-7.0.2` | [NuGet](https://www.nuget.org/packages/Testcontainers.Couchbase) | [Source](https://github.com/testcontainers/testcontainers-dotnet/tree/develop/src/Testcontainers.Couchbase) | | CouchDB | `couchdb:3.3` | [NuGet](https://www.nuget.org/packages/Testcontainers.CouchDb) | [Source](https://github.com/testcontainers/testcontainers-dotnet/tree/develop/src/Testcontainers.CouchDb) | | DynamoDB | `amazon/dynamodb-local:1.21.0` | [NuGet](https://www.nuget.org/packages/Testcontainers.DynamoDb) | [Source](https://github.com/testcontainers/testcontainers-dotnet/tree/develop/src/Testcontainers.DynamoDb) | | Elasticsearch | `elasticsearch:8.6.1` | [NuGet](https://www.nuget.org/packages/Testcontainers.Elasticsearch) | [Source](https://github.com/testcontainers/testcontainers-dotnet/tree/develop/src/Testcontainers.Elasticsearch) | | EventStoreDB | `eventstore/eventstore:22.10.1-buster-slim` | [NuGet](https://www.nuget.org/packages/Testcontainers.EventStoreDb) | [Source](https://github.com/testcontainers/testcontainers-dotnet/tree/develop/src/Testcontainers.EventStoreDb) | +| FakeGcsServer | `fsouza/fake-gcs-server:1.47` | [NuGet](https://www.nuget.org/packages/Testcontainers.FakeGcsServer) | [Source](https://github.com/testcontainers/testcontainers-dotnet/tree/develop/src/Testcontainers.FakeGcsServer) | | Firestore | `gcr.io/google.com/cloudsdktool/google-cloud-cli:446.0.1-emulators` | [NuGet](https://www.nuget.org/packages/Testcontainers.Firestore) | [Source](https://github.com/testcontainers/testcontainers-dotnet/tree/develop/src/Testcontainers.Firestore) | | InfluxDB | `influxdb:2.7` | [NuGet](https://www.nuget.org/packages/Testcontainers.InfluxDb) | [Source](https://github.com/testcontainers/testcontainers-dotnet/tree/develop/src/Testcontainers.InfluxDb) | | K3s | `rancher/k3s:v1.26.2-k3s1` | [NuGet](https://www.nuget.org/packages/Testcontainers.K3s) | [Source](https://github.com/testcontainers/testcontainers-dotnet/tree/develop/src/Testcontainers.K3s) | @@ -41,10 +43,11 @@ await moduleNameContainer.StartAsync(); | MinIO | `minio/minio:RELEASE.2023-01-31T02-24-19Z` | [NuGet](https://www.nuget.org/packages/Testcontainers.Minio) | [Source](https://github.com/testcontainers/testcontainers-dotnet/tree/develop/src/Testcontainers.Minio) | | MongoDB | `mongo:6.0` | [NuGet](https://www.nuget.org/packages/Testcontainers.MongoDb) | [Source](https://github.com/testcontainers/testcontainers-dotnet/tree/develop/src/Testcontainers.MongoDb) | | MySQL | `mysql:8.0` | [NuGet](https://www.nuget.org/packages/Testcontainers.MySql) | [Source](https://github.com/testcontainers/testcontainers-dotnet/tree/develop/src/Testcontainers.MySql) | -| NATS | `nats:2.9` | [NuGet](https://www.nuget.org/packages/Testcontainers.Nats) | [Source](https://github.com/testcontainers/testcontainers-dotnet/tree/develop/src/Testcontainers.Nats) | +| NATS | `nats:2.9` | [NuGet](https://www.nuget.org/packages/Testcontainers.Nats) | [Source](https://github.com/testcontainers/testcontainers-dotnet/tree/develop/src/Testcontainers.Nats) | | Neo4j | `neo4j:5.4` | [NuGet](https://www.nuget.org/packages/Testcontainers.Neo4j) | [Source](https://github.com/testcontainers/testcontainers-dotnet/tree/develop/src/Testcontainers.Neo4j) | | Oracle | `gvenzl/oracle-xe:21.3.0-slim-faststart` | [NuGet](https://www.nuget.org/packages/Testcontainers.Oracle) | [Source](https://github.com/testcontainers/testcontainers-dotnet/tree/develop/src/Testcontainers.Oracle) | | PostgreSQL | `postgres:15.1` | [NuGet](https://www.nuget.org/packages/Testcontainers.PostgreSql) | [Source](https://github.com/testcontainers/testcontainers-dotnet/tree/develop/src/Testcontainers.PostgreSql) | +| PubSub | `gcr.io/google.com/cloudsdktool/google-cloud-cli:446.0.1-emulators` | [NuGet](https://www.nuget.org/packages/Testcontainers.PubSub) | [Source](https://github.com/testcontainers/testcontainers-dotnet/tree/develop/src/Testcontainers.PubSub) | | RabbitMQ | `rabbitmq:3.11` | [NuGet](https://www.nuget.org/packages/Testcontainers.RabbitMq) | [Source](https://github.com/testcontainers/testcontainers-dotnet/tree/develop/src/Testcontainers.RabbitMq) | | RavenDB | `ravendb/ravendb:5.4-ubuntu-latest` | [NuGet](https://www.nuget.org/packages/Testcontainers.RavenDb) | [Source](https://github.com/testcontainers/testcontainers-dotnet/tree/develop/src/Testcontainers.RavenDb) | | Redis | `redis:7.0` | [NuGet](https://www.nuget.org/packages/Testcontainers.Redis) | [Source](https://github.com/testcontainers/testcontainers-dotnet/tree/develop/src/Testcontainers.Redis) | diff --git a/src/Testcontainers/Images/DockerImage.cs b/src/Testcontainers/Images/DockerImage.cs index 3ce296fdf..d6203ceeb 100644 --- a/src/Testcontainers/Images/DockerImage.cs +++ b/src/Testcontainers/Images/DockerImage.cs @@ -8,10 +8,18 @@ namespace DotNet.Testcontainers.Images [PublicAPI] public sealed class DockerImage : IImage { + private const string LatestTag = "latest"; + private static readonly Func GetDockerImage = MatchImage.Match; + private static readonly char[] TrimChars = { ' ', ':', '/' }; + private readonly string _hubImageNamePrefix; + private readonly Lazy _lazyFullName; + + private readonly Lazy _lazyHostname; + /// /// Initializes a new instance of the class. /// @@ -44,7 +52,7 @@ public DockerImage(string image) public DockerImage( string repository, string name, - string tag, + string tag = null, string hubImageNamePrefix = null) { _ = Guard.Argument(repository, nameof(repository)) @@ -56,11 +64,38 @@ public DockerImage( .NotEmpty() .NotUppercase(); - _hubImageNamePrefix = hubImageNamePrefix; + _hubImageNamePrefix = TrimOrDefault(hubImageNamePrefix); + + Repository = TrimOrDefault(repository, repository); + Name = TrimOrDefault(name, name); + Tag = TrimOrDefault(tag, LatestTag); + + _lazyFullName = new Lazy(() => + { + var imageComponents = new[] { _hubImageNamePrefix, Repository, Name } + .Where(imageComponent => !string.IsNullOrEmpty(imageComponent)); + + return string.Join("/", imageComponents) + ":" + Tag; + }); + + _lazyHostname = new Lazy(() => + { + var firstSegmentOfRepository = new[] { _hubImageNamePrefix, Repository } + .Where(imageComponent => !string.IsNullOrEmpty(imageComponent)) + .DefaultIfEmpty(string.Empty) + .First() + .Split('/') + .First(); - Repository = repository; - Name = name; - Tag = string.IsNullOrEmpty(tag) ? "latest" : tag; + if (firstSegmentOfRepository.IndexOfAny(new[] { '.', ':' }) >= 0) + { + return firstSegmentOfRepository; + } + else + { + return null; + } + }); } /// @@ -73,23 +108,14 @@ public DockerImage( public string Tag { get; } /// - public string FullName - { - get - { - var imageComponents = new[] { _hubImageNamePrefix, Repository, Name } - .Where(imageComponent => !string.IsNullOrEmpty(imageComponent)) - .Select(imageComponent => imageComponent.Trim('/', ':')) - .Where(imageComponent => !string.IsNullOrEmpty(imageComponent)); - return string.Join("/", imageComponents) + ":" + Tag; - } - } + public string FullName => _lazyFullName.Value; /// - public string GetHostname() + public string GetHostname() => _lazyHostname.Value; + + private static string TrimOrDefault(string value, string defaultValue = default) { - var firstSegmentOfRepository = (string.IsNullOrEmpty(_hubImageNamePrefix) ? Repository : _hubImageNamePrefix).Split('/')[0]; - return firstSegmentOfRepository.IndexOfAny(new[] { '.', ':' }) >= 0 ? firstSegmentOfRepository : null; + return string.IsNullOrEmpty(value) ? defaultValue : value.Trim(TrimChars); } } } diff --git a/tests/Testcontainers.Tests/Unit/Images/TestcontainersImageTest.cs b/tests/Testcontainers.Tests/Unit/Images/TestcontainersImageTest.cs index 40a47743e..4eacc1c80 100644 --- a/tests/Testcontainers.Tests/Unit/Images/TestcontainersImageTest.cs +++ b/tests/Testcontainers.Tests/Unit/Images/TestcontainersImageTest.cs @@ -11,8 +11,8 @@ public sealed class TestcontainersImageTest 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, null)); + Assert.Throws(() => new DockerImage("fedora", null)); } [Fact]