Skip to content

feat: Add Platform property to IImage interface#1610

Merged
HofmeisterAn merged 6 commits intodevelopfrom
feature/add-platform-support
Dec 28, 2025
Merged

feat: Add Platform property to IImage interface#1610
HofmeisterAn merged 6 commits intodevelopfrom
feature/add-platform-support

Conversation

@HofmeisterAn
Copy link
Collaborator

@HofmeisterAn HofmeisterAn commented Dec 22, 2025

What does this PR do?

This PR extends the IImage interface by adding the Platform property. The new property allows developers to specify which platform the container runtime should pull the image for. This is especially important on macOS (Apple Silicon), where some images are not natively available for the host architecture.

When using the Docker Engine API, the runtime does not automatically fall back, e.g. for linux/arm64 to linux/amd64. This is the client's responsibility.

The new property makes it possible to explicitly set the platform when creating a new IImage instance using the DockerImage implementation, for example:

_ = new DockerImage("postgres:15.1", "linux/amd64")

The platform flag is also evaluated when building an image. If the platform is specified in a Dockerfile, Testcontainers now respects it and pulls the correct image.

@0xced LMKWYT

Why is it important?

The PR allows pulling images that do not match the container runtime host architecture.

Related issues

Summary by CodeRabbit

  • New Features

    • Platform-aware image support added across the API, including a Platform type for explicit architecture targeting (e.g., linux/amd64, linux/arm64, linux/arm/v6, linux/arm/v7).
    • Dockerfile parsing now recognizes FROM-ARG/platform entries to derive image platforms.
  • Bug Fixes

    • Platform is propagated to image pull/create and container creation requests for correct platform selection.
  • Documentation

    • Guidance added for configuring container images with platform-aware options and spec format.
  • Tests

    • Updated and added tests for platform parsing, serialization, selection, and behavior.
  • Chores

    • Minor test cleanup (removed unused imports).

✏️ Tip: You can customize this high-level summary in your review settings.

@HofmeisterAn HofmeisterAn added the enhancement New feature or request label Dec 22, 2025
@netlify
Copy link

netlify bot commented Dec 22, 2025

Deploy Preview for testcontainers-dotnet ready!

Name Link
🔨 Latest commit 09ea9c1
🔍 Latest deploy log https://app.netlify.com/projects/testcontainers-dotnet/deploys/694ac0b55376a40008e70df5
😎 Deploy Preview https://deploy-preview-1610--testcontainers-dotnet.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai
Copy link

coderabbitai bot commented Dec 22, 2025

Walkthrough

Adds platform support: new Platform struct and IImage.Platform; makes DockerImage and FutureDockerImage platform-aware; parses FROM ARG/FROM platform tokens in Dockerfiles; and propagates platform into image-pull and container-create Docker API calls. Tests and docs updated.

Changes

Cohort / File(s) Summary
Core image types
src/Testcontainers/Images/IImage.cs, src/Testcontainers/Images/Platform.cs, src/Testcontainers/Images/DockerImage.cs, src/Testcontainers/Images/FutureDockerImage.cs
Add Platform readonly struct and nullable IImage.Platform; add _platform field, public Platform property and new/updated constructors on DockerImage; expose Platform on FutureDockerImage.
Docker operations
src/Testcontainers/Clients/DockerImageOperations.cs, src/Testcontainers/Clients/DockerContainerOperations.cs
Populate Docker API request objects' Platform from image/configuration when creating/pulling images and creating containers.
Dockerfile parsing
src/Testcontainers/Images/DockerfileArchive.cs
Parse ARG/FROM arguments (including platform tokens), substitute variables for ARG and FROM parts, and construct DockerImage(image, Platform) so base images carry platform metadata.
Extensions & utilities
src/Testcontainers/Images/IImageExtensions.cs
Pass platform through when creating DockerImage in ApplyHubImageNamePrefix.
Tests — fixtures & serialization
tests/.../Fixtures/Images/DockerImageFixture.cs, tests/.../Fixtures/Images/DockerImageFixtureSerializable.cs, tests/.../Fixtures/Images/HealthCheckFixture.cs
Update fixtures and (de)serialization to include Platform parameter; expose Platform on test fixture wrappers.
Tests — unit & assets
tests/.../Unit/Images/TestcontainersImageTest.cs, tests/.../Unit/Images/ImageFromDockerfileTest.cs, tests/.../Unit/Configurations/DockerRegistryAuthenticationProviderTest.cs, tests/Testcontainers.Tests/Assets/pullBaseImages/Dockerfile
Add tests for DockerImage.Platform; update Dockerfile test asset to include ARG PLATFORM and explicit platform FROM lines; adjust expectations to DockerImage objects with platforms.
Cleanup
tests/.../Fixtures/Containers/Unix/DockerMTls.cs, tests/.../Fixtures/Containers/Unix/DockerTlsFixture.cs
Remove unused using directives in test fixtures.

Sequence Diagram(s)

mermaid
sequenceDiagram
participant Test as Test Code / Caller
participant Parser as DockerfileArchive
participant Model as DockerImage / Platform
participant Client as DockerImageOperations / DockerContainerOperations
participant Docker as Docker daemon API
Note over Test,Parser: Resolve image specification (string, IImage, or Dockerfile)
Test->>Parser: Parse Dockerfile -> base images (ARG/FROM, platform)
Parser->>Model: Construct DockerImage(image, Platform)
Test->>Model: Build image/config (IImage.Platform)
Test->>Client: Request image pull/create (includes Platform)
Client->>Docker: Images.CreateImageAsync / Containers.CreateAsync (with Platform)
Docker-->>Client: Result
Client-->>Test: Image pulled / Container created

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

breaking change

Poem

🐰
I nibbled a FROM line, found a platform tucked tight,
From amd64 to arm, I hop through morning light.
I stitch it through constructors, whisper it to Docker's call —
Now images wear their platforms and happily stand tall. 🥕

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 44.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat: Add Platform property to IImage interface' clearly and concisely describes the primary change in the changeset.
Description check ✅ Passed The PR description comprehensively covers all required sections: what the change does, why it's important, and links the related issue (#1587).
Linked Issues check ✅ Passed The PR successfully implements all objectives from issue #1587: adds Platform property to IImage and DockerImage, enables platform-specific image pulling and building, and supports cross-architecture consistency.
Out of Scope Changes check ✅ Passed All changes are directly related to the linked issue #1587 and focus on implementing the Platform feature across the codebase without introducing unrelated modifications.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/add-platform-support

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/Testcontainers/Images/DockerfileArchive.cs (1)

418-432: Minor style suggestion: Remove redundant else after return.

The else block after the return statement on line 424 is unnecessary since the function already returns.

🔎 Suggested simplification
     private static (string Name, string Value) ParseFlag(string flag)
     {
       var trimmed = flag.TrimStart('-');
       var eqIndex = trimmed.IndexOf('=');
       if (eqIndex == -1)
       {
         return (trimmed, null);
       }
-      else
-      {
-        var name = trimmed.Substring(0, eqIndex);
-        var value = trimmed.Substring(eqIndex + 1).Trim(' ', '"', '\'');
-        return (name, value);
-      }
+
+      var name = trimmed.Substring(0, eqIndex);
+      var value = trimmed.Substring(eqIndex + 1).Trim(' ', '"', '\'');
+      return (name, value);
     }
📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cd2f52a and 4f4b6ad.

📒 Files selected for processing (15)
  • src/Testcontainers/Clients/DockerImageOperations.cs
  • src/Testcontainers/Images/DockerImage.cs
  • src/Testcontainers/Images/DockerfileArchive.cs
  • src/Testcontainers/Images/FutureDockerImage.cs
  • src/Testcontainers/Images/IImage.cs
  • src/Testcontainers/Images/IImageExtensions.cs
  • tests/Testcontainers.Tests/Assets/pullBaseImages/Dockerfile
  • tests/Testcontainers.Tests/Fixtures/Containers/Unix/DockerMTls.cs
  • tests/Testcontainers.Tests/Fixtures/Containers/Unix/DockerTlsFixture.cs
  • tests/Testcontainers.Tests/Fixtures/Images/DockerImageFixture.cs
  • tests/Testcontainers.Tests/Fixtures/Images/DockerImageFixtureSerializable.cs
  • tests/Testcontainers.Tests/Fixtures/Images/HealthCheckFixture.cs
  • tests/Testcontainers.Tests/Unit/Configurations/DockerRegistryAuthenticationProviderTest.cs
  • tests/Testcontainers.Tests/Unit/Images/ImageFromDockerfileTest.cs
  • tests/Testcontainers.Tests/Unit/Images/TestcontainersImageTest.cs
💤 Files with no reviewable changes (2)
  • tests/Testcontainers.Tests/Fixtures/Containers/Unix/DockerMTls.cs
  • tests/Testcontainers.Tests/Fixtures/Containers/Unix/DockerTlsFixture.cs
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-11-17T17:58:43.958Z
Learnt from: diegosasw
Repo: testcontainers/testcontainers-dotnet PR: 1583
File: src/Testcontainers.KurrentDb/Testcontainers.KurrentDb.csproj:7-7
Timestamp: 2025-11-17T17:58:43.958Z
Learning: In the testcontainers-dotnet repository, JetBrains.Annotations should use version 2023.3.0 to maintain consistency with the main Testcontainers csproj, rather than always using the latest available version.

Applied to files:

  • tests/Testcontainers.Tests/Unit/Images/ImageFromDockerfileTest.cs
  • src/Testcontainers/Images/IImageExtensions.cs
  • tests/Testcontainers.Tests/Unit/Configurations/DockerRegistryAuthenticationProviderTest.cs
🧬 Code graph analysis (9)
src/Testcontainers/Images/FutureDockerImage.cs (1)
src/Testcontainers/Resource.cs (1)
  • ThrowIfResourceNotFound (76-81)
tests/Testcontainers.Tests/Unit/Images/TestcontainersImageTest.cs (1)
src/Testcontainers/Images/DockerImage.cs (5)
  • DockerImage (41-44)
  • DockerImage (51-54)
  • DockerImage (67-73)
  • DockerImage (85-100)
  • DockerImage (102-139)
tests/Testcontainers.Tests/Unit/Images/ImageFromDockerfileTest.cs (1)
src/Testcontainers/Images/DockerImage.cs (5)
  • DockerImage (41-44)
  • DockerImage (51-54)
  • DockerImage (67-73)
  • DockerImage (85-100)
  • DockerImage (102-139)
src/Testcontainers/Images/DockerfileArchive.cs (1)
src/Testcontainers/Images/DockerImage.cs (5)
  • DockerImage (41-44)
  • DockerImage (51-54)
  • DockerImage (67-73)
  • DockerImage (85-100)
  • DockerImage (102-139)
src/Testcontainers/Images/DockerImage.cs (2)
src/Testcontainers/Images/IImageExtensions.cs (1)
  • IImage (18-31)
src/Testcontainers/Configurations/CustomConfiguration.cs (1)
  • IImage (92-109)
src/Testcontainers/Images/IImageExtensions.cs (1)
src/Testcontainers/Images/DockerImage.cs (5)
  • DockerImage (41-44)
  • DockerImage (51-54)
  • DockerImage (67-73)
  • DockerImage (85-100)
  • DockerImage (102-139)
tests/Testcontainers.Tests/Unit/Configurations/DockerRegistryAuthenticationProviderTest.cs (2)
src/Testcontainers/Images/IImageExtensions.cs (1)
  • IImage (18-31)
src/Testcontainers/Images/DockerImage.cs (5)
  • DockerImage (41-44)
  • DockerImage (51-54)
  • DockerImage (67-73)
  • DockerImage (85-100)
  • DockerImage (102-139)
tests/Testcontainers.Tests/Fixtures/Images/DockerImageFixtureSerializable.cs (1)
src/Testcontainers/Images/DockerImage.cs (5)
  • DockerImage (41-44)
  • DockerImage (51-54)
  • DockerImage (67-73)
  • DockerImage (85-100)
  • DockerImage (102-139)
tests/Testcontainers.Tests/Fixtures/Images/DockerImageFixture.cs (1)
src/Testcontainers/Images/DockerImage.cs (5)
  • DockerImage (41-44)
  • DockerImage (51-54)
  • DockerImage (67-73)
  • DockerImage (85-100)
  • DockerImage (102-139)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: analyze (csharp)
  • GitHub Check: ci (Testcontainers.Redis, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Platform.Windows, windows-2025)
🔇 Additional comments (20)
tests/Testcontainers.Tests/Unit/Images/TestcontainersImageTest.cs (1)

72-84: LGTM!

The test correctly validates that the Platform property returns the value passed to the constructor. The test follows the existing file conventions and adequately covers the new functionality.

src/Testcontainers/Images/FutureDockerImage.cs (1)

71-79: LGTM!

The Platform property follows the same pattern as the existing Repository, Registry, Tag, Digest, and FullName properties, correctly invoking ThrowIfResourceNotFound() before delegating to the underlying image configuration.

src/Testcontainers/Images/IImage.cs (1)

36-45: LGTM!

Well-documented interface addition. The [CanBeNull] annotation correctly indicates the optional nature of the platform specification, and the remarks provide clear guidance on the expected format with a reference to the containerd/platforms specification.

tests/Testcontainers.Tests/Fixtures/Images/HealthCheckFixture.cs (1)

26-27: LGTM!

The property correctly delegates to the underlying _image.Platform, consistent with the other delegating properties in this fixture.

tests/Testcontainers.Tests/Unit/Configurations/DockerRegistryAuthenticationProviderTest.cs (1)

51-51: LGTM!

The constructor call correctly adapts to the updated DockerImage signature by passing null for the new platform parameter (position 5), maintaining the existing test behavior.

src/Testcontainers/Clients/DockerImageOperations.cs (1)

58-64: LGTM!

This is the key integration point for the platform feature. The Platform property is correctly propagated to ImagesCreateParameters, enabling explicit platform selection during image pulls. When image.Platform is null, Docker defaults to the host platform, preserving backward compatibility.

tests/Testcontainers.Tests/Assets/pullBaseImages/Dockerfile (1)

2-3: LGTM!

This test asset provides comprehensive coverage for platform parsing, including hardcoded values, variable substitution, and both single/double-quoted formats. This effectively exercises the Dockerfile parsing logic for platform extraction.

Also applies to: 13-16

tests/Testcontainers.Tests/Fixtures/Images/DockerImageFixture.cs (1)

40-41: LGTM!

The fixture correctly adapts to the updated DockerImage constructor signature by inserting null for the platform parameter, allowing the hub image name prefix tests to continue functioning as expected.

tests/Testcontainers.Tests/Unit/Images/ImageFromDockerfileTest.cs (2)

23-35: LGTM! Test properly validates platform extraction from Dockerfile.

The test correctly constructs expected DockerImage objects with platform specifications for the azurelinux3.0 variants, matching the expected behavior of DockerfileArchive.GetBaseImages() which now parses --platform flags from FROM statements.


49-49: Appropriate use of Assert.Equivalent for structural comparison.

Using Assert.Equivalent allows comparing the DockerImage objects by their property values rather than reference equality, which is the correct approach here.

src/Testcontainers/Images/IImageExtensions.cs (1)

30-30: LGTM! Platform is correctly propagated when applying hub image name prefix.

The constructor call now includes image.Platform to ensure the platform specification is preserved when the hub image name prefix is applied.

tests/Testcontainers.Tests/Fixtures/Images/DockerImageFixtureSerializable.cs (2)

19-27: LGTM! Serialization correctly handles the new Platform property.

The deserialization reads the Platform value and passes it to the DockerImage constructor, maintaining symmetry with the serialization that writes the Platform property.


29-36: Serialization correctly includes Platform.

The Platform property is now persisted during serialization, ensuring round-trip compatibility for test fixtures.

src/Testcontainers/Images/DockerfileArchive.cs (2)

164-175: LGTM! Platform extraction logic is well-structured.

The implementation correctly:

  1. Extracts both the arg and image groups from FROM statements
  2. Applies variable substitution to both parts
  3. Parses FROM args to extract the platform flag
  4. Creates DockerImage instances with the extracted platform

314-331: LGTM! Parameter rename improves clarity.

Renaming the parameter from image to line better reflects that this method now processes both FROM args and image strings.

src/Testcontainers/Images/DockerImage.cs (5)

34-36: LGTM! Platform field follows existing field conventions.

The _platform field is properly annotated with [CanBeNull], consistent with other nullable fields in the class.


41-43: LGTM! IImage copy constructor now preserves Platform.

The constructor correctly propagates image.Platform to maintain platform information when creating a DockerImage from another IImage instance.


56-73: LGTM! New constructor enables platform specification with image string.

This constructor enables the primary use case from the PR objective: new DockerImage("postgres:15.1", "linux/amd64"). The documentation clearly explains the supported platform format with a link to containerd/platforms.


85-100: LGTM! Main constructor signature extended with platform parameter.

The platform parameter is correctly positioned before hubImageNamePrefix with a default value of null, maintaining backward compatibility.


153-155: LGTM! Platform property correctly exposes the backing field.

The property follows the same pattern as other properties in the class (Repository, Registry, Tag, Digest).

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (3)
docs/api/create_docker_container.md (1)

16-21: Consider adding optional context about default and common platform values.

The documentation effectively introduces the platform parameter, but readers might benefit from brief guidance on what happens when platform is not specified (falls back to Docker Engine default behavior) and examples of common platform values (linux/amd64, linux/arm64, etc.). This would help users understand when and why they need to explicitly set a platform.

src/Testcontainers/Images/DockerfileArchive.cs (2)

369-411: Quote parsing logic is sound; error message could be more helpful.

The quote-aware tokenization correctly handles both single and double quotes and properly splits on whitespace outside quoted sections.

Related to previous review: The error message on line 404 no longer includes the incorrect position (good!), but it also doesn't include any position information. For better developer experience when debugging malformed Dockerfiles, consider tracking where the unmatched quote opened:

Optional enhancement to track quote position
+    var quoteStart = -1;
+
     for (var i = 0; i < line.Length; i++)
     {
       var c = line[i];

       if ((c == '"' || c == '\'') && (quote == null || quote == c))
       {
-        quote = quote == null ? c : null;
+        if (quote == null)
+        {
+          quote = c;
+          quoteStart = i;
+        }
+        else
+        {
+          quote = null;
+        }
       }
       
       // ... rest of logic
     }

     if (quote != null)
     {
-      throw new FormatException($"Unmatched {quote} quote in line: '{line}'.");
+      throw new FormatException($"Unmatched {quote} quote starting at position {quoteStart} in line: '{line}'.");
     }

Note: This method's output feeds into the case-sensitivity concern flagged on line 172.


418-432: LGTM! Flag parsing handles common patterns correctly.

The method properly strips flag prefixes, splits on the equals sign, and removes surrounding quotes. The double-Trim pattern on line 429 correctly handles quoted values like --platform="linux/amd64".

Optional consideration: The Trim().Trim('"', '\'') pattern will also remove internal whitespace (e.g., " value ""value"value). This is likely acceptable for Docker flag values, but if preserving internal whitespace is important, consider trimming quotes before trimming whitespace:

var value = trimmed.Substring(eqIndex + 1).Trim('"', '\'').Trim();

However, the current approach is likely fine for typical Docker use cases.

📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4f4b6ad and c1b76c5.

📒 Files selected for processing (2)
  • docs/api/create_docker_container.md
  • src/Testcontainers/Images/DockerfileArchive.cs
🧰 Additional context used
🧬 Code graph analysis (1)
src/Testcontainers/Images/DockerfileArchive.cs (1)
src/Testcontainers/Images/DockerImage.cs (5)
  • DockerImage (41-44)
  • DockerImage (51-54)
  • DockerImage (67-73)
  • DockerImage (85-100)
  • DockerImage (102-139)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (83)
  • GitHub Check: Redirect rules - testcontainers-dotnet
  • GitHub Check: Header rules - testcontainers-dotnet
  • GitHub Check: Pages changed - testcontainers-dotnet
  • GitHub Check: ci (Testcontainers.ArangoDb, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Bigtable, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.BigQuery, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Azurite, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Cassandra, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ActiveMq, ubuntu-24.04)
  • GitHub Check: Redirect rules - testcontainers-dotnet
  • GitHub Check: Header rules - testcontainers-dotnet
  • GitHub Check: Pages changed - testcontainers-dotnet
  • GitHub Check: ci (Testcontainers.ArangoDb, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Bigtable, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.BigQuery, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Azurite, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Cassandra, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ActiveMq, ubuntu-24.04)
  • GitHub Check: Redirect rules - testcontainers-dotnet
  • GitHub Check: Header rules - testcontainers-dotnet
  • GitHub Check: Pages changed - testcontainers-dotnet
  • GitHub Check: ci (Testcontainers.ArangoDb, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Bigtable, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.BigQuery, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Azurite, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Cassandra, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ActiveMq, ubuntu-24.04)
  • GitHub Check: Redirect rules - testcontainers-dotnet
  • GitHub Check: Header rules - testcontainers-dotnet
  • GitHub Check: Pages changed - testcontainers-dotnet
  • GitHub Check: ci (Testcontainers.ArangoDb, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Bigtable, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.BigQuery, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Azurite, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Cassandra, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ActiveMq, ubuntu-24.04)
  • GitHub Check: Redirect rules - testcontainers-dotnet
  • GitHub Check: Header rules - testcontainers-dotnet
  • GitHub Check: Pages changed - testcontainers-dotnet
  • GitHub Check: ci (Testcontainers.ArangoDb, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Bigtable, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.BigQuery, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Azurite, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Cassandra, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ActiveMq, ubuntu-24.04)
  • GitHub Check: Redirect rules - testcontainers-dotnet
  • GitHub Check: Header rules - testcontainers-dotnet
  • GitHub Check: Pages changed - testcontainers-dotnet
  • GitHub Check: ci (Testcontainers.ArangoDb, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Bigtable, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.BigQuery, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Azurite, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Cassandra, ubuntu-24.04)
  • GitHub Check: Redirect rules - testcontainers-dotnet
  • GitHub Check: Header rules - testcontainers-dotnet
  • GitHub Check: Pages changed - testcontainers-dotnet
  • GitHub Check: ci (Testcontainers.ArangoDb, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Bigtable, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.BigQuery, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Cassandra, ubuntu-24.04)
  • GitHub Check: Redirect rules - testcontainers-dotnet
  • GitHub Check: Header rules - testcontainers-dotnet
  • GitHub Check: Pages changed - testcontainers-dotnet
  • GitHub Check: ci (Testcontainers.ArangoDb, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Bigtable, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.BigQuery, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Cassandra, ubuntu-24.04)
  • GitHub Check: Redirect rules - testcontainers-dotnet
  • GitHub Check: Header rules - testcontainers-dotnet
  • GitHub Check: Pages changed - testcontainers-dotnet
  • GitHub Check: ci (Testcontainers.CockroachDb, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ArangoDb, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Bigtable, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ClickHouse, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Cassandra, ubuntu-24.04)
  • GitHub Check: Redirect rules - testcontainers-dotnet
  • GitHub Check: Header rules - testcontainers-dotnet
  • GitHub Check: Pages changed - testcontainers-dotnet
  • GitHub Check: ci (Testcontainers.CockroachDb, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ArangoDb, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Bigtable, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ClickHouse, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Cassandra, ubuntu-24.04)
🔇 Additional comments (4)
docs/api/create_docker_container.md (1)

5-21: Well-structured documentation for platform support.

The new "Configure container image" section clearly explains how to specify container images with both simple string syntax and platform-explicit DockerImage instances. The examples are properly formatted and demonstrate practical usage patterns.

src/Testcontainers/Images/DockerfileArchive.cs (3)

130-132: LGTM! Clean constant additions.

The new group name constants follow the existing pattern and clearly support the enhanced FROM statement parsing.


314-331: LGTM! Signature change aligns with new usage.

Renaming the parameter from image to line accurately reflects that this method now handles variable substitution for both FROM arguments and image references. The logic remains sound.


164-175: Platform extraction logic is correct; no changes needed.

The code properly extracts and passes the platform flag. While ParseFlag preserves casing and TryGetValue uses exact lowercase matching, this is appropriate because Docker's --platform flag is always lowercase per specification. Dockerfiles with alternate casings would fail Docker's own parsing before reaching this code, making case-insensitive lookup unnecessary and potentially counterproductive.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/Testcontainers/Images/DockerfileArchive.cs (1)

366-408: Consider adding position information to the error message.

The ParseFromArgs implementation correctly handles quoted strings and whitespace parsing. However, the error message for unmatched quotes (line 401) no longer includes position information, which could make debugging Dockerfile syntax errors more difficult.

🔎 Optional enhancement to track quote position
+    var quoteStart = -1;
+
     for (var i = 0; i < line.Length; i++)
     {
       var c = line[i];

       if ((c == '"' || c == '\'') && (quote == null || quote == c))
       {
-        quote = quote == null ? c : null;
+        if (quote == null)
+        {
+          quote = c;
+          quoteStart = i;
+        }
+        else
+        {
+          quote = null;
+        }
       }
       
       // ... rest of loop
     }

     if (quote != null)
     {
-      throw new FormatException($"Unmatched {quote} quote in line: '{line}'.");
+      throw new FormatException($"Unmatched {quote} quote starting at position {quoteStart} in line: '{line}'.");
     }
📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c1b76c5 and 3dfe17a.

📒 Files selected for processing (7)
  • docs/api/create_docker_container.md
  • src/Testcontainers/Clients/DockerContainerOperations.cs
  • src/Testcontainers/Images/DockerImage.cs
  • src/Testcontainers/Images/DockerfileArchive.cs
  • src/Testcontainers/Images/IImage.cs
  • src/Testcontainers/Images/Platform.cs
  • tests/Testcontainers.Tests/Unit/Images/ImageFromDockerfileTest.cs
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/Testcontainers/Images/IImage.cs
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-11-17T17:58:43.958Z
Learnt from: diegosasw
Repo: testcontainers/testcontainers-dotnet PR: 1583
File: src/Testcontainers.KurrentDb/Testcontainers.KurrentDb.csproj:7-7
Timestamp: 2025-11-17T17:58:43.958Z
Learning: In the testcontainers-dotnet repository, JetBrains.Annotations should use version 2023.3.0 to maintain consistency with the main Testcontainers csproj, rather than always using the latest available version.

Applied to files:

  • tests/Testcontainers.Tests/Unit/Images/ImageFromDockerfileTest.cs
🧬 Code graph analysis (3)
src/Testcontainers/Images/DockerImage.cs (3)
src/Testcontainers/Images/IImage.cs (1)
  • CanBeNull (59-60)
src/Testcontainers/Images/IImageExtensions.cs (1)
  • IImage (18-31)
src/Testcontainers/Configurations/CustomConfiguration.cs (1)
  • IImage (92-109)
src/Testcontainers/Images/DockerfileArchive.cs (1)
src/Testcontainers/Images/DockerImage.cs (5)
  • DockerImage (41-44)
  • DockerImage (51-54)
  • DockerImage (62-68)
  • DockerImage (80-95)
  • DockerImage (97-134)
tests/Testcontainers.Tests/Unit/Images/ImageFromDockerfileTest.cs (1)
src/Testcontainers/Images/DockerImage.cs (5)
  • DockerImage (41-44)
  • DockerImage (51-54)
  • DockerImage (62-68)
  • DockerImage (80-95)
  • DockerImage (97-134)
🪛 markdownlint-cli2 (0.18.1)
docs/api/create_docker_container.md

27-27: Code block style
Expected: fenced; Actual: indented

(MD046, code-block-style)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (60)
  • GitHub Check: ci (Testcontainers.Bigtable, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ArangoDb, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ActiveMq, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Cassandra, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Azurite, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.BigQuery, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Bigtable, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ArangoDb, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ActiveMq, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Cassandra, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Azurite, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.BigQuery, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Bigtable, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ArangoDb, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ActiveMq, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Cassandra, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Azurite, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.BigQuery, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Bigtable, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ArangoDb, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ActiveMq, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Cassandra, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Azurite, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.BigQuery, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Bigtable, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ArangoDb, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ActiveMq, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Cassandra, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Azurite, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.BigQuery, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Bigtable, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ArangoDb, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ActiveMq, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Cassandra, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Azurite, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.BigQuery, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Bigtable, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ArangoDb, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ActiveMq, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Cassandra, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Azurite, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.BigQuery, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Bigtable, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ArangoDb, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ActiveMq, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Cassandra, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Azurite, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.BigQuery, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Bigtable, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ArangoDb, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ActiveMq, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Cassandra, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Azurite, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.BigQuery, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Bigtable, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ArangoDb, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ActiveMq, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Cassandra, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Azurite, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.BigQuery, ubuntu-24.04)
🔇 Additional comments (7)
docs/api/create_docker_container.md (1)

5-28: LGTM! Clear documentation of the platform feature.

The documentation effectively explains the new platform support with progressive examples: basic string usage, IImage for advanced scenarios, and DockerImage with explicit platform specification. The tip about the platform specifier format is helpful and correctly references the containerd/platforms standard.

Note: The static analysis hint about line 27 being an indented code block appears to be a false positive, as it's just text within the tip block.

src/Testcontainers/Clients/DockerContainerOperations.cs (1)

205-205: LGTM! Platform propagated correctly.

The platform value is properly propagated from the image configuration to the Docker container creation parameters, ensuring platform-specific container creation as intended.

tests/Testcontainers.Tests/Unit/Images/ImageFromDockerfileTest.cs (1)

25-49: LGTM! Test updated to validate platform-aware image parsing.

The test correctly reflects the new behavior where GetBaseImages() returns DockerImage objects with platform information rather than plain strings. The use of Assert.Equivalent properly validates object equality by comparing properties. The test coverage for multiple platform variants of the same base image (azurelinux3.0) demonstrates proper handling of multi-platform Dockerfile scenarios.

src/Testcontainers/Images/DockerfileArchive.cs (1)

164-175: LGTM! Platform extraction from Dockerfile FROM arguments.

The refactored logic correctly:

  1. Extracts both arg and image components from FROM statements
  2. Applies variable substitution to each component
  3. Parses FROM arguments to extract platform values
  4. Constructs DockerImage instances with the parsed platform

This enables proper multi-platform Dockerfile support where different base images can specify different target platforms.

src/Testcontainers/Images/DockerImage.cs (3)

56-68: LGTM! Platform-aware constructor implemented correctly.

The new constructor DockerImage(string image, Platform platform) provides a clean API for specifying platform while avoiding breaking changes by using a distinct Platform type parameter. The implementation properly delegates to the existing image parsing logic and assigns the platform value.


77-94: LGTM! Platform parameter integrated into constructor chain.

The platform parameter is properly added to the public constructor signature with a default value of null, maintaining backward compatibility. The value is correctly propagated through to the private constructor via TrimOrDefault(platform).


148-149: LGTM! Platform property exposes the platform value.

The Platform property correctly implements the IImage interface and exposes the internal _platform field, completing the platform support implementation.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
src/Testcontainers/Images/DockerfileArchive.cs (1)

317-331: Good refactoring: parameter rename improves clarity.

Renaming the parameter from image to line better reflects the method's broader usage—it now processes both FROM arguments and image strings (called on line 166 for both). The implementation remains correct and all internal references are consistent.

📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3dfe17a and f2bf9d7.

📒 Files selected for processing (3)
  • docs/api/create_docker_container.md
  • src/Testcontainers/Images/DockerfileArchive.cs
  • src/Testcontainers/Images/Platform.cs
🧰 Additional context used
🧬 Code graph analysis (2)
src/Testcontainers/Images/Platform.cs (1)
src/Testcontainers/Images/DockerImage.cs (1)
  • PublicAPI (9-209)
src/Testcontainers/Images/DockerfileArchive.cs (1)
src/Testcontainers/Images/DockerImage.cs (5)
  • DockerImage (41-44)
  • DockerImage (51-54)
  • DockerImage (62-68)
  • DockerImage (80-95)
  • DockerImage (97-134)
🪛 markdownlint-cli2 (0.18.1)
docs/api/create_docker_container.md

27-27: Code block style
Expected: fenced; Actual: indented

(MD046, code-block-style)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (54)
  • GitHub Check: ci (Testcontainers.ClickHouse, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.CockroachDb, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Bigtable, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ArangoDb, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Cassandra, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ClickHouse, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.CockroachDb, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Consul, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Bigtable, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ArangoDb, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Cassandra, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ClickHouse, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.CockroachDb, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Consul, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Bigtable, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Couchbase, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ClickHouse, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.CockroachDb, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Consul, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Bigtable, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.CosmosDb, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Couchbase, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ClickHouse, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.CockroachDb, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Consul, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Bigtable, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.CosmosDb, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Couchbase, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ClickHouse, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.CockroachDb, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Consul, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.CosmosDb, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Couchbase, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ClickHouse, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.CockroachDb, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Consul, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.CosmosDb, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.CouchDb, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Couchbase, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ClickHouse, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.CockroachDb, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Consul, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.CosmosDb, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.CouchDb, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Couchbase, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ClickHouse, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.CockroachDb, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Consul, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.CosmosDb, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.CouchDb, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Couchbase, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ClickHouse, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.CockroachDb, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Consul, ubuntu-24.04)
🔇 Additional comments (5)
src/Testcontainers/Images/Platform.cs (1)

23-26: LGTM! Constructor fix confirmed.

The critical issue identified in the previous review has been resolved. The constructor now correctly assigns the value parameter to the Value property (line 25), ensuring the readonly struct is properly initialized.

docs/api/create_docker_container.md (1)

5-28: Documentation accurately reflects the platform feature.

The new section clearly explains how to configure container images with platform targeting. The examples correctly demonstrate both the simple string overload and the platform-specific DockerImage constructor, and the format specification matches the implementation in Platform.cs.

src/Testcontainers/Images/DockerfileArchive.cs (3)

165-175: Platform extraction logic is well-structured.

The integration of FROM-argument parsing with image extraction is correct:

  • Both arguments and image strings undergo variable substitution (line 166)
  • Platform is correctly extracted from parsed arguments using TryGetValue (line 172), defaulting to null if not specified
  • The DockerImage constructor receives the platform value appropriately (line 173)

The implementation handles typical Dockerfile FROM syntax (e.g., FROM --platform=linux/amd64 postgres:15.1) correctly.


366-408: FROM-argument parsing correctly handles standard Docker syntax.

The ParseFromArgs implementation properly handles quote-delimited values:

  • Correctly toggles quote state for matching quote characters (line 381-384)
  • Treats whitespace inside quotes as part of the value (line 386-388)
  • Appropriately yields tokens on whitespace boundaries outside quotes (lines 391-396)
  • Reports unmatched quotes without position details (line 401), which avoids the complexity of tracking quote positions during state changes

The algorithm is well-suited for typical Docker FROM argument syntax (e.g., --platform="linux/amd64" --pull=always).


415-429: Argument parsing correctly extracts flag names and values.

The ParseArg method appropriately:

  • Strips leading dashes (line 417) to extract the flag name
  • Splits on = to separate name and value (line 418)
  • Handles flags without values by returning null (lines 419-421)
  • Trims both whitespace and quotes from values (line 426), providing lenient parsing for variations like --platform="linux/amd64" or --platform= "value"

The implementation is robust for standard Docker FROM argument syntax.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
tests/Testcontainers.Tests/Unit/Images/TestcontainersImageTest.cs (1)

72-84: The test correctly validates the Platform property functionality.

The test properly verifies that the Platform property returns the expected value when a platform is specified. It follows existing conventions and uses the appropriate constructor signature. However, consider expanding test coverage to match the thoroughness demonstrated elsewhere in this file (see existing tests with Theory patterns for multiple scenarios).

The following additional test cases would enhance coverage:

  1. Default platform behavior - Verify that the Platform property returns null when no platform is specified:
[Fact]
public void Platform_NoPlatformSpecified_ReturnsNull()
{
    // Given
    IImage dockerImage = new DockerImage("foo");
    
    // When
    var result = dockerImage.Platform;
    
    // Then
    Assert.Null(result);
}
  1. Multiple valid platform strings - Use Theory with different platform formats:
[Theory]
[InlineData("linux/amd64")]
[InlineData("linux/arm64")]
[InlineData("linux/arm/v7")]
[InlineData("windows/amd64")]
public void Platform_ValidPlatformStrings_ReturnsPlatform(string platform)
{
    // Given
    IImage dockerImage = new DockerImage("foo", new Platform(platform));
    
    // When
    var result = dockerImage.Platform;
    
    // Then
    Assert.Equal(platform, result);
}
📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f2bf9d7 and eb674c8.

📒 Files selected for processing (1)
  • tests/Testcontainers.Tests/Unit/Images/TestcontainersImageTest.cs
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
  • GitHub Check: ci (Testcontainers.ArangoDb, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ActiveMq, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Cassandra, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Bigtable, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.BigQuery, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Azurite, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers, ubuntu-24.04)
  • GitHub Check: analyze (csharp)

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
src/Testcontainers/Images/Platform.cs (1)

16-38: Consider overriding Equals, GetHashCode, and ToString.

For value types that may be compared or used in collections, it's recommended to override Equals, GetHashCode, and ToString rather than relying on the default struct implementations. This improves performance (avoids reflection) and provides better debugging support.

🔎 Suggested implementation
 public readonly struct Platform
 {
   public Platform(string value)
   {
     Value = value;
   }

   [PublicAPI]
   [CanBeNull]
   public string Value { get; }
+
+  public override bool Equals(object obj)
+  {
+    return obj is Platform other && Equals(Value, other.Value);
+  }
+
+  public override int GetHashCode()
+  {
+    return Value?.GetHashCode() ?? 0;
+  }
+
+  public override string ToString()
+  {
+    return Value ?? string.Empty;
+  }
 }
📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between eb674c8 and 09ea9c1.

📒 Files selected for processing (2)
  • src/Testcontainers/Images/Platform.cs
  • tests/Testcontainers.Tests/Unit/Images/TestcontainersImageTest.cs
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/Testcontainers.Tests/Unit/Images/TestcontainersImageTest.cs
🧰 Additional context used
🧬 Code graph analysis (1)
src/Testcontainers/Images/Platform.cs (1)
src/Testcontainers/Images/IImage.cs (1)
  • CanBeNull (59-60)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (57)
  • GitHub Check: ci (Testcontainers.ArangoDb, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Cassandra, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Bigtable, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ClickHouse, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Azurite, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ActiveMq, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ArangoDb, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Cassandra, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Bigtable, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ClickHouse, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Azurite, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ActiveMq, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ArangoDb, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Cassandra, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Bigtable, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ClickHouse, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Azurite, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ActiveMq, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ArangoDb, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Cassandra, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ClickHouse, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Azurite, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ActiveMq, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ArangoDb, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Cassandra, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ClickHouse, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Azurite, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ActiveMq, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.CockroachDb, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ArangoDb, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Cassandra, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ClickHouse, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Azurite, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ActiveMq, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.CockroachDb, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ArangoDb, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Cassandra, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ClickHouse, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Azurite, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ActiveMq, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.CockroachDb, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ArangoDb, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Cassandra, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ClickHouse, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Azurite, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ActiveMq, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.CockroachDb, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ArangoDb, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Cassandra, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ClickHouse, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Azurite, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ActiveMq, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.CockroachDb, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ArangoDb, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Cassandra, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ClickHouse, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ActiveMq, ubuntu-24.04)
🔇 Additional comments (5)
src/Testcontainers/Images/Platform.cs (5)

1-3: LGTM: Clean namespace and imports.

The namespace aligns with the module structure, and JetBrains.Annotations is appropriately used for API surface annotations.


5-14: LGTM: Clear and comprehensive documentation.

The XML documentation effectively describes the platform format and provides a helpful reference to the containerd/platforms specification.


15-16: LGTM: Appropriate struct declaration.

The readonly struct design ensures immutability and the [PublicAPI] attribute properly documents this as part of the public API surface.


18-26: Constructor fix confirmed.

The critical issue identified in the previous review has been properly addressed—the constructor now assigns the value parameter to the Value property on line 25.


28-37: LGTM: Well-documented property.

The getter-only Value property is properly designed for the readonly struct, and the [CanBeNull] annotation combined with the remarks clearly documents the null semantics.

@HofmeisterAn HofmeisterAn merged commit 465012e into develop Dec 28, 2025
248 of 288 checks passed
@HofmeisterAn HofmeisterAn deleted the feature/add-platform-support branch December 28, 2025 08:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Enhancement]: Support customizing image pull behavior to include a "platform" override

1 participant