Skip to content

test: rust differ - #543

Merged
bzp2010 merged 4 commits into
rust-nextfrom
bzp/feat-rust-test-fw
Aug 1, 2026
Merged

test: rust differ#543
bzp2010 merged 4 commits into
rust-nextfrom
bzp/feat-rust-test-fw

Conversation

@bzp2010

@bzp2010 bzp2010 commented Aug 1, 2026

Copy link
Copy Markdown
Collaborator

Description

Add a Rust differ test suite that matches the TS version test suite.

Checklist

  • I have explained the need for this PR and the problem it solves
  • I have explained the changes or the new features added to this PR
  • I have added tests corresponding to this change
  • I have updated the documentation to reflect this change
  • I have verified that this change is backward compatible

Summary by CodeRabbit

  • New Features

    • Added a Rust-based configuration differ supporting resource creation, updates, deletions, nested routes, plugins, credentials, upstreams, SSL settings, defaults, and generated identifiers.
    • Added a Rust SDK with resource metadata, event models, value comparison, and identifier generation.
    • Added a local mock Admin API server and synchronization benchmarking tools.
  • Tests

    • Added broad cross-language fixture coverage and validation for differ behavior, regressions, event ordering, and performance scenarios.
  • Chores

    • Added Rust workspace configuration and generated benchmark fixtures.

@coderabbitai

coderabbitai Bot commented Aug 1, 2026

Copy link
Copy Markdown

Review Change Stack

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 1cc9e4ef-e635-4e35-8206-f99717f9c6d8

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Changes

The pull request adds a Rust ADC SDK and a Rust Differ V4 implementation. It adds shared fixtures, integration tests, fixture comparison tools, benchmark data, a mock Admin API server, and synchronization benchmarks.

Rust Differ V4

Layer / File(s) Summary
SDK contracts and value operations
rust/crates/adc-sdk/...
Adds resource metadata, event models, field metadata, default values, ID generation, and structural JSON diffing.
Differ V4 event engine
rust/crates/adc-differ/src/differ_v4.rs, rust/crates/adc-differ/src/lib.rs
Adds resource matching, nested event generation, default merging, plugin comparison, identifier handling, and deterministic event ordering.
Differ behavior validation
fixtures/differ/*, rust/crates/adc-differ/tests/*
Adds fixtures and tests for resource changes, nested resources, defaults, plugins, credentials, upstreams, stream services, custom IDs, and event ordering.
Fixture execution and parity tooling
libs/differ/*, rust/crates/adc-differ/src/bin/run_fixtures.rs, scripts/compare-differ-fixtures.mjs, .gitignore
Adds fixture result dumping, Rust fixture execution, TypeScript/Rust output comparison, Vitest configuration, Nx wiring, and the Rust target ignore rule.
Benchmark and synchronization support
rust/Cargo.toml, rust/benches/fixtures/*, rust/crates/adc-differ/benches/*, rust/crates/adc-differ/examples/*, rust/crates/adc-mock-server/*, rust/crates/adc-sync-bench/*
Adds the Rust workspace, generated benchmark fixtures, differ benchmarks, a mock Admin API server, and an asynchronous synchronization benchmark.

Estimated code review effort: 5 (Critical) | ~120 minutes

Sequence Diagram(s)

sequenceDiagram
  participant FixtureRunner
  participant DifferV4
  participant ResourceMetadata
  participant EventOutput
  FixtureRunner->>DifferV4: Load local, remote, and default values
  DifferV4->>ResourceMetadata: Resolve resource fields and identifiers
  ResourceMetadata-->>DifferV4: Return merge and nesting metadata
  DifferV4->>DifferV4: Compute resource and nested events
  DifferV4->>EventOutput: Sort and serialize events
  EventOutput-->>FixtureRunner: Return fixture result map
Loading

Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (1 error, 1 warning)

Check name Status Explanation Resolution
Security Check ❌ Error Category 1 CRITICAL: Event serializes raw credential values and diffs; fixture tools write/print them without redaction (event.rs:24-37, run_fixtures.rs:90-93). Add field-aware redaction before result serialization and mismatch logging, and stop adc-mock-server from echoing PUT/POST bodies; retain raw secrets only for protected requests.
E2e Test Quality Review ⚠️ Warning Added Rust tests call DifferV4::diff on in-memory JSON and assert events; no test starts or calls a real/stateful API, and the mock server is only a benchmark executable. Add CI-wired E2E tests that sync create/update/delete events through the backend and verify dumped state; add invalid-input, HTTP-failure, and concurrency cases.
✅ Passed checks (4 passed)
Check name Status Explanation
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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the Rust differ test implementation, which is a central part of the changeset.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch bzp/feat-rust-test-fw

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

@bzp2010 bzp2010 changed the title Bzp/feat rust test fw test: rust differ Aug 1, 2026
@bzp2010
bzp2010 changed the base branch from main to rust-next August 1, 2026 14:53

@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: 9

🧹 Nitpick comments (2)
rust/crates/adc-differ/src/differ_v4.rs (1)

21-27: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Avoid deep-cloning DefaultValue on every recursive diff call.

DifferV4::diff clones the whole DefaultValue into the new differ instance. handle_delete, handle_create, and handle_update call DifferV4::diff again for each resource item, so the clone repeats once per item that has nested fields. For a config with many services and routes, this copies the full core and plugin default maps many times. Hold a borrow or a Cow instead.

♻️ Proposed refactor using a borrowed default value
-pub struct DifferV4 {
-    default_value: DefaultValue,
-}
+pub struct DifferV4<'a> {
+    default_value: std::borrow::Cow<'a, DefaultValue>,
+}
 
-impl DifferV4 {
+impl<'a> DifferV4<'a> {
     pub fn diff(
         local: &InternalConfiguration,
         remote: &InternalConfiguration,
-        default_value: Option<&DefaultValue>,
+        default_value: Option<&'a DefaultValue>,
         parent_name: Option<&str>,
     ) -> Vec<Event> {
-        let differ = DifferV4 { default_value: default_value.cloned().unwrap_or_default() };
+        let differ = DifferV4 {
+            default_value: default_value
+                .map(std::borrow::Cow::Borrowed)
+                .unwrap_or_else(|| std::borrow::Cow::Owned(DefaultValue::default())),
+        };
🤖 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 `@rust/crates/adc-differ/src/differ_v4.rs` around lines 21 - 27, Update
DifferV4::diff and the DifferV4 default_value field to borrow the existing
DefaultValue (or use Cow) instead of calling cloned().unwrap_or_default() on
every recursive invocation. Adjust handle_delete, handle_create, and
handle_update recursion to reuse that borrowed/default reference while
preserving the existing fallback behavior when no default value is provided.
rust/crates/adc-sdk/src/differ_meta.rs (1)

50-51: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Consider returning static metadata instead of building it per call.

differ_meta allocates a new ResourceDifferMeta on every call. strip_nested_ids in rust/crates/adc-differ/src/differ_v4.rs (lines 333-336) calls it once per candidate type for every nested field, so the cost multiplies with config size. A &'static ResourceDifferMeta per variant, or a LazyLock lookup table keyed by config_field, removes both the allocation and the linear scan.

🤖 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 `@rust/crates/adc-sdk/src/differ_meta.rs` around lines 50 - 51, Update
differ_meta to return reusable static ResourceDifferMeta instances per
ResourceType variant instead of constructing metadata on every call. Preserve
the existing variant-to-metadata mapping and adjust callers such as
strip_nested_ids to use the static reference without repeated allocation or
linear lookup.
🤖 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 `@fixtures/differ/basic.update_resource.json`:
- Around line 1-4: The generic fixture basic.update_resource.json duplicates
basic.update_resource_add_plugin.json; update basic.update_resource.json to
represent the generic update scenario or remove it if no longer needed, while
leaving the distinct add-plugin fixture unchanged.

In `@libs/differ/tools/dump-fixture-results.ts`:
- Around line 20-21: Update the fixture directory initialization near
FIXTURES_DIR to remove the machine-specific absolute fallback. Resolve the
repository’s fixtures/differ directory relative to import.meta.url, or require
ADC_DIFFER_FIXTURES_DIR when it is unset, while preserving the existing
environment-variable override.

In `@rust/crates/adc-differ/src/bin/run_fixtures.rs`:
- Around line 67-72: Update fixture discovery in the entries collection to
propagate errors from directory iteration instead of silently discarding them
via filter_map(|e| e.ok()). Make the runner fail with context identifying
fixtures_dir when an entry cannot be read, while preserving the existing JSON
path filtering and collection behavior.

In `@rust/crates/adc-differ/src/differ_v4.rs`:
- Around line 206-256: Redact ConsumerCredential secret fields before Event
values are exposed or serialized: ensure config.password and config.secret are
removed from both old_value and new_value in the differ flow around event
construction. Apply the same sanitization for create, update, and delete events,
then add fixture tests in run_fixtures.rs covering all three event types and
verifying secrets are absent from serialized output.

In `@rust/crates/adc-mock-server/src/main.rs`:
- Line 54: Update the port parsing in main so the default 18899 is used only
when no argument is supplied; when an argument is present but cannot be parsed
as u16, return a clear error instead of falling back. Preserve successful
explicit port values.

In `@rust/crates/adc-sdk/src/value_diff.rs`:
- Around line 33-52: Update every path field in the ValueDiff variants New,
Deleted, Edit, and Array with serde’s empty-vector skip rule so empty root paths
are omitted during serialization, while non-empty paths remain serialized.

In `@rust/crates/adc-sync-bench/src/main.rs`:
- Around line 113-115: Validate the benchmark arguments before loading the
fixture: update the parsing around concurrency, iterations, and runtime_flavor
to report invalid numeric input instead of unwrapping, reject zero concurrency
and iterations, and accept only “current” or “multi” runtime names. Preserve the
existing defaults for omitted arguments and ensure invalid values terminate
before fixture loading.

In `@scripts/compare-differ-fixtures.mjs`:
- Around line 94-101: Update the failure-reporting loop over failures so the TS
and normalized Rust diagnostic payloads are recursively redacted before
JSON.stringify and console.log output. Ensure credentials, authentication
headers, and event values cannot appear in terminal or CI logs; omit resource
bodies entirely if no redaction helper is available.
- Around line 19-21: Update scripts/compare-differ-fixtures.mjs to create a
unique private temporary directory per parity run, pass its TypeScript result
path to Vitest, and use its Rust result path for run_fixtures instead of fixed
/tmp filenames. Update libs/differ/tools/dump-fixture-results.ts so its output
path is required or generated as a private per-process file, never defaulting to
a shared predictable /tmp path.

---

Nitpick comments:
In `@rust/crates/adc-differ/src/differ_v4.rs`:
- Around line 21-27: Update DifferV4::diff and the DifferV4 default_value field
to borrow the existing DefaultValue (or use Cow) instead of calling
cloned().unwrap_or_default() on every recursive invocation. Adjust
handle_delete, handle_create, and handle_update recursion to reuse that
borrowed/default reference while preserving the existing fallback behavior when
no default value is provided.

In `@rust/crates/adc-sdk/src/differ_meta.rs`:
- Around line 50-51: Update differ_meta to return reusable static
ResourceDifferMeta instances per ResourceType variant instead of constructing
metadata on every call. Preserve the existing variant-to-metadata mapping and
adjust callers such as strip_nested_ids to use the static reference without
repeated allocation or linear lookup.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 1c94076d-e627-4696-9f7c-035c8f1f835a

📥 Commits

Reviewing files that changed from the base of the PR and between 9914252 and f0a8bdd.

⛔ Files ignored due to path filters (1)
  • rust/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (77)
  • .gitignore
  • fixtures/differ/basic.adapts_to_default_core_values.json
  • fixtures/differ/basic.adapts_to_default_plugin_values.json
  • fixtures/differ/basic.boolean_defaults_merged_correctly.json
  • fixtures/differ/basic.create_resource.json
  • fixtures/differ/basic.delete_resource.json
  • fixtures/differ/basic.empty_input_yields_empty_output.json
  • fixtures/differ/basic.generates_hashed_resource_id.json
  • fixtures/differ/basic.keeps_plugins_when_plugins_not_changed.json
  • fixtures/differ/basic.merges_array_nested_object_defaults_correctly.json
  • fixtures/differ/basic.route_and_stream_route_ids_generated_correctly.json
  • fixtures/differ/basic.selectively_merges_objects_in_default_values.json
  • fixtures/differ/basic.sorted_by_event_type.json
  • fixtures/differ/basic.update_resource.json
  • fixtures/differ/basic.update_resource_add_plugin.json
  • fixtures/differ/basic.update_resource_update_plugin_with_default_value.json
  • fixtures/differ/basic.updates_service_and_its_nested_route.json
  • fixtures/differ/basic.updates_service_nested_route.json
  • fixtures/differ/consumer.creates_updates_deletes_consumer_credentials.json
  • fixtures/differ/consumer.deletes_consumer_credentials_when_consumer_is_deleted.json
  • fixtures/differ/custom_id.deletes_and_creates_new_resource_when_id_changes.json
  • fixtures/differ/regression.does_not_apply_stream_service_default_to_http_service.json
  • fixtures/differ/regression.resolves_stream_service_default_type_correctly.json
  • fixtures/differ/service_upstream.creates_non_default_upstreams.json
  • fixtures/differ/service_upstream.creates_service_and_upstream.json
  • fixtures/differ/service_upstream.deletes_non_default_upstreams.json
  • fixtures/differ/service_upstream.replaces_non_default_upstreams.json
  • fixtures/differ/service_upstream.unchanged_service_with_default_and_named_upstreams.json
  • fixtures/differ/service_upstream.unchanged_service_with_only_default_upstream.json
  • fixtures/differ/service_upstream.updates_default_upstream.json
  • fixtures/differ/service_upstream.updates_non_default_upstreams.json
  • fixtures/differ/upstream.creates_and_updates_ssl_before_upstream.json
  • fixtures/differ/usecase.renames_service_with_nested_routes.json
  • fixtures/differ/usecase.selectively_merges_objects_in_default_values_on_a_service.json
  • libs/differ/package.json
  • libs/differ/tools/dump-fixture-results.ts
  • libs/differ/vitest.fixtures.config.ts
  • rust/Cargo.toml
  • rust/benches/fixtures/large.few.local.json
  • rust/benches/fixtures/large.many.local.json
  • rust/benches/fixtures/large.none.local.json
  • rust/benches/fixtures/large.remote.json
  • rust/benches/fixtures/medium.few.local.json
  • rust/benches/fixtures/medium.many.local.json
  • rust/benches/fixtures/medium.none.local.json
  • rust/benches/fixtures/medium.remote.json
  • rust/benches/fixtures/small.few.local.json
  • rust/benches/fixtures/small.many.local.json
  • rust/benches/fixtures/small.none.local.json
  • rust/benches/fixtures/small.remote.json
  • rust/crates/adc-differ/Cargo.toml
  • rust/crates/adc-differ/benches/differ_bench.rs
  • rust/crates/adc-differ/examples/gen_fixtures.rs
  • rust/crates/adc-differ/src/bin/run_fixtures.rs
  • rust/crates/adc-differ/src/differ_v4.rs
  • rust/crates/adc-differ/src/lib.rs
  • rust/crates/adc-differ/tests/basic.rs
  • rust/crates/adc-differ/tests/consumer.rs
  • rust/crates/adc-differ/tests/custom_id.rs
  • rust/crates/adc-differ/tests/fixtures_sanity.rs
  • rust/crates/adc-differ/tests/regression.rs
  • rust/crates/adc-differ/tests/service_upstream.rs
  • rust/crates/adc-differ/tests/upstream.rs
  • rust/crates/adc-differ/tests/usecase.rs
  • rust/crates/adc-mock-server/Cargo.toml
  • rust/crates/adc-mock-server/src/main.rs
  • rust/crates/adc-sdk/Cargo.toml
  • rust/crates/adc-sdk/src/differ_meta.rs
  • rust/crates/adc-sdk/src/event.rs
  • rust/crates/adc-sdk/src/field_meta.rs
  • rust/crates/adc-sdk/src/lib.rs
  • rust/crates/adc-sdk/src/resource.rs
  • rust/crates/adc-sdk/src/utils.rs
  • rust/crates/adc-sdk/src/value_diff.rs
  • rust/crates/adc-sync-bench/Cargo.toml
  • rust/crates/adc-sync-bench/src/main.rs
  • scripts/compare-differ-fixtures.mjs

Comment thread fixtures/differ/basic.update_resource.json
Comment thread libs/differ/tools/dump-fixture-results.ts
Comment thread rust/crates/adc-differ/src/bin/run_fixtures.rs
Comment thread rust/crates/adc-differ/src/differ_v4.rs
Comment thread rust/crates/adc-mock-server/src/main.rs
Comment thread rust/crates/adc-sdk/src/value_diff.rs
Comment thread rust/crates/adc-sync-bench/src/main.rs
Comment thread scripts/compare-differ-fixtures.mjs
Comment thread scripts/compare-differ-fixtures.mjs
@bzp2010
bzp2010 merged commit 6573d00 into rust-next Aug 1, 2026
2 checks passed
@bzp2010
bzp2010 deleted the bzp/feat-rust-test-fw branch August 1, 2026 15:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant