feat(deltagraph): Bolt e2e boot test + QUICKSTART docs (Phase 4.3)#337
Conversation
Ships Phase 4.3 of the DeltaGraph plan — automated regression coverage
that the deltagraph server boots end-to-end in Databricks mode and
exposes the Bolt protocol unchanged, plus a manual Neo4j Browser
walkthrough that turns this into the user-promised killer demo.
**Test (tests/rust/bin/deltagraph_bolt_e2e.rs)**
Spawns the actual `deltagraph` subprocess against a wiremock Databricks
endpoint, waits up to 10s for the Bolt port to bind, then completes
the Bolt v5 handshake (4-byte magic + 4 version slots → server picks a
version). Asserts the server returned a non-zero version. Proves:
1. server::run_with_config's Databricks dispatch actually builds an
executor from DATABRICKS_* env vars,
2. HTTP + Bolt servers boot to a listening state — no ClickHouse-
specific init was tripped by mistake,
3. Bolt protocol negotiation works against a Databricks-backed
AppState — the listener is wired, not just bound.
Driving an actual RUN/PULL query through Bolt is deferred to a
follow-up (would require neo4rs as a dev-dep); the current scope is
the cheapest credible regression net for "deltagraph boots + speaks
Bolt." Runs in ~110ms on a developer laptop.
To support the test, build_databricks_config in src/server/mod.rs now
reads an optional DATABRICKS_BASE_URL env var that redirects the
executor's HTTP client at the wiremock URL. Production users leave it
unset; documented in-source as test-only.
**Docs (docs/deltagraph/QUICKSTART.md)**
End-user walkthrough: build deltagraph with --features databricks,
configure DATABRICKS_HOST/WAREHOUSE_ID/TOKEN (token is env-only — never
a flag), point Neo4j Browser at bolt://localhost:7687, run sample
Cypher (count, top followers, friends-of-friends VLP), inspect the
generated Spark SQL via --sql-only or `cg`, troubleshoot the most
common failure modes.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Adds end-to-end regression coverage and user-facing documentation for DeltaGraph (the deltagraph binary in databricks mode), ensuring the server boots with a Databricks-backed AppState and exposes a functioning Bolt listener.
Changes:
- Introduces a new Rust integration test that spawns
deltagraph, waits for the Bolt port, and completes the Bolt handshake. - Extends Databricks config resolution to support a test-oriented
DATABRICKS_BASE_URLoverride (to redirect executor HTTP to wiremock). - Adds a DeltaGraph QUICKSTART guide for building, configuring, and using Neo4j Browser +
cgwith Databricks.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
| tests/rust/bin/deltagraph_bolt_e2e.rs | New Bolt-level boot/handshake e2e test for the deltagraph binary in Databricks mode. |
| src/server/mod.rs | Adds optional DATABRICKS_BASE_URL env override when building DatabricksConfig. |
| docs/deltagraph/QUICKSTART.md | New end-user quickstart for DeltaGraph (build, env vars, Browser demo, troubleshooting). |
| Cargo.toml | Registers the new deltagraph_bolt_e2e test target (gated on databricks). |
| // Use unusual port range to avoid colliding with a dev server on the | ||
| // default 7475/7687. If a parallel test invocation needs different | ||
| // ports, factor this into an allocator — for one test this is fine. | ||
| const HTTP_PORT: u16 = 17_475; | ||
| const BOLT_PORT: u16 = 17_687; | ||
|
|
| // Magic + propose [5.4, 5.0, 4.4, 0] — `deltagraph` advertises | ||
| // through Bolt 5.x, so 5.4 should win. The fallback slots let an | ||
| // older server (or a future one with narrower support) still pick | ||
| // something rather than rejecting outright. | ||
| let mut preamble = vec![0x60u8, 0x60, 0xB0, 0x17]; | ||
| preamble.extend_from_slice(&0x0000_0504u32.to_be_bytes()); // 5.4 | ||
| preamble.extend_from_slice(&0x0000_0500u32.to_be_bytes()); // 5.0 | ||
| preamble.extend_from_slice(&0x0000_0404u32.to_be_bytes()); // 4.4 | ||
| preamble.extend_from_slice(&0u32.to_be_bytes()); // empty |
| impl Drop for ChildGuard { | ||
| fn drop(&mut self) { | ||
| if let Some(mut child) = self.0.take() { | ||
| let _ = child.start_kill(); |
| // Test-only override for the executor's request base URL. Honored | ||
| // by the executor (`DatabricksConfig.base_url`) and used by the | ||
| // deltagraph subprocess test in tests/rust/bin/ to redirect HTTP | ||
| // at a wiremock URL. Production callers leave this unset — the | ||
| // executor falls back to `https://{hostname}`. | ||
| cfg.base_url = std::env::var("DATABRICKS_BASE_URL").ok(); |
| against Databricks for now — embedded chdb is the write target. Phase 5 | ||
| may add limited write support via `INSERT INTO` for Delta tables. |
All five inline comments addressed:
1. **Dynamic ports** (tests/rust/bin/deltagraph_bolt_e2e.rs): the
subprocess test now picks free ports via `TcpListener::bind("127.0.0.1:0")`
instead of hard-coding 17475/17687, eliminating collision with
deltagraph_smoke.rs and with a developer's local server on the same
ports. Comment acknowledges the small bind-race.
2. **Wider Bolt version proposal** (same file): handshake now offers
5.8/5.7/5.6/4.4 instead of 5.4/5.0/4.4. Tracks the server's
SUPPORTED_VERSIONS head; stays forward-compatible if older minors
are pruned.
3. **ChildGuard reaps on Drop** (same file): when Drop fires on a
panic, the guard now spawns a detached tokio task that calls
child.wait().await after start_kill(). Without this, the kernel
keeps a zombie entry until the test process exits, briefly holding
the ports. Documented why Handle::try_current is needed (Drop may
run post-runtime).
4. **DATABRICKS_BASE_URL scheme validation** (src/server/mod.rs): a
typo'd override would otherwise POST the PAT in plaintext to
whatever endpoint is named. The new validate_databricks_base_url
accepts https:// unconditionally and http:// only for loopback
(localhost / 127.0.0.1). Any successful override also emits a
log::warn! so a stray production setting can't be silent. Adds 4
unit tests covering accept / reject / unknown-scheme cases.
5. **QUICKSTART writes section** (docs/deltagraph/QUICKSTART.md):
removed the speculative Phase 5 INSERT INTO claim. The plan
doesn't promise write support; the wording is now a neutral
"not on the current roadmap, no committed timeline" pointer to
DELTAGRAPH_PLAN.md.
Re-requesting Copilot review per the HOUSE RULE (5 comments
≥ 5 → re-review required, not direct merge).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
@copilot please re-review — all 5 inline comments addressed in 47f1a94:
|
All 5 changes verified in commit
Test results:
|
Summary
Ships Phase 4.3 of the DeltaGraph plan — automated regression coverage that
deltagraphboots end-to-end in Databricks mode and exposes Bolt unchanged, plus a manual Neo4j Browser walkthrough that turns this into the user-promised killer demo.What ships
Automated test (
tests/rust/bin/deltagraph_bolt_e2e.rs):Spawns the real
deltagraphsubprocess against a wiremock Databricks endpoint, waits up to 10s for the Bolt port to bind, then completes the Bolt v5 handshake (4-byte magic + 4 version slots → server picks a version). Proves:server::run_with_config's Databricks dispatch actually builds an executor fromDATABRICKS_*env varsdatabricks=trueAppStateRuns in ~110ms on a developer laptop.
Server change (
src/server/mod.rs):build_databricks_confignow reads an optionalDATABRICKS_BASE_URLenv var that redirects the executor's HTTP client at a wiremock URL. Documented in-source as test-only; production users leave it unset.Docs (
docs/deltagraph/QUICKSTART.md): end-user walkthrough — build with--features databricks, configureDATABRICKS_HOST/WAREHOUSE_ID/TOKEN(token is env-only — never a flag), point Neo4j Browser atbolt://localhost:7687, run sample Cypher (count, top followers, friends-of-friends VLP), inspect generated Spark SQL via--sql-onlyorcg, troubleshoot common failures.What's deferred to a follow-up
Driving an actual RUN/PULL query through Bolt end-to-end would require
neo4rsas a dev-dep (+ its tokio/tower/h2 transitive tree). The current scope is the cheapest credible regression net for "deltagraph boots + speaks Bolt"; the next natural step is a query-level e2e that asserts aMATCH (u) RETURN ...round-trips through Bolt to wiremock withcollect_list(in the SQL body.Tests
Test plan
cargo build --bin deltagraph --features databricksproduces working binarycargo test --features databricks --test deltagraph_bolt_e2e— Bolt handshake passescargo test --features databricks --test deltagraph_bin— existing smoke tests unaffectedcargo clippy --all-targets— 0 warnings, both feature flavorscargo fmt --all --checkclean🤖 Generated with Claude Code