Skip to content

Commit

Permalink
fix: Improve ReceiveMessagesTest with log asserts (#230)
Browse files Browse the repository at this point in the history
Fixes #49

@gnarea Notice the failing test. Feels weird that deleting the ThirdPartyEndpoint is not enough, since it triggers another error. Are we forgetting to delete something inside the `delete()` method?
  • Loading branch information
sdsantos authored May 18, 2022
1 parent c8071a8 commit 583e796
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import tech.relaycorp.awaladroid.endpoint.ThirdPartyEndpoint
import tech.relaycorp.awaladroid.endpoint.UnknownFirstPartyEndpointException
import tech.relaycorp.awaladroid.endpoint.UnknownThirdPartyEndpointException
import tech.relaycorp.awaladroid.storage.persistence.PersistenceException
import tech.relaycorp.relaynet.keystores.MissingKeyException
import tech.relaycorp.relaynet.messages.InvalidMessageException
import tech.relaycorp.relaynet.messages.Parcel
import tech.relaycorp.relaynet.pki.CertificationPath
Expand Down Expand Up @@ -62,7 +63,14 @@ public class IncomingMessage internal constructor(
)

val context = Awala.getContextOrThrow()
val serviceMessage = context.endpointManager.unwrapMessagePayload(parcel)

val serviceMessage = try {
context.endpointManager.unwrapMessagePayload(parcel)
} catch (e: MissingKeyException) {
throw UnknownThirdPartyEndpointException(
"Missing third-party endpoint session keys"
)
}
if (serviceMessage.type == PDA_PATH_TYPE) {
processPDAPath(serviceMessage.content, sender, recipientEndpoint)
ack()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import tech.relaycorp.awaladroid.GatewayException
import tech.relaycorp.awaladroid.GatewayProtocolException
import tech.relaycorp.awaladroid.common.Logging.logger
import tech.relaycorp.awaladroid.endpoint.UnknownFirstPartyEndpointException
import tech.relaycorp.awaladroid.endpoint.UnknownThirdPartyEndpointException
import tech.relaycorp.awaladroid.storage.persistence.PersistenceException
import tech.relaycorp.poweb.PoWebClient
import tech.relaycorp.relaynet.bindings.pdc.ClientBindingException
Expand Down Expand Up @@ -95,7 +96,7 @@ internal class ReceiveMessages(
} catch (exp: UnknownFirstPartyEndpointException) {
parcelCollection.disregard("Incoming parcel with invalid recipient", exp)
return@mapNotNull null
} catch (exp: UnknownFirstPartyEndpointException) {
} catch (exp: UnknownThirdPartyEndpointException) {
parcelCollection.disregard("Incoming parcel issues with invalid sender", exp)
return@mapNotNull null
} catch (exp: EnvelopedDataException) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package tech.relaycorp.awaladroid.messaging

import java.time.ZonedDateTime
import java.util.UUID
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.toCollection
import kotlinx.coroutines.test.runBlockingTest
import nl.altindag.log.LogCaptor
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Test
Expand Down Expand Up @@ -35,6 +35,7 @@ internal class ReceiveMessagesTest : MockContextTestCase() {
private val subject = ReceiveMessages { pdcClient }

private val serviceMessage = ServiceMessage("type", "content".toByteArray())
private val logCaptor = LogCaptor.forClass(ParcelCollection::class.java)

@Test
fun receiveParcelSuccessfully() = runBlockingTest {
Expand Down Expand Up @@ -95,15 +96,14 @@ internal class ReceiveMessagesTest : MockContextTestCase() {
@Test
fun receiveInvalidParcel_ackedButNotDeliveredToApp() = runBlockingTest {
val invalidParcel = Parcel(
recipientAddress = UUID.randomUUID().toString(),
payload = "1234".toByteArray(),
senderCertificate = PDACertPath.PRIVATE_ENDPOINT,
creationDate = ZonedDateTime.now().plusDays(1)
recipientAddress = KeyPairSet.PRIVATE_ENDPOINT.public.privateAddress,
payload = "".toByteArray(),
senderCertificate = PDACertPath.PRIVATE_ENDPOINT
)
var ackWasCalled = false
val parcelCollection = ParcelCollection(
parcelSerialized = invalidParcel.serialize(KeyPairSet.PRIVATE_ENDPOINT.private),
trustedCertificates = emptyList(),
trustedCertificates = emptyList(), // sender won't be trusted
ack = { ackWasCalled = true }
)
val collectParcelsCall = CollectParcelsCall(Result.success(flowOf(parcelCollection)))
Expand All @@ -115,6 +115,7 @@ internal class ReceiveMessagesTest : MockContextTestCase() {
assertTrue(collectParcelsCall.wasCalled)
assertTrue(messages.isEmpty())
assertTrue(ackWasCalled)
assertTrue(logCaptor.warnLogs.contains("Invalid incoming parcel"))
}

@Test
Expand All @@ -134,6 +135,47 @@ internal class ReceiveMessagesTest : MockContextTestCase() {
assertTrue(collectParcelsCall.wasCalled)
assertTrue(messages.isEmpty())
assertTrue(ackWasCalled)
assertTrue(logCaptor.warnLogs.contains("Malformed incoming parcel"))
}

@Test
fun receiveParcelWithUnknownRecipient_ackedButNotDeliveredToApp() = runBlockingTest {
val channel = createEndpointChannel(RecipientAddressType.PUBLIC)
val parcel = buildParcel(channel)
var ackWasCalled = false
val parcelCollection = parcel.toParcelCollection { ackWasCalled = true }
val collectParcelsCall = CollectParcelsCall(Result.success(flowOf(parcelCollection)))
pdcClient = MockPDCClient(collectParcelsCall)

channel.firstPartyEndpoint.delete()

val messages = subject.receive().toCollection(mutableListOf())

assertTrue(pdcClient.wasClosed)
assertTrue(collectParcelsCall.wasCalled)
assertTrue(messages.isEmpty())
assertTrue(ackWasCalled)
assertTrue(logCaptor.warnLogs.contains("Incoming parcel with invalid recipient"))
}

@Test
fun receiveParcelWithUnknownSender_ackedButNotDeliveredToApp() = runBlockingTest {
val channel = createEndpointChannel(RecipientAddressType.PUBLIC)
val parcel = buildParcel(channel)
var ackWasCalled = false
val parcelCollection = parcel.toParcelCollection { ackWasCalled = true }
val collectParcelsCall = CollectParcelsCall(Result.success(flowOf(parcelCollection)))
pdcClient = MockPDCClient(collectParcelsCall)

channel.thirdPartyEndpoint.delete()

val messages = subject.receive().toCollection(mutableListOf())

assertTrue(pdcClient.wasClosed)
assertTrue(collectParcelsCall.wasCalled)
assertTrue(messages.isEmpty())
assertTrue(ackWasCalled)
assertTrue(logCaptor.warnLogs.contains("Incoming parcel issues with invalid sender"))
}

@Test
Expand Down Expand Up @@ -168,6 +210,11 @@ internal class ReceiveMessagesTest : MockContextTestCase() {
assertTrue(pdcClient.wasClosed)
assertTrue(messages.isEmpty())
assertTrue(ackWasCalled)
assertTrue(
logCaptor.warnLogs.contains(
"Failed to decrypt parcel; sender might have used wrong key"
)
)
}

@Test
Expand Down Expand Up @@ -200,6 +247,11 @@ internal class ReceiveMessagesTest : MockContextTestCase() {
assertTrue(pdcClient.wasClosed)
assertTrue(messages.isEmpty())
assertTrue(ackWasCalled)
assertTrue(
logCaptor.warnLogs.contains(
"Incoming parcel did not encapsulate a valid service message"
)
)
}

private fun buildParcel(channel: EndpointChannel) = Parcel(
Expand Down

0 comments on commit 583e796

Please sign in to comment.