fix(graph): correct TESTED_BY edge direction in tests_for queries#527
fix(graph): correct TESTED_BY edge direction in tests_for queries#527Devilthelegend wants to merge 4 commits into
Conversation
The parser stores TESTED_BY edges as source=production, target=test, but query_graph(pattern="tests_for"), get_transitive_tests, and load_flow_adjacency all traversed them in the wrong direction. The naming-convention fallback (test_<name>/Test<name>) silently masked the bug for tests following standard naming. Changes: - tools/query.py: flip tests_for branch to use get_edges_by_source + e.target_qualified - graph.py::get_transitive_tests: flip three SQL queries to select target_qualified where source_qualified = ? - graph.py::load_flow_adjacency: track production node (src) in has_tested_by so criticality scoring reflects real coverage Regression tests use unconventional test names so the naming-convention fallback cannot mask future regressions. Fixes tirth8205#515
Follow-up to the initial fix for tirth8205#515. The earlier patch updated only the tests_for query, but two other production sites and several test fixtures still assumed the inverted direction. Those bugs cancelled each other in the test suite, so the regression only surfaced after fixing the original site. Production code: - changes.py: analyze_changes() now uses get_edges_by_source() when detecting test gaps so changed production functions correctly find their TESTED_BY edges. - enrich.py: symbol enrichment now traverses TESTED_BY edges by source and reads the target qualified name to surface real test references. Test fixtures: flip source/target on TESTED_BY edges in tests/test_changes.py, tests/test_enrich.py, and tests/test_graph.py to match the canonical Production -> Test direction.
|
All 9 actual checks are green. The pending "expected" status looks like a stale required-context entry in branch protection — could you take a look when you get a chance? |
|
Thanks @Devilthelegend — thorough work. I applied and tested locally: all five inverted consumer sites are fixed (including enrich.py and load_flow_adjacency, which my own audit missed), the already-correct readers in analysis.py/build.py/review.py were rightly left alone, your three regression tests fail on main and pass with the fix, and the full suite is green (1277 passed). Since only the parser writes TESTED_BY edges, existing DBs need no migration — good that this is read-side only. One ask before merge: the producer side of the contract is still unpinned. test_parser.py::test_tested_by_edges_generated only asserts edges exist, not direction — a future parser flip would pass your new tests (they hand-insert edges) and silently reintroduce #515. Either assert source=production/target=test there, or add one end-to-end parse -> store -> get_transitive_tests test. Non-blocking: refactor.py:495-507 still reads TESTED_BY by target — inert today (shadowed by companion CALLS edges) but worth a follow-up issue. The stale "expected" status check was a branch-protection misconfiguration on my side (a required context named "CI" that no job reports) — being fixed. |
) Existing parser tests only asserted that TESTED_BY edges exist (len >= 1), not which way they point. That left a gap where the parser could silently revert to the inverted direction and every consumer-side regression test would still pass. Lock the canonical direction at the producer: source=production, target=test (reads as 'X is tested by Y'). This is the direction the parser already writes and that the consumer-side fixes in this PR now query against. Requested in maintainer review on tirth8205#527.
Summary
query_graph(pattern="tests_for")traversedTESTED_BYedges in the wrong direction. The parser stores these edges as source = production node, target = test node, but three sites in the code looked them up as if the direction were reversed:code_review_graph/tools/query.py— the MCP-facingtests_forbranch.code_review_graph/graph.py::get_transitive_tests— three SQL queries (direct match, bare-name fallback, transitive viaCALLS).code_review_graph/graph.py::load_flow_adjacency— thehas_tested_byset was populated with test nodes instead of production nodes, corrupting criticality scoring's coverage-gap detection.Because
query_graphfalls back to a naming-convention search (test_<name>/Test<name>) when no edges match, the bug was silently masked for tests following standard naming. It surfaced for users whose tests had unconventional names or whose test discovery relied on the underlying edges.Fix
Flipped the traversal direction in all three places so that for a production node
qn:source_qualified = qn.target_qualified.For
load_flow_adjacency,has_tested_by.add(src)so the set represents production nodes that have at least one test covering them — which is whatflows.compute_criticalityexpects when checking for coverage gaps.Tests
Added three regression tests that deliberately use unconventional test names (
verify_addition,verify_compute,verify_combine_behaviour) so the naming-convention fallback cannot mask future regressions:tests/test_graph.py::TestGraphStore::test_get_transitive_tests_follows_direct_tested_by_edgetests/test_graph.py::TestGraphStore::test_get_transitive_tests_follows_calls_then_tested_bytests/test_tools.py::TestQueryGraphTestsFor::test_query_graph_tests_for_finds_direct_edgeAll three pass locally. The broader
test_graph.py,test_tools.py, andtest_flows.pysuites show no real-test regressions (only pre-existing Windows SQLite teardownPermissionErrors, which affect every test in those classes).Blast radius
query_graph(pattern="tests_for")get_transitive_tests(used by review context, hints, criticality)compute_criticalitycoverage-gap detectionFixes #515