Skip to content

Conversation

NathanBaulch
Copy link
Contributor

@NathanBaulch NathanBaulch commented Oct 14, 2025

What does this PR do?

The default MS "azurite" container entrypoint runs the blob, queue and table services internally. The azurite Testcontainers module has an option to specify these services but it's not exposed to consumers and therefore always contains all 3 services.

This PR uses the options pattern established in the Redpanda module to allow consumers to choose the services they actually need. If only "blob" or "queue" are chosen, then the special azurite-blob or azurite-queue entrypoint is used respectively. Note that azurite-table is supported in the official container but is relatively new and appears to hang on shutdown for me so I'm not using that.

This also means fewer exposed ports and fewer wait strategies. FWIW, I'm seeing 30% faster startup time on my machine when running azurite-blob vs the full azurite.

Why is it important?

Faster startup and lower memory usage, especially for the common scenario where only blob storage is needed.

@NathanBaulch NathanBaulch requested a review from a team as a code owner October 14, 2025 06:15
Copy link

netlify bot commented Oct 14, 2025

Deploy Preview for testcontainers-go ready!

Name Link
🔨 Latest commit 2d6e5fb
🔍 Latest deploy log https://app.netlify.com/projects/testcontainers-go/deploys/68f756d5680a7700087d0a46
😎 Deploy Preview https://deploy-preview-3451--testcontainers-go.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.

Copy link

coderabbitai bot commented Oct 14, 2025

Summary by CodeRabbit

Release Notes

  • New Features

    • Added WithEnabledServices option to Azurite for selective Azure Storage service configuration (Blob, Queue, Table)
    • Added examples demonstrating service-specific configurations
  • Documentation

    • Updated Azurite documentation with WithEnabledServices usage details

Summary by CodeRabbit

  • New Features

    • Added WithEnabledServices option to selectively enable specific Azure Storage services (Blob, Queue, Table), reducing resource consumption and exposed ports.
  • Documentation

    • Updated documentation for Azurite container configuration options.

Walkthrough

Run accepts Azurite-specific Options, validates enabled services, builds per-service entrypoint/flags, aggregates exposed ports and wait strategies, and starts the container via testcontainers.Run. Service-to-port resolution was centralized in servicePort; ServiceURL now uses it and per-service URL helpers delegate to ServiceURL.

Changes

Cohort / File(s) Change summary
Core runtime
modules/azure/azurite/azurite.go
Added servicePort(Service) (nat.Port, error); updated ServiceURL to use it and return via PortEndpoint; removed internal serviceURL helper; refactored Run() to apply Options, compute per-service entrypoint/CLI flags, aggregate WithCmd, WithExposedPorts, and WithWaitStrategy, then call testcontainers.Run.
Options API
modules/azure/azurite/options.go
Introduced exported Option type (func(*options) error) with Customize to satisfy testcontainers.ContainerCustomizer; added WithEnabledServices(...) with validation, duplicate check, and defaulting to Blob/Queue/Table; changed options.EnabledServices to []Service.
Service types
modules/azure/azurite/services.go
Simplified to type Service string; exported BlobService, QueueService, TableService as Service constants; removed old alias types and internal constants.
Tests & examples
modules/azure/azurite/azurite_test.go, modules/azure/azurite/examples_test.go
Added TestAzurite_enabledServices to verify enabling/disabling services and ServiceURL behavior; examples updated to call WithEnabledServices(...) for specific services.
Docs / compile assertions
modules/azure/eventhubs/options.go, modules/azure/servicebus/options.go, docs/modules/azure.md
Updated comments and compile-time assertions to reference testcontainers.ContainerCustomizer; docs add WithEnabledServices subsection describing selective service enabling.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant Dev as Caller
    participant Run as azurite.Run
    participant Opts as Option funcs
    participant Builder as module opts builder
    participant TC as testcontainers.Run
    participant Container as started container

    Dev->>Run: Call Run(opts...)
    Run->>Opts: Iterate & apply Option funcs (Customize)
    Note right of Run #bfe1d6: validate enabled services\n(default blob,queue,table)
    Run->>Builder: Build entrypoint/cmd, per-service flags, exposed ports, wait strategies
    Builder-->>Run: module customizers (WithCmd, WithExposedPorts, WithWaitStrategy)
    Run->>TC: Call testcontainers.Run(module customizers + remaining opts)
    TC-->>Container: Return running container or error
    Run->>Dev: Return container or wrapped error
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

feature

Suggested reviewers

  • mdelapenya

Poem

"I hopped into code with a twitchy nose,
Turned knobs for services that Azurite knows.
Ports aligned and commands in queue,
Containers wake — a bright debut.
Hop, test, and run — a rabbit's bravo 🐇"

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed The PR title "feat(azure): reduce time/memory by running specific sub-services" directly and clearly summarizes the main objective of the changeset. The primary change is the introduction of the WithEnabledServices option that allows consumers to select which Azure Storage services (blob, queue, table) to run, rather than always running all three. This enables reduced startup time and memory usage when only specific services are needed. The title is concise, specific, and accurately captures this core improvement without extraneous details.
Description Check ✅ Passed The PR description is well-related to the changeset and provides meaningful context. It clearly explains what the PR does (exposing service selection via the options pattern), how it works (using specific entrypoints like azurite-blob or azurite-queue for individual services), and why it matters (faster startup, lower memory, fewer exposed ports). The description includes concrete details such as the 30% startup improvement observed by the author and acknowledges the limitation with azurite-table. The content aligns well with the actual code changes across multiple files, including the new WithEnabledServices option, refactored service URL methods, and updated documentation.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c67652c and 2d6e5fb.

📒 Files selected for processing (2)
  • docs/modules/azure.md (1 hunks)
  • modules/azure/azurite/azurite_test.go (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • modules/azure/azurite/azurite_test.go
  • docs/modules/azure.md
⏰ 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: test (1.25.x, modules/azure) / test: modules/azure/1.25.x
  • GitHub Check: test (1.24.x, modules/azure) / test: modules/azure/1.24.x
  • GitHub Check: Analyze (go)

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: 0

🧹 Nitpick comments (1)
modules/azure/azurite/options.go (1)

32-46: Consider validating against empty service list.

WithEnabledServices() can be called with no arguments, resulting in an empty EnabledServices slice. This would cause the container to start without any services enabled, which is likely a configuration error.

Consider adding validation:

 func WithEnabledServices(services ...service) Option {
 	return func(o *options) error {
+		if len(services) == 0 {
+			return fmt.Errorf("at least one service must be enabled")
+		}
+
 		for _, s := range services {
 			switch s {
 			case blobService, queueService, tableService:
 			default:
 				return fmt.Errorf("unknown service: %s", s)
 			}
 		}
 
 		o.EnabledServices = services
 		return nil
 	}
 }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 931625e and 72e4633.

📒 Files selected for processing (4)
  • modules/azure/azurite/azurite.go (1 hunks)
  • modules/azure/azurite/azurite_test.go (1 hunks)
  • modules/azure/azurite/examples_test.go (3 hunks)
  • modules/azure/azurite/options.go (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (4)
modules/azure/azurite/options.go (4)
options.go (1)
  • ContainerCustomizer (22-24)
modules/azure/servicebus/options.go (1)
  • Option (30-30)
modules/azure/eventhubs/options.go (1)
  • Option (30-30)
generic.go (1)
  • GenericContainerRequest (21-27)
modules/azure/azurite/azurite.go (4)
modules/azure/azurite/options.go (1)
  • Option (24-24)
options.go (5)
  • ContainerCustomizer (22-24)
  • WithEntrypoint (438-443)
  • WithCmd (462-467)
  • WithExposedPorts (454-459)
  • WithWaitStrategy (366-368)
wait/wait.go (1)
  • Strategy (17-19)
wait/host_port.go (1)
  • ForListeningPort (67-69)
modules/azure/azurite/examples_test.go (2)
modules/azure/azurite/options.go (1)
  • WithEnabledServices (33-46)
modules/azure/azurite/services.go (3)
  • BlobService (9-9)
  • QueueService (16-16)
  • TableService (23-23)
modules/azure/azurite/azurite_test.go (3)
modules/azure/azurite/azurite.go (1)
  • Run (74-134)
modules/azure/azurite/options.go (1)
  • WithEnabledServices (33-46)
testing.go (1)
  • CleanupContainer (91-97)
⏰ 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: test (1.24.x, modules/azure) / test: modules/azure/1.24.x
  • GitHub Check: test (1.25.x, modules/azure) / test: modules/azure/1.25.x
  • GitHub Check: Analyze (go)
🔇 Additional comments (7)
modules/azure/azurite/examples_test.go (1)

60-60: Excellent demonstration of the service-selection feature.

The examples clearly show how to enable specific services using WithEnabledServices, which helps users understand the new API and its benefits (reduced resource usage, faster startup).

Also applies to: 202-202, 297-297

modules/azure/azurite/azurite_test.go (1)

39-64: Comprehensive test coverage for service selection.

The test validates both positive cases (valid services) and negative cases (invalid service), and confirms that ServiceURL correctly returns errors for disabled services. The nested loop at lines 54-61 effectively verifies isolation between services.

modules/azure/azurite/options.go (1)

20-30: Clean Option API design following testcontainers patterns.

The Option type implements ContainerCustomizer with a NOOP Customize method, which is correct since the actual option processing happens in azurite.go:Run(). This allows options to be processed twice (once for settings, once by testcontainers) without side effects.

modules/azure/azurite/azurite.go (4)

77-83: Correct option processing with type-safe filtering.

The implementation correctly processes only Option-type options to build settings, while passing all options (including non-Option types like WithInMemoryPersistence) through to testcontainers.Run. This design allows mixing azurite-specific options with generic testcontainers options.


85-90: Smart entrypoint selection based on enabled services.

Using specialized entrypoints (azurite-blob, azurite-queue) for single-service configurations is a good optimization. The comment about azurite-table having slow shutdown is helpful context for excluding it from this optimization.


94-118: Well-structured dynamic configuration per enabled service.

The implementation correctly builds command arguments, exposed ports, and wait strategies based on the enabled services. This ensures that only necessary resources are allocated and reduces startup time.


100-100: Trim /tcp suffix from Azurite port flags
BlobPort, QueuePort, and TablePort include /tcp, but Azurite’s --blobPort, --queuePort, and --tablePort flags expect plain numeric ports. Confirm whether Azurite accepts the /tcp suffix; if not, wrap each port constant with strings.TrimSuffix(port, "/tcp") when building the command.

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 (2)
modules/azure/azurite/options.go (2)

38-44: Consider adding a comment for the empty switch case.

The validation logic is correct, but the empty case for valid services could benefit from a brief comment explaining that no action is needed for valid services, making the intent explicit.

Apply this diff if desired:

 			for _, s := range services {
 				switch s {
-				case blobService, queueService, tableService:
+				case blobService, queueService, tableService:
+					// Valid service, continue
 				default:
 					return fmt.Errorf("unknown service: %s", s)
 				}
 			}

42-42: Suggest implementing fmt.Stringer on service for custom error output
service is currently an alias of string, so %s prints its raw value. Add a func (s service) String() string if you need more descriptive names in the error.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 72e4633 and bda73a3.

📒 Files selected for processing (1)
  • modules/azure/azurite/options.go (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
modules/azure/azurite/options.go (3)
modules/azure/servicebus/options.go (1)
  • Option (30-30)
modules/azure/eventhubs/options.go (1)
  • Option (30-30)
generic.go (1)
  • GenericContainerRequest (21-27)
⏰ 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: test (1.24.x, modules/azure) / test: modules/azure/1.24.x
  • GitHub Check: test (1.25.x, modules/azure) / test: modules/azure/1.25.x
  • GitHub Check: Analyze (go)
🔇 Additional comments (1)
modules/azure/azurite/options.go (1)

23-30: LGTM! Option pattern correctly implements ContainerCustomizer.

The dual-purpose design (functional option + ContainerCustomizer) is appropriate here. The NOOP Customize method satisfies the interface while actual option processing happens in the Run function, allowing module-specific logic to execute before container creation.

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

♻️ Duplicate comments (1)
modules/azure/azurite/options.go (1)

20-21: Comment correctly reflects the verified interface.

The comment accurately states that the code satisfies the testcontainers.ContainerCustomizer interface, matching the assertion on line 21. The issue raised in the previous review has been resolved.

🧹 Nitpick comments (1)
modules/azure/azurite/options.go (1)

32-51: Consider adding duplicate service detection.

The validation logic correctly checks for valid service types, but it does not detect duplicate services. If a user calls WithEnabledServices(blobService, blobService), the function will accept it, potentially leading to duplicate port configurations or wait strategies downstream.

Consider adding duplicate detection:

 func WithEnabledServices(services ...service) Option {
 	return func(o *options) error {
 		if len(services) == 0 {
 			services = []service{blobService, queueService, tableService}
 		} else {
+			seen := make(map[service]bool)
 			for _, s := range services {
+				if seen[s] {
+					return fmt.Errorf("duplicate service: %s", s)
+				}
+				seen[s] = true
+
 				switch s {
 				case blobService, queueService, tableService:
 					// valid service, continue
 				default:
 					return fmt.Errorf("unknown service: %s", s)
 				}
 			}
 		}
 
 		o.EnabledServices = services
 		return nil
 	}
 }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bda73a3 and 5b64ae5.

📒 Files selected for processing (3)
  • modules/azure/azurite/options.go (1 hunks)
  • modules/azure/eventhubs/options.go (1 hunks)
  • modules/azure/servicebus/options.go (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
modules/azure/azurite/options.go (3)
modules/azure/eventhubs/options.go (1)
  • Option (30-30)
modules/azure/servicebus/options.go (1)
  • Option (30-30)
generic.go (1)
  • GenericContainerRequest (21-27)
⏰ 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: test (1.24.x, modules/azure) / test: modules/azure/1.24.x
  • GitHub Check: test (1.25.x, modules/azure) / test: modules/azure/1.25.x
  • GitHub Check: Analyze (go)
🔇 Additional comments (3)
modules/azure/eventhubs/options.go (1)

26-26: LGTM! Comment now accurately reflects the interface.

The comment correctly identifies ContainerCustomizer as the interface being satisfied, matching the assertion on line 27.

modules/azure/servicebus/options.go (1)

26-26: LGTM! Comment now accurately reflects the interface.

The comment correctly identifies ContainerCustomizer as the interface being satisfied, matching the assertion on line 27.

modules/azure/azurite/options.go (1)

23-30: LGTM! Option type correctly implements ContainerCustomizer.

The Option function type with a NOOP Customize method properly satisfies the testcontainers.ContainerCustomizer interface, following the same pattern as eventhubs and servicebus modules.

@mdelapenya mdelapenya self-assigned this Oct 14, 2025
@mdelapenya mdelapenya changed the title feat(azurite): reduce time/memory by running specific sub-services feat(azure): reduce time/memory by running specific sub-services Oct 14, 2025
@NathanBaulch
Copy link
Contributor Author

Goes without saying, but if this PR is accepted then the service constants in services.go will need to be un-deprecated. Not sure about the ServiceURL function, which I found useful in the unit tests.

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 (2)
modules/azure/azurite/options.go (1)

32-55: Avoid slice aliasing when storing EnabledServices.

Store a copy to prevent unexpected mutations from the caller’s slice.

Apply this minimal change:

-        o.EnabledServices = services
+        // copy to avoid retaining caller's backing array
+        o.EnabledServices = append([]Service(nil), services...)
modules/azure/azurite/azurite.go (1)

36-44: Optional: return a clearer error if a service wasn’t enabled.

Currently this fails deep in PortEndpoint. Guard early for better DX.

Example change:

 func (c *Container) ServiceURL(ctx context.Context, srv Service) (string, error) {
+    // make a quick enabled-set
+    enabled := false
+    for _, s := range c.opts.EnabledServices {
+        if s == srv {
+            enabled = true
+            break
+        }
+    }
+    if !enabled {
+        return "", fmt.Errorf("service %q not enabled", srv)
+    }
     port, err := servicePort(srv)
     if err != nil {
         return "", err
     }
     return c.PortEndpoint(ctx, port, "http")
 }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2e20ed6 and 7dda54b.

📒 Files selected for processing (4)
  • modules/azure/azurite/azurite.go (1 hunks)
  • modules/azure/azurite/azurite_test.go (1 hunks)
  • modules/azure/azurite/options.go (1 hunks)
  • modules/azure/azurite/services.go (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • modules/azure/azurite/azurite_test.go
🧰 Additional context used
🧬 Code graph analysis (2)
modules/azure/azurite/options.go (2)
modules/azure/azurite/services.go (4)
  • Service (15-15)
  • BlobService (5-5)
  • QueueService (8-8)
  • TableService (11-11)
options.go (1)
  • ContainerCustomizer (22-24)
modules/azure/azurite/azurite.go (6)
modules/azure/azurite/services.go (4)
  • BlobService (5-5)
  • QueueService (8-8)
  • TableService (11-11)
  • Service (15-15)
modules/azurite/services.go (4)
  • BlobService (12-12)
  • QueueService (18-18)
  • TableService (24-24)
  • Service (31-31)
modules/azurite/azurite.go (3)
  • BlobPort (15-15)
  • QueuePort (18-18)
  • TablePort (21-21)
options.go (4)
  • WithEntrypoint (438-443)
  • WithCmd (462-467)
  • WithExposedPorts (454-459)
  • WithWaitStrategy (366-368)
modules/azure/azurite/options.go (1)
  • Option (24-24)
wait/host_port.go (1)
  • ForListeningPort (67-69)
⏰ 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: test (1.24.x, modules/azure) / test: modules/azure/1.24.x
  • GitHub Check: test (1.25.x, modules/azure) / test: modules/azure/1.25.x
  • GitHub Check: Analyze (go)
🔇 Additional comments (2)
modules/azure/azurite/services.go (1)

5-11: Public Service type and constants look good.

Names, types, and values are clear and consistent with usage elsewhere.

Also applies to: 15-15

modules/azure/azurite/options.go (1)

20-21: Comment fix matches the interface assertion.

Accurate and tidy.

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

♻️ Duplicate comments (1)
modules/azure/azurite/azurite.go (1)

95-108: Ports/CLI flags now correct; resolves earlier critical issue

Using port.Port() for the CLI (“--Port ”) and string(port) for exposed ports is exactly right. The wait strategy uses nat.Port, also correct.

🧹 Nitpick comments (2)
modules/azure/azurite/azurite.go (2)

61-72: Service-to-port mapping OK; minor optional refactor

Switch is fine. Optionally, use a map[Service]nat.Port to simplify and make additions easier.


117-129: Error handling pattern LGTM

Returning a possibly-initialized container alongside the error is helpful for cleanup.

Optionally, document in the function comment that on error a non-nil container may be returned for caller-managed termination.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7dda54b and f51a656.

📒 Files selected for processing (1)
  • modules/azure/azurite/azurite.go (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
modules/azure/azurite/azurite.go (5)
modules/azurite/services.go (4)
  • BlobService (12-12)
  • QueueService (18-18)
  • TableService (24-24)
  • Service (31-31)
modules/azurite/azurite.go (3)
  • BlobPort (15-15)
  • QueuePort (18-18)
  • TablePort (21-21)
options.go (4)
  • WithEntrypoint (438-443)
  • WithCmd (462-467)
  • WithExposedPorts (454-459)
  • WithWaitStrategy (366-368)
modules/azure/azurite/options.go (1)
  • Option (24-24)
wait/host_port.go (1)
  • ForListeningPort (67-69)
⏰ 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). (2)
  • GitHub Check: test (1.24.x, modules/azure) / test: modules/azure/1.24.x
  • GitHub Check: Analyze (go)
🔇 Additional comments (5)
modules/azure/azurite/azurite.go (5)

38-44: ServiceURL centralization looks good

Using servicePort + PortEndpoint(ctx, nat.Port, "http") is correct and avoids hardcoding ports in multiple places.


46-59: Helper delegation LGTM

BlobServiceURL, QueueServiceURL, and TableServiceURL delegating to ServiceURL reduces duplication.


78-85: Verify Option wiring into Run

You type-assert azurite Option from opts (ContainerCustomizer). This requires Option to satisfy testcontainers.ContainerCustomizer. Please confirm it does; otherwise WithEnabledServices(...) won’t compile when passed to Run.

If needed, add a no-op Customize method so Option satisfies the interface:

--- a/modules/azure/azurite/options.go
+++ b/modules/azure/azurite/options.go
@@
- type Option func(*options) error
+ type Option func(*options) error
+
+ // Ensure Option also satisfies testcontainers.ContainerCustomizer so it can be passed to Run.
+ func (o Option) Customize(req *testcontainers.GenericContainerRequest) error {
+     return nil
+ }

86-91: Entrypoint selection is sensible

Choosing azurite-blob/azurite-queue for a single enabled service and avoiding table due to shutdown hangs is a pragmatic default.

Consider a short comment linking to the azurite-table shutdown issue for future re-evaluation.


110-114: Aggregating module options is fine

WithCmd, WithExposedPorts, and WithWaitStrategy applied together is coherent. 60s default wait deadline via WithWaitStrategy is reasonable.

@mdelapenya
Copy link
Member

Looks good to me thanks! Could you update the docs/azure file for this new option?

@NathanBaulch
Copy link
Contributor Author

Done.

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)
docs/modules/azure.md (1)

64-68: Add usage example for consistency with existing options documentation.

The section explains the purpose but doesn't show how to invoke the option. For consistency with the WithInMemoryPersistence option documented below, add the function signature and a concrete usage example (e.g., azurite.WithEnabledServices("blob")).

Update lines 66-68 to include the actual function signature and usage pattern:

- The default Azurite container entrypoint runs all three storage services: blob, queue, and table. Use this option to specify the required services for fewer exposed ports and slightly reduced container resources.
+ The default Azurite container entrypoint runs all three storage services: blob, queue, and table. Use `WithEnabledServices(services ...string)` to specify the required services for fewer exposed ports and slightly reduced container resources. E.g. `azurite.WithEnabledServices("blob", "queue")`.
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f51a656 and 593257b.

📒 Files selected for processing (1)
  • docs/modules/azure.md (1 hunks)
⏰ 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: test (1.25.x, modules/azure) / test: modules/azure/1.25.x
  • GitHub Check: test (1.24.x, modules/azure) / test: modules/azure/1.24.x
  • GitHub Check: Analyze (go)

mdelapenya
mdelapenya previously approved these changes Oct 21, 2025
Copy link
Member

@mdelapenya mdelapenya left a comment

Choose a reason for hiding this comment

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

LGTM! I'm approving this even though I added some comments, once addressed, and the CI pass (will pass 😉 ), this is ready to be merged.

Thank you so much for contributing to testcontainers-go, the library gets better day by day with your contributions!

Copy link
Member

@mdelapenya mdelapenya left a comment

Choose a reason for hiding this comment

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

LGTM, thanks!

@mdelapenya mdelapenya added the feature New functionality or new behaviors on the existing one label Oct 21, 2025
@mdelapenya mdelapenya merged commit 32220d6 into testcontainers:main Oct 21, 2025
17 checks passed
@NathanBaulch NathanBaulch deleted the azurite branch October 21, 2025 19:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature New functionality or new behaviors on the existing one

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants