mirror of
https://github.com/austinried/subtracks.git
synced 2026-11-10 23:21:59 +01:00
stop poisoning the unit suite from Room teardown races
The ThemeTest failure was cross-test contamination, not a theme bug. A Room invalidation-tracker query keeps running on a cancelled flow collector after the in-memory DB is closed or finalised, throws "no such table: sources", and kotlinx-coroutines-test records it and fails the next Compose test with UncaughtExceptionsBeforeTest. Which test it lands on is just ordering/load luck. Close repositories the way DownloadRepository already did: cancel and join the scope, so Room work cannot outlive close. Stop closing the in-memory test DBs; the DB is dropped and collected once the test releases it, instead of being torn down under a pending query. Wait for the stored ref in offlineModeStillServesDownloadedArtwork instead of asserting once, since it was waiting on a different flow than the state coverArt reads. Print full stack traces for failed tests in CI.
This commit is contained in:
@@ -13,9 +13,11 @@ import com.subtracks.R
|
||||
import com.subtracks.data.repo.DownloadRepository
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.cancel
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
|
||||
/**
|
||||
* Our own aggregated progress notification for the downloads the platform engine runs. The engine's
|
||||
@@ -44,7 +46,9 @@ class DownloadNotifier(
|
||||
}
|
||||
|
||||
internal fun close() {
|
||||
val job = scope.coroutineContext[Job]
|
||||
scope.cancel()
|
||||
runBlocking { job?.join() }
|
||||
}
|
||||
|
||||
private fun build(content: DownloadNotification): Notification =
|
||||
|
||||
@@ -16,6 +16,7 @@ import com.subtracks.data.source.streamLengthSuffix
|
||||
import com.subtracks.data.source.subsonic.SubsonicClient
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.cancel
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
@@ -25,6 +26,7 @@ import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.withContext
|
||||
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||
import okhttp3.OkHttpClient
|
||||
@@ -100,7 +102,9 @@ class SourceRepository(
|
||||
}
|
||||
|
||||
fun close() {
|
||||
val job = scope.coroutineContext[Job]
|
||||
scope.cancel()
|
||||
runBlocking { job?.join() }
|
||||
}
|
||||
|
||||
fun sources(): Flow<List<Source>> = db.sourcesDao().sources()
|
||||
|
||||
@@ -7,11 +7,14 @@ import com.subtracks.data.repo.SourceRepository
|
||||
import kotlinx.coroutines.CancellationException
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.cancel
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
|
||||
sealed interface SyncStatus {
|
||||
data object Idle : SyncStatus
|
||||
@@ -46,6 +49,12 @@ class SyncManager(
|
||||
requests.trySend(Unit)
|
||||
}
|
||||
|
||||
fun close() {
|
||||
val job = scope.coroutineContext[Job]
|
||||
scope.cancel()
|
||||
runBlocking { job?.join() }
|
||||
}
|
||||
|
||||
private suspend fun runSync() {
|
||||
if (sourceRepository.offline.value) {
|
||||
showMessage("Offline mode is on")
|
||||
|
||||
Reference in New Issue
Block a user