aglinxinyuan opened a new pull request, #7800:
URL: https://github.com/apache/texera/pull/7800

   ### What changes were proposed in this PR?
   
   Three test-only fixes. **45 insertions, 9 deletions across 3 spec files; 
`git diff -- '*/src/main/*'` is empty.**
   
   ### 1. A leaked file handle was aborting the operator suite and killing the 
module's coverage run
   
   The exact mechanism, established by instrumenting the run rather than by 
inspection: in `"create LargeBinary when reading file with LARGE_BINARY type"`, 
`createTuplesFromFile` throws mid-`map` with `IllegalStateException: 
LargeBinaryManager.create() requires a base URI, but none was set on the 
current thread`. That abandons the `AutoClosingIterator` before exhaustion, so 
its close-on-exhaustion hook never fires. `afterAll` then fails with 
`test_large_binary.txt: The process cannot access the file because it is being 
used by another process`, aborting the suite.
   
   The blast radius is the whole module:
   
   | | before | after |
   |---|---|---|
   | Suites | 289 completed, **1 aborted** | **290 completed, 0 aborted** |
   | sbt exit | 1 | **0** |
   | jacoco report | **no report directory emitted** | `jacoco.xml`, 1.8 MB |
   | Tests | 2301 succeeded | 2301 succeeded |
   
   So `WorkflowOperator/jacoco` could not produce coverage for *any* file in 
the module on Windows. POSIX `unlink` masks this on Linux CI.
   
   **The fix is in the test**: the read is wrapped so the iterator is drained 
in a `finally`, firing the close hook on both the success and failure paths. 
`AutoClosingIterator` and `createTuplesFromFile` are untouched — the leak is a 
test that stops early, not a broken production contract.
   
   Also worth recording: the `.zip` fixture was stranded too. It only *looked* 
fine because `.gitignore:10` is `*.zip`; `afterAll` never reached it, because 
the `.txt` delete threw first.
   
   ### 2. `IntervalOpExecSpec` is now deterministic
   
   It imported `scala.util.Random.{nextInt, nextLong}` and used them at four 
sites — input ordering twice, a 1k-row dataset, and the interval constant — so 
`IntervalJoinOpExec`'s coverage footprint drifted between runs of identical 
source (CI has reported 2 missed + 14 partial where a local run gave 0 + 13).
   
   Now a fixed `Seed`, with a fresh `new Random(Seed)` created at each use site 
so determinism does not depend on test execution order either. No assertion 
changed.
   
   Verified rather than assumed: instrumented to print every generated input, 
two runs produced byte-identical output (22 lines, empty `diff`), and **two 
full `WorkflowOperator/jacoco` runs now give byte-identical 
`IntervalJoinOpExec` counters and all 110 per-line entries.**
   
   One observation left alone as out of scope: the 1k test deterministically 
yields 0 matches, because random 64-bit longs essentially never fall inside a 
sub-1000-wide window, so `outputTuples.size == bruteForceResult` is `0 == 0`. 
That was equally true before this change.
   
   ### 3. `PveResourceSpec`'s traversal assertion said something it did not test
   
   `getPythonBin(testCuid, "..") shouldBe None` appeared to pin the guard at 
`PveManager.scala:91`, but `".."` **matches** the name regex on line 88 
(`^[A-Za-z0-9._-]+$` admits dots), and `<VenvRoot>/<cuid>/../pve` normalizes to 
`<VenvRoot>/pve` — still under root. The `None` came from the `Files.exists` 
check on line 92.
   
   **Proven, not argued:** deleting line 91 produced results identical to 
baseline (43 run, 37 succeeded, 6 failed, 1 canceled) and the traversal test 
still **passed**. Nothing in the spec detects that guard's removal. The 
production file was reverted afterwards.
   
   Split into two honest cases:
   - `"reject pveNames containing a path separator"` keeps `"../../../etc"` and 
`"foo/bar"` — both carry a `/`, so they genuinely pin the **name regex**.
   - `"return None for a dot-only pveName, which has no venv"` keeps the `".."` 
case and pins what it actually pins: a name with no venv on disk yields `None`.
   
   A comment records that line 91 is **unreachable by construction** — the 
regex forbids `/` and `cuid` is an `Int` — so it is defensive code rather than 
untested code. The guard is left in place; removing it is a production 
decision, not a test one.
   
   ### Verification
   
   - Full `WorkflowOperator/jacoco`: **290 suites, 0 aborted, 2301 tests 
succeeded, sbt exit 0**, report emitted.
   - `PveResourceSpec`: 44 run, 38 succeeded — both reshaped tests pass. The 6 
failures are pre-existing and environmental (the mock fabricates `bin/python` 
while `PveManager` looks for `Scripts/python.exe` on Windows); baseline shows 
the identical 6.
   - `git diff -- '*/src/main/*'` is empty; no stranded fixtures (checked with 
`git status --ignored`).
   - Lint green: `WorkflowOperator/Test/scalafmtCheck`, 
`WorkflowOperator/scalafixAll --check`, 
`WorkflowExecutionService/Test/scalafmtCheck`, 
`WorkflowExecutionService/scalafixAll --check`.
   
   ### One further defect found, deliberately not fixed here
   
   The same `FileScanSourceOpExecSpec` test wraps its assertions in `catch { 
case e: Exception => info(...) }`. ScalaTest's `TestFailedException` extends 
`Exception`, and `info` output is invisible under this build's `-u`-only 
reporter (`build.sbt:37`) — so **that test currently cannot fail**. Narrowing 
the catch (or using `cancel`/`assume`) would make it a real test again, but it 
needs care about how `LargeBinaryManagerSpec` binds a base URI, so it does not 
belong in this change.
   
   ### Any related issues, documentation, discussions?
   
   Closes #7799
   
   ### How was this PR tested?
   
   ```
   sbt "WorkflowOperator/jacoco"
   ```
   
   ```
   [info] Suites: completed 290, aborted 0
   [info] Tests: succeeded 2301, failed 0, canceled 0, ignored 0, pending 2
   ```
   
   ### Was this PR authored or co-authored using generative AI tooling?
   
   Generated-by: Claude Code (Opus 5)
   


-- 
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]

Reply via email to