Skip to content

Commit 9bd9f4a

Browse files
committed
Migrate testtool to use cbor and websockets to improve compatibility tests performance
1 parent 938da36 commit 9bd9f4a

22 files changed

+421
-220
lines changed

cryptography-providers/tests/build.gradle.kts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ kotlin {
4848
api(projects.cryptographySerializationAsn1)
4949
api(projects.cryptographySerializationAsn1Modules)
5050

51-
api(libs.kotlinx.serialization.json)
5251
api(libs.kotlinx.coroutines.test)
5352

5453
implementation("testtool:client")

cryptography-providers/tests/src/commonMain/kotlin/compatibility/AesCbcCompatibilityTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ abstract class AesCbcCompatibilityTest(provider: CryptographyProvider) :
2323
@Serializable
2424
private data class CipherParameters(
2525
val padding: Boolean,
26-
val iv: ByteStringAsString?,
26+
val iv: SerializableByteString?,
2727
) : TestParameters
2828

2929
override suspend fun CompatibilityTestScope<AES.CBC>.generate(isStressTest: Boolean) {

cryptography-providers/tests/src/commonMain/kotlin/compatibility/AesCtrCompatibilityTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ abstract class AesCtrCompatibilityTest(provider: CryptographyProvider) :
1919

2020
@Serializable
2121
private data class CipherParameters(
22-
val iv: ByteStringAsString?,
22+
val iv: SerializableByteString?,
2323
) : TestParameters {
2424
override fun toString(): String = "CipherParameters(iv.size=${iv?.size})"
2525
}

cryptography-providers/tests/src/commonMain/kotlin/compatibility/AesGcmCompatibilityTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ abstract class AesGcmCompatibilityTest(provider: CryptographyProvider) :
2222
@Serializable
2323
private data class CipherParameters(
2424
val tagSizeBits: Int,
25-
val iv: ByteStringAsString?,
25+
val iv: SerializableByteString?,
2626
) : TestParameters
2727

2828
override suspend fun CompatibilityTestScope<AES.GCM>.generate(isStressTest: Boolean) {

cryptography-providers/tests/src/commonMain/kotlin/compatibility/HkdfCompatibilityTest.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ abstract class HkdfCompatibilityTest(provider: CryptographyProvider) : Compatibi
2323
@Serializable
2424
private data class Parameters(
2525
val digestName: String,
26-
val salt: ByteStringAsString,
27-
val info: ByteStringAsString?,
26+
val salt: SerializableByteString,
27+
val info: SerializableByteString?,
2828
val outputSizeBytes: Int,
2929
) : TestParameters {
3030
val digest get() = digest(digestName)

cryptography-providers/tests/src/commonMain/kotlin/compatibility/Pbkdf2CompatibilityTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ abstract class Pbkdf2CompatibilityTest(provider: CryptographyProvider) : Compati
2626
@Serializable
2727
private data class Parameters(
2828
val digestName: String,
29-
val salt: ByteStringAsString,
29+
val salt: SerializableByteString,
3030
val iterations: Int,
3131
val outputSizeBytes: Int,
3232
) : TestParameters {

cryptography-providers/tests/src/commonMain/kotlin/compatibility/api/ByteStringAsStringSerializer.kt

Lines changed: 0 additions & 19 deletions
This file was deleted.
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* Copyright (c) 2024-2025 Oleg Yukhnevich. Use of this source code is governed by the Apache 2.0 license.
3+
*/
4+
5+
package dev.whyoleg.cryptography.providers.tests.compatibility.api
6+
7+
import kotlinx.io.bytestring.*
8+
import kotlinx.io.bytestring.unsafe.*
9+
import kotlinx.serialization.*
10+
import kotlinx.serialization.descriptors.*
11+
import kotlinx.serialization.encoding.*
12+
import kotlin.jvm.*
13+
14+
typealias SerializableByteString = @Serializable(ByteStringSerializer::class) ByteString
15+
16+
@Serializable
17+
@JvmInline
18+
private value class ByteStringWrapper(val value: ByteArray)
19+
20+
@OptIn(UnsafeByteStringApi::class)
21+
internal object ByteStringSerializer : KSerializer<ByteString> {
22+
private val delegate get() = ByteStringWrapper.serializer()
23+
24+
override val descriptor: SerialDescriptor get() = delegate.descriptor
25+
26+
override fun deserialize(decoder: Decoder): ByteString {
27+
return UnsafeByteStringOperations.wrapUnsafe(delegate.deserialize(decoder).value)
28+
}
29+
30+
override fun serialize(encoder: Encoder, value: ByteString) {
31+
UnsafeByteStringOperations.withByteArrayUnsafe(value) {
32+
delegate.serialize(encoder, ByteStringWrapper(it))
33+
}
34+
}
35+
}

cryptography-providers/tests/src/commonMain/kotlin/compatibility/api/CompatibilityStorageApi.kt

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package dev.whyoleg.cryptography.providers.tests.compatibility.api
66

77
import dev.whyoleg.cryptography.providers.tests.*
8+
import kotlinx.coroutines.flow.*
89
import kotlin.reflect.*
910

1011
abstract class CompatibilityStorageApi(
@@ -20,9 +21,9 @@ abstract class CompatibilityStorageApi(
2021
}
2122

2223
suspend inline fun <reified T : TestParameters> getParameters(
23-
block: (parameters: T, parametersId: TestParametersId, context: TestContext) -> Unit,
24+
crossinline block: suspend (parameters: T, parametersId: TestParametersId, context: TestContext) -> Unit,
2425
) {
25-
getParameters<T>(typeOf<T>()).forEach { (id, parameters, context) ->
26+
getParameters<T>(typeOf<T>()).collect { (id, parameters, context) ->
2627
logger.log { "$storageName.getParameters: $id -> $parameters | $context" }
2728
block(parameters, TestParametersId(id), context)
2829
}
@@ -39,18 +40,18 @@ abstract class CompatibilityStorageApi(
3940
parametersId: TestParametersId,
4041
crossinline block: suspend (data: T, reference: TestReference, context: TestContext) -> Unit,
4142
) {
42-
getData<T>(parametersId, typeOf<T>()).forEach { (id, data, context) ->
43+
getData<T>(parametersId, typeOf<T>()).collect { (id, data, context) ->
4344
val reference = TestReference(parametersId, TestDataId(id))
4445
logger.log { "$storageName.getData: $reference -> $data | $context" }
4546
block(data, reference, context)
4647
}
4748
}
4849

4950
abstract suspend fun <T : TestParameters> saveParameters(parameters: T, type: KType): String
50-
abstract suspend fun <T : TestParameters> getParameters(type: KType): List<TestContent<T>>
51+
abstract fun <T : TestParameters> getParameters(type: KType): Flow<TestContent<T>>
5152

5253
abstract suspend fun <T : TestData> saveData(parametersId: TestParametersId, data: T, type: KType): String
53-
abstract suspend fun <T : TestData> getData(parametersId: TestParametersId, type: KType): List<TestContent<T>>
54+
abstract fun <T : TestData> getData(parametersId: TestParametersId, type: KType): Flow<TestContent<T>>
5455

5556
data class TestContent<T>(
5657
val id: String,

cryptography-providers/tests/src/commonMain/kotlin/compatibility/api/CompatibilityTest.kt

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package dev.whyoleg.cryptography.providers.tests.compatibility.api
66

77
import dev.whyoleg.cryptography.*
88
import dev.whyoleg.cryptography.providers.tests.*
9+
import dev.whyoleg.cryptography.testtool.client.*
910
import kotlin.test.*
1011

1112
abstract class CompatibilityTest<A : CryptographyAlgorithm>(
@@ -18,19 +19,25 @@ abstract class CompatibilityTest<A : CryptographyAlgorithm>(
1819
@Test
1920
fun generateStep() = testWithAlgorithm {
2021
val logger = logger.child("GENERATE")
21-
runCompatibilityTestStep(logger, ServerApi(algorithmId.name, context, logger)) { generate(isStressTest = false) }
22+
withTestToolClient { client ->
23+
runCompatibilityTestStep(logger, ServerApi(algorithmId.name, context, logger, client)) { generate(isStressTest = false) }
24+
}
2225
}
2326

2427
@Test
2528
fun generateStressStep() = testWithAlgorithm {
2629
val logger = logger.child("GENERATE")
27-
runCompatibilityTestStep(logger, ServerApi(algorithmId.name, context, logger)) { generate(isStressTest = true) }
30+
withTestToolClient { client ->
31+
runCompatibilityTestStep(logger, ServerApi(algorithmId.name, context, logger, client)) { generate(isStressTest = true) }
32+
}
2833
}
2934

3035
@Test
3136
fun validateStep() = testWithAlgorithm {
3237
val logger = logger.child("VALIDATE")
33-
runCompatibilityTestStep(logger, ServerApi(algorithmId.name, context, logger)) { validate() }
38+
withTestToolClient { client ->
39+
runCompatibilityTestStep(logger, ServerApi(algorithmId.name, context, logger, client)) { validate() }
40+
}
3441
}
3542

3643
@Test
@@ -49,4 +56,13 @@ abstract class CompatibilityTest<A : CryptographyAlgorithm>(
4956
) {
5057
CompatibilityTestScope(logger, context, provider, algorithm, api).block()
5158
}
59+
60+
private suspend inline fun withTestToolClient(block: (TesttoolClient) -> Unit) {
61+
val client = TesttoolClient()
62+
try {
63+
block(client)
64+
} finally {
65+
client.cleanup()
66+
}
67+
}
5268
}

0 commit comments

Comments
 (0)