Skip to content

test(tooling): stop pending Hive opens from hanging later tests - #9057

Merged
NotThatKindOfDrLiz merged 9 commits into
mainfrom
test/9053-hive-open-guard
Sep 15, 2026
Merged

NotThatKindOfDrLiz merged 9 commits into
mainfrom
test/9053-hive-open-guard

Conversation

@NotThatKindOfDrLiz

Copy link
Copy Markdown
Member

Problem

Flutter widget tests can start a real Hive box open inside fake async and leave Hive’s private opening registry waiting forever. The existing root guard only sees boxes after they are fully open, so a later suite opening the same name can spend ten minutes waiting on an unrelated test. The current /hashtag/rust route test is one concrete trigger.

Why this fix

App-owned box opens now pass through a thin HiveBoxOpener seam. Production still delegates directly to Hive. The merged test harness installs an observer that starts the Hive operation in its captured real-async zone, records it until settlement, and gives root teardown enough visibility to await, heal, and attribute pending work to the test that started it.

This deliberately avoids HiveImpl.unregisterBox(): removing a private registry entry would not cancel the original I/O and could allow two opens to race. A zero-baseline generated-files guard prevents production code from bypassing the observable seam.

Strict Hive attribution is enabled in Mobile CI and mise run test. The existing hashtag route test also uses the same mocked service pattern as the focused hashtag screen tests, so it no longer starts storage that its routing assertion does not exercise.

What this leaves alone

Verification

  • Exact merged two-file reproduction: 19/19 passed with strict channel and Hive guards; neither cache-recovery test timed out.
  • Focused Hive guard, route, repository-provider, notification-preferences, and upload-initialization suites passed (35 tests).
  • flutter analyze lib test integration_test
  • ARB consistency and hardcoded-string scan
  • Direct-Hive-open zero ratchet
  • Codex generated/config checks
  • Generated Riverpod output refreshed

Closes #9053
Closes #9022

Supersedes #9050 by including its approved route-test fix.

@NotThatKindOfDrLiz
NotThatKindOfDrLiz requested a review from a team as a code owner September 10, 2026 23:01
@NotThatKindOfDrLiz
NotThatKindOfDrLiz requested review from dcadenas and rabble and removed request for a team September 10, 2026 23:01
@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@rabble

rabble commented Sep 11, 2026

Copy link
Copy Markdown
Member

CI is red on Tests (shard 3/4) — 22 failures, all in test/providers/social_providers_cleanup_test.dart under userDataCleanupServiceProvider (account switch, destructive/non-destructive cleanup, owner-scoped DM cleanup, Hive upload purge).

Run: https://github.com/divinevideo/divine-mobile/actions/runs/34542608847/job/103088446784

This reads as a regression from this PR's test-tooling change rather than the #9022 hang it targets: the failures are concentrated in one suite and repeat, not a 10-minute timeout in cache_recovery_service_test.dart. Holding review until it is green. Happy to pull the first assertion if that helps.

@github-actions

This comment has been minimized.

@rabble rabble left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Requesting changes: one real regression in the shared test seam, plus a guard that now passes vacuously.

Blocking

mobile/test/services/hive_box_opener_test.dart:37 — tearDown sets HiveBoxOpener.observerForTesting = null. Under very_good --optimization, flutter_test_config.testExecutable runs once for the whole bundle and installs the shared observer at bundle start, so nulling it here permanently disables the real-zone open seam for every suite that runs after this file. That reintroduces the #9022 hang and removes the pending-open attribution strict mode depends on. Capture the prior observer in setUp and restore it in tearDown, or drop the null.

Non-blocking

mobile/test/constants/hive_box_names_test.dart:40 — after moving the app call sites to HiveBoxOpener.open(...), the _openBoxCall pattern (.open(?:Lazy)?Box() no longer matches any app call site, so the #6919 "every box named via HiveBoxNames" guard scans nothing and passes vacuously. The comment "Its callers remain covered here" is no longer true. Extend the scanner to match HiveBoxOpener.open/openLazy, or scan the opener's callers.

Questions

  • The PR verifies focused suites (35 tests). Was the full --optimization bundle run under DIVINE_STRICT_HIVE_BOXES=true before enabling it in CI? If unrelated pre-existing leaks remain, strict mode could turn CI red.
  • mobile/test/providers/social_providers_cleanup_test.dart:120 adds cleanup for the notifications box, but this suite never references it. Is the leak owned here, or is this masking a leak strict mode should attribute elsewhere?

@NotThatKindOfDrLiz

Copy link
Copy Markdown
Member Author

Author update: the current head d82ff4dbe addresses both review items.

  • Fixed: the earlier shard-3 cleanup failures were resolved by closing the notification preferences box in 1f16b17.
  • Fixed: hive_box_opener_test.dart now preserves and restores the root Hive observer instead of clearing the process-global hook for every later optimized test. The regression failed before the fix and passes afterward.

Verification on the current head:

  • focused observer test: 2/2 passed
  • strict optimized Hive-related suite: 64 passed; 8 web-only tests skipped by their existing platform guards
  • pre-push analyzer, generated-file checks, and 67 affected tests passed
  • all GitHub checks passed, including all four optimized test shards

@rabble @dcadenas please re-review.

@github-actions

This comment has been minimized.

@NotThatKindOfDrLiz

Copy link
Copy Markdown
Member Author

Addressed every item from the latest review:

  • Fixed — root observer restoration: d82ff4dbe captures the exact observer installed by flutter_test_config and restores that same instance after each hive_box_opener_test. The new regression reproduced the old behavior (the second test saw null) before the fix and passes after it.
  • Fixed — box-name scanner coverage: 57978d8d3 extends the source scanner to recognize HiveBoxOpener.open and HiveBoxOpener.openLazy as well as direct Hive openBox/openLazyBox calls. A regression test proves an opener call using HiveBoxNames.notifications is captured, so the guard is no longer vacuous after the migration.
  • Answered — full strict optimization run: yes. Mobile CI runs the complete optimized test bundle with DIVINE_STRICT_HIVE_BOXES=true; all four shards are green on the current head. I also ran the directly affected strict optimized suites locally: 64 passed with 8 expected web-only skips.
  • Answered — notifications cleanup ownership: the social-provider cleanup suite resolves UserDataCleanupService, which clears preferences through the Hive-backed notificationPreferencesStoreProvider. That suite therefore owns the notifications box it opens; cleaning it in setup/teardown is suite isolation, not masking an unrelated leak. 57978d8d3 documents that relationship at the cleanup site.

Current head 57978d8d3 is clean and every GitHub check is green, including Generated Files, Analyze, Integration Tests, and all four Mobile CI shards.

@rabble @dcadenas please re-review.

@NotThatKindOfDrLiz

Copy link
Copy Markdown
Member Author

Overlap heads-up: this PR and draft PR #8540 both change repository_providers.dart and repository_providers.g.dart. The handwritten changes are in different provider sections, but the generated hash will conflict. Please coordinate merge order; whichever lands second should rebase onto fresh origin/main, regenerate the provider output, and rerun the focused Hive-opening and people-list provider tests.

@dcadenas dcadenas left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@NotThatKindOfDrLiz the head at 57978d8d340e addresses rabble's earlier review: the root Hive observer is captured and restored, and the box-name scanner is effective again for app-owned Hive opens. I reviewed that revision and have nothing blocking it.

Checks

  • Mobile CI run 34672113021 on this exact commit: success. Analyze, Format, Generated Files, Goldens, all four Tests shards, VGV Tag Gate, CI Configuration Tests, Codemagic Variable Groups, Codex Configuration, and Mobile CI pass.
  • Shard 0's job log records --dart-define=DIVINE_STRICT_HIVE_BOXES=true in the test flags, and all four shards pass.
  • Build Flutter Web Preview, Integration Tests (services), mergeability, semantic title, and CLA checks pass.
  • Locally: dart format and flutter analyze pass, 49 focused Hive tests pass, and a wider run of 10 Hive-touching suites under both strict flags passes (133 tests). scripts/check_direct_hive_opens.sh passes with an empty baseline.
  • A non-vacuity probe confirmed the scanner fails and names an offender when an app-owned open uses an unknown box name; the probe was then removed.
  • The full local flutter test run hit the per-command time limit under machine load and did not complete. The CI run above is the merged-bundle evidence for this commit.

This approval follows an independent review of the same revision.

@rabble your change request predates 57978d8d340e and your re-review request is already pending, so nothing was re-requested here. Take another look when you can.

Merge stays with you; your #8540 merge-order note does not change this review.

@NotThatKindOfDrLiz

Copy link
Copy Markdown
Member Author

Additional overlap heads-up: #9120 now intersects this PR in upload_initialization_helper.dart and social provider cleanup coverage. Please coordinate merge order; whichever lands later should rebase onto fresh origin/main and verify pending Hive opens remain isolated after the upload package extraction.

@github-actions

Copy link
Copy Markdown

Mobile PR Preview

Preview refreshed for 30ca5f8

Last refresh: 30ca5f8 at 2026-09-15 01:13:39 UTC (preview run)

Property Value
Preview URL https://d2cbe8c3.openvine-app.pages.dev
Pages project openvine-app
Preview branch pr-9057
PR branch test/9053-hive-open-guard
Commit 30ca5f8

@NotThatKindOfDrLiz

Copy link
Copy Markdown
Member Author

Author update: #9057 is rebased onto current origin/main and ready for fresh review at 30ca5f8fea.

  • Resolved the .claude/rules/testing.md conflict by preserving both current main's owned Hive.init(path) reset rule and this PR's HiveBoxOpener/pending-open guidance.
  • Git correctly skipped the original hashtag-route commit because that fix is already present on main.
  • Regenerated Riverpod outputs; generation produced no tracked changes.
  • Fixed the post-rebase process-global guard failure in 30ca5f8fea by replacing the test's bare Hive.init(null) reset with TestHelpers.resetHiveHomeForTesting().

Verification on the exact current head:

  • strict optimized focused bundle: 74 passed, 8 existing web-only skips
  • direct-Hive-open and process-global-mutation guards: pass
  • canonical analyzer scope: pass
  • pre-push generated-file verification and 66 affected tests: pass
  • every GitHub check: green, including Generated Files and all four strict Mobile CI shards
  • GitHub mergeability: mergeable

@rabble @dcadenas please re-review this rebased head. The remaining CHANGES_REQUESTED state is from the pre-fix review.

@rabble rabble left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved. No remaining findings on this revision.

Reviewed commit 30ca5f8fea98b00ef09c8ca1a3ac1a62352269d3.

The root Hive observer is now captured and restored, preserving the observer for subsequent suites in the optimized test isolate. The box-name scanner matches both HiveBoxOpener.open and openLazy, so production call sites remain covered. Notification-box cleanup belongs to the social-provider cleanup suite because its UserDataCleanupService uses the Hive-backed preferences store. The strict flags are enabled in CI.

Independently ran the opener, shared Hive guard, box-name scanner, and social-provider cleanup suites: 43 tests passed in ordinary mode and 43 passed in optimized merged mode, both with strict channel and Hive guards. Focused analysis and the direct-Hive-open guard passed. All four exact-head CI shards are green. No new findings. Coordinate the Hive seam with #9120's upload extraction.

@NotThatKindOfDrLiz
NotThatKindOfDrLiz added this pull request to the merge queue Sep 15, 2026
Merged via the queue into main with commit 1d04113 Sep 15, 2026
21 checks passed
@NotThatKindOfDrLiz
NotThatKindOfDrLiz deleted the test/9053-hive-open-guard branch September 15, 2026 15:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

3 participants