test: migrate MigrationTest to runTest and add missing repository fakes

Part A — runBlocking → runTest
- Migrated all 5 runBlocking sites in core/database MigrationTest
  (@Before + 4 @Test bodies) to kotlinx.coroutines.test.runTest so
  test dispatchers are virtual-time aware and cancellation semantics
  match the rest of the suite.
- Left DatabaseManagerLegacyCleanupTest on runBlocking: it polls with
  delay(100) for async cleanup that runs on Dispatchers.IO. runTest's
  virtual-time delay would collapse instantly and race the real IO
  cleanup, so runBlocking is the correct choice there.

Part B — missing repository fakes
Added five in-memory fakes in core:testing (pure Kotlin, MutableStateFlow
backed) that implement their repository interface exactly:
- FakeDeviceHardwareRepository      (DeviceHardwareRepository)
- FakeFirmwareReleaseRepository     (FirmwareReleaseRepository)
- FakeQuickChatActionRepository     (QuickChatActionRepository)
- FakeTracerouteSnapshotRepository  (TracerouteSnapshotRepository)
- FakeRadioConfigRepository         (RadioConfigRepository)

Each fake is exercised by a new test in
core/testing/src/commonTest/kotlin/.../RepositoryFakesTest.kt:
upsert/delete/reorder flows for quick-chat, seeded lookups +
call-recording for device hardware, stable/alpha emission for
firmware releases, snapshot round-trips for traceroute, and
channel-set mutations for radio config. PacketRepository was
skipped — 40+ members and a FakePacketRepository helper already
exists for informal use; left for a focused follow-up.

Validation (all green):
  ./gradlew spotlessApply spotlessCheck
  ./gradlew :core:testing:jvmTest :core:database:testAndroid
  ./gradlew detekt kmpSmokeCompile

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
James Rich 2026-04-17 11:07:51 -05:00
parent a97f704300
commit 2afb82b600
8 changed files with 844 additions and 6 deletions

View file

@ -20,7 +20,7 @@ import androidx.room3.Room
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.test.runTest
import okio.ByteString.Companion.toByteString
import org.junit.After
import org.junit.Before
@ -59,7 +59,7 @@ class MigrationTest {
)
@Before
fun createDb(): Unit = runBlocking {
fun createDb(): Unit = runTest {
val context = ApplicationProvider.getApplicationContext<android.content.Context>()
database =
Room.inMemoryDatabaseBuilder<MeshtasticDatabase>(
@ -77,7 +77,7 @@ class MigrationTest {
}
@Test
fun testMigrateChannelsByPSK_duplicatePSK() = runBlocking {
fun testMigrateChannelsByPSK_duplicatePSK() = runTest {
// PSK \"AQ==\" is base64 for single byte 0x01
val pskBytes = byteArrayOf(0x01).toByteString()
@ -103,7 +103,7 @@ class MigrationTest {
}
@Test
fun testMigrateChannelsByPSK_reorder() = runBlocking {
fun testMigrateChannelsByPSK_reorder() = runTest {
val pskA = byteArrayOf(0x01).toByteString()
val pskB = byteArrayOf(0x02).toByteString()
@ -122,7 +122,7 @@ class MigrationTest {
}
@Test
fun testMigrateChannelsByPSK_disambiguateByName() = runBlocking {
fun testMigrateChannelsByPSK_disambiguateByName() = runTest {
val pskA = byteArrayOf(0x01).toByteString()
insertPacket(channel = 0, text = "Msg A1")
@ -141,7 +141,7 @@ class MigrationTest {
}
@Test
fun testMigrateChannelsByPSK_preferSameIndexIfStillAmbiguous() = runBlocking {
fun testMigrateChannelsByPSK_preferSameIndexIfStillAmbiguous() = runTest {
val pskA = byteArrayOf(0x01).toByteString()
insertPacket(channel = 0, text = "Msg A")