Version: 2.3.8 (fresh build, not an upgraded graph)
Language: Python (Odoo 18 codebase, ~9.9k files)
Symptom
tests_for returns 0 results for symbols that are covered by tests, and whose
TESTED_BY edge is present in the graph. callers_of on the same target
returns the test, flagged is_test=True.
$ code-review-graph query tests_for "<abs>/wizard_update_invoice_supplierinfo_line.py::WizardUpdateInvoiceSupplierinfoLine._prepare_supplierinfo_update"
status: ok | result_count: 0
$ code-review-graph query callers_of "<same target>"
status: ok | result_count: 2
test_ninguna_clave_del_core_se_pierde_en_silencio tests/test_wizard_steps.py:291 is_test=True
update_supplierinfo wizard_update_invoice_supplierinfo.py:45
The information is in the graph; this query does not reach it. Silent false
negative — it reports covered code as uncovered.
Root cause
TESTED_BY edges are stored with a bare source_qualified in 64.5% of
cases (85,475 of 132,484 in this repo):
source_qualified: _prepare_supplierinfo_update
target_qualified: <abs>/tests/test_wizard_steps.py::TestWizardSteps.test_ninguna_clave...
get_transitive_tests looks up by fully-qualified name, so the direct lookup
misses. The bare-name fallback that follows is gated by
_select_evidence_backed_candidate (graph.py:720):
supported = [
qualified
for qualified, candidate_file in candidates
if candidate_file == context_file or candidate_file in imported_files
]
return supported[0] if len(supported) == 1 else None
candidate_file is an absolute file path. imported_files is built in
_candidate_for_context from IMPORTS_FROM.target_qualified, which for Python
holds dotted module names:
odoo
odoo.exceptions
odoo.addons.account.tests.common
odoo.addons.account_invoice_supplierinfo_update.wizard.wizard_update_...
Two different namespaces, compared with in. The membership test can never
succeed, supported is empty, None is returned, and every edge that depends
on the fallback is dropped by the continue.
In this repo 78.3% of IMPORTS_FROM edges (22,546 of 28,780) carry dotted
module targets; only 21.7% are file paths.
Reproduction
Any Python project where the test does not import the production symbol
directly (framework-mediated access — Odoo's self.env['model'], Django's app
registry, pytest fixtures). 2,712 symbols in this repo have TESTED_BY edges
reachable only through the bare-name fallback; all of them report 0.
Not an upgrade artifact: reproduced after a full build on 2.3.8
(9,891 files, 57,706 nodes, 547,277 edges). postprocess alone does not
change the bare-edge count either (85,438 before and after).
Related
Suggested direction
Normalize both sides before comparing: resolve dotted module targets to the
file paths of the nodes they refer to when building imported_files (the
graph already indexes those files), or store IMPORTS_FROM targets
consistently as paths. The C# fix in #799 may be directly portable.
Version: 2.3.8 (fresh
build, not an upgraded graph)Language: Python (Odoo 18 codebase, ~9.9k files)
Symptom
tests_forreturns 0 results for symbols that are covered by tests, and whoseTESTED_BYedge is present in the graph.callers_ofon the same targetreturns the test, flagged
is_test=True.The information is in the graph; this query does not reach it. Silent false
negative — it reports covered code as uncovered.
Root cause
TESTED_BYedges are stored with a baresource_qualifiedin 64.5% ofcases (85,475 of 132,484 in this repo):
get_transitive_testslooks up by fully-qualified name, so the direct lookupmisses. The bare-name fallback that follows is gated by
_select_evidence_backed_candidate(graph.py:720):candidate_fileis an absolute file path.imported_filesis built in_candidate_for_contextfromIMPORTS_FROM.target_qualified, which for Pythonholds dotted module names:
Two different namespaces, compared with
in. The membership test can neversucceed,
supportedis empty,Noneis returned, and every edge that dependson the fallback is dropped by the
continue.In this repo 78.3% of
IMPORTS_FROMedges (22,546 of 28,780) carry dottedmodule targets; only 21.7% are file paths.
Reproduction
Any Python project where the test does not import the production symbol
directly (framework-mediated access — Odoo's
self.env['model'], Django's appregistry, pytest fixtures). 2,712 symbols in this repo have
TESTED_BYedgesreachable only through the bare-name fallback; all of them report 0.
Not an upgrade artifact: reproduced after a full
buildon 2.3.8(9,891 files, 57,706 nodes, 547,277 edges).
postprocessalone does notchange the bare-edge count either (85,438 before and after).
Related
imports in impact and test resolution"). The Python side appears to have the
identical defect.
TESTED_BYsources in postprocessing; that passleaves these edges untouched here.
tests_forreturning 0 for all C# code — same symptom, otherlanguage.
Suggested direction
Normalize both sides before comparing: resolve dotted module targets to the
file paths of the nodes they refer to when building
imported_files(thegraph already indexes those files), or store
IMPORTS_FROMtargetsconsistently as paths. The C# fix in #799 may be directly portable.