RetryTestRule.kt 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. /*
  2. * Nextcloud - Android Client
  3. *
  4. * SPDX-FileCopyrightText: 2020 Tobias Kaminsky <tobias@kaminsky.me>
  5. * SPDX-FileCopyrightText: 2020 Nextcloud GmbH
  6. * SPDX-License-Identifier: AGPL-3.0-or-later OR GPL-2.0-only
  7. */
  8. package com.nextcloud.test
  9. import com.owncloud.android.BuildConfig
  10. import com.owncloud.android.lib.common.utils.Log_OC
  11. import org.junit.rules.TestRule
  12. import org.junit.runner.Description
  13. import org.junit.runners.model.Statement
  14. /**
  15. * C&p from https://stackoverflow.com/questions/45635833/how-can-i-use-flakytest-annotation-now on 18.03.2020
  16. */
  17. class RetryTestRule(val retryCount: Int = defaultRetryValue) : TestRule {
  18. companion object {
  19. private val TAG = RetryTestRule::class.java.simpleName
  20. @Suppress("MagicNumber")
  21. private val defaultRetryValue: Int = if (BuildConfig.CI) 5 else 1
  22. }
  23. override fun apply(base: Statement, description: Description): Statement {
  24. return statement(base, description)
  25. }
  26. @Suppress("TooGenericExceptionCaught") // and this exactly what we want here
  27. private fun statement(base: Statement, description: Description): Statement {
  28. return object : Statement() {
  29. override fun evaluate() {
  30. Log_OC.d(TAG, "Evaluating ${description.methodName}")
  31. var caughtThrowable: Throwable? = null
  32. for (i in 0 until retryCount) {
  33. try {
  34. base.evaluate()
  35. return
  36. } catch (t: Throwable) {
  37. caughtThrowable = t
  38. Log_OC.e(TAG, description.methodName + ": run " + (i + 1) + " failed")
  39. }
  40. }
  41. Log_OC.e(TAG, description.methodName + ": giving up after " + retryCount + " failures")
  42. if (caughtThrowable != null) {
  43. throw caughtThrowable
  44. }
  45. }
  46. }
  47. }
  48. }