Skip to content

fix(routes): scope DATA_FLOWS pairing at the test-file boundary (R1 + R2) - #2707

Merged
DeusData merged 4 commits into
mainfrom
fix/data-flows-test-file-scope
Oct 19, 2026
Merged

DeusData merged 4 commits into
mainfrom
fix/data-flows-test-file-scope

Conversation

@DeusData

Copy link
Copy Markdown
Owner

What

Design decision (2026-10-18): DATA_FLOWS pair callers and handlers across the test boundary only within one file (R1 + R2):

  • R1: a handler defined in a test file pairs only with callers in that same file.
  • R2: a caller in a test file pairs only with handlers in that same file.

A test's request to the application, a production caller matched to a test's mock server, and two tests' private mock servers pairing across files are not data flows of the application. Main never implemented this. Since #2689, every caller of a route is linked to every handler of it, so those pairs were made.

try_create_data_flow now refuses a pair when the caller's or the handler's file is a test file and the two files differ. It uses cbm_is_test_file, the per-language rule that extraction already uses for is_test.

  • Unchanged: HTTP_CALLS and HANDLES. Only the pairing is scoped.
  • Logging: the pass log counts the refused pairs as skipped_test_scope.

This removes most of main's current DATA_FLOWS. On the measured repos, 627 of 696 parallel flows go, nearly all of them a test calling a production controller. That is the 2026-10-18 R1 + R2 design decision applied to the edges as they stand. A test's own HTTP_CALLS stay, so test-to-endpoint reachability is still in the graph.

Evidence

Corpus proof: a from-scratch build of this branch's fix commit 6f00af3 on main 684dcf5 (built from a commit with the identical tree) against a from-scratch build of main 684dcf5. Six repos with route flows, parallel (two runs each, noise 0) and sequential. Only DATA_FLOWS moves, only removals, no attribute changes:

repo DATA_FLOWS parallel sequential
thingsboard/thingsboard 432 -> 4 0 -> 0
spring-projects/spring-boot 232 -> 46 396 -> 72
apolloconfig/apollo 15 -> 10 11 -> 6
apache/shenyu 14 -> 9 0 -> 0
Kilo-Org/kilocode 3 -> 0 0 -> 0
microsoft/healthcare-ai-model-evaluator 0 -> 0 0 -> 0

Every removed flow crosses files and involves a test file (classified with the same per-language rule):

  • Parallel, 627 removed: test -> production 505, test -> another test file 86, production -> test mock 36.
  • Sequential, 329 removed: test -> production 146, test -> another test file 123, production -> test mock 60.

What remains is production -> production (61 parallel) and same-file pairs (8 parallel). These are byte-identical to the base: no added edges and no attribute changes. Sequential DATA_FLOWS are lower on thingsboard because the argument-URL client heuristic runs only on the parallel path (a known, separate parity gap).

Tests:

  • infrascan:
    • infrascan_data_flows_test_callers_pair_only_within_their_file: test callers by each language's rule (a tests/ directory, a Java *Test.java, a TypeScript .spec.ts) get no flow to a production handler. The production caller keeps its flow.
    • infrascan_data_flows_test_handlers_pair_only_within_their_file: a production caller gets no flow to a test's mock server. A test reaches the mock server in its own file, but not one in another test file.
  • edge_types_probe: data_flows_test_files_pair_within_their_file_sequential and ..._parallel. A Spring controller, a mock controller under src/test/, a production TypeScript fetch client and a .test.ts client all meet on the same __route__ANY__ nodes, and exactly one flow is expected: production client -> production controller.
  • Without the fix, all four fail. End to end, both venues give 3 flows instead of 1: the test -> controller pair and the production -> mock pair. With the fix, all four pass.

Suites on the fix commit 6f00af3 (ASan test-runner): infrascan, edge_types_probe, architecture_projection, convergence_probe, edge_structural, extraction, graph_mem, lang_contract, lsp_resolution_probe, matrix_known_classes, ui, route_canon, cross_repo, parallel, pipeline, httpd, incremental. 1,686 passed, plus 1 Windows-only platform skip (#798).

Lint on pass_route_nodes.c is clean: lint-memory-core, the NOLINT check, Homebrew clang-format and CI's cppcheck 2.20.

Head 8d1815c merges main 0f6cc06. Main has not touched this PR's files since 684dcf5, and merge-tree is clean.

Design decision 2026-10-18 (R1 + R2): a DATA_FLOWS caller in a test file
pairs only with handlers in that same file, and a handler in a test
file pairs only with callers in that same file.

infrascan: test callers by each language rule (a tests/ directory, a
Java *Test.java, a TS .spec.ts) get no flow to a production handler; a
production caller gets no flow to a test mock server; a test reaches
the mock server of its own file but not one in another test file.
Controls: a production caller keeps its flow, and so does a same-file
test pair.

edge_types_probe: a Spring controller, a mock controller under
src/test/, a production TS client and a TS .test.ts client meet on
the same __route__ANY__ nodes. Exactly one flow (production client to
production controller) on the sequential and on the parallel path.

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
… R2)

Design decision 2026-10-18 (R1 + R2): a handler defined in a test file
pairs only with callers in that same file, and a caller in a test file
pairs only with handlers in that same file. A test's request to the
application, a production caller matched to a test's mock server, and
the private mock servers of two tests pairing across files are not
data flows of the application. #2689 links every caller of a route to
every handler of it, so these pairs were made on main.

try_create_data_flow now refuses a pair whose caller or handler is in a
test file (cbm_is_test_file, the per-language rule extraction uses)
when the two files differ. HTTP_CALLS and HANDLES are unchanged; only
the pairing is scoped. The pass log counts the refused pairs
(skipped_test_scope).

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
…ile-scope

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
…ile-scope

Conflict in tests/test_edge_types_probe.c: both sides added tests after
et_handles_exact (the R1 + R2 DATA_FLOWS tests and the #1692 ASP.NET
overload test); both are kept.

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
@DeusData
DeusData merged commit d211526 into main Oct 19, 2026
28 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant