viirya commented on PR #54:
URL: 
https://github.com/apache/spark-connect-rust/pull/54#issuecomment-5419297669

   Re-reviewed after the updates. Every item I raised has been addressed, and I 
verified each one in the code rather than taking the commit messages at face 
value. Two of the fixes went further than I suggested, and one of them exposed 
a mistake in my own earlier review that I want to correct explicitly. One new 
finding at the end.
   
   ## The deselection bug — and a correction to my last comment
   
   Commit `bc33579` is the important one here. The manifest deselection **never 
matched anything**: pytest was handed an absolute test path while it emits node 
ids relative to its rootdir, so every `--deselect <abspath>::Class::test` 
silently matched nothing and the whole 65-entry manifest was void.
   
   I need to correct myself on this. My last comment said the matching was 
"exact, not substring — so a loose match can't silently swallow neighbouring 
tests," and that a malformed entry "matches nothing, meaning the test runs and 
fails loudly. That fails safe." The first half was right about the mechanism 
and the wrong conclusion to draw: *every* entry was matching nothing, so the 
property I described as a safety net was in fact the bug. I checked the 
matching logic in isolation and never asked whether it matched in practice — 
running the gate, or even just noting that a 65-entry manifest ought to change 
the failure count, would have caught it.
   
   The knock-on effect is the interesting part: once deselection worked and the 
missing `test_support/sql` fixtures were vendored, most of the manifest turned 
out to be stale. It's now **2 entries**, both with specific, checkable reasons 
(`testcat` needing `InMemoryCatalog`, a test-only class absent from the 
distribution) rather than the uniform `# reference also fails (environmental)` 
boilerplate. So the gate now genuinely exercises 63 tests it was previously 
reporting on but not really running. That's a much bigger improvement in gate 
strength than anything I asked for.
   
   ## Confirmed fixed
   
   - **Retries are scoped.** `FLAKY_FILES` (`run_official_tests.py:43-52`) is 
an explicit 7-file set — the streaming/listener/observation/transformWithState 
files — and `retries = args.retries if tf.name in FLAKY_FILES else 0` (line 
228). Everything else gets zero retries, so a non-deterministic bug outside 
those files fails the gate on first occurrence.
   - **Drift check added, and non-blocking as suggested.** Lines 263-288 re-run 
the skiplisted tests selecting only them, and report any that now pass without 
failing the gate. The comment states the rationale (the manifest "can only rot 
toward less coverage"). This is what caught the 29/31 stale entries.
   - **`stat.rs` (4) and `conf.rs` (5) now release the GIL.**
   - **Sort uses the generated enum constants** — `SortDirection::Ascending as 
i32` and the `NullOrdering` import, no more bare `1i32`.
   - **Map keys stringify to their scalar form.** A dedicated 
`map_key_to_string` (`dataframe.rs:2102`) with a comment naming the exact case: 
a `map<int,string>` key must be `"1"`, never `"Integer(1)"`.
   - **`rust_coverage.sh` no longer swallows failures** — the `|| true` is 
gone, with a comment distinguishing "exits 0 on per-op gaps" from "cannot run 
at all."
   - **The coverage-gate claim is corrected.** The description now carries an 
explicit "Coverage status (no gate enforced yet)" section saying there is 
**no** `rust-coverage` CI job and that the script is local tooling. That's the 
honest framing.
   - **Branch is rebased** onto master, so #53 is included.
   
   ## The test-quality response went further than I asked
   
   I suggested adding value assertions to `e2e_wrapper.py`. What landed is more 
than that:
   
   - `ckv(label, fn, expected)` asserts results, and its docstring names the 
failure mode it exists for (a nullary `F.struct()` returning an empty struct 
and throwing nothing). 14 call sites so far against 179 `ck`, so most of the 
wrapper is still exception-only — reasonable, since not every op has a cheap 
expected value, and `ck`'s own docstring now points readers at `ckv`.
   - More significantly, the three assertion-free `*_coverage_golden.rs` 
snapshot files were **removed** and replaced with behavioral tests that assert 
real results against a live server: `e2e_functions.rs` (24 assertions), 
`e2e_columns.rs` (37), `e2e_dataframe.rs` (25), `types_behavior.rs` (55). 
Swapping ~1,200 lines of "does not panic" for 141 real assertions is the right 
trade.
   - And they earned their keep immediately — `600c8e4` and `37c442c` fix 
`select_expr`, `to_json`, and `DataType::String.simpleString` as bugs the 
behavioral tests found. That's the difference between a coverage vehicle and a 
test suite.
   
   Separately, `ca32e8c` is a good catch that wasn't in my review at all: 
`StreamingQuery::_execute_command` and the manager equivalent sent their 
command and discarded the response stream, so `status()`/`isActive()` failed 
and `explain`/`exception`/`lastProgress`/`recentProgress`/`awaitTermination` 
all silently saw empty results. Same "result discarded" shape as the 
plan-builder family.
   
   ## New: the behavioral e2e tests don't run in CI
   
   The four new behavioral files all gate on `SPARK_REMOTE`:
   
   ```rust
   fn should_run() -> bool { std::env::var("SPARK_REMOTE").is_ok() }
   ...
   if !should_run() { return; }
   ```
   
   No workflow sets `SPARK_REMOTE` — I grepped `.github/workflows/` and there 
are no matches — so all 141 assertions currently no-op in CI. Worse, because 
the guard is an early `return` rather than `#[ignore]`, they report as 
**passed** rather than skipped, so the test count looks healthy while nothing 
is being checked.
   
   This matters more than usual given the context: these tests exist precisely 
because the proto-snapshot tests they replaced couldn't catch silently-wrong 
values, and they've already found three real bugs locally. As written they 
protect a developer who happens to have a server running, and nobody else — a 
regression in `select_expr` or `to_json` would land green.
   
   Two options, and the choice depends on how much CI time you want to spend. 
The parity job already stands up a Spark 4.2.0 Connect server, so pointing 
`SPARK_REMOTE` at it and running `cargo test -p apache-spark-connect --test 
e2e_functions --test e2e_columns --test e2e_dataframe --test types_behavior` in 
that job would be nearly free. If you'd rather not couple them, switching the 
guard to `#[ignore]` (or having `should_run()` panic when a 
`REQUIRE_SPARK_REMOTE` flag is set) would at least make the skip visible 
instead of looking like a pass.
   
   ## Smaller notes
   
   `types_behavior.rs` has 55 assertions and does not appear to need a server 
for most of them (proto/JSON round-trips, `StructType` helpers) — worth 
confirming those run unconditionally, since they'd be the portion that can 
guard CI today without any server plumbing.
   
   ## What I verified
   
   I read the updated scripts, workflows, and the changed core/binding files, 
and grepped the workflow tree for `SPARK_REMOTE`. I did not run the parity 
gate, the coverage script, or the e2e tests against a live server, so the 
claims about which tests now pass (the 29/31 stale entries, 32/32 datasources) 
I'm taking from the commit messages rather than independent confirmation.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to