Skip to content

Judge gradle-cache storing by new entry names, not net count - #134

Merged
janicduplessis merged 4 commits into
mainfrom
fix/issue-132-gradle-check
Aug 31, 2026
Merged

Judge gradle-cache storing by new entry names, not net count#134
janicduplessis merged 4 commits into
mainfrom
fix/issue-132-gradle-check

Conversation

@janicduplessis

@janicduplessis janicduplessis commented Aug 31, 2026

Copy link
Copy Markdown
Collaborator

Description

The gradle-cache check in the cache e2e judged storing by comparing the file count of ~/.gradle/caches/build-cache-1 before and after the cold assemble. Gradle's periodic cleanup (entries unused >7 days) can remove more entries than the build adds, so on a lived-in machine the delta goes negative and the check fails as "engaged-but-not-storing" while storing actually worked. Hit during the rc.5 pre-tag QA: net -1104 files, yet 225 entries were created during the window (proven by mtime). CI is unaffected for a simpler reason the review corrected: the e2e workflow restores no Gradle cache at all, so the directory starts empty there.

Solution

Snapshot the cache's entry basenames before the cold assemble and assert that new names appear afterwards (set difference), which is immune to concurrent deletions. The evidence line now also reports how many old files cleanup removed in the same window, so the next reader of a passing-but-shrinking cache isn't puzzled.

Test plan

  • Helper semantics verified directly: a new entry is detected despite a concurrent removal; a missing dir yields an empty list.
  • Real-world validation: a full caches expo-android run on the same machine (populated, cleanup-prone gradle cache) that produced the false negative — result to be attached before marking ready.

Fixes #132


Validation evidence (attached per review)

Two full caches expo-android runs on the machine that produced the false negative:

  1. First run exposed a third mode the original check also mishandled: the machine cache already held every one of this fixture's task outputs (from the release-QA run hours earlier), so the cold workspace stored 0 new entries and loaded FROM-CACHE instead -- correct Gradle behavior that the store-only assertion called a failure. The check now accepts either direction (store on a cold machine cache, load on a warm one) and names which it saw.
  2. Rerun with the final check: suite exit 0, gradle-cache PASS: --build-cache on the argv; warm machine cache reused by wt1 (89 FROM-CACHE); 89 FROM-CACHE task(s) in the second worktree.

Review fixes also applied: entries are matched by the 32-hex name shape (build-cache-1.lock/gc.properties can no longer satisfy the check on a cold directory -- the CI case), an unreadable directory now throws instead of reading as all-new, and the removed-count evidence derives from the same name sets instead of mixing a recursive count with a flat listing.

Gradle's periodic cleanup of entries unused for 7 days can remove more
files from ~/.gradle/caches/build-cache-1 than a cold assemble adds, so
the before/after count went negative on a lived-in machine and the check
reported engaged-but-not-storing while 225 new entries had in fact been
written. The check now snapshots entry basenames and asserts on the set
difference, and reports concurrent cleanup in its evidence.

Fixes #132
The cache directory also holds build-cache-1.lock and gc.properties; on
a cold directory (CI) those alone satisfied a new-names check. An
unreadable directory now throws instead of reading as all-new, and the
removed count comes from the same name sets rather than mixing a
recursive file count with a flat listing.
…toring

A previous suite run on the same machine can leave every one of this
fixture's task outputs in ~/.gradle/caches/build-cache-1; the cold
workspace then loads FROM-CACHE and stores nothing, which is the cache
working, not failing. The check now accepts either direction and names
which one it saw.
A later check rebuilds wt1, so reading its log lazily would let a
reordered check satisfy warm mode from the wrong build -- the same
snapshot-timing class this branch already fixed for the name sets. The
warm-mode pass string states outright that storing was not exercised.
@janicduplessis
janicduplessis marked this pull request as ready for review August 31, 2026 17:53
@janicduplessis
janicduplessis merged commit 86f9273 into main Aug 31, 2026
5 checks passed
@janicduplessis
janicduplessis deleted the fix/issue-132-gradle-check branch August 31, 2026 17:53
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.

cache e2e: gradle-cache check is defeated by Gradle's cache cleanup on a lived-in machine

1 participant