| /* |
| * |
| * Copyright (c) 2021-2022 Project CHIP Authors |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include <stdio.h> |
| #include <string.h> |
| #include <string> |
| #include <vector> |
| |
| #include <gtest/gtest.h> |
| |
| #include <lib/support/BytesToHex.h> |
| #include <lib/support/CodeUtils.h> |
| #include <lib/support/EnforceFormat.h> |
| #include <lib/support/Span.h> |
| #include <lib/support/logging/CHIPLogging.h> |
| namespace { |
| |
| using namespace chip; |
| using namespace chip::Encoding; |
| |
| // To accumulate redirected logs for some tests |
| std::vector<std::string> gRedirectedLogLines; |
| |
| TEST(TestBytesToHex, TestBytesToHexNotNullTerminated) |
| { |
| // Uppercase |
| { |
| uint8_t src[] = { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }; |
| char dest[18] = { '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '!', '@' }; |
| char dest2[18] = { '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '!', '@' }; |
| char expected[18] = { 'F', 'E', 'D', 'C', 'B', 'A', '9', '8', '7', '6', '5', '4', '3', '2', '1', '0', '!', '@' }; |
| EXPECT_EQ(BytesToHex(&src[0], sizeof(src), &dest[0], sizeof(src) * 2u, HexFlags::kUppercase), CHIP_NO_ERROR); |
| EXPECT_EQ(memcmp(&dest[0], &expected[0], sizeof(expected)), 0); |
| |
| EXPECT_EQ(BytesToUppercaseHexBuffer(&src[0], sizeof(src), &dest2[0], sizeof(src) * 2u), CHIP_NO_ERROR); |
| EXPECT_EQ(memcmp(&dest2[0], &expected[0], sizeof(expected)), 0); |
| } |
| |
| // Lowercase |
| { |
| uint8_t src[] = { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }; |
| char dest[18] = { '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '!', '@' }; |
| char dest2[18] = { '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '!', '@' }; |
| char expected[18] = { 'f', 'e', 'd', 'c', 'b', 'a', '9', '8', '7', '6', '5', '4', '3', '2', '1', '0', '!', '@' }; |
| EXPECT_EQ(BytesToHex(&src[0], sizeof(src), &dest[0], sizeof(src) * 2u, HexFlags::kNone), CHIP_NO_ERROR); |
| EXPECT_EQ(memcmp(&dest[0], &expected[0], sizeof(expected)), 0); |
| |
| // Test Alias |
| EXPECT_EQ(BytesToLowercaseHexBuffer(&src[0], sizeof(src), &dest2[0], sizeof(src) * 2u), CHIP_NO_ERROR); |
| EXPECT_EQ(memcmp(&dest2[0], &expected[0], sizeof(expected)), 0); |
| } |
| |
| // Trivial: Zero size input |
| { |
| uint8_t src[] = { 0x00 }; |
| char dest[2] = { '!', '@' }; |
| char expected[2] = { '!', '@' }; |
| EXPECT_EQ(BytesToHex(&src[0], 0, &dest[0], sizeof(src) * 2u, HexFlags::kNone), CHIP_NO_ERROR); |
| // Nothing should have been touched. |
| EXPECT_EQ(memcmp(&dest[0], &expected[0], sizeof(expected)), 0); |
| } |
| |
| // Trivial: Zero size input with null buffer |
| { |
| char dest[2] = { '!', '@' }; |
| char expected[2] = { '!', '@' }; |
| EXPECT_EQ(BytesToHex(nullptr, 0, &dest[0], sizeof(dest), HexFlags::kNone), CHIP_NO_ERROR); |
| // Nothing should have been touched. |
| EXPECT_EQ(memcmp(&dest[0], &expected[0], sizeof(expected)), 0); |
| |
| EXPECT_EQ(BytesToHex(nullptr, 0, nullptr, 0, HexFlags::kNone), CHIP_NO_ERROR); |
| // Nothing should have been touched. |
| EXPECT_EQ(memcmp(&dest[0], &expected[0], sizeof(expected)), 0); |
| |
| EXPECT_EQ(BytesToHex(nullptr, 0, nullptr, 1, HexFlags::kNone), CHIP_ERROR_INVALID_ARGUMENT); |
| } |
| } |
| |
| TEST(TestBytesToHex, TestBytesToHexNullTerminated) |
| { |
| // Uppercase |
| { |
| uint8_t src[] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF }; |
| char dest[18] = { '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '!', '@' }; |
| char dest2[18] = { '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '!', '@' }; |
| char expected[18] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', '\0', '@' }; |
| EXPECT_LE(((sizeof(src) * 2u) + 1u), sizeof(dest)); |
| EXPECT_EQ(BytesToHex(&src[0], sizeof(src), &dest[0], (sizeof(src) * 2u) + 1, HexFlags::kUppercaseAndNullTerminate), |
| CHIP_NO_ERROR); |
| EXPECT_EQ(memcmp(&dest[0], &expected[0], sizeof(expected)), 0); |
| |
| // Test Alias |
| CHIP_ERROR retval = BytesToUppercaseHexString(&src[0], sizeof(src), &dest2[0], sizeof(dest2)); |
| printf("retval=%" CHIP_ERROR_FORMAT "\n", retval.Format()); |
| EXPECT_EQ(retval, CHIP_NO_ERROR); |
| EXPECT_EQ(memcmp(&dest2[0], &expected[0], sizeof(expected)), 0); |
| } |
| |
| // Lowercase |
| { |
| uint8_t src[] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF }; |
| char dest[18] = { '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '!', '@' }; |
| char dest2[18] = { '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '!', '@' }; |
| char expected[18] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', '\0', '@' }; |
| EXPECT_LE(((sizeof(src) * 2u) + 1u), sizeof(dest)); |
| EXPECT_EQ(BytesToHex(&src[0], sizeof(src), &dest[0], (sizeof(src) * 2u) + 1, HexFlags::kNullTerminate), CHIP_NO_ERROR); |
| EXPECT_EQ(memcmp(&dest[0], &expected[0], sizeof(expected)), 0); |
| |
| // Test Alias |
| EXPECT_EQ(BytesToLowercaseHexString(&src[0], sizeof(src), &dest2[0], sizeof(dest2)), CHIP_NO_ERROR); |
| printf("->%s\n", dest2); |
| EXPECT_EQ(memcmp(&dest2[0], &expected[0], sizeof(expected)), 0); |
| } |
| |
| // Trivial: Zero size input |
| { |
| uint8_t src[] = { 0x00 }; |
| char dest[2] = { '!', '@' }; |
| char expected[2] = { '\0', '@' }; |
| EXPECT_EQ(BytesToHex(&src[0], 0, &dest[0], sizeof(dest), HexFlags::kNullTerminate), CHIP_NO_ERROR); |
| // Expect nul termination |
| EXPECT_EQ(memcmp(&dest[0], &expected[0], sizeof(expected)), 0); |
| } |
| |
| // Trivial: Zero size input with null buffer |
| { |
| char dest[2] = { '!', '@' }; |
| char expected[2] = { '\0', '@' }; |
| EXPECT_EQ(BytesToHex(nullptr, 0, &dest[0], sizeof(dest), HexFlags::kNullTerminate), CHIP_NO_ERROR); |
| // Nothing should have been touched. |
| EXPECT_EQ(memcmp(&dest[0], &expected[0], sizeof(expected)), 0); |
| |
| EXPECT_EQ(BytesToHex(nullptr, 0, nullptr, 0, HexFlags::kNullTerminate), CHIP_ERROR_BUFFER_TOO_SMALL); |
| |
| EXPECT_EQ(BytesToHex(nullptr, 0, &dest[0], 1, HexFlags::kNullTerminate), CHIP_NO_ERROR); |
| // Nothing should have been touched. |
| EXPECT_EQ(memcmp(&dest[0], &expected[0], sizeof(expected)), 0); |
| |
| EXPECT_EQ(BytesToHex(nullptr, 0, nullptr, 1, HexFlags::kNullTerminate), CHIP_ERROR_INVALID_ARGUMENT); |
| } |
| } |
| |
| TEST(TestBytesToHex, TestBytesToHexErrors) |
| { |
| // NULL destination |
| { |
| uint8_t src[] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF }; |
| char * dest = nullptr; |
| EXPECT_EQ(BytesToHex(&src[0], 0, dest, sizeof(src) * 2u, HexFlags::kNone), CHIP_ERROR_INVALID_ARGUMENT); |
| } |
| |
| // Destination buffer too small for non-null-terminated |
| { |
| uint8_t src[] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF }; |
| char dest[18] = { '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '!', '@' }; |
| char expected[18] = { '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '!', '@' }; |
| EXPECT_LE(((sizeof(src) * 2u) + 1u), sizeof(dest)); |
| EXPECT_EQ(BytesToHex(&src[0], sizeof(src), &dest[0], (sizeof(src) * 2u) - 1, HexFlags::kNone), CHIP_ERROR_BUFFER_TOO_SMALL); |
| // Ensure output not touched |
| EXPECT_EQ(memcmp(&dest[0], &expected[0], sizeof(expected)), 0); |
| } |
| |
| // Destination buffer too small for null-terminated |
| { |
| uint8_t src[] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF }; |
| char dest[18] = { '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '!', '@' }; |
| char expected[18] = { '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '!', '@' }; |
| EXPECT_LE(((sizeof(src) * 2u) + 1u), sizeof(dest)); |
| EXPECT_EQ(BytesToHex(&src[0], sizeof(src), &dest[0], (sizeof(src) * 2u), HexFlags::kNullTerminate), |
| CHIP_ERROR_BUFFER_TOO_SMALL); |
| // Ensure output not touched |
| EXPECT_EQ(memcmp(&dest[0], &expected[0], sizeof(expected)), 0); |
| } |
| |
| // Writing in a larger buffer is fine, bytes past the nul terminator (when requested) are untouched. |
| { |
| uint8_t src[] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF }; |
| char dest[18] = { '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '!', '@' }; |
| char expected[18] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', '\0', '@' }; |
| EXPECT_LT(((sizeof(src) * 2u) + 1u), sizeof(dest)); |
| EXPECT_EQ(BytesToHex(&src[0], sizeof(src), &dest[0], sizeof(dest), HexFlags::kNullTerminate), CHIP_NO_ERROR); |
| EXPECT_EQ(memcmp(&dest[0], &expected[0], sizeof(expected)), 0); |
| } |
| |
| // Source size that would not fit in any output using size_t |
| { |
| uint8_t src[] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF }; |
| char dest[18] = { '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '!', '@' }; |
| char expected[18] = { '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '!', '@' }; |
| EXPECT_EQ(BytesToHex(&src[0], SIZE_MAX / 2u, &dest[0], sizeof(dest), HexFlags::kNullTerminate), |
| CHIP_ERROR_BUFFER_TOO_SMALL); |
| EXPECT_EQ(memcmp(&dest[0], &expected[0], sizeof(expected)), 0); |
| |
| EXPECT_EQ(BytesToHex(&src[0], SIZE_MAX / 2u, &dest[0], sizeof(dest), HexFlags::kNone), CHIP_ERROR_BUFFER_TOO_SMALL); |
| EXPECT_EQ(memcmp(&dest[0], &expected[0], sizeof(expected)), 0); |
| } |
| } |
| |
| TEST(TestBytesToHex, TestBytesToHexUint64) |
| { |
| // Different values in each byte and each nibble should let us know if the conversion is correct. |
| uint64_t test = 0x0123456789ABCDEF; |
| uint32_t test32_0 = 0x01234567; |
| uint32_t test32_1 = 0x89ABCDEF; |
| uint16_t test16_0 = 0x0123; |
| uint16_t test16_1 = 0x4567; |
| uint16_t test16_2 = 0x89AB; |
| uint16_t test16_3 = 0xCDEF; |
| char buf[17]; |
| char upperExpected[] = "0123456789ABCDEF"; |
| char lowerExpected[] = "0123456789abcdef"; |
| |
| // Lower case - uint64_t. |
| memset(buf, 1, sizeof(buf)); |
| EXPECT_EQ(Uint64ToHex(test, buf, sizeof(buf), HexFlags::kNone), CHIP_NO_ERROR); |
| EXPECT_EQ(memcmp(buf, lowerExpected, strlen(lowerExpected)), 0); |
| // No null termination. |
| EXPECT_EQ(buf[16], 1); |
| |
| // Lower case - uint32_t. |
| memset(buf, 1, sizeof(buf)); |
| EXPECT_EQ(Uint32ToHex(test32_0, buf, sizeof(uint32_t) * 2, HexFlags::kNone), CHIP_NO_ERROR); |
| EXPECT_EQ(Uint32ToHex(test32_1, &buf[sizeof(uint32_t) * 2], sizeof(uint32_t) * 2, HexFlags::kNone), CHIP_NO_ERROR); |
| EXPECT_EQ(memcmp(buf, lowerExpected, strlen(lowerExpected)), 0); |
| // No null termination. |
| EXPECT_EQ(buf[16], 1); |
| |
| // Upper case - uint64_t. |
| memset(buf, 1, sizeof(buf)); |
| EXPECT_EQ(Uint64ToHex(test, buf, sizeof(buf), HexFlags::kUppercase), CHIP_NO_ERROR); |
| EXPECT_EQ(memcmp(buf, upperExpected, strlen(upperExpected)), 0); |
| // No null termination. |
| EXPECT_EQ(buf[16], 1); |
| |
| // Upper case - uint16_t. |
| memset(buf, 1, sizeof(buf)); |
| EXPECT_EQ(Uint16ToHex(test16_0, buf, sizeof(uint16_t) * 2, HexFlags::kUppercase), CHIP_NO_ERROR); |
| EXPECT_EQ(Uint16ToHex(test16_1, &buf[sizeof(uint16_t) * 2 * 1], sizeof(uint16_t) * 2, HexFlags::kUppercase), CHIP_NO_ERROR); |
| EXPECT_EQ(Uint16ToHex(test16_2, &buf[sizeof(uint16_t) * 2 * 2], sizeof(uint16_t) * 2, HexFlags::kUppercase), CHIP_NO_ERROR); |
| EXPECT_EQ(Uint16ToHex(test16_3, &buf[sizeof(uint16_t) * 2 * 3], sizeof(uint16_t) * 2, HexFlags::kUppercase), CHIP_NO_ERROR); |
| EXPECT_EQ(memcmp(buf, upperExpected, strlen(upperExpected)), 0); |
| // No null termination. |
| EXPECT_EQ(buf[16], 1); |
| |
| // Lower case with null termination. |
| memset(buf, 1, sizeof(buf)); |
| EXPECT_EQ(Uint64ToHex(test, buf, sizeof(buf), HexFlags::kNullTerminate), CHIP_NO_ERROR); |
| EXPECT_EQ(memcmp(buf, lowerExpected, sizeof(lowerExpected)), 0); |
| |
| // Upper case with null termination. |
| memset(buf, 1, sizeof(buf)); |
| EXPECT_EQ(Uint64ToHex(test, buf, sizeof(buf), HexFlags::kUppercaseAndNullTerminate), CHIP_NO_ERROR); |
| EXPECT_EQ(memcmp(buf, upperExpected, sizeof(upperExpected)), 0); |
| |
| // Too small buffer |
| EXPECT_EQ(Uint64ToHex(test, buf, sizeof(buf) - 2, HexFlags::kNone), CHIP_ERROR_BUFFER_TOO_SMALL); |
| EXPECT_EQ(Uint64ToHex(test, buf, sizeof(buf) - 2, HexFlags::kUppercase), CHIP_ERROR_BUFFER_TOO_SMALL); |
| EXPECT_EQ(Uint64ToHex(test, buf, sizeof(buf) - 1, HexFlags::kNullTerminate), CHIP_ERROR_BUFFER_TOO_SMALL); |
| EXPECT_EQ(Uint64ToHex(test, buf, sizeof(buf) - 1, HexFlags::kUppercaseAndNullTerminate), CHIP_ERROR_BUFFER_TOO_SMALL); |
| } |
| |
| TEST(TestBytesToHex, TestHexToBytesAndUint) |
| { |
| // Different values in each byte and each nibble should let us know if the conversion is correct. |
| char hexInLowercase[] = "0123456789abcdef"; |
| char hexInUppercase[] = "0123456789ABCDEF"; |
| char hexInUppercase32[] = "6789ABCD"; |
| char hexInUppercase16[] = "D7AB"; |
| uint8_t bytesOutExpected[] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF }; |
| uint64_t test64OutExpected = 0x0123456789ABCDEF; |
| uint32_t test32OutExpected = 0x6789ABCD; |
| uint16_t test16OutExpected = 0xD7AB; |
| uint64_t test64Out; |
| uint32_t test32Out; |
| uint16_t test16Out; |
| uint8_t buf[8]; |
| |
| // Lower case - bytes. |
| memset(buf, 0, sizeof(buf)); |
| EXPECT_EQ(HexToBytes(hexInLowercase, strlen(hexInLowercase), buf, sizeof(buf)), sizeof(buf)); |
| EXPECT_EQ(memcmp(buf, bytesOutExpected, sizeof(buf)), 0); |
| |
| // Upper case - bytes. |
| memset(buf, 0, sizeof(buf)); |
| EXPECT_EQ(HexToBytes(hexInUppercase, strlen(hexInUppercase), buf, sizeof(buf)), sizeof(buf)); |
| EXPECT_EQ(memcmp(buf, bytesOutExpected, sizeof(buf)), 0); |
| |
| // Lower case - uint64_t. |
| test64Out = 0; |
| EXPECT_EQ(UppercaseHexToUint64(hexInLowercase, strlen(hexInLowercase), test64Out), 0u); |
| |
| // Upper case - uint64_t. |
| test64Out = 0; |
| EXPECT_EQ(UppercaseHexToUint64(hexInUppercase, strlen(hexInUppercase), test64Out), sizeof(uint64_t)); |
| EXPECT_EQ(test64Out, test64OutExpected); |
| |
| // Upper case - uint32_t. |
| test32Out = 0; |
| EXPECT_EQ(UppercaseHexToUint32(hexInUppercase32, strlen(hexInUppercase32), test32Out), sizeof(uint32_t)); |
| EXPECT_EQ(test32Out, test32OutExpected); |
| |
| // Upper case - uint16_t. |
| test16Out = 0; |
| EXPECT_EQ(UppercaseHexToUint16(hexInUppercase16, strlen(hexInUppercase16), test16Out), sizeof(uint16_t)); |
| EXPECT_EQ(test16Out, test16OutExpected); |
| } |
| |
| #if CHIP_PROGRESS_LOGGING |
| |
| ENFORCE_FORMAT(3, 0) void AccumulateLogLineCallback(const char * module, uint8_t category, const char * msg, va_list args) |
| { |
| (void) module; |
| (void) category; |
| |
| char line[256]; |
| memset(&line[0], 0, sizeof(line)); |
| vsnprintf(line, sizeof(line), msg, args); |
| gRedirectedLogLines.push_back(std::string(line)); |
| } |
| |
| void ValidateTextMatches(const char ** expected, size_t numLines, const std::vector<std::string> & candidate) |
| { |
| EXPECT_EQ(candidate.size(), numLines); |
| if (candidate.size() != numLines) |
| { |
| return; |
| } |
| for (size_t idx = 0; idx < numLines; idx++) |
| { |
| printf("Checking '%s' against '%s'\n", candidate.at(idx).c_str(), expected[idx]); |
| EXPECT_EQ(candidate.at(idx), expected[idx]); |
| if (candidate.at(idx) != expected[idx]) |
| { |
| return; |
| } |
| } |
| } |
| |
| TEST(TestBytesToHex, TestLogBufferAsHex) |
| { |
| const char * kExpectedText1[] = { |
| ">>>A54A39294B28886E8BFC15B44105A3FD22745225983A753E6BB82DA7C62493BF", |
| ">>>02C3ED03D41B6F7874E7E887321DE7B4872CEB9F080B6ECE14A8ABFA260573A3", |
| ">>>8D759C", |
| }; |
| |
| const char * kExpectedText2[] = { |
| "label>>>A54A39294B28886E8BFC15B44105A3FD22745225983A753E6BB82DA7C62493BF", |
| "label>>>02C3ED03D41B6F7874E7E887321DE7B4872CEB9F080B6ECE14A8ABFA260573A3", |
| "label>>>8D759C", |
| }; |
| |
| const char * kExpectedText3[] = { |
| "label>>>", |
| }; |
| |
| const char * kExpectedText4[] = { |
| "label>>>A54A39", |
| }; |
| |
| const uint8_t buffer[67] = { 0xa5, 0x4a, 0x39, 0x29, 0x4b, 0x28, 0x88, 0x6e, 0x8b, 0xfc, 0x15, 0xb4, 0x41, 0x05, |
| 0xa3, 0xfd, 0x22, 0x74, 0x52, 0x25, 0x98, 0x3a, 0x75, 0x3e, 0x6b, 0xb8, 0x2d, 0xa7, |
| 0xc6, 0x24, 0x93, 0xbf, 0x02, 0xc3, 0xed, 0x03, 0xd4, 0x1b, 0x6f, 0x78, 0x74, 0xe7, |
| 0xe8, 0x87, 0x32, 0x1d, 0xe7, 0xb4, 0x87, 0x2c, 0xeb, 0x9f, 0x08, 0x0b, 0x6e, 0xce, |
| 0x14, 0xa8, 0xab, 0xfa, 0x26, 0x05, 0x73, 0xa3, 0x8d, 0x75, 0x9c }; |
| |
| struct TestCase |
| { |
| const char * label; |
| chip::ByteSpan buffer; |
| const char ** expectedText; |
| size_t numLines; |
| }; |
| |
| const TestCase kTestCases[] = { |
| // Basic cases |
| { "", ByteSpan(buffer), kExpectedText1, ArraySize(kExpectedText1) }, |
| { nullptr, ByteSpan(buffer), kExpectedText1, ArraySize(kExpectedText1) }, |
| { "label", ByteSpan(buffer), kExpectedText2, ArraySize(kExpectedText2) }, |
| |
| // Empty buffer leads to a single label |
| { "label", ByteSpan(), kExpectedText3, ArraySize(kExpectedText3) }, |
| // Less than full single line works |
| { "label", ByteSpan(&buffer[0], 3), kExpectedText4, ArraySize(kExpectedText4) }, |
| }; |
| |
| for (auto testCase : kTestCases) |
| { |
| chip::Logging::SetLogRedirectCallback(&AccumulateLogLineCallback); |
| gRedirectedLogLines.clear(); |
| { |
| LogBufferAsHex(testCase.label, testCase.buffer); |
| } |
| chip::Logging::SetLogRedirectCallback(nullptr); |
| ValidateTextMatches(testCase.expectedText, testCase.numLines, gRedirectedLogLines); |
| } |
| } |
| |
| #endif |
| } // namespace |