diff --git a/features/migration/impl/src/main/kotlin/io/element/android/features/migration/impl/migrations/AppMigration07.kt b/features/migration/impl/src/main/kotlin/io/element/android/features/migration/impl/migrations/AppMigration07.kt new file mode 100644 index 0000000000..c0da439f9b --- /dev/null +++ b/features/migration/impl/src/main/kotlin/io/element/android/features/migration/impl/migrations/AppMigration07.kt @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2024 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.features.migration.impl.migrations + +import com.squareup.anvil.annotations.ContributesMultibinding +import io.element.android.features.rageshake.api.logs.LogFilesRemover +import io.element.android.libraries.di.AppScope +import javax.inject.Inject + +/** + * Delete the previous log files. + */ +@ContributesMultibinding(AppScope::class) +class AppMigration07 @Inject constructor( + private val logFilesRemover: LogFilesRemover, +) : AppMigration { + override val order: Int = 7 + + override suspend fun migrate() { + logFilesRemover.perform { file -> + file.name.startsWith("logs-") + } + } +} diff --git a/features/migration/impl/src/test/kotlin/io/element/android/features/migration/impl/migrations/AppMigration07Test.kt b/features/migration/impl/src/test/kotlin/io/element/android/features/migration/impl/migrations/AppMigration07Test.kt new file mode 100644 index 0000000000..06bd809038 --- /dev/null +++ b/features/migration/impl/src/test/kotlin/io/element/android/features/migration/impl/migrations/AppMigration07Test.kt @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2024 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.features.migration.impl.migrations + +import com.google.common.truth.Truth.assertThat +import io.element.android.features.rageshake.test.logs.FakeLogFilesRemover +import io.element.android.tests.testutils.lambda.lambdaRecorder +import kotlinx.coroutines.test.runTest +import org.junit.Test +import java.io.File + +class AppMigration07Test { + @Test + fun `test migration`() = runTest { + val performLambda = lambdaRecorder<(File) -> Boolean, Unit> { predicate -> + // Test the predicate + assertThat(predicate(File("logs-0433.log.gz"))).isTrue() + assertThat(predicate(File("logs.2024-08-01-20.log.gz"))).isFalse() + } + val logsFileRemover = FakeLogFilesRemover(performLambda = performLambda) + val migration = AppMigration07(logsFileRemover) + migration.migrate() + logsFileRemover.performLambda.assertions().isCalledOnce() + } +} diff --git a/features/rageshake/api/src/main/kotlin/io/element/android/features/rageshake/api/logs/LogFilesRemover.kt b/features/rageshake/api/src/main/kotlin/io/element/android/features/rageshake/api/logs/LogFilesRemover.kt index dd73133060..2b1fa29261 100644 --- a/features/rageshake/api/src/main/kotlin/io/element/android/features/rageshake/api/logs/LogFilesRemover.kt +++ b/features/rageshake/api/src/main/kotlin/io/element/android/features/rageshake/api/logs/LogFilesRemover.kt @@ -16,6 +16,12 @@ package io.element.android.features.rageshake.api.logs +import java.io.File + interface LogFilesRemover { - suspend fun perform() + /** + * Perform the log files removal. + * @param predicate a predicate to filter the files to remove. By default, all files are removed. + */ + suspend fun perform(predicate: (File) -> Boolean = { true }) } diff --git a/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/logs/DefaultLogFilesRemover.kt b/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/logs/DefaultLogFilesRemover.kt index c0c7c8c346..dd551d517e 100644 --- a/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/logs/DefaultLogFilesRemover.kt +++ b/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/logs/DefaultLogFilesRemover.kt @@ -20,13 +20,14 @@ import com.squareup.anvil.annotations.ContributesBinding import io.element.android.features.rageshake.api.logs.LogFilesRemover import io.element.android.features.rageshake.impl.reporter.DefaultBugReporter import io.element.android.libraries.di.AppScope +import java.io.File import javax.inject.Inject @ContributesBinding(AppScope::class) class DefaultLogFilesRemover @Inject constructor( private val bugReporter: DefaultBugReporter, ) : LogFilesRemover { - override suspend fun perform() { - bugReporter.deleteAllFiles() + override suspend fun perform(predicate: (File) -> Boolean) { + bugReporter.deleteAllFiles(predicate) } } diff --git a/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/reporter/DefaultBugReporter.kt b/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/reporter/DefaultBugReporter.kt index 72e668c3f4..925577ce77 100755 --- a/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/reporter/DefaultBugReporter.kt +++ b/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/reporter/DefaultBugReporter.kt @@ -301,9 +301,11 @@ class DefaultBugReporter @Inject constructor( } } - suspend fun deleteAllFiles() { + suspend fun deleteAllFiles(predicate: (File) -> Boolean) { withContext(coroutineDispatchers.io) { - getLogFiles().forEach { it.safeDelete() } + getLogFiles() + .filter(predicate) + .forEach { it.safeDelete() } } } diff --git a/features/rageshake/test/src/main/kotlin/io/element/android/features/rageshake/test/logs/FakeLogFilesRemover.kt b/features/rageshake/test/src/main/kotlin/io/element/android/features/rageshake/test/logs/FakeLogFilesRemover.kt index a416f2eeb4..7d5d880a7b 100644 --- a/features/rageshake/test/src/main/kotlin/io/element/android/features/rageshake/test/logs/FakeLogFilesRemover.kt +++ b/features/rageshake/test/src/main/kotlin/io/element/android/features/rageshake/test/logs/FakeLogFilesRemover.kt @@ -17,13 +17,14 @@ package io.element.android.features.rageshake.test.logs import io.element.android.features.rageshake.api.logs.LogFilesRemover -import io.element.android.tests.testutils.lambda.LambdaNoParamRecorder +import io.element.android.tests.testutils.lambda.LambdaOneParamRecorder import io.element.android.tests.testutils.lambda.lambdaRecorder +import java.io.File class FakeLogFilesRemover( - var performLambda: LambdaNoParamRecorder = lambdaRecorder { -> }, + var performLambda: LambdaOneParamRecorder<(File) -> Boolean, Unit> = lambdaRecorder<(File) -> Boolean, Unit> { }, ) : LogFilesRemover { - override suspend fun perform() { - performLambda() + override suspend fun perform(predicate: (File) -> Boolean) { + performLambda(predicate) } }