fix(test): stop androidApp unit tests opening the app database - #7070
Conversation
Robolectric boots the manifest's MeshUtilApplication for any test that does not override it, and its background init opens a Room3 database on BundledSQLiteDriver. onTerminate does try to close that database at teardown, but close() gives up after a 5s drain when the open is still in flight and deliberately retains the pools for a later retry a test never makes. Robolectric then deletes the temp data dir under the live connection, and the next test in the fork dies with SIGSEGV in the sqlite JNI -- exit 134, no test named, and whatever PR was in the merge queue is silently ejected. Four test classes were booting the production Application, three of them incidentally. Default the unit-test Application to android.app.Application so it is opt-in, and give the one test that needs the real Koin graph a subclass with background init suppressed. Also upload hs_err_pid*.log from the test shards: that run produced no artifacts, so a native crash there is currently undiagnosable.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (5)
💤 Files with no reviewable changes (1)
Included review availability: Your plan provides up to 4 included reviews per hour; 2 remain after this review. 📝 WalkthroughWalkthroughThe change separates application background initialization from ChangesAndroid test lifecycle and diagnostics
Priority: ⬇️ Low — Defer this narrow test-isolation change because it prevents Robolectric database crashes without changing app behavior. Estimated code review effort: 2 (Simple) | ~10 minutes Severity of issue fixed: Low Merge Risk: ⚪ Minimal · up to This change isolates Android unit tests from production database startup while preserving application initialization behavior and adds crash-log collection for failed test shards. No current merge-blocking risk is identified. 🚥 Pre-merge checks | ✅ 7 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (7 passed)
Full details: Regression Coverage For Changed BehaviorExplanation Coverage gap: Resolution Add a Robolectric regression test in the common Android unit-test source set with no
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
androidApp unit tests keep taking the whole test fork down with a native SIGSEGV, which ejects whatever PR is in the merge queue with no failing test named. #7020 was ejected twice on 2026-09-08 and #7005 hit the same thing on 2026-09-03. In every case the PR's own run of that shard had passed.
Robolectric boots the manifest's
MeshUtilApplicationfor any test that does not override it. Its background init opens the app's Room3 database onBundledSQLiteDriver, andonTerminatecannot reliably close it:DatabaseManager.close()bound-waitsWRITER_DRAIN_TIMEOUT_MS(5s) for the in-flight open, then deliberately retains the pools for a later close retry that a test never makes. Robolectric destroys that test's temp data dir out from under the live connection, and the next test in the fork dies in the sqlite JNI (walIndexTryHdr,sqlite3VdbeHalt,sqlite3ExprDeleteNN), exit 134.Four androidApp test classes were booting the production Application. Three of them (
KmlToGoogleLayerTest,MapLayerOpacityTest,KmlImportTest) only wantedandroid.graphicsand had no teardown at all.🐛 Bug Fixes
robolectric.properties: default the unit-test Application toandroid.app.Application, so booting the production one is opt-in per test.MeshUtilApplication: move theonCreatebackground launches intoprotected open fun startBackgroundInit().CoilImageLoaderLifecycleTestnow boots a subclass that no-ops it, so it still asserts the real Koin/Coil wiring without opening a database.GoogleMeshUtilApplicationstill launches its own AppFunctions sync aftersuper.onCreate(); that test pinsMeshUtilApplication::classso it never runs there.ShareMessageDeepLinkTestno longer needs itscancelBackgroundInitteardown.cancelBackgroundInitis private again and its doc no longer claims Robolectric skipsonTerminate. It does call it, fromAndroidTestEnvironment.tearDownApplication.🧹 Chores
hs_err_pid*.logfrom the test shards on failure. Both ejecting runs produced no artifacts at all, so the JVM crash report, the only thing that names the crashing thread, was gone.Testing Performed
:androidApp:testGoogleDebugUnitTestand:androidApp:testFdroidDebugUnitTestwith--rerun: green. Noandroidx_sqliteJni,BundledSQLiteDriverorMeshtasticDatabasereference is left in either task's results. The only database traffic remaining is WorkManager's own Room 2.x throughandroidx.sqlite.db.framework, which is the shadowed framework pathsqliteMode=LEGACYalready covers.spotlessApply spotlessCheck detekt assembleDebug test allTests.No behaviour change in the app.
startBackgroundInit()runs from the same point inonCreate.Summary by CodeRabbit
Bug Fixes
Refactor