Instant validation for caches excluded from prerenders (#98342)
Follow-up to #98339. Turns out we were not testing how caches excluded
from static/runtime prerenders and app shells behave in Instant
Validation, and it was somewhat broken. This PR adds test coverage and
fixes some bugs I found along the way.
### Fixes
- `use-cache-wrapper` was incorrectly gating cache delays in "request"
stores on `NODE_ENV === "development"`, which does not include
build-time instant validation. The correct check is now implemented in
`isValidationRender`
- `use-cache-wrapper` has divergent behavior for caches with `stale <
MIN_SHELL_STALE` across app shells and PPR/static shells, which needs to
be tracked so that we know that the same render can't be used for both
Instant and Static Shell validation. When we see a cache entry like
that, we now call `trackIncompatibleShellContent()`
- A render that had a cache miss could still report that it's compatible
with both SSV and IV, because we only do the above for a cache hit. As a
result so we'd incorrectly reuse `LAZY_FULL_RENDER` for both. Cache
misses now result in a `trackIncompatibleShellContent()` call to avoid
this
### Tests
We now have tests for:
- `stale < MIN_SHELL_STALE` - excluded from app shells, but included in
static and runtime prefetches
- `stale < MIN_PREFETCHABLE_STALE` - excluded from all prerenders
- `expire < MIN_PRERENDERABLE_EXPIRE` - excluded from static prerenders,
but allowed in runtime prerenders
Due to bugs mentioned above, some of the added tests were failing before
the fixes (mostly the ones that expect an error -- passing a "no
validation errors" test is easy, just don't create any dynamic holes)
In build, these tests incorrectly reported no errors when they should've
failed IV:
- `invalid - unguarded non-prefetchable cache (with short stale)` (both
PPF and non-PPF)
- `non-app shell validation > invalid - unguarded non-prerenderable
cache with short expire` in build:
- `app shell validation > invalid - unguarded cache with a
shorter-than-shell staleTime` in build:
This is because we were missing cache delays in build-time instant
validation (now fixed with `isValidationRender`), so the caches weren't
dynamic holes at all.
The `stale < MIN_SHELL_STALE` tests (`app shell validation > invalid -
unguarded cache with a shorter-than-shell staleTime`) were also failing
in dev:
- **{initial load, client navigation} with cold caches**: Should be an
IV error, but is an SSV error. The initial render had cache misses, so
we did a warm-cache full rerender with runtime shells, which resolved
`await nonShellCache()` in the Runtime stage. But the initial render
**did not track incompatible data**, so we incorrectly re-used it for
SSV and IV. The cache was resolved in `Runtime` so SSV saw a runtime
hole and `await nonShellCache()` errored in SSV with `Next.js
encountered runtime data during prerendering.`
- **client navigation with warm caches**: same as above, except there
weren't cache misses, so incorrectly reused the *original* runtime-shell
render for SSV and IV
- **initial load with warm caches**: No redbox when IV should've
errored. The main render was an initial load and did not use runtime
shells, so it resolved `await nonShellCache()` in `PrefetchStatic`. We
had no cache misses and **did not track incompatible data**, so we
incorrectly re-used the main non-runtime-shell render for SSV and IV.
The cache resolved in `PrefetchStatic` and it wasn't a hole in
`ShellRuntime` so no error was reported.