Add receipt processing benchmark tests.

This commit is contained in:
Cody Henthorne
2026-02-25 08:59:05 -05:00
parent b6dd4a3579
commit c06944da13
13 changed files with 375 additions and 75 deletions

View File

@@ -0,0 +1,44 @@
/*
* Copyright 2026 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
package org.thoughtcrime.benchmark
import androidx.benchmark.macro.ExperimentalMetricApi
import androidx.benchmark.macro.TraceSectionMetric
import androidx.benchmark.macro.TraceSectionMetric.Mode
@OptIn(ExperimentalMetricApi::class)
object BenchmarkMetrics {
val incomingMessageObserver: List<TraceSectionMetric>
get() = listOf(
TraceSectionMetric("IncomingMessageObserver#decryptMessage", Mode.Average),
TraceSectionMetric("IncomingMessageObserver#perMessageTransaction", Mode.Average),
TraceSectionMetric("IncomingMessageObserver#processMessage", Mode.Average),
TraceSectionMetric("IncomingMessageObserver#totalProcessing", Mode.Sum)
)
val dataMessageProcessor: List<TraceSectionMetric>
get() = listOf(
TraceSectionMetric("DataMessageProcessor#gv2PreProcessing", Mode.Average),
TraceSectionMetric("DataMessageProcessor#messageInsert", Mode.Average),
TraceSectionMetric("DataMessageProcessor#postProcess", Mode.Average)
)
val messageContentProcessor: List<TraceSectionMetric>
get() = listOf(
TraceSectionMetric("MessageContentProcessor#handleMessage", Mode.Average)
)
val deliveryReceipt: List<TraceSectionMetric>
get() = listOf(
TraceSectionMetric("ReceiptMessageProcessor#incrementDeliveryReceiptCounts", Mode.Average)
)
val readReceipt: List<TraceSectionMetric>
get() = listOf(
TraceSectionMetric("ReceiptMessageProcessor#incrementReadReceiptCounts", Mode.Average)
)
}

View File

@@ -22,6 +22,14 @@ object BenchmarkSetup {
device.benchmarkCommandBroadcast("group-send")
}
fun setupGroupDeliveryReceipt(device: UiDevice) {
device.benchmarkCommandBroadcast("group-delivery-receipt")
}
fun setupGroupReadReceipt(device: UiDevice) {
device.benchmarkCommandBroadcast("group-read-receipt")
}
fun releaseMessages(device: UiDevice) {
device.benchmarkCommandBroadcast("release-messages")
}

View File

@@ -8,11 +8,11 @@ package org.thoughtcrime.benchmark
import androidx.annotation.RequiresApi
import androidx.benchmark.macro.CompilationMode
import androidx.benchmark.macro.ExperimentalMetricApi
import androidx.benchmark.macro.TraceSectionMetric
import androidx.benchmark.macro.TraceSectionMetric.Mode
import androidx.benchmark.macro.MacrobenchmarkScope
import androidx.benchmark.macro.junit4.MacrobenchmarkRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.uiautomator.By
import androidx.test.uiautomator.UiDevice
import androidx.test.uiautomator.Until
import org.junit.Rule
import org.junit.Test
@@ -30,62 +30,22 @@ class GroupMessageProcessingBenchmarks {
@Test
fun groupMessageReceiveOnConversationList() {
run(withConversationOpen = false)
runGroupMessageReceive(withConversationOpen = false)
}
@Test
fun individualMessageReceiveOnConversation() {
run(withConversationOpen = true)
fun groupMessageReceiveOnConversation() {
runGroupMessageReceive(withConversationOpen = true)
}
private fun run(withConversationOpen: Boolean) {
private fun runGroupMessageReceive(withConversationOpen: Boolean) {
benchmarkRule.measureRepeated(
packageName = "org.thoughtcrime.securesms.benchmark",
metrics = listOf(
TraceSectionMetric(
sectionName = "IncomingMessageObserver#decryptMessage",
mode = Mode.Average
),
TraceSectionMetric(
sectionName = "IncomingMessageObserver#perMessageTransaction",
mode = Mode.Average
),
TraceSectionMetric(
sectionName = "DataMessageProcessor#gv2PreProcessing",
mode = Mode.Average
),
TraceSectionMetric(
sectionName = "DataMessageProcessor#messageInsert",
mode = Mode.Average
),
TraceSectionMetric(
sectionName = "DataMessageProcessor#postProcess",
mode = Mode.Average
),
TraceSectionMetric(
sectionName = "IncomingMessageObserver#processMessage",
mode = Mode.Average
),
TraceSectionMetric(
sectionName = "IncomingMessageObserver#totalProcessing",
mode = Mode.Sum
)
),
metrics = BenchmarkMetrics.incomingMessageObserver + BenchmarkMetrics.messageContentProcessor + BenchmarkMetrics.dataMessageProcessor,
iterations = 5,
compilationMode = CompilationMode.Partial(),
setupBlock = {
BenchmarkSetup.setup("group-message-send", device)
killProcess()
startActivityAndWait()
device.waitForIdle()
BenchmarkSetup.setupGroupSend(device)
val uiObject = device.wait(Until.findObject(By.textContains("Title")), 5_000)
if (withConversationOpen) {
uiObject.click()
}
setupGroup("group-message-send", BenchmarkSetup::setupGroupSend, withConversationOpen)
}
) {
@@ -94,4 +54,76 @@ class GroupMessageProcessingBenchmarks {
device.wait(Until.hasObject(By.textContains("505")),10_000L)
}
}
@Test
fun groupDeliveryReceiptOnConversationList() {
runGroupDeliveryReceipt(withConversationOpen = false)
}
@Test
fun groupDeliveryReceiptOnConversation() {
runGroupDeliveryReceipt(withConversationOpen = true)
}
private fun runGroupDeliveryReceipt(withConversationOpen: Boolean) {
benchmarkRule.measureRepeated(
packageName = "org.thoughtcrime.securesms.benchmark",
metrics = BenchmarkMetrics.incomingMessageObserver + BenchmarkMetrics.messageContentProcessor + BenchmarkMetrics.deliveryReceipt,
iterations = 5,
compilationMode = CompilationMode.Partial(),
setupBlock = {
setupGroup("group-delivery-receipt", BenchmarkSetup::setupGroupDeliveryReceipt, withConversationOpen)
}
) {
BenchmarkSetup.releaseMessages(device)
Thread.sleep(10_000)
}
}
@Test
fun groupReadReceiptOnConversationList() {
runGroupReadReceipt(withConversationOpen = false)
}
@Test
fun groupReadReceiptOnConversation() {
runGroupReadReceipt(withConversationOpen = true)
}
private fun runGroupReadReceipt(withConversationOpen: Boolean) {
benchmarkRule.measureRepeated(
packageName = "org.thoughtcrime.securesms.benchmark",
metrics = BenchmarkMetrics.incomingMessageObserver + BenchmarkMetrics.messageContentProcessor + BenchmarkMetrics.readReceipt,
iterations = 5,
compilationMode = CompilationMode.Partial(),
setupBlock = {
setupGroup("group-read-receipt", BenchmarkSetup::setupGroupReadReceipt, withConversationOpen)
}
) {
BenchmarkSetup.releaseMessages(device)
Thread.sleep(10_000)
}
}
private fun MacrobenchmarkScope.setupGroup(
setupType: String,
prepareCommand: (UiDevice) -> Unit,
withConversationOpen: Boolean
) {
BenchmarkSetup.setup(setupType, device)
killProcess()
startActivityAndWait()
device.waitForIdle()
prepareCommand(device)
device.wait(Until.findObject(By.textContains("Title")), 5_000)
if (withConversationOpen) {
device.waitForIdle()
device.findObject(By.textContains("Title")).click()
}
}
}

View File

@@ -8,8 +8,6 @@ package org.thoughtcrime.benchmark
import androidx.annotation.RequiresApi
import androidx.benchmark.macro.CompilationMode
import androidx.benchmark.macro.ExperimentalMetricApi
import androidx.benchmark.macro.TraceSectionMetric
import androidx.benchmark.macro.TraceSectionMetric.Mode
import androidx.benchmark.macro.junit4.MacrobenchmarkRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.uiautomator.By
@@ -41,24 +39,7 @@ class MessageProcessingBenchmarks {
private fun run(withConversationOpen: Boolean) {
benchmarkRule.measureRepeated(
packageName = "org.thoughtcrime.securesms.benchmark",
metrics = listOf(
TraceSectionMetric(
sectionName = "IncomingMessageObserver#decryptMessage",
mode = Mode.Average
),
TraceSectionMetric(
sectionName = "MessageContentProcessor#handleMessage",
mode = Mode.Average
),
TraceSectionMetric(
sectionName = "IncomingMessageObserver#processMessage",
mode = Mode.Average
),
TraceSectionMetric(
sectionName = "IncomingMessageObserver#totalProcessing",
mode = Mode.Sum
)
),
metrics = BenchmarkMetrics.incomingMessageObserver + BenchmarkMetrics.messageContentProcessor,
iterations = 5,
compilationMode = CompilationMode.Partial(),
setupBlock = {