test(client): Plan 3 — remote (wiremock) + syncer integration coverage#17
Conversation
Code Review — Plan 3: Remote + Syncer Integration CoverageOverall this is a well-structured PR. The test architecture is sound (real SQLite, real Chunker, wiremock for the HTTP layer), the coverage is meaningful, and the drive-by clippy cleanups are legitimate. A few concerns worth addressing before merge. Blocking / worth discussing
The test deliberately delays the mock response by #[ignore = "deliberately waits for REQUEST_TIMEOUT_SECS (~60 s); run with -- --ignored"]
#[tokio::test]
async fn poll_treats_client_timeout_as_ok() { ... }The behavior is load-bearing and worth keeping, but gating CI on a wall-clock sleep is not a good trade. Multipart body in The hand-assembled multipart body is: Per RFC 2046 §5.1.1, the Non-blocking but worth noting
Every syncer test uses: let chunker_arc = Arc::new(Mutex::new(&mut base.chunker));This wraps a mutable reference (not the owned value) in Arc<Mutex<>>. It works for single-threaded async since the borrow is scoped to the test frame, but it's surprising — Missing error-path tests for single-chunk
There's Minor: Several test helpers pass Minor: local A few tests import What's done well
The 60-second unignored test and the multipart CRLF question are the two items I'd want resolved before merge. Everything else is minor polish. |
|
@claude let's address these review items |
|
Claude finished @dubadub's task in 11m 26s —— View job Addressing Review Items — Done ✓All review items addressed in commit Blocking (resolved)
Non-blocking (all addressed)
5 files changed: |
Three warnings predate Plan 3 (two on main, one introduced in Plan 1). All three sit in test code (#[cfg(test)] mod tests in models.rs and connection_tests.rs in tests/). Fixing them here so Plan 3's full-suite gate (-D warnings) is honest. No production behavior change.
Blocking fixes: - Add #[ignore] to poll_treats_client_timeout_as_ok (60s wall-clock test was running unignored in default suite) Non-blocking fixes: - Change Arc<Mutex<&mut Chunker>> → Arc<Mutex<Chunker>> in syncer.rs, lib.rs, and syncer_tests.rs; syncer::run now takes owned Chunker - Change registry::create/delete params from &Vec<T> to &[T] (idiomatic Rust API); update all test callsites from &vec![...] to &[...] - Add upload_maps_401_to_unauthorized and upload_maps_5xx_to_unknown tests - Add upload_batch_maps_5xx_to_unknown test (missing alongside 401 test) - Add check_upload_once_propagates_unauthorized_from_commit syncer test Style fixes: - Move all per-test `use` statements to module level in remote_tests.rs and syncer_tests.rs - Remove unnecessary `mut` from `let mut base` bindings where chunker is moved (not mutably borrowed) into Arc<Mutex<>> CRLF verified: process_part strips trailing 2 bytes (part.len() - 2) so b"hello" and b"Eggs\n" assertions are correct as written. Co-authored-by: Alex Dubowski <dubadub@users.noreply.github.com>
43169dc to
c3d1268
Compare
Code Review - Plan 3 (post-fix pass)Prior review items have all been addressed in commit A few small items remain worth cleaning up before merge. Minor: style consistencyThe two new tests added at the bottom of registry::create(conn, &vec![sample_create("gone.cook", 10, 1)]).expect("create");
registry::delete(conn, &vec![sample_delete(sample)]).expect("delete");
registry::create(conn, &vec![form]).expect("create");These should be slice literals: Minor: coverage gapThere is Nit: brittle body assertion in tombstone testIn .and(body_string_contains("chunk_ids=&")) // empty chunk_ids, followed by next fieldThis is sensitive to form-field ordering; if What is in good shape
The |
Summary
Stacked on #16. Plan 3 of the test coverage initiative: integration coverage for
client/src/remote.rsdriven bywiremock, and forsyncer::check_upload_once/check_download_oncedriven by a real SQLite pool + realChunker+wiremockposing as the remote. Also absorbs three follow-ups deferred from the PR #16 review.23 new client tests; full client suite (~112 tests) green; clippy clean under
-D warnings.remote_tests.rs(17 tests) — everyRemotemethod × happy/401/5xx, pluspoll's timeout-as-Ok semantics anddownload_batchmultipart streaming.syncer_tests.rs(7 tests) — upload happy + NeedChunks → upload_batch + tombstone short-circuits hashify; download apply + tombstone + empty-list noop + Unauthorized propagation.registry_tests.rs(+2) — tombstone surfaced byupdated_locally;latest_jidreturnsOk(0)forSome(0).indexer_tests.rs(+1) —check_index_onceon empty dir is a no-op.common::ClientBasehelper — bundles pool + tempdir + chunker for syncer tests.Drive-by clippy cleanup
One commit (
b2a94e6) fixes 3 pre-existing clippy warnings in test code (#[cfg(test)] mod testsblocks inclient/src/models.rsandclient/tests/connection_tests.rs). Two of the three predate Plan 1; one was introduced by Plan 1'sconnection_tests.rs. No production runtime code is touched. Plan 3's verification gate requires-D warningsto be clean, so this cleanup is a prerequisite.Spec deviation note
Plan Task 17 Step 3 expects
git diff --stat main..HEAD -- client/src/to be empty. The cleanup commit changesclient/src/models.rs(test code only). Treated as honest reconciliation of the plan's "0 warnings" gate vs the "noclient/src/changes" gate, since the offending lines are inside#[cfg(test)] mod testsand never compile into the library binary.Plan document
docs/superpowers/plans/2026-04-15-test-coverage-plan-3-remote-syncer.md(commitcf5d225, also onmain).Stacked PR notes
test-coverage-plan-2(PR test(client): Plan 2 — registry + indexer integration coverage #16). Merge that first, or re-target this PR tomainafter test(client): Plan 2 — registry + indexer integration coverage #16 merges.Test plan
cargo test -p cooklang-sync-client -- --test-threads=4— 112 passed, 0 failed, 1 ignoredcargo clippy -p cooklang-sync-client --tests -- -D warnings— cleandownload_batchtestspoll_treats_client_timeout_as_oktest (currently unignored — pinning load-bearing download-loop behavior)