diff --git a/core/network/build.gradle.kts b/core/network/build.gradle.kts index 21b240b00..c70edc7c4 100644 --- a/core/network/build.gradle.kts +++ b/core/network/build.gradle.kts @@ -67,6 +67,10 @@ kotlin { implementation(libs.okhttp3.logging.interceptor) } - commonTest.dependencies { implementation(libs.kotlinx.coroutines.test) } + commonTest.dependencies { + implementation(libs.kotlinx.coroutines.test) + implementation(libs.kotest.assertions) + implementation(libs.kotest.property) + } } } diff --git a/core/network/src/commonTest/kotlin/org/meshtastic/core/network/transport/StreamFrameCodecTest.kt b/core/network/src/commonTest/kotlin/org/meshtastic/core/network/transport/StreamFrameCodecTest.kt index 955c89129..93ee0d7ec 100644 --- a/core/network/src/commonTest/kotlin/org/meshtastic/core/network/transport/StreamFrameCodecTest.kt +++ b/core/network/src/commonTest/kotlin/org/meshtastic/core/network/transport/StreamFrameCodecTest.kt @@ -16,6 +16,14 @@ */ package org.meshtastic.core.network.transport +import io.kotest.matchers.nulls.shouldNotBeNull +import io.kotest.matchers.shouldBe +import io.kotest.property.Arb +import io.kotest.property.arbitrary.byte +import io.kotest.property.arbitrary.byteArray +import io.kotest.property.arbitrary.int +import io.kotest.property.checkAll +import kotlinx.coroutines.test.runTest import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertTrue @@ -56,6 +64,33 @@ class StreamFrameCodecTest { assertEquals(listOf(0x55.toByte()), receivedPackets[0].toList()) } + @Test + fun `frameAndSend and processInputByte are inverse`() = runTest { + checkAll(Arb.byteArray(Arb.int(0, 512), Arb.byte())) { payload -> + var received: ByteArray? = null + val codec = StreamFrameCodec(onPacketReceived = { received = it }) + + val bytes = mutableListOf() + codec.frameAndSend(payload, sendBytes = { bytes.add(it) }) + + bytes.forEach { arr -> + arr.forEach { codec.processInputByte(it) } + } + + received.shouldNotBeNull() + received.shouldBe(payload) + } + } + + @Test + fun `processInputByte is robust against random noise`() = runTest { + checkAll(Arb.byteArray(Arb.int(0, 1000), Arb.byte())) { noise -> + val codec = StreamFrameCodec(onPacketReceived = { /* ignore */ }) + noise.forEach { codec.processInputByte(it) } + // Should not crash + } + } + @Test fun `processInputByte handles multiple packets sequentially`() { val packet1 = byteArrayOf(0x94.toByte(), 0xc3.toByte(), 0x00, 0x01, 0x11)