mirror of
https://github.com/signalapp/Signal-Android.git
synced 2025-12-24 13:08:46 +00:00
Cleanup MessageContentProcessorTestV2.
This commit is contained in:
committed by
Greyson Parrelli
parent
a874efee4e
commit
36ef36be61
@@ -8,6 +8,7 @@ import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.signal.core.util.ThreadUtil
|
||||
import org.signal.core.util.logging.Log
|
||||
import org.signal.core.util.readToList
|
||||
import org.signal.core.util.select
|
||||
import org.signal.core.util.toSingleLine
|
||||
@@ -38,9 +39,10 @@ import java.util.Optional
|
||||
class MessageContentProcessorTestV2 {
|
||||
|
||||
companion object {
|
||||
private val TAGS = listOf(MessageContentProcessorV2.TAG, AttachmentTable.TAG)
|
||||
private val TAGS = listOf(MessageContentProcessor.TAG, MessageContentProcessorV2.TAG, AttachmentTable.TAG)
|
||||
|
||||
private val GENERALIZE_TAG = mapOf(
|
||||
MessageContentProcessor.TAG to "MCP",
|
||||
MessageContentProcessorV2.TAG to "MCP",
|
||||
AttachmentTable.TAG to AttachmentTable.TAG
|
||||
)
|
||||
@@ -78,12 +80,12 @@ class MessageContentProcessorTestV2 {
|
||||
fun textMessage() {
|
||||
var start = envelopeTimestamp
|
||||
|
||||
val messages: List<TestMessage> = (0 until 1).map {
|
||||
val messages: List<TestMessage> = (0 until 100).map {
|
||||
start += 200
|
||||
TestMessage(
|
||||
envelope = MessageContentFuzzer.envelope(start),
|
||||
content = MessageContentFuzzer.fuzzTextMessage(),
|
||||
metadata = MessageContentFuzzer.fuzzMetadata(harness.others[0], harness.self.id),
|
||||
metadata = MessageContentFuzzer.envelopeMetadata(harness.others[0], harness.self.id),
|
||||
serverDeliveredTimestamp = MessageContentFuzzer.fuzzServerDeliveredTimestamp(start)
|
||||
)
|
||||
}
|
||||
@@ -98,59 +100,52 @@ class MessageContentProcessorTestV2 {
|
||||
fun mediaMessage() {
|
||||
var start = envelopeTimestamp
|
||||
|
||||
val messages: List<TestMessage> = (0 until 10).map {
|
||||
val textMessages: List<TestMessage> = (0 until 10).map {
|
||||
start += 200
|
||||
TestMessage(
|
||||
envelope = MessageContentFuzzer.envelope(start),
|
||||
content = MessageContentFuzzer.fuzzTextMessage(),
|
||||
metadata = MessageContentFuzzer.fuzzMetadata(harness.others[0], harness.self.id),
|
||||
metadata = MessageContentFuzzer.envelopeMetadata(harness.others[0], harness.self.id),
|
||||
serverDeliveredTimestamp = MessageContentFuzzer.fuzzServerDeliveredTimestamp(start)
|
||||
)
|
||||
}
|
||||
|
||||
val moreMessages: List<TestMessage> = (0 until 10).map {
|
||||
val firstBatchMediaMessages: List<TestMessage> = (0 until 10).map {
|
||||
start += 200
|
||||
TestMessage(
|
||||
envelope = MessageContentFuzzer.envelope(start),
|
||||
content = MessageContentFuzzer.fuzzMediaMessageWithBody(messages),
|
||||
metadata = MessageContentFuzzer.fuzzMetadata(harness.others[0], harness.self.id),
|
||||
content = MessageContentFuzzer.fuzzMediaMessageWithBody(textMessages),
|
||||
metadata = MessageContentFuzzer.envelopeMetadata(harness.others[0], harness.self.id),
|
||||
serverDeliveredTimestamp = MessageContentFuzzer.fuzzServerDeliveredTimestamp(start)
|
||||
)
|
||||
}
|
||||
|
||||
val evenMoreMessages: List<TestMessage> = (0 until 10).map {
|
||||
val secondBatchNoContentMediaMessages: List<TestMessage> = (0 until 10).map {
|
||||
start += 200
|
||||
TestMessage(
|
||||
envelope = MessageContentFuzzer.envelope(start),
|
||||
content = MessageContentFuzzer.fuzzMediaMessageNoContent(messages + moreMessages),
|
||||
metadata = MessageContentFuzzer.fuzzMetadata(harness.others[0], harness.self.id),
|
||||
content = MessageContentFuzzer.fuzzMediaMessageNoContent(textMessages + firstBatchMediaMessages),
|
||||
metadata = MessageContentFuzzer.envelopeMetadata(harness.others[0], harness.self.id),
|
||||
serverDeliveredTimestamp = MessageContentFuzzer.fuzzServerDeliveredTimestamp(start)
|
||||
)
|
||||
}
|
||||
|
||||
val evenMoreMoreMessages: List<TestMessage> = (0 until 10).map {
|
||||
val thirdBatchNoTextMediaMessagesMessages: List<TestMessage> = (0 until 10).map {
|
||||
start += 200
|
||||
TestMessage(
|
||||
envelope = MessageContentFuzzer.envelope(start),
|
||||
content = MessageContentFuzzer.fuzzMediaMessageNoText(messages + moreMessages),
|
||||
metadata = MessageContentFuzzer.fuzzMetadata(harness.others[0], harness.self.id),
|
||||
content = MessageContentFuzzer.fuzzMediaMessageNoText(textMessages + firstBatchMediaMessages),
|
||||
metadata = MessageContentFuzzer.envelopeMetadata(harness.others[0], harness.self.id),
|
||||
serverDeliveredTimestamp = MessageContentFuzzer.fuzzServerDeliveredTimestamp(start)
|
||||
)
|
||||
}
|
||||
|
||||
testResult.runV2(messages + moreMessages + evenMoreMessages + evenMoreMoreMessages)
|
||||
testResult.runV1(messages + moreMessages + evenMoreMessages + evenMoreMoreMessages)
|
||||
testResult.runV2(textMessages + firstBatchMediaMessages + secondBatchNoContentMediaMessages + thirdBatchNoTextMediaMessagesMessages)
|
||||
testResult.runV1(textMessages + firstBatchMediaMessages + secondBatchNoContentMediaMessages + thirdBatchNoTextMediaMessagesMessages)
|
||||
|
||||
testResult.assert()
|
||||
}
|
||||
|
||||
// @Test
|
||||
// fun fuzzIt() {
|
||||
// MessageContentFuzzer.fuzzProto(SignalServiceProtos.DataMessage.Contact.Name::class)
|
||||
// MessageContentFuzzer.fuzzProto(SignalServiceProtos.DataMessage.Contact.Avatar::class)
|
||||
// MessageContentFuzzer.fuzzProto(SignalServiceProtos.DataMessage.Contact.Email::class)
|
||||
// }
|
||||
|
||||
private inner class TestResults {
|
||||
|
||||
private lateinit var v1Logs: List<Entry>
|
||||
@@ -285,8 +280,8 @@ class MessageContentProcessorTestV2 {
|
||||
Cursor.FIELD_TYPE_BLOB -> Base64.encodeToString(cursor.getBlob(index), 0)
|
||||
else -> cursor.getString(index)
|
||||
}
|
||||
if (table == MessageTable.TABLE_NAME && column == "type") {
|
||||
data = thing(cursor.getLong(index))
|
||||
if (table == MessageTable.TABLE_NAME && column == MessageTable.TYPE) {
|
||||
data = typeColumnToString(cursor.getLong(index))
|
||||
}
|
||||
|
||||
column to data
|
||||
@@ -319,7 +314,7 @@ class MessageContentProcessorTestV2 {
|
||||
return SignalServiceContent.createFromProto(contentProto)!!
|
||||
}
|
||||
|
||||
fun thing(type: Long): String {
|
||||
fun typeColumnToString(type: Long): String {
|
||||
return """
|
||||
isOutgoingMessageType:${isOutgoingMessageType(type)}
|
||||
isForcedSms:${type and MessageTypes.MESSAGE_FORCE_SMS_BIT != 0L}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package org.thoughtcrime.securesms.testing
|
||||
|
||||
import com.google.protobuf.ByteString
|
||||
import org.signal.core.util.logging.Log
|
||||
import org.thoughtcrime.securesms.database.model.toProtoByteString
|
||||
import org.thoughtcrime.securesms.messages.TestMessage
|
||||
import org.thoughtcrime.securesms.recipients.Recipient
|
||||
@@ -16,13 +15,11 @@ import org.whispersystems.signalservice.internal.push.SignalServiceProtos.Envelo
|
||||
import java.util.UUID
|
||||
import kotlin.random.Random
|
||||
import kotlin.random.nextInt
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.reflect.KFunction
|
||||
import kotlin.reflect.full.declaredFunctions
|
||||
import kotlin.reflect.full.functions
|
||||
import kotlin.reflect.jvm.jvmErasure
|
||||
import kotlin.time.Duration.Companion.days
|
||||
|
||||
/**
|
||||
* Random but deterministic fuzzer for create various message content protos.
|
||||
*/
|
||||
object MessageContentFuzzer {
|
||||
|
||||
private val mediaTypes = listOf("image/png", "image/jpeg", "image/heic", "image/heif", "image/avif", "image/webp", "image/gif", "audio/aac", "audio/*", "video/mp4", "video/*", "text/x-vcard", "text/x-signal-plain", "application/x-signal-view-once", "*/*", "application/octet-stream")
|
||||
@@ -30,6 +27,9 @@ object MessageContentFuzzer {
|
||||
|
||||
private val random = Random(1)
|
||||
|
||||
/**
|
||||
* Create an [Envelope].
|
||||
*/
|
||||
fun envelope(timestamp: Long): Envelope {
|
||||
return Envelope.newBuilder()
|
||||
.setTimestamp(timestamp)
|
||||
@@ -38,6 +38,25 @@ object MessageContentFuzzer {
|
||||
.build()
|
||||
}
|
||||
|
||||
/**
|
||||
* Create metadata to match an [Envelope].
|
||||
*/
|
||||
fun envelopeMetadata(source: RecipientId, destination: RecipientId): EnvelopeMetadata {
|
||||
return EnvelopeMetadata(
|
||||
sourceServiceId = Recipient.resolved(source).requireServiceId(),
|
||||
sourceE164 = null,
|
||||
sourceDeviceId = 1,
|
||||
sealedSender = true,
|
||||
groupId = null,
|
||||
destinationServiceId = Recipient.resolved(destination).requireServiceId()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a random text message that will contain a body but may also contain
|
||||
* - An expire timer value
|
||||
* - Bold style body ranges
|
||||
*/
|
||||
fun fuzzTextMessage(): Content {
|
||||
return Content.newBuilder()
|
||||
.setDataMessage(
|
||||
@@ -62,6 +81,13 @@ object MessageContentFuzzer {
|
||||
.build()
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a random media message that may be:
|
||||
* - A text body
|
||||
* - A text body with a quote that references an existing message
|
||||
* - A text body with a quote that references a non existing message
|
||||
* - A message with 0-2 attachment pointers and may contain a text body
|
||||
*/
|
||||
fun fuzzMediaMessageWithBody(quoteAble: List<TestMessage> = emptyList()): Content {
|
||||
return Content.newBuilder()
|
||||
.setDataMessage(
|
||||
@@ -105,6 +131,10 @@ object MessageContentFuzzer {
|
||||
.build()
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a random media message that contains no traditional media content. It may be:
|
||||
* - A reaction to a prior message
|
||||
*/
|
||||
fun fuzzMediaMessageNoContent(previousMessages: List<TestMessage> = emptyList()): Content {
|
||||
return Content.newBuilder()
|
||||
.setDataMessage(
|
||||
@@ -125,6 +155,10 @@ object MessageContentFuzzer {
|
||||
).build()
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a random media message that can never contain a text body. It may be:
|
||||
* - A sticker
|
||||
*/
|
||||
fun fuzzMediaMessageNoText(previousMessages: List<TestMessage> = emptyList()): Content {
|
||||
return Content.newBuilder()
|
||||
.setDataMessage(
|
||||
@@ -144,6 +178,9 @@ object MessageContentFuzzer {
|
||||
).build()
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a random [String].
|
||||
*/
|
||||
fun string(length: Int = 10, allowNullString: Boolean = false): String {
|
||||
var string = ""
|
||||
|
||||
@@ -157,12 +194,18 @@ object MessageContentFuzzer {
|
||||
return string
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a random [ByteString].
|
||||
*/
|
||||
fun byteString(length: Int = 512): ByteString {
|
||||
return random.nextBytes(512).toProtoByteString()
|
||||
return random.nextBytes(length).toProtoByteString()
|
||||
}
|
||||
|
||||
fun attachmentPointer(): SignalServiceProtos.AttachmentPointer {
|
||||
return SignalServiceProtos.AttachmentPointer.newBuilder().run {
|
||||
/**
|
||||
* Generate a random [AttachmentPointer].
|
||||
*/
|
||||
fun attachmentPointer(): AttachmentPointer {
|
||||
return AttachmentPointer.newBuilder().run {
|
||||
cdnKey = string()
|
||||
contentType = mediaTypes.random(random)
|
||||
key = byteString()
|
||||
@@ -182,39 +225,10 @@ object MessageContentFuzzer {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a server delivered timestamp that is always later than the envelope and server "received" timestamp.
|
||||
*/
|
||||
fun fuzzServerDeliveredTimestamp(envelopeTimestamp: Long): Long {
|
||||
return envelopeTimestamp + 10
|
||||
}
|
||||
|
||||
fun fuzzMetadata(source: RecipientId, destination: RecipientId): EnvelopeMetadata {
|
||||
return EnvelopeMetadata(
|
||||
sourceServiceId = Recipient.resolved(source).requireServiceId(),
|
||||
sourceE164 = null,
|
||||
sourceDeviceId = 1,
|
||||
sealedSender = true,
|
||||
groupId = null,
|
||||
destinationServiceId = Recipient.resolved(destination).requireServiceId()
|
||||
)
|
||||
}
|
||||
|
||||
fun <T : Any> fuzzProto(protoClazz: KClass<T>) {
|
||||
val newBuilder: Any = protoClazz.declaredFunctions.first { it.name == "newBuilder" }.call()!!
|
||||
|
||||
val setters: List<KFunction<*>> = newBuilder::class.functions.filter { it.name.startsWith("set") && !it.name.contains("Bytes") }
|
||||
|
||||
for (setter in setters) {
|
||||
val type = setter.parameters[1].type.jvmErasure
|
||||
when {
|
||||
type == String::class -> setter.call(newBuilder, string())
|
||||
type == Int::class -> setter.call(newBuilder, random.nextInt())
|
||||
type == Long::class -> setter.call(newBuilder, random.nextLong())
|
||||
type == AttachmentPointer::class -> setter.call(newBuilder, attachmentPointer())
|
||||
type == Boolean::class -> setter.call(newBuilder, random.nextBoolean())
|
||||
// type.superclasses.contains(EnumLite::class) ->
|
||||
else -> Log.e("CODY", "WHAT!?!?!?! ${setter.parameters[1].type.jvmErasure}")
|
||||
}
|
||||
}
|
||||
|
||||
Log.e("CODY", newBuilder::class.functions.first { it.name == "build" }.call(newBuilder).toString())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -819,7 +819,7 @@ object DataMessageProcessor {
|
||||
val mentions: List<Mention> = getMentions(message.bodyRangesList)
|
||||
val sticker: Attachment? = getStickerAttachment(envelope.timestamp, message)
|
||||
val attachments: List<Attachment> = message.attachmentsList.toPointers()
|
||||
val messageRanges: BodyRangeList? = message.bodyRangesList.filter { it.hasStyle() }.toList().toBodyRangeList()
|
||||
val messageRanges: BodyRangeList? = if (message.bodyRangesCount > 0) message.bodyRangesList.filter { it.hasStyle() }.toList().toBodyRangeList() else null
|
||||
|
||||
handlePossibleExpirationUpdate(envelope, metadata, senderRecipient.id, threadRecipientId, groupId, message.expireTimer.seconds, receivedTime)
|
||||
|
||||
|
||||
@@ -201,7 +201,7 @@ import java.util.concurrent.TimeUnit;
|
||||
@SuppressWarnings({ "OptionalGetWithoutIsPresent", "OptionalIsPresent" })
|
||||
public class MessageContentProcessor {
|
||||
|
||||
private static final String TAG = Log.tag(MessageContentProcessor.class);
|
||||
public static final String TAG = Log.tag(MessageContentProcessor.class);
|
||||
|
||||
private final Context context;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user