Try to fix pending sync state test failures by using a hot flow (#1839)

* Remove the ignore annotation

* Turn inPendingState in to a hot state flow for the test duration

Signed-off-by: Sunik Kupfer <kupfer@bitfire.at>

* Rename methods registering the sync state observer

Signed-off-by: Sunik Kupfer <kupfer@bitfire.at>

---------

Signed-off-by: Sunik Kupfer <kupfer@bitfire.at>
This commit is contained in:
Sunik Kupfer
2025-12-01 14:40:52 +01:00
committed by GitHub
parent 6f09f55e1a
commit b5e8c80db1

View File

@@ -15,8 +15,7 @@ import at.bitfire.davdroid.sync.account.TestAccount
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.android.testing.HiltAndroidRule
import dagger.hilt.android.testing.HiltAndroidTest
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withTimeout
@@ -26,7 +25,6 @@ import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.BeforeClass
import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import java.util.logging.Logger
@@ -51,17 +49,8 @@ class AccountSettingsMigration21Test {
lateinit var account: Account
val authority = CalendarContract.AUTHORITY
private val inPendingState = callbackFlow {
val stateChangeListener = ContentResolver.addStatusChangeListener(
ContentResolver.SYNC_OBSERVER_TYPE_PENDING or ContentResolver.SYNC_OBSERVER_TYPE_ACTIVE
) {
trySend(ContentResolver.isSyncPending(account, authority))
}
trySend(ContentResolver.isSyncPending(account, authority))
awaitClose {
ContentResolver.removeStatusChangeListener(stateChangeListener)
}
}
private val inPendingState = MutableStateFlow(false)
private var statusChangeListener: Any? = null
@Before
fun setUp() {
@@ -71,15 +60,18 @@ class AccountSettingsMigration21Test {
// Enable sync globally and for the test account
ContentResolver.setIsSyncable(account, authority, 1)
// Start hot flow
registerSyncStateObserver()
}
@After
fun tearDown() {
unregisterSyncStateObserver()
TestAccount.remove(account)
}
@Ignore("Sometimes failing, see https://github.com/bitfireAT/davx5-ose/issues/1835")
@SdkSuppress(minSdkVersion = 34)
@Test
fun testCancelsSyncAndClearsPendingState() = runBlocking {
@@ -117,6 +109,22 @@ class AccountSettingsMigration21Test {
.setManual(true) // equivalent of setting both SYNC_EXTRAS_IGNORE_SETTINGS and SYNC_EXTRAS_IGNORE_BACKOFF
.build()
private fun registerSyncStateObserver() {
// listener pushes updates immediately when sync status changes
statusChangeListener = ContentResolver.addStatusChangeListener(
ContentResolver.SYNC_OBSERVER_TYPE_PENDING or ContentResolver.SYNC_OBSERVER_TYPE_ACTIVE
) {
inPendingState.tryEmit(ContentResolver.isSyncPending(account, authority))
}
// Emit initial state
inPendingState.tryEmit(ContentResolver.isSyncPending(account, authority))
}
private fun unregisterSyncStateObserver() {
statusChangeListener?.let { ContentResolver.removeStatusChangeListener(it) }
}
companion object {
var globalAutoSyncBeforeTest = false