Skip to content

Conversation

@mdelapenya
Copy link
Member

What does this PR do?

Use the Run function in openldap

Why is it important?

Migrate modules to the new API, improving consistency and leveraging the latest testcontainers functionality.

Related issues

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
@mdelapenya mdelapenya requested a review from a team as a code owner October 7, 2025 15:34
@mdelapenya mdelapenya added the chore Changes that do not impact the existing functionality label Oct 7, 2025
@netlify
Copy link

netlify bot commented Oct 7, 2025

Deploy Preview for testcontainers-go ready!

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

@coderabbitai
Copy link

coderabbitai bot commented Oct 7, 2025

Summary by CodeRabbit

  • Refactor

    • Migrated OpenLDAP container configuration helpers to a new, unified customization interface (breaking change for integrators using the old helpers).
    • Streamlined startup by composing options and deriving effective settings from the running container for more reliable initialization.
  • Bug Fixes

    • Improved robustness by synchronizing configuration with the container’s final environment values after start.
  • Chores

    • Enhanced error messages during start and inspect operations for clearer troubleshooting.

Walkthrough

Refactors the OpenLDAP module to use testcontainers.Run with ContainerCustomizer options, converts env option helpers to return ContainerCustomizer, handles initial LDIF via files and lifecycle hooks, and adds post-start container inspection to read environment values and update internal fields, with adjusted error messages.

Changes

Cohort / File(s) Summary of changes
OpenLDAP module: Run API migration and env handling
modules/openldap/openldap.go
Migrated from GenericContainerRequest to testcontainers.Run with a composed slice of ContainerCustomizer. Converted WithAdminUsername/WithAdminPassword/WithRoot to return ContainerCustomizer (use WithEnv). Reworked WithInitialLdif to use WithFiles and lifecycle hooks. Added post-start Inspect to read envs and sync container fields. Updated error messages.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor Caller
  participant OpenLDAP as OpenLDAP Module
  participant TC as testcontainers.Run
  participant C as OpenLDAP Container

  Caller->>OpenLDAP: Start(opts: ContainerCustomizer...)
  OpenLDAP->>OpenLDAP: Build moduleOpts (WithImage, WithEnv, ...)
  alt Initial LDIF provided
    OpenLDAP->>OpenLDAP: Create ContainerFile + lifecycle hook
    OpenLDAP->>TC: WithFiles + WithAdditionalLifecycleHooks
  end
  OpenLDAP->>TC: Run(moduleOpts...)
  TC->>C: Create & Start container
  TC-->>OpenLDAP: Container handle or error

  alt Start ok
    OpenLDAP->>C: Inspect()
    C-->>OpenLDAP: Env (LDAP_ADMIN_USERNAME/PASSWORD/ROOT)
    OpenLDAP->>OpenLDAP: Update internal fields (fallback to defaults)
  else Start/Inspect error
    OpenLDAP-->>Caller: Return error ("run openldap"/"inspect openldap")
  end

  OpenLDAP-->>Caller: OpenLDAPContainer handle
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

A rabbit taps the docker drum,
With envs that hop and LDIFs that hum.
Hooks in place, we run, then peek—
Inspect the burrow for creds we seek.
New paths dug, the module’s spry—
Carrot-approved, containers fly! 🥕🐇

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Title Check ✅ Passed The title succinctly identifies the type of change as a chore for the openldap module and clearly states that it switches to using the Run function, which directly reflects the primary modification in the pull request.
Description Check ✅ Passed The description directly explains that the PR uses the Run function in the openldap module and clarifies why the migration to the new API is important, while also linking to the related upstream issue, all of which align with the changeset.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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 (2)
modules/openldap/openldap.go (2)

70-104: Harden WithInitialLdif: read env from the container (not req.Env) and consider returning ContainerCustomizer

Accessing req.Env inside a PostReadies hook can be stale when used outside this module. Inspect the container to obtain final env values, and optionally return ContainerCustomizer for API consistency.

Apply:

-func WithInitialLdif(ldif string) testcontainers.CustomizeRequestOption {
-	return func(req *testcontainers.GenericContainerRequest) error {
+func WithInitialLdif(ldif string) testcontainers.ContainerCustomizer {
+	return testcontainers.CustomizeRequestOption(func(req *testcontainers.GenericContainerRequest) error {
@@
-		hook := testcontainers.ContainerLifecycleHooks{
+		hook := testcontainers.ContainerLifecycleHooks{
 			PostReadies: []testcontainers.ContainerHook{
 				func(ctx context.Context, container testcontainers.Container) error {
-					username := req.Env["LDAP_ADMIN_USERNAME"]
-					rootDn := req.Env["LDAP_ROOT"]
-					password := req.Env["LDAP_ADMIN_PASSWORD"]
+					inspect, err := container.Inspect(ctx)
+					if err != nil {
+						return err
+					}
+
+					username, password, rootDn := defaultUser, defaultPassword, defaultRoot
+					for _, e := range inspect.Config.Env {
+						if v, ok := strings.CutPrefix(e, "LDAP_ADMIN_USERNAME="); ok {
+							username = v
+						}
+						if v, ok := strings.CutPrefix(e, "LDAP_ADMIN_PASSWORD="); ok {
+							password = v
+						}
+						if v, ok := strings.CutPrefix(e, "LDAP_ROOT="); ok {
+							rootDn = v
+						}
+					}
+
 					code, output, err := container.Exec(ctx, []string{"ldapadd", "-H", "ldap://localhost:1389", "-x", "-D", fmt.Sprintf("cn=%s,%s", username, rootDn), "-w", password, "-f", "/initial_ldif.ldif"})
 					if err != nil {
 						return err
 					}
 					if code != 0 {
 						data, _ := io.ReadAll(output)
 						return errors.New(string(data))
 					}
 					return nil
 				},
 			},
 		}
@@
-		return testcontainers.WithAdditionalLifecycleHooks(hook)(req)
-	}
+		return testcontainers.WithAdditionalLifecycleHooks(hook)(req)
+	})
 }

150-165: Optional: extract env parsing into a small helper

Env extraction via CutPrefix is fine; consider a shared helper (e.g., getEnv(inspect.Config.Env, "KEY", fallback)) to reduce duplication across modules.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3697410 and e5755f8.

📒 Files selected for processing (1)
  • modules/openldap/openldap.go (4 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
modules/openldap/openldap.go (5)
options.go (7)
  • ContainerCustomizer (22-24)
  • WithEnv (75-85)
  • CustomizeRequestOption (28-28)
  • WithFiles (524-529)
  • WithAdditionalLifecycleHooks (497-502)
  • WithExposedPorts (454-459)
  • WithWaitStrategy (366-368)
generic.go (1)
  • GenericContainerRequest (21-27)
container.go (1)
  • ContainerFile (110-115)
lifecycle.go (1)
  • ContainerLifecycleHooks (43-55)
modules/mysql/mysql.go (1)
  • Run (54-121)
⏰ 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/openldap) / test: modules/openldap/1.24.x
  • GitHub Check: test (1.25.x, modules/openldap) / test: modules/openldap/1.25.x
  • GitHub Check: Analyze (go)
🔇 Additional comments (4)
modules/openldap/openldap.go (4)

54-56: Env option helpers migration looks good

Returning ContainerCustomizer via WithEnv aligns with the new Run API and other modules.

Also applies to: 61-63, 66-68


114-125: Defaults and wait strategy are sensible

Good use of WithEnv defaults, exposing 1389/tcp, and ForAll(wait.ForLog + ForListeningPort). Matches patterns in other modules.


129-137: Post-run container wiring LGTM

Creating OpenLDAPContainer with defaults, to be overridden after inspect, is clear and safe.


141-149: Error wrapping and inspect behavior is consistent

Returning partial container on error mirrors other modules (e.g., mysql). Message prefixes are clear.

@mdelapenya mdelapenya self-assigned this Oct 7, 2025
@mdelapenya mdelapenya merged commit a642d65 into testcontainers:main Oct 7, 2025
17 checks passed
@mdelapenya mdelapenya deleted the use-run-claude-openldap branch October 7, 2025 15:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

chore Changes that do not impact the existing functionality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant