Skip to content
Snippets Groups Projects
Unverified Commit cb4918c8 authored by Matthias Urhahn's avatar Matthias Urhahn Committed by GitHub
Browse files

Merge pull request #1800 from corona-warn-app/fix/1.8.x-into-1.9.x

1.8.x into 1.9.x (DEV)
parents 5e0a9a6d 56422390
No related branches found
No related tags found
No related merge requests found
...@@ -205,11 +205,16 @@ class TaskController @Inject constructor( ...@@ -205,11 +205,16 @@ class TaskController @Inject constructor(
// Handle collision behavior for tasks of same type // Handle collision behavior for tasks of same type
when { when {
!arePreconditionsMet -> {
Timber.tag(TAG).d("Preconditions are not met, skipping: %s", state)
workMap[state.id] = state.toSkippedState()
}
siblingTasks.isEmpty() -> { siblingTasks.isEmpty() -> {
Timber.tag(TAG).d("No siblings exists, running: %s", state)
workMap[state.id] = state.toRunningState() workMap[state.id] = state.toRunningState()
} }
!arePreconditionsMet ||
state.config.collisionBehavior == CollisionBehavior.SKIP_IF_SIBLING_RUNNING -> { state.config.collisionBehavior == CollisionBehavior.SKIP_IF_SIBLING_RUNNING -> {
Timber.tag(TAG).d("Siblings exists, skipping according to collision behavior: %s", state)
workMap[state.id] = state.toSkippedState() workMap[state.id] = state.toSkippedState()
} }
state.config.collisionBehavior == CollisionBehavior.ENQUEUE -> { state.config.collisionBehavior == CollisionBehavior.ENQUEUE -> {
......
...@@ -63,29 +63,19 @@ data class TracingCardState( ...@@ -63,29 +63,19 @@ data class TracingCardState(
* the persisted risk level is of importance * the persisted risk level is of importance
*/ */
fun getSavedRiskBody(c: Context): String { fun getSavedRiskBody(c: Context): String {
// Don't display last risk when tracing is disabled val stateToDisplay = when {
if (isTracingOff()) { riskState == CALCULATION_FAILED -> lastSuccessfulRiskState
val arg = c.getString(R.string.risk_card_no_calculation_possible_headline) isTracingOff() -> riskState
return c.getString(R.string.risk_card_no_calculation_possible_body_saved_risk).format(arg) else -> null
}
// Don't have any old risk state to display
if (lastSuccessfulRiskState == CALCULATION_FAILED) {
return ""
} }
return when (stateToDisplay) {
// If we failed this time, we want to display the old risk
if (riskState == CALCULATION_FAILED) {
val arg = when (lastSuccessfulRiskState) {
INCREASED_RISK -> R.string.risk_card_increased_risk_headline INCREASED_RISK -> R.string.risk_card_increased_risk_headline
LOW_RISK -> R.string.risk_card_low_risk_headline LOW_RISK -> R.string.risk_card_low_risk_headline
else -> null else -> null
}?.let { c.getString(it) } ?: "" }?.let {
return c.getString(R.string.risk_card_no_calculation_possible_body_saved_risk).format(arg) val argumentValue = c.getString(it)
} c.getString(R.string.risk_card_no_calculation_possible_body_saved_risk).format(argumentValue)
} ?: ""
// We are not in an error state
return ""
} }
/** /**
......
...@@ -3,6 +3,7 @@ package de.rki.coronawarnapp.task ...@@ -3,6 +3,7 @@ package de.rki.coronawarnapp.task
import de.rki.coronawarnapp.task.common.DefaultTaskRequest import de.rki.coronawarnapp.task.common.DefaultTaskRequest
import de.rki.coronawarnapp.task.example.QueueingTask import de.rki.coronawarnapp.task.example.QueueingTask
import de.rki.coronawarnapp.task.testtasks.SkippingTask import de.rki.coronawarnapp.task.testtasks.SkippingTask
import de.rki.coronawarnapp.task.testtasks.precondition.PreconditionTask
import de.rki.coronawarnapp.task.testtasks.timeout.TimeoutTask import de.rki.coronawarnapp.task.testtasks.timeout.TimeoutTask
import de.rki.coronawarnapp.task.testtasks.timeout.TimeoutTask2 import de.rki.coronawarnapp.task.testtasks.timeout.TimeoutTask2
import de.rki.coronawarnapp.task.testtasks.timeout.TimeoutTaskArguments import de.rki.coronawarnapp.task.testtasks.timeout.TimeoutTaskArguments
...@@ -54,6 +55,7 @@ class TaskControllerTest : BaseIOTest() { ...@@ -54,6 +55,7 @@ class TaskControllerTest : BaseIOTest() {
private val timeoutFactory2 = spyk(TimeoutTask2.Factory(Provider { TimeoutTask2() })) private val timeoutFactory2 = spyk(TimeoutTask2.Factory(Provider { TimeoutTask2() }))
private val queueingFactory = spyk(QueueingTask.Factory(Provider { QueueingTask() })) private val queueingFactory = spyk(QueueingTask.Factory(Provider { QueueingTask() }))
private val skippingFactory = spyk(SkippingTask.Factory(Provider { SkippingTask() })) private val skippingFactory = spyk(SkippingTask.Factory(Provider { SkippingTask() }))
private val preconditionFactory = spyk(PreconditionTask.Factory(Provider { PreconditionTask() }))
@BeforeEach @BeforeEach
fun setup() { fun setup() {
...@@ -63,6 +65,7 @@ class TaskControllerTest : BaseIOTest() { ...@@ -63,6 +65,7 @@ class TaskControllerTest : BaseIOTest() {
taskFactoryMap[SkippingTask::class.java] = skippingFactory taskFactoryMap[SkippingTask::class.java] = skippingFactory
taskFactoryMap[TimeoutTask::class.java] = timeoutFactory taskFactoryMap[TimeoutTask::class.java] = timeoutFactory
taskFactoryMap[TimeoutTask2::class.java] = timeoutFactory2 taskFactoryMap[TimeoutTask2::class.java] = timeoutFactory2
taskFactoryMap[PreconditionTask::class.java] = preconditionFactory
every { timeStamper.nowUTC } answers { every { timeStamper.nowUTC } answers {
Instant.now() Instant.now()
...@@ -340,6 +343,43 @@ class TaskControllerTest : BaseIOTest() { ...@@ -340,6 +343,43 @@ class TaskControllerTest : BaseIOTest() {
instance.close() instance.close()
} }
@Test
fun `tasks with preconditions that are not met are skipped`() = runBlockingTest {
val instance = createInstance(scope = this)
val request = DefaultTaskRequest(type = PreconditionTask::class)
preconditionFactory.arePreconditionsMet = false
instance.submit(request)
advanceUntilIdle()
val request2 = DefaultTaskRequest(type = PreconditionTask::class)
preconditionFactory.arePreconditionsMet = true
instance.submit(request2)
this.advanceUntilIdle()
val infoFinished = instance.tasks.first { emission ->
emission.any { it.taskState.executionState == TaskState.ExecutionState.FINISHED }
}
infoFinished.size shouldBe 2
infoFinished.single { it.taskState.request == request }.apply {
taskState.type shouldBe PreconditionTask::class
taskState.isSkipped shouldBe true
taskState.result shouldBe null
taskState.error shouldBe null
}
infoFinished.single { it.taskState.request == request2 }.apply {
taskState.type shouldBe PreconditionTask::class
taskState.isSkipped shouldBe false
taskState.result shouldNotBe null
taskState.error shouldBe null
}
instance.close()
}
@Test @Test
fun `collision behavior only affects task of same type`() = runBlockingTest { fun `collision behavior only affects task of same type`() = runBlockingTest {
val arguments = QueueingTask.Arguments(path = File(testDir, UUID.randomUUID().toString())) val arguments = QueueingTask.Arguments(path = File(testDir, UUID.randomUUID().toString()))
......
package de.rki.coronawarnapp.task.testtasks.precondition
import de.rki.coronawarnapp.task.Task
import de.rki.coronawarnapp.task.TaskFactory
import de.rki.coronawarnapp.task.common.DefaultProgress
import kotlinx.coroutines.channels.ConflatedBroadcastChannel
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.asFlow
import org.joda.time.Duration
import timber.log.Timber
import javax.inject.Provider
class PreconditionTask : Task<DefaultProgress, PreconditionTask.Result> {
private val internalProgress = ConflatedBroadcastChannel<DefaultProgress>()
override val progress: Flow<DefaultProgress> = internalProgress.asFlow()
private var isCanceled = false
override suspend fun run(arguments: Task.Arguments): Result = try {
Timber.d("Running with arguments=%s", arguments)
Result()
} finally {
Timber.i("Finished (isCanceled=$isCanceled).")
internalProgress.close()
}
override suspend fun cancel() {
Timber.w("cancel() called.")
isCanceled = true
}
class Config(private val arePreconditionsMet: Boolean) : TaskFactory.Config {
override val executionTimeout: Duration = Duration.standardSeconds(10)
override val collisionBehavior: TaskFactory.Config.CollisionBehavior =
TaskFactory.Config.CollisionBehavior.ENQUEUE
override val preconditions: List<suspend () -> Boolean>
get() = listOf { arePreconditionsMet }
}
class Result : Task.Result
class Factory constructor(
private val taskByDagger: Provider<PreconditionTask>
) : TaskFactory<DefaultProgress, Result> {
var arePreconditionsMet = true
override suspend fun createConfig(): TaskFactory.Config = Config(arePreconditionsMet)
override val taskProvider: () -> Task<DefaultProgress, Result> = { taskByDagger.get() }
}
}
...@@ -169,6 +169,48 @@ class TracingCardStateTest : BaseTest() { ...@@ -169,6 +169,48 @@ class TracingCardStateTest : BaseTest() {
} }
} }
@Test
fun `saved risk body when tracing is disabled`() {
createInstance(
riskState = CALCULATION_FAILED,
lastSuccessfulRiskState = LOW_RISK,
tracingStatus = Status.TRACING_INACTIVE
).apply {
getSavedRiskBody(context)
verify {
context
.getString(R.string.risk_card_no_calculation_possible_body_saved_risk)
.format(context.getString(R.string.risk_card_low_risk_headline))
}
}
createInstance(
riskState = CALCULATION_FAILED,
lastSuccessfulRiskState = INCREASED_RISK,
tracingStatus = Status.TRACING_INACTIVE
).apply {
getSavedRiskBody(context)
verify {
context
.getString(R.string.risk_card_no_calculation_possible_body_saved_risk)
.format(context.getString(R.string.risk_card_increased_risk_headline))
}
}
createInstance(
riskState = CALCULATION_FAILED,
lastSuccessfulRiskState = LOW_RISK,
tracingStatus = Status.TRACING_INACTIVE
).apply {
getSavedRiskBody(context)
verify {
context
.getString(R.string.risk_card_no_calculation_possible_body_saved_risk)
.format(context.getString(R.string.risk_card_low_risk_headline))
}
}
}
@Test @Test
fun `risk contact body is affected by risklevel`() { fun `risk contact body is affected by risklevel`() {
createInstance(riskState = CALCULATION_FAILED, daysWithEncounters = 0).apply { createInstance(riskState = CALCULATION_FAILED, daysWithEncounters = 0).apply {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment