nick-boss-tech opened a new pull request, #5028: URL: https://github.com/apache/solr/pull/5028
🤖 *AI text below* 🤖 *(posted on behalf of Nick Shanin)* https://issues.apache.org/jira/browse/SOLR-18505 ## What happens today `DirectUpdateHandlerTest.testExpungeDeletes` is flaky. With seed `71E7F210A62A9B8C` it fails at the first sample with `maxDoc !> numDocs ... expected some deletions`: the duplicate add is supposed to leave the first segment holding a deleted document (maxDoc 5, numDocs 4), but the sample sometimes reads maxDoc == numDocs == 4. The failed assertion also skips the request close, and the leaked searcher makes `testDeleteRollback` and the suite teardown fail as knock-on effects. This failure fired in a Crave run on an unrelated PR and is what prompted the investigation on SOLR-18505. ## What this change does Test-only change to `testExpungeDeletes`. Root cause: the duplicate add leaves the first segment 50 percent deleted, above the class-pinned TieredMergePolicy's default `deletesPctAllowed` of 20 percent, so the policy schedules a deletion-driven merge that runs on the merge scheduler thread during the second commit; if it lands before the post-commit searcher is sampled, the deletion is already physically gone. The test now wraps the core's live merge policy in a `FilterMergePolicy` that returns no natural merges, installed before the first add and restored in a `finally` block, so no background merge can rewrite the segments between the commits and the samples. The wrapper delegates `findForcedDeletesMerges` to the live policy, so the `expungeDeletes` commit still performs the real expunge the end of the test verifies. Raising `deletesPctAllowed` instead cannot express this pin (the setter accepts at most 50, and a segment deleted exactly 50 percent still qualifies at that setting ), and `NoMergePolicy` was rejected because its `findForcedDeletesMerges` returns null, which would turn the expunge into a no-op. Both sample requests now use try-with-resources, so a future assertion failure in this test cannot leak a searcher into the next test's teardown. ## Proof The premise is timing dependent, stated plainly: during the root cause investigation on 2026-10-05, the class with seed `71E7F210A62A9B8C` failed 6 of 6 forced re-executions on unmodified main (on both sides of the PR #5001 merge), five times at the line 494 assertion and once at the second sample, and the surviving index of a failing run contains a segment whose diagnostics say `source=merge`, proving the background merge ran. Later the same day on this VM the merge lost the race and the seed passed on unmodified main, so the failure does not reproduce on demand in every environment; the fix removes the mechanism by construction rather than narrowing the race window. With this change, verified 2026-10-05 at head 1c5a948d3e4: five forced re-executions of the class with seed `71E7F210A62A9B8C` pass 7/7 each, two runs with random seeds pass 7/7 each, neighboring `MaxSizeAutoCommitTest` passes 3/3 and `DirectUpdateHandlerWithUpdateLogTest` passes 1/1, and the gate (tidy, Error Prone compile, `:solr:core:check -x test`) is green. ## Limits The test no longer covers the interaction between plain commits and deletion-driven merging; that interaction was never its intent (it is named and structured around expungeDeletes), and merge policy behavior has its own coverage elsewhere. The policy swap mutates the live writer config for the duration of the method; the restore sits in a `finally` block, and `setUp` recreates the core before every test, which bounds the effect of a missed restore. No changelog entry: this change is test-only. ### AI assistance AI agents assisted with research, implementation, review, and drafting. Nick Shanin directed the work and takes responsibility for this contribution. -- 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]
