Skip to content

Commit

Permalink
chore: Storage testing (#66)
Browse files Browse the repository at this point in the history
  • Loading branch information
sdsantos authored Mar 17, 2021
1 parent 4c3a077 commit 9b5b0c9
Show file tree
Hide file tree
Showing 2 changed files with 177 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package tech.relaycorp.awaladroid.storage

import androidx.annotation.VisibleForTesting
import java.security.KeyPair
import tech.relaycorp.awaladroid.endpoint.PrivateThirdPartyEndpointData
import tech.relaycorp.awaladroid.endpoint.PublicThirdPartyEndpointData
Expand Down Expand Up @@ -51,7 +52,8 @@ constructor(

internal open class Module<T>(
private val persistence: Persistence,
private val prefix: String,
@VisibleForTesting
internal val prefix: String,
private val serializer: (T) -> ByteArray,
private val deserializer: (ByteArray) -> T
) {
Expand Down
174 changes: 174 additions & 0 deletions lib/src/test/java/tech/relaycorp/awaladroid/storage/StorageImplTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
package tech.relaycorp.awaladroid.storage

import com.nhaarman.mockitokotlin2.any
import com.nhaarman.mockitokotlin2.eq
import com.nhaarman.mockitokotlin2.mock
import com.nhaarman.mockitokotlin2.verify
import com.nhaarman.mockitokotlin2.whenever
import java.util.UUID
import kotlinx.coroutines.test.runBlockingTest
import org.junit.Assert.assertArrayEquals
import org.junit.Assert.assertTrue
import org.junit.Test
import tech.relaycorp.awaladroid.endpoint.AuthorizationBundle
import tech.relaycorp.awaladroid.endpoint.PrivateThirdPartyEndpointData
import tech.relaycorp.awaladroid.endpoint.PublicThirdPartyEndpointData
import tech.relaycorp.awaladroid.storage.persistence.Persistence
import tech.relaycorp.relaynet.testing.pki.KeyPairSet
import tech.relaycorp.relaynet.testing.pki.PDACertPath

internal class StorageImplTest {

private val persistence = mock<Persistence>()
private val storage = StorageImpl(persistence)

@Test
fun identityKeyPair() = runBlockingTest {
storage.identityKeyPair.testGet(
KeyPairSet.PRIVATE_GW.private.encoded,
KeyPairSet.PRIVATE_GW
) { a, b -> a.private == b.private && a.public == b.public }
storage.identityKeyPair.testSet(
KeyPairSet.PRIVATE_GW,
KeyPairSet.PRIVATE_GW.private.encoded
)
storage.identityKeyPair.testDelete()
storage.identityKeyPair.testDeleteAll()
storage.identityKeyPair.testList()
}

@Test
fun identityCertificate() = runBlockingTest {
storage.identityCertificate.testGet(
PDACertPath.PRIVATE_ENDPOINT.serialize(),
PDACertPath.PRIVATE_ENDPOINT
)
storage.identityCertificate.testSet(
PDACertPath.PRIVATE_ENDPOINT,
PDACertPath.PRIVATE_ENDPOINT.serialize()
)
storage.identityCertificate.testDelete()
storage.identityCertificate.testDeleteAll()
storage.identityCertificate.testList()
}

@Test
fun gatewayCertificate() = runBlockingTest {
storage.gatewayCertificate.testGet(
PDACertPath.PRIVATE_ENDPOINT.serialize(),
PDACertPath.PRIVATE_ENDPOINT
)
storage.gatewayCertificate.testSet(
PDACertPath.PRIVATE_ENDPOINT,
PDACertPath.PRIVATE_ENDPOINT.serialize()
)
storage.gatewayCertificate.testDelete()
}

@Test
fun privateThirdParty() = runBlockingTest {
val data = PrivateThirdPartyEndpointData(
PDACertPath.PRIVATE_ENDPOINT,
AuthorizationBundle(
PDACertPath.PDA.serialize(),
listOf(PDACertPath.PRIVATE_GW.serialize())
)
)
val rawData = data.serialize()

storage.privateThirdParty.testGet(rawData, data) { a, b ->
a.identityCertificate.subjectPublicKey == b.identityCertificate.subjectPublicKey &&
a.authBundle.pdaSerialized.contentEquals(b.authBundle.pdaSerialized) &&
a.authBundle.pdaChainSerialized.mapIndexed { index, bytes ->
bytes.contentEquals(b.authBundle.pdaChainSerialized[index])
}.all { it }
}
storage.privateThirdParty.testSet(data, rawData)
storage.privateThirdParty.testDelete()
storage.privateThirdParty.testDeleteAll()
storage.privateThirdParty.testList()
}

@Test
fun publicThirdParty() = runBlockingTest {
val data = PublicThirdPartyEndpointData(
"example.org",
PDACertPath.PUBLIC_GW
)
val rawData = data.serialize()

storage.publicThirdParty.testGet(rawData, data)
storage.publicThirdParty.testSet(data, rawData)
storage.publicThirdParty.testDelete()
storage.publicThirdParty.testDeleteAll()
storage.publicThirdParty.testList()
}

// Helpers

private suspend fun <T : Any> StorageImpl.Module<T>.testGet(
rawData: ByteArray,
expectedOutput: T,
equalityCheck: ((T, T) -> Boolean) = Any::equals
) {
val key = UUID.randomUUID().toString()
whenever(persistence.get(any())).thenReturn(rawData)
val output = get(key)!!
verify(persistence).get(eq("$prefix$key"))
assertTrue(
"expected $expectedOutput, got $output",
equalityCheck(expectedOutput, output)
)
}

private suspend fun <T> StorageImpl.Module<T>.testSet(
data: T,
expectedRawData: ByteArray
) {
val key = UUID.randomUUID().toString()
set(key, data)
verify(persistence).set(eq("$prefix$key"), eq(expectedRawData))
}

private suspend fun <T> StorageImpl.Module<T>.testDelete() {
val key = UUID.randomUUID().toString()
delete(key)
verify(persistence).delete(eq("$prefix$key"))
}

private suspend fun <T> StorageImpl.Module<T>.testDeleteAll() {
deleteAll()
verify(persistence).deleteAll(eq(prefix))
}

private suspend fun <T> StorageImpl.Module<T>.testList() {
val key = UUID.randomUUID().toString()
val keyWithPrefix = prefix + key
whenever(persistence.list(any())).thenReturn(listOf(keyWithPrefix))
val result = list()
verify(persistence).list(eq(prefix))
assertArrayEquals(arrayOf(key), result.toTypedArray())
}

private suspend fun <T : Any> StorageImpl.SingleModule<T>.testGet(
rawData: ByteArray,
expectedOutput: T,
equalityCheck: ((T, T) -> Boolean) = Any::equals
) {
whenever(persistence.get(any())).thenReturn(rawData)
val output = get()!!
verify(persistence).get(eq("${prefix}base"))
assertTrue(
"expected $expectedOutput, got $output",
equalityCheck(expectedOutput, output)
)
}

private suspend fun <T> StorageImpl.SingleModule<T>.testSet(
data: T,
expectedRawData: ByteArray
) {
set(data)
verify(persistence).set(eq("${prefix}base"), eq(expectedRawData))
}
}

0 comments on commit 9b5b0c9

Please sign in to comment.