Skip to content

chore(ers): add BDD cukes for multi-strategy ERS (Claims + LDAP)#3767

Merged
jrschumacher merged 8 commits into
opentdf:mainfrom
khvirtru:test/multi-strategy-ers-cukes
Jul 24, 2026
Merged

chore(ers): add BDD cukes for multi-strategy ERS (Claims + LDAP)#3767
jrschumacher merged 8 commits into
opentdf:mainfrom
khvirtru:test/multi-strategy-ers-cukes

Conversation

@khvirtru

@khvirtru khvirtru commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Add 3 end-to-end BDD/Cucumber scenarios that validate multi-strategy entity resolution (Claims + LDAP) through the full gRPC stack (SDK → Connect RPC → platform → ERS → LDAP)
  • Catches serialization bugs at the gRPC/structpb boundary that direct-call integration tests miss (e.g. fix(ers): coerce attempted_strategies []string to []interface{} for structpb #3645 structpb coercion). Related: fix(ers): marshal/unmarshal metadata correctly. #3672 (pgx driver + broader []string normalization) fixes the same class of structpb bug for multi-valued claim/metadata fields — not exercised by current test data but would be needed for LDAP attributes returning multiple values.
  • ERS configuration is defined inline in the feature file using DocString-based step definitions, making mapping strategies, providers, and conditions visible without referencing external template files
  • LDAP testcontainer using osixia/openldap:1.5.0 with existing LDIF fixtures from service/entityresolution/integration/ldap_test_data/

What's new

Files created

  • tests-bdd/cukes/steps_ldap.go — LDAP testcontainer step definition (Given an LDAP directory with test users), idempotent for @stateless reuse
  • tests-bdd/cukes/steps_ers.go — Inline ERS configuration step definitions using DocString YAML:
    • an ERS configuration with mode "X" and failure strategy "Y" — creates config
    • an ERS provider "name" of type "type" — plain provider (e.g. claims)
    • an ERS provider "name" of type "type" connected to the LDAP directory — auto-wires LDAP host/port
    • an ERS mapping strategy "name" using provider "provider" + DocString — mapping strategy with inline YAML config
    • a local platform with inline ERS configuration — assembles config, patches base template, starts platform
  • tests-bdd/features/multi-strategy-ers.feature — 3 scenarios tagged @multi-strategy-ers @stateless

Files modified

  • tests-bdd/cukes/glue_platform.goLDAPPort field on LocalDevScenarioOptions + propagate in @stateless scenario copies
  • tests-bdd/cukes/steps_localplatform.goldapPort template variable + ersConfig YAML-patching support in createPlatformConfiguration
  • tests-bdd/platform_test.go — Register LDAP and ERS step definitions

Scenarios

# User LDAP department Resource Expected
1 alice engineering engineering PERMIT
2 bob marketing engineering DENY
3 charlie security security PERMIT

How to run

DOCKER_HOST="unix://$HOME/.colima/default/docker.sock" \
TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE=/var/run/docker.sock \
TESTCONTAINERS_RYUK_DISABLED=true \
PLATFORM_IMAGE=DEBUG \
go test ./tests-bdd/ -v --tags=cukes --godog.tags=@multi-strategy-ers --count=1

Note: Requires keytool (JDK) on the host for the cukes framework's keystore generation.

Test plan

  • All 3 scenarios pass locally (57/57 steps, 0 failures)
  • go vet --tags=cukes ./tests-bdd/... passes
  • Existing cukes tests unaffected (no shared code behavior changes)
  • CI pipeline passes

DSPX-4100

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added multi-strategy ERS end-to-end tests combining claims passthrough and LDAP-by-username.
    • Added automated LDAP test-directory provisioning and reuse across stateless scenarios.
    • Enabled inline ERS configuration in local platform BDD runs (including LDAP port wiring).
  • Tests

    • Added BDD coverage asserting PERMIT/DENY outcomes for engineering, marketing, and security users.
  • Documentation

    • Documented “Multi-Strategy ERS Testing (Claims + LDAP)” setup, execution, and expected behavior.

@khvirtru
khvirtru requested a review from a team as a code owner July 21, 2026 18:51
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The BDD suite provisions reusable OpenLDAP data, injects LDAP-backed inline ERS configuration into local platform startup, registers LDAP and ERS steps, and validates multi-strategy authorization with three end-to-end scenarios.

Changes

LDAP-backed ERS BDD coverage

Layer / File(s) Summary
LDAP container and scenario state
tests-bdd/cukes/glue_platform.go, tests-bdd/cukes/steps_ldap.go, tests-bdd/platform_test.go
LDAP ports are stored and reused across stateless scenarios; LDAP testcontainers, LDIF fixtures, readiness checks, cleanup, and step registration are added.
Inline ERS platform configuration
tests-bdd/cukes/steps_ers.go, tests-bdd/cukes/steps_localplatform.go
ERS providers and mapping strategies are serialized into platform configuration, with LDAP connection data and the mapped LDAP port included when configured.
Scenario coverage and test documentation
tests-bdd/features/multi-strategy-ers.feature, tests-bdd/README.md
Three scenarios validate engineering PERMIT, marketing DENY, and security PERMIT outcomes, with setup and execution documentation added.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Suggested reviewers: jakedoublev

Poem

I’m a rabbit with LDAP in my burrow tonight,
ERS maps the clues and the claims just right.
PERMIT for some, DENY for a few,
Three hopping scenarios prove the flow through.
Tests bloom softly—carrot-sized delight!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding BDD Cucumber coverage for multi-strategy ERS with LDAP.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests-bdd/cukes/steps_ldap.go`:
- Around line 65-92: Update the LDAP setup flow around GenericContainer, Host,
and MappedPort so every error path terminates the already-started ldapContainer
before returning. Register cleanup immediately after successful container
creation, or explicitly invoke the same termination logic for subsequent setup
failures, while preserving the existing shutdown hook for successful setup.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 75c9a4d7-5468-49aa-9542-2cc355939246

📥 Commits

Reviewing files that changed from the base of the PR and between 9e5d148 and b52d49c.

📒 Files selected for processing (6)
  • tests-bdd/cukes/glue_platform.go
  • tests-bdd/cukes/resources/platform.multi_strategy_ers.template
  • tests-bdd/cukes/steps_ldap.go
  • tests-bdd/cukes/steps_localplatform.go
  • tests-bdd/features/multi-strategy-ers.feature
  • tests-bdd/platform_test.go

Comment thread tests-bdd/cukes/steps_ldap.go
@khvirtru khvirtru changed the title test(ers): add BDD cukes for multi-strategy ERS (Claims + LDAP) chore(ers): add BDD cukes for multi-strategy ERS (Claims + LDAP) Jul 21, 2026
Comment thread tests-bdd/features/multi-strategy-ers.feature
@khvirtru
khvirtru force-pushed the test/multi-strategy-ers-cukes branch from 440837b to 39ee26b Compare July 22, 2026 17:56

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests-bdd/README.md`:
- Around line 323-365: Add the text language identifier to the architecture
diagram fence in the README, and insert blank lines before each listed command
fence under the prerequisites and workflow sections. Update only the Markdown
formatting around the diagram and command examples so markdownlint passes.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 20de5dbf-d858-457d-a7db-bd2e7cda862f

📥 Commits

Reviewing files that changed from the base of the PR and between b52d49c and 39ee26b.

📒 Files selected for processing (7)
  • tests-bdd/README.md
  • tests-bdd/cukes/glue_platform.go
  • tests-bdd/cukes/resources/platform.multi_strategy_ers.template
  • tests-bdd/cukes/steps_ldap.go
  • tests-bdd/cukes/steps_localplatform.go
  • tests-bdd/features/multi-strategy-ers.feature
  • tests-bdd/platform_test.go

Comment thread tests-bdd/README.md Outdated
Comment thread tests-bdd/features/multi-strategy-ers.feature Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
tests-bdd/cukes/steps_localplatform.go (1)

537-541: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Use the dev-mode LDAP host for ERS in DEBUG mode.

pgHost switches to options.Hostname only when !devMode, but buildEntityResolutionConfig always receives options.Hostname, so in-process PLATFORM_IMAGE=DEBUG runs point LDAP-backed ERS at the remote platform host instead of localhost:<mapped LDAP port>. Apply the same local-dev flag as pgHost and pass that LDAP host into ERS config.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests-bdd/cukes/steps_localplatform.go` around lines 537 - 541, Update the
ERS configuration call through buildEntityResolutionConfig to use the same
devMode-dependent local host selection as pgHost: use localhost in DEBUG/dev
mode and options.Hostname otherwise, ensuring in-process LDAP-backed ERS
connects to the mapped local LDAP endpoint.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests-bdd/cukes/steps_ers.go`:
- Around line 111-153: Add a direct unit test in steps_ers_test.go for
buildEntityResolutionConfig, covering provider connection construction and
mapping-strategy YAML parsing/merging. Include malformed YAML to verify the
returned error and a key-collision case to validate the intended merge behavior,
keeping the test focused on this helper rather than the full BDD stack.

In `@tests-bdd/cukes/steps_localplatform.go`:
- Line 587: Update the os.WriteFile call in the rendered opentdf.yaml setup to
use restrictive 0o600 permissions when ersConfig.AutoWireLDAP embeds the LDAP
bind password, while preserving the existing permissions for configurations
without secrets.

---

Outside diff comments:
In `@tests-bdd/cukes/steps_localplatform.go`:
- Around line 537-541: Update the ERS configuration call through
buildEntityResolutionConfig to use the same devMode-dependent local host
selection as pgHost: use localhost in DEBUG/dev mode and options.Hostname
otherwise, ensuring in-process LDAP-backed ERS connects to the mapped local LDAP
endpoint.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 69c2457f-b10f-4428-9bc6-69068ba8bf90

📥 Commits

Reviewing files that changed from the base of the PR and between 39ee26b and 41e53ee.

📒 Files selected for processing (5)
  • tests-bdd/README.md
  • tests-bdd/cukes/steps_ers.go
  • tests-bdd/cukes/steps_localplatform.go
  • tests-bdd/features/multi-strategy-ers.feature
  • tests-bdd/platform_test.go

Comment thread tests-bdd/cukes/steps_ers.go
Comment thread tests-bdd/cukes/steps_localplatform.go
jrschumacher
jrschumacher previously approved these changes Jul 23, 2026
@policy-bot-opentdf
policy-bot-opentdf Bot dismissed jrschumacher’s stale review July 23, 2026 20:18

Invalidated by push of 7148586

khvirtru and others added 8 commits July 24, 2026 10:15
Add end-to-end BDD tests that validate multi-strategy entity resolution
through the full gRPC stack (SDK → Connect RPC → platform → ERS → LDAP),
catching serialization bugs at the gRPC/structpb boundary that direct-call
integration tests miss.

- 3 scenarios: PERMIT for matching department, DENY for non-matching,
  PERMIT for different department value
- LDAP testcontainer step using osixia/openldap with existing LDIF fixtures
- Multi-strategy platform template with Claims + LDAP providers
- LDAPPort propagation in @stateless scenario context

DSPX-4100

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Ken Ho <kho@virtru.com>
Add getting started guide, architecture diagram, key files reference,
and implementation notes for the multi-strategy ERS BDD tests.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Ken Ho <kho@virtru.com>
Ensure the LDAP testcontainer is terminated if Host() or MappedPort()
fail after the container has started, preventing leaked containers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Ken Ho <kho@virtru.com>
Extract magic numbers to constants and use errors.New for static error
strings to satisfy mnd and perfsprint linters.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Ken Ho <kho@virtru.com>
Add language tag to architecture diagram fence and blank lines before
code blocks to satisfy markdownlint.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Ken Ho <kho@virtru.com>
Replace the external platform.multi_strategy_ers.template with inline
ERS configuration step definitions using Gherkin DocStrings. Mapping
strategies, providers, and conditions are now visible directly in the
feature file, making tests self-documenting per review feedback.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Ken Ho <kho@virtru.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Ken Ho <kho@virtru.com>
@khvirtru
khvirtru force-pushed the test/multi-strategy-ers-cukes branch from 7148586 to 68e2413 Compare July 24, 2026 14:31

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
tests-bdd/cukes/steps_localplatform.go (1)

587-587: 🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win

File containing plaintext LDAP bind password is written world-readable.

os.WriteFile(tempFileName, renderedBytes, os.FileMode(0o755)) still uses 0o755 even though, when ersConfig.AutoWireLDAP is set, renderedBytes now embeds the plaintext LDAP bind password (admin123). This was flagged in a prior review and remains unaddressed.

🔒 Proposed fix
-	err := os.WriteFile(tempFileName, renderedBytes, os.FileMode(0o755)) //nolint:mnd // mkdir dir
+	err := os.WriteFile(tempFileName, renderedBytes, os.FileMode(0o600)) //nolint:mnd // mkdir dir
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests-bdd/cukes/steps_localplatform.go` at line 587, Update the os.WriteFile
call in the temporary-file setup to use restrictive permissions when
renderedBytes may contain the plaintext LDAP bind password, especially when
ersConfig.AutoWireLDAP is enabled; do not leave the file world-readable or
executable, while preserving the existing file-writing behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests-bdd/cukes/steps_localplatform.go`:
- Around line 561-585: Update the buildEntityResolutionConfig call in the
ersConfig patching block to pass the already computed devMode-aware pgHost
instead of options.Hostname, preserving localhost for devMode and the
compose-reachable hostname otherwise.

---

Duplicate comments:
In `@tests-bdd/cukes/steps_localplatform.go`:
- Line 587: Update the os.WriteFile call in the temporary-file setup to use
restrictive permissions when renderedBytes may contain the plaintext LDAP bind
password, especially when ersConfig.AutoWireLDAP is enabled; do not leave the
file world-readable or executable, while preserving the existing file-writing
behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: dab3c35a-4c4e-47df-a0bd-e764aecba86e

📥 Commits

Reviewing files that changed from the base of the PR and between 41e53ee and 68e2413.

📒 Files selected for processing (7)
  • tests-bdd/README.md
  • tests-bdd/cukes/glue_platform.go
  • tests-bdd/cukes/steps_ers.go
  • tests-bdd/cukes/steps_ldap.go
  • tests-bdd/cukes/steps_localplatform.go
  • tests-bdd/features/multi-strategy-ers.feature
  • tests-bdd/platform_test.go

Comment thread tests-bdd/cukes/steps_localplatform.go
@jrschumacher
jrschumacher enabled auto-merge July 24, 2026 15:29
@jrschumacher
jrschumacher added this pull request to the merge queue Jul 24, 2026
Merged via the queue into opentdf:main with commit cbb141a Jul 24, 2026
46 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants