Repository navigation
Description
Describe the bug
tests/analysis/java/test_jcodeanalyzer.py::test_get_all_entrypoint_methods_in_application failed on assert len(entrypoint_methods) > 0 during one full release-gate run, while the runs either side of it were green and the file passes 44/44 in isolation.
This matters more than an ordinary flake: .github/workflows/release.yml deletes the tag when the gate fails (#306), so a spurious red does not merely annoy, it kills a release that was otherwise fine. The first v2.0.0-rc.2 tag was already lost once to a genuine failure; a flake costs the same tag.
To Reproduce
Not stated in the original issue.
Expected behavior
- The three real-analyzer tests in
test_jcodeanalyzer.pyno longer depend on cache state left by any other test - The full gate run ten times without a spurious failure, or the trigger identified and named
Additional context
What is established
- Not reproducible by repetition. Three consecutive
tests/analysis/javaruns:129 passed, 14 skippedeach time. So the Java suite alone does not poison itself. - Not an ordering effect.
pytest-randomlyis not installed, so collection order is stable between runs. - Seen only inside a full-suite gate run, which is what makes a shared-state trigger the leading hypothesis rather than the test's own logic.
- The shape fits. The test constructs a real
JCodeanalyzerover the unzipped daytrader8 fixture witheager_analysis=False, so it reuses whateveranalysis.jsonis already cached rather than re-running the analyzer. An empty entrypoint map is exactly what reading a stale, partial or foreign cache would produce. Three tests in the file share that shape.
Not yet established: which other test leaves the cache in that state, and whether an interrupted analyzer run can leave a partial analysis.json behind that the level check still accepts.
Scope boundary
In scope: making these tests independent of cache state — a per-test cache directory, or a mocked analyzer where the test is about the accessor rather than the analyzer.
Out of scope: the check_exisiting_analysis_file_level reuse logic itself, unless the investigation shows a partial file passes it.
Already fixed on an unmerged branch, but not where it currently ships
Leg 3a (#310) rewrites this file: every test drives a mocked analyzer with analysis_json_path=tmp_path, so no test touches a shared cache and the shape is gone. But the TypeScript release (rc.3) lands before Java 3a, so the branch that ships next still carries the flaky version. Either land a minimal fix on release/2.0 first, or accept a re-tag risk on rc.3 knowingly.
Activity
rahlk commentedon Sep 6, 2026
Fixed by #347, which rewrote the file this issue is about. No separate change is needed, provided #347 merges before the next release — which is the plan.
Why the shape is gone. The three tests that could see a poisoned cache built a real
JCodeanalyzerover the shared daytrader8 fixture witheager_analysis=False, so they reused whateveranalysis.jsonwas already on disk. On the leg-3a branch that file drives a mocked analyzer withanalysis_json_path=tmp_pathper test:release/2.0Three constructions on the branch still pass no explicit cache directory, and all three are safe: one is inside the mocked-subprocess helper, and the other two assert a raise before any analyzer runs.
Coverage was not simply deleted. The entrypoint accessors are still exercised by
test_java_analysis.py::test_get_entry_point_classesand::test_get_entry_point_methods,test_jcodeanalyzer.py::test_entry_points, the multi-application scope audit, andtest_java_neo4j_backend.py::test_entrypoint_parityagainst the live graph.Verified rather than reasoned. Five consecutive full release-gate runs on the leg-3a branch:
Identical every time. The flake appeared once in three runs on the old code, so five clean runs is not proof of absence, but combined with the cause being structurally removed it is enough to stop treating it as a release risk.
Leaving this open until #347 merges, since until then
release/2.0still carries the flaky version.