From 7da66430de3fc235bfc6ebb0b85fb90ea246138d Mon Sep 17 00:00:00 2001 From: Chris Nisbet Date: Wed, 12 Feb 2020 21:08:44 +1300 Subject: [PATCH] tests: blobmsg: add test case * add a test for blobmsg_check_array() to test an array with a string in it This test was added in conjunction with a change to blobmsg_check_array() to get it to pass the length obtained from blob_len() rather than blobmsg_len(). Signed-off-by: Chris Nisbet --- tests/cram/test_blobmsg_check_array.t | 8 ++ tests/test-blobmsg_check_array.c | 169 ++++++++++++++++++++++++++ 2 files changed, 177 insertions(+) create mode 100644 tests/cram/test_blobmsg_check_array.t create mode 100644 tests/test-blobmsg_check_array.c diff --git a/tests/cram/test_blobmsg_check_array.t b/tests/cram/test_blobmsg_check_array.t new file mode 100644 index 0000000..f01bdbf --- /dev/null +++ b/tests/cram/test_blobmsg_check_array.t @@ -0,0 +1,8 @@ +check that blobmsg_check_array() is producing expected results: + + $ [ -n "$TEST_BIN_DIR" ] && export PATH="$TEST_BIN_DIR:$PATH" + + $ test-blobmsg_check_array + Process array_a: entry 0 + array_b contains string: 1 + blobmsg_check_array() test passed diff --git a/tests/test-blobmsg_check_array.c b/tests/test-blobmsg_check_array.c new file mode 100644 index 0000000..5620431 --- /dev/null +++ b/tests/test-blobmsg_check_array.c @@ -0,0 +1,169 @@ +#include + +#include "blobmsg.h" + +/* + * This test tests a blob of this form... + * + { + "array_a" : [ + { + "array_b": [ + "1" + ] + } + ] + } + * + */ + + +enum { + ARRAY_A = 0, + ARRAY_B = 0, +}; + +static char const array_a[] = "array_a"; +static char const array_b[] = "array_b"; + +static const struct blobmsg_policy pol_a[] = { + [ARRAY_A] = { + .name = array_a, + .type = BLOBMSG_TYPE_ARRAY + } +}; + +static const struct blobmsg_policy pol_b[] = { + [ARRAY_B] = { + .name = array_b, + .type = BLOBMSG_TYPE_ARRAY + } +}; + +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) +#endif + +static int +check_table_a_entries(struct blob_attr *attr) +{ + struct blob_attr *cur; + size_t rem; + int entry_number = 0; + + blobmsg_for_each_attr(cur, attr, rem) { + int failed = 0; + + fprintf(stderr, "Process %s: entry %d\n", array_a, entry_number); + + struct blob_attr *tb[ARRAY_SIZE(pol_b)]; + + if (blobmsg_parse(pol_b, ARRAY_SIZE(pol_b), tb, + blobmsg_data(cur), blobmsg_data_len(cur)) != 0) { + fprintf(stderr, "Policy %s parse failed\n", array_b); + return -1; + } + + if (tb[ARRAY_B] == NULL) { + fprintf(stderr, "%s not found\n", array_b); + return -1; + } + + /* + * This is the test that fails when blobmsg_check_array() passes the + * length obtained by blob_len(attr). + * It succeeds when blobmsg_check_array() uses blob_len(attr), which is + * equivalent to the origianl code, pre the length check changes. + */ + if (blobmsg_check_array(tb[ARRAY_B], BLOBMSG_TYPE_STRING) < 0) { + fprintf(stderr, "Failed blobmsg_check_array() (STRING) on %s\n", + array_b); + failed = 1; + } + + /* + * Continue outputting the strings even though the test above might + * have failed. + * This will show that the array does actually contain the expected + * string. + */ + + struct blob_attr *cur2; + size_t rem2; + + blobmsg_for_each_attr(cur2, tb[ARRAY_B], rem2) { + fprintf(stderr, "%s contains string: %s\n", + array_b, blobmsg_get_string(cur2)); + } + + + entry_number++; + + if (failed) + return -1; + } + + return 0; +} + +static int +check_message(struct blob_buf *buf) +{ + struct blob_attr *tb[ARRAY_SIZE(pol_a)]; + + if (blobmsg_parse(pol_a, ARRAY_SIZE(pol_a), tb, + blob_data(buf->head), blobmsg_data_len(buf->head)) != 0) { + fprintf(stderr, "Policy %s parse failed\n", array_a); + return -1; + } + + if (tb[ARRAY_A] == NULL) { + fprintf(stderr, "%s not found\n", array_a); + return -1; + } + + int const result = blobmsg_check_array(tb[ARRAY_A], BLOBMSG_TYPE_TABLE); + + if (result < 0) { + fprintf(stderr, "Failed blobmsg_check_array() (TABLE) on %s (%d)\n", + array_a, result); + return -1; + } + + return check_table_a_entries(tb[ARRAY_A]); +} + +static void +fill_message(struct blob_buf * const buf) +{ + void * const tbl_a = blobmsg_open_array(buf, "array_a"); + void * const obj = blobmsg_open_table(buf, NULL); + + void * const tbl_b = blobmsg_open_array(buf, "array_b"); + + blobmsg_add_string(buf, NULL, "1"); + + blobmsg_close_array(buf, tbl_b); + + blobmsg_close_table(buf, obj); + + blobmsg_close_array(buf, tbl_a); +} + +int main(int argc, char **argv) +{ + int result; + static struct blob_buf buf; + + blobmsg_buf_init(&buf); + fill_message(&buf); + + result = check_message(&buf); + if (result == 0) + fprintf(stderr, "blobmsg_check_array() test passed\n"); + + if (buf.buf != NULL) + free(buf.buf); + + return result ? EXIT_FAILURE : EXIT_SUCCESS; +}