Skip to content

Commit

Permalink
Implement unit tests for ManualOnboardingPayload (#27446)
Browse files Browse the repository at this point in the history
* Implement unit tests for ManualOnboardingPayload

* Restyled by gn

---------

Co-authored-by: Restyled.io <[email protected]>
  • Loading branch information
2 people authored and pull[bot] committed Nov 15, 2023
1 parent 0e3efb1 commit 1308279
Show file tree
Hide file tree
Showing 6 changed files with 761 additions and 38 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/java-tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,8 @@ jobs:
chip.tlv.TlvWriterTest \
chip.tlv.TlvReadWriteTest \
chip.tlv.TlvReaderTest \
chip.jsontlv.JsonToTlvToJsonTest
chip.jsontlv.JsonToTlvToJsonTest \
chip.onboardingpayload.ManualCodeTest
- name: Build Java Matter Controller and all clusters app
timeout-minutes: 60
run: |
Expand Down
15 changes: 15 additions & 0 deletions src/controller/java/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -261,9 +261,24 @@ kotlin_library("onboarding_payload") {
]
}

kotlin_library("onboardingpayload_manual_code_test") {
output_name = "OnboardingPayloadManualCodeTest.jar"

deps = [
":onboarding_payload",
"${chip_root}/third_party/java_deps:junit-4",
"${chip_root}/third_party/java_deps:truth",
]

sources = [ "tests/chip/onboardingpayload/ManualCodeTest.kt" ]

kotlinc_flags = [ "-Xlint:deprecation" ]
}

group("unit_tests") {
deps = [
":json_to_tlv_to_json_test",
":onboardingpayload_manual_code_test",
":tlv_read_write_test",
":tlv_reader_test",
":tlv_writer_test",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,30 +71,31 @@ class ManualOnboardingPayloadGenerator(private val payloadContents: OnboardingPa

var offset = 0

decimalStringWithPadding(decimalString.sliceArray(offset until offset + kManualSetupCodeChunk1CharLength), chunk1)
decimalStringWithPadding(decimalString, offset, kManualSetupCodeChunk1CharLength, chunk1)
offset += kManualSetupCodeChunk1CharLength
decimalStringWithPadding(decimalString.sliceArray(offset until offset + kManualSetupCodeChunk2CharLength), chunk2)
decimalStringWithPadding(decimalString, offset, kManualSetupCodeChunk2CharLength, chunk2)
offset += kManualSetupCodeChunk2CharLength
decimalStringWithPadding(decimalString.sliceArray(offset until offset + kManualSetupCodeChunk3CharLength), chunk3)
decimalStringWithPadding(decimalString, offset, kManualSetupCodeChunk3CharLength, chunk3)
offset += kManualSetupCodeChunk3CharLength

if (useLongCode) {
decimalStringWithPadding(decimalString.sliceArray(offset until offset + kManualSetupVendorIdCharLength), payloadContents.vendorId)
decimalStringWithPadding(decimalString, offset, kManualSetupVendorIdCharLength, payloadContents.vendorId)
offset += kManualSetupVendorIdCharLength
decimalStringWithPadding(decimalString.sliceArray(offset until offset + kManualSetupProductIdCharLength), payloadContents.productId)
decimalStringWithPadding(decimalString, offset, kManualSetupProductIdCharLength, payloadContents.productId)
offset += kManualSetupProductIdCharLength
}

val checkDigit = Verhoeff10.charToVal(Verhoeff10.computeCheckChar(decimalString.concatToString()))
decimalStringWithPadding(decimalString.sliceArray(offset until offset + 2), checkDigit)
val str = decimalString.concatToString().substring(0, offset)
val checkDigit = Verhoeff10.charToVal(Verhoeff10.computeCheckChar(str))
decimalStringWithPadding(decimalString, offset, 1, checkDigit)
offset += 1

// Reduce decimalString size to be the size of written data and to not include null-terminator. In Kotlin, there is no direct
// method to resize an array.We use copyOfRange(0, offset) to create a new CharArray that includes only the elements from index
// 0 to offset-1, effectively reducing the size of the buffer.
decimalString.copyOfRange(0, offset)
val newDecimalString = decimalString.copyOfRange(0, offset)

return decimalString.joinToString()
return String(newDecimalString)
}

private fun chunk1PayloadRepresentation(payload: OnboardingPayload): Int {
Expand Down Expand Up @@ -141,12 +142,11 @@ class ManualOnboardingPayloadGenerator(private val payloadContents: OnboardingPa
return ((payload.setupPinCode.toInt() shr pincodeShift) and pincodeMask) shl kManualSetupChunk3PINCodeMsbitsPos
}

private fun decimalStringWithPadding(buffer: CharArray, number: Int): Unit {
val len = buffer.size - 1
val retval = String.format("%0${len}d", number).toCharArray(buffer, 0, buffer.size)

if (retval.size >= buffer.size) {
private fun decimalStringWithPadding(buffer: CharArray, offset: Int, len: Int, number: Int): Unit {
if (offset + len > buffer.size) {
throw OnboardingPayloadException("The outBuffer has insufficient size")
}

String.format("%0${len}d", number).toCharArray(buffer, offset, 0, len)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,19 @@ class ManualOnboardingPayloadParser(decimalRepresentation: String) {
}

companion object {
private fun checkDecimalStringValidity(decimalString: String): String {
fun toNumber(decimalString: String): UInt {
var number: UInt = 0u
for (c in decimalString) {
if (!c.isDigit()) {
throw InvalidManualPairingCodeFormatException("Failed decoding base10. Character was invalid $c")
}
number *= 10u
number += (c - '0').toUInt()
}
return number
}

fun checkDecimalStringValidity(decimalString: String): String {
if (decimalString.length < 2) {
throw InvalidManualPairingCodeFormatException("Failed decoding base10. Input was empty. ${decimalString.length}")
}
Expand All @@ -116,25 +128,13 @@ class ManualOnboardingPayloadParser(decimalRepresentation: String) {
return repWithoutCheckChar
}

private fun checkCodeLengthValidity(decimalString: String, isLongCode: Boolean): Unit {
fun checkCodeLengthValidity(decimalString: String, isLongCode: Boolean): Unit {
val expectedCharLength = if (isLongCode) kManualSetupLongCodeCharLength else kManualSetupShortCodeCharLength
if (decimalString.length != expectedCharLength) {
throw InvalidManualPairingCodeFormatException("Failed decoding base10. Input length ${decimalString.length} was not expected length $expectedCharLength")
}
}

private fun toNumber(decimalString: String): UInt {
var number: UInt = 0u
for (c in decimalString) {
if (!c.isDigit()) {
throw InvalidManualPairingCodeFormatException("Failed decoding base10. Character was invalid $c")
}
number *= 10u
number += (c - '0').toUInt()
}
return number
}

// Populate numberOfChars into dest from decimalString starting at startIndex (least significant digit = left-most digit)
fun readDigitsFromDecimalString(decimalString: String, index: AtomicInteger, numberOfCharsToRead: Int): UInt {
val startIndex = index.get()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ const val kBPKFSaltTag = 0x02
const val kNumberOFDevicesTag = 0x03
const val kCommissioningTimeoutTag = 0x04

const val kSetupPINCodeMaximumValue = 99999998
const val kSetupPINCodeUndefinedValue = 0
const val kSetupPINCodeMaximumValue = 99999998L
const val kSetupPINCodeUndefinedValue = 0L

const val kTotalPayloadDataSizeInBits: Int =
kVersionFieldLengthInBits +
Expand Down Expand Up @@ -195,6 +195,24 @@ class OnboardingPayload(
return checkPayloadCommonConstraints()
}

fun setShortDiscriminatorValue(discriminator: Int) {
if (discriminator != (discriminator and kDiscriminatorShortMask)) {
throw OnboardingPayloadException("Invalid argument")
}

this.discriminator = (discriminator and kDiscriminatorShortMask)
this.hasShortDiscriminator = true
}

fun setLongDiscriminatorValue(discriminator: Int) {
if (discriminator != (discriminator and kDiscriminatorLongMask)) {
throw OnboardingPayloadException("Invalid argument")
}

this.discriminator = (discriminator and kDiscriminatorLongMask)
this.hasShortDiscriminator = false;
}

fun getShortDiscriminatorValue(): Int {
if (hasShortDiscriminator) {
return discriminator
Expand Down Expand Up @@ -474,7 +492,7 @@ class OnboardingPayload(
return false
}

if (!isValidSetupPIN(setupPinCode.toInt())) {
if (!isValidSetupPIN(setupPinCode)) {
return false
}

Expand All @@ -494,12 +512,14 @@ class OnboardingPayload(
}

companion object {
private fun isValidSetupPIN(setupPIN: Int): Boolean {
return (setupPIN != kSetupPINCodeUndefinedValue && setupPIN <= kSetupPINCodeMaximumValue &&
setupPIN != 11111111 && setupPIN != 22222222 && setupPIN != 33333333 &&
setupPIN != 44444444 && setupPIN != 55555555 && setupPIN != 66666666 &&
setupPIN != 77777777 && setupPIN != 88888888 && setupPIN != 12345678 &&
setupPIN != 87654321)
private fun isValidSetupPIN(setupPIN: Long): Boolean {
// SHALL be restricted to the values 0x0000001 to 0x5F5E0FE (00000001 to 99999998 in decimal),
// excluding the invalid Passcode values.
return (setupPIN != kSetupPINCodeUndefinedValue && setupPIN <= kSetupPINCodeMaximumValue &&
setupPIN != 11111111L && setupPIN != 22222222L && setupPIN != 33333333L &&
setupPIN != 44444444L && setupPIN != 55555555L && setupPIN != 66666666L &&
setupPIN != 77777777L && setupPIN != 88888888L && setupPIN != 12345678L &&
setupPIN != 87654321L)
}

private fun longToShortValue(longValue: Int): Int {
Expand Down
Loading

0 comments on commit 1308279

Please sign in to comment.