From f9c8011ce45436153c4a8bc4cde132b76ddf4dbc Mon Sep 17 00:00:00 2001
From: Ralf Gehrer <ralfgehrer@users.noreply.github.com>
Date: Wed, 25 Nov 2020 11:22:42 +0100
Subject: [PATCH] A connection timeout should not invalidate the cache
 (EXPOSUREAPP-3912) (#1698)

Co-authored-by: harambasicluka <64483219+harambasicluka@users.noreply.github.com>
Co-authored-by: Matthias Urhahn <matthias.urhahn@sap.com>
---
 .../diagnosiskeys/download/HourPackageSyncTool.kt | 11 ++++++++++-
 .../download/HourPackageSyncToolTest.kt           | 15 +++++++++++++++
 2 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/diagnosiskeys/download/HourPackageSyncTool.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/diagnosiskeys/download/HourPackageSyncTool.kt
index a15a2fa69..6cd2b7368 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/diagnosiskeys/download/HourPackageSyncTool.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/diagnosiskeys/download/HourPackageSyncTool.kt
@@ -9,6 +9,7 @@ import de.rki.coronawarnapp.diagnosiskeys.server.LocationCode
 import de.rki.coronawarnapp.diagnosiskeys.storage.CachedKey
 import de.rki.coronawarnapp.diagnosiskeys.storage.CachedKeyInfo.Type
 import de.rki.coronawarnapp.diagnosiskeys.storage.KeyCacheRepository
+import de.rki.coronawarnapp.exception.http.NetworkConnectTimeoutException
 import de.rki.coronawarnapp.storage.DeviceStorage
 import de.rki.coronawarnapp.util.TimeAndDateExtensions.toLocalDate
 import de.rki.coronawarnapp.util.TimeStamper
@@ -51,7 +52,12 @@ class HourPackageSyncTool @Inject constructor(
         val keysWereRevoked = revokeCachedKeys(downloadConfig.revokedHourPackages)
 
         val missingHours = targetLocations.mapNotNull {
-            determineMissingHours(it, forceIndexLookup || keysWereRevoked)
+            try {
+                determineMissingHours(it, forceIndexLookup || keysWereRevoked)
+            } catch (e: NetworkConnectTimeoutException) {
+                Timber.tag(TAG).i("missing hours sync failed due to network timeout")
+                return SyncResult(successful = false, newPackages = emptyList())
+            }
         }
         if (missingHours.isEmpty()) {
             Timber.tag(TAG).i("There were no missing hours.")
@@ -142,6 +148,9 @@ class HourPackageSyncTool @Inject constructor(
         val availableHours = run {
             val hoursToday = try {
                 keyServer.getHourIndex(location, today)
+            } catch (e: NetworkConnectTimeoutException) {
+                Timber.tag(TAG).e(e, "Failed to get today's hour due - not going to delete the cache.")
+                throw e
             } catch (e: IOException) {
                 Timber.tag(TAG).e(e, "failed to get today's hour index.")
                 emptyList()
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/diagnosiskeys/download/HourPackageSyncToolTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/diagnosiskeys/download/HourPackageSyncToolTest.kt
index f6dae8e55..5e50eeaed 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/diagnosiskeys/download/HourPackageSyncToolTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/diagnosiskeys/download/HourPackageSyncToolTest.kt
@@ -4,6 +4,7 @@ import de.rki.coronawarnapp.appconfig.mapping.RevokedKeyPackage
 import de.rki.coronawarnapp.diagnosiskeys.storage.CachedKey
 import de.rki.coronawarnapp.diagnosiskeys.storage.CachedKeyInfo
 import de.rki.coronawarnapp.diagnosiskeys.storage.CachedKeyInfo.Type
+import de.rki.coronawarnapp.exception.http.NetworkConnectTimeoutException
 import io.kotest.matchers.shouldBe
 import io.mockk.coEvery
 import io.mockk.coVerify
@@ -258,4 +259,18 @@ class HourPackageSyncToolTest : CommonSyncToolTest() {
 
         coVerify(exactly = 0) { keyServer.getHourIndex("EUR".loc, "2020-01-04".day) }
     }
+
+    @Test
+    fun `network connection time out does not clear the cache and returns an unsuccessful result`() = runBlockingTest {
+        coEvery { keyServer.getHourIndex(any(), any()) } throws NetworkConnectTimeoutException()
+
+        val instance = createInstance()
+        instance.syncMissingHourPackages(listOf("EUR".loc), false) shouldBe BaseKeyPackageSyncTool.SyncResult(
+            successful = false,
+            newPackages = emptyList()
+        )
+
+        coVerify(exactly = 1) { keyServer.getHourIndex("EUR".loc, "2020-01-04".day) }
+        coVerify(exactly = 0) { keyCache.delete(any()) }
+    }
 }
-- 
GitLab