amethyst/benchmark/src/androidTest/java/com/vitorpamplona/quartz/benchmark/GiftWrapBenchmark.kt

195 wiersze
6.5 KiB
Kotlin

/**
* Copyright (c) 2023 Vitor Pamplona
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package com.vitorpamplona.quartz.benchmark
import androidx.benchmark.junit4.BenchmarkRule
import androidx.benchmark.junit4.measureRepeated
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.vitorpamplona.quartz.crypto.CryptoUtils
import com.vitorpamplona.quartz.crypto.KeyPair
import com.vitorpamplona.quartz.events.Event
import com.vitorpamplona.quartz.events.GiftWrapEvent
import com.vitorpamplona.quartz.events.NIP24Factory
import com.vitorpamplona.quartz.events.SealedGossipEvent
import com.vitorpamplona.quartz.signers.NostrSignerInternal
import junit.framework.TestCase
import org.junit.Assert
import org.junit.Assert.assertTrue
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit
/**
* Benchmark, which will execute on an Android device.
*
* The body of [BenchmarkRule.measureRepeated] is measured in a loop, and Studio will output the
* result. Modify your code to see how it affects performance.
*/
@RunWith(AndroidJUnit4::class)
class GiftWrapBenchmark {
@get:Rule val benchmarkRule = BenchmarkRule()
fun basePerformanceTest(
message: String,
expectedLength: Int,
) {
val sender = NostrSignerInternal(KeyPair())
val receiver = NostrSignerInternal(KeyPair())
var events: NIP24Factory.Result? = null
val countDownLatch = CountDownLatch(1)
NIP24Factory().createMsgNIP24(
message,
listOf(receiver.pubKey),
sender,
) {
events = it
countDownLatch.countDown()
}
assertTrue(countDownLatch.await(1, TimeUnit.SECONDS))
val countDownLatch2 = CountDownLatch(1)
Assert.assertEquals(
expectedLength,
events!!
.wraps
.map {
println("TEST ${it.toJson()}")
it.toJson()
}
.joinToString("")
.length,
)
// Simulate Receiver
events!!.wraps.forEach {
it.checkSignature()
val keyToUse = if (it.recipientPubKey() == sender.pubKey) sender else receiver
it.cachedGift(keyToUse) { event ->
event.checkSignature()
if (event is SealedGossipEvent) {
event.cachedGossip(keyToUse) { innerData ->
Assert.assertEquals(message, innerData.content)
countDownLatch2.countDown()
}
} else {
Assert.fail("Wrong Event")
}
}
}
assertTrue(countDownLatch2.await(1, TimeUnit.SECONDS))
}
fun receivePerformanceTest(message: String) {
val sender = NostrSignerInternal(KeyPair())
val receiver = NostrSignerInternal(KeyPair())
var giftWrap: GiftWrapEvent? = null
val countDownLatch = CountDownLatch(1)
NIP24Factory().createMsgNIP24(
message,
listOf(receiver.pubKey),
sender,
) {
giftWrap = it.wraps.first()
countDownLatch.countDown()
}
assertTrue(countDownLatch.await(1, TimeUnit.SECONDS))
val keyToUse = if (giftWrap!!.recipientPubKey() == sender.pubKey) sender else receiver
val giftWrapJson = giftWrap!!.toJson()
// Simulate Receiver
benchmarkRule.measureRepeated {
CryptoUtils.clearCache()
val counter = CountDownLatch(1)
val wrap = Event.fromJson(giftWrapJson) as GiftWrapEvent
wrap.checkSignature()
wrap.cachedGift(keyToUse) { seal ->
seal.checkSignature()
if (seal is SealedGossipEvent) {
seal.cachedGossip(keyToUse) { innerData ->
Assert.assertEquals(message, innerData.content)
counter.countDown()
}
} else {
Assert.fail("Wrong Event")
}
}
TestCase.assertTrue(counter.await(1, TimeUnit.SECONDS))
}
}
@Test
fun tinyMessageHardCoded() {
benchmarkRule.measureRepeated { basePerformanceTest("Hola, que tal?", 3402) }
}
@Test
fun regularMessageHardCoded() {
benchmarkRule.measureRepeated {
basePerformanceTest("Hi, honey, can you drop by the market and get some bread?", 3746)
}
}
@Test
fun longMessageHardCoded() {
benchmarkRule.measureRepeated {
basePerformanceTest(
"My queen, you are nothing short of royalty to me. You possess more beauty in the nail of your pinkie toe than everything else in this world combined. I am astounded by your grace, generosity, and graciousness. I am so lucky to know you. ",
5114,
)
}
}
@Test
fun receivesTinyMessage() {
receivePerformanceTest("Hola, que tal?")
}
@Test
fun receivesRegularMessage() {
receivePerformanceTest("Hi, honey, can you drop by the market and get some bread?")
}
@Test
fun receivesLongMessageHardCoded() {
receivePerformanceTest(
"My queen, you are nothing short of royalty to me. You possess more beauty in the nail of your pinkie toe than everything else in this world combined. I am astounded by your grace, generosity, and graciousness. I am so lucky to know you. ",
)
}
}