mirror of
https://github.com/signalapp/Signal-Android.git
synced 2025-12-22 12:08:34 +00:00
Reduce noise of flaky test.
This commit is contained in:
committed by
mtang-signal
parent
627b939326
commit
630875dae2
@@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2024 Signal Messenger, LLC
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.thoughtcrime.securesms.backup.v2
|
||||||
|
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
import org.junit.Assert.assertEquals
|
||||||
|
import org.junit.Rule
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
import org.thoughtcrime.securesms.testing.SignalFlakyTest
|
||||||
|
import org.thoughtcrime.securesms.testing.SignalFlakyTestRule
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
class FlakyTestAnnotationTest {
|
||||||
|
|
||||||
|
@get:Rule
|
||||||
|
val flakyTestRule = SignalFlakyTestRule()
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private var count = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
@SignalFlakyTest
|
||||||
|
@Test
|
||||||
|
fun purposelyFlaky() {
|
||||||
|
count++
|
||||||
|
assertEquals(3, count)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,9 +4,12 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
|
|||||||
import junit.framework.Assert.assertFalse
|
import junit.framework.Assert.assertFalse
|
||||||
import junit.framework.Assert.assertTrue
|
import junit.framework.Assert.assertTrue
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
|
import org.junit.Rule
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
import org.signal.core.util.concurrent.SignalExecutors
|
import org.signal.core.util.concurrent.SignalExecutors
|
||||||
|
import org.thoughtcrime.securesms.testing.SignalFlakyTest
|
||||||
|
import org.thoughtcrime.securesms.testing.SignalFlakyTestRule
|
||||||
import java.util.concurrent.CountDownLatch
|
import java.util.concurrent.CountDownLatch
|
||||||
import java.util.concurrent.atomic.AtomicBoolean
|
import java.util.concurrent.atomic.AtomicBoolean
|
||||||
|
|
||||||
@@ -18,6 +21,9 @@ class SQLiteDatabaseTest {
|
|||||||
|
|
||||||
private lateinit var db: SQLiteDatabase
|
private lateinit var db: SQLiteDatabase
|
||||||
|
|
||||||
|
@get:Rule
|
||||||
|
val flakyTestRule = SignalFlakyTestRule()
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun setup() {
|
fun setup() {
|
||||||
db = SignalDatabase.instance!!.signalWritableDatabase
|
db = SignalDatabase.instance!!.signalWritableDatabase
|
||||||
@@ -181,6 +187,7 @@ class SQLiteDatabaseTest {
|
|||||||
assertTrue(hasRun2.get())
|
assertTrue(hasRun2.get())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SignalFlakyTest
|
||||||
@Test
|
@Test
|
||||||
fun runPostSuccessfulTransaction_runsAfterMainTransactionInNestedTransaction() {
|
fun runPostSuccessfulTransaction_runsAfterMainTransactionInNestedTransaction() {
|
||||||
val hasRun1 = AtomicBoolean(false)
|
val hasRun1 = AtomicBoolean(false)
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2024 Signal Messenger, LLC
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.thoughtcrime.securesms.testing
|
||||||
|
|
||||||
|
@Retention(AnnotationRetention.RUNTIME)
|
||||||
|
annotation class SignalFlakyTest(val allowedAttempts: Int = 3)
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2024 Signal Messenger, LLC
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.thoughtcrime.securesms.testing
|
||||||
|
|
||||||
|
import org.junit.rules.TestRule
|
||||||
|
import org.junit.runner.Description
|
||||||
|
import org.junit.runners.model.Statement
|
||||||
|
import org.signal.core.util.logging.Log
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A JUnit rule that retries tests annotated with [SignalFlakyTest] before considering them to be a failure.
|
||||||
|
* As the name implies, this is useful for known-flaky tests.
|
||||||
|
*/
|
||||||
|
class SignalFlakyTestRule : TestRule {
|
||||||
|
override fun apply(base: Statement, description: Description): Statement {
|
||||||
|
val flakyAnnotation = description.getAnnotation(SignalFlakyTest::class.java)
|
||||||
|
|
||||||
|
return if (flakyAnnotation != null) {
|
||||||
|
FlakyStatement(
|
||||||
|
base = base,
|
||||||
|
description = description,
|
||||||
|
allowedAttempts = flakyAnnotation.allowedAttempts
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
base
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class FlakyStatement(private val base: Statement, private val description: Description, private val allowedAttempts: Int) : Statement() {
|
||||||
|
override fun evaluate() {
|
||||||
|
var attemptsRemaining = allowedAttempts
|
||||||
|
while (attemptsRemaining > 0) {
|
||||||
|
try {
|
||||||
|
base.evaluate()
|
||||||
|
return
|
||||||
|
} catch (t: Throwable) {
|
||||||
|
attemptsRemaining--
|
||||||
|
if (attemptsRemaining <= 0) {
|
||||||
|
throw t
|
||||||
|
}
|
||||||
|
Log.w(description.testClass.simpleName, "[${description.methodName}] Flaky test failed! $attemptsRemaining attempt(s) remaining.", t)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user