2323| Decision | Rationale |
2424| ---| ---|
2525| Crate at repo root (not ` libraries/test-utils/ ` ) | Standalone repo; path matches dora monorepo only when merged upstream |
26- | ` arrow = "53" ` | Matches the Arrow version DORA uses for inter-node data |
27- | ` tokio ` for mock channels | ` mpsc ` channels replace daemon socket; same runtime as DORA |
26+ | ` arrow = "58" ` | Matches the Arrow version DORA uses for inter-node data (upgraded from 53 in Week 2) |
27+ | ` flume ` for output capture | ` TestingOutput::ToChannel ` uses flume; same channel crate DORA uses internally |
28+ | ` tokio ` for mock channels | Mock types use ` tokio::sync::mpsc ` channels; same runtime as DORA |
2829| Stub-only (no real impl yet) | Week 1–2 scope is design + scaffold; implementation starts Week 3 |
29- | ` dora-node-api ` NOT yet a dependency | Need to confirm the exact git rev / crate name with mentor before wiring up |
30+ | ` dora-node-api ` pinned to ` 45436aad ` | Confirmed with mentor; locked to specific commit for reproducibility |
3031
3132---
3233
3637
3738- [x] ** Clone & audit DORA source** at ` dora/ ` (commit 45436aad)
3839- [x] ** Post mentor discussion** with 4 questions in GitHub Discussions
39- - [x] ** Update Cargo.toml** with ` dora-node-api ` = { git = "...", branch = "main " }
40+ - [x] ** Update Cargo.toml** with ` dora-node-api ` = { git = "...", rev = "45436aad " }
4041- [x] ** Implement MockOutputSender** (complete with unit tests)
4142 - [x] ` MockOutputSender::send(output_id, ArrayData) -> Result<()> ` ✅
4243 - [x] ` OutputCollector ` buffer & indexing by output_id ✅
5051- [x] ** Cargo.toml adjustments**
5152 - [x] Upgrade Arrow from 53 → 58 (matches DORA main branch)
5253 - [x] Add futures = "0.3" for Stream trait compatibility
53- - [x] ** NodeHarness::new() skeleton implemented** (2026-06-07)
54- - [x] Calls ` DoraNode::init_testing() ` with ` TestingInput::Input(...) ` + ` TestingOutput::ToWriter(sink()) `
55- - [x] Stores ` (DoraNode, EventStream) ` + mock channel handles (` input_tx ` , ` output_collector ` )
56- - [x] ` send_input ` / ` tick ` / ` recv_output ` / ` run_to_completion ` remain ` todo!() ` (Week 3)
57- - [x] ` #[allow(dead_code)] ` on fields — intentionally unused at skeleton stage
54+ - [x] ** NodeHarness fully wired** (2026-06-07, rewired 2026-06-09 per mentor feedback)
55+ - [x] Calls ` DoraNode::init_testing() ` with ` TestingInput::Channel(rx) ` + ` TestingOutput::ToChannel(tx) `
56+ - [x] Both legs live: input via flume channel for runtime injection, output via flume for capture
57+ - [x] Returns ` Result<Self, NodeError> ` instead of panicking
58+ - [x] ` send_input(TimedIncomingEvent) ` implemented — pushes events through live channel
59+ - [x] ` send_stop() ` convenience method added
60+ - [x] ` tick() ` uses synchronous ` EventStream::recv() ` (blocking — consistent with ` init_testing ` )
61+ - [x] ` recv_output() ` drains flume-based output buffers (returns JSON maps per DORA format)
62+ - [x] Field order ensures clean shutdown: ` input_tx ` dropped first → unblocks daemon thread
63+ - [x] Upstream dora change: added ` TestingInput::Channel(flume::Receiver<TimedIncomingEvent>) ` variant
64+ - [x] Upstream dora change: added ` EventSource ` enum to ` IntegrationTestingEvents ` for channel support
65+ - [x] Smoke test passes: create harness → send_stop → tick → assert event received
5866- [x] ** Bug fix: MockEventStream hanging tests**
5967 - [x] ` test_mock_event_stream_multiple_events ` — drop ` tx ` before checking ` None `
6068 - [x] ` test_mock_event_stream_multiple_senders ` — drop ` tx1 ` + ` tx2 ` before checking ` None `
@@ -97,12 +105,27 @@ pub fn init_testing(
97105
98106* * EventStream : ** Implements `futures :: Stream <Item = Event >`; uses `tokio :: sync :: mpsc :: Receiver `
99107
100- ### Next : Week 3
101-
102- - [x ] * * Implement NodeHarness :: new ()** calling `DoraNode :: init_testing ()` ✅ (done Week 2 )
103- - [ ] * * Implement send_input / recv_output / tick **
104- - [ ] * * Wire mock channels ** into the event loop (replacing pre - declared TestingInput events )
105- - [ ] * * Write end - to - end unit tests ** with real node execution
108+ ### Next : Week 3 (COMPLETED 2026 - 06 - 09 )
109+
110+ - [x ] * * Implement send_input / recv_output / tick ** ✅
111+ - [x ] `send_input (TimedIncomingEvent )` — pushes events through live flume channel
112+ - [x ] `send_stop ()` — convenience wrapper for Stop events
113+ - [x ] `tick ()` — synchronous , polls `EventStream :: recv ()`, collects outputs
114+ - [x ] `recv_output (id )` — drains output buffers ; returns `Option <Vec <Map >>`
115+ - [x ] * * Added `TestingInput :: Channel ` variant upstream ** (in vendored dora source )
116+ - [x ] `TestingInput :: Channel (flume :: Receiver <TimedIncomingEvent >)` in `integration_testing . rs`
117+ - [x ] `EventSource ` enum in `node_integration_testing . rs` — supports Vec + Channel
118+ - [x ] `check_poisoned ()` extracted as reusable helper
119+ - [x ] * * Added `NodeHarness :: send_output ()`** — delegates to `DoraNode :: send_output `
120+ - [x ] Known limitation : deadlocks if called between `tick ()` calls (event - stream prefetch blocks daemon )
121+ - [x ] * * Wrote end - to - end test ** (`tests / e2e . rs`)
122+ - [x ] `e2e_receive_input_and_stop `: send_input (Input ) + send_stop → tick ×2 → verify events
123+ - [x ] * * Fixed bugs from code review **
124+ - [x ] Typo : " Convience" → " Convenience"
125+ - [x ] `send_output `: `NodeError :: Init ` → `NodeError :: Output ` for invalid output_id
126+ - [x ] `send_output `: removed `. parse (). unwrap ()` panic , returns `Result ` instead
127+ - [x ] * * CI gates pass ** : fmt ✅ | clippy ✅ | 10 / 10 tests ✅ (6 unit + 3 smoke + 1 E2E )
128+ - [x ] * * Mentor feedback resolved ** : Option B confirmed (init_testing + Channel ), pure - mock discarded
106129
107130---
108131
@@ -143,29 +166,33 @@ pub fn init_testing(
143166
144167```
145168gsoc2026-dora-test-utils/
146- ├── Cargo.toml
169+ ├── Cargo.toml # (TEMP: path dep for TestingInput::Channel dev)
147170├── Cargo.lock
148171├── src/
149- │ ├── lib.rs # Crate docs + re-exports
150- │ ├── harness.rs # NodeHarness skeleton (init_testing wired )
172+ │ ├── lib.rs # Crate docs + status table + re-exports
173+ │ ├── harness.rs # NodeHarness (live channels, send/recv/tick )
151174│ └── mock/
152- │ ├── mod.rs # Mock module docs
153- │ ├── event_stream.rs # MockEventStream (✅ full impl + 3 tests)
154- │ └── output.rs # MockOutputSender + OutputCollector (✅ + 3 tests)
175+ │ ├── mod.rs # Mock module docs
176+ │ ├── event_stream.rs # MockEventStream (✅ full impl + 3 tests)
177+ │ └── output.rs # MockOutputSender + OutputCollector (✅ + 3 tests)
155178├── tests/
156- │ └── smoke.rs # 3 smoke tests passing
179+ │ ├── smoke.rs # 3 smoke tests (harness construction + mock pairs)
180+ │ └── e2e.rs # 1 E2E test (send_input → tick → verify events)
181+ ├── dora/ # Vendored dora source (TestingInput::Channel changes)
157182├── docs/
158- │ ├── PROGRESS.md # This file
159- │ ├── WEEK1-2_SUMMARY.md # Week 1-2 summary
160- │ └── WEEKLY_PLAN.md # Detailed weekly plan
183+ │ ├── PROGRESS.md # This file
184+ │ ├── WEEK1-2_SUMMARY.md # Week 1-2 summary
185+ │ ├── WEEKLY_PLAN.md # Detailed weekly plan
186+ │ ├── PR-REVIEW/ # Mentor PR reviews
187+ │ └── superpowers/ # Design specs + implementation plans
188+ │ ├── specs/
189+ │ └── plans/
161190├── .github/workflows/
162- │ └── ci.yml # check / test / clippy / fmt
163- ├── .claude/
164- │ └── settings.local.json # Local permissions (bypass mode)
191+ │ └── ci.yml # check / test / clippy / fmt
165192├── CLAUDE.md
166193├── README.md
167194├── LICENSE
168- └── proposal.pdf
195+ └── docs/ proposal.pdf
169196```
170197
171198---
@@ -174,29 +201,18 @@ gsoc2026-dora-test-utils/
174201
175202### 🔴 Critical Path (Blocking)
176203
177- #### Week 3 (高优先级)
204+ #### Week 3 (高优先级) ✅ COMPLETE (2026-06-09)
178205- [x] **Q1: DORA commit pin** — ✅ Locked to 45436aad (2026-06-07)
179206- [x] **Q2: init_testing() signature** — ✅ Found in dora source code
180- - [x] **Implement NodeHarness::new()** — Core entry point ✅ (done Week 2)
181- - [x] Wrap `DoraNode::init_testing(TestingInput, TestingOutput, TestingOptions)`
182- - [x] Wire up MockEventStream as event source (sender stored as `input_tx`)
183- - [x] Wire up MockOutputSender as output sink (collector stored as `output_collector`)
184- - [x] Handle async runtime (tokio) — `init_testing()` is synchronous
185- - [ ] **NodeHarness::send_input()** — Inject test events
186- - [ ] Create Event::Input from user-provided ArrayData
187- - [ ] Push to MockEventStream mpsc channel
188- - [ ] Handle input_id validation
189- - [ ] **NodeHarness::recv_output()** — Drain captured outputs
190- - [ ] Call OutputCollector::drain(output_id)
191- - [ ] Return Vec<ArrayData> or None
192- - [ ] **NodeHarness::tick()** — Drive one iteration
193- - [ ] Poll node event loop once
194- - [ ] Collect any outputs via OutputCollector::collect_pending()
195- - [ ] **End-to-end test** — Verify harness works
196- - [ ] Create node via harness
197- - [ ] Send synthetic Input event
198- - [ ] Call tick()
199- - [ ] Assert output received
207+ - [x] **Add TestingInput::Channel upstream** — ✅ Added Channel variant in vendored dora source
208+ - [x] **NodeHarness::new()** — ✅ Uses TestingInput::Channel + TestingOutput::ToChannel
209+ - [x] **NodeHarness::send_input()** — ✅ Pushes TimedIncomingEvent through live flume channel
210+ - [x] **NodeHarness::send_stop()** — ✅ Convenience wrapper
211+ - [x] **NodeHarness::send_output()** — ✅ Delegates to DoraNode::send_output (known deadlock after tick)
212+ - [x] **NodeHarness::recv_output()** — ✅ Drains output buffers by ID
213+ - [x] **NodeHarness::tick()** — ✅ Synchronous, polls EventStream::recv(), collects outputs
214+ - [x] **End-to-end test** — ✅ `tests/e2e.rs`: send_input → tick → verify Input + Stop events
215+ - [x] **Code review bugs fixed** — ✅ Typo, error variant, unwrap panic resolved
200216
201217#### Week 4 (高优先级)
202218- [ ] **NodeHarness::run_to_completion()** — Batch mode
@@ -294,7 +310,7 @@ gsoc2026-dora-test-utils/
294310| Week 1–2 API design | 7/7 deliverables | 7/7 | ✅ |
295311| Week 2 Mock impl | 6 unit + 3 smoke tests passing | 9/9 | ✅ |
296312| Week 2 NodeHarness::new() | Skeleton calling init_testing() | ✅ | ✅ |
297- | Week 3 NodeHarness core | 4 methods + E2E test | 1/5 | ⏳ |
313+ | Week 3 NodeHarness core | 6 methods (send_input/send_stop/send_output/tick/recv_output/new) + E2E test | 10/10 tests passing | ✅ |
298314| Week 5 Binaries | TestSource + TestSink | 0/2 | ⏳ |
299315| Week 11 Docs | API + Setup + Usage | 0/3 | ⏳ |
300316| **Mid-term eval (Week 12)** | MVP complete | TBD | ⏳ |
0 commit comments