Skip to content

acc: make changed-test detection reusable - #5880

Open
pietern wants to merge 6 commits into
mainfrom
extract-changed-tests
Open

acc: make changed-test detection reusable#5880
pietern wants to merge 6 commits into
mainfrom
extract-changed-tests

Conversation

@pietern

@pieternpietern commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Extract the changed-test detection added in #5844 (DATABRICKS_TEST_SKIPLOCAL=withchanged) into acceptance/internal so it is generic for any functionality that wants to inspect which acceptance tests a diff touches, and harden it to catch cross-directory dependencies it previously missed.

  • internal.ChangedTests(baseRef, headRef, testDirs) runs the git diff; an empty headRef diffs against the working tree, a non-empty one diffs between two refs (checkout-independent). internal.ParseChangedTests is a pure function over git diff --name-status text, unit-tested with literal diff strings.
  • selectChangedLocalTests keeps only the skiplocal policy (added-first ordering, maxChangedLocalTests cap) and delegates detection.
  • Ignore deleted invariant configs: a deletion no longer adds an INPUT_CONFIG= filter for a variant that is gone.
  • Keep ChangedTest.Added sticky across diff lines so a newly-added dir stays added regardless of line order.
  • Detect cross-directory dependencies: a parent script.prepare/script.cleanup/test.toml re-enables its whole subtree; a change under acceptance/bin/ re-enables the whole suite; any other unowned file (a sourced _script, a fixture read via $TESTDIR/..) re-enables its subtree.

This pull request and its description were written by Isaac.

Move the "which acceptance test dirs did this branch's diff affect?" logic out
of the skiplocal_test.go helper and into acceptance/internal, so both the
existing DATABRICKS_TEST_SKIPLOCAL=withchanged path and future callers can share
one detection function.
- internal.ChangedTests(baseRef, headRef, testDirs) runs the git diff and returns
a map of test dir -> ChangedTest{Added, VariantFilters}. An empty headRef diffs
against the working tree (preserving withchanged's local-dev behavior of
re-enabling uncommitted edits); a non-empty headRef diffs between two refs,
independent of the checkout, for CI and replaying historical PRs.
- internal.ParseChangedTests is split out as a pure function over git diff text,
unit-tested with literal diff strings (added dir, rename, nested dir, invariant
config INPUT_CONFIG= expansion, files outside acceptance/).
- selectChangedLocalTests keeps only the skiplocal policy (added-first ordering
and the maxChangedLocalTests cap) and delegates detection to ChangedTests.
No behavior change: the withchanged path produces the same selection as before.
Co-authored-by: Isaac
@pietern
pieterntemporarily deployed to test-trigger-is July 9, 2026 13:29 — with GitHub Actions Inactive
@pietern
pieterntemporarily deployed to test-trigger-is July 9, 2026 13:29 — with GitHub Actions Inactive
@github-actions

Copy link
Copy Markdown
Contributor

Waiting for approval

Based on git history, these people are best suited to review:

  • @denik -- recent work in acceptance/internal/, acceptance/

Eligible reviewers: @andrewnester, @anton-107, @janniklasrose, @renaudhartert-db, @shreyas-goenka, @simonfaltum

Suggestions based on git history. See OWNERS for ownership rules.

A deleted invariant config (D status) previously added an INPUT_CONFIG= filter
for a variant that no longer exists, so the invariant subdirs were re-enabled
for a config that can never match. Skip deletions in the invariant-config branch.
Also add deletion coverage to the parser tests: a deleted file in a still-present
test dir re-enables that dir; a deleted whole test dir (script gone) is ignored;
a deleted config is ignored; and a deleted config alongside a modified one keeps
only the modified config's filter.
Co-authored-by: Isaac
@eng-dev-ecosystem-bot

eng-dev-ecosystem-bot commented Jul 9, 2026

Copy link
Copy Markdown
Collaborator

Integration test report

Commit: 658e3b7

Run: 29732679933

Env💚​RECOVERED🙈​SKIP✅​pass🙈​skipTime
💚​aws linux4422711225:06
💚​aws windows4422911208:35
💚​aws-ucws linux4431410395:56
💚​aws-ucws windows4431610377:28
💚​azure linux4422711215:21
💚​azure windows4422911196:43
💚​azure-ucws linux4431610367:20
💚​azure-ucws windows4431810349:48
💚​gcp linux4422611234:53
💚​gcp windows4422811216:53
8 interesting tests: 4 RECOVERED, 4 SKIP
Test Nameaws linuxaws windowsaws-ucws linuxaws-ucws windowsazure linuxazure windowsazure-ucws linuxazure-ucws windowsgcp linuxgcp windows
💚​TestAccept💚​R💚​R💚​R💚​R💚​R💚​R💚​R💚​R💚​R💚​R
🙈​TestAccept/bundle/invariant/no_drift🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S
🙈​TestAccept/bundle/resources/vector_search_endpoints/drift/recreated_same_name🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S
🙈​TestAccept/bundle/resources/vector_search_indexes/recreate/embedding_dimension🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S
🙈​TestAccept/ssh/connection🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S
💚​TestFetchRepositoryInfoAPI_FromRepo💚​R💚​R💚​R💚​R💚​R💚​R💚​R💚​R💚​R💚​R
💚​TestFetchRepositoryInfoAPI_FromRepo/root💚​R💚​R💚​R💚​R💚​R💚​R💚​R💚​R💚​R💚​R
💚​TestFetchRepositoryInfoAPI_FromRepo/subdir💚​R💚​R💚​R💚​R💚​R💚​R💚​R💚​R💚​R💚​R
Top 10 slowest tests (at least 2 minutes):
durationenvtestname
8:21azure-ucws windowsTestAccept
8:04aws windowsTestAccept
6:29gcp windowsTestAccept
6:19azure windowsTestAccept
6:16aws-ucws windowsTestAccept
3:00aws linuxTestAccept
2:58gcp linuxTestAccept
2:56azure linuxTestAccept
2:54azure-ucws linuxTestAccept
2:50aws-ucws linuxTestAccept

ParseChangedTests overwrote the whole ChangedTest for every changed file in a
dir, so a later diff line (e.g. test.toml) reset Added to false after an added
script had set it true. Since git diff lines for a dir arrive in arbitrary
order, a brand-new dir could end up Added=false, breaking the added-first
ordering that selectChangedLocalTests relies on under maxChangedLocalTests.
Preserve the existing entry when a direct change re-enables all variants: clear
VariantFilters but OR in Added. This restores parity with the pre-refactor
algorithm's separate added map. Add tests covering both diff-line orders and the
added-subdir-overrides-config-filter interaction.
Co-authored-by: Isaac
@pieternpietern changed the title acc: extract changed-test detection into internal.ChangedTestsacc: make changed-test detection reusableJul 9, 2026
@pietern
pieterntemporarily deployed to test-trigger-is July 9, 2026 14:17 — with GitHub Actions Inactive
@pietern
pieterntemporarily deployed to test-trigger-is July 9, 2026 14:17 — with GitHub Actions Inactive
The mapper only saw a changed file's own innermost test dir, so it missed
changes to files that affect tests in other dirs:
- A parent script.prepare/script.cleanup/test.toml is concatenated or inherited
into every descendant test, so it now re-enables that whole subtree (works
even when its own dir is also a test dir with nested test dirs under it).
- A helper under acceptance/bin/ is on PATH for every test, so a change there
re-enables the whole suite.
- Any other changed file that no test dir owns (a sourced _script, a fixture
read via $TESTDIR/..) re-enables every test dir in its subtree. This
over-selects but errs toward running more tests, never skipping a real one.
A stray file at the acceptance root maps to nothing and is ignored.
Verified against real commits: a root script.prepare change (49ea8ae) now
re-enables every test dir; earlier resource/config PRs are unchanged.
Co-authored-by: Isaac
@pietern
pieterntemporarily deployed to test-trigger-is July 9, 2026 14:52 — with GitHub Actions Inactive
@pietern
pieterntemporarily deployed to test-trigger-is July 9, 2026 14:52 — with GitHub Actions Inactive
Two edge cases surfaced in review, both from the parser looking at only the
new path of each diff record and treating deletes too coarsely:
- A rename affects tests at both paths, but only the new path was classified.
Moving an inherited test.toml/script.prepare out of a parent dir left its old
descendants unmarked. Expand each rename record into a deletion of the old
path plus a modification of the new, so one classifier covers deletes,
renames, and edits uniformly (the new path stays "M", not "A", so a moved
script does not mark its dir brand-new).
- A deleted invariant config helper (job.yml.tmpl-init.sh) was ignored along
with the config template itself, but the template still exists and its variant
changed. Only skip a deletion when the deleted path is the .yml.tmpl template.
Extract the per-path logic into classifyPath so the rename expansion reuses it.
Co-authored-by: Isaac
Pure refactor, no behavior change: classifyPath was a five-branch precedence
ladder mixing dispatch with dense per-case logic. Turn it into a switch that
delegates the two knowledge-dense cases to named helpers (markInvariantConfig,
markTestDir), so the dispatch reads at a glance and the details are opt-in.
Co-authored-by: Isaac
Sign up for freeto 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.

2 participants

@pietern@eng-dev-ecosystem-bot