diff --git a/libraries/pushstore/impl/build.gradle.kts b/libraries/pushstore/impl/build.gradle.kts index dca5c82a4d..5946e77694 100644 --- a/libraries/pushstore/impl/build.gradle.kts +++ b/libraries/pushstore/impl/build.gradle.kts @@ -20,6 +20,11 @@ plugins { android { namespace = "io.element.android.libraries.push.pushstore.impl" + + defaultConfig { + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + testInstrumentationRunnerArguments["clearPackageData"] = "true" + } } anvil { @@ -43,4 +48,13 @@ dependencies { testImplementation(libs.coroutines.test) testImplementation(projects.libraries.matrix.test) testImplementation(projects.services.appnavstate.test) + + androidTestImplementation(libs.coroutines.test) + androidTestImplementation(libs.test.core) + androidTestImplementation(libs.test.junit) + androidTestImplementation(libs.test.truth) + androidTestImplementation(libs.test.runner) + androidTestImplementation(projects.libraries.sessionStorage.test) + + coreLibraryDesugaring(libs.android.desugar) } diff --git a/libraries/pushstore/impl/src/androidTest/kotlin/io/element/android/libraries/pushstore/impl/DefaultUserPushStoreFactoryTest.kt b/libraries/pushstore/impl/src/androidTest/kotlin/io/element/android/libraries/pushstore/impl/DefaultUserPushStoreFactoryTest.kt new file mode 100644 index 0000000000..c87c772ddf --- /dev/null +++ b/libraries/pushstore/impl/src/androidTest/kotlin/io/element/android/libraries/pushstore/impl/DefaultUserPushStoreFactoryTest.kt @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2023 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.libraries.pushstore.impl + +import androidx.test.platform.app.InstrumentationRegistry +import io.element.android.libraries.matrix.api.core.SessionId +import io.element.android.libraries.pushstore.api.UserPushStore +import io.element.android.libraries.sessionstorage.test.observer.NoOpSessionObserver +import kotlinx.coroutines.runBlocking +import org.junit.Test +import kotlin.concurrent.thread + +/** + * Note: to clear the emulator, invoke: + * adb uninstall io.element.android.libraries.push.pushstore.impl.test + */ +class DefaultUserPushStoreFactoryTest { + + /** + * Ensure that creating UserPushStore is thread safe. + */ + @Test + fun testParallelCreation() { + val context = InstrumentationRegistry.getInstrumentation().targetContext.applicationContext + val sessionId = SessionId("@alice:server.org") + val userPushStoreFactory = DefaultUserPushStoreFactory(context, NoOpSessionObserver()) + var userPushStore1: UserPushStore? = null + val thread1 = thread { + userPushStore1 = userPushStoreFactory.create(sessionId) + } + var userPushStore2: UserPushStore? = null + val thread2 = thread { + userPushStore2 = userPushStoreFactory.create(sessionId) + } + thread1.join() + thread2.join() + runBlocking { + userPushStore1!!.areNotificationEnabledForDevice() + userPushStore2!!.areNotificationEnabledForDevice() + } + } +} diff --git a/libraries/session-storage/test/build.gradle.kts b/libraries/session-storage/test/build.gradle.kts new file mode 100644 index 0000000000..0c8de84669 --- /dev/null +++ b/libraries/session-storage/test/build.gradle.kts @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2023 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. + */ +plugins { + id("io.element.android-library") +} + +android { + namespace = "io.element.android.libraries.sessionstorage.test" +} + +dependencies { + implementation(projects.libraries.sessionStorage.api) +} diff --git a/libraries/session-storage/test/src/main/kotlin/io/element/android/libraries/sessionstorage/test/observer/NoOpSessionObserver.kt b/libraries/session-storage/test/src/main/kotlin/io/element/android/libraries/sessionstorage/test/observer/NoOpSessionObserver.kt new file mode 100644 index 0000000000..03487a3701 --- /dev/null +++ b/libraries/session-storage/test/src/main/kotlin/io/element/android/libraries/sessionstorage/test/observer/NoOpSessionObserver.kt @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2023 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.libraries.sessionstorage.test.observer + +import io.element.android.libraries.sessionstorage.api.observer.SessionListener +import io.element.android.libraries.sessionstorage.api.observer.SessionObserver + +class NoOpSessionObserver : SessionObserver { + override fun addListener(listener: SessionListener) = Unit + override fun removeListener(listener: SessionListener) = Unit +}