From 7998fd60b425d8f21eb0a7f79a24718ea226f96b Mon Sep 17 00:00:00 2001 From: Harshit Malpani Date: Mon, 7 Nov 2022 11:19:12 +0530 Subject: [PATCH] cbor: Add test for cbor component --- cbor/test/CMakeLists.txt | 4 + cbor/test/test.c | 230 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 234 insertions(+) create mode 100644 cbor/test/CMakeLists.txt create mode 100644 cbor/test/test.c diff --git a/cbor/test/CMakeLists.txt b/cbor/test/CMakeLists.txt new file mode 100644 index 0000000..b39a409 --- /dev/null +++ b/cbor/test/CMakeLists.txt @@ -0,0 +1,4 @@ +idf_component_register(SRC_DIRS "." + PRIV_INCLUDE_DIRS "." + REQUIRES unity + PRIV_REQUIRES cmock cbor) diff --git a/cbor/test/test.c b/cbor/test/test.c new file mode 100644 index 0000000..eef53b1 --- /dev/null +++ b/cbor/test/test.c @@ -0,0 +1,230 @@ +/* + * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +#include +#include + +#include "unity.h" +#if __has_include("esp_random.h") +#include "esp_random.h" +#else +#include "esp_system.h" +#endif + +#include "cbor.h" + +#define CBOR_CHECK(a, str, goto_tag, ret_value, ...) \ + do \ + { \ + if ((a) != CborNoError) \ + { \ + printf("%s(%d): " str, __FUNCTION__, __LINE__, ##__VA_ARGS__); \ + ret = ret_value; \ + goto goto_tag; \ + } \ + } while (0) + +static void indent(int nestingLevel) +{ + while (nestingLevel--) { + printf(" "); + } +} + +static void dumpbytes(const uint8_t *buf, size_t len) +{ + while (len--) { + printf("%02X ", *buf++); + } +} + +/** + * Decode CBOR data manuallly + */ +static CborError example_dump_cbor_buffer(CborValue *it, int nestingLevel) +{ + CborError ret = CborNoError; + while (!cbor_value_at_end(it)) { + CborType type = cbor_value_get_type(it); + + indent(nestingLevel); + switch (type) { + case CborArrayType: { + CborValue recursed; + assert(cbor_value_is_container(it)); + puts("Array["); + ret = cbor_value_enter_container(it, &recursed); + CBOR_CHECK(ret, "enter container failed", err, ret); + ret = example_dump_cbor_buffer(&recursed, nestingLevel + 1); + CBOR_CHECK(ret, "recursive dump failed", err, ret); + ret = cbor_value_leave_container(it, &recursed); + CBOR_CHECK(ret, "leave container failed", err, ret); + indent(nestingLevel); + puts("]"); + continue; + } + case CborMapType: { + CborValue recursed; + assert(cbor_value_is_container(it)); + puts("Map{"); + ret = cbor_value_enter_container(it, &recursed); + CBOR_CHECK(ret, "enter container failed", err, ret); + ret = example_dump_cbor_buffer(&recursed, nestingLevel + 1); + CBOR_CHECK(ret, "recursive dump failed", err, ret); + ret = cbor_value_leave_container(it, &recursed); + CBOR_CHECK(ret, "leave container failed", err, ret); + indent(nestingLevel); + puts("}"); + continue; + } + case CborIntegerType: { + int64_t val; + ret = cbor_value_get_int64(it, &val); + CBOR_CHECK(ret, "parse int64 failed", err, ret); + printf("%lld\n", (long long)val); + break; + } + case CborByteStringType: { + uint8_t *buf; + size_t n; + ret = cbor_value_dup_byte_string(it, &buf, &n, it); + CBOR_CHECK(ret, "parse byte string failed", err, ret); + dumpbytes(buf, n); + puts(""); + free(buf); + continue; + } + case CborTextStringType: { + char *buf; + size_t n; + ret = cbor_value_dup_text_string(it, &buf, &n, it); + CBOR_CHECK(ret, "parse text string failed", err, ret); + puts(buf); + free(buf); + continue; + } + case CborTagType: { + CborTag tag; + ret = cbor_value_get_tag(it, &tag); + CBOR_CHECK(ret, "parse tag failed", err, ret); + printf("Tag(%lld)\n", (long long)tag); + break; + } + case CborSimpleType: { + uint8_t type; + ret = cbor_value_get_simple_type(it, &type); + CBOR_CHECK(ret, "parse simple type failed", err, ret); + printf("simple(%u)\n", type); + break; + } + case CborNullType: + puts("null"); + break; + case CborUndefinedType: + puts("undefined"); + break; + case CborBooleanType: { + bool val; + ret = cbor_value_get_boolean(it, &val); + CBOR_CHECK(ret, "parse boolean type failed", err, ret); + puts(val ? "true" : "false"); + break; + } + case CborHalfFloatType: { + uint16_t val; + ret = cbor_value_get_half_float(it, &val); + CBOR_CHECK(ret, "parse half float type failed", err, ret); + printf("__f16(%04x)\n", val); + break; + } + case CborFloatType: { + float val; + ret = cbor_value_get_float(it, &val); + CBOR_CHECK(ret, "parse float type failed", err, ret); + printf("%g\n", val); + break; + } + case CborDoubleType: { + double val; + ret = cbor_value_get_double(it, &val); + CBOR_CHECK(ret, "parse double float type failed", err, ret); + printf("%g\n", val); + break; + } + case CborInvalidType: { + ret = CborErrorUnknownType; + CBOR_CHECK(ret, "unknown cbor type", err, ret); + break; + } + } + + ret = cbor_value_advance_fixed(it); + CBOR_CHECK(ret, "fix value failed", err, ret); + } + return CborNoError; +err: + return ret; +} + + +TEST_CASE("CBOR example", "[cbor]") +{ + CborEncoder root_encoder; + CborParser root_parser; + CborValue it; + uint8_t buf[100]; + + // Initialize the outermost cbor encoder + cbor_encoder_init(&root_encoder, buf, sizeof(buf), 0); + + // Create an array containing several items + CborEncoder array_encoder; + CborEncoder map_encoder; + cbor_encoder_create_array(&root_encoder, &array_encoder, 5); // [ + // 1. Create a map containing several pairs + cbor_encoder_create_map(&array_encoder, &map_encoder, 3); // { + // chip:esp32 + cbor_encode_text_stringz(&map_encoder, "chip"); + cbor_encode_text_stringz(&map_encoder, "esp32"); + // unicore:false + cbor_encode_text_stringz(&map_encoder, "unicore"); + cbor_encode_boolean(&map_encoder, false); + // ip:[192,168,1,100] + cbor_encode_text_stringz(&map_encoder, "ip"); + CborEncoder array2; + cbor_encoder_create_array(&map_encoder, &array2, 4); // [ + // Encode several numbers + cbor_encode_uint(&array2, 192); + cbor_encode_uint(&array2, 168); + cbor_encode_uint(&array2, 1); + cbor_encode_uint(&array2, 100); + cbor_encoder_close_container(&map_encoder, &array2); // ] + cbor_encoder_close_container(&array_encoder, &map_encoder); // } + // 2. Encode float number + cbor_encode_float(&array_encoder, 3.14); + // 3. Encode simple value + cbor_encode_simple_value(&array_encoder, 99); + // 4. Encode a string + cbor_encode_text_stringz(&array_encoder, "2019-07-10 09:00:00+0000"); + // 5. Encode a undefined value + cbor_encode_undefined(&array_encoder); + cbor_encoder_close_container(&root_encoder, &array_encoder); // ] + + // If error happend when encoding, then this value should be meaningless + printf("encoded buffer size %d", cbor_encoder_get_buffer_size(&root_encoder, buf)); + + // Initialize the cbor parser and the value iterator + cbor_parser_init(buf, sizeof(buf), 0, &root_parser, &it); + + printf("convert CBOR to JSON"); + // Dump the values in JSON format + cbor_value_to_json(stdout, &it, 0); + puts(""); + + printf("decode CBOR manually: "); + // Decode CBOR data manully + TEST_ESP_OK(example_dump_cbor_buffer(&it, 0)); +} +