diff options
Diffstat (limited to '')
37 files changed, 2715 insertions, 1195 deletions
diff --git a/tests/utests/basic/test_common.c b/tests/utests/basic/test_common.c index 75235a2..46b80ab 100644 --- a/tests/utests/basic/test_common.c +++ b/tests/utests/basic/test_common.c @@ -1,4 +1,4 @@ -/* +/** * @file test_common.c * @author: Radek Krejci <rkrejci@cesnet.cz> * @brief unit tests for functions from common.c diff --git a/tests/utests/basic/test_context.c b/tests/utests/basic/test_context.c index 4c4cc3f..cfba1d3 100644 --- a/tests/utests/basic/test_context.c +++ b/tests/utests/basic/test_context.c @@ -1,4 +1,4 @@ -/* +/** * @file test_context.c * @author: Radek Krejci <rkrejci@cesnet.cz> * @brief unit tests for functions from context.c @@ -298,8 +298,8 @@ test_models(void **state) assert_int_equal(LY_EVALID, lys_parse_in(UTEST_LYCTX, in, LYS_IN_YANG, NULL, NULL, &unres.creating, &mod1)); lys_unres_glob_erase(&unres); ly_in_free(in, 0); - CHECK_LOG_CTX("Parsing module \"y\" failed.", NULL, - "Name collision between module and submodule of name \"y\".", "Line number 1."); + CHECK_LOG_CTX("Parsing module \"y\" failed.", NULL); + CHECK_LOG_CTX("Name collision between module and submodule of name \"y\".", "Line number 1."); assert_int_equal(LY_SUCCESS, ly_in_new_memory("module a {namespace urn:a;prefix a;include y;revision 2018-10-30; }", &in)); assert_int_equal(LY_SUCCESS, lys_parse_in(UTEST_LYCTX, in, LYS_IN_YANG, NULL, NULL, &unres.creating, &mod1)); @@ -308,8 +308,8 @@ test_models(void **state) assert_int_equal(LY_EVALID, lys_parse_in(UTEST_LYCTX, in, LYS_IN_YANG, NULL, NULL, &unres.creating, &mod1)); lys_unres_glob_erase(&unres); ly_in_free(in, 0); - CHECK_LOG_CTX("Parsing module \"y\" failed.", NULL, - "Name collision between module and submodule of name \"y\".", "Line number 1."); + CHECK_LOG_CTX("Parsing module \"y\" failed.", NULL); + CHECK_LOG_CTX("Name collision between module and submodule of name \"y\".", "Line number 1."); ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, "submodule y {belongs-to b {prefix b;}}"); assert_int_equal(LY_SUCCESS, ly_in_new_memory("module b {namespace urn:b;prefix b;include y;}", &in)); @@ -317,10 +317,10 @@ test_models(void **state) lys_unres_glob_revert(UTEST_LYCTX, &unres); lys_unres_glob_erase(&unres); ly_in_free(in, 0); - CHECK_LOG_CTX("Parsing module \"b\" failed.", NULL, - "Including \"y\" submodule into \"b\" failed.", NULL, - "Parsing submodule failed.", NULL, - "Name collision between submodules of name \"y\".", "Line number 1."); + CHECK_LOG_CTX("Parsing module \"b\" failed.", NULL); + CHECK_LOG_CTX("Including \"y\" submodule into \"b\" failed.", NULL); + CHECK_LOG_CTX("Parsing submodule failed.", NULL); + CHECK_LOG_CTX("Name collision between submodules of name \"y\".", "Line number 1."); /* selecting correct revision of the submodules */ ly_ctx_reset_latests(UTEST_LYCTX); @@ -338,19 +338,6 @@ test_models(void **state) assert_non_null(mod1->compiled); assert_non_null(mod1->parsed); -#if 0 - /* TODO in case we are able to remove the parsed schema, here we will test how it will handle missing import parsed schema */ - - assert_int_equal(LY_SUCCESS, ly_in_new_memory("module z {namespace urn:z;prefix z;import w {prefix w;revision-date 2018-10-24;}}", &in)); - /* mod1->parsed is necessary to compile mod2 because of possible groupings, typedefs, ... */ - ly_ctx_set_module_imp_clb(UTEST_LYCTX, NULL, NULL); - assert_int_equal(LY_ENOTFOUND, lys_create_module(UTEST_LYCTX, in, LYS_IN_YANG, 1, NULL, NULL, &mod2)); - /*logbuf_assert("Unable to reload \"w\" module to import it into \"z\", source data not found.");*/ - CHECK_LOG_CTX("Recompilation of module \"w\" failed.", NULL); - assert_null(mod2); - ly_in_free(in, 0); -#endif - assert_int_equal(LY_SUCCESS, ly_in_new_memory("module z {namespace urn:z;prefix z;import w {prefix w;revision-date 2018-10-24;}}", &in)); ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, "module w {namespace urn:w;prefix w;revision 2018-10-24;}"); assert_int_equal(LY_SUCCESS, lys_parse(UTEST_LYCTX, in, LYS_IN_YANG, NULL, &mod2)); @@ -425,6 +412,7 @@ test_imports(void **state) "import a {prefix a;}" "}"; assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL)); + ly_err_clean(UTEST_LYCTX, NULL); } static void diff --git a/tests/utests/basic/test_hash_table.c b/tests/utests/basic/test_hash_table.c index 25b595a..78950cd 100644 --- a/tests/utests/basic/test_hash_table.c +++ b/tests/utests/basic/test_hash_table.c @@ -1,4 +1,4 @@ -/* +/** * @file test_hash_table.c * @author: Radek Krejci <rkrejci@cesnet.cz> * @brief unit tests for functions from hash_table.c @@ -19,8 +19,6 @@ #include "common.h" #include "hash_table.h" -struct ht_rec *lyht_get_rec(unsigned char *recs, uint16_t rec_size, uint32_t idx); - static void test_invalid_arguments(void **state) { @@ -83,7 +81,7 @@ static void test_ht_basic(void **state) { uint32_t i; - struct hash_table *ht; + struct ly_ht *ht; assert_non_null(ht = lyht_new(8, sizeof(int), ht_equal_clb, NULL, 0)); @@ -96,15 +94,14 @@ test_ht_basic(void **state) assert_int_equal(LY_ENOTFOUND, lyht_remove(ht, &i, i)); CHECK_LOG("Invalid argument hash (lyht_remove_with_resize_cb()).", NULL); - lyht_free(ht); + lyht_free(ht, NULL); } static void test_ht_resize(void **state) { uint32_t i; - struct ht_rec *rec; - struct hash_table *ht; + struct ly_ht *ht; assert_non_null(ht = lyht_new(8, sizeof(int), ht_equal_clb, NULL, 1)); assert_int_equal(8, ht->size); @@ -120,13 +117,12 @@ test_ht_resize(void **state) for (i = 0; i < 16; ++i) { if ((i >= 2) && (i < 8)) { /* inserted data on indexes 2-7 */ - rec = lyht_get_rec(ht->recs, ht->rec_size, i); - assert_int_equal(1, rec->hits); - assert_int_equal(i, rec->hash); + assert_int_not_equal(UINT32_MAX, ht->hlists[i].first); + assert_int_equal(LY_SUCCESS, lyht_find(ht, &i, i, NULL)); } else { /* nothing otherwise */ - rec = lyht_get_rec(ht->recs, ht->rec_size, i); - assert_int_equal(0, rec->hits); + assert_int_equal(UINT32_MAX, ht->hlists[i].first); + assert_int_equal(LY_ENOTFOUND, lyht_find(ht, &i, i, NULL)); } } @@ -153,7 +149,7 @@ test_ht_resize(void **state) } /* cleanup */ - lyht_free(ht); + lyht_free(ht, NULL); } static void @@ -162,8 +158,10 @@ test_ht_collisions(void **UNUSED(state)) #define GET_REC_INT(rec) (*((uint32_t *)&(rec)->val)) uint32_t i; - struct ht_rec *rec; - struct hash_table *ht; + struct ly_ht_rec *rec; + struct ly_ht *ht; + uint32_t rec_idx; + int count; assert_non_null(ht = lyht_new(8, sizeof(int), ht_equal_clb, NULL, 1)); @@ -172,66 +170,69 @@ test_ht_collisions(void **UNUSED(state)) } /* check all records */ - for (i = 0; i < 2; ++i) { - rec = lyht_get_rec(ht->recs, ht->rec_size, i); - assert_int_equal(rec->hits, 0); + for (i = 0; i < 8; ++i) { + if (i == 2) { + assert_int_not_equal(UINT32_MAX, ht->hlists[i].first); + } else { + assert_int_equal(UINT32_MAX, ht->hlists[i].first); + } } - rec = lyht_get_rec(ht->recs, ht->rec_size, i); - assert_int_equal(rec->hits, 4); - assert_int_equal(GET_REC_INT(rec), i); - ++i; - for ( ; i < 6; ++i) { - rec = lyht_get_rec(ht->recs, ht->rec_size, i); - assert_int_equal(rec->hits, 1); - assert_int_equal(GET_REC_INT(rec), i); + for (i = 0; i < 8; ++i) { + if ((i >= 2) && (i < 6)) { + assert_int_equal(LY_SUCCESS, lyht_find(ht, &i, 2, NULL)); + } else { + assert_int_equal(LY_ENOTFOUND, lyht_find(ht, &i, 2, NULL)); + } } - for ( ; i < 8; ++i) { - rec = lyht_get_rec(ht->recs, ht->rec_size, i); - assert_int_equal(rec->hits, 0); + rec_idx = ht->hlists[2].first; + count = 0; + while (rec_idx != UINT32_MAX) { + rec = lyht_get_rec(ht->recs, ht->rec_size, rec_idx); + rec_idx = rec->next; + assert_int_equal(rec->hash, 2); + count++; } + assert_int_equal(count, 4); i = 4; assert_int_equal(lyht_remove(ht, &i, 2), 0); rec = lyht_get_rec(ht->recs, ht->rec_size, i); - assert_int_equal(rec->hits, -1); i = 2; assert_int_equal(lyht_remove(ht, &i, 2), 0); /* check all records */ - for (i = 0; i < 2; ++i) { - rec = lyht_get_rec(ht->recs, ht->rec_size, i); - assert_int_equal(rec->hits, 0); + for (i = 0; i < 8; ++i) { + if (i == 2) { + assert_int_not_equal(UINT32_MAX, ht->hlists[i].first); + } else { + assert_int_equal(UINT32_MAX, ht->hlists[i].first); + } } - rec = lyht_get_rec(ht->recs, ht->rec_size, i); - assert_int_equal(rec->hits, 2); - assert_int_equal(GET_REC_INT(rec), 5); - ++i; - rec = lyht_get_rec(ht->recs, ht->rec_size, i); - assert_int_equal(rec->hits, 1); - assert_int_equal(GET_REC_INT(rec), 3); - ++i; - for ( ; i < 6; ++i) { - rec = lyht_get_rec(ht->recs, ht->rec_size, i); - assert_int_equal(rec->hits, -1); + for (i = 0; i < 8; ++i) { + if ((i == 3) || (i == 5)) { + assert_int_equal(LY_SUCCESS, lyht_find(ht, &i, 2, NULL)); + } else { + assert_int_equal(LY_ENOTFOUND, lyht_find(ht, &i, 2, NULL)); + } } - for ( ; i < 8; ++i) { - rec = lyht_get_rec(ht->recs, ht->rec_size, i); - assert_int_equal(rec->hits, 0); + rec_idx = ht->hlists[2].first; + count = 0; + while (rec_idx != UINT32_MAX) { + rec = lyht_get_rec(ht->recs, ht->rec_size, rec_idx); + rec_idx = rec->next; + assert_int_equal(rec->hash, 2); + count++; } + assert_int_equal(count, 2); - for (i = 0; i < 3; ++i) { - assert_int_equal(lyht_find(ht, &i, 2, NULL), LY_ENOTFOUND); - } - assert_int_equal(lyht_find(ht, &i, 2, NULL), LY_SUCCESS); - ++i; - assert_int_equal(lyht_find(ht, &i, 2, NULL), LY_ENOTFOUND); - ++i; - assert_int_equal(lyht_find(ht, &i, 2, NULL), LY_SUCCESS); - ++i; - for ( ; i < 8; ++i) { - assert_int_equal(lyht_find(ht, &i, 2, NULL), LY_ENOTFOUND); + for (i = 0; i < 8; ++i) { + if ((i == 3) || (i == 5)) { + assert_int_equal(lyht_find(ht, &i, 2, NULL), LY_SUCCESS); + } else { + assert_int_equal(lyht_find(ht, &i, 2, NULL), LY_ENOTFOUND); + } } i = 3; @@ -240,20 +241,11 @@ test_ht_collisions(void **UNUSED(state)) assert_int_equal(lyht_remove(ht, &i, 2), 0); /* check all records */ - for (i = 0; i < 2; ++i) { - rec = lyht_get_rec(ht->recs, ht->rec_size, i); - assert_int_equal(rec->hits, 0); - } - for ( ; i < 6; ++i) { - rec = lyht_get_rec(ht->recs, ht->rec_size, i); - assert_int_equal(rec->hits, -1); - } - for ( ; i < 8; ++i) { - rec = lyht_get_rec(ht->recs, ht->rec_size, i); - assert_int_equal(rec->hits, 0); + for (i = 0; i < 8; ++i) { + assert_int_equal(UINT32_MAX, ht->hlists[i].first); } - lyht_free(ht); + lyht_free(ht, NULL); } int diff --git a/tests/utests/basic/test_inout.c b/tests/utests/basic/test_inout.c index be27510..3f83568 100644 --- a/tests/utests/basic/test_inout.c +++ b/tests/utests/basic/test_inout.c @@ -84,8 +84,11 @@ test_input_mem(void **UNUSED(state)) char *str1 = "a", *str2 = "b"; assert_int_equal(LY_EINVAL, ly_in_new_memory(NULL, NULL)); + CHECK_LOG_LASTMSG("Invalid argument str (ly_in_new_memory())."); assert_int_equal(LY_EINVAL, ly_in_new_memory(str1, NULL)); + CHECK_LOG_LASTMSG("Invalid argument in (ly_in_new_memory())."); assert_null(ly_in_memory(NULL, NULL)); + CHECK_LOG_LASTMSG("Invalid argument in (ly_in_memory())."); assert_int_equal(LY_SUCCESS, ly_in_new_memory(str1, &in)); assert_int_equal(LY_IN_MEMORY, ly_in_type(in)); @@ -103,12 +106,15 @@ test_input_fd(void **UNUSED(state)) struct stat statbuf; assert_int_equal(LY_EINVAL, ly_in_new_fd(-1, NULL)); + CHECK_LOG_LASTMSG("Invalid argument fd >= 0 (ly_in_new_fd())."); assert_int_equal(-1, ly_in_fd(NULL, -1)); + CHECK_LOG_LASTMSG("Invalid argument in (ly_in_fd())."); assert_int_not_equal(-1, fd1 = open(TEST_INPUT_FILE, O_RDONLY)); assert_int_not_equal(-1, fd2 = open(TEST_INPUT_FILE, O_RDONLY)); assert_int_equal(LY_EINVAL, ly_in_new_fd(fd1, NULL)); + CHECK_LOG_LASTMSG("Invalid argument in (ly_in_new_fd())."); assert_int_equal(LY_SUCCESS, ly_in_new_fd(fd1, &in)); assert_int_equal(LY_IN_FD, ly_in_type(in)); diff --git a/tests/utests/basic/test_json.c b/tests/utests/basic/test_json.c index 1896b8a..08b7719 100644 --- a/tests/utests/basic/test_json.c +++ b/tests/utests/basic/test_json.c @@ -1,4 +1,4 @@ -/* +/** * @file test_json.c * @author: Radek Krejci <rkrejci@cesnet.cz> * @brief unit tests for a generic JSON parser @@ -27,39 +27,40 @@ test_general(void **state) /* empty */ str = ""; assert_int_equal(LY_SUCCESS, ly_in_new_memory(str, &in)); - assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); - assert_int_equal(LYJSON_END, lyjson_ctx_status(jsonctx, 0)); - lyjson_ctx_free(jsonctx); + assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); + CHECK_LOG_CTX("Empty JSON file.", "Line number 1."); str = " \n\t \n"; assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); - assert_int_equal(LYJSON_END, lyjson_ctx_status(jsonctx, 0)); - lyjson_ctx_free(jsonctx); + assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); + CHECK_LOG_CTX("Empty JSON file.", "Line number 3."); /* constant values */ str = "true"; assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); - assert_int_equal(LYJSON_TRUE, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); + assert_int_equal(LYJSON_TRUE, lyjson_ctx_status(jsonctx)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL)); - assert_int_equal(LYJSON_END, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LYJSON_END, lyjson_ctx_status(jsonctx)); lyjson_ctx_free(jsonctx); str = "false"; assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); - assert_int_equal(LYJSON_FALSE, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); + assert_int_equal(LYJSON_FALSE, lyjson_ctx_status(jsonctx)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL)); - assert_int_equal(LYJSON_END, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LYJSON_END, lyjson_ctx_status(jsonctx)); lyjson_ctx_free(jsonctx); str = "null"; assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); - assert_int_equal(LYJSON_NULL, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); + assert_int_equal(LYJSON_NULL, lyjson_ctx_status(jsonctx)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL)); - assert_int_equal(LYJSON_END, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LYJSON_END, lyjson_ctx_status(jsonctx)); lyjson_ctx_free(jsonctx); ly_in_free(in, 0); @@ -75,8 +76,8 @@ test_number(void **state) /* simple value */ str = "11"; assert_int_equal(LY_SUCCESS, ly_in_new_memory(str, &in)); - assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); - assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); + assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx)); assert_string_equal("11", jsonctx->value); assert_int_equal(2, jsonctx->value_len); assert_int_equal(0, jsonctx->dynamic); @@ -85,8 +86,8 @@ test_number(void **state) /* fraction number */ str = "37.7668"; assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); - assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); + assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx)); assert_string_equal("37.7668", jsonctx->value); assert_int_equal(7, jsonctx->value_len); assert_int_equal(0, jsonctx->dynamic); @@ -95,8 +96,8 @@ test_number(void **state) /* negative number */ str = "-122.3959"; assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); - assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); + assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx)); assert_string_equal("-122.3959", jsonctx->value); assert_int_equal(9, jsonctx->value_len); assert_int_equal(0, jsonctx->dynamic); @@ -105,8 +106,8 @@ test_number(void **state) /* integer, positive exponent */ str = "550E3"; assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); - assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); + assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx)); assert_string_equal("550000", jsonctx->value); assert_int_equal(6, jsonctx->value_len); assert_int_equal(1, jsonctx->dynamic); @@ -114,8 +115,8 @@ test_number(void **state) str = "-550E3"; assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); - assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); + assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx)); assert_string_equal("-550000", jsonctx->value); assert_int_equal(7, jsonctx->value_len); assert_int_equal(1, jsonctx->dynamic); @@ -124,8 +125,8 @@ test_number(void **state) /* integer, negative exponent */ str = "1E-1"; assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); - assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); + assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx)); assert_string_equal("0.1", jsonctx->value); assert_int_equal(3, jsonctx->value_len); assert_int_equal(1, jsonctx->dynamic); @@ -133,8 +134,8 @@ test_number(void **state) str = "15E-1"; assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); - assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); + assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx)); assert_string_equal("1.5", jsonctx->value); assert_int_equal(3, jsonctx->value_len); assert_int_equal(1, jsonctx->dynamic); @@ -142,8 +143,8 @@ test_number(void **state) str = "-15E-1"; assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); - assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); + assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx)); assert_string_equal("-1.5", jsonctx->value); assert_int_equal(4, jsonctx->value_len); assert_int_equal(1, jsonctx->dynamic); @@ -151,8 +152,8 @@ test_number(void **state) str = "16E-2"; assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); - assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); + assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx)); assert_string_equal("0.16", jsonctx->value); assert_int_equal(4, jsonctx->value_len); assert_int_equal(1, jsonctx->dynamic); @@ -160,8 +161,8 @@ test_number(void **state) str = "-16E-2"; assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); - assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); + assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx)); assert_string_equal("-0.16", jsonctx->value); assert_int_equal(5, jsonctx->value_len); assert_int_equal(1, jsonctx->dynamic); @@ -169,8 +170,8 @@ test_number(void **state) str = "17E-3"; assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); - assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); + assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx)); assert_string_equal("0.017", jsonctx->value); assert_int_equal(5, jsonctx->value_len); assert_int_equal(1, jsonctx->dynamic); @@ -178,8 +179,8 @@ test_number(void **state) str = "-17E-3"; assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); - assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); + assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx)); assert_string_equal("-0.017", jsonctx->value); assert_int_equal(6, jsonctx->value_len); assert_int_equal(1, jsonctx->dynamic); @@ -187,8 +188,8 @@ test_number(void **state) str = "21000E-2"; assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); - assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); + assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx)); assert_string_equal("210", jsonctx->value); assert_int_equal(3, jsonctx->value_len); assert_int_equal(1, jsonctx->dynamic); @@ -196,8 +197,8 @@ test_number(void **state) str = "21000E-4"; assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); - assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); + assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx)); assert_string_equal("2.1", jsonctx->value); assert_int_equal(3, jsonctx->value_len); assert_int_equal(1, jsonctx->dynamic); @@ -205,8 +206,8 @@ test_number(void **state) str = "21000E-7"; assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); - assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); + assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx)); assert_string_equal("0.0021", jsonctx->value); assert_int_equal(6, jsonctx->value_len); assert_int_equal(1, jsonctx->dynamic); @@ -215,8 +216,8 @@ test_number(void **state) /* decimal number, positive exponent */ str = "5.087E1"; assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); - assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); + assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx)); assert_string_equal("50.87", jsonctx->value); assert_int_equal(5, jsonctx->value_len); assert_int_equal(1, jsonctx->dynamic); @@ -224,8 +225,8 @@ test_number(void **state) str = "-5.087E1"; assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); - assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); + assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx)); assert_string_equal("-50.87", jsonctx->value); assert_int_equal(6, jsonctx->value_len); assert_int_equal(1, jsonctx->dynamic); @@ -233,8 +234,8 @@ test_number(void **state) str = "5.087E5"; assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); - assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); + assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx)); assert_string_equal("508700", jsonctx->value); assert_int_equal(6, jsonctx->value_len); assert_int_equal(1, jsonctx->dynamic); @@ -242,8 +243,8 @@ test_number(void **state) str = "59.1e+1"; assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); - assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); + assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx)); assert_string_equal("591", jsonctx->value); assert_int_equal(3, jsonctx->value_len); assert_int_equal(1, jsonctx->dynamic); @@ -251,8 +252,8 @@ test_number(void **state) str = "0.005087E1"; assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); - assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); + assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx)); assert_string_equal("0.05087", jsonctx->value); assert_int_equal(7, jsonctx->value_len); assert_int_equal(1, jsonctx->dynamic); @@ -260,8 +261,8 @@ test_number(void **state) str = "0.005087E2"; assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); - assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); + assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx)); assert_string_equal("0.5087", jsonctx->value); assert_int_equal(6, jsonctx->value_len); assert_int_equal(1, jsonctx->dynamic); @@ -269,8 +270,8 @@ test_number(void **state) str = "0.005087E6"; assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); - assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); + assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx)); assert_string_equal("5087", jsonctx->value); assert_int_equal(4, jsonctx->value_len); assert_int_equal(1, jsonctx->dynamic); @@ -278,8 +279,8 @@ test_number(void **state) str = "0.05087E6"; assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); - assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); + assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx)); assert_string_equal("50870", jsonctx->value); assert_int_equal(5, jsonctx->value_len); assert_int_equal(1, jsonctx->dynamic); @@ -287,8 +288,8 @@ test_number(void **state) str = "0.005087E8"; assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); - assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); + assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx)); assert_string_equal("508700", jsonctx->value); assert_int_equal(6, jsonctx->value_len); assert_int_equal(1, jsonctx->dynamic); @@ -297,8 +298,8 @@ test_number(void **state) /* decimal number, negative exponent */ str = "35.94e-1"; assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); - assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); + assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx)); assert_string_equal("3.594", jsonctx->value); assert_int_equal(5, jsonctx->value_len); assert_int_equal(1, jsonctx->dynamic); @@ -306,8 +307,8 @@ test_number(void **state) str = "-35.94e-1"; assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); - assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); + assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx)); assert_string_equal("-3.594", jsonctx->value); assert_int_equal(6, jsonctx->value_len); assert_int_equal(1, jsonctx->dynamic); @@ -315,8 +316,8 @@ test_number(void **state) str = "35.94e-2"; assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); - assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); + assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx)); assert_string_equal("0.3594", jsonctx->value); assert_int_equal(6, jsonctx->value_len); assert_int_equal(1, jsonctx->dynamic); @@ -324,8 +325,8 @@ test_number(void **state) str = "35.94e-3"; assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); - assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); + assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx)); assert_string_equal("0.03594", jsonctx->value); assert_int_equal(7, jsonctx->value_len); assert_int_equal(1, jsonctx->dynamic); @@ -333,8 +334,8 @@ test_number(void **state) str = "0.3594e-1"; assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); - assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); + assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx)); assert_string_equal("0.03594", jsonctx->value); assert_int_equal(7, jsonctx->value_len); assert_int_equal(1, jsonctx->dynamic); @@ -342,8 +343,8 @@ test_number(void **state) str = "0.03594e-1"; assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); - assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); + assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx)); assert_string_equal("0.003594", jsonctx->value); assert_int_equal(8, jsonctx->value_len); assert_int_equal(1, jsonctx->dynamic); @@ -351,8 +352,8 @@ test_number(void **state) str = "0.003594e-1"; assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); - assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); + assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx)); assert_string_equal("0.0003594", jsonctx->value); assert_int_equal(9, jsonctx->value_len); assert_int_equal(1, jsonctx->dynamic); @@ -360,8 +361,8 @@ test_number(void **state) str = "0.3594e-2"; assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); - assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); + assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx)); assert_string_equal("0.003594", jsonctx->value); assert_int_equal(8, jsonctx->value_len); assert_int_equal(1, jsonctx->dynamic); @@ -369,8 +370,8 @@ test_number(void **state) str = "0.03594e-2"; assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); - assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); + assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx)); assert_string_equal("0.0003594", jsonctx->value); assert_int_equal(9, jsonctx->value_len); assert_int_equal(1, jsonctx->dynamic); @@ -378,8 +379,8 @@ test_number(void **state) str = "0.003594e-2"; assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); - assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); + assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx)); assert_string_equal("0.00003594", jsonctx->value); assert_int_equal(10, jsonctx->value_len); assert_int_equal(1, jsonctx->dynamic); @@ -388,8 +389,8 @@ test_number(void **state) /* zero */ str = "0"; assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); - assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); + assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx)); assert_true(jsonctx->value[0] == '0'); assert_int_equal(1, jsonctx->value_len); assert_int_equal(0, jsonctx->dynamic); @@ -397,8 +398,8 @@ test_number(void **state) str = "-0"; assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); - assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); + assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx)); assert_true(jsonctx->value[0] == '-'); assert_true(jsonctx->value[1] == '0'); assert_int_equal(2, jsonctx->value_len); @@ -407,8 +408,8 @@ test_number(void **state) str = "94E0"; assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); - assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); + assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx)); assert_true(jsonctx->value[0] == '9'); assert_true(jsonctx->value[1] == '4'); assert_int_equal(2, jsonctx->value_len); @@ -417,8 +418,8 @@ test_number(void **state) str = "0E2"; assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); - assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); + assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx)); assert_true(jsonctx->value[0] == '0'); assert_int_equal(1, jsonctx->value_len); assert_int_equal(0, jsonctx->dynamic); @@ -426,8 +427,8 @@ test_number(void **state) str = "-0E2"; assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); - assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); + assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx)); assert_true(jsonctx->value[0] == '-'); assert_true(jsonctx->value[1] == '0'); assert_int_equal(2, jsonctx->value_len); @@ -436,8 +437,8 @@ test_number(void **state) str = "5.320e+2"; assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); - assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); + assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx)); assert_string_equal("532", jsonctx->value); assert_int_equal(3, jsonctx->value_len); assert_int_equal(1, jsonctx->dynamic); @@ -445,8 +446,8 @@ test_number(void **state) str = "5.320e-1"; assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); - assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); + assert_int_equal(LYJSON_NUMBER, lyjson_ctx_status(jsonctx)); assert_string_equal("0.532", jsonctx->value); assert_int_equal(5, jsonctx->value_len); assert_int_equal(1, jsonctx->dynamic); @@ -455,69 +456,64 @@ test_number(void **state) /* various invalid inputs */ str = "-x"; assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); + assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); CHECK_LOG_CTX("Invalid character in JSON Number value (\"x\").", "Line number 1."); str = " -"; assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); + assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); CHECK_LOG_CTX("Unexpected end-of-input.", "Line number 1."); str = "--1"; assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); + assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); CHECK_LOG_CTX("Invalid character in JSON Number value (\"-\").", "Line number 1."); str = "+1"; assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); + assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); CHECK_LOG_CTX("Invalid character sequence \"+1\", expected a JSON value.", "Line number 1."); str = " 1.x "; assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); + assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); CHECK_LOG_CTX("Invalid character in JSON Number value (\"x\").", "Line number 1."); str = "1."; assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); + assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); CHECK_LOG_CTX("Unexpected end-of-input.", "Line number 1."); str = " 1eo "; assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); + assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); CHECK_LOG_CTX("Invalid character in JSON Number value (\"o\").", "Line number 1."); str = "1e"; assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); + assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); CHECK_LOG_CTX("Unexpected end-of-input.", "Line number 1."); str = "1E1000"; assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); + assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); CHECK_LOG_CTX("Number encoded as a string exceeded the LY_NUMBER_MAXLEN limit.", "Line number 1."); str = "1e9999999999999999999"; assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); + assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); CHECK_LOG_CTX("Exponent out-of-bounds in a JSON Number value (1e9999999999999999999).", "Line number 1."); str = "1.1e66000"; assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); + assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); CHECK_LOG_CTX("Exponent out-of-bounds in a JSON Number value (1.1e66000).", "Line number 1."); str = "1.1e-66000"; assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); + assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); CHECK_LOG_CTX("Exponent out-of-bounds in a JSON Number value (1.1e-66000).", "Line number 1."); - str = "-2.1e0."; - assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); - CHECK_LOG_CTX("Unexpected character \".\" after JSON number.", "Line number 1."); - ly_in_free(in, 0); } @@ -532,68 +528,12 @@ test_string(void **state) str = ""; assert_int_equal(LY_SUCCESS, ly_in_new_memory(str, &in)); -#if 0 - /* simple string */ - str = "\"hello\""; - assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); - assert_int_equal(LYJSON_STRING, lyjson_ctx_status(jsonctx, 0)); - assert_ptr_equal(&str[1], jsonctx->value); - assert_int_equal(5, jsonctx->value_len); - assert_int_equal(0, jsonctx->dynamic); - lyjson_ctx_free(jsonctx); - - /* 4-byte utf8 character */ - str = "\"\\t𠜎\""; - assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); - assert_int_equal(LYJSON_STRING, lyjson_ctx_status(jsonctx, 0)); - assert_string_equal("\t𠜎", jsonctx->value); - assert_int_equal(5, jsonctx->value_len); - assert_int_equal(1, jsonctx->dynamic); - lyjson_ctx_free(jsonctx); - - /* valid escape sequences - note that here it mixes valid JSON string characters (RFC 7159, sec. 7) and - * valid characters in YANG string type (RFC 7950, sec. 9.4). Since the latter is a subset of JSON string, - * the YANG string type's restrictions apply to the JSON escape sequences */ - str = "\"\\\" \\\\ \\r \\/ \\n \\t \\u20ac\""; - assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); - assert_int_equal(LYJSON_STRING, lyjson_ctx_status(jsonctx, 0)); - assert_string_equal("\" \\ \r / \n \t €", jsonctx->value); - assert_int_equal(15, jsonctx->value_len); - assert_int_equal(1, jsonctx->dynamic); - lyjson_ctx_free(jsonctx); - - /* backspace and form feed are valid JSON escape sequences, but the control characters they represents are not allowed values for YANG string type */ - str = "\"\\b\""; - assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); - CHECK_LOG_CTX("Invalid character reference \"\\b\" (0x00000008).", "Line number 1."); - - str = "\"\\f\""; - assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); - CHECK_LOG_CTX("Invalid character reference \"\\f\" (0x0000000c).", "Line number 1."); -#endif - /* unterminated string */ str = "\"unterminated string"; assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); + assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); CHECK_LOG_CTX("Missing quotation-mark at the end of a JSON string.", "Line number 1."); -#if 0 - /* invalid escape sequence */ - str = "\"char \\x \""; - assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); - CHECK_LOG_CTX("Invalid character escape sequence \\x.", "Line number 1."); - - /* new line is allowed only as escaped character in JSON */ - str = "\"\n\""; - assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); - CHECK_LOG_CTX("Invalid character in JSON string \"\n\" (0x0000000a).", "Line number 1."); -#endif + CHECK_LOG_CTX("Unexpected end-of-input.", "Line number 1."); ly_in_free(in, 0); } @@ -608,95 +548,122 @@ test_object(void **state) /* empty */ str = " { } "; assert_int_equal(LY_SUCCESS, ly_in_new_memory(str, &in)); - assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); - assert_int_equal(LYJSON_OBJECT_EMPTY, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); + assert_int_equal(LYJSON_OBJECT, lyjson_ctx_status(jsonctx)); + + assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL)); + assert_int_equal(LYJSON_OBJECT_CLOSED, lyjson_ctx_status(jsonctx)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL)); - assert_int_equal(LYJSON_END, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LYJSON_END, lyjson_ctx_status(jsonctx)); lyjson_ctx_free(jsonctx); /* simple value */ str = "{\"name\" : \"Radek\"}"; assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); - assert_int_equal(LYJSON_OBJECT, lyjson_ctx_status(jsonctx, 0)); + + assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); + assert_int_equal(LYJSON_OBJECT, lyjson_ctx_status(jsonctx)); + + assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL)); + assert_int_equal(LYJSON_OBJECT_NAME, lyjson_ctx_status(jsonctx)); assert_ptr_equal(&str[2], jsonctx->value); assert_int_equal(4, jsonctx->value_len); assert_int_equal(0, jsonctx->dynamic); - assert_string_equal("\"Radek\"}", jsonctx->in->current); + assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL)); - assert_int_equal(LYJSON_STRING, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LYJSON_STRING, lyjson_ctx_status(jsonctx)); assert_string_equal("Radek\"}", jsonctx->value); assert_int_equal(5, jsonctx->value_len); assert_int_equal(0, jsonctx->dynamic); - assert_string_equal("}", jsonctx->in->current); + assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL)); - assert_int_equal(LYJSON_OBJECT_CLOSED, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LYJSON_OBJECT_CLOSED, lyjson_ctx_status(jsonctx)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL)); - assert_int_equal(LYJSON_END, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LYJSON_END, lyjson_ctx_status(jsonctx)); lyjson_ctx_free(jsonctx); /* two values */ str = "{\"smart\" : true,\"handsom\":false}"; assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); - assert_int_equal(LYJSON_OBJECT, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); + assert_int_equal(LYJSON_OBJECT, lyjson_ctx_status(jsonctx)); + + assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL)); + assert_int_equal(LYJSON_OBJECT_NAME, lyjson_ctx_status(jsonctx)); assert_string_equal("smart\" : true,\"handsom\":false}", jsonctx->value); assert_int_equal(5, jsonctx->value_len); assert_int_equal(0, jsonctx->dynamic); - assert_string_equal("true,\"handsom\":false}", jsonctx->in->current); + + assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL)); + assert_int_equal(LYJSON_TRUE, lyjson_ctx_status(jsonctx)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL)); - assert_int_equal(LYJSON_TRUE, lyjson_ctx_status(jsonctx, 0)); - assert_string_equal(",\"handsom\":false}", jsonctx->in->current); + assert_int_equal(LYJSON_OBJECT_NEXT, lyjson_ctx_status(jsonctx)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL)); - assert_int_equal(LYJSON_OBJECT, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LYJSON_OBJECT_NAME, lyjson_ctx_status(jsonctx)); assert_string_equal("handsom\":false}", jsonctx->value); assert_int_equal(7, jsonctx->value_len); assert_int_equal(0, jsonctx->dynamic); - assert_string_equal("false}", jsonctx->in->current); + assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL)); - assert_int_equal(LYJSON_FALSE, lyjson_ctx_status(jsonctx, 0)); - assert_string_equal("}", jsonctx->in->current); + assert_int_equal(LYJSON_FALSE, lyjson_ctx_status(jsonctx)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL)); - assert_int_equal(LYJSON_OBJECT_CLOSED, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LYJSON_OBJECT_CLOSED, lyjson_ctx_status(jsonctx)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL)); - assert_int_equal(LYJSON_END, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LYJSON_END, lyjson_ctx_status(jsonctx)); lyjson_ctx_free(jsonctx); /* inherited objects */ str = "{\"person\" : {\"name\":\"Radek\"}}"; assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); - assert_int_equal(LYJSON_OBJECT, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); + assert_int_equal(LYJSON_OBJECT, lyjson_ctx_status(jsonctx)); + + assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL)); + assert_int_equal(LYJSON_OBJECT_NAME, lyjson_ctx_status(jsonctx)); assert_string_equal("person\" : {\"name\":\"Radek\"}}", jsonctx->value); assert_int_equal(6, jsonctx->value_len); assert_int_equal(0, jsonctx->dynamic); - assert_string_equal("{\"name\":\"Radek\"}}", jsonctx->in->current); + assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL)); - assert_int_equal(LYJSON_OBJECT, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LYJSON_OBJECT, lyjson_ctx_status(jsonctx)); + + assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL)); + assert_int_equal(LYJSON_OBJECT_NAME, lyjson_ctx_status(jsonctx)); assert_string_equal("name\":\"Radek\"}}", jsonctx->value); assert_int_equal(4, jsonctx->value_len); assert_int_equal(0, jsonctx->dynamic); - assert_string_equal("\"Radek\"}}", jsonctx->in->current); + assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL)); - assert_int_equal(LYJSON_STRING, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LYJSON_STRING, lyjson_ctx_status(jsonctx)); assert_string_equal("Radek\"}}", jsonctx->value); assert_int_equal(5, jsonctx->value_len); assert_int_equal(0, jsonctx->dynamic); - assert_string_equal("}}", jsonctx->in->current); + assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL)); - assert_int_equal(LYJSON_OBJECT_CLOSED, lyjson_ctx_status(jsonctx, 0)); - assert_string_equal("}", jsonctx->in->current); + assert_int_equal(LYJSON_OBJECT_CLOSED, lyjson_ctx_status(jsonctx)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL)); - assert_int_equal(LYJSON_OBJECT_CLOSED, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LYJSON_OBJECT_CLOSED, lyjson_ctx_status(jsonctx)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL)); - assert_int_equal(LYJSON_END, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LYJSON_END, lyjson_ctx_status(jsonctx)); lyjson_ctx_free(jsonctx); - /* new line is allowed only as escaped character in JSON */ + /* unquoted string */ str = "{ unquoted : \"data\"}"; assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_EVALID, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); - CHECK_LOG_CTX("Invalid character sequence \"unquoted : \"data\"}\", expected a JSON object's member.", "Line number 1."); + assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); + assert_int_equal(LYJSON_OBJECT, lyjson_ctx_status(jsonctx)); + + assert_int_equal(LY_EVALID, lyjson_ctx_next(jsonctx, NULL)); + CHECK_LOG_CTX("Invalid character sequence \"unquoted : \"data\"}\", expected a JSON object name.", "Line number 1."); + lyjson_ctx_free(jsonctx); ly_in_free(in, 0); } @@ -711,67 +678,79 @@ test_array(void **state) /* empty */ str = " [ ] "; assert_int_equal(LY_SUCCESS, ly_in_new_memory(str, &in)); - assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); - assert_int_equal(LYJSON_ARRAY_EMPTY, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); + assert_int_equal(LYJSON_ARRAY, lyjson_ctx_status(jsonctx)); + + assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL)); + assert_int_equal(LYJSON_ARRAY_CLOSED, lyjson_ctx_status(jsonctx)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL)); - assert_int_equal(LYJSON_END, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LYJSON_END, lyjson_ctx_status(jsonctx)); lyjson_ctx_free(jsonctx); /* simple value */ str = "[ null]"; assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); - assert_int_equal(LYJSON_ARRAY, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); + assert_int_equal(LYJSON_ARRAY, lyjson_ctx_status(jsonctx)); assert_null(jsonctx->value); assert_int_equal(0, jsonctx->value_len); assert_int_equal(0, jsonctx->dynamic); - assert_string_equal("null]", jsonctx->in->current); + assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL)); - assert_int_equal(LYJSON_NULL, lyjson_ctx_status(jsonctx, 0)); - assert_string_equal("]", jsonctx->in->current); + assert_int_equal(LYJSON_NULL, lyjson_ctx_status(jsonctx)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL)); - assert_int_equal(LYJSON_ARRAY_CLOSED, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LYJSON_ARRAY_CLOSED, lyjson_ctx_status(jsonctx)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL)); - assert_int_equal(LYJSON_END, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LYJSON_END, lyjson_ctx_status(jsonctx)); lyjson_ctx_free(jsonctx); /* two values */ str = "[{\"a\":null},\"x\"]"; assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); - assert_int_equal(LYJSON_ARRAY, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); + assert_int_equal(LYJSON_ARRAY, lyjson_ctx_status(jsonctx)); assert_null(jsonctx->value); assert_int_equal(0, jsonctx->value_len); assert_int_equal(0, jsonctx->dynamic); - assert_string_equal("{\"a\":null},\"x\"]", jsonctx->in->current); + assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL)); - assert_int_equal(LYJSON_OBJECT, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LYJSON_OBJECT, lyjson_ctx_status(jsonctx)); + + assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL)); + assert_int_equal(LYJSON_OBJECT_NAME, lyjson_ctx_status(jsonctx)); assert_string_equal("a\":null},\"x\"]", jsonctx->value); assert_int_equal(1, jsonctx->value_len); assert_int_equal(0, jsonctx->dynamic); - assert_string_equal("null},\"x\"]", jsonctx->in->current); + assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL)); - assert_int_equal(LYJSON_NULL, lyjson_ctx_status(jsonctx, 0)); - assert_string_equal("},\"x\"]", jsonctx->in->current); + assert_int_equal(LYJSON_NULL, lyjson_ctx_status(jsonctx)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL)); - assert_int_equal(LYJSON_OBJECT_CLOSED, lyjson_ctx_status(jsonctx, 0)); - assert_string_equal(",\"x\"]", jsonctx->in->current); + assert_int_equal(LYJSON_OBJECT_CLOSED, lyjson_ctx_status(jsonctx)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL)); - assert_int_equal(LYJSON_STRING, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LYJSON_ARRAY_NEXT, lyjson_ctx_status(jsonctx)); + + assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL)); + assert_int_equal(LYJSON_STRING, lyjson_ctx_status(jsonctx)); assert_string_equal("x\"]", jsonctx->value); assert_int_equal(1, jsonctx->value_len); assert_int_equal(0, jsonctx->dynamic); - assert_string_equal("]", jsonctx->in->current); + assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL)); - assert_int_equal(LYJSON_ARRAY_CLOSED, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LYJSON_ARRAY_CLOSED, lyjson_ctx_status(jsonctx)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_next(jsonctx, NULL)); - assert_int_equal(LYJSON_END, lyjson_ctx_status(jsonctx, 0)); + assert_int_equal(LYJSON_END, lyjson_ctx_status(jsonctx)); lyjson_ctx_free(jsonctx); /* new line is allowed only as escaped character in JSON */ str = "[ , null]"; assert_non_null(ly_in_memory(in, str)); - assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, 0, &jsonctx)); + assert_int_equal(LY_SUCCESS, lyjson_ctx_new(UTEST_LYCTX, in, &jsonctx)); assert_int_equal(LY_EVALID, lyjson_ctx_next(jsonctx, NULL)); CHECK_LOG_CTX("Invalid character sequence \", null]\", expected a JSON value.", "Line number 1."); lyjson_ctx_free(jsonctx); diff --git a/tests/utests/basic/test_plugins.c b/tests/utests/basic/test_plugins.c index 7f3fe40..de13c0b 100644 --- a/tests/utests/basic/test_plugins.c +++ b/tests/utests/basic/test_plugins.c @@ -1,4 +1,4 @@ -/* +/** * @file test_plugins.c * @author: Radek Krejci <rkrejci@cesnet.cz> * @brief unit tests for functions from set.c diff --git a/tests/utests/basic/test_set.c b/tests/utests/basic/test_set.c index af39afa..9485927 100644 --- a/tests/utests/basic/test_set.c +++ b/tests/utests/basic/test_set.c @@ -1,4 +1,4 @@ -/* +/** * @file test_set.c * @author: Radek Krejci <rkrejci@cesnet.cz> * @brief unit tests for functions from set.c diff --git a/tests/utests/basic/test_xml.c b/tests/utests/basic/test_xml.c index 668de4b..071846a 100644 --- a/tests/utests/basic/test_xml.c +++ b/tests/utests/basic/test_xml.c @@ -1,4 +1,4 @@ -/* +/** * @file test_xml.c * @author: Radek Krejci <rkrejci@cesnet.cz> * @brief unit tests for functions from xml.c diff --git a/tests/utests/basic/test_xpath.c b/tests/utests/basic/test_xpath.c index b388dc3..754abf2 100644 --- a/tests/utests/basic/test_xpath.c +++ b/tests/utests/basic/test_xpath.c @@ -88,6 +88,19 @@ const char *schema_a = " type string;\n" " }\n" " }\n" + "\n" + " rpc r {\n" + " input {\n" + " leaf l {\n" + " type string;\n" + " }\n" + " }\n" + " output {\n" + " leaf l {\n" + " type string;\n" + " }\n" + " }\n" + " }\n" "}"; static int @@ -254,9 +267,11 @@ test_invalid(void **state) assert_int_equal(LY_EVALID, lyd_find_xpath(tree, "/a:foo2[.=]", &set)); assert_null(set); + CHECK_LOG_CTX("Unexpected XPath token \"]\" (\"]\").", NULL); assert_int_equal(LY_EVALID, lyd_find_xpath(tree, "/a:", &set)); assert_null(set); + CHECK_LOG_CTX("Invalid character 'a'[2] of expression '/a:'.", NULL); lyd_free_all(tree); } @@ -381,6 +396,31 @@ test_hash(void **state) } static void +test_rpc(void **state) +{ + const char *data = + "<r xmlns=\"urn:tests:a\">\n" + " <l>val</l>\n" + "</r>"; + struct ly_in *in; + struct lyd_node *tree; + struct ly_set *set; + + assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in)); + assert_int_equal(LY_SUCCESS, lyd_parse_op(UTEST_LYCTX, NULL, in, LYD_XML, LYD_TYPE_REPLY_YANG, &tree, NULL)); + ly_in_free(in, 0); + assert_non_null(tree); + + /* name collision input/output, hashes are not used */ + assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/a:r/l", &set)); + assert_int_equal(1, set->count); + + ly_set_free(set, NULL); + + lyd_free_all(tree); +} + +static void test_toplevel(void **state) { const char *schema_b = @@ -479,7 +519,7 @@ test_atomize(void **state) /* some random paths just making sure the API function works */ assert_int_equal(LY_SUCCESS, lys_find_xpath_atoms(UTEST_LYCTX, NULL, "/a:*", 0, &set)); - assert_int_equal(6, set->count); + assert_int_equal(7, set->count); ly_set_free(set, NULL); /* all nodes from all modules (including internal, which can change easily, so check just the test modules) */ @@ -496,7 +536,7 @@ test_atomize(void **state) ly_set_free(set, NULL); assert_int_equal(LY_SUCCESS, lys_find_xpath_atoms(UTEST_LYCTX, NULL, "/*", 0, &set)); - assert_int_equal(13, set->count); + assert_int_equal(14, set->count); ly_set_free(set, NULL); /* @@ -530,7 +570,7 @@ test_atomize(void **state) /* descendant-or-self */ assert_int_equal(LY_SUCCESS, lys_find_xpath_atoms(UTEST_LYCTX, NULL, "/a:*/descendant-or-self::c", 0, &set)); - assert_int_equal(7, set->count); + assert_int_equal(8, set->count); ly_set_free(set, NULL); /* following */ @@ -545,11 +585,11 @@ test_atomize(void **state) /* parent */ assert_int_equal(LY_SUCCESS, lys_find_xpath_atoms(UTEST_LYCTX, NULL, "/child::a:*/c/parent::l1", 0, &set)); - assert_int_equal(7, set->count); + assert_int_equal(8, set->count); ly_set_free(set, NULL); assert_int_equal(LY_SUCCESS, lys_find_xpath_atoms(UTEST_LYCTX, NULL, "/child::a:c//..", 0, &set)); - assert_int_equal(8, set->count); + assert_int_equal(11, set->count); ly_set_free(set, NULL); /* preceding */ @@ -898,6 +938,7 @@ test_variables(void **state) LOCAL_SETUP(data, tree); assert_int_equal(LY_SUCCESS, lyxp_vars_set(&vars, "var1", "\"mstr\"")); assert_int_equal(LY_ENOTFOUND, lyd_find_xpath2(tree, "/foo[text() = $var55]", vars, &set)); + CHECK_LOG_CTX("Variable \"var55\" not defined.", NULL); LOCAL_TEARDOWN(set, tree, vars); /* Syntax error in value. */ @@ -906,6 +947,7 @@ test_variables(void **state) LOCAL_SETUP(data, tree); assert_int_equal(LY_SUCCESS, lyxp_vars_set(&vars, "var", "\"")); assert_int_equal(LY_EVALID, lyd_find_xpath2(tree, "/foo[$var]", vars, &set)); + CHECK_LOG_CTX("Unterminated string delimited with \" (\").", "Data location \"/a:foo\"."); LOCAL_TEARDOWN(set, tree, vars); /* Prefix is not supported. */ @@ -914,7 +956,7 @@ test_variables(void **state) LOCAL_SETUP(data, tree); assert_int_equal(LY_SUCCESS, lyxp_vars_set(&vars, "var", "\"")); assert_int_equal(LY_EVALID, lyd_find_xpath2(tree, "/foo[$pref:var]", vars, &set)); - assert_string_equal("Variable with prefix is not supported.", _UC->err_msg); + CHECK_LOG_CTX("Variable with prefix is not supported.", NULL); LOCAL_TEARDOWN(set, tree, vars); #undef LOCAL_SETUP @@ -1050,6 +1092,154 @@ test_axes(void **state) lyd_free_all(tree); } +static void +test_trim(void **state) +{ + const char *data; + char *str1; + struct lyd_node *tree; + + data = + "<l1 xmlns=\"urn:tests:a\">" + " <a>a1</a>" + " <b>b1</b>" + " <c>c1</c>" + "</l1>" + "<l1 xmlns=\"urn:tests:a\">" + " <a>a2</a>" + " <b>b2</b>" + "</l1>" + "<l1 xmlns=\"urn:tests:a\">" + " <a>a3</a>" + " <b>b3</b>" + "</l1>" + "<l1 xmlns=\"urn:tests:a\">" + " <a>a4</a>" + " <b>b4</b>" + " <c>c4</c>" + "</l1>" + "<l1 xmlns=\"urn:tests:a\">" + " <a>a5</a>" + " <b>b5</b>" + " <c>c5</c>" + "</l1>" + "<foo2 xmlns=\"urn:tests:a\">50</foo2>" + "<c xmlns=\"urn:tests:a\">" + " <x>key2</x>" + " <ll>" + " <a>key1</a>" + " <ll>" + " <a>key11</a>" + " <b>val11</b>" + " </ll>" + " <ll>" + " <a>key12</a>" + " <b>val12</b>" + " </ll>" + " <ll>" + " <a>key13</a>" + " <b>val13</b>" + " </ll>" + " </ll>" + " <ll>" + " <a>key2</a>" + " <ll>" + " <a>key21</a>" + " <b>val21</b>" + " </ll>" + " <ll>" + " <a>key22</a>" + " <b>val22</b>" + " </ll>" + " </ll>" + " <ll>" + " <a>key3</a>" + " <ll>" + " <a>key31</a>" + " <b>val31</b>" + " </ll>" + " <ll>" + " <a>key32</a>" + " <b>val32</b>" + " </ll>" + " </ll>" + "</c>"; + + /* trim #1 */ + assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(UTEST_LYCTX, data, LYD_XML, LYD_PARSE_STRICT, LYD_VALIDATE_PRESENT, &tree)); + assert_non_null(tree); + + assert_int_equal(LY_SUCCESS, lyd_trim_xpath(&tree, "/a:c/ll/ll[a='key11']", NULL)); + lyd_print_mem(&str1, tree, LYD_XML, LYD_PRINT_WITHSIBLINGS); + assert_string_equal(str1, + "<c xmlns=\"urn:tests:a\">\n" + " <ll>\n" + " <a>key1</a>\n" + " <ll>\n" + " <a>key11</a>\n" + " <b>val11</b>\n" + " </ll>\n" + " </ll>\n" + "</c>\n"); + + free(str1); + lyd_free_all(tree); + + /* trim #2 */ + assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(UTEST_LYCTX, data, LYD_XML, LYD_PARSE_STRICT, LYD_VALIDATE_PRESENT, &tree)); + assert_non_null(tree); + + assert_int_equal(LY_SUCCESS, lyd_trim_xpath(&tree, "/a:c/ll/ll[contains(.,'2')]", NULL)); + lyd_print_mem(&str1, tree, LYD_XML, LYD_PRINT_WITHSIBLINGS); + assert_string_equal(str1, + "<c xmlns=\"urn:tests:a\">\n" + " <ll>\n" + " <a>key1</a>\n" + " <ll>\n" + " <a>key12</a>\n" + " <b>val12</b>\n" + " </ll>\n" + " </ll>\n" + " <ll>\n" + " <a>key2</a>\n" + " <ll>\n" + " <a>key21</a>\n" + " <b>val21</b>\n" + " </ll>\n" + " <ll>\n" + " <a>key22</a>\n" + " <b>val22</b>\n" + " </ll>\n" + " </ll>\n" + " <ll>\n" + " <a>key3</a>\n" + " <ll>\n" + " <a>key32</a>\n" + " <b>val32</b>\n" + " </ll>\n" + " </ll>\n" + "</c>\n"); + + free(str1); + lyd_free_all(tree); + + /* trim #3 */ + assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(UTEST_LYCTX, data, LYD_XML, LYD_PARSE_STRICT, LYD_VALIDATE_PRESENT, &tree)); + assert_non_null(tree); + + assert_int_equal(LY_SUCCESS, lyd_trim_xpath(&tree, "/l1[4]//.", NULL)); + lyd_print_mem(&str1, tree, LYD_XML, LYD_PRINT_WITHSIBLINGS); + assert_string_equal(str1, + "<l1 xmlns=\"urn:tests:a\">\n" + " <a>a4</a>\n" + " <b>b4</b>\n" + " <c>c4</c>\n" + "</l1>\n"); + + free(str1); + lyd_free_all(tree); +} + int main(void) { @@ -1058,6 +1248,7 @@ main(void) UTEST(test_union, setup), UTEST(test_invalid, setup), UTEST(test_hash, setup), + UTEST(test_rpc, setup), UTEST(test_toplevel, setup), UTEST(test_atomize, setup), UTEST(test_canonize, setup), @@ -1065,6 +1256,7 @@ main(void) UTEST(test_augment, setup), UTEST(test_variables, setup), UTEST(test_axes, setup), + UTEST(test_trim, setup), }; return cmocka_run_group_tests(tests, NULL, NULL); diff --git a/tests/utests/data/test_diff.c b/tests/utests/data/test_diff.c index 1b7592a..4400b5d 100644 --- a/tests/utests/data/test_diff.c +++ b/tests/utests/data/test_diff.c @@ -4,7 +4,7 @@ * @author Michal Vasko <mvasko@cesnet.cz> * @brief tests for lyd_diff() * - * Copyright (c) 2020 CESNET, z.s.p.o. + * Copyright (c) 2020 - 2023 CESNET, z.s.p.o. * * This source code is licensed under BSD 3-Clause License (the "License"). * You may not use this file except in compliance with the License. @@ -17,15 +17,15 @@ #include "libyang.h" -#define CHECK_PARSE_LYD(INPUT, MODEL) \ - CHECK_PARSE_LYD_PARAM(INPUT, LYD_XML, LYD_PARSE_ONLY, 0, LY_SUCCESS, MODEL) +#define CHECK_PARSE_LYD(INPUT, OUTPUT) \ + CHECK_PARSE_LYD_PARAM(INPUT, LYD_XML, LYD_PARSE_ONLY, 0, LY_SUCCESS, OUTPUT) -#define CHECK_LYD_STRING(IN_MODEL, TEXT) \ - CHECK_LYD_STRING_PARAM(IN_MODEL, TEXT, LYD_XML, LYD_PRINT_WITHSIBLINGS) +#define CHECK_LYD_STRING(INPUT, TEXT) \ + CHECK_LYD_STRING_PARAM(INPUT, TEXT, LYD_XML, LYD_PRINT_WITHSIBLINGS) -#define CHECK_PARSE_LYD_DIFF(INPUT_1, INPUT_2, OUT_MODEL) \ - assert_int_equal(LY_SUCCESS, lyd_diff_siblings(INPUT_1, INPUT_2, 0, &OUT_MODEL));\ - assert_non_null(OUT_MODEL) +#define CHECK_PARSE_LYD_DIFF(INPUT_1, INPUT_2, OUT_DIFF) \ + assert_int_equal(LY_SUCCESS, lyd_diff_siblings(INPUT_1, INPUT_2, 0, &OUT_DIFF));\ + assert_non_null(OUT_DIFF) #define TEST_DIFF_3(XML1, XML2, XML3, DIFF1, DIFF2, MERGE) \ { \ @@ -117,6 +117,12 @@ const char *schema1 = " leaf l2 {\n" " type int32;\n" " }\n" + "" + " container cont {\n" + " leaf l3 {\n" + " type string;\n" + " }\n" + " }\n" " }\n" "" " leaf-list dllist {\n" @@ -312,6 +318,8 @@ test_invalid(void **state) struct lyd_node *diff = NULL; assert_int_equal(lyd_diff_siblings(model_1, lyd_child(model_1), 0, &diff), LY_EINVAL); + CHECK_LOG_CTX("Invalid arguments - cannot create diff for unrelated data (lyd_diff()).", NULL); + assert_int_equal(lyd_diff_siblings(NULL, NULL, 0, NULL), LY_EINVAL); lyd_free_all(model_1); @@ -637,6 +645,126 @@ test_list(void **state) } static void +test_nested_list(void **state) +{ + struct lyd_node *data1, *data2, *diff; + const char *xml1, *xml2; + + (void) state; + + xml1 = + "<df xmlns=\"urn:libyang:tests:defaults\">" + " <list>" + " <name>n1</name>" + " <value>25</value>" + " <list2>" + " <name2>n22</name2>" + " <value2>26</value2>" + " </list2>" + " </list>" + " <list>" + " <name>n2</name>" + " <value>25</value>" + " <list2>" + " <name2>n22</name2>" + " <value2>26</value2>" + " </list2>" + " </list>" + " <list>" + " <name>n3</name>" + " <value>25</value>" + " <list2>" + " <name2>n22</name2>" + " <value2>26</value2>" + " </list2>" + " </list>" + " <list>" + " <name>n4</name>" + " <value>25</value>" + " <list2>" + " <name2>n22</name2>" + " <value2>26</value2>" + " </list2>" + " </list>" + " <list>" + " <name>n0</name>" + " <value>26</value>" + " <list2>" + " <name2>n22</name2>" + " <value2>26</value2>" + " </list2>" + " <list2>" + " <name2>n23</name2>" + " <value2>26</value2>" + " </list2>" + " </list>" + "</df>"; + xml2 = + "<df xmlns=\"urn:libyang:tests:defaults\">" + " <list>" + " <name>n0</name>" + " <value>30</value>" + " <list2>" + " <name2>n23</name2>" + " <value2>26</value2>" + " </list2>" + " </list>" + "</df>"; + + CHECK_PARSE_LYD(xml1, data1); + CHECK_PARSE_LYD(xml2, data2); + CHECK_PARSE_LYD_DIFF(data1, data2, diff); + + CHECK_LYD_STRING(diff, + "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n" + " <list yang:operation=\"delete\">\n" + " <name>n1</name>\n" + " <value>25</value>\n" + " <list2>\n" + " <name2>n22</name2>\n" + " <value2>26</value2>\n" + " </list2>\n" + " </list>\n" + " <list yang:operation=\"delete\">\n" + " <name>n2</name>\n" + " <value>25</value>\n" + " <list2>\n" + " <name2>n22</name2>\n" + " <value2>26</value2>\n" + " </list2>\n" + " </list>\n" + " <list yang:operation=\"delete\">\n" + " <name>n3</name>\n" + " <value>25</value>\n" + " <list2>\n" + " <name2>n22</name2>\n" + " <value2>26</value2>\n" + " </list2>\n" + " </list>\n" + " <list yang:operation=\"delete\">\n" + " <name>n4</name>\n" + " <value>25</value>\n" + " <list2>\n" + " <name2>n22</name2>\n" + " <value2>26</value2>\n" + " </list2>\n" + " </list>\n" + " <list yang:operation=\"none\">\n" + " <name>n0</name>\n" + " <value yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"26\">30</value>\n" + " <list2 yang:operation=\"delete\">\n" + " <name2>n22</name2>\n" + " <value2>26</value2>\n" + " </list2>\n" + " </list>\n" + "</df>\n"); + + lyd_free_all(data1); + lyd_free_all(data2); + lyd_free_all(diff); +} + +static void test_userord_llist(void **state) { (void) state; @@ -940,6 +1068,118 @@ test_userord_list2(void **state) } static void +test_userord_list3(void **state) +{ + (void) state; + const char *xml1 = + "<df xmlns=\"urn:libyang:tests:defaults\">\n" + " <ul>\n" + " <l1>a</l1>\n" + " <l2>1</l2>\n" + " </ul>\n" + " <ul>\n" + " <l1>b</l1>\n" + " <l2>2</l2>\n" + " </ul>\n" + " <ul>\n" + " <l1>c</l1>\n" + " <cont>\n" + " <l3>val1</l3>\n" + " </cont>\n" + " </ul>\n" + " <ul>\n" + " <l1>d</l1>\n" + " <l2>4</l2>\n" + " </ul>\n" + "</df>\n"; + const char *xml2 = + "<df xmlns=\"urn:libyang:tests:defaults\">\n" + " <ul>\n" + " <l1>c</l1>\n" + " <l2>3</l2>\n" + " <cont>\n" + " <l3>val2</l3>\n" + " </cont>\n" + " </ul>\n" + " <ul>\n" + " <l1>a</l1>\n" + " <l2>1</l2>\n" + " </ul>\n" + " <ul>\n" + " <l1>d</l1>\n" + " <l2>44</l2>\n" + " </ul>\n" + " <ul>\n" + " <l1>b</l1>\n" + " <l2>2</l2>\n" + " </ul>\n" + "</df>\n"; + const char *xml3 = + "<df xmlns=\"urn:libyang:tests:defaults\">\n" + " <ul>\n" + " <l1>a</l1>\n" + " </ul>\n" + " <ul>\n" + " <l1>c</l1>\n" + " <l2>3</l2>\n" + " <cont>\n" + " <l3>val2</l3>\n" + " </cont>\n" + " </ul>\n" + " <ul>\n" + " <l1>d</l1>\n" + " <l2>44</l2>\n" + " </ul>\n" + " <ul>\n" + " <l1>b</l1>\n" + " <l2>2</l2>\n" + " </ul>\n" + "</df>\n"; + + const char *out_diff_1 = + "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n" + " <ul yang:operation=\"replace\" yang:key=\"\" yang:orig-key=\"[l1='b']\">\n" + " <l1>c</l1>\n" + " <l2 yang:operation=\"create\">3</l2>\n" + " <cont yang:operation=\"none\">\n" + " <l3 yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"val1\">val2</l3>\n" + " </cont>\n" + " </ul>\n" + " <ul yang:operation=\"replace\" yang:key=\"[l1='a']\" yang:orig-key=\"[l1='b']\">\n" + " <l1>d</l1>\n" + " <l2 yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"4\">44</l2>\n" + " </ul>\n" + "</df>\n"; + const char *out_diff_2 = + "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n" + " <ul yang:operation=\"replace\" yang:key=\"\" yang:orig-key=\"[l1='c']\">\n" + " <l1>a</l1>\n" + " <l2 yang:operation=\"delete\">1</l2>\n" + " </ul>\n" + "</df>\n"; + const char *out_merge = + "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n" + " <ul yang:operation=\"replace\" yang:key=\"\" yang:orig-key=\"[l1='b']\">\n" + " <l1>c</l1>\n" + " <l2 yang:operation=\"create\">3</l2>\n" + " <cont yang:operation=\"none\">\n" + " <l3 yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"val1\">val2</l3>\n" + " </cont>\n" + " </ul>\n" + " <ul yang:operation=\"replace\" yang:key=\"[l1='a']\" yang:orig-key=\"[l1='b']\">\n" + " <l1>d</l1>\n" + " <l2 yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"4\">44</l2>\n" + " </ul>\n" + " <ul yang:key=\"\" yang:orig-key=\"[l1='c']\" yang:operation=\"replace\">\n" + " <l1>a</l1>\n" + " <l2 yang:operation=\"delete\">1</l2>\n" + " </ul>\n" + "</df>\n"; + + TEST_DIFF_3(xml1, xml2, xml3, out_diff_1, out_diff_2, out_merge); +} + +static void test_keyless_list(void **state) { (void) state; @@ -1207,11 +1447,13 @@ main(void) UTEST(test_delete_merge, setup), UTEST(test_leaf, setup), UTEST(test_list, setup), + UTEST(test_nested_list, setup), UTEST(test_userord_llist, setup), UTEST(test_userord_llist2, setup), UTEST(test_userord_mix, setup), UTEST(test_userord_list, setup), UTEST(test_userord_list2, setup), + UTEST(test_userord_list3, setup), UTEST(test_keyless_list, setup), UTEST(test_state_llist, setup), UTEST(test_wd, setup), diff --git a/tests/utests/data/test_new.c b/tests/utests/data/test_new.c index 7642960..5cee903 100644 --- a/tests/utests/data/test_new.c +++ b/tests/utests/data/test_new.c @@ -55,6 +55,7 @@ const char *schema_a = "module a {\n" " anydata any {\n" " config false;\n" " }\n" + " anyxml anyx;\n" " leaf-list ll2 {\n" " config false;\n" " type string;\n" @@ -128,6 +129,16 @@ test_top_level(void **state) assert_int_equal(lyd_new_list2(NULL, mod, "l1", "[a= 'a']\n[b =\t'b']", 0, &node), LY_SUCCESS); lyd_free_tree(node); + const char *key_vals[] = {"a", "b"}; + + assert_int_equal(lyd_new_list3(NULL, mod, "l1", key_vals, NULL, 0, &node), LY_SUCCESS); + lyd_free_tree(node); + + uint32_t val_lens[] = {1, 1}; + + assert_int_equal(lyd_new_list3_bin(NULL, mod, "l1", (const void **)key_vals, val_lens, 0, &node), LY_SUCCESS); + lyd_free_tree(node); + /* leaf */ assert_int_equal(lyd_new_term(NULL, mod, "foo", "[a='a'][b='b'][c='c']", 0, &node), LY_EVALID); CHECK_LOG_CTX("Invalid type uint16 value \"[a='a'][b='b'][c='c']\".", "Schema location \"/a:foo\"."); @@ -290,6 +301,7 @@ test_path(void **state) ret = lyd_new_path2(root, NULL, "/a:c2/l3[1]", NULL, 0, 0, 0, NULL, &node); assert_int_equal(ret, LY_EEXIST); + CHECK_LOG_CTX("Path \"/a:c2/l3[1]\" already exists.", "Data location \"/a:c2/l3[1]\"."); ret = lyd_new_path2(root, NULL, "/a:c2/l3[2]/x", "val2", 0, 0, 0, NULL, &node); assert_int_equal(ret, LY_SUCCESS); @@ -348,6 +360,7 @@ test_path(void **state) ret = lyd_new_path2(root, NULL, "/a:ll2[1]", "", 0, 0, 0, NULL, &node); assert_int_equal(ret, LY_EEXIST); + CHECK_LOG_CTX("Path \"/a:ll2[1]\" already exists.", "Data location \"/a:ll2[1]\"."); ret = lyd_new_path2(root, NULL, "/a:ll2[2]", "val2", 0, 0, 0, NULL, &node); assert_int_equal(ret, LY_SUCCESS); @@ -362,6 +375,7 @@ test_path(void **state) ret = lyd_new_path2(root, NULL, "/a:ll2[3][.='val3']", NULL, 0, 0, 0, NULL, &node); assert_int_equal(ret, LY_EVALID); + CHECK_LOG_CTX("Unparsed characters \"[.='val3']\" left at the end of path.", NULL); lyd_print_mem(&str, root, LYD_XML, LYD_PRINT_WITHSIBLINGS); assert_string_equal(str, @@ -391,6 +405,55 @@ test_path(void **state) "}\n"); free(str); lyd_free_siblings(root); + + /* anyxml */ + ret = lyd_new_path2(NULL, UTEST_LYCTX, "/a:anyx", "<a/><b/><c/>", 0, LYD_ANYDATA_XML, 0, &root, NULL); + assert_int_equal(ret, LY_SUCCESS); + assert_non_null(root); + + lyd_print_mem(&str, root, LYD_XML, LYD_PRINT_WITHSIBLINGS); + assert_string_equal(str, + "<anyx xmlns=\"urn:tests:a\">\n" + " <a/>\n" + " <b/>\n" + " <c/>\n" + "</anyx>\n"); + free(str); + lyd_print_mem(&str, root, LYD_JSON, LYD_PRINT_WITHSIBLINGS); + assert_string_equal(str, + "{\n" + " \"a:anyx\": {\n" + " \"a\": [null],\n" + " \"b\": [null],\n" + " \"c\": [null]\n" + " }\n" + "}\n"); + free(str); + lyd_free_siblings(root); + + ret = lyd_new_path2(NULL, UTEST_LYCTX, "/a:anyx", "{\"a\":[null],\"b\":[null],\"c\":[null]}", 0, LYD_ANYDATA_JSON, 0, &root, NULL); + assert_int_equal(ret, LY_SUCCESS); + assert_non_null(root); + + lyd_print_mem(&str, root, LYD_XML, LYD_PRINT_WITHSIBLINGS); + assert_string_equal(str, + "<anyx xmlns=\"urn:tests:a\">\n" + " <a/>\n" + " <b/>\n" + " <c/>\n" + "</anyx>\n"); + free(str); + lyd_print_mem(&str, root, LYD_JSON, LYD_PRINT_WITHSIBLINGS); + assert_string_equal(str, + "{\n" + " \"a:anyx\": {\n" + " \"a\": [null],\n" + " \"b\": [null],\n" + " \"c\": [null]\n" + " }\n" + "}\n"); + free(str); + lyd_free_siblings(root); } static void diff --git a/tests/utests/data/test_parser_json.c b/tests/utests/data/test_parser_json.c index d341e31..8feed9c 100644 --- a/tests/utests/data/test_parser_json.c +++ b/tests/utests/data/test_parser_json.c @@ -1,9 +1,10 @@ -/* +/** * @file test_parser_json.c - * @author: Radek Krejci <rkrejci@cesnet.cz> - * @brief unit tests for functions from parser_xml.c + * @author Radek Krejci <rkrejci@cesnet.cz> + * @author Michal Vasko <mvasko@cesnet.cz> + * @brief unit tests for JSON parser * - * Copyright (c) 2019 CESNET, z.s.p.o. + * Copyright (c) 2019 - 2023 CESNET, z.s.p.o. * * This source code is licensed under BSD 3-Clause License (the "License"). * You may not use this file except in compliance with the License. @@ -44,7 +45,10 @@ setup(void **state) "leaf-list ll1 { type uint8; }" "leaf foo2 { type string; default \"default-val\"; }" "leaf foo3 { type uint32; }" - "notification n2;}"; + "leaf foo4 { type uint64; }" + "rpc r1 {input {leaf l1 {type string;} leaf l2 {type string;}}}" + "notification n2;" + "}"; UTEST_SETUP; @@ -160,6 +164,7 @@ test_leaf(void **state) /* reverse solidus in JSON object member name */ data = "{\"@a:foo\":{\"a:hi\\nt\":1},\"a:foo\":\"xxx\"}"; assert_int_equal(LY_EINVAL, lyd_parse_data_mem(UTEST_LYCTX, data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, &tree)); + CHECK_LOG_CTX("Annotation definition for attribute \"a:hi\nt\" not found.", "Path \"/@a:foo/@a:hi\nt\", line number 1."); } static void @@ -427,12 +432,10 @@ test_list(void **state) assert_non_null(leaf = (struct lyd_node_term *)leaf->next); CHECK_LYSC_NODE(leaf->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "d", 1, LYS_LEAF, 1, 0, NULL, 0); CHECK_LOG_CTX(NULL, NULL); - CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, "{\"a:l1\":[{\"a\":\"a\",\"b\":\"b\",\"c\":1,\"d\":\"d\"}]}"); lyd_free_all(tree); - /* */ CHECK_PARSE_LYD("{\"a:l1\":[{\"c\":1,\"b\":\"b\",\"a\":\"a\"}]}", LYD_PARSE_STRICT, LYD_VALIDATE_PRESENT, tree); CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "l1", 1, LYS_LIST, 0, 0, NULL, 0); @@ -447,11 +450,16 @@ test_list(void **state) CHECK_LYSC_NODE(leaf->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "c", 1, LYS_LEAF, 1, 0, NULL, 0); CHECK_LOG_CTX(NULL, NULL); - CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, "{\"a:l1\":[{\"a\":\"a\",\"b\":\"b\",\"c\":1}]}"); lyd_free_all(tree); + /* skip unknown nested nodes */ + data = "{\"a:l1\":[{\"a\":\"val_a\",\"b\":\"val_b\",\"c\":3,\"counters\":{\"count1\":\"c1\",\"count2\":\"c2\"}}]}"; + CHECK_PARSE_LYD(data, LYD_PARSE_ONLY, 0, tree); + CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, "{\"a:l1\":[{\"a\":\"val_a\",\"b\":\"val_b\",\"c\":3}]}"); + lyd_free_all(tree); + data = "{\"a:cp\":{\"@\":{\"a:hint\":1}}}"; CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree); assert_non_null(tree); @@ -460,7 +468,6 @@ test_list(void **state) 1, LYS_CONTAINER, 0, 0, NULL, 0); CHECK_LYD_META(tree->meta, 1, "hint", 0, 1, INT8, "1", 1); assert_null(tree->meta->next); - CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, data); lyd_free_all(tree); } @@ -516,6 +523,25 @@ test_opaq(void **state) CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, data); lyd_free_all(tree); + /* special chars */ + data = "{\"a:foo3\":\"ab\\\"\\\\\\r\\t\"}"; + CHECK_PARSE_LYD(data, LYD_PARSE_OPAQ | LYD_PARSE_ONLY, 0, tree); + CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, data); + lyd_free_all(tree); + + /* wrong encoding */ + data = "{\"a:foo3\":\"25\"}"; + CHECK_PARSE_LYD(data, LYD_PARSE_OPAQ | LYD_PARSE_ONLY, 0, tree); + CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)tree, 0, 0, LY_VALUE_JSON, "foo3", 0, 0, NULL, 0, "25"); + CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, data); + lyd_free_all(tree); + + data = "{\"a:foo4\":25}"; + CHECK_PARSE_LYD(data, LYD_PARSE_OPAQ | LYD_PARSE_ONLY, 0, tree); + CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)tree, 0, 0, LY_VALUE_JSON, "foo4", 0, 0, NULL, 0, "25"); + CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, data); + lyd_free_all(tree); + /* missing key, no flags */ data = "{\"a:l1\":[{\"a\":\"val_a\",\"b\":\"val_b\",\"d\":\"val_d\"}]}"; PARSER_CHECK_ERROR(data, 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID, @@ -555,11 +581,12 @@ test_opaq(void **state) /* invalid metadata */ data = "{\"@a:foo\":\"str\",\"@a:foo3\":1,\"a:foo3\":2}"; PARSER_CHECK_ERROR(data, 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID, - "Unknown module of node \"@a:foo\".", "Data location \"/@a:foo\"."); + "Unknown module of node \"@a:foo\".", "Path \"/\"."); + CHECK_LOG_CTX("Missing JSON data instance to be coupled with @a:foo metadata.", "Data location \"/@a:foo\", line number 1."); /* empty name */ PARSER_CHECK_ERROR("{\"@a:foo\":{\"\":0}}", 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID, - "A JSON object member name cannot be a zero-length string.", "Line number 1."); + "JSON object member name cannot be a zero-length string.", "Data location \"/@a:foo\", line number 1."); /* opaque data tree format print */ data = @@ -626,6 +653,7 @@ static void test_rpc(void **state) { const char *data; + char *str; struct ly_in *in; struct lyd_node *tree, *op; const struct lyd_node *node; @@ -675,8 +703,16 @@ test_rpc(void **state) CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, data); lyd_free_all(tree); - /* wrong namespace, element name, whatever... */ - /* TODO */ + /* append to parent */ + assert_int_equal(LY_SUCCESS, lyd_new_path(NULL, UTEST_LYCTX, "/a:r1", NULL, 0, &op)); + assert_int_equal(LY_SUCCESS, ly_in_new_memory("{\"l1\": \"some str\", \"l2\": \"some other str\"}", &in)); + assert_int_equal(LY_SUCCESS, lyd_parse_op(UTEST_LYCTX, op, in, LYD_JSON, LYD_TYPE_RPC_YANG, &tree, NULL)); + ly_in_free(in, 0); + + assert_int_equal(LY_SUCCESS, lyd_print_mem(&str, op, LYD_JSON, LYD_PRINT_WITHSIBLINGS | LYD_PRINT_SHRINK)); + lyd_free_tree(op); + assert_string_equal(str, "{\"a:r1\":{\"l1\":\"some str\",\"l2\":\"some other str\"}}"); + free(str); } static void @@ -772,6 +808,112 @@ test_reply(void **state) /* TODO */ } +static void +test_restconf_rpc(void **state) +{ + const char *data; + struct ly_in *in; + struct lyd_node *tree, *envp; + + assert_non_null((ly_ctx_load_module(UTEST_LYCTX, "ietf-netconf-nmda", "2019-01-07", NULL))); + + assert_int_equal(LY_SUCCESS, lyd_new_path(NULL, UTEST_LYCTX, "/ietf-netconf-nmda:edit-data", NULL, 0, &tree)); + + data = "{\"ietf-netconf-nmda:input\":{" + "\"datastore\":\"ietf-datastores:running\"," + "\"config\":{\"a:cp\":{\"z\":[null],\"@z\":{\"ietf-netconf:operation\":\"replace\"}}," + "\"a:l1\":[{\"@\":{\"ietf-netconf:operation\":\"replace\"},\"a\":\"val_a\",\"b\":\"val_b\",\"c\":\"val_c\"}]}" + "}}"; + assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in)); + assert_int_equal(LY_SUCCESS, lyd_parse_op(UTEST_LYCTX, tree, in, LYD_JSON, LYD_TYPE_RPC_RESTCONF, &envp, NULL)); + ly_in_free(in, 0); + + /* the same just connected to the edit-data RPC */ + data = "{\"ietf-netconf-nmda:edit-data\":{" + "\"datastore\":\"ietf-datastores:running\"," + "\"config\":{\"a:cp\":{\"z\":[null],\"@z\":{\"ietf-netconf:operation\":\"replace\"}}," + "\"a:l1\":[{\"@\":{\"ietf-netconf:operation\":\"replace\"},\"a\":\"val_a\",\"b\":\"val_b\",\"c\":\"val_c\"}]}" + "}}"; + CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, data); + lyd_free_all(tree); + lyd_free_all(envp); +} + +static void +test_restconf_notification(void **state) +{ + const char *data; + struct ly_in *in; + struct lyd_node *tree, *ntf; + + data = "{\"ietf-restconf:notification\":{\"eventTime\":\"2013-12-21T00:01:00Z\",\"a:c\":{\"n1\":{\"nl\":\"value\"}}}}"; + assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in)); + assert_int_equal(LY_SUCCESS, lyd_parse_op(UTEST_LYCTX, NULL, in, LYD_JSON, LYD_TYPE_NOTIF_RESTCONF, &tree, &ntf)); + ly_in_free(in, 0); + + /* envelopes separately */ + data = "{\"ietf-restconf:notification\":{\"eventTime\":\"2013-12-21T00:01:00Z\"}}"; + CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, data); + + /* notification with the parent node */ + data = "{\"a:c\":{\"n1\":{\"nl\":\"value\"}}}"; + CHECK_LYD_STRING(lyd_parent(ntf), LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, data); + + lyd_free_all(tree); + lyd_free_all(ntf); + + /* wrong order */ + data = "{\"ietf-restconf:notification\":{\"a:n2\":{},\"eventTime\":\"2013-12-21T00:01:00Z\"}}"; + assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in)); + assert_int_equal(LY_SUCCESS, lyd_parse_op(UTEST_LYCTX, NULL, in, LYD_JSON, LYD_TYPE_NOTIF_RESTCONF, &tree, &ntf)); + ly_in_free(in, 0); + + lyd_free_all(tree); + lyd_free_all(ntf); + + /* unknown notification */ + data = "{\"ietf-restconf:notification\":{\"eventTime\":\"2013-12-21T00:01:00Z\",\"invalid:n2\":{}}}"; + assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in)); + assert_int_equal(LY_EVALID, lyd_parse_op(UTEST_LYCTX, NULL, in, LYD_JSON, LYD_TYPE_NOTIF_RESTCONF, &tree, &ntf)); + UTEST_LOG_CTX_CLEAN; + ly_in_free(in, 0); + lyd_free_all(tree); +} + +static void +test_restconf_reply(void **state) +{ + const char *data; + struct ly_in *in; + struct lyd_node *tree, *envp; + + assert_int_equal(LY_SUCCESS, lyd_new_path(NULL, UTEST_LYCTX, "/a:c/act", NULL, 0, &tree)); + + data = "{\"a:output\":{\"al\":25}}"; + assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in)); + assert_int_equal(LY_SUCCESS, lyd_parse_op(UTEST_LYCTX, lyd_child(tree), in, LYD_JSON, LYD_TYPE_REPLY_RESTCONF, &envp, NULL)); + ly_in_free(in, 0); + + /* connected to the RPC with the parent */ + data = "{\"a:c\":{\"act\":{\"al\":25}}}"; + CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, data); + lyd_free_all(tree); + lyd_free_all(envp); +} + +static void +test_metadata(void **state) +{ + const char *data; + struct lyd_node *tree; + + /* invalid metadata value */ + data = "{\"a:c\":{\"x\":\"xval\",\"@x\":{\"a:hint\":\"value\"}}}"; + assert_int_equal(LY_EVALID, lyd_parse_data_mem(_UC->ctx, data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, &tree)); + assert_null(tree); + CHECK_LOG_CTX("Invalid non-number-encoded int8 value \"value\".", "Path \"/a:c/x/@a:hint\", line number 1."); +} + int main(void) { @@ -787,6 +929,10 @@ main(void) UTEST(test_action, setup), UTEST(test_notification, setup), UTEST(test_reply, setup), + UTEST(test_restconf_rpc, setup), + UTEST(test_restconf_notification, setup), + UTEST(test_restconf_reply, setup), + UTEST(test_metadata, setup), }; return cmocka_run_group_tests(tests, NULL, NULL); diff --git a/tests/utests/data/test_parser_xml.c b/tests/utests/data/test_parser_xml.c index 7defd9c..4f33f00 100644 --- a/tests/utests/data/test_parser_xml.c +++ b/tests/utests/data/test_parser_xml.c @@ -31,6 +31,7 @@ setup(void **state) " namespace urn:tests:a;\n" " prefix a;\n" " yang-version 1.1;\n" + " import ietf-yang-metadata {prefix md;}" " list l1 { key \"a b c\"; leaf a {type string;} leaf b {type string;} leaf c {type int16;}" " leaf d {type string;}" " container cont {leaf e {type boolean;}}" @@ -42,9 +43,12 @@ setup(void **state) " notification n1 { leaf nl {type string;}}}\n" " container cp {presence \"container switch\"; leaf y {type string;} leaf z {type int8;}}\n" " anydata any {config false;}\n" + " anyxml anyx;\n" " leaf foo2 { type string; default \"default-val\"; }\n" " leaf foo3 { type uint32; }\n" - " notification n2;}"; + " notification n2;" + " md:annotation attr {type enumeration {enum val;}}" + "}"; UTEST_SETUP; @@ -122,6 +126,7 @@ static void test_anydata(void **state) { const char *data; + char *str; struct lyd_node *tree; data = "<any xmlns=\"urn:tests:a\">\n" @@ -145,6 +150,49 @@ test_anydata(void **state) "</any>\n"; CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, data_expected); + + assert_int_equal(LY_SUCCESS, lyd_any_value_str(tree, &str)); + lyd_free_all(tree); + + assert_int_equal(LY_SUCCESS, lyd_new_path2(NULL, UTEST_LYCTX, "/a:any", str, strlen(str), LYD_ANYDATA_XML, 0, &tree, NULL)); + free(str); + CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, data_expected); + lyd_free_all(tree); +} + +static void +test_anyxml(void **state) +{ + const char *data; + char *str; + struct lyd_node *tree; + + data = "<anyx xmlns=\"urn:tests:a\">\n" + " <element1>\n" + " <element2 x:attr2=\"test\" xmlns:x=\"urn:x\">data</element2>\n" + " </element1>\n" + " <element1a/>\n" + "</anyx>\n"; + CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree); + assert_non_null(tree); + tree = tree->next; + + const char *data_expected = + "<anyx xmlns=\"urn:tests:a\">\n" + " <element1>\n" + " <element2 xmlns:x=\"urn:x\" x:attr2=\"test\">data</element2>\n" + " </element1>\n" + " <element1a/>\n" + "</anyx>\n"; + + CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, data_expected); + + assert_int_equal(LY_SUCCESS, lyd_any_value_str(tree, &str)); + lyd_free_all(tree); + + assert_int_equal(LY_SUCCESS, lyd_new_path2(NULL, UTEST_LYCTX, "/a:anyx", str, strlen(str), LYD_ANYDATA_XML, 0, &tree, NULL)); + free(str); + CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, data_expected); lyd_free_all(tree); } @@ -170,17 +218,21 @@ test_list(void **state) /* missing keys */ PARSER_CHECK_ERROR("<l1 xmlns=\"urn:tests:a\"><c>1</c><b>b</b></l1>", 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID, "List instance is missing its key \"a\".", "Data location \"/a:l1[b='b'][c='1']\", line number 1."); + CHECK_LOG_CTX("Invalid position of the key \"b\" in a list.", NULL); PARSER_CHECK_ERROR("<l1 xmlns=\"urn:tests:a\"><a>a</a></l1>", 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID, "List instance is missing its key \"b\".", "Data location \"/a:l1[a='a']\", line number 1."); PARSER_CHECK_ERROR("<l1 xmlns=\"urn:tests:a\"><b>b</b><a>a</a></l1>", 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID, "List instance is missing its key \"c\".", "Data location \"/a:l1[a='a'][b='b']\", line number 1."); + CHECK_LOG_CTX("Invalid position of the key \"a\" in a list.", NULL); /* key duplicate */ PARSER_CHECK_ERROR("<l1 xmlns=\"urn:tests:a\"><c>1</c><b>b</b><a>a</a><c>1</c></l1>", 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID, "Duplicate instance of \"c\".", "Data location \"/a:l1[a='a'][b='b'][c='1'][c='1']/c\", line number 1."); + CHECK_LOG_CTX("Invalid position of the key \"a\" in a list.", NULL); + CHECK_LOG_CTX("Invalid position of the key \"b\" in a list.", NULL); /* keys order */ CHECK_PARSE_LYD("<l1 xmlns=\"urn:tests:a\"><d>d</d><a>a</a><c>1</c><b>b</b></l1>", 0, LYD_VALIDATE_PRESENT, tree); @@ -209,6 +261,7 @@ test_list(void **state) assert_non_null(leaf = (struct lyd_node_term *)leaf->next); CHECK_LYSC_NODE(leaf->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "c", 1, LYS_LEAF, 1, 0, NULL, 0); CHECK_LOG_CTX("Invalid position of the key \"a\" in a list.", NULL); + CHECK_LOG_CTX("Invalid position of the key \"b\" in a list.", NULL); lyd_free_all(tree); PARSER_CHECK_ERROR(data, LYD_PARSE_STRICT, LYD_VALIDATE_PRESENT, tree, LY_EVALID, @@ -250,14 +303,14 @@ test_opaq(void **state) /* opaq flag */ CHECK_PARSE_LYD(data, LYD_PARSE_OPAQ | LYD_PARSE_ONLY, 0, tree); - CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)tree, 0, 0, LY_VALUE_XML, "foo3", 0, 0, NULL, 0, ""); + CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)tree, 0, 0, LY_VALUE_XML, "foo3", 0, 0, NULL, 1, ""); CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, "<foo3 xmlns=\"urn:tests:a\"/>\n"); lyd_free_all(tree); /* list, opaq flag */ data = "<l1 xmlns=\"urn:tests:a\"/>"; CHECK_PARSE_LYD(data, LYD_PARSE_OPAQ | LYD_PARSE_ONLY, 0, tree); - CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)tree, 0, 0, LY_VALUE_XML, "l1", 0, 0, NULL, 0, ""); + CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)tree, 0, 0, LY_VALUE_XML, "l1", 0, 0, NULL, 1, ""); CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, "<l1 xmlns=\"urn:tests:a\"/>\n"); lyd_free_all(tree); @@ -273,7 +326,7 @@ test_opaq(void **state) /* opaq flag */ CHECK_PARSE_LYD(data, LYD_PARSE_OPAQ | LYD_PARSE_ONLY, 0, tree); - CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)tree, 0, 0x1, LY_VALUE_XML, "l1", 0, 0, NULL, 0, ""); + CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)tree, 0, 0x1, LY_VALUE_XML, "l1", 0, 0, NULL, 1, ""); CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, data); lyd_free_all(tree); @@ -289,7 +342,7 @@ test_opaq(void **state) /* opaq flag */ CHECK_PARSE_LYD(data, LYD_PARSE_OPAQ | LYD_PARSE_ONLY, 0, tree); - CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)tree, 0, 0x1, LY_VALUE_XML, "l1", 0, 0, NULL, 0, ""); + CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)tree, 0, 0x1, LY_VALUE_XML, "l1", 0, 0, NULL, 1, ""); CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, data); lyd_free_all(tree); @@ -300,7 +353,7 @@ test_opaq(void **state) " <c xmld:id=\"D\">1</c>\n" "</a>\n", LYD_XML, LYD_PARSE_OPAQ, LYD_VALIDATE_PRESENT, &tree)); - CHECK_LOG_CTX("Unknown XML prefix \"xmld\".", "Line number 3."); + CHECK_LOG_CTX("Unknown XML prefix \"xmld\".", "Data location \"/a\", line number 3."); } static void @@ -358,10 +411,10 @@ test_rpc(void **state) node = lyd_child(node); /* z has no value */ - CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)node, 0x1, 0, LY_VALUE_XML, "z", 0, 0, NULL, 0, ""); + CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)node, 0x1, 0, LY_VALUE_XML, "z", 0, 0, NULL, 1, ""); node = node->parent->next; /* l1 key c has invalid value so it is at the end */ - CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)node, 0x1, 0x1, LY_VALUE_XML, "l1", 0, 0, NULL, 0, ""); + CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)node, 0x1, 0x1, LY_VALUE_XML, "l1", 0, 0, NULL, 1, ""); CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, "<edit-config xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n" @@ -554,10 +607,10 @@ test_netconf_rpc(void **state) node = lyd_child(node); /* z has no value */ - CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)node, 0x1, 0, LY_VALUE_XML, "z", 0, 0, NULL, 0, ""); + CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)node, 0x1, 0, LY_VALUE_XML, "z", 0, 0, NULL, 1, ""); node = node->parent->next; /* l1 key c has invalid value so it is at the end */ - CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)node, 0x1, 0x1, LY_VALUE_XML, "l1", 0, 0, NULL, 0, ""); + CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)node, 0x1, 0x1, LY_VALUE_XML, "l1", 0, 0, NULL, 1, ""); CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, "<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" message-id=\"25\"/>\n"); @@ -581,8 +634,33 @@ test_netconf_rpc(void **state) lyd_free_all(tree); lyd_free_all(op); - /* wrong namespace, element name, whatever... */ - /* TODO */ + /* invalid anyxml nested metadata value */ + data = "<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" message-id=\"1\" pid=\"4114692032\">\n" + " <copy-config>\n" + " <target>\n" + " <running/>\n" + " </target>\n" + " <source>\n" + " <config>\n" + " <l1 xmlns=\"urn:tests:a\" xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n" + " <a>val_a</a>\n" + " <b>val_b</b>\n" + " <c>5</c>\n" + " <cont nc:operation=\"merge\">\n" + " <e nc:operation=\"merge2\">false</e>\n" + " </cont>\n" + " </l1>\n" + " </config>\n" + " </source>\n" + " </copy-config>\n" + "</rpc>\n"; + assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in)); + assert_int_equal(LY_EVALID, lyd_parse_op(UTEST_LYCTX, NULL, in, LYD_XML, LYD_TYPE_RPC_NETCONF, &tree, &op)); + ly_in_free(in, 0); + CHECK_LOG_CTX("Invalid enumeration value \"merge2\".", + "Path \"/ietf-netconf:copy-config/source/config/a:l1[a='val_a'][b='val_b'][c='5']/cont/e/@ietf-netconf:operation\", line number 13."); + lyd_free_all(tree); + assert_null(op); } static void @@ -678,6 +756,22 @@ test_netconf_reply_or_notification(void **state) lyd_free_all(tree); lyd_free_all(op2); + /* notification with a different order */ + data = "<notification xmlns=\"urn:ietf:params:xml:ns:netconf:notification:1.0\">\n" + "<c xmlns=\"urn:tests:a\">\n" + " <n1>\n" + " <nl>value</nl>\n" + " </n1>\n" + "</c>\n" + "<eventTime>2010-12-06T08:00:01Z</eventTime>\n" + "</notification>\n"; + assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in)); + assert_int_equal(LY_SUCCESS, lyd_parse_op(UTEST_LYCTX, NULL, in, LYD_XML, LYD_TYPE_NOTIF_NETCONF, &tree, &op2)); + ly_in_free(in, 0); + + lyd_free_all(tree); + lyd_free_all(op2); + /* parse a data reply */ data = "<rpc-reply message-id=\"55\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n" " <al xmlns=\"urn:tests:a\">25</al>\n" @@ -739,6 +833,64 @@ test_netconf_reply_or_notification(void **state) } static void +test_restconf_rpc(void **state) +{ + const char *data; + struct ly_in *in; + struct lyd_node *tree, *envp; + + assert_non_null((ly_ctx_load_module(UTEST_LYCTX, "ietf-netconf-nmda", "2019-01-07", NULL))); + + assert_int_equal(LY_SUCCESS, lyd_new_path(NULL, UTEST_LYCTX, "/ietf-netconf-nmda:edit-data", NULL, 0, &tree)); + + data = "<input xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-nmda\">" + "<datastore xmlns:ds=\"urn:ietf:params:xml:ns:yang:ietf-datastores\">ds:running</datastore>" + "<config>" + "<cp xmlns=\"urn:tests:a\"><z xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\" nc:operation=\"replace\"/></cp>" + "<l1 xmlns=\"urn:tests:a\" xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\" nc:operation=\"replace\">" + "<a>val_a</a><b>val_b</b><c>val_c</c>" + "</l1>" + "</config></input>"; + assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in)); + assert_int_equal(LY_SUCCESS, lyd_parse_op(UTEST_LYCTX, tree, in, LYD_XML, LYD_TYPE_RPC_RESTCONF, &envp, NULL)); + ly_in_free(in, 0); + + /* the same just connected to the edit-data RPC */ + data = "<edit-data xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-nmda\">" + "<datastore xmlns:ds=\"urn:ietf:params:xml:ns:yang:ietf-datastores\">ds:running</datastore>" + "<config>" + "<cp xmlns=\"urn:tests:a\"><z xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\" nc:operation=\"replace\"/></cp>" + "<l1 xmlns=\"urn:tests:a\" xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\" nc:operation=\"replace\">" + "<a>val_a</a><b>val_b</b><c>val_c</c>" + "</l1>" + "</config></edit-data>"; + CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, data); + lyd_free_all(tree); + lyd_free_all(envp); +} + +static void +test_restconf_reply(void **state) +{ + const char *data; + struct ly_in *in; + struct lyd_node *tree, *envp; + + assert_int_equal(LY_SUCCESS, lyd_new_path(NULL, UTEST_LYCTX, "/a:c/act", NULL, 0, &tree)); + + data = "<output xmlns=\"urn:tests:a\"><al>25</al></output>"; + assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in)); + assert_int_equal(LY_SUCCESS, lyd_parse_op(UTEST_LYCTX, lyd_child(tree), in, LYD_XML, LYD_TYPE_REPLY_RESTCONF, &envp, NULL)); + ly_in_free(in, 0); + + /* connected to the RPC with the parent */ + data = "<c xmlns=\"urn:tests:a\"><act><al>25</al></act></c>"; + CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, data); + lyd_free_all(tree); + lyd_free_all(envp); +} + +static void test_filter_attributes(void **state) { const char *data; @@ -812,12 +964,58 @@ test_data_skip(void **state) lyd_free_all(tree); } +static void +test_metadata(void **state) +{ + const char *data; + struct lyd_node *tree; + + /* invalid metadata value */ + data = "<c xmlns=\"urn:tests:a\" xmlns:a=\"urn:tests:a\"><x a:attr=\"value\">xval</x></c>"; + assert_int_equal(LY_EVALID, lyd_parse_data_mem(_UC->ctx, data, LYD_XML, 0, LYD_VALIDATE_PRESENT, &tree)); + assert_null(tree); + CHECK_LOG_CTX("Invalid enumeration value \"value\".", "Path \"/a:c/x/@a:attr\", line number 1."); +} + +static void +test_subtree(void **state) +{ + const char *data; + struct ly_in *in; + struct lyd_node *tree; + + /* prepare data with the parent */ + data = "<l1 xmlns=\"urn:tests:a\">\n" + " <a>val_a</a>\n" + " <b>val_b</b>\n" + " <c>1</c>\n" + "</l1>\n"; + assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(UTEST_LYCTX, data, LYD_XML, 0, LYD_VALIDATE_PRESENT, &tree)); + + /* parse a subtree of it */ + data = "<cont xmlns=\"urn:tests:a\">\n" + " <e>true</e>\n" + "</cont>\n"; + assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in)); + assert_int_equal(LY_SUCCESS, lyd_parse_data(UTEST_LYCTX, tree, in, LYD_XML, 0, LYD_VALIDATE_PRESENT, NULL)); + ly_in_free(in, 0); + + /* parse another container, fails */ + assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in)); + assert_int_equal(LY_EVALID, lyd_parse_data(UTEST_LYCTX, tree, in, LYD_XML, 0, LYD_VALIDATE_PRESENT, NULL)); + ly_in_free(in, 0); + CHECK_LOG_CTX("Duplicate instance of \"cont\".", "Data location \"/a:l1[a='val_a'][b='val_b'][c='1']/cont\"."); + + lyd_free_all(tree); +} + int main(void) { const struct CMUnitTest tests[] = { UTEST(test_leaf, setup), UTEST(test_anydata, setup), + UTEST(test_anyxml, setup), UTEST(test_list, setup), UTEST(test_container, setup), UTEST(test_opaq, setup), @@ -828,8 +1026,12 @@ main(void) UTEST(test_netconf_rpc, setup), UTEST(test_netconf_action, setup), UTEST(test_netconf_reply_or_notification, setup), + UTEST(test_restconf_rpc, setup), + UTEST(test_restconf_reply, setup), UTEST(test_filter_attributes, setup), UTEST(test_data_skip, setup), + UTEST(test_metadata, setup), + UTEST(test_subtree, setup), }; return cmocka_run_group_tests(tests, NULL, NULL); diff --git a/tests/utests/data/test_printer_xml.c b/tests/utests/data/test_printer_xml.c index d533c41..6213a37 100644 --- a/tests/utests/data/test_printer_xml.c +++ b/tests/utests/data/test_printer_xml.c @@ -145,7 +145,8 @@ test_anydata(void **state) " <cont>\n" " <elem1 xmlns=\"urn:tests:defs\">\n" " <elem2 xmlns=\"urn:tests:types\" xmlns:defs=\"urn:tests:defs\" xmlns:defaults=\"urn:defaults\" " - "defs:attr1=\"defaults:val\" attr2=\"/defaults:node/defs:node2\"/>\n" + "defs:attr1=\"defaults:val\" attr2=\"/defaults:node/defs:node2\">\n" + " </elem2>\n" " </elem1>\n" " </cont>\n" "</any>\n"; diff --git a/tests/utests/data/test_tree_data.c b/tests/utests/data/test_tree_data.c index 27dba42..494fdf3 100644 --- a/tests/utests/data/test_tree_data.c +++ b/tests/utests/data/test_tree_data.c @@ -1,9 +1,9 @@ /** * @file test_tree_data.c - * @author: Radek Krejci <rkrejci@cesnet.cz> - * @brief unit tests for functions from tress_data.c + * @author Radek Krejci <rkrejci@cesnet.cz> + * @brief unit tests for functions from tree_data.c * - * Copyright (c) 2018-2019 CESNET, z.s.p.o. + * Copyright (c) 2018-2023 CESNET, z.s.p.o. * * This source code is licensed under BSD 3-Clause License (the "License"). * You may not use this file except in compliance with the License. @@ -100,7 +100,7 @@ test_compare(void **state) data2 = "<l2 xmlns=\"urn:tests:a\"><c><x>b</x></c></l2>"; CHECK_PARSE_LYD(data1, 0, LYD_VALIDATE_PRESENT, tree1); CHECK_PARSE_LYD(data2, 0, LYD_VALIDATE_PRESENT, tree2); - assert_int_equal(LY_ENOT, lyd_compare_single(tree1->next, tree2->next, 0)); + assert_int_equal(LY_ENOT, lyd_compare_single(tree1->next, tree2->next, LYD_COMPARE_FULL_RECURSION)); assert_int_equal(LY_SUCCESS, lyd_compare_single(tree1->next->next, tree2->next, 0)); lyd_free_all(tree1); lyd_free_all(tree2); @@ -145,6 +145,14 @@ test_compare(void **state) assert_int_equal(LY_SUCCESS, lyd_compare_single(tree1, tree2, 0)); lyd_free_all(tree1); lyd_free_all(tree2); + + data1 = "<c xmlns=\"urn:tests:a\"><x>c</x><x>a</x><x>b</x></c>"; + data2 = "<c xmlns=\"urn:tests:a\"><x>a</x><x>b</x><x>c</x></c>"; + CHECK_PARSE_LYD(data1, 0, LYD_VALIDATE_PRESENT, tree1); + CHECK_PARSE_LYD(data2, 0, LYD_VALIDATE_PRESENT, tree2); + assert_int_equal(LY_SUCCESS, lyd_compare_single(tree1, tree2, LYD_COMPARE_FULL_RECURSION)); + lyd_free_all(tree1); + lyd_free_all(tree2); } static void @@ -196,7 +204,7 @@ test_compare_diff_ctx(void **state) data2 = "<l2 xmlns=\"urn:tests:b\"><c><x>b</x></c></l2>"; CHECK_PARSE_LYD_PARAM_CTX(UTEST_LYCTX, data1, 0, tree1); CHECK_PARSE_LYD_PARAM_CTX(ctx2, data2, 0, tree2); - assert_int_equal(LY_ENOT, lyd_compare_single(tree1, tree2, 0)); + assert_int_equal(LY_SUCCESS, lyd_compare_single(tree1, tree2, 0)); lyd_free_all(tree1); lyd_free_all(tree2); @@ -210,7 +218,7 @@ test_compare_diff_ctx(void **state) data2 = "<l2 xmlns=\"urn:tests:b\"><c><x>b</x></c></l2>"; CHECK_PARSE_LYD_PARAM_CTX(UTEST_LYCTX, data1, 0, tree1); CHECK_PARSE_LYD_PARAM_CTX(ctx2, data2, 0, tree2); - assert_int_equal(LY_ENOT, lyd_compare_single(tree1, tree2, 0)); + assert_int_equal(LY_SUCCESS, lyd_compare_single(tree1, tree2, 0)); lyd_free_all(tree1); lyd_free_all(tree2); @@ -329,8 +337,7 @@ test_dup(void **state) data = "<l2 xmlns=\"urn:tests:a\"><c><x>b</x></c></l2>"; CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree1); - assert_int_equal(LY_SUCCESS, lyd_dup_single(((struct lyd_node_inner *)((struct lyd_node_inner *)tree1->next)->child)->child, NULL, - LYD_DUP_WITH_PARENTS, &tree2)); + assert_int_equal(LY_SUCCESS, lyd_dup_single(lyd_child(lyd_child(tree1->next)), NULL, LYD_DUP_WITH_PARENTS, &tree2)); int unsigned flag = LYS_CONFIG_R | LYS_SET_ENUM; CHECK_LYSC_NODE(tree2->schema, NULL, 0, flag, 1, "x", 1, LYS_LEAF, 1, 0, NULL, 0); @@ -352,8 +359,8 @@ test_dup(void **state) data = "<l2 xmlns=\"urn:tests:a\"><c><x>b</x></c></l2>"; CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree1); assert_int_equal(LY_SUCCESS, lyd_dup_single(tree1->next, NULL, 0, &tree2)); - assert_int_equal(LY_SUCCESS, lyd_dup_single(((struct lyd_node_inner *)((struct lyd_node_inner *)tree1->next)->child)->child, - (struct lyd_node_inner *)tree2, LYD_DUP_WITH_PARENTS, NULL)); + assert_int_equal(LY_SUCCESS, lyd_dup_single(lyd_child(lyd_child(tree1->next)), (struct lyd_node_inner *)tree2, + LYD_DUP_WITH_PARENTS, NULL)); assert_int_equal(LY_SUCCESS, lyd_compare_single(tree1->next, tree2, LYD_COMPARE_FULL_RECURSION)); lyd_free_all(tree1); lyd_free_all(tree2); @@ -363,6 +370,8 @@ test_dup(void **state) CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree1); assert_int_equal(LY_EINVAL, lyd_dup_single(((struct lyd_node_inner *)tree1)->child->prev, (struct lyd_node_inner *)tree1->next, LYD_DUP_WITH_PARENTS, NULL)); + CHECK_LOG_CTX("None of the duplicated node \"c\" schema parents match the provided parent \"c\".", + NULL); lyd_free_all(tree1); } @@ -488,6 +497,11 @@ test_find_path(void **state) assert_int_equal(LY_SUCCESS, lyd_find_path(root, "/c:cont/nexthop[gateway='10.0.0.1']", 0, NULL)); assert_int_equal(LY_SUCCESS, lyd_find_path(root, "/c:cont/nexthop[gateway='2100::1']", 0, NULL)); assert_int_equal(LY_SUCCESS, lyd_find_path(root, "/c:cont/pref[.='fc00::/64']", 0, NULL)); + + assert_int_equal(LY_EVALID, lyd_find_path(root, "/cont", 0, NULL)); + CHECK_LOG_CTX("Prefix missing for \"cont\" in path.", "Schema location \"/c:cont\"."); + assert_int_equal(LY_SUCCESS, lyd_find_path(root, "nexthop[gateway='2100::1']", 0, NULL)); + lyd_free_all(root); } @@ -525,6 +539,7 @@ test_data_hash(void **state) /* The run must not crash due to the assert that checks the hash. */ CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree); + CHECK_LOG_CTX("Duplicate instance of \"ll\".", "Data location \"/test-data-hash:c/ll[.='']\", line number 1."); lyd_free_all(tree); } diff --git a/tests/utests/data/test_validation.c b/tests/utests/data/test_validation.c index 415e16a..d0dcae5 100644 --- a/tests/utests/data/test_validation.c +++ b/tests/utests/data/test_validation.c @@ -1154,6 +1154,92 @@ test_must(void **state) CHECK_LOG_CTX_APPTAG("l leaf is not left", "Data location \"/i:cont/l3\".", "not-left"); } +static void +test_multi_error(void **state) +{ + struct lyd_node *tree; + const char *schema = + "module ii {\n" + " namespace urn:tests:ii;\n" + " prefix ii;\n" + " yang-version 1.1;\n" + "\n" + " container cont {\n" + " leaf l {\n" + " type string;\n" + " }\n" + " leaf l2 {\n" + " must \"../l = 'right'\";\n" + " type string;\n" + " }\n" + " leaf l3 {\n" + " must \"../l = 'left'\" {\n" + " error-app-tag \"not-left\";\n" + " error-message \"l leaf is not left\";\n" + " }\n" + " type string;\n" + " }\n" + " leaf-list ll {\n" + " type uint32;\n" + " min-elements 2;\n" + " }\n" + " }\n" + "}"; + const char *data; + + UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL); + + /* xml */ + data = + "<cont xmlns=\"urn:tests:ii\">\n" + " <l>wrong</l>\n" + " <l>wrong2</l>\n" + " <l2>val</l2>\n" + " <l3>val</l3>\n" + " <ll>ahoy</ll>\n" + "</cont>\n"; + CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT | LYD_VALIDATE_MULTI_ERROR, LY_EVALID, tree); + CHECK_LOG_CTX_APPTAG("Too few \"ll\" instances.", "Schema location \"/ii:cont/ll\".", "too-few-elements"); + CHECK_LOG_CTX_APPTAG("l leaf is not left", "Data location \"/ii:cont/l3\".", "not-left"); + CHECK_LOG_CTX_APPTAG("Must condition \"../l = 'right'\" not satisfied.", "Data location \"/ii:cont/l2\".", "must-violation"); + CHECK_LOG_CTX_APPTAG("Invalid type uint32 value \"ahoy\".", "Data location \"/ii:cont/ll\", line number 6.", NULL); + + /* json */ + data = "{\n" + " \"ii:cont\": {\n" + " \"l\": \"wrong\",\n" + " \"l\": \"wrong2\",\n" + " \"l2\": \"val\",\n" + " \"l3\": \"val\",\n" + " \"ll\": [\"ahoy\"]\n" + " }\n" + "}\n"; + CHECK_PARSE_LYD_PARAM(data, LYD_JSON, 0, LYD_VALIDATE_PRESENT | LYD_VALIDATE_MULTI_ERROR, LY_EVALID, tree); + CHECK_LOG_CTX_APPTAG("Too few \"ll\" instances.", "Schema location \"/ii:cont/ll\".", "too-few-elements"); + CHECK_LOG_CTX_APPTAG("l leaf is not left", "Data location \"/ii:cont/l3\".", "not-left"); + CHECK_LOG_CTX_APPTAG("Must condition \"../l = 'right'\" not satisfied.", "Data location \"/ii:cont/l2\".", "must-violation"); + CHECK_LOG_CTX_APPTAG("Invalid non-number-encoded uint32 value \"ahoy\".", "Data location \"/ii:cont/ll\", line number 7.", NULL); + + /* validation */ + data = "{\n" + " \"ii:cont\": {\n" + " \"l\": \"wrong\",\n" + " \"l\": \"wrong2\",\n" + " \"l2\": \"val\",\n" + " \"l3\": \"val\",\n" + " \"ll\": [25]\n" + " }\n" + "}\n"; + CHECK_PARSE_LYD_PARAM(data, LYD_JSON, LYD_PARSE_ONLY, 0, LY_SUCCESS, tree); + assert_int_equal(LY_EVALID, lyd_validate_all(&tree, NULL, LYD_VALIDATE_PRESENT | LYD_VALIDATE_MULTI_ERROR, NULL)); + lyd_free_tree(tree); + CHECK_LOG_CTX_APPTAG("Too few \"ll\" instances.", "Schema location \"/ii:cont/ll\".", "too-few-elements"); + CHECK_LOG_CTX_APPTAG("l leaf is not left", "Data location \"/ii:cont/l3\".", "not-left"); + CHECK_LOG_CTX_APPTAG("Must condition \"../l = 'right'\" not satisfied.", "Data location \"/ii:cont/l2\".", "must-violation"); + CHECK_LOG_CTX_APPTAG("Duplicate instance of \"l\".", "Data location \"/ii:cont/l\".", NULL); + CHECK_LOG_CTX_APPTAG("Duplicate instance of \"l\".", "Data location \"/ii:cont/l\".", NULL); +} + const char *schema_j = "module j {\n" " namespace urn:tests:j;\n" @@ -1212,6 +1298,7 @@ test_action(void **state) struct lyd_node *tree, *op_tree; UTEST_ADD_MODULE(schema_j, LYS_IN_YANG, feats_j, NULL); + UTEST_LOG_CTX_CLEAN; assert_int_equal(LY_SUCCESS, ly_in_new_memory( "<cont xmlns=\"urn:tests:j\">\n" @@ -1304,6 +1391,7 @@ test_reply(void **state) struct lyd_node *tree, *op_tree; UTEST_ADD_MODULE(schema_j, LYS_IN_YANG, feats_j, NULL); + UTEST_LOG_CTX_CLEAN; assert_int_equal(LY_SUCCESS, ly_in_new_memory( "<cont xmlns=\"urn:tests:j\">\n" @@ -1422,7 +1510,7 @@ test_case(void **state) " }\n" "}\n", LYD_JSON, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree); CHECK_LOG_CTX("Data for both cases \"v0\" and \"v2\" exist.", - "Data location \"/k:ch\", line number 5."); + "Data location \"/k:ch\", line number 6."); CHECK_PARSE_LYD_PARAM( "{\n" @@ -1432,7 +1520,7 @@ test_case(void **state) " }\n" "}\n", LYD_JSON, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree); CHECK_LOG_CTX("Data for both cases \"v0\" and \"v2\" exist.", - "Data location \"/k:ch\", line number 5."); + "Data location \"/k:ch\", line number 6."); } int @@ -1450,6 +1538,7 @@ main(void) UTEST(test_defaults), UTEST(test_state), UTEST(test_must), + UTEST(test_multi_error), UTEST(test_action), UTEST(test_rpc), UTEST(test_reply), diff --git a/tests/utests/extensions/test_metadata.c b/tests/utests/extensions/test_metadata.c index 39d29be..f1edd29 100644 --- a/tests/utests/extensions/test_metadata.c +++ b/tests/utests/extensions/test_metadata.c @@ -53,7 +53,7 @@ test_yang(void **state) "md:annotation aa;}"; assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, data, LYS_IN_YANG, NULL)); CHECK_LOG_CTX("Ext plugin \"ly2 metadata v1\": Missing mandatory keyword \"type\" as a child of \"md:annotation aa\".", - "/aa:{extension='md:annotation'}/aa"); + "Path \"/aa:{extension='md:annotation'}/aa\"."); /* not allowed substatement */ data = "module aa {yang-version 1.1; namespace urn:tests:extensions:metadata:aa; prefix aa;" @@ -61,7 +61,7 @@ test_yang(void **state) "md:annotation aa {default x;}}"; assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, data, LYS_IN_YANG, NULL)); CHECK_LOG_CTX("Invalid keyword \"default\" as a child of \"md:annotation aa\" extension instance.", - "/aa:{extension='md:annotation'}/aa"); + "Path \"/aa:{extension='md:annotation'}/aa\"."); /* invalid cardinality of units substatement */ data = "module aa {yang-version 1.1; namespace urn:tests:extensions:metadata:aa; prefix aa;" @@ -69,7 +69,7 @@ test_yang(void **state) "md:annotation aa {type string; units x; units y;}}"; assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, data, LYS_IN_YANG, NULL)); CHECK_LOG_CTX("Duplicate keyword \"units\".", - "/aa:{extension='md:annotation'}/aa"); + "Path \"/aa:{extension='md:annotation'}/aa\"."); /* invalid cardinality of status substatement */ data = "module aa {yang-version 1.1; namespace urn:tests:extensions:metadata:aa; prefix aa;" @@ -77,7 +77,7 @@ test_yang(void **state) "md:annotation aa {type string; status current; status obsolete;}}"; assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, data, LYS_IN_YANG, NULL)); CHECK_LOG_CTX("Duplicate keyword \"status\".", - "/aa:{extension='md:annotation'}/aa"); + "Path \"/aa:{extension='md:annotation'}/aa\"."); /* invalid cardinality of status substatement */ data = "module aa {yang-version 1.1; namespace urn:tests:extensions:metadata:aa; prefix aa;" @@ -85,7 +85,7 @@ test_yang(void **state) "md:annotation aa {type string; type uint8;}}"; assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, data, LYS_IN_YANG, NULL)); CHECK_LOG_CTX("Duplicate keyword \"type\".", - "/aa:{extension='md:annotation'}/aa"); + "Path \"/aa:{extension='md:annotation'}/aa\"."); /* duplication of the same annotation */ data = "module aa {yang-version 1.1; namespace urn:tests:extensions:metadata:aa; prefix aa;" @@ -93,7 +93,7 @@ test_yang(void **state) "md:annotation aa {type string;} md:annotation aa {type uint8;}}"; assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, data, LYS_IN_YANG, NULL)); CHECK_LOG_CTX("Ext plugin \"ly2 metadata v1\": Extension md:annotation is instantiated multiple times.", - "/aa:{extension='md:annotation'}/aa"); + "Path \"/aa:{extension='md:annotation'}/aa\"."); } static void @@ -134,7 +134,7 @@ test_yin(void **state) "</module>"; assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, data, LYS_IN_YIN, NULL)); CHECK_LOG_CTX("Ext plugin \"ly2 metadata v1\": Missing mandatory keyword \"type\" as a child of \"md:annotation aa\".", - "/aa:{extension='md:annotation'}/aa"); + "Path \"/aa:{extension='md:annotation'}/aa\"."); /* not allowed substatement */ data = "<module xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\" xmlns:md=\"urn:ietf:params:xml:ns:yang:ietf-yang-metadata\" name=\"aa\">\n" @@ -145,7 +145,7 @@ test_yin(void **state) "</md:annotation></module>"; assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, data, LYS_IN_YIN, NULL)); CHECK_LOG_CTX("Invalid keyword \"default\" as a child of \"md:annotation aa\" extension instance.", - "/aa:{extension='md:annotation'}/aa"); + "Path \"/aa:{extension='md:annotation'}/aa\"."); /* invalid cardinality of units substatement */ data = "<module xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\" xmlns:md=\"urn:ietf:params:xml:ns:yang:ietf-yang-metadata\" name=\"aa\">\n" @@ -158,7 +158,7 @@ test_yin(void **state) "</md:annotation></module>"; assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, data, LYS_IN_YIN, NULL)); CHECK_LOG_CTX("Duplicate keyword \"units\".", - "/aa:{extension='md:annotation'}/aa"); + "Path \"/aa:{extension='md:annotation'}/aa\"."); /* invalid cardinality of status substatement */ data = "<module xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\" xmlns:md=\"urn:ietf:params:xml:ns:yang:ietf-yang-metadata\" name=\"aa\">\n" @@ -171,7 +171,7 @@ test_yin(void **state) "</md:annotation></module>"; assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, data, LYS_IN_YIN, NULL)); CHECK_LOG_CTX("Duplicate keyword \"status\".", - "/aa:{extension='md:annotation'}/aa"); + "Path \"/aa:{extension='md:annotation'}/aa\"."); /* invalid cardinality of status substatement */ data = "<module xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\" xmlns:md=\"urn:ietf:params:xml:ns:yang:ietf-yang-metadata\" name=\"aa\">\n" @@ -183,7 +183,7 @@ test_yin(void **state) "</md:annotation></module>"; assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, data, LYS_IN_YIN, NULL)); CHECK_LOG_CTX("Duplicate keyword \"type\".", - "/aa:{extension='md:annotation'}/aa"); + "Path \"/aa:{extension='md:annotation'}/aa\"."); /* duplication of the same annotation */ data = "<module xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\" xmlns:md=\"urn:ietf:params:xml:ns:yang:ietf-yang-metadata\" name=\"aa\">\n" @@ -196,7 +196,7 @@ test_yin(void **state) "</md:annotation></module>"; assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, data, LYS_IN_YIN, NULL)); CHECK_LOG_CTX("Ext plugin \"ly2 metadata v1\": Extension md:annotation is instantiated multiple times.", - "/aa:{extension='md:annotation'}/aa"); + "Path \"/aa:{extension='md:annotation'}/aa\"."); } int diff --git a/tests/utests/extensions/test_nacm.c b/tests/utests/extensions/test_nacm.c index 1c999fb..5f7028e 100644 --- a/tests/utests/extensions/test_nacm.c +++ b/tests/utests/extensions/test_nacm.c @@ -58,7 +58,7 @@ test_deny_all(void **state) assert_int_equal(LY_SUCCESS, lys_parse_mem(UTEST_LYCTX, data, LYS_IN_YANG, NULL)); CHECK_LOG_CTX("Ext plugin \"ly2 NACM v1\": " "Extension nacm:default-deny-all is allowed only in a data nodes, but it is placed in \"module\" statement.", - "/b:{extension='nacm:default-deny-all'}"); + "Path \"/b:{extension='nacm:default-deny-all'}\"."); /* invalid */ data = "module aa {yang-version 1.1; namespace urn:tests:extensions:nacm:aa; prefix en;" @@ -67,7 +67,7 @@ test_deny_all(void **state) assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, data, LYS_IN_YANG, NULL)); CHECK_LOG_CTX("Ext plugin \"ly2 NACM v1\": " "Extension nacm:default-deny-write is mixed with nacm:default-deny-all.", - "/aa:l/{extension='nacm:default-deny-all'}"); + "Path \"/aa:l/{extension='nacm:default-deny-all'}\"."); } static void @@ -100,7 +100,7 @@ test_deny_write(void **state) assert_int_equal(LY_SUCCESS, lys_parse_mem(UTEST_LYCTX, data, LYS_IN_YANG, NULL)); CHECK_LOG_CTX("Ext plugin \"ly2 NACM v1\": " "Extension nacm:default-deny-write is not allowed in notification statement.", - "/b:notif/{extension='nacm:default-deny-write'}"); + "Path \"/b:notif/{extension='nacm:default-deny-write'}\"."); /* invalid */ data = "module aa {yang-version 1.1; namespace urn:tests:extensions:nacm:aa; prefix en;" @@ -109,7 +109,7 @@ test_deny_write(void **state) assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, data, LYS_IN_YANG, NULL)); CHECK_LOG_CTX("Ext plugin \"ly2 NACM v1\": " "Extension nacm:default-deny-write is instantiated multiple times.", - "/aa:l/{extension='nacm:default-deny-write'}"); + "Path \"/aa:l/{extension='nacm:default-deny-write'}\"."); } int diff --git a/tests/utests/extensions/test_schema_mount.c b/tests/utests/extensions/test_schema_mount.c index be879ec..17a4c94 100644 --- a/tests/utests/extensions/test_schema_mount.c +++ b/tests/utests/extensions/test_schema_mount.c @@ -75,7 +75,7 @@ test_schema(void **state) assert_int_equal(LY_EINVAL, lys_parse_mem(UTEST_LYCTX, schema, LYS_IN_YANG, NULL)); CHECK_LOG_CTX("Ext plugin \"ly2 schema mount v1\": " "Extension \"yangmnt:mount-point\" instance not allowed in YANG version 1 module.", - "/sm:root/{extension='yangmnt:mount-point'}/root"); + "Path \"/sm:root/{extension='yangmnt:mount-point'}/root\"."); schema = "module sm {\n" @@ -92,7 +92,7 @@ test_schema(void **state) assert_int_equal(LY_EINVAL, lys_parse_mem(UTEST_LYCTX, schema, LYS_IN_YANG, NULL)); CHECK_LOG_CTX("Ext plugin \"ly2 schema mount v1\": " "Extension \"yangmnt:mount-point\" instance allowed only in container or list statement.", - "/sm:{extension='yangmnt:mount-point'}/root"); + "Path \"/sm:{extension='yangmnt:mount-point'}/root\"."); schema = "module sm {\n" @@ -114,7 +114,7 @@ test_schema(void **state) assert_int_equal(LY_EINVAL, lys_parse_mem(UTEST_LYCTX, schema, LYS_IN_YANG, NULL)); CHECK_LOG_CTX("Ext plugin \"ly2 schema mount v1\": " "Extension \"yangmnt:mount-point\" instance allowed only in container or list statement.", - "/sm:root/l/{extension='yangmnt:mount-point'}/root"); + "Path \"/sm:root/l/{extension='yangmnt:mount-point'}/root\"."); schema = "module sm {\n" @@ -138,7 +138,7 @@ test_schema(void **state) assert_int_equal(LY_EINVAL, lys_parse_mem(UTEST_LYCTX, schema, LYS_IN_YANG, NULL)); CHECK_LOG_CTX("Ext plugin \"ly2 schema mount v1\": " "Multiple extension \"yangmnt:mount-point\" instances.", - "/sm:l/{extension='yangmnt:mount-point'}/root"); + "Path \"/sm:l/{extension='yangmnt:mount-point'}/root\"."); /* valid */ schema = @@ -410,25 +410,25 @@ test_parse_invalid(void **state) CHECK_PARSE_LYD_PARAM(xml, LYD_XML, LYD_PARSE_STRICT, LYD_VALIDATE_PRESENT, LY_EVALID, data); CHECK_LOG_CTX("Ext plugin \"ly2 schema mount v1\": " "Mandatory node \"type\" instance does not exist.", - "Schema location \"/ietf-interfaces:interfaces/interface/type\"."); + "Data location \"/ietf-interfaces:interfaces/interface[name='bu']\"."); CHECK_PARSE_LYD_PARAM(json, LYD_JSON, LYD_PARSE_STRICT, LYD_VALIDATE_PRESENT, LY_EVALID, data); CHECK_LOG_CTX("Ext plugin \"ly2 schema mount v1\": " "Mandatory node \"type\" instance does not exist.", - "Schema location \"/ietf-interfaces:interfaces/interface/type\"."); + "Data location \"/ietf-interfaces:interfaces/interface[name='bu']\"."); /* same validation fail in separate validation */ CHECK_PARSE_LYD_PARAM(xml, LYD_XML, LYD_PARSE_STRICT | LYD_PARSE_ONLY, 0, LY_SUCCESS, data); assert_int_equal(LY_EVALID, lyd_validate_all(&data, NULL, LYD_VALIDATE_PRESENT, NULL)); CHECK_LOG_CTX("Ext plugin \"ly2 schema mount v1\": " "Mandatory node \"type\" instance does not exist.", - "Schema location \"/ietf-interfaces:interfaces/interface/type\"."); + "Data location \"/ietf-interfaces:interfaces/interface[name='bu']\"."); lyd_free_siblings(data); CHECK_PARSE_LYD_PARAM(json, LYD_JSON, LYD_PARSE_STRICT | LYD_PARSE_ONLY, 0, LY_SUCCESS, data); assert_int_equal(LY_EVALID, lyd_validate_all(&data, NULL, LYD_VALIDATE_PRESENT, NULL)); CHECK_LOG_CTX("Ext plugin \"ly2 schema mount v1\": " "Mandatory node \"type\" instance does not exist.", - "Schema location \"/ietf-interfaces:interfaces/interface/type\"."); + "Data location \"/ietf-interfaces:interfaces/interface[name='bu']\"."); lyd_free_siblings(data); /* success */ @@ -878,7 +878,7 @@ test_parse_shared(void **state) CHECK_PARSE_LYD_PARAM(xml, LYD_XML, LYD_PARSE_STRICT, LYD_VALIDATE_PRESENT, LY_EVALID, data); CHECK_LOG_CTX("Ext plugin \"ly2 schema mount v1\": " "Shared-schema yang-library content-id \"2\" differs from \"1\" used previously.", - "/ietf-yang-library:yang-library/content-id"); + "Path \"/ietf-yang-library:yang-library/content-id\"."); /* data for 2 mount points */ ly_ctx_set_ext_data_clb(UTEST_LYCTX, test_ext_data_clb, @@ -1549,6 +1549,108 @@ test_new(void **state) lyd_free_siblings(data); } +static void +test_lys_getnext(void **state) +{ + const struct lysc_node *parent, *node; + struct ly_ctx *sm_ctx; + + ly_ctx_set_ext_data_clb(UTEST_LYCTX, test_ext_data_clb, + "<yang-library xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\" " + " xmlns:ds=\"urn:ietf:params:xml:ns:yang:ietf-datastores\">" + " <module-set>" + " <name>test-set</name>" + " <module>" + " <name>ietf-datastores</name>" + " <revision>2018-02-14</revision>" + " <namespace>urn:ietf:params:xml:ns:yang:ietf-datastores</namespace>" + " </module>" + " <module>" + " <name>ietf-yang-library</name>" + " <revision>2019-01-04</revision>" + " <namespace>urn:ietf:params:xml:ns:yang:ietf-yang-library</namespace>" + " </module>" + " <module>" + " <name>ietf-yang-schema-mount</name>" + " <revision>2019-01-14</revision>" + " <namespace>urn:ietf:params:xml:ns:yang:ietf-yang-schema-mount</namespace>" + " </module>" + " <module>" + " <name>ietf-interfaces</name>" + " <revision>2014-05-08</revision>" + " <namespace>urn:ietf:params:xml:ns:yang:ietf-interfaces</namespace>" + " </module>" + " <module>" + " <name>iana-if-type</name>" + " <revision>2014-05-08</revision>" + " <namespace>urn:ietf:params:xml:ns:yang:iana-if-type</namespace>" + " </module>" + " <module>" + " <name>ietf-ip</name>" + " <revision>2014-06-16</revision>" + " <namespace>urn:ietf:params:xml:ns:yang:ietf-ip</namespace>" + " </module>" + " <import-only-module>" + " <name>ietf-yang-types</name>" + " <revision>2013-07-15</revision>" + " <namespace>urn:ietf:params:xml:ns:yang:ietf-yang-types</namespace>" + " </import-only-module>" + " </module-set>" + " <schema>" + " <name>test-schema</name>" + " <module-set>test-set</module-set>" + " </schema>" + " <datastore>" + " <name>ds:running</name>" + " <schema>test-schema</schema>" + " </datastore>" + " <datastore>" + " <name>ds:operational</name>" + " <schema>test-schema</schema>" + " </datastore>" + " <content-id>1</content-id>" + "</yang-library>" + "<modules-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\">" + " <module-set-id>1</module-set-id>" + "</modules-state>" + "<schema-mounts xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-schema-mount\">" + " <mount-point>" + " <module>sm</module>" + " <label>root</label>" + " <shared-schema/>" + " </mount-point>" + "</schema-mounts>"); + + parent = lys_find_path(UTEST_LYCTX, NULL, "/sm:root", 0); + assert_non_null(parent); + + node = lys_getnext(NULL, parent, NULL, LYS_GETNEXT_WITHSCHEMAMOUNT); + assert_non_null(node); + assert_string_equal(node->name, "schema-mounts"); + sm_ctx = node->module->ctx; + + node = lys_getnext(node, parent, NULL, LYS_GETNEXT_WITHSCHEMAMOUNT); + assert_non_null(node); + assert_string_equal(node->name, "yang-library"); + + node = lys_getnext(node, parent, NULL, LYS_GETNEXT_WITHSCHEMAMOUNT); + assert_non_null(node); + assert_string_equal(node->name, "modules-state"); + + node = lys_getnext(node, parent, NULL, LYS_GETNEXT_WITHSCHEMAMOUNT); + assert_non_null(node); + assert_string_equal(node->name, "interfaces"); + + node = lys_getnext(node, parent, NULL, LYS_GETNEXT_WITHSCHEMAMOUNT); + assert_non_null(node); + assert_string_equal(node->name, "interfaces-state"); + + node = lys_getnext(node, parent, NULL, LYS_GETNEXT_WITHSCHEMAMOUNT); + assert_null(node); + + ly_ctx_destroy(sm_ctx); +} + int main(void) { @@ -1560,6 +1662,7 @@ main(void) UTEST(test_parse_shared_parent_ref, setup), UTEST(test_parse_config, setup), UTEST(test_new, setup), + UTEST(test_lys_getnext, setup), }; return cmocka_run_group_tests(tests, NULL, NULL); diff --git a/tests/utests/extensions/test_structure.c b/tests/utests/extensions/test_structure.c index 23af450..9bad7a7 100644 --- a/tests/utests/extensions/test_structure.c +++ b/tests/utests/extensions/test_structure.c @@ -148,7 +148,7 @@ test_schema_invalid(void **state) "sx:structure struct {import yang;}}"; UTEST_INVALID_MODULE(data, LYS_IN_YANG, NULL, LY_EVALID); CHECK_LOG_CTX("Invalid keyword \"import\" as a child of \"sx:structure struct\" extension instance.", - "/a:{extension='sx:structure'}/struct"); + "Path \"/a:{extension='sx:structure'}/struct\"."); data = "module a {yang-version 1.1; namespace urn:tests:extensions:structure:a; prefix self;" "import ietf-yang-structure-ext {prefix sx;}" @@ -156,14 +156,14 @@ test_schema_invalid(void **state) UTEST_INVALID_MODULE(data, LYS_IN_YANG, NULL, LY_EVALID); CHECK_LOG_CTX("Ext plugin \"ly2 structure v1\": " "Extension sx:structure must not be used as a non top-level statement in \"container\" statement.", - "/a:b/{extension='sx:structure'}/struct"); + "Path \"/a:b/{extension='sx:structure'}/struct\"."); data = "module a {yang-version 1.1; namespace urn:tests:extensions:structure:a; prefix self;" "import ietf-yang-structure-ext {prefix sx;}" "sx:structure { container x { leaf x {type string;}}}}"; UTEST_INVALID_MODULE(data, LYS_IN_YANG, NULL, LY_EVALID); - CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL, - "Extension instance \"sx:structure\" missing argument element \"name\".", NULL); + CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL); + CHECK_LOG_CTX("Extension instance \"sx:structure\" missing argument element \"name\".", NULL); data = "module a {yang-version 1.1; namespace urn:tests:extensions:structure:a; prefix self;" "import ietf-yang-structure-ext {prefix sx;}" @@ -171,7 +171,7 @@ test_schema_invalid(void **state) "sx:structure struct { container y { leaf y {type string;}}}}"; UTEST_INVALID_MODULE(data, LYS_IN_YANG, NULL, LY_EVALID); CHECK_LOG_CTX("Ext plugin \"ly2 structure v1\": Extension sx:structure is instantiated multiple times.", - "/a:{extension='sx:structure'}/struct"); + "Path \"/a:{extension='sx:structure'}/struct\"."); data = "module a {yang-version 1.1; namespace urn:tests:extensions:structure:a; prefix self;" "import ietf-yang-structure-ext {prefix sx;}" @@ -179,7 +179,7 @@ test_schema_invalid(void **state) "choice struct { container y { leaf y {type string;}}}}"; UTEST_INVALID_MODULE(data, LYS_IN_YANG, NULL, LY_EVALID); CHECK_LOG_CTX("Ext plugin \"ly2 structure v1\": Extension sx:structure collides with a choice with the same identifier.", - "/a:{extension='sx:structure'}/struct"); + "Path \"/a:{extension='sx:structure'}/struct\"."); /* augment-structure */ data = "module a {yang-version 1.1; namespace urn:tests:extensions:structure:a; prefix a;" @@ -199,7 +199,7 @@ test_schema_invalid(void **state) "}}"; UTEST_INVALID_MODULE(data, LYS_IN_YANG, NULL, LY_ENOTFOUND); CHECK_LOG_CTX("Augment extension target node \"/a:n1\" from module \"b\" was not found.", - "/b:{extension='sx:augment-structure'}/{augment='/a:n1'}"); + "Path \"/b:{extension='sx:augment-structure'}/{augment='/a:n1'}\"."); } static void diff --git a/tests/utests/extensions/test_yangdata.c b/tests/utests/extensions/test_yangdata.c index 8c0176f..57caaf2 100644 --- a/tests/utests/extensions/test_yangdata.c +++ b/tests/utests/extensions/test_yangdata.c @@ -119,7 +119,7 @@ test_schema(void **state) assert_null(mod->compiled->exts); CHECK_LOG_CTX("Ext plugin \"ly2 yang-data v1\": " "Extension rc:yang-data is ignored since it appears as a non top-level statement in \"container\" statement.", - "/b:b/{extension='rc:yang-data'}/template"); + "Path \"/b:b/{extension='rc:yang-data'}/template\"."); assert_int_equal(LY_SUCCESS, lys_print_mem(&printed, mod, LYS_OUT_YANG_COMPILED, 0)); assert_string_equal(printed, info); free(printed); @@ -168,7 +168,7 @@ test_schema_invalid(void **state) assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, data, LYS_IN_YANG, NULL)); CHECK_LOG_CTX("Invalid keyword \"leaf\" as a child of \"rc:yang-data template\" extension instance.", - "/a:{extension='rc:yang-data'}/template"); + "Path \"/a:{extension='rc:yang-data'}/template\"."); data = "module a {yang-version 1.1; namespace urn:tests:extensions:yangdata:a; prefix self;" "import ietf-restconf {revision-date 2017-01-26; prefix rc;}" @@ -177,7 +177,7 @@ test_schema_invalid(void **state) CHECK_LOG_CTX("Ext plugin \"ly2 yang-data v1\": " "Extension rc:yang-data is instantiated with leaf top level data node (inside a choice), " "but only a single container data node is allowed.", - "/a:{extension='rc:yang-data'}/template"); + "Path \"/a:{extension='rc:yang-data'}/template\"."); data = "module a {yang-version 1.1; namespace urn:tests:extensions:yangdata:a; prefix self;" "import ietf-restconf {revision-date 2017-01-26; prefix rc;}" @@ -186,7 +186,7 @@ test_schema_invalid(void **state) CHECK_LOG_CTX("Ext plugin \"ly2 yang-data v1\": " "Extension rc:yang-data is instantiated with multiple top level data nodes (inside a single choice's case), " "but only a single container data node is allowed.", - "/a:{extension='rc:yang-data'}/template"); + "Path \"/a:{extension='rc:yang-data'}/template\"."); data = "module a {yang-version 1.1; namespace urn:tests:extensions:yangdata:a; prefix self;" "import ietf-restconf {revision-date 2017-01-26; prefix rc;}" @@ -195,7 +195,7 @@ test_schema_invalid(void **state) CHECK_LOG_CTX("Ext plugin \"ly2 yang-data v1\": " "Extension rc:yang-data is instantiated with multiple top level data nodes, " "but only a single container data node is allowed.", - "/a:{extension='rc:yang-data'}/template"); + "Path \"/a:{extension='rc:yang-data'}/template\"."); data = "module a {yang-version 1.1; namespace urn:tests:extensions:yangdata:a; prefix self;" "import ietf-restconf {revision-date 2017-01-26; prefix rc;}" @@ -204,14 +204,14 @@ test_schema_invalid(void **state) CHECK_LOG_CTX("Ext plugin \"ly2 yang-data v1\": " "Extension rc:yang-data is instantiated without any top level data node, " "but exactly one container data node is expected.", - "/a:{extension='rc:yang-data'}/template"); + "Path \"/a:{extension='rc:yang-data'}/template\"."); data = "module a {yang-version 1.1; namespace urn:tests:extensions:yangdata:a; prefix self;" "import ietf-restconf {revision-date 2017-01-26; prefix rc;}" "rc:yang-data { container x { leaf x {type string;}}}}"; assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, data, LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL, - "Extension instance \"rc:yang-data\" missing argument element \"name\".", NULL); + CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL); + CHECK_LOG_CTX("Extension instance \"rc:yang-data\" missing argument element \"name\".", NULL); data = "module a {yang-version 1.1; namespace urn:tests:extensions:yangdata:a; prefix self;" "import ietf-restconf {revision-date 2017-01-26; prefix rc;}" @@ -220,7 +220,7 @@ test_schema_invalid(void **state) assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, data, LYS_IN_YANG, NULL)); CHECK_LOG_CTX("Ext plugin \"ly2 yang-data v1\": " "Extension rc:yang-data is instantiated multiple times.", - "/a:{extension='rc:yang-data'}/template"); + "Path \"/a:{extension='rc:yang-data'}/template\"."); data = "module a {yang-version 1.1; namespace urn:tests:extensions:yangdata:a; prefix self;" "import ietf-restconf {revision-date 2017-01-26; prefix rc;}" @@ -230,7 +230,7 @@ test_schema_invalid(void **state) CHECK_LOG_CTX("Ext plugin \"ly2 yang-data v1\": " "Extension rc:yang-data is instantiated with leaf-list top level data node, " "but only a single container data node is allowed.", - "/a:{extension='rc:yang-data'}/template"); + "Path \"/a:{extension='rc:yang-data'}/template\"."); } static void diff --git a/tests/utests/node/list.c b/tests/utests/node/list.c index 8b14ece..987b416 100644 --- a/tests/utests/node/list.c +++ b/tests/utests/node/list.c @@ -169,8 +169,8 @@ test_schema_yang(void **state) "leaf group{type string;}" "}"); UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID); - CHECK_LOG_CTX("Parsing module \"TERR_0\" failed.", NULL, - "Invalid value \"-1\" of \"max-elements\".", "Line number 5."); + CHECK_LOG_CTX("Parsing module \"TERR_0\" failed.", NULL); + CHECK_LOG_CTX("Invalid value \"-1\" of \"max-elements\".", "Line number 5."); schema = MODULE_CREATE_YANG("TERR_0", "list user {" "key uid;" @@ -181,8 +181,8 @@ test_schema_yang(void **state) "leaf group{type string;}" "}"); UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID); - CHECK_LOG_CTX("Parsing module \"TERR_0\" failed.", NULL, - "Value \"4294967298\" is out of \"max-elements\" bounds.", "Line number 5."); + CHECK_LOG_CTX("Parsing module \"TERR_0\" failed.", NULL); + CHECK_LOG_CTX("Value \"4294967298\" is out of \"max-elements\" bounds.", "Line number 5."); schema = MODULE_CREATE_YANG("TERR_0", "list user {" "key uid;" @@ -193,7 +193,7 @@ test_schema_yang(void **state) "leaf group{type string;}" "}"); UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID); - CHECK_LOG_CTX("List min-elements 20 is bigger than max-elements 10.", "/TERR_0:user"); + CHECK_LOG_CTX("List min-elements 20 is bigger than max-elements 10.", "Path \"/TERR_0:user\"."); schema = MODULE_CREATE_YANG("TERR_0", "list user {" "key uid;" @@ -204,8 +204,8 @@ test_schema_yang(void **state) "leaf group{type string;}" "}"); UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID); - CHECK_LOG_CTX("Parsing module \"TERR_0\" failed.", NULL, - "Invalid value \"-1\" of \"min-elements\".", "Line number 5."); + CHECK_LOG_CTX("Parsing module \"TERR_0\" failed.", NULL); + CHECK_LOG_CTX("Invalid value \"-1\" of \"min-elements\".", "Line number 5."); schema = MODULE_CREATE_YANG("TERR_0", "list user {" "key uid;" @@ -215,8 +215,8 @@ test_schema_yang(void **state) "leaf group{type string;}" "}"); UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID); - CHECK_LOG_CTX("Parsing module \"TERR_0\" failed.", NULL, - "Duplicate keyword \"key\".", "Line number 5."); + CHECK_LOG_CTX("Parsing module \"TERR_0\" failed.", NULL); + CHECK_LOG_CTX("Duplicate keyword \"key\".", "Line number 5."); schema = MODULE_CREATE_YANG("T6", "list user {" "config false;" @@ -282,8 +282,8 @@ test_schema_yang(void **state) "leaf group{type string;}" "}"); UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID); - CHECK_LOG_CTX("Parsing module \"TERROR0\" failed.", NULL, - "Invalid value \"systeme\" of \"ordered-by\".", "Line number 5."); + CHECK_LOG_CTX("Parsing module \"TERROR0\" failed.", NULL); + CHECK_LOG_CTX("Invalid value \"systeme\" of \"ordered-by\".", "Line number 5."); schema = MODULE_CREATE_YANG("TERROR0", "list \"\" {" "key uid;" @@ -294,8 +294,8 @@ test_schema_yang(void **state) "leaf group{type string;}" "}"); UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID); - CHECK_LOG_CTX("Parsing module \"TERROR0\" failed.", NULL, - "Statement argument is required.", "Line number 5."); + CHECK_LOG_CTX("Parsing module \"TERROR0\" failed.", NULL); + CHECK_LOG_CTX("Statement argument is required.", "Line number 5."); schema = MODULE_CREATE_YANG("T9", "list user {" "key uid;" @@ -389,7 +389,7 @@ test_schema_yin(void **state) " <leaf name=\"group\"><type name=\"string\"/></leaf>" "</list>"); UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID); - CHECK_LOG_CTX("The list's key \"u<id\" not found.", "/T00:user"); + CHECK_LOG_CTX("The list's key \"u<id\" not found.", "Path \"/T00:user\"."); schema = MODULE_CREATE_YIN("T1", "<list name=\"user\"> " " <key value=\"uid\"/>" @@ -498,8 +498,8 @@ test_schema_yin(void **state) " <leaf name=\"uid\"> <type name=\"int32\"> </leaf>" "</list>"); UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID); - CHECK_LOG_CTX("Parsing module \"TERR_0\" failed.", NULL, - "Invalid value \"-1\" of \"value\" attribute in \"max-elements\" element.", "Line number 8."); + CHECK_LOG_CTX("Parsing module \"TERR_0\" failed.", NULL); + CHECK_LOG_CTX("Invalid value \"-1\" of \"value\" attribute in \"max-elements\" element.", "Line number 8."); schema = MODULE_CREATE_YIN("TERR_0", "<list name=\"user\">" @@ -511,8 +511,8 @@ test_schema_yin(void **state) " <leaf name=\"group\"> <type name=\"string\"/> </leaf>" "</list>"); UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID); - CHECK_LOG_CTX("Parsing module \"TERR_0\" failed.", NULL, - "Value \"4294967298\" of \"value\" attribute in \"max-elements\" element is out of bounds.", "Line number 8."); + CHECK_LOG_CTX("Parsing module \"TERR_0\" failed.", NULL); + CHECK_LOG_CTX("Value \"4294967298\" of \"value\" attribute in \"max-elements\" element is out of bounds.", "Line number 8."); schema = MODULE_CREATE_YIN("TERR_0", "<list name=\"user\">" @@ -524,8 +524,9 @@ test_schema_yin(void **state) " <leaf name=\"group\"> <type name=\"string\"/> </leaf>" "</list>"); UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID); - CHECK_LOG_CTX("Parsing module \"TERR_0\" failed.", NULL, - "Invalid combination of min-elements and max-elements: min value 20 is bigger than the max value 10.", "Line number 8."); + CHECK_LOG_CTX("Parsing module \"TERR_0\" failed.", NULL); + CHECK_LOG_CTX("Invalid combination of min-elements and max-elements: min value 20 is bigger than the max value 10.", + "Line number 8."); schema = MODULE_CREATE_YIN("TERR_0", "<list name=\"user\">" @@ -537,8 +538,8 @@ test_schema_yin(void **state) " <leaf name=\"group\"> <type name=\"string\"/> </leaf>" "</list>"); UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID); - CHECK_LOG_CTX("Parsing module \"TERR_0\" failed.", NULL, - "Value \"-1\" of \"value\" attribute in \"min-elements\" element is out of bounds.", "Line number 8."); + CHECK_LOG_CTX("Parsing module \"TERR_0\" failed.", NULL); + CHECK_LOG_CTX("Value \"-1\" of \"value\" attribute in \"min-elements\" element is out of bounds.", "Line number 8."); schema = MODULE_CREATE_YIN("TERR_0", "<list name=\"user\">" @@ -549,8 +550,8 @@ test_schema_yin(void **state) " <leaf name=\"group\"> <type name=\"string\"/> </leaf>" "</list>"); UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID); - CHECK_LOG_CTX("Parsing module \"TERR_0\" failed.", NULL, - "Redefinition of \"key\" sub-element in \"list\" element.", "Line number 8."); + CHECK_LOG_CTX("Parsing module \"TERR_0\" failed.", NULL); + CHECK_LOG_CTX("Redefinition of \"key\" sub-element in \"list\" element.", "Line number 8."); schema = MODULE_CREATE_YIN("T6", "<list name=\"user\">" @@ -620,8 +621,8 @@ test_schema_yin(void **state) " <leaf name=\"group\"><type name=\"string\"/> </leaf>" "</list>"); UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID); - CHECK_LOG_CTX("Parsing module \"TERROR0\" failed.", NULL, - "Invalid value \"systeme\" of \"value\" attribute in \"ordered-by\" element. Valid values are \"system\" and \"user\".", + CHECK_LOG_CTX("Parsing module \"TERROR0\" failed.", NULL); + CHECK_LOG_CTX("Invalid value \"systeme\" of \"value\" attribute in \"ordered-by\" element. Valid values are \"system\" and \"user\".", "Line number 8."); schema = MODULE_CREATE_YIN("T_DEFS1", diff --git a/tests/utests/schema/test_printer_tree.c b/tests/utests/schema/test_printer_tree.c index c076ece..40fb15f 100644 --- a/tests/utests/schema/test_printer_tree.c +++ b/tests/utests/schema/test_printer_tree.c @@ -1574,6 +1574,7 @@ print_compiled_node(void **state) " yang-version 1.1;\n" " namespace \"x:y\";\n" " prefix x;\n" + "\n" " container g {\n" " leaf a {\n" " type string;\n" @@ -1586,6 +1587,12 @@ print_compiled_node(void **state) " leaf c {\n" " type string;\n" " }\n" + " list l {\n" + " key \"ip\";\n" + " leaf ip {\n" + " type string;\n" + " }\n" + " }\n" " }\n" " }\n" "}\n"; @@ -1610,13 +1617,31 @@ print_compiled_node(void **state) ly_out_reset(UTEST_OUT); + /* pyang -f tree --tree-path /g/h/l */ + expect = + "module: a26\n" + " +--rw g\n" + " +--rw h\n" + " +--rw l* [ip]\n" + " +--rw ip string\n"; + + node = lys_find_path(UTEST_LYCTX, NULL, "/a26:g/h/l", 0); + CHECK_POINTER(node, 1); + assert_int_equal(LY_SUCCESS, lys_print_node(UTEST_OUT, node, LYS_OUT_TREE, 72, 0)); + assert_int_equal(strlen(expect), ly_out_printed(UTEST_OUT)); + assert_string_equal(printed, expect); + + ly_out_reset(UTEST_OUT); + /* pyang -f tree --tree-path /g/h */ expect = "module: a26\n" " +--rw g\n" " +--rw h\n" " +--rw b string\n" - " +--rw c? string\n"; + " +--rw c? string\n" + " +--rw l* [ip]\n" + " +--rw ip string\n"; node = lys_find_path(UTEST_LYCTX, NULL, "/a26:g/h", 0); CHECK_POINTER(node, 1); @@ -1643,6 +1668,59 @@ print_compiled_node(void **state) TEST_LOCAL_TEARDOWN; } +static void +print_compiled_node_augment(void **state) +{ + TEST_LOCAL_SETUP; + const struct lysc_node *node; + + orig = + "module b26xx {\n" + " yang-version 1.1;\n" + " namespace \"xx:y\";\n" + " prefix xx;\n" + " container c;\n" + "}\n"; + + UTEST_ADD_MODULE(orig, LYS_IN_YANG, NULL, &mod); + + /* module with import statement */ + orig = + "module b26 {\n" + " yang-version 1.1;\n" + " namespace \"x:y\";\n" + " prefix x;\n" + "\n" + " import b26xx {\n" + " prefix xx;\n" + " }\n" + "\n" + " augment \"/xx:c\" {\n" + " container e;\n" + " }\n" + "}\n"; + + UTEST_ADD_MODULE(orig, LYS_IN_YANG, NULL, &mod); + + /* pyang -f tree --tree-path /c/e ... but prefixes modified */ + expect = + "module: b26\n" + " +--rw xx:c\n" + " +--rw e\n"; + + /* using lysc tree */ + ly_ctx_set_options(UTEST_LYCTX, LY_CTX_SET_PRIV_PARSED); + node = lys_find_path(UTEST_LYCTX, NULL, "/b26xx:c/b26:e", 0); + CHECK_POINTER(node, 1); + assert_int_equal(LY_SUCCESS, lys_print_node(UTEST_OUT, node, LYS_OUT_TREE, 72, 0)); + assert_int_equal(strlen(expect), ly_out_printed(UTEST_OUT)); + assert_string_equal(printed, expect); + ly_out_reset(UTEST_OUT); + ly_ctx_unset_options(UTEST_LYCTX, LY_CTX_SET_PRIV_PARSED); + + TEST_LOCAL_TEARDOWN; +} + static LY_ERR local_imp_clb(const char *UNUSED(mod_name), const char *UNUSED(mod_rev), const char *UNUSED(submod_name), const char *UNUSED(sub_rev), void *user_data, LYS_INFORMAT *format, @@ -2365,6 +2443,43 @@ structure(void **state) TEST_LOCAL_TEARDOWN; } +static void +annotation(void **state) +{ + TEST_LOCAL_SETUP; + + orig = + "module ann {\n" + " yang-version 1.1;\n" + " namespace \"urn:example:ann\";\n" + " prefix an;\n" + "\n" + " import ietf-yang-metadata {\n" + " prefix md;\n" + " }\n" + "\n" + " leaf lf1 {\n" + " type string;\n" + " }\n" + " md:annotation avalue {\n" + " type string;\n" + " }\n" + "}\n"; + + expect = + "module: ann\n" + " +--rw lf1? string\n"; + + /* annotation is ignored without error message */ + UTEST_ADD_MODULE(orig, LYS_IN_YANG, NULL, &mod); + TEST_LOCAL_PRINT(mod, 72); + assert_int_equal(strlen(expect), ly_out_printed(UTEST_OUT)); + assert_string_equal(printed, expect); + ly_out_reset(UTEST_OUT); + + TEST_LOCAL_TEARDOWN; +} + int main(void) { @@ -2395,10 +2510,12 @@ main(void) UTEST(transition_between_rpc_and_notif), UTEST(local_augment), UTEST(print_compiled_node), + UTEST(print_compiled_node_augment), UTEST(print_parsed_submodule), UTEST(yang_data), UTEST(mount_point), UTEST(structure), + UTEST(annotation), }; return cmocka_run_group_tests(tests, NULL, NULL); diff --git a/tests/utests/schema/test_schema.c b/tests/utests/schema/test_schema.c index 175b569..17c4e4f 100644 --- a/tests/utests/schema/test_schema.c +++ b/tests/utests/schema/test_schema.c @@ -91,7 +91,8 @@ test_imp_clb(const char *UNUSED(mod_name), const char *UNUSED(mod_rev), const ch const char *test_str__; \ TEST_SCHEMA_STR(RFC7950, YIN, MOD_NAME, CONTENT, test_str__) \ assert_int_not_equal(lys_parse_mem(UTEST_LYCTX, test_str__, YIN ? LYS_IN_YIN : LYS_IN_YANG, NULL), LY_SUCCESS); \ - CHECK_LOG_CTX("Parsing module \""MOD_NAME"\" failed.", NULL, ERRMSG, ERRPATH); \ + CHECK_LOG_CTX("Parsing module \""MOD_NAME"\" failed.", NULL); \ + CHECK_LOG_CTX(ERRMSG, ERRPATH); \ } #define TEST_STMT_DUP(RFC7950, YIN, STMT, MEMBER, VALUE1, VALUE2, LINE) \ @@ -283,12 +284,12 @@ test_revisions(void **state) strcpy(rev->date, "2018-12-31"); assert_int_equal(2, LY_ARRAY_COUNT(revs)); - assert_string_equal("2018-01-01", &revs[0]); - assert_string_equal("2018-12-31", &revs[1]); + assert_string_equal("2018-01-01", revs[0].date); + assert_string_equal("2018-12-31", revs[1].date); /* the order should be fixed, so the newest revision will be the first in the array */ lysp_sort_revisions(revs); - assert_string_equal("2018-12-31", &revs[0]); - assert_string_equal("2018-01-01", &revs[1]); + assert_string_equal("2018-12-31", revs[0].date); + assert_string_equal("2018-01-01", revs[1].date); LY_ARRAY_FREE(revs); } @@ -306,80 +307,80 @@ test_collision_typedef(void **state) /* collision with a built-in type */ str = "module a {namespace urn:a; prefix a; typedef binary {type string;}}"; assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID); - CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL, - "Duplicate identifier \"binary\" of typedef statement - name collision with a built-in type.", NULL); + CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL); + CHECK_LOG_CTX("Duplicate identifier \"binary\" of typedef statement - name collision with a built-in type.", NULL); str = "module a {namespace urn:a; prefix a; typedef bits {type string;}}"; assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID); - CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL, - "Duplicate identifier \"bits\" of typedef statement - name collision with a built-in type.", NULL); + CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL); + CHECK_LOG_CTX("Duplicate identifier \"bits\" of typedef statement - name collision with a built-in type.", NULL); str = "module a {namespace urn:a; prefix a; typedef boolean {type string;}}"; assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID); - CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL, - "Duplicate identifier \"boolean\" of typedef statement - name collision with a built-in type.", NULL); + CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL); + CHECK_LOG_CTX("Duplicate identifier \"boolean\" of typedef statement - name collision with a built-in type.", NULL); str = "module a {namespace urn:a; prefix a; typedef decimal64 {type string;}}"; assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID); - CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL, - "Duplicate identifier \"decimal64\" of typedef statement - name collision with a built-in type.", NULL); + CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL); + CHECK_LOG_CTX("Duplicate identifier \"decimal64\" of typedef statement - name collision with a built-in type.", NULL); str = "module a {namespace urn:a; prefix a; typedef empty {type string;}}"; assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID); - CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL, - "Duplicate identifier \"empty\" of typedef statement - name collision with a built-in type.", NULL); + CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL); + CHECK_LOG_CTX("Duplicate identifier \"empty\" of typedef statement - name collision with a built-in type.", NULL); str = "module a {namespace urn:a; prefix a; typedef enumeration {type string;}}"; assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID); - CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL, - "Duplicate identifier \"enumeration\" of typedef statement - name collision with a built-in type.", NULL); + CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL); + CHECK_LOG_CTX("Duplicate identifier \"enumeration\" of typedef statement - name collision with a built-in type.", NULL); str = "module a {namespace urn:a; prefix a; typedef int8 {type string;}}"; assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID); - CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL, - "Duplicate identifier \"int8\" of typedef statement - name collision with a built-in type.", NULL); + CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL); + CHECK_LOG_CTX("Duplicate identifier \"int8\" of typedef statement - name collision with a built-in type.", NULL); str = "module a {namespace urn:a; prefix a; typedef int16 {type string;}}"; assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID); - CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL, - "Duplicate identifier \"int16\" of typedef statement - name collision with a built-in type.", NULL); + CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL); + CHECK_LOG_CTX("Duplicate identifier \"int16\" of typedef statement - name collision with a built-in type.", NULL); str = "module a {namespace urn:a; prefix a; typedef int32 {type string;}}"; assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID); - CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL, - "Duplicate identifier \"int32\" of typedef statement - name collision with a built-in type.", NULL); + CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL); + CHECK_LOG_CTX("Duplicate identifier \"int32\" of typedef statement - name collision with a built-in type.", NULL); str = "module a {namespace urn:a; prefix a; typedef int64 {type string;}}"; assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID); - CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL, - "Duplicate identifier \"int64\" of typedef statement - name collision with a built-in type.", NULL); + CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL); + CHECK_LOG_CTX("Duplicate identifier \"int64\" of typedef statement - name collision with a built-in type.", NULL); str = "module a {namespace urn:a; prefix a; typedef instance-identifier {type string;}}"; assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID); - CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL, - "Duplicate identifier \"instance-identifier\" of typedef statement - name collision with a built-in type.", NULL); + CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL); + CHECK_LOG_CTX("Duplicate identifier \"instance-identifier\" of typedef statement - name collision with a built-in type.", NULL); str = "module a {namespace urn:a; prefix a; typedef identityref {type string;}}"; assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID); - CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL, - "Duplicate identifier \"identityref\" of typedef statement - name collision with a built-in type.", NULL); + CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL); + CHECK_LOG_CTX("Duplicate identifier \"identityref\" of typedef statement - name collision with a built-in type.", NULL); str = "module a {namespace urn:a; prefix a; typedef leafref {type string;}}"; assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID); - CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL, - "Duplicate identifier \"leafref\" of typedef statement - name collision with a built-in type.", NULL); + CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL); + CHECK_LOG_CTX("Duplicate identifier \"leafref\" of typedef statement - name collision with a built-in type.", NULL); str = "module a {namespace urn:a; prefix a; typedef string {type int8;}}"; assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID); - CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL, - "Duplicate identifier \"string\" of typedef statement - name collision with a built-in type.", NULL); + CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL); + CHECK_LOG_CTX("Duplicate identifier \"string\" of typedef statement - name collision with a built-in type.", NULL); str = "module a {namespace urn:a; prefix a; typedef union {type string;}}"; assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID); - CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL, - "Duplicate identifier \"union\" of typedef statement - name collision with a built-in type.", NULL); + CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL); + CHECK_LOG_CTX("Duplicate identifier \"union\" of typedef statement - name collision with a built-in type.", NULL); str = "module a {namespace urn:a; prefix a; typedef uint8 {type string;}}"; assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID); - CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL, - "Duplicate identifier \"uint8\" of typedef statement - name collision with a built-in type.", NULL); + CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL); + CHECK_LOG_CTX("Duplicate identifier \"uint8\" of typedef statement - name collision with a built-in type.", NULL); str = "module a {namespace urn:a; prefix a; typedef uint16 {type string;}}"; assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID); - CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL, - "Duplicate identifier \"uint16\" of typedef statement - name collision with a built-in type.", NULL); + CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL); + CHECK_LOG_CTX("Duplicate identifier \"uint16\" of typedef statement - name collision with a built-in type.", NULL); str = "module a {namespace urn:a; prefix a; typedef uint32 {type string;}}"; assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID); - CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL, - "Duplicate identifier \"uint32\" of typedef statement - name collision with a built-in type.", NULL); + CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL); + CHECK_LOG_CTX("Duplicate identifier \"uint32\" of typedef statement - name collision with a built-in type.", NULL); str = "module a {namespace urn:a; prefix a; typedef uint64 {type string;}}"; assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID); - CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL, - "Duplicate identifier \"uint64\" of typedef statement - name collision with a built-in type.", NULL); + CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL); + CHECK_LOG_CTX("Duplicate identifier \"uint64\" of typedef statement - name collision with a built-in type.", NULL); str = "module mytypes {namespace urn:types; prefix t; typedef binary_ {type string;} typedef bits_ {type string;} typedef boolean_ {type string;} " "typedef decimal64_ {type string;} typedef empty_ {type string;} typedef enumeration_ {type string;} typedef int8_ {type string;} typedef int16_ {type string;}" @@ -391,34 +392,34 @@ test_collision_typedef(void **state) /* collision in node's scope */ str = "module a {namespace urn:a; prefix a; container c {typedef y {type int8;} typedef y {type string;}}}"; assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID); - CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL, - "Duplicate identifier \"y\" of typedef statement - name collision with sibling type.", NULL); + CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL); + CHECK_LOG_CTX("Duplicate identifier \"y\" of typedef statement - name collision with sibling type.", NULL); /* collision with parent node */ str = "module a {namespace urn:a; prefix a; container c {container d {typedef y {type int8;}} typedef y {type string;}}}"; assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID); - CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL, - "Duplicate identifier \"y\" of typedef statement - name collision with another scoped type.", NULL); + CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL); + CHECK_LOG_CTX("Duplicate identifier \"y\" of typedef statement - name collision with another scoped type.", NULL); /* collision with module's top-level */ str = "module a {namespace urn:a; prefix a; typedef x {type string;} container c {typedef x {type int8;}}}"; assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID); - CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL, - "Duplicate identifier \"x\" of typedef statement - scoped type collide with a top-level type.", NULL); + CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL); + CHECK_LOG_CTX("Duplicate identifier \"x\" of typedef statement - scoped type collide with a top-level type.", NULL); /* collision of submodule's node with module's top-level */ ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, "submodule b {belongs-to a {prefix a;} container c {typedef x {type string;}}}"); str = "module a {namespace urn:a; prefix a; include b; typedef x {type int8;}}"; assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID); - CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL, - "Duplicate identifier \"x\" of typedef statement - scoped type collide with a top-level type.", NULL); + CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL); + CHECK_LOG_CTX("Duplicate identifier \"x\" of typedef statement - scoped type collide with a top-level type.", NULL); /* collision of module's node with submodule's top-level */ ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, "submodule b {belongs-to a {prefix a;} typedef x {type int8;}}"); str = "module a {namespace urn:a; prefix a; include b; container c {typedef x {type string;}}}"; assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID); - CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL, - "Duplicate identifier \"x\" of typedef statement - scoped type collide with a top-level type.", NULL); + CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL); + CHECK_LOG_CTX("Duplicate identifier \"x\" of typedef statement - scoped type collide with a top-level type.", NULL); /* collision of submodule's node with another submodule's top-level */ str = "module a {yang-version 1.1; namespace urn:a; prefix a; include asub; include bsub;}"; @@ -426,29 +427,29 @@ test_collision_typedef(void **state) list[1].data = "submodule bsub {belongs-to a {prefix a;} container c {typedef g {type int;}}}"; ly_ctx_set_module_imp_clb(UTEST_LYCTX, module_clb, list); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL, - "Duplicate identifier \"g\" of typedef statement - scoped type collide with a top-level type.", NULL); + CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL); + CHECK_LOG_CTX("Duplicate identifier \"g\" of typedef statement - scoped type collide with a top-level type.", NULL); /* collision of module's top-levels */ str = "module a {namespace urn:a; prefix a; typedef test {type string;} typedef test {type int8;}}"; assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID); - CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL, - "Duplicate identifier \"test\" of typedef statement - name collision with another top-level type.", NULL); + CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL); + CHECK_LOG_CTX("Duplicate identifier \"test\" of typedef statement - name collision with another top-level type.", NULL); /* collision of submodule's top-levels */ submod = "submodule asub {belongs-to a {prefix a;} typedef g {type int;} typedef g {type int;}}"; str = "module a {yang-version 1.1; namespace urn:a; prefix a; include asub;}"; ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, submod); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL, - "Duplicate identifier \"g\" of typedef statement - name collision with another top-level type.", NULL); + CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL); + CHECK_LOG_CTX("Duplicate identifier \"g\" of typedef statement - name collision with another top-level type.", NULL); /* collision of module's top-level with submodule's top-levels */ ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, "submodule b {belongs-to a {prefix a;} typedef x {type string;}}"); str = "module a {namespace urn:a; prefix a; include b; typedef x {type int8;}}"; assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID); - CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL, - "Duplicate identifier \"x\" of typedef statement - name collision with another top-level type.", NULL); + CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL); + CHECK_LOG_CTX("Duplicate identifier \"x\" of typedef statement - name collision with another top-level type.", NULL); /* collision of submodule's top-level with another submodule's top-levels */ str = "module a {yang-version 1.1; namespace urn:a; prefix a; include asub; include bsub;}"; @@ -456,15 +457,14 @@ test_collision_typedef(void **state) list[1].data = "submodule bsub {belongs-to a {prefix a;} typedef g {type int;}}"; ly_ctx_set_module_imp_clb(UTEST_LYCTX, module_clb, list); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL, - "Duplicate identifier \"g\" of typedef statement - name collision with another top-level type.", NULL); + CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL); + CHECK_LOG_CTX("Duplicate identifier \"g\" of typedef statement - name collision with another top-level type.", NULL); /* error in type-stmt */ str = "module a {namespace urn:a; prefix a; container c {typedef x {type t{}}"; assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID); - CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL, - "Unexpected end-of-input.", "Line number 1."); - UTEST_LOG_CLEAN; + CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL); + CHECK_LOG_CTX("Unexpected end-of-input.", "Line number 1."); /* no collision if the same names are in different scope */ str = "module a {yang-version 1.1; namespace urn:a; prefix a;" @@ -485,34 +485,34 @@ test_collision_grouping(void **state) /* collision in node's scope */ str = "module a {namespace urn:a; prefix a; container c {grouping y; grouping y;}}"; assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID); - CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL, - "Duplicate identifier \"y\" of grouping statement - name collision with sibling grouping.", NULL); + CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL); + CHECK_LOG_CTX("Duplicate identifier \"y\" of grouping statement - name collision with sibling grouping.", NULL); /* collision with parent node */ str = "module a {namespace urn:a; prefix a; container c {container d {grouping y;} grouping y;}}"; assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID); - CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL, - "Duplicate identifier \"y\" of grouping statement - name collision with another scoped grouping.", NULL); + CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL); + CHECK_LOG_CTX("Duplicate identifier \"y\" of grouping statement - name collision with another scoped grouping.", NULL); /* collision with module's top-level */ str = "module a {namespace urn:a; prefix a; grouping x; container c {grouping x;}}"; assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID); - CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL, - "Duplicate identifier \"x\" of grouping statement - scoped grouping collide with a top-level grouping.", NULL); + CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL); + CHECK_LOG_CTX("Duplicate identifier \"x\" of grouping statement - scoped grouping collide with a top-level grouping.", NULL); /* collision of submodule's node with module's top-level */ ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, "submodule b {belongs-to a {prefix a;} container c {grouping x;}}"); str = "module a {namespace urn:a; prefix a; include b; grouping x;}"; assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID); - CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL, - "Duplicate identifier \"x\" of grouping statement - scoped grouping collide with a top-level grouping.", NULL); + CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL); + CHECK_LOG_CTX("Duplicate identifier \"x\" of grouping statement - scoped grouping collide with a top-level grouping.", NULL); /* collision of module's node with submodule's top-level */ ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, "submodule b {belongs-to a {prefix a;} grouping x;}"); str = "module a {namespace urn:a; prefix a; include b; container c {grouping x;}}"; assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID); - CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL, - "Duplicate identifier \"x\" of grouping statement - scoped grouping collide with a top-level grouping.", NULL); + CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL); + CHECK_LOG_CTX("Duplicate identifier \"x\" of grouping statement - scoped grouping collide with a top-level grouping.", NULL); /* collision of submodule's node with another submodule's top-level */ str = "module a {yang-version 1.1; namespace urn:a; prefix a; include asub; include bsub;}"; @@ -520,29 +520,29 @@ test_collision_grouping(void **state) list[1].data = "submodule bsub {belongs-to a {prefix a;} container c {grouping g;}}"; ly_ctx_set_module_imp_clb(UTEST_LYCTX, module_clb, list); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL, - "Duplicate identifier \"g\" of grouping statement - scoped grouping collide with a top-level grouping.", NULL); + CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL); + CHECK_LOG_CTX("Duplicate identifier \"g\" of grouping statement - scoped grouping collide with a top-level grouping.", NULL); /* collision of module's top-levels */ str = "module a {namespace urn:a; prefix a; grouping test; grouping test;}"; assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID); - CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL, - "Duplicate identifier \"test\" of grouping statement - name collision with another top-level grouping.", NULL); + CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL); + CHECK_LOG_CTX("Duplicate identifier \"test\" of grouping statement - name collision with another top-level grouping.", NULL); /* collision of submodule's top-levels */ submod = "submodule asub {belongs-to a {prefix a;} grouping g; grouping g;}"; str = "module a {yang-version 1.1; namespace urn:a; prefix a; include asub;}"; ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, submod); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL, - "Duplicate identifier \"g\" of grouping statement - name collision with another top-level grouping.", NULL); + CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL); + CHECK_LOG_CTX("Duplicate identifier \"g\" of grouping statement - name collision with another top-level grouping.", NULL); /* collision of module's top-level with submodule's top-levels */ ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, "submodule b {belongs-to a {prefix a;} grouping x;}"); str = "module a {namespace urn:a; prefix a; include b; grouping x;}"; assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID); - CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL, - "Duplicate identifier \"x\" of grouping statement - name collision with another top-level grouping.", NULL); + CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL); + CHECK_LOG_CTX("Duplicate identifier \"x\" of grouping statement - name collision with another top-level grouping.", NULL); /* collision of submodule's top-level with another submodule's top-levels */ str = "module a {yang-version 1.1; namespace urn:a; prefix a; include asub; include bsub;}"; @@ -550,25 +550,27 @@ test_collision_grouping(void **state) list[1].data = "submodule bsub {belongs-to a {prefix a;} grouping g;}"; ly_ctx_set_module_imp_clb(UTEST_LYCTX, module_clb, list); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL, - "Duplicate identifier \"g\" of grouping statement - name collision with another top-level grouping.", NULL); + CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL); + CHECK_LOG_CTX("Duplicate identifier \"g\" of grouping statement - name collision with another top-level grouping.", NULL); /* collision in nested groupings, top-level */ str = "module a {namespace urn:a; prefix a; grouping g {grouping g;}}"; assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID); - CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL, - "Duplicate identifier \"g\" of grouping statement - scoped grouping collide with a top-level grouping.", NULL); + CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL); + CHECK_LOG_CTX("Duplicate identifier \"g\" of grouping statement - scoped grouping collide with a top-level grouping.", NULL); /* collision in nested groupings, in node */ str = "module a {namespace urn:a; prefix a; container c {grouping g {grouping g;}}}"; assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID); - CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL, - "Duplicate identifier \"g\" of grouping statement - name collision with another scoped grouping.", NULL); + CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL); + CHECK_LOG_CTX("Duplicate identifier \"g\" of grouping statement - name collision with another scoped grouping.", NULL); /* no collision if the same names are in different scope */ str = "module a {yang-version 1.1; namespace urn:a; prefix a;" "container c {grouping g;} container d {grouping g;}}"; assert_int_equal(LY_SUCCESS, lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL)); + CHECK_LOG_CTX("Locally scoped grouping \"g\" not used.", NULL); + CHECK_LOG_CTX("Locally scoped grouping \"g\" not used.", NULL); } static void @@ -584,24 +586,24 @@ test_collision_identity(void **state) /* collision of module's top-levels */ str = "module a {yang-version 1.1; namespace urn:a; prefix a; identity g; identity g;}"; assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL, - "Duplicate identifier \"g\" of identity statement - name collision with another top-level identity.", NULL); + CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL); + CHECK_LOG_CTX("Duplicate identifier \"g\" of identity statement - name collision with another top-level identity.", NULL); /* collision of submodule's top-levels */ submod = "submodule asub {belongs-to a {prefix a;} identity g; identity g;}"; str = "module a {yang-version 1.1; namespace urn:a; prefix a; include asub;}"; ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, submod); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL, - "Duplicate identifier \"g\" of identity statement - name collision with another top-level identity.", NULL); + CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL); + CHECK_LOG_CTX("Duplicate identifier \"g\" of identity statement - name collision with another top-level identity.", NULL); /* collision of module's top-level with submodule's top-levels */ submod = "submodule asub {belongs-to a {prefix a;} identity g;}"; str = "module a {yang-version 1.1; namespace urn:a; prefix a; include asub; identity g;}"; ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, submod); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL, - "Duplicate identifier \"g\" of identity statement - name collision with another top-level identity.", NULL); + CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL); + CHECK_LOG_CTX("Duplicate identifier \"g\" of identity statement - name collision with another top-level identity.", NULL); /* collision of submodule's top-level with another submodule's top-levels */ str = "module a {yang-version 1.1; namespace urn:a; prefix a; include asub; include bsub;}"; @@ -609,8 +611,8 @@ test_collision_identity(void **state) list[1].data = "submodule bsub {belongs-to a {prefix a;} identity g;}"; ly_ctx_set_module_imp_clb(UTEST_LYCTX, module_clb, list); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL, - "Duplicate identifier \"g\" of identity statement - name collision with another top-level identity.", NULL); + CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL); + CHECK_LOG_CTX("Duplicate identifier \"g\" of identity statement - name collision with another top-level identity.", NULL); } static void @@ -626,24 +628,24 @@ test_collision_feature(void **state) /* collision of module's top-levels */ str = "module a {yang-version 1.1; namespace urn:a; prefix a; feature g; feature g;}"; assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL, - "Duplicate identifier \"g\" of feature statement - name collision with another top-level feature.", NULL); + CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL); + CHECK_LOG_CTX("Duplicate identifier \"g\" of feature statement - name collision with another top-level feature.", NULL); /* collision of submodule's top-levels */ submod = "submodule asub {belongs-to a {prefix a;} feature g; feature g;}"; str = "module a {yang-version 1.1; namespace urn:a; prefix a; include asub;}"; ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, submod); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL, - "Duplicate identifier \"g\" of feature statement - name collision with another top-level feature.", NULL); + CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL); + CHECK_LOG_CTX("Duplicate identifier \"g\" of feature statement - name collision with another top-level feature.", NULL); /* collision of module's top-level with submodule's top-levels */ submod = "submodule asub {belongs-to a {prefix a;} feature g;}"; str = "module a {yang-version 1.1; namespace urn:a; prefix a; include asub; feature g;}"; ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, submod); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL, - "Duplicate identifier \"g\" of feature statement - name collision with another top-level feature.", NULL); + CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL); + CHECK_LOG_CTX("Duplicate identifier \"g\" of feature statement - name collision with another top-level feature.", NULL); /* collision of submodule's top-level with another submodule's top-levels */ str = "module a {yang-version 1.1; namespace urn:a; prefix a; include asub; include bsub;}"; @@ -651,8 +653,8 @@ test_collision_feature(void **state) list[1].data = "submodule bsub {belongs-to a {prefix a;} feature g;}"; ly_ctx_set_module_imp_clb(UTEST_LYCTX, module_clb, list); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL, - "Duplicate identifier \"g\" of feature statement - name collision with another top-level feature.", NULL); + CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL); + CHECK_LOG_CTX("Duplicate identifier \"g\" of feature statement - name collision with another top-level feature.", NULL); } static void @@ -1046,15 +1048,15 @@ test_includes(void **state) ly_ctx_set_module_imp_clb(UTEST_LYCTX, module_clb, list); mod = ly_ctx_load_module(UTEST_LYCTX, "main_b", NULL, NULL); assert_null(mod); - CHECK_LOG_CTX("Loading \"main_b\" module failed.", NULL, - "Data model \"main_b\" not found in local searchdirs.", NULL, - "Parsing module \"main_b\" failed.", NULL, - "Including \"sub_b_one\" submodule into \"main_b\" failed.", NULL, - "Data model \"sub_b_one\" not found in local searchdirs.", NULL, - "Parsing submodule \"sub_b_one\" failed.", NULL, - "YANG 1.1 requires all submodules to be included from main module. But submodule \"sub_b_one\" includes " - "submodule \"sub_b_two\" which is not included by main module \"main_b\".", NULL, - "YANG version 1.1 expects all includes in main module, includes in submodules (sub_b_one) are not necessary.", NULL); + CHECK_LOG_CTX("Loading \"main_b\" module failed.", NULL); + CHECK_LOG_CTX("Data model \"main_b\" not found in local searchdirs.", NULL); + CHECK_LOG_CTX("Parsing module \"main_b\" failed.", NULL); + CHECK_LOG_CTX("Including \"sub_b_one\" submodule into \"main_b\" failed.", NULL); + CHECK_LOG_CTX("Data model \"sub_b_one\" not found in local searchdirs.", NULL); + CHECK_LOG_CTX("Parsing submodule \"sub_b_one\" failed.", NULL); + CHECK_LOG_CTX("YANG 1.1 requires all submodules to be included from main module. But submodule \"sub_b_one\" includes " + "submodule \"sub_b_two\" which is not included by main module \"main_b\".", NULL); + CHECK_LOG_CTX("YANG version 1.1 expects all includes in main module, includes in submodules (sub_b_one) are not necessary.", NULL); } { @@ -1073,6 +1075,7 @@ test_includes(void **state) assert_false(mod->parsed->includes[1].injected); /* result is ok, but log includes the warning */ CHECK_LOG_CTX("YANG version 1.1 expects all includes in main module, includes in submodules (sub_c_two) are not necessary.", NULL); + CHECK_LOG_CTX("YANG version 1.1 expects all includes in main module, includes in submodules (sub_c_one) are not necessary.", NULL); } } @@ -1083,7 +1086,8 @@ test_key_order(void **state) const struct lysc_node *node; struct module_clb_list list1[] = { - {"a", "module a {" + { + "a", "module a {" "yang-version 1.1;" "namespace urn:test:a;" "prefix a;" @@ -1092,7 +1096,8 @@ test_key_order(void **state) " leaf k2 {type string;}" " leaf k1 {type string;}" "}" - "}"}, + "}" + }, {NULL, NULL} }; @@ -1106,7 +1111,8 @@ test_key_order(void **state) assert_string_equal("k2", node->name); struct module_clb_list list2[] = { - {"b", "module b {" + { + "b", "module b {" "yang-version 1.1;" "namespace urn:test:b;" "prefix b;" @@ -1121,7 +1127,8 @@ test_key_order(void **state) " leaf k1 {type string;}" " leaf k3 {type string;}" "}" - "}"}, + "}" + }, {NULL, NULL} }; @@ -1156,7 +1163,7 @@ test_disabled_enum(void **state) "}}" "}"; assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID); - CHECK_LOG_CTX("Enumeration type of node \"l\" without any (or all disabled) valid values.", "Schema location \"/a:l\"."); + CHECK_LOG_CTX("Node \"l\" without any (or all disabled) valid values.", "Schema location \"/a:l\"."); /* disabled default value */ str = "module a {" @@ -1263,10 +1270,10 @@ test_identity(void **state) assert_ptr_equal(mod->identities[1].derived[0], &mod->identities[0]); ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, "submodule inv_sub {belongs-to inv {prefix inv;} identity i1;}"); - TEST_SCHEMA_ERR(0, 0, "inv", "identity i1 {base i2;}", "Unable to find base (i2) of identity \"i1\".", "/inv:{identity='i1'}"); - TEST_SCHEMA_ERR(0, 0, "inv", "identity i1 {base i1;}", "Identity \"i1\" is derived from itself.", "/inv:{identity='i1'}"); + TEST_SCHEMA_ERR(0, 0, "inv", "identity i1 {base i2;}", "Unable to find base (i2) of identity \"i1\".", "Path \"/inv:{identity='i1'}\"."); + TEST_SCHEMA_ERR(0, 0, "inv", "identity i1 {base i1;}", "Identity \"i1\" is derived from itself.", "Path \"/inv:{identity='i1'}\"."); TEST_SCHEMA_ERR(0, 0, "inv", "identity i1 {base i2;}identity i2 {base i3;}identity i3 {base i1;}", - "Identity \"i1\" is indirectly derived from itself.", "/inv:{identity='i3'}"); + "Identity \"i1\" is indirectly derived from itself.", "Path \"/inv:{identity='i3'}\"."); /* base in non-implemented module */ ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, @@ -1606,8 +1613,8 @@ test_extension_argument_element(void **state) /* invalid */ mod_test_yang = "module x { namespace \"urn:x\"; prefix x; import a { prefix a; } a:e; }"; assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, mod_test_yang, LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Parsing module \"x\" failed.", NULL, - "Extension instance \"a:e\" missing argument element \"name\".", NULL); + CHECK_LOG_CTX("Parsing module \"x\" failed.", NULL); + CHECK_LOG_CTX("Extension instance \"a:e\" missing argument element \"name\".", NULL); mod_test_yin = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" "<module name=\"x\"\n" @@ -1622,8 +1629,8 @@ test_extension_argument_element(void **state) " <a:e/>\n" "</module>\n"; assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, mod_test_yin, LYS_IN_YIN, NULL)); - CHECK_LOG_CTX("Parsing module \"x\" failed.", NULL, - "Extension instance \"a:e\" missing argument element \"name\".", NULL); + CHECK_LOG_CTX("Parsing module \"x\" failed.", NULL); + CHECK_LOG_CTX("Extension instance \"a:e\" missing argument element \"name\".", NULL); mod_test_yin = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" "<module name=\"x\"\n" @@ -1638,8 +1645,8 @@ test_extension_argument_element(void **state) " <a:e name=\"xxx\"/>\n" "</module>\n"; assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, mod_test_yin, LYS_IN_YIN, NULL)); - CHECK_LOG_CTX("Parsing module \"x\" failed.", NULL, - "Extension instance \"a:e\" missing argument element \"name\".", NULL); + CHECK_LOG_CTX("Parsing module \"x\" failed.", NULL); + CHECK_LOG_CTX("Extension instance \"a:e\" missing argument element \"name\".", NULL); mod_test_yin = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" "<module name=\"x\"\n" @@ -1656,8 +1663,8 @@ test_extension_argument_element(void **state) " </a:e>\n" "</module>\n"; assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, mod_test_yin, LYS_IN_YIN, NULL)); - CHECK_LOG_CTX("Parsing module \"x\" failed.", NULL, - "Extension instance \"a:e\" element and its argument element \"name\" are expected in the same namespace, but they differ.", + CHECK_LOG_CTX("Parsing module \"x\" failed.", NULL); + CHECK_LOG_CTX("Extension instance \"a:e\" element and its argument element \"name\" are expected in the same namespace, but they differ.", NULL); mod_test_yin = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" @@ -1675,8 +1682,8 @@ test_extension_argument_element(void **state) " </a:e>\n" "</module>\n"; assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, mod_test_yin, LYS_IN_YIN, NULL)); - CHECK_LOG_CTX("Parsing module \"x\" failed.", NULL, - "Extension instance \"a:e\" expects argument element \"name\" as its first XML child, but \"value\" element found.", + CHECK_LOG_CTX("Parsing module \"x\" failed.", NULL); + CHECK_LOG_CTX("Extension instance \"a:e\" expects argument element \"name\" as its first XML child, but \"value\" element found.", NULL); } diff --git a/tests/utests/schema/test_tree_schema_compile.c b/tests/utests/schema/test_tree_schema_compile.c index d6f0538..85da486 100644 --- a/tests/utests/schema/test_tree_schema_compile.c +++ b/tests/utests/schema/test_tree_schema_compile.c @@ -1,9 +1,10 @@ -/* +/** * @file test_tree_schema_compile.c - * @author: Radek Krejci <rkrejci@cesnet.cz> + * @author Radek Krejci <rkrejci@cesnet.cz> + * @author Michal Vasko <mvasko@cesnet.cz> * @brief unit tests for functions from parser_yang.c * - * Copyright (c) 2018 CESNET, z.s.p.o. + * Copyright (c) 2018 - 2023 CESNET, z.s.p.o. * * This source code is licensed under BSD 3-Clause License (the "License"). * You may not use this file except in compliance with the License. @@ -82,6 +83,7 @@ test_module(void **state) ly_in_free(in, 0); assert_int_equal(0, mod->implemented); assert_int_equal(LY_EINVAL, lys_set_implemented(mod, feats)); + CHECK_LOG_CTX("Feature \"invalid\" not found in module \"test\".", NULL); assert_int_equal(LY_SUCCESS, lys_set_implemented(mod, NULL)); assert_non_null(mod->compiled); assert_string_equal("test", mod->name); @@ -112,7 +114,7 @@ test_module(void **state) assert_int_equal(LY_SUCCESS, ly_in_new_memory(str, &in)); assert_int_equal(LY_EEXIST, lys_parse(UTEST_LYCTX, in, LYS_IN_YANG, NULL, &mod)); ly_in_free(in, 0); - CHECK_LOG_CTX("Duplicate identifier \"a\" of data definition/RPC/action/notification statement.", "/aa:a"); + CHECK_LOG_CTX("Duplicate identifier \"a\" of data definition/RPC/action/notification statement.", "Path \"/aa:a\"."); } static void @@ -127,7 +129,7 @@ test_name_collisions(void **state) " leaf c {type empty;}" "}"; assert_int_equal(LY_EEXIST, lys_parse_mem(UTEST_LYCTX, yang_data, LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Duplicate identifier \"c\" of data definition/RPC/action/notification statement.", "/a:c"); + CHECK_LOG_CTX("Duplicate identifier \"c\" of data definition/RPC/action/notification statement.", "Path \"/a:c\"."); UTEST_LOG_CLEAN; yang_data = "module a {namespace urn:a;prefix a;" @@ -136,7 +138,7 @@ test_name_collisions(void **state) " notification c;" "}"; assert_int_equal(LY_EEXIST, lys_parse_mem(UTEST_LYCTX, yang_data, LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Duplicate identifier \"c\" of data definition/RPC/action/notification statement.", "/a:c"); + CHECK_LOG_CTX("Duplicate identifier \"c\" of data definition/RPC/action/notification statement.", "Path \"/a:c\"."); UTEST_LOG_CLEAN; yang_data = "module a {namespace urn:a;prefix a;" @@ -145,7 +147,7 @@ test_name_collisions(void **state) " rpc c;" "}"; assert_int_equal(LY_EEXIST, lys_parse_mem(UTEST_LYCTX, yang_data, LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Duplicate identifier \"c\" of data definition/RPC/action/notification statement.", "/a:c"); + CHECK_LOG_CTX("Duplicate identifier \"c\" of data definition/RPC/action/notification statement.", "Path \"/a:c\"."); UTEST_LOG_CLEAN; yang_data = "module a {namespace urn:a;prefix a;" @@ -159,7 +161,7 @@ test_name_collisions(void **state) " }" "}"; assert_int_equal(LY_EEXIST, lys_parse_mem(UTEST_LYCTX, yang_data, LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Duplicate identifier \"c\" of data definition/RPC/action/notification statement.", "/a:ch/c/c"); + CHECK_LOG_CTX("Duplicate identifier \"c\" of data definition/RPC/action/notification statement.", "Path \"/a:ch/c/c\"."); UTEST_LOG_CLEAN; /* nested */ @@ -168,7 +170,7 @@ test_name_collisions(void **state) "container a;" "}}}"; assert_int_equal(LY_EEXIST, lys_parse_mem(UTEST_LYCTX, yang_data, LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Duplicate identifier \"a\" of data definition/RPC/action/notification statement.", "/a:c/l/a"); + CHECK_LOG_CTX("Duplicate identifier \"a\" of data definition/RPC/action/notification statement.", "Path \"/a:c/l/a\"."); UTEST_LOG_CLEAN; yang_data = "module a {yang-version 1.1;namespace urn:a;prefix a;container c { list l {key \"k\"; leaf k {type string;}" @@ -176,7 +178,7 @@ test_name_collisions(void **state) "notification a;" "}}}"; assert_int_equal(LY_EEXIST, lys_parse_mem(UTEST_LYCTX, yang_data, LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Duplicate identifier \"a\" of data definition/RPC/action/notification statement.", "/a:c/l/a"); + CHECK_LOG_CTX("Duplicate identifier \"a\" of data definition/RPC/action/notification statement.", "Path \"/a:c/l/a\"."); UTEST_LOG_CLEAN; yang_data = "module a {yang-version 1.1;namespace urn:a;prefix a;container c { list l {key \"k\"; leaf k {type string;}" @@ -184,7 +186,7 @@ test_name_collisions(void **state) "action a;" "}}}"; assert_int_equal(LY_EEXIST, lys_parse_mem(UTEST_LYCTX, yang_data, LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Duplicate identifier \"a\" of data definition/RPC/action/notification statement.", "/a:c/l/a"); + CHECK_LOG_CTX("Duplicate identifier \"a\" of data definition/RPC/action/notification statement.", "Path \"/a:c/l/a\"."); UTEST_LOG_CLEAN; /* grouping */ @@ -250,15 +252,6 @@ test_node_leaflist(void **state) assert_non_null(((struct lysc_type_leafref *)type)->realtype); assert_int_equal(LY_TYPE_INT8, ((struct lysc_type_leafref *)type)->realtype->basetype); - /* now test for string type is in file ./tests/utests/types/string.c */ -#if 0 - assert_int_equal(LY_SUCCESS, lys_parse_mem(UTEST_LYCTX, "module b {namespace urn:b;prefix b;leaf-list ll {type string;}}", LYS_IN_YANG, &mod)); - assert_non_null(mod->compiled); - assert_non_null((ll = (struct lysc_node_leaflist *)mod->compiled->data)); - assert_int_equal(0, ll->min); - assert_int_equal((uint32_t)-1, ll->max); -#endif - assert_int_equal(LY_SUCCESS, lys_parse_mem(UTEST_LYCTX, "module c {yang-version 1.1;namespace urn:c;prefix c;typedef mytype {type int8;default 10;}" "leaf-list ll1 {type mytype;default 1; default 1; config false;}" "leaf-list ll2 {type mytype; ordered-by user;}}", LYS_IN_YANG, &mod)); @@ -304,7 +297,7 @@ test_node_leaflist(void **state) /* invalid */ assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module aa {namespace urn:aa;prefix aa;leaf-list ll {type empty;}}", LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Leaf-list of type \"empty\" is allowed only in YANG 1.1 modules.", "/aa:ll"); + CHECK_LOG_CTX("Leaf-list of type \"empty\" is allowed only in YANG 1.1 modules.", "Path \"/aa:ll\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module bb {yang-version 1.1;namespace urn:bb;prefix bb;leaf-list ll {type empty; default x;}}", LYS_IN_YANG, NULL)); CHECK_LOG_CTX("Invalid default - value does not fit the type (Invalid empty value length 1.).", "Schema location \"/bb:ll\"."); @@ -317,12 +310,12 @@ test_node_leaflist(void **state) assert_int_equal(3, LY_ARRAY_COUNT(ll->dflts)); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module dd {yang-version 1.1;namespace urn:dd;prefix dd;" "leaf-list ll {type string; default one;default two;default one;}}", LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Configuration leaf-list has multiple defaults of the same value \"one\".", "/dd:ll"); + CHECK_LOG_CTX("Configuration leaf-list has multiple defaults of the same value \"one\".", "Path \"/dd:ll\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module ee {yang-version 1.1; namespace urn:ee;prefix ee;" "leaf ref {type instance-identifier {require-instance true;} default \"/ee:g\";}}", LYS_IN_YANG, NULL)); CHECK_LOG_CTX("Invalid default - value does not fit the type " - "(Invalid instance-identifier \"/ee:g\" value - semantic error.).", "Schema location \"/ee:ref\"."); + "(Invalid instance-identifier \"/ee:g\" value - semantic error: Not found node \"g\" in path.).", "Schema location \"/ee:ref\"."); } static void @@ -412,11 +405,11 @@ test_node_list(void **state) /* invalid */ assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module aa {namespace urn:aa;prefix aa;list l;}", LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Missing key in list representing configuration data.", "/aa:l"); + CHECK_LOG_CTX("Missing key in list representing configuration data.", "Path \"/aa:l\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module bb {yang-version 1.1; namespace urn:bb;prefix bb;" "list l {key x; leaf x {type string; when 1;}}}", LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("List's key must not have any \"when\" statement.", "/bb:l/x"); + CHECK_LOG_CTX("List's key must not have any \"when\" statement.", "Path \"/bb:l/x\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module cc {yang-version 1.1;namespace urn:cc;prefix cc;feature f;" "list l {key x; leaf x {type string; if-feature f;}}}", LYS_IN_YANG, NULL)); @@ -424,43 +417,43 @@ test_node_list(void **state) assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module dd {namespace urn:dd;prefix dd;" "list l {key x; leaf x {type string; config false;}}}", LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Key of a configuration list must not be a state leaf.", "/dd:l/x"); + CHECK_LOG_CTX("Key of a configuration list must not be a state leaf.", "Path \"/dd:l/x\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module ee {namespace urn:ee;prefix ee;" "list l {config false;key x; leaf x {type string; config true;}}}", LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Configuration node cannot be child of any state data node.", "/ee:l/x"); + CHECK_LOG_CTX("Configuration node cannot be child of any state data node.", "Path \"/ee:l/x\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module ff {namespace urn:ff;prefix ff;" "list l {key x; leaf-list x {type string;}}}", LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("The list's key \"x\" not found.", "/ff:l"); + CHECK_LOG_CTX("The list's key \"x\" not found.", "Path \"/ff:l\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module gg {namespace urn:gg;prefix gg;" "list l {key x; unique y;leaf x {type string;} leaf-list y {type string;}}}", LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Unique's descendant-schema-nodeid \"y\" refers to leaf-list node instead of a leaf.", "/gg:l"); + CHECK_LOG_CTX("Unique's descendant-schema-nodeid \"y\" refers to leaf-list node instead of a leaf.", "Path \"/gg:l\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module hh {namespace urn:hh;prefix hh;" "list l {key x; unique \"x y\";leaf x {type string;} leaf y {config false; type string;}}}", LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Unique statement \"x y\" refers to leaves with different config type.", "/hh:l"); + CHECK_LOG_CTX("Unique statement \"x y\" refers to leaves with different config type.", "Path \"/hh:l\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module ii {namespace urn:ii;prefix ii;" "list l {key x; unique a:x;leaf x {type string;}}}", LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Invalid descendant-schema-nodeid value \"a:x\" - prefix \"a\" not defined in module \"ii\".", "/ii:l"); + CHECK_LOG_CTX("Invalid descendant-schema-nodeid value \"a:x\" - prefix \"a\" not defined in module \"ii\".", "Path \"/ii:l\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module jj {namespace urn:jj;prefix jj;" "list l {key x; unique c/x;leaf x {type string;}container c {leaf y {type string;}}}}", LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Invalid descendant-schema-nodeid value \"c/x\" - target node not found.", "/jj:l"); + CHECK_LOG_CTX("Invalid descendant-schema-nodeid value \"c/x\" - target node not found.", "Path \"/jj:l\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module kk {namespace urn:kk;prefix kk;" "list l {key x; unique c^y;leaf x {type string;}container c {leaf y {type string;}}}}", LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Invalid descendant-schema-nodeid value \"c^\" - missing \"/\" as node-identifier separator.", "/kk:l"); + CHECK_LOG_CTX("Invalid descendant-schema-nodeid value \"c^\" - missing \"/\" as node-identifier separator.", "Path \"/kk:l\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module ll {namespace urn:ll;prefix ll;" "list l {key \"x y x\";leaf x {type string;}leaf y {type string;}}}", LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Duplicated key identifier \"x\".", "/ll:l"); + CHECK_LOG_CTX("Duplicated key identifier \"x\".", "Path \"/ll:l\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module mm {namespace urn:mm;prefix mm;" "list l {key x;leaf x {type empty;}}}", LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("List's key cannot be of \"empty\" type until it is in YANG 1.1 module.", "/mm:l/x"); + CHECK_LOG_CTX("List key of the \"empty\" type is allowed only in YANG 1.1 modules.", "Path \"/mm:l/x\"."); } static void @@ -499,26 +492,26 @@ test_node_choice(void **state) assert_int_equal(LY_EEXIST, lys_parse_mem(UTEST_LYCTX, "module aa {namespace urn:aa;prefix aa;" "choice ch {case a {leaf x {type string;}}leaf x {type string;}}}", LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Duplicate identifier \"x\" of data definition/RPC/action/notification statement.", "/aa:ch/x/x"); + CHECK_LOG_CTX("Duplicate identifier \"x\" of data definition/RPC/action/notification statement.", "Path \"/aa:ch/x/x\"."); assert_int_equal(LY_EEXIST, lys_parse_mem(UTEST_LYCTX, "module aa2 {namespace urn:aa2;prefix aa;" "choice ch {case a {leaf y {type string;}}case b {leaf y {type string;}}}}", LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Duplicate identifier \"y\" of data definition/RPC/action/notification statement.", "/aa2:ch/b/y"); + CHECK_LOG_CTX("Duplicate identifier \"y\" of data definition/RPC/action/notification statement.", "Path \"/aa2:ch/b/y\"."); assert_int_equal(LY_EEXIST, lys_parse_mem(UTEST_LYCTX, "module bb {namespace urn:bb;prefix bb;" "choice ch {case a {leaf x {type string;}}leaf a {type string;}}}", LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Duplicate identifier \"a\" of case statement.", "/bb:ch/a"); + CHECK_LOG_CTX("Duplicate identifier \"a\" of case statement.", "Path \"/bb:ch/a\"."); assert_int_equal(LY_EEXIST, lys_parse_mem(UTEST_LYCTX, "module bb2 {namespace urn:bb2;prefix bb;" "choice ch {case b {leaf x {type string;}}case b {leaf y {type string;}}}}", LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Duplicate identifier \"b\" of case statement.", "/bb2:ch/b"); + CHECK_LOG_CTX("Duplicate identifier \"b\" of case statement.", "Path \"/bb2:ch/b\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module ca {namespace urn:ca;prefix ca;" "choice ch {default c;case a {leaf x {type string;}}case b {leaf y {type string;}}}}", LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Default case \"c\" not found.", "/ca:ch"); + CHECK_LOG_CTX("Default case \"c\" not found.", "Path \"/ca:ch\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module cb {namespace urn:cb;prefix cb; import a {prefix a;}" "choice ch {default a:a;case a {leaf x {type string;}}case b {leaf y {type string;}}}}", LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Default case \"a:a\" not found.", "/cb:ch"); + CHECK_LOG_CTX("Default case \"a:a\" not found.", "Path \"/cb:ch\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module cc {namespace urn:cc;prefix cc;" "choice ch {default a;case a {leaf x {mandatory true;type string;}}}}", LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Mandatory node \"x\" under the default case \"a\".", "/cc:ch"); + CHECK_LOG_CTX("Mandatory node \"x\" under the default case \"a\".", "Path \"/cc:ch\"."); /* TODO check with mandatory nodes from augment placed into the case */ } @@ -544,8 +537,9 @@ test_node_anydata(void **state) /* invalid */ assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module aa {namespace urn:aa;prefix aa;anydata any;}", LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Parsing module \"aa\" failed.", NULL, - "Invalid keyword \"anydata\" as a child of \"module\" - the statement is allowed only in YANG 1.1 modules.", "Line number 1."); + CHECK_LOG_CTX("Parsing module \"aa\" failed.", NULL); + CHECK_LOG_CTX("Invalid keyword \"anydata\" as a child of \"module\" - the statement is allowed only in YANG 1.1 modules.", + "Line number 1."); } static void @@ -579,31 +573,32 @@ test_action(void **state) /* invalid */ assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module aa {namespace urn:aa;prefix aa;container top {action x;}}", LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Parsing module \"aa\" failed.", NULL, - "Invalid keyword \"action\" as a child of \"container\" - the statement is allowed only in YANG 1.1 modules.", "Line number 1."); + CHECK_LOG_CTX("Parsing module \"aa\" failed.", NULL); + CHECK_LOG_CTX("Invalid keyword \"action\" as a child of \"container\" - the statement is allowed only in YANG 1.1 modules.", + "Line number 1."); assert_int_equal(LY_EEXIST, lys_parse_mem(UTEST_LYCTX, "module bb {namespace urn:bb;prefix bb;leaf x{type string;} rpc x;}", LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Duplicate identifier \"x\" of data definition/RPC/action/notification statement.", "/bb:x"); + CHECK_LOG_CTX("Duplicate identifier \"x\" of data definition/RPC/action/notification statement.", "Path \"/bb:x\"."); assert_int_equal(LY_EEXIST, lys_parse_mem(UTEST_LYCTX, "module cc {yang-version 1.1; namespace urn:cc;prefix cc;container c {leaf y {type string;} action y;}}", LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Duplicate identifier \"y\" of data definition/RPC/action/notification statement.", "/cc:c/y"); + CHECK_LOG_CTX("Duplicate identifier \"y\" of data definition/RPC/action/notification statement.", "Path \"/cc:c/y\"."); assert_int_equal(LY_EEXIST, lys_parse_mem(UTEST_LYCTX, "module dd {yang-version 1.1; namespace urn:dd;prefix dd;container c {action z; action z;}}", LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Duplicate identifier \"z\" of data definition/RPC/action/notification statement.", "/dd:c/z"); + CHECK_LOG_CTX("Duplicate identifier \"z\" of data definition/RPC/action/notification statement.", "Path \"/dd:c/z\"."); ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, "submodule eesub {belongs-to ee {prefix ee;} notification w;}"); assert_int_equal(LY_EEXIST, lys_parse_mem(UTEST_LYCTX, "module ee {yang-version 1.1; namespace urn:ee;prefix ee;include eesub; rpc w;}", LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Duplicate identifier \"w\" of data definition/RPC/action/notification statement.", "/ee:w"); + CHECK_LOG_CTX("Duplicate identifier \"w\" of data definition/RPC/action/notification statement.", "Path \"/ee:w\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module ff {yang-version 1.1; namespace urn:ff;prefix ff; rpc test {input {container a {leaf b {type string;}}}}" "augment /test/input/a {action invalid {input {leaf x {type string;}}}}}", LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Action \"invalid\" is placed inside another RPC/action.", "/ff:{augment='/test/input/a'}/invalid"); + CHECK_LOG_CTX("Action \"invalid\" is placed inside another RPC/action.", "Path \"/ff:{augment='/test/input/a'}/invalid\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module gg {yang-version 1.1; namespace urn:gg;prefix gg; notification test {container a {leaf b {type string;}}}" "augment /test/a {action invalid {input {leaf x {type string;}}}}}", LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Action \"invalid\" is placed inside notification.", "/gg:{augment='/test/a'}/invalid"); + CHECK_LOG_CTX("Action \"invalid\" is placed inside notification.", "Path \"/gg:{augment='/test/a'}/invalid\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module hh {yang-version 1.1; namespace urn:hh;prefix hh; notification test {container a {uses grp;}}" "grouping grp {action invalid {input {leaf x {type string;}}}}}", LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Action \"invalid\" is placed inside notification.", "/hh:test/a/{uses='grp'}/invalid"); + CHECK_LOG_CTX("Action \"invalid\" is placed inside notification.", "Path \"/hh:test/a/{uses='grp'}/invalid\"."); } static void @@ -650,30 +645,31 @@ test_notification(void **state) /* invalid */ assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module aa {namespace urn:aa;prefix aa;container top {notification x;}}", LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Parsing module \"aa\" failed.", NULL, - "Invalid keyword \"notification\" as a child of \"container\" - the statement is allowed only in YANG 1.1 modules.", "Line number 1."); + CHECK_LOG_CTX("Parsing module \"aa\" failed.", NULL); + CHECK_LOG_CTX("Invalid keyword \"notification\" as a child of \"container\" - the statement is allowed only in YANG 1.1 modules.", + "Line number 1."); assert_int_equal(LY_EEXIST, lys_parse_mem(UTEST_LYCTX, "module bb {namespace urn:bb;prefix bb;leaf x{type string;} notification x;}", LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Duplicate identifier \"x\" of data definition/RPC/action/notification statement.", "/bb:x"); + CHECK_LOG_CTX("Duplicate identifier \"x\" of data definition/RPC/action/notification statement.", "Path \"/bb:x\"."); assert_int_equal(LY_EEXIST, lys_parse_mem(UTEST_LYCTX, "module cc {yang-version 1.1; namespace urn:cc;prefix cc;container c {leaf y {type string;} notification y;}}", LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Duplicate identifier \"y\" of data definition/RPC/action/notification statement.", "/cc:c/y"); + CHECK_LOG_CTX("Duplicate identifier \"y\" of data definition/RPC/action/notification statement.", "Path \"/cc:c/y\"."); assert_int_equal(LY_EEXIST, lys_parse_mem(UTEST_LYCTX, "module dd {yang-version 1.1; namespace urn:dd;prefix dd;container c {notification z; notification z;}}", LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Duplicate identifier \"z\" of data definition/RPC/action/notification statement.", "/dd:c/z"); + CHECK_LOG_CTX("Duplicate identifier \"z\" of data definition/RPC/action/notification statement.", "Path \"/dd:c/z\"."); ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, "submodule eesub {belongs-to ee {prefix ee;} rpc w;}"); assert_int_equal(LY_EEXIST, lys_parse_mem(UTEST_LYCTX, "module ee {yang-version 1.1; namespace urn:ee;prefix ee;include eesub; notification w;}", LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Duplicate identifier \"w\" of data definition/RPC/action/notification statement.", "/ee:w"); + CHECK_LOG_CTX("Duplicate identifier \"w\" of data definition/RPC/action/notification statement.", "Path \"/ee:w\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module ff {yang-version 1.1; namespace urn:ff;prefix ff; rpc test {input {container a {leaf b {type string;}}}}" "augment /test/input/a {notification invalid {leaf x {type string;}}}}", LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Notification \"invalid\" is placed inside RPC/action.", "/ff:{augment='/test/input/a'}/invalid"); + CHECK_LOG_CTX("Notification \"invalid\" is placed inside RPC/action.", "Path \"/ff:{augment='/test/input/a'}/invalid\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module gg {yang-version 1.1; namespace urn:gg;prefix gg; notification test {container a {leaf b {type string;}}}" "augment /test/a {notification invalid {leaf x {type string;}}}}", LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Notification \"invalid\" is placed inside another notification.", "/gg:{augment='/test/a'}/invalid"); + CHECK_LOG_CTX("Notification \"invalid\" is placed inside another notification.", "Path \"/gg:{augment='/test/a'}/invalid\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module hh {yang-version 1.1; namespace urn:hh;prefix hh; rpc test {input {container a {uses grp;}}}" "grouping grp {notification invalid {leaf x {type string;}}}}", LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Notification \"invalid\" is placed inside RPC/action.", "/hh:test/input/a/{uses='grp'}/invalid"); + CHECK_LOG_CTX("Notification \"invalid\" is placed inside RPC/action.", "Path \"/hh:test/input/a/{uses='grp'}/invalid\"."); } /** @@ -686,21 +682,6 @@ test_type_range(void **state) struct lys_module *mod; struct lysc_type *type; -#if 0 - /*test about int8 should be in tests/utests/types/int8.c*/ - assert_int_equal(LY_SUCCESS, lys_parse_mem(UTEST_LYCTX, "module a {namespace urn:a;prefix a;leaf l {type int8 {range min..10|max;}}}", LYS_IN_YANG, &mod)); - type = ((struct lysc_node_leaf *)mod->compiled->data)->type; - assert_non_null(type); - assert_int_equal(LY_TYPE_INT8, type->basetype); - assert_non_null(((struct lysc_type_num *)type)->range); - assert_non_null(((struct lysc_type_num *)type)->range->parts); - assert_int_equal(2, LY_ARRAY_COUNT(((struct lysc_type_num *)type)->range->parts)); - assert_int_equal(-128, ((struct lysc_type_num *)type)->range->parts[0].min_64); - assert_int_equal(10, ((struct lysc_type_num *)type)->range->parts[0].max_64); - assert_int_equal(127, ((struct lysc_type_num *)type)->range->parts[1].min_64); - assert_int_equal(127, ((struct lysc_type_num *)type)->range->parts[1].max_64); -#endif - assert_int_equal(LY_SUCCESS, lys_parse_mem(UTEST_LYCTX, "module b {namespace urn:b;prefix b;leaf l {type int16 {range min..10|max;}}}", LYS_IN_YANG, &mod)); type = ((struct lysc_node_leaf *)mod->compiled->data)->type; assert_non_null(type); @@ -937,83 +918,56 @@ test_type_length(void **state) assert_int_equal(10, ((struct lysc_type_bin *)type)->length->parts[0].min_u64); assert_int_equal(100, ((struct lysc_type_bin *)type)->length->parts[0].max_u64); - /* new string is tested in file ./tests/utests/types/string.c */ -#if 0 - assert_int_equal(LY_SUCCESS, lys_parse_mem(UTEST_LYCTX, "module l {namespace urn:l;prefix l;typedef mytype {type string {length 10..100;}}" - "typedef mytype2 {type mytype {pattern '[0-9]*';}} leaf l {type mytype2 {pattern '[0-4]*';}}}", LYS_IN_YANG, &mod)); - type = ((struct lysc_node_leaf *)mod->compiled->data)->type; - assert_non_null(type); - assert_int_equal(LY_TYPE_STRING, type->basetype); - assert_int_equal(1, type->refcount); - assert_non_null(((struct lysc_type_str *)type)->length); - assert_non_null(((struct lysc_type_str *)type)->length->parts); - assert_int_equal(1, LY_ARRAY_COUNT(((struct lysc_type_str *)type)->length->parts)); - assert_int_equal(10, ((struct lysc_type_str *)type)->length->parts[0].min_u64); - assert_int_equal(100, ((struct lysc_type_str *)type)->length->parts[0].max_u64); - - assert_int_equal(LY_SUCCESS, lys_parse_mem(UTEST_LYCTX, "module m {namespace urn:m;prefix m;typedef mytype {type string {length 10;}}" - "leaf l {type mytype {length min..max;}}}", LYS_IN_YANG, &mod)); - type = ((struct lysc_node_leaf *)mod->compiled->data)->type; - assert_non_null(type); - assert_int_equal(LY_TYPE_STRING, type->basetype); - assert_int_equal(1, type->refcount); - assert_non_null(((struct lysc_type_str *)type)->length); - assert_non_null(((struct lysc_type_str *)type)->length->parts); - assert_int_equal(1, LY_ARRAY_COUNT(((struct lysc_type_str *)type)->length->parts)); - assert_int_equal(10, ((struct lysc_type_str *)type)->length->parts[0].min_u64); - assert_int_equal(10, ((struct lysc_type_str *)type)->length->parts[0].max_u64); -#endif - /* invalid values */ assert_int_equal(LY_EDENIED, lys_parse_mem(UTEST_LYCTX, "module aa {namespace urn:aa;prefix aa;leaf l {type binary {length -10;}}}", LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Invalid length restriction - value \"-10\" does not fit the type limitations.", "/aa:l"); + CHECK_LOG_CTX("Invalid length restriction - value \"-10\" does not fit the type limitations.", "Path \"/aa:l\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module bb {namespace urn:bb;prefix bb;leaf l {type binary {length 18446744073709551616;}}}", LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Invalid length restriction - invalid value \"18446744073709551616\".", "/bb:l"); + CHECK_LOG_CTX("Invalid length restriction - invalid value \"18446744073709551616\".", "Path \"/bb:l\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module cc {namespace urn:cc;prefix cc;leaf l {type binary {length \"max .. 10\";}}}", LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Invalid length restriction - unexpected data after max keyword (.. 10).", "/cc:l"); + CHECK_LOG_CTX("Invalid length restriction - unexpected data after max keyword (.. 10).", "Path \"/cc:l\"."); assert_int_equal(LY_EEXIST, lys_parse_mem(UTEST_LYCTX, "module dd {namespace urn:dd;prefix dd;leaf l {type binary {length 50..10;}}}", LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Invalid length restriction - values are not in ascending order (10).", "/dd:l"); + CHECK_LOG_CTX("Invalid length restriction - values are not in ascending order (10).", "Path \"/dd:l\"."); assert_int_equal(LY_EEXIST, lys_parse_mem(UTEST_LYCTX, "module ee {namespace urn:ee;prefix ee;leaf l {type binary {length \"50 | 10\";}}}", LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Invalid length restriction - values are not in ascending order (10).", "/ee:l"); + CHECK_LOG_CTX("Invalid length restriction - values are not in ascending order (10).", "Path \"/ee:l\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module ff {namespace urn:ff;prefix ff;leaf l {type binary {length \"x\";}}}", LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Invalid length restriction - unexpected data (x).", "/ff:l"); + CHECK_LOG_CTX("Invalid length restriction - unexpected data (x).", "Path \"/ff:l\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module gg {namespace urn:gg;prefix gg;leaf l {type binary {length \"50 | min\";}}}", LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Invalid length restriction - unexpected data before min keyword (50 | ).", "/gg:l"); + CHECK_LOG_CTX("Invalid length restriction - unexpected data before min keyword (50 | ).", "Path \"/gg:l\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module hh {namespace urn:hh;prefix hh;leaf l {type binary {length \"| 50\";}}}", LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Invalid length restriction - unexpected beginning of the expression (| 50).", "/hh:l"); + CHECK_LOG_CTX("Invalid length restriction - unexpected beginning of the expression (| 50).", "Path \"/hh:l\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module ii {namespace urn:ii;prefix ii;leaf l {type binary {length \"10 ..\";}}}", LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Invalid length restriction - unexpected end of the expression after \"..\" (10 ..).", "/ii:l"); + CHECK_LOG_CTX("Invalid length restriction - unexpected end of the expression after \"..\" (10 ..).", "Path \"/ii:l\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module jj {namespace urn:jj;prefix jj;leaf l {type binary {length \".. 10\";}}}", LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Invalid length restriction - unexpected \"..\" without a lower bound.", "/jj:l"); + CHECK_LOG_CTX("Invalid length restriction - unexpected \"..\" without a lower bound.", "Path \"/jj:l\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module kk {namespace urn:kk;prefix kk;leaf l {type binary {length \"10 |\";}}}", LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Invalid length restriction - unexpected end of the expression (10 |).", "/kk:l"); + CHECK_LOG_CTX("Invalid length restriction - unexpected end of the expression (10 |).", "Path \"/kk:l\"."); assert_int_equal(LY_EEXIST, lys_parse_mem(UTEST_LYCTX, "module kl {namespace urn:kl;prefix kl;leaf l {type binary {length \"10..20 | 15..30\";}}}", LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Invalid length restriction - values are not in ascending order (15).", "/kl:l"); + CHECK_LOG_CTX("Invalid length restriction - values are not in ascending order (15).", "Path \"/kl:l\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module ll {namespace urn:ll;prefix ll;typedef mytype {type binary {length 10;}}" "leaf l {type mytype {length 11;}}}", LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Invalid length restriction - the derived restriction (11) is not equally or more limiting.", "/ll:l"); + CHECK_LOG_CTX("Invalid length restriction - the derived restriction (11) is not equally or more limiting.", "Path \"/ll:l\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module mm {namespace urn:mm;prefix mm;typedef mytype {type binary {length 10..100;}}" "leaf l {type mytype {length 1..11;}}}", LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Invalid length restriction - the derived restriction (1..11) is not equally or more limiting.", "/mm:l"); + CHECK_LOG_CTX("Invalid length restriction - the derived restriction (1..11) is not equally or more limiting.", "Path \"/mm:l\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module nn {namespace urn:nn;prefix nn;typedef mytype {type binary {length 10..100;}}" "leaf l {type mytype {length 20..110;}}}", LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Invalid length restriction - the derived restriction (20..110) is not equally or more limiting.", "/nn:l"); + CHECK_LOG_CTX("Invalid length restriction - the derived restriction (20..110) is not equally or more limiting.", "Path \"/nn:l\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module oo {namespace urn:oo;prefix oo;typedef mytype {type binary {length 10..100;}}" "leaf l {type mytype {length 20..30|110..120;}}}", LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Invalid length restriction - the derived restriction (20..30|110..120) is not equally or more limiting.", "/oo:l"); + CHECK_LOG_CTX("Invalid length restriction - the derived restriction (20..30|110..120) is not equally or more limiting.", "Path \"/oo:l\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module pp {namespace urn:pp;prefix pp;typedef mytype {type binary {length 10..11;}}" "leaf l {type mytype {length 15;}}}", LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Invalid length restriction - the derived restriction (15) is not equally or more limiting.", "/pp:l"); + CHECK_LOG_CTX("Invalid length restriction - the derived restriction (15) is not equally or more limiting.", "Path \"/pp:l\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module qq {namespace urn:qq;prefix qq;typedef mytype {type binary {length 10..20|30..40;}}" "leaf l {type mytype {length 15..35;}}}", LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Invalid length restriction - the derived restriction (15..35) is not equally or more limiting.", "/qq:l"); + CHECK_LOG_CTX("Invalid length restriction - the derived restriction (15..35) is not equally or more limiting.", "Path \"/qq:l\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module rr {namespace urn:rr;prefix rr;typedef mytype {type binary {length 10;}}" "leaf l {type mytype {length 10..35;}}}", LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Invalid length restriction - the derived restriction (10..35) is not equally or more limiting.", "/rr:l"); + CHECK_LOG_CTX("Invalid length restriction - the derived restriction (10..35) is not equally or more limiting.", "Path \"/rr:l\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module ss {namespace urn:ss;prefix ss;leaf l {type binary {pattern '[0-9]*';}}}", LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Invalid type restrictions for binary type.", "/ss:l"); + CHECK_LOG_CTX("Invalid type restrictions for binary type.", "Path \"/ss:l\"."); } static void @@ -1152,61 +1106,63 @@ test_type_enum(void **state) /* invalid cases */ assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module aa {namespace urn:aa;prefix aa; feature f; leaf l {type enumeration {" "enum one {if-feature f;}}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Parsing module \"aa\" failed.", NULL, - "Invalid keyword \"if-feature\" as a child of \"enum\" - the statement is allowed only in YANG 1.1 modules.", "Line number 1."); + CHECK_LOG_CTX("Parsing module \"aa\" failed.", NULL); + CHECK_LOG_CTX("Invalid keyword \"if-feature\" as a child of \"enum\" - the statement is allowed only in YANG 1.1 modules.", + "Line number 1."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module aa {namespace urn:aa;prefix aa; leaf l {type enumeration {" "enum one {value -2147483649;}}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Parsing module \"aa\" failed.", NULL, - "Invalid value \"-2147483649\" of \"value\".", "Line number 1."); + CHECK_LOG_CTX("Parsing module \"aa\" failed.", NULL); + CHECK_LOG_CTX("Invalid value \"-2147483649\" of \"value\".", "Line number 1."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module aa {namespace urn:aa;prefix aa; leaf l {type enumeration {" "enum one {value 2147483648;}}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Parsing module \"aa\" failed.", NULL, - "Invalid value \"2147483648\" of \"value\".", "Line number 1."); + CHECK_LOG_CTX("Parsing module \"aa\" failed.", NULL); + CHECK_LOG_CTX("Invalid value \"2147483648\" of \"value\".", "Line number 1."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module aa {namespace urn:aa;prefix aa; leaf l {type enumeration {" "enum one; enum one;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Parsing module \"aa\" failed.", NULL, - "Duplicate identifier \"one\" of enum statement.", "Line number 1."); + CHECK_LOG_CTX("Parsing module \"aa\" failed.", NULL); + CHECK_LOG_CTX("Duplicate identifier \"one\" of enum statement.", "Line number 1."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module aa {namespace urn:aa;prefix aa; leaf l {type enumeration {" "enum '';}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Parsing module \"aa\" failed.", NULL, - "Enum name must not be zero-length.", "Line number 1."); + CHECK_LOG_CTX("Parsing module \"aa\" failed.", NULL); + CHECK_LOG_CTX("Enum name must not be zero-length.", "Line number 1."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module aa {namespace urn:aa;prefix aa; leaf l {type enumeration {" "enum ' x';}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Parsing module \"aa\" failed.", NULL, - "Enum name must not have any leading or trailing whitespaces (\" x\").", "Line number 1."); + CHECK_LOG_CTX("Parsing module \"aa\" failed.", NULL); + CHECK_LOG_CTX("Enum name must not have any leading or trailing whitespaces (\" x\").", "Line number 1."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module aa {namespace urn:aa;prefix aa; leaf l {type enumeration {" "enum 'x ';}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Parsing module \"aa\" failed.", NULL, - "Enum name must not have any leading or trailing whitespaces (\"x \").", "Line number 1."); + CHECK_LOG_CTX("Parsing module \"aa\" failed.", NULL); + CHECK_LOG_CTX("Enum name must not have any leading or trailing whitespaces (\"x \").", "Line number 1."); assert_int_equal(LY_SUCCESS, lys_parse_mem(UTEST_LYCTX, "module aa {namespace urn:aa;prefix aa; leaf l {type enumeration {" "enum 'inva\nlid';}}}", LYS_IN_YANG, &mod)); CHECK_LOG_CTX("Control characters in enum name should be avoided (\"inva\nlid\", character number 5).", NULL); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module bb {namespace urn:bb;prefix bb; leaf l {type enumeration;}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Missing enum substatement for enumeration type.", "/bb:l"); + CHECK_LOG_CTX("Missing enum substatement for enumeration type.", "Path \"/bb:l\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module cc {yang-version 1.1;namespace urn:cc;prefix cc;typedef mytype {type enumeration {enum one;}}" "leaf l {type mytype {enum two;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Invalid enumeration - derived type adds new item \"two\".", "/cc:l"); + CHECK_LOG_CTX("Invalid enumeration - derived type adds new item \"two\".", "Path \"/cc:l\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module dd {yang-version 1.1;namespace urn:dd;prefix dd;typedef mytype {type enumeration {enum one;}}" "leaf l {type mytype {enum one {value 1;}}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Invalid enumeration - value of the item \"one\" has changed from 0 to 1 in the derived type.", "/dd:l"); + CHECK_LOG_CTX("Invalid enumeration - value of the item \"one\" has changed from 0 to 1 in the derived type.", "Path \"/dd:l\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module ee {namespace urn:ee;prefix ee;leaf l {type enumeration {enum x {value 2147483647;}enum y;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Invalid enumeration - it is not possible to auto-assign enum value for \"y\" since the highest value is already 2147483647.", "/ee:l"); + CHECK_LOG_CTX("Invalid enumeration - it is not possible to auto-assign enum value for \"y\" since the highest value is already 2147483647.", + "Path \"/ee:l\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module ff {namespace urn:ff;prefix ff;leaf l {type enumeration {enum x {value 1;}enum y {value 1;}}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Invalid enumeration - value 1 collide in items \"y\" and \"x\".", "/ff:l"); + CHECK_LOG_CTX("Invalid enumeration - value 1 collide in items \"y\" and \"x\".", "Path \"/ff:l\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module gg {namespace urn:gg;prefix gg;typedef mytype {type enumeration;}" "leaf l {type mytype {enum one;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Missing enum substatement for enumeration type mytype.", "/gg:l"); + CHECK_LOG_CTX("Missing enum substatement for enumeration type mytype.", "Path \"/gg:l\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module hh {namespace urn:hh;prefix hh; typedef mytype {type enumeration {enum one;}}" "leaf l {type mytype {enum one;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Enumeration type can be subtyped only in YANG 1.1 modules.", "/hh:l"); + CHECK_LOG_CTX("Enumeration type can be subtyped only in YANG 1.1 modules.", "Path \"/hh:l\"."); } static void @@ -1256,43 +1212,43 @@ test_type_dec64(void **state) /* invalid cases */ assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module aa {namespace urn:aa;prefix aa; leaf l {type decimal64 {fraction-digits 0;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Parsing module \"aa\" failed.", NULL, - "Invalid value \"0\" of \"fraction-digits\".", "Line number 1."); + CHECK_LOG_CTX("Parsing module \"aa\" failed.", NULL); + CHECK_LOG_CTX("Invalid value \"0\" of \"fraction-digits\".", "Line number 1."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module aa {namespace urn:aa;prefix aa; leaf l {type decimal64 {fraction-digits -1;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Parsing module \"aa\" failed.", NULL, - "Invalid value \"-1\" of \"fraction-digits\".", "Line number 1."); + CHECK_LOG_CTX("Parsing module \"aa\" failed.", NULL); + CHECK_LOG_CTX("Invalid value \"-1\" of \"fraction-digits\".", "Line number 1."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module aa {namespace urn:aa;prefix aa; leaf l {type decimal64 {fraction-digits 19;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Parsing module \"aa\" failed.", NULL, - "Value \"19\" is out of \"fraction-digits\" bounds.", "Line number 1."); + CHECK_LOG_CTX("Parsing module \"aa\" failed.", NULL); + CHECK_LOG_CTX("Value \"19\" is out of \"fraction-digits\" bounds.", "Line number 1."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module aa {namespace urn:aa;prefix aa; leaf l {type decimal64;}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Missing fraction-digits substatement for decimal64 type.", "/aa:l"); + CHECK_LOG_CTX("Missing fraction-digits substatement for decimal64 type.", "Path \"/aa:l\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module ab {namespace urn:ab;prefix ab; typedef mytype {type decimal64;}leaf l {type mytype;}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Missing fraction-digits substatement for decimal64 type mytype.", "/ab:l"); + CHECK_LOG_CTX("Missing fraction-digits substatement for decimal64 type mytype.", "Path \"/ab:l\"."); assert_int_equal(LY_EINVAL, lys_parse_mem(UTEST_LYCTX, "module bb {namespace urn:bb;prefix bb; leaf l {type decimal64 {fraction-digits 2;" "range '3.142';}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Range boundary \"3.142\" of decimal64 type exceeds defined number (2) of fraction digits.", "/bb:l"); + CHECK_LOG_CTX("Range boundary \"3.142\" of decimal64 type exceeds defined number (2) of fraction digits.", "Path \"/bb:l\"."); assert_int_equal(LY_EEXIST, lys_parse_mem(UTEST_LYCTX, "module cc {namespace urn:cc;prefix cc; leaf l {type decimal64 {fraction-digits 2;" "range '4 | 3.14';}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Invalid range restriction - values are not in ascending order (3.14).", "/cc:l"); + CHECK_LOG_CTX("Invalid range restriction - values are not in ascending order (3.14).", "Path \"/cc:l\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module dd {namespace urn:dd;prefix dd; typedef mytype {type decimal64 {fraction-digits 2;}}" "leaf l {type mytype {fraction-digits 3;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Invalid fraction-digits substatement for type not directly derived from decimal64 built-in type.", "/dd:l"); + CHECK_LOG_CTX("Invalid fraction-digits substatement for type not directly derived from decimal64 built-in type.", "Path \"/dd:l\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module de {namespace urn:de;prefix de; typedef mytype {type decimal64 {fraction-digits 2;}}" "typedef mytype2 {type mytype {fraction-digits 3;}}leaf l {type mytype2;}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Invalid fraction-digits substatement for type \"mytype2\" not directly derived from decimal64 built-in type.", "/de:l"); + CHECK_LOG_CTX("Invalid fraction-digits substatement for type \"mytype2\" not directly derived from decimal64 built-in type.", "Path \"/de:l\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module ee {namespace urn:ee;prefix ee;typedef mytype {type decimal64 {" "fraction-digits 18;range '-10 .. 0';}}leaf l {type mytype;}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Invalid range restriction - invalid value \"-10000000000000000000\".", "/ee:l"); + CHECK_LOG_CTX("Invalid range restriction - invalid value \"-10000000000000000000\".", "Path \"/ee:l\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module ee {namespace urn:ee;prefix ee;typedef mytype {type decimal64 {" "fraction-digits 18;range '0 .. 10';}}leaf l {type mytype;}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Invalid range restriction - invalid value \"10000000000000000000\".", "/ee:l"); + CHECK_LOG_CTX("Invalid range restriction - invalid value \"10000000000000000000\".", "Path \"/ee:l\"."); } static void @@ -1321,11 +1277,11 @@ test_type_instanceid(void **state) /* invalid cases */ assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module aa {namespace urn:aa;prefix aa; leaf l {type instance-identifier {require-instance yes;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Parsing module \"aa\" failed.", NULL, - "Invalid value \"yes\" of \"require-instance\".", "Line number 1."); + CHECK_LOG_CTX("Parsing module \"aa\" failed.", NULL); + CHECK_LOG_CTX("Invalid value \"yes\" of \"require-instance\".", "Line number 1."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module aa {namespace urn:aa;prefix aa; leaf l {type instance-identifier {fraction-digits 1;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Invalid type restrictions for instance-identifier type.", "/aa:l"); + CHECK_LOG_CTX("Invalid type restrictions for instance-identifier type.", "Path \"/aa:l\"."); } static ly_bool @@ -1721,29 +1677,29 @@ test_type_identityref(void **state) /* invalid cases */ assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module aa {namespace urn:aa;prefix aa; leaf l {type identityref;}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Missing base substatement for identityref type.", "/aa:l"); + CHECK_LOG_CTX("Missing base substatement for identityref type.", "Path \"/aa:l\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module bb {namespace urn:bb;prefix bb; typedef mytype {type identityref;}" "leaf l {type mytype;}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Missing base substatement for identityref type mytype.", "/bb:l"); + CHECK_LOG_CTX("Missing base substatement for identityref type mytype.", "Path \"/bb:l\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module cc {namespace urn:cc;prefix cc; identity i; typedef mytype {type identityref {base i;}}" "leaf l {type mytype {base i;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Invalid base substatement for the type not directly derived from identityref built-in type.", "/cc:l"); + CHECK_LOG_CTX("Invalid base substatement for the type not directly derived from identityref built-in type.", "Path \"/cc:l\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module dd {namespace urn:dd;prefix dd; identity i; typedef mytype {type identityref {base i;}}" "typedef mytype2 {type mytype {base i;}}leaf l {type mytype2;}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Invalid base substatement for the type \"mytype2\" not directly derived from identityref built-in type.", "/dd:l"); + CHECK_LOG_CTX("Invalid base substatement for the type \"mytype2\" not directly derived from identityref built-in type.", "Path \"/dd:l\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module ee {namespace urn:ee;prefix ee; identity i; identity j;" "leaf l {type identityref {base i;base j;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Multiple bases in identityref type are allowed only in YANG 1.1 modules.", "/ee:l"); + CHECK_LOG_CTX("Multiple bases in identityref type are allowed only in YANG 1.1 modules.", "Path \"/ee:l\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module ff {namespace urn:ff;prefix ff; identity i;leaf l {type identityref {base j;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Unable to find base (j) of identityref.", "/ff:l"); + CHECK_LOG_CTX("Unable to find base (j) of identityref.", "Path \"/ff:l\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module gg {namespace urn:gg;prefix gg;leaf l {type identityref {base x:j;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Invalid prefix used for base (x:j) of identityref.", "/gg:l"); + CHECK_LOG_CTX("Invalid prefix used for base (x:j) of identityref.", "Path \"/gg:l\"."); } static void @@ -1759,18 +1715,27 @@ test_type_leafref(void **state) path = "invalid_path"; assert_int_equal(LY_EVALID, ly_path_parse(UTEST_LYCTX, NULL, path, strlen(path), 1, LY_PATH_BEGIN_EITHER, LY_PATH_PREFIX_OPTIONAL, LY_PATH_PRED_LEAFREF, &expr)); + CHECK_LOG_CTX("Unexpected XPath token \"NameTest\" (\"invalid_path\"), expected \"..\".", NULL); + path = ".."; assert_int_equal(LY_EVALID, ly_path_parse(UTEST_LYCTX, NULL, path, strlen(path), 1, LY_PATH_BEGIN_EITHER, LY_PATH_PREFIX_OPTIONAL, LY_PATH_PRED_LEAFREF, &expr)); + CHECK_LOG_CTX("Unexpected XPath expression end.", NULL); + path = "..["; assert_int_equal(LY_EVALID, ly_path_parse(UTEST_LYCTX, NULL, path, strlen(path), 1, LY_PATH_BEGIN_EITHER, LY_PATH_PREFIX_OPTIONAL, LY_PATH_PRED_LEAFREF, &expr)); + CHECK_LOG_CTX("Unexpected XPath token \"[\" (\"[\"), expected \"Operator(Path)\".", NULL); + path = "../"; assert_int_equal(LY_EVALID, ly_path_parse(UTEST_LYCTX, NULL, path, strlen(path), 1, LY_PATH_BEGIN_EITHER, LY_PATH_PREFIX_OPTIONAL, LY_PATH_PRED_LEAFREF, &expr)); + CHECK_LOG_CTX("Unexpected XPath expression end.", NULL); + path = "/"; assert_int_equal(LY_EVALID, ly_path_parse(UTEST_LYCTX, NULL, path, strlen(path), 1, LY_PATH_BEGIN_EITHER, LY_PATH_PREFIX_OPTIONAL, LY_PATH_PRED_LEAFREF, &expr)); + CHECK_LOG_CTX("Unexpected XPath expression end.", NULL); path = "../../pref:id/xxx[predicate]/invalid!!!"; assert_int_equal(LY_EVALID, ly_path_parse(UTEST_LYCTX, NULL, path, strlen(path), 1, LY_PATH_BEGIN_EITHER, @@ -1861,6 +1826,7 @@ test_type_leafref(void **state) "leaf target {if-feature 'f1'; type boolean;}}"; assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, &mod)); CHECK_LOG_CTX("Target of leafref \"ref1\" cannot be referenced because it is disabled.", "Schema location \"/e:ref1\"."); + CHECK_LOG_CTX("Not found node \"target\" in path.", "Schema location \"/e:ref1\"."); str = "module en {yang-version 1.1;namespace urn:en;prefix en;feature f1;" "leaf ref1 {if-feature 'f1'; type leafref {path /target;}}" @@ -1881,6 +1847,7 @@ test_type_leafref(void **state) "leaf ref {must \"/cl:h > 0\"; type uint16;}}", LYS_IN_YANG, &mod)); ly_ctx_unset_options(UTEST_LYCTX, LY_CTX_REF_IMPLEMENTED); CHECK_LOG_CTX("Target of leafref \"g\" cannot be referenced because it is disabled.", "Schema location \"/cl:g\"."); + CHECK_LOG_CTX("Not found node \"f\" in path.", "Schema location \"/cl:g\"."); assert_int_equal(LY_SUCCESS, lys_parse_mem(UTEST_LYCTX, "module f {namespace urn:f;prefix f;" "list interface{key name;leaf name{type string;}list address {key ip;leaf ip {type string;}}}" @@ -1956,6 +1923,13 @@ test_type_leafref(void **state) assert_int_equal(LY_TYPE_BOOL, ((struct lysc_node_leaf *)mod->compiled->data)->dflt->realtype->basetype); assert_int_equal(1, ((struct lysc_node_leaf *)mod->compiled->data)->dflt->boolean); + /* union reference */ + assert_int_equal(LY_SUCCESS, lys_parse_mem(UTEST_LYCTX, "module m {namespace urn:m;prefix m;" + "typedef s-ref {type union {type leafref {path '/str';}}}" + "leaf str {type string {length \"1..16\" {error-message \"Custom message\";}}}" + "leaf ref1 {type s-ref;}" + "leaf ref2 {type s-ref;}}", LYS_IN_YANG, NULL)); + /* invalid paths */ assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module aa {namespace urn:aa;prefix aa;container a {leaf target2 {type uint8;}}" "leaf ref1 {type leafref {path ../a/invalid;}}}", LYS_IN_YANG, &mod)); @@ -1972,8 +1946,8 @@ test_type_leafref(void **state) CHECK_LOG_CTX("List predicate defined for container \"a\" in path.", "Schema location \"/dd:ref1\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module ee {namespace urn:ee;prefix ee;\n container a {leaf target2 {type uint8;}}\n" "leaf ref1 {type leafref {path /a!invalid;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Parsing module \"ee\" failed.", NULL, - "Invalid character 0x21 ('!'), perhaps \"a\" is supposed to be a function call.", "Line number 3."); + CHECK_LOG_CTX("Parsing module \"ee\" failed.", NULL); + CHECK_LOG_CTX("Invalid character 0x21 ('!'), perhaps \"a\" is supposed to be a function call.", "Line number 3."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module ff {namespace urn:ff;prefix ff;container a {leaf target2 {type uint8;}}" "leaf ref1 {type leafref {path /a;}}}", LYS_IN_YANG, &mod)); CHECK_LOG_CTX("Invalid leafref path \"/a\" - target node is container instead of leaf or leaf-list.", "Schema location \"/ff:ref1\"."); @@ -1983,36 +1957,36 @@ test_type_leafref(void **state) "Schema location \"/gg:ref1\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module hh {namespace urn:hh;prefix hh;" "leaf ref1 {type leafref;}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Missing path substatement for leafref type.", "/hh:ref1"); + CHECK_LOG_CTX("Missing path substatement for leafref type.", "Path \"/hh:ref1\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module ii {namespace urn:ii;prefix ii;typedef mytype {type leafref;}" "leaf ref1 {type mytype;}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Missing path substatement for leafref type mytype.", "/ii:ref1"); + CHECK_LOG_CTX("Missing path substatement for leafref type mytype.", "Path \"/ii:ref1\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module kk {namespace urn:kk;prefix kk;" "leaf ref {type leafref {path /target;}}leaf target {type string;config false;}}", LYS_IN_YANG, &mod)); CHECK_LOG_CTX("Invalid leafref path \"/target\" - target is supposed to represent configuration data (as the leafref does), but it does not.", "Schema location \"/kk:ref\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module ll {namespace urn:ll;prefix ll;" "leaf ref {type leafref {path /target; require-instance true;}}leaf target {type string;}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Leafref type can be restricted by require-instance statement only in YANG 1.1 modules.", "/ll:ref"); + CHECK_LOG_CTX("Leafref type can be restricted by require-instance statement only in YANG 1.1 modules.", "Path \"/ll:ref\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module mm {namespace urn:mm;prefix mm;typedef mytype {type leafref {path /target;require-instance false;}}" "leaf ref {type mytype;}leaf target {type string;}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Leafref type \"mytype\" can be restricted by require-instance statement only in YANG 1.1 modules.", "/mm:ref"); + CHECK_LOG_CTX("Leafref type \"mytype\" can be restricted by require-instance statement only in YANG 1.1 modules.", "Path \"/mm:ref\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module nn {namespace urn:nn;prefix nn;\n" "list interface{key name;leaf name{type string;}leaf ip {type string;}}\n" "leaf ifname{type leafref{ path \"../interface/name\";}}\n" "leaf address {type leafref{\n path \"/interface[name is current()/../ifname]/ip\";}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Parsing module \"nn\" failed.", NULL, - "Invalid character 0x69 ('i'), perhaps \"name\" is supposed to be a function call.", "Line number 5."); + CHECK_LOG_CTX("Parsing module \"nn\" failed.", NULL); + CHECK_LOG_CTX("Invalid character 0x69 ('i'), perhaps \"name\" is supposed to be a function call.", "Line number 5."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module oo {namespace urn:oo;prefix oo;\n" "list interface{key name;leaf name{type string;}leaf ip {type string;}}\n" "leaf ifname{type leafref{ path \"../interface/name\";}}\n" "leaf address {type leafref{\n path \"/interface[name=current()/../ifname/ip\";}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Parsing module \"oo\" failed.", NULL, - "Unexpected XPath expression end.", "Line number 5."); + CHECK_LOG_CTX("Parsing module \"oo\" failed.", NULL); + CHECK_LOG_CTX("Unexpected XPath expression end.", "Line number 5."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module pp {namespace urn:pp;prefix pp;" "list interface{key name;leaf name{type string;}leaf ip {type string;}}" @@ -2034,56 +2008,56 @@ test_type_leafref(void **state) "leaf ifname{type leafref{ path \"../interface/name\";}}leaf test{type string;}\n" "leaf address {type leafref{ path \"/interface[name=current() / .. / ifname][name=current()/../test]/ip\";}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Parsing module \"rr\" failed.", NULL, - "Duplicate predicate key \"name\" in path.", "Line number 4."); + CHECK_LOG_CTX("Parsing module \"rr\" failed.", NULL); + CHECK_LOG_CTX("Duplicate predicate key \"name\" in path.", "Line number 4."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module ss {namespace urn:ss;prefix ss;\n" "list interface{key name;leaf name{type string;}leaf ip {type string;}}\n" "leaf ifname{type leafref{ path \"../interface/name\";}}leaf test{type string;}\n" "leaf address {type leafref{ path \"/interface[name = ../ifname]/ip\";}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Parsing module \"ss\" failed.", NULL, - "Unexpected XPath token \"..\" (\"../ifname]/ip\"), expected \"FunctionName\".", "Line number 4."); + CHECK_LOG_CTX("Parsing module \"ss\" failed.", NULL); + CHECK_LOG_CTX("Unexpected XPath token \"..\" (\"../ifname]/ip\"), expected \"FunctionName\".", "Line number 4."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module tt {namespace urn:tt;prefix tt;\n" "list interface{key name;leaf name{type string;}leaf ip {type string;}}\n" "leaf ifname{type leafref{ path \"../interface/name\";}}leaf test{type string;}\n" "leaf address {type leafref{ path \"/interface[name = current()../ifname]/ip\";}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Parsing module \"tt\" failed.", NULL, - "Unexpected XPath token \"..\" (\"../ifname]/ip\"), expected \"]\".", "Line number 4."); + CHECK_LOG_CTX("Parsing module \"tt\" failed.", NULL); + CHECK_LOG_CTX("Unexpected XPath token \"..\" (\"../ifname]/ip\"), expected \"Operator(Path)\".", "Line number 4."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module uu {namespace urn:uu;prefix uu;\n" "list interface{key name;leaf name{type string;}leaf ip {type string;}}\n" "leaf ifname{type leafref{ path \"../interface/name\";}}leaf test{type string;}\n" "leaf address {type leafref{ path \"/interface[name = current()/..ifname]/ip\";}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Parsing module \"uu\" failed.", NULL, - "Invalid character 'i'[31] of expression '/interface[name = current()/..ifname]/ip'.", "Line number 4."); + CHECK_LOG_CTX("Parsing module \"uu\" failed.", NULL); + CHECK_LOG_CTX("Invalid character 'i'[31] of expression '/interface[name = current()/..ifname]/ip'.", "Line number 4."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module vv {namespace urn:vv;prefix vv;\n" "list interface{key name;leaf name{type string;}leaf ip {type string;}}\n" "leaf ifname{type leafref{ path \"../interface/name\";}}leaf test{type string;}\n" "leaf address {type leafref{ path \"/interface[name = current()/ifname]/ip\";}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Parsing module \"vv\" failed.", NULL, - "Unexpected XPath token \"NameTest\" (\"ifname]/ip\"), expected \"..\".", "Line number 4."); + CHECK_LOG_CTX("Parsing module \"vv\" failed.", NULL); + CHECK_LOG_CTX("Unexpected XPath token \"NameTest\" (\"ifname]/ip\"), expected \"..\".", "Line number 4."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module ww {namespace urn:ww;prefix ww;\n" "list interface{key name;leaf name{type string;}leaf ip {type string;}}\n" "leaf ifname{type leafref{ path \"../interface/name\";}}leaf test{type string;}\n" "leaf address {type leafref{ path \"/interface[name = current()/../]/ip\";}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Parsing module \"ww\" failed.", NULL, - "Unexpected XPath token \"]\" (\"]/ip\").", "Line number 4."); + CHECK_LOG_CTX("Parsing module \"ww\" failed.", NULL); + CHECK_LOG_CTX("Unexpected XPath token \"]\" (\"]/ip\"), expected \"NameTest\".", "Line number 4."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module xx {namespace urn:xx;prefix xx;\n" "list interface{key name;leaf name{type string;}leaf ip {type string;}}\n" "leaf ifname{type leafref{ path \"../interface/name\";}}leaf test{type string;}\n" "leaf address {type leafref{ path \"/interface[name = current()/../#node]/ip\";}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Parsing module \"xx\" failed.", NULL, - "Invalid character '#'[32] of expression '/interface[name = current()/../#node]/ip'.", "Line number 4."); + CHECK_LOG_CTX("Parsing module \"xx\" failed.", NULL); + CHECK_LOG_CTX("Invalid character '#'[32] of expression '/interface[name = current()/../#node]/ip'.", "Line number 4."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module yy {namespace urn:yy;prefix yy;\n" "list interface{key name;leaf name{type string;}leaf ip {type string;}}\n" @@ -2143,7 +2117,7 @@ test_type_empty(void **state) assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module bb {namespace urn:bb;prefix bb;typedef mytype {type empty; default x;}" "leaf l {type mytype;}}", LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Invalid type \"mytype\" - \"empty\" type must not have a default value (x).", "/bb:l"); + CHECK_LOG_CTX("Invalid type \"mytype\" - \"empty\" type must not have a default value (x).", "Path \"/bb:l\"."); } static void @@ -2197,25 +2171,25 @@ test_type_union(void **state) /* invalid unions */ assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module aa {namespace urn:aa;prefix aa;typedef mytype {type union;}" "leaf l {type mytype;}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Missing type substatement for union type mytype.", "/aa:l"); + CHECK_LOG_CTX("Missing type substatement for union type mytype.", "Path \"/aa:l\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module bb {namespace urn:bb;prefix bb;leaf l {type union;}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Missing type substatement for union type.", "/bb:l"); + CHECK_LOG_CTX("Missing type substatement for union type.", "Path \"/bb:l\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module cc {namespace urn:cc;prefix cc;typedef mytype {type union{type int8; type string;}}" "leaf l {type mytype {type string;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Invalid type substatement for the type not directly derived from union built-in type.", "/cc:l"); + CHECK_LOG_CTX("Invalid type substatement for the type not directly derived from union built-in type.", "Path \"/cc:l\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module dd {namespace urn:dd;prefix dd;typedef mytype {type union{type int8; type string;}}" "typedef mytype2 {type mytype {type string;}}leaf l {type mytype2;}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Invalid type substatement for the type \"mytype2\" not directly derived from union built-in type.", "/dd:l"); + CHECK_LOG_CTX("Invalid type substatement for the type \"mytype2\" not directly derived from union built-in type.", "Path \"/dd:l\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module ee {namespace urn:ee;prefix ee;typedef mytype {type union{type mytype; type string;}}" "leaf l {type mytype;}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Invalid \"mytype\" type reference - circular chain of types detected.", "/ee:l"); + CHECK_LOG_CTX("Invalid \"mytype\" type reference - circular chain of types detected.", "Path \"/ee:l\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module ef {namespace urn:ef;prefix ef;typedef mytype {type mytype2;}" "typedef mytype2 {type mytype;} leaf l {type mytype;}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Invalid \"mytype\" type reference - circular chain of types detected.", "/ef:l"); + CHECK_LOG_CTX("Invalid \"mytype\" type reference - circular chain of types detected.", "Path \"/ef:l\"."); } static void @@ -2304,20 +2278,173 @@ test_type_dflt(void **state) } static void +test_type_exts(void **state) +{ + const char *schema1, *schema2, *schema3, *schema4; + struct lys_module *mod; + const struct lysc_node *snode; + struct lysc_type *type; + struct lysc_type_union *type_u; + + schema1 = "module my-extensions {\n" + " namespace \"urn:my-extensions\";\n" + " prefix my-ext;\n" + "\n" + " extension shortdesc {\n" + " argument shortdsc;\n" + " }\n" + "}\n"; + schema2 = "module module-inet {\n" + " yang-version 1.1;\n" + " namespace \"urn:module-inet\";\n" + " prefix mod-inet;\n" + "\n" + " import ietf-inet-types {\n" + " prefix inet;\n" + " }\n" + "\n" + " import my-extensions {\n" + " prefix my-ext;\n" + " }\n" + "\n" + " typedef domain-name {\n" + " type inet:domain-name {\n" + " my-ext:shortdesc \"<host-name>\";\n" + " }\n" + " }\n" + "\n" + " typedef ipv4-address {\n" + " type inet:ipv4-address-no-zone {\n" + " my-ext:shortdesc \"<A.B.C.D>\";\n" + " }\n" + " }\n" + " typedef my-enum {\n" + " type enumeration {\n" + " enum one;\n" + " enum two;\n" + " enum three;\n" + " }\n" + " }\n" + "}\n"; + schema3 = "module module-a {\n" + " yang-version 1.1;\n" + " namespace \"urn:module-a\";\n" + " prefix mod-a;\n" + "\n" + " import module-inet {\n" + " prefix mod-inet;\n" + " }\n" + "\n" + " import my-extensions {\n" + " prefix my-ext;\n" + " }\n" + "\n" + " typedef server-address {\n" + " type union {\n" + " type mod-inet:ipv4-address {\n" + " my-ext:shortdesc \"<ipv4-address>\";\n" + " }\n" + " type mod-inet:domain-name {\n" + " my-ext:shortdesc \"<fqdn>\";\n" + " }\n" + " }\n" + " }\n" + "}\n"; + schema4 = "module main-module {\n" + " yang-version 1.1;\n" + " namespace \"urn:main-module\";\n" + " prefix main;\n" + "\n" + " import module-a {\n" + " prefix mod-a;\n" + " }\n" + "\n" + " import module-inet {\n" + " prefix mod-inet;\n" + " }\n" + "\n" + " import my-extensions {\n" + " prefix my-ext;\n" + " }\n" + "\n" + " container config {\n" + " leaf server {\n" + " type mod-a:server-address {\n" + " my-ext:shortdesc \"<server-address>\";\n" + " }\n" + " }\n" + "\n" + " leaf hostname {\n" + " type union {\n" + " type mod-inet:domain-name;\n" + " type string;\n" + " }\n" + " }\n" + " }\n" + "\n" + " leaf my-leaf {\n" + " type mod-inet:my-enum {\n" + " my-ext:shortdesc \"my enum\";\n" + " }\n" + " }\n" + "}\n"; + + assert_int_equal(LY_SUCCESS, lys_parse_mem(UTEST_LYCTX, schema1, LYS_IN_YANG, NULL)); + assert_int_equal(LY_SUCCESS, lys_parse_mem(UTEST_LYCTX, schema2, LYS_IN_YANG, NULL)); + assert_int_equal(LY_SUCCESS, lys_parse_mem(UTEST_LYCTX, schema3, LYS_IN_YANG, NULL)); + assert_int_equal(LY_SUCCESS, lys_parse_mem(UTEST_LYCTX, schema4, LYS_IN_YANG, &mod)); + + /* server */ + snode = lys_find_path(UTEST_LYCTX, NULL, "/main-module:config/server", 0); + assert_non_null(snode); + + type = ((struct lysc_node_leaf *)snode)->type; + assert_int_equal(LY_ARRAY_COUNT(type->exts), 1); + assert_string_equal(type->exts[0].argument, "<server-address>"); + type_u = (struct lysc_type_union *)type; + assert_int_equal(LY_ARRAY_COUNT(type_u->types), 2); + + type = type_u->types[0]; + assert_int_equal(LY_ARRAY_COUNT(type->exts), 2); + assert_string_equal(type->exts[0].argument, "<A.B.C.D>"); + assert_string_equal(type->exts[1].argument, "<ipv4-address>"); + + type = type_u->types[1]; + assert_int_equal(LY_ARRAY_COUNT(type->exts), 2); + assert_string_equal(type->exts[0].argument, "<host-name>"); + assert_string_equal(type->exts[1].argument, "<fqdn>"); + + /* hostname */ + snode = lys_find_path(UTEST_LYCTX, NULL, "/main-module:config/hostname", 0); + assert_non_null(snode); + type = ((struct lysc_node_leaf *)snode)->type; + assert_int_equal(LY_ARRAY_COUNT(type->exts), 0); + type_u = (struct lysc_type_union *)type; + assert_int_equal(LY_ARRAY_COUNT(type_u->types), 2); + + type = type_u->types[0]; + assert_int_equal(LY_ARRAY_COUNT(type->exts), 1); + assert_string_equal(type->exts[0].argument, "<host-name>"); + + type = type_u->types[1]; + assert_int_equal(LY_ARRAY_COUNT(type->exts), 0); +} + +static void test_status(void **state) { assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module aa {namespace urn:aa;prefix aa;" "container c {status deprecated; leaf l {status current; type string;}}}", LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Status \"current\" of \"l\" is in conflict with \"deprecated\" status of parent \"c\".", "/aa:c/l"); + CHECK_LOG_CTX("Status \"current\" of \"l\" is in conflict with \"deprecated\" status of parent \"c\".", "Path \"/aa:c/l\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module bb {namespace urn:bb;prefix bb;" "container c {status obsolete; leaf l {status current; type string;}}}", LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Status \"current\" of \"l\" is in conflict with \"obsolete\" status of parent \"c\".", "/bb:c/l"); + CHECK_LOG_CTX("Status \"current\" of \"l\" is in conflict with \"obsolete\" status of parent \"c\".", "Path \"/bb:c/l\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module cc {namespace urn:cc;prefix cc;" "container c {status obsolete; leaf l {status deprecated; type string;}}}", LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Status \"deprecated\" of \"l\" is in conflict with \"obsolete\" status of parent \"c\".", "/cc:c/l"); + CHECK_LOG_CTX("Status \"deprecated\" of \"l\" is in conflict with \"obsolete\" status of parent \"c\".", "Path \"/cc:c/l\"."); /* just a warning */ assert_int_equal(LY_SUCCESS, lys_parse_mem(UTEST_LYCTX, "module cc {namespace urn:dd;prefix d;" @@ -2344,11 +2471,12 @@ test_grouping(void **state) /* invalid - error in a non-instantiated grouping */ assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module aa {namespace urn:aa;prefix aa;" "grouping grp {leaf x {type leafref;}}}", LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Missing path substatement for leafref type.", "/aa:{grouping='grp'}/x"); - UTEST_LOG_CLEAN; + CHECK_LOG_CTX("Missing path substatement for leafref type.", "Path \"/aa:{grouping='grp'}/x\"."); + assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module aa {namespace urn:aa;prefix aa;" "container a {grouping grp {leaf x {type leafref;}}}}", LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Missing path substatement for leafref type.", "/aa:a/{grouping='grp'}/x"); + CHECK_LOG_CTX("Missing path substatement for leafref type.", "Path \"/aa:a/{grouping='grp'}/x\"."); + CHECK_LOG_CTX("Locally scoped grouping \"grp\" not used.", NULL); /* config check */ ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, "module z1 {namespace urn:z1;prefix z1;" @@ -2519,52 +2647,53 @@ test_uses(void **state) /* invalid */ assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module aa {namespace urn:aa;prefix aa;uses missinggrp;}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Grouping \"missinggrp\" referenced by a uses statement not found.", "/aa:{uses='missinggrp'}"); + CHECK_LOG_CTX("Grouping \"missinggrp\" referenced by a uses statement not found.", "Path \"/aa:{uses='missinggrp'}\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module bb {namespace urn:bb;prefix bb;uses grp;" "grouping grp {leaf a{type string;}uses grp1;}" "grouping grp1 {leaf b {type string;}uses grp2;}" "grouping grp2 {leaf c {type string;}uses grp;}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Grouping \"grp\" references itself through a uses statement.", "/bb:{uses='grp'}/{uses='grp1'}/{uses='grp2'}/{uses='grp'}"); + CHECK_LOG_CTX("Grouping \"grp\" references itself through a uses statement.", "Path \"/bb:{uses='grp'}/{uses='grp1'}/{uses='grp2'}/{uses='grp'}\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module cc {namespace urn:cc;prefix cc;uses a:missingprefix;}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Invalid prefix used for grouping \"a:missingprefix\" reference.", "/cc:{uses='a:missingprefix'}"); + CHECK_LOG_CTX("Invalid prefix used for grouping \"a:missingprefix\" reference.", "Path \"/cc:{uses='a:missingprefix'}\"."); assert_int_equal(LY_EEXIST, lys_parse_mem(UTEST_LYCTX, "module dd {namespace urn:dd;prefix dd;grouping grp{leaf a{type string;}}" "leaf a {type string;}uses grp;}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Duplicate identifier \"a\" of data definition/RPC/action/notification statement.", "/dd:{uses='grp'}/dd:a"); + CHECK_LOG_CTX("Duplicate identifier \"a\" of data definition/RPC/action/notification statement.", "Path \"/dd:{uses='grp'}/dd:a\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module ee {namespace urn:ee;prefix ee;grouping grp {leaf l {type string; status deprecated;}}" "uses grp {status obsolete;}}", LYS_IN_YANG, &mod)); CHECK_LOG_CTX("Inherited schema-only status \"obsolete\" is in conflict with \"deprecated\" status of \"l\".", - "/ee:{uses='grp'}/ee:l"); + "Path \"/ee:{uses='grp'}/ee:l\"."); assert_int_equal(LY_EEXIST, lys_parse_mem(UTEST_LYCTX, "module ff {namespace urn:ff;prefix ff;grouping grp {leaf l {type string;}}" "leaf l {type int8;}uses grp;}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Duplicate identifier \"l\" of data definition/RPC/action/notification statement.", "/ff:{uses='grp'}/ff:l"); + CHECK_LOG_CTX("Duplicate identifier \"l\" of data definition/RPC/action/notification statement.", "Path \"/ff:{uses='grp'}/ff:l\"."); assert_int_equal(LY_EEXIST, lys_parse_mem(UTEST_LYCTX, "module fg {namespace urn:fg;prefix fg;grouping grp {leaf m {type string;}}" "uses grp;leaf m {type int8;}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Duplicate identifier \"m\" of data definition/RPC/action/notification statement.", "/fg:m"); + CHECK_LOG_CTX("Duplicate identifier \"m\" of data definition/RPC/action/notification statement.", "Path \"/fg:m\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module gg {namespace urn:gg;prefix gg; grouping grp {container g;}" "leaf g {type string;}" "container top {uses grp {augment /g {leaf x {type int8;}}}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Invalid descendant-schema-nodeid value \"/g\" - name test expected instead of \"/\".", "/gg:top/{uses='grp'}/{augment='/g'}"); + CHECK_LOG_CTX("Invalid descendant-schema-nodeid value \"/g\" - name test expected instead of \"/\".", + "Path \"/gg:top/{uses='grp'}/{augment='/g'}\"."); assert_int_equal(LY_ENOTFOUND, lys_parse_mem(UTEST_LYCTX, "module hh {yang-version 1.1;namespace urn:hh;prefix hh;" "grouping grp {notification g { description \"super g\";}}" "container top {notification h; uses grp {refine h {description \"ultra h\";}}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Refine(s) target node \"h\" in grouping \"grp\" was not found.", "/hh:top/{uses='grp'}"); + CHECK_LOG_CTX("Refine(s) target node \"h\" in grouping \"grp\" was not found.", "Path \"/hh:top/{uses='grp'}\"."); assert_int_equal(LY_ENOTFOUND, lys_parse_mem(UTEST_LYCTX, "module ii {yang-version 1.1;namespace urn:ii;prefix ii;" "grouping grp {action g { description \"super g\";}}" "container top {action i; uses grp {refine i {description \"ultra i\";}}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Refine(s) target node \"i\" in grouping \"grp\" was not found.", "/ii:top/{uses='grp'}"); + CHECK_LOG_CTX("Refine(s) target node \"i\" in grouping \"grp\" was not found.", "Path \"/ii:top/{uses='grp'}\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module jj {yang-version 1.1;namespace urn:jj;prefix jj;" "grouping grp {leaf j { when \"1\"; type invalid;}}" "container top {uses grp;}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Referenced type \"invalid\" not found.", "/jj:top/{uses='grp'}/j"); + CHECK_LOG_CTX("Referenced type \"invalid\" not found.", "Path \"/jj:top/{uses='grp'}/j\"."); } static void @@ -2666,65 +2795,71 @@ test_refine(void **state) /* invalid */ assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module aa {namespace urn:aa;prefix aa;import grp {prefix g;}" "uses g:grp {refine c {default hello;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Invalid refine of container node - it is not possible to replace \"default\" property.", "/aa:{uses='g:grp'}/aa:c/{refine='c'}"); + CHECK_LOG_CTX("Invalid refine of container node - it is not possible to replace \"default\" property.", + "Path \"/aa:{uses='g:grp'}/aa:c/{refine='c'}\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module bb {namespace urn:bb;prefix bb;import grp {prefix g;}" "uses g:grp {refine c/l {default hello; default world;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Invalid refine of leaf with too many (2) default properties.", "/bb:{uses='g:grp'}/bb:c/l/{refine='c/l'}"); + CHECK_LOG_CTX("Invalid refine of leaf with too many (2) default properties.", "Path \"/bb:{uses='g:grp'}/bb:c/l/{refine='c/l'}\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module cc {namespace urn:cc;prefix cc;import grp {prefix g;}" "uses g:grp {refine c/ll {default hello; default world;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Invalid refine of default in leaf-list - the default statement is allowed only in YANG 1.1 modules.", "/cc:{uses='g:grp'}/cc:c/ll/{refine='c/ll'}"); + CHECK_LOG_CTX("Invalid refine of default in leaf-list - the default statement is allowed only in YANG 1.1 modules.", + "Path \"/cc:{uses='g:grp'}/cc:c/ll/{refine='c/ll'}\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module dd {namespace urn:dd;prefix dd;import grp {prefix g;}" "uses g:grp {refine c/ll {mandatory true;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Invalid refine of leaf-list node - it is not possible to replace \"mandatory\" property.", "/dd:{uses='g:grp'}/dd:c/ll/{refine='c/ll'}"); + CHECK_LOG_CTX("Invalid refine of leaf-list node - it is not possible to replace \"mandatory\" property.", + "Path \"/dd:{uses='g:grp'}/dd:c/ll/{refine='c/ll'}\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module ee {namespace urn:ee;prefix ee;import grp {prefix g;}" "uses g:grp {refine c/l {mandatory true;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Compilation of a deviated and/or refined node failed.", "/ee:{uses='g:grp'}/ee:c/l", - "Invalid mandatory leaf with a default value.", "/ee:{uses='g:grp'}/ee:c/l"); + CHECK_LOG_CTX("Compilation of a deviated and/or refined node failed.", "Path \"/ee:{uses='g:grp'}/ee:c/l\"."); + CHECK_LOG_CTX("Invalid mandatory leaf with a default value.", "Path \"/ee:{uses='g:grp'}/ee:c/l\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module ef {namespace urn:ef;prefix ef;import grp {prefix g;}" "uses g:grp {refine c/ch {mandatory true;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Compilation of a deviated and/or refined node failed.", "/ef:{uses='g:grp'}/ef:c/ch", - "Invalid mandatory choice with a default case.", "/ef:{uses='g:grp'}/ef:c/ch"); + CHECK_LOG_CTX("Compilation of a deviated and/or refined node failed.", "Path \"/ef:{uses='g:grp'}/ef:c/ch\"."); + CHECK_LOG_CTX("Invalid mandatory choice with a default case.", "Path \"/ef:{uses='g:grp'}/ef:c/ch\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module ff {namespace urn:ff;prefix ff;import grp {prefix g;}" "uses g:grp {refine c/ch/ca/ca {mandatory true;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Mandatory node \"ca\" under the default case \"ca\".", "/ff:{uses='g:grp'}/ff:c/ch"); + CHECK_LOG_CTX("Mandatory node \"ca\" under the default case \"ca\".", "Path \"/ff:{uses='g:grp'}/ff:c/ch\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module gg {namespace urn:gg;prefix gg;import grp {prefix g;}" "uses g:grp {refine c/x {default hello;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Compilation of a deviated and/or refined node failed.", "/gg:{uses='g:grp'}/gg:c/x", - "Invalid mandatory leaf with a default value.", "/gg:{uses='g:grp'}/gg:c/x"); + CHECK_LOG_CTX("Compilation of a deviated and/or refined node failed.", "Path \"/gg:{uses='g:grp'}/gg:c/x\"."); + CHECK_LOG_CTX("Invalid mandatory leaf with a default value.", "Path \"/gg:{uses='g:grp'}/gg:c/x\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module hh {namespace urn:hh;prefix hh;import grp {prefix g;}" "uses g:grp {refine c/c/l {config true;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Compilation of a deviated and/or refined node failed.", "/hh:{uses='g:grp'}/hh:c/c/l", - "Configuration node cannot be child of any state data node.", "/hh:{uses='g:grp'}/hh:c/c/l"); + CHECK_LOG_CTX("Compilation of a deviated and/or refined node failed.", "Path \"/hh:{uses='g:grp'}/hh:c/c/l\"."); + CHECK_LOG_CTX("Configuration node cannot be child of any state data node.", "Path \"/hh:{uses='g:grp'}/hh:c/c/l\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module ii {namespace urn:ii;prefix ii;grouping grp {leaf l {type string; status deprecated;}}" "uses grp {status obsolete;}}", LYS_IN_YANG, &mod)); CHECK_LOG_CTX("Inherited schema-only status \"obsolete\" is in conflict with \"deprecated\" status of \"l\".", - "/ii:{uses='grp'}/ii:l"); + "Path \"/ii:{uses='grp'}/ii:l\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module jj {namespace urn:jj;prefix jj;import grp {prefix g;}" "uses g:grp {refine c/x {presence nonsence;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Invalid refine of leaf node - it is not possible to replace \"presence\" property.", "/jj:{uses='g:grp'}/jj:c/x/{refine='c/x'}"); + CHECK_LOG_CTX("Invalid refine of leaf node - it is not possible to replace \"presence\" property.", + "Path \"/jj:{uses='g:grp'}/jj:c/x/{refine='c/x'}\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module kk {namespace urn:kk;prefix kk;import grp {prefix g;}" "uses g:grp {refine c/ch {must 1;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Invalid refine of choice node - it is not possible to add \"must\" property.", "/kk:{uses='g:grp'}/kk:c/ch/{refine='c/ch'}"); + CHECK_LOG_CTX("Invalid refine of choice node - it is not possible to add \"must\" property.", + "Path \"/kk:{uses='g:grp'}/kk:c/ch/{refine='c/ch'}\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module ll {namespace urn:ll;prefix ll;import grp {prefix g;}" "uses g:grp {refine c/x {min-elements 1;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Invalid refine of leaf node - it is not possible to replace \"min-elements\" property.", "/ll:{uses='g:grp'}/ll:c/x/{refine='c/x'}"); + CHECK_LOG_CTX("Invalid refine of leaf node - it is not possible to replace \"min-elements\" property.", + "Path \"/ll:{uses='g:grp'}/ll:c/x/{refine='c/x'}\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module mm {namespace urn:mm;prefix mm;import grp {prefix g;}" "uses g:grp {refine c/ll {min-elements 1;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Compilation of a deviated and/or refined node failed.", "/mm:{uses='g:grp'}/mm:c/ll", - "The default statement is present on leaf-list with a nonzero min-elements.", "/mm:{uses='g:grp'}/mm:c/ll"); + CHECK_LOG_CTX("Compilation of a deviated and/or refined node failed.", "Path \"/mm:{uses='g:grp'}/mm:c/ll\"."); + CHECK_LOG_CTX("The default statement is present on leaf-list with a nonzero min-elements.", "Path \"/mm:{uses='g:grp'}/mm:c/ll\"."); } static void @@ -2867,40 +3002,41 @@ test_augment(void **state) assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module aa {namespace urn:aa;prefix aa; container c {leaf a {type string;}}" "augment /x/ {leaf a {type int8;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Invalid absolute-schema-nodeid value \"/x/\" - unexpected end of expression.", "/aa:{augment='/x/'}"); + CHECK_LOG_CTX("Invalid absolute-schema-nodeid value \"/x/\" - unexpected end of expression.", "Path \"/aa:{augment='/x/'}\"."); assert_int_equal(LY_ENOTFOUND, lys_parse_mem(UTEST_LYCTX, "module aa {namespace urn:aa;prefix aa; container c {leaf a {type string;}}" "augment /x {leaf a {type int8;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Augment target node \"/x\" from module \"aa\" was not found.", "/aa:{augment='/x'}"); + CHECK_LOG_CTX("Augment target node \"/x\" from module \"aa\" was not found.", "Path \"/aa:{augment='/x'}\"."); assert_int_equal(LY_EEXIST, lys_parse_mem(UTEST_LYCTX, "module bb {namespace urn:bb;prefix bb; container c {leaf a {type string;}}" "augment /c {leaf a {type int8;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Duplicate identifier \"a\" of data definition/RPC/action/notification statement.", "/bb:{augment='/c'}/a"); + CHECK_LOG_CTX("Duplicate identifier \"a\" of data definition/RPC/action/notification statement.", "Path \"/bb:{augment='/c'}/a\"."); assert_int_equal(LY_ENOTFOUND, lys_parse_mem(UTEST_LYCTX, "module cc {namespace urn:cc;prefix cc; container c {leaf a {type string;}}" "augment /c/a {leaf a {type int8;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Augment target node \"/c/a\" from module \"cc\" was not found.", "/cc:{augment='/c/a'}"); + CHECK_LOG_CTX("Augment target node \"/c/a\" from module \"cc\" was not found.", "Path \"/cc:{augment='/c/a'}\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module dd {namespace urn:dd;prefix dd; container c {leaf a {type string;}}" "augment /c {case b {leaf d {type int8;}}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Invalid augment of container node which is not allowed to contain case node \"b\".", "/dd:{augment='/c'}"); + CHECK_LOG_CTX("Invalid augment of container node which is not allowed to contain case node \"b\".", "Path \"/dd:{augment='/c'}\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module ee {namespace urn:ee;prefix ee; import himp {prefix hi;}" "augment /hi:top {container c {leaf d {mandatory true; type int8;}}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Invalid augment adding mandatory node \"c\" without making it conditional via when statement.", "/ee:{augment='/hi:top'}"); + CHECK_LOG_CTX("Invalid augment adding mandatory node \"c\" without making it conditional via when statement.", "Path \"/ee:{augment='/hi:top'}\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module ff {namespace urn:ff;prefix ff; container top;" "augment ../top {leaf x {type int8;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Invalid absolute-schema-nodeid value \"../top\" - \"/\" expected instead of \"..\".", "/ff:{augment='../top'}"); + CHECK_LOG_CTX("Invalid absolute-schema-nodeid value \"../top\" - \"/\" expected instead of \"..\".", "Path \"/ff:{augment='../top'}\"."); assert_int_equal(LY_ENOTFOUND, lys_parse_mem(UTEST_LYCTX, "module gg {namespace urn:gg;prefix gg; rpc func;" "augment /func {leaf x {type int8;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Augment target node \"/func\" from module \"gg\" was not found.", "/gg:{augment='/func'}"); + CHECK_LOG_CTX("Augment target node \"/func\" from module \"gg\" was not found.", "Path \"/gg:{augment='/func'}\"."); assert_int_equal(LY_ENOTFOUND, lys_parse_mem(UTEST_LYCTX, "module hh {namespace urn:hh;prefix hh;import himp {prefix hi;}" "augment /hi:func/input {leaf x {type string;}}" "augment /hi:func/output {leaf y {type string;}}}", LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Augment target node \"/hi:func/input\" from module \"hh\" was not found.", "/hh:{augment='/hi:func/input'}"); + CHECK_LOG_CTX("Augment target node \"/hi:func/input\" from module \"hh\" was not found.", "Path \"/hh:{augment='/hi:func/input'}\"."); + CHECK_LOG_CTX("Augment target node \"/hi:func/output\" from module \"hh\" was not found.", "Path \"/hh:{augment='/hi:func/output'}\"."); } static void @@ -3104,18 +3240,18 @@ test_deviation(void **state) assert_true(node->flags & LYS_CONFIG_R); assert_int_equal(LY_SUCCESS, lys_parse_mem(UTEST_LYCTX, "module l {namespace urn:l;prefix l; leaf a {config false; type string;}" - "container top {config false; leaf x {type string;}}" + "container top {leaf x {type string;}}" "deviation /a {deviate replace {config true;}}" - "deviation /top {deviate replace {config true;}}}", LYS_IN_YANG, &mod)); + "deviation /top {deviate replace {config false;}}}", LYS_IN_YANG, &mod)); assert_non_null(node = mod->compiled->data); assert_string_equal("a", node->name); assert_true(node->flags & LYS_CONFIG_W); assert_non_null(node = node->next); assert_string_equal("top", node->name); - assert_true(node->flags & LYS_CONFIG_W); + assert_true(node->flags & LYS_CONFIG_R); assert_non_null(node = lysc_node_child(node)); assert_string_equal("x", node->name); - assert_true(node->flags & LYS_CONFIG_W); + assert_true(node->flags & LYS_CONFIG_R); assert_int_equal(LY_SUCCESS, lys_parse_mem(UTEST_LYCTX, "module m {namespace urn:m;prefix m;" "container a {leaf a {type string;}}" @@ -3356,194 +3492,199 @@ test_deviation(void **state) assert_int_equal(LY_ENOTFOUND, lys_parse_mem(UTEST_LYCTX, "module aa1 {namespace urn:aa1;prefix aa1;import a {prefix a;}" "deviation /a:top/a:z {deviate not-supported;}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Deviation(s) target node \"/a:top/a:z\" from module \"aa1\" was not found.", "/a:{deviation='/a:top/a:z'}"); + CHECK_LOG_CTX("Deviation(s) target node \"/a:top/a:z\" from module \"aa1\" was not found.", "Path \"/a:{deviation='/a:top/a:z'}\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module aa2 {namespace urn:aa2;prefix aa2;import a {prefix a;}" "deviation /a:top/a:a {deviate not-supported;}" "deviation /a:top/a:a {deviate add {default error;}}}", LYS_IN_YANG, NULL)); - CHECK_LOG_CTX("Multiple deviations of \"/a:top/a:a\" with one of them being \"not-supported\".", "/aa2:{deviation='/a:top/a:a'}"); + CHECK_LOG_CTX("Multiple deviations of \"/a:top/a:a\" with one of them being \"not-supported\".", "Path \"/aa2:{deviation='/a:top/a:a'}\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module bb {namespace urn:bb;prefix bb;import a {prefix a;}" "deviation a:top/a:a {deviate not-supported;}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Invalid absolute-schema-nodeid value \"a:top/a:a\" - \"/\" expected instead of \"a:top\".", "/bb:{deviation='a:top/a:a'}"); + CHECK_LOG_CTX("Invalid absolute-schema-nodeid value \"a:top/a:a\" - \"/\" expected instead of \"a:top\".", "Path \"/bb:{deviation='a:top/a:a'}\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module cc {namespace urn:cc;prefix cc; container c;" "deviation /c {deviate add {units meters;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Invalid deviation of container node - it is not possible to add \"units\" property.", "/cc:{deviation='/c'}"); + CHECK_LOG_CTX("Invalid deviation of container node - it is not possible to add \"units\" property.", "Path \"/cc:{deviation='/c'}\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module cd {namespace urn:cd;prefix cd; leaf c {type string; units centimeters;}" "deviation /c {deviate add {units meters;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Invalid deviation adding \"units\" property which already exists (with value \"centimeters\").", "/cd:{deviation='/c'}"); + CHECK_LOG_CTX("Invalid deviation adding \"units\" property which already exists (with value \"centimeters\").", "Path \"/cd:{deviation='/c'}\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module dd1 {namespace urn:dd1;prefix dd1; container c;" "deviation /c {deviate delete {units meters;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Invalid deviation of container node - it is not possible to delete \"units\" property.", "/dd1:{deviation='/c'}"); + CHECK_LOG_CTX("Invalid deviation of container node - it is not possible to delete \"units\" property.", "Path \"/dd1:{deviation='/c'}\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module dd2 {namespace urn:dd2;prefix dd2; leaf c {type string;}" "deviation /c {deviate delete {units meters;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Invalid deviation deleting \"units\" property \"meters\" which is not present.", "/dd2:{deviation='/c'}"); + CHECK_LOG_CTX("Invalid deviation deleting \"units\" property \"meters\" which is not present.", "Path \"/dd2:{deviation='/c'}\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module dd3 {namespace urn:dd3;prefix dd3; leaf c {type string; units centimeters;}" "deviation /c {deviate delete {units meters;}}}", LYS_IN_YANG, &mod)); CHECK_LOG_CTX("Invalid deviation deleting \"units\" property \"meters\" which does not match the target's property value \"centimeters\".", - "/dd3:{deviation='/c'}"); + "Path \"/dd3:{deviation='/c'}\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module ee1 {namespace urn:ee1;prefix ee1; container c;" "deviation /c {deviate replace {units meters;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Invalid deviation of container node - it is not possible to replace \"units\" property.", "/ee1:{deviation='/c'}"); + CHECK_LOG_CTX("Invalid deviation of container node - it is not possible to replace \"units\" property.", "Path \"/ee1:{deviation='/c'}\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module ee2 {namespace urn:ee2;prefix ee2; leaf c {type string;}" "deviation /c {deviate replace {units meters;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Invalid deviation replacing \"units\" property \"meters\" which is not present.", "/ee2:{deviation='/c'}"); + CHECK_LOG_CTX("Invalid deviation replacing \"units\" property \"meters\" which is not present.", "Path \"/ee2:{deviation='/c'}\"."); /* the default is already deleted in /e:a byt module f */ assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module ff1 {namespace urn:ff1;prefix ff1; import e {prefix e;}" "deviation /e:a {deviate delete {default x:aa;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Invalid deviation deleting \"default\" property \"x:aa\" which is not present.", "/ff1:{deviation='/e:a'}"); + CHECK_LOG_CTX("Invalid deviation deleting \"default\" property \"x:aa\" which is not present.", "Path \"/ff1:{deviation='/e:a'}\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module ff3 {namespace urn:ff3;prefix ff3; import e {prefix e;}" "deviation /e:b {deviate delete {default e:b;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Invalid deviation deleting \"default\" property \"e:b\" which does not match the target's property value \"x:ba\".", "/ff3:{deviation='/e:b'}"); + CHECK_LOG_CTX("Invalid deviation deleting \"default\" property \"e:b\" which does not match the target's property value \"x:ba\".", + "Path \"/ff3:{deviation='/e:b'}\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module ff5 {namespace urn:ff5;prefix ff5; anyxml a;" "deviation /a {deviate delete {default x;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Invalid deviation of anyxml node - it is not possible to delete \"default\" property.", "/ff5:{deviation='/a'}"); + CHECK_LOG_CTX("Invalid deviation of anyxml node - it is not possible to delete \"default\" property.", "Path \"/ff5:{deviation='/a'}\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module ff6 {namespace urn:ff6;prefix ff6; import e {prefix e;}" "deviation /e:c {deviate delete {default hi;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Invalid deviation deleting \"default\" property \"hi\" which does not match the target's property value \"hello\".", "/ff6:{deviation='/e:c'}"); + CHECK_LOG_CTX("Invalid deviation deleting \"default\" property \"hi\" which does not match the target's property value \"hello\".", + "Path \"/ff6:{deviation='/e:c'}\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module ff7 {namespace urn:ff7;prefix ff7; import e {prefix e;}" "deviation /e:d {deviate delete {default hi;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Invalid deviation deleting \"default\" property \"hi\" which does not match any of the target's property values.", "/ff7:{deviation='/e:d'}"); + CHECK_LOG_CTX("Invalid deviation deleting \"default\" property \"hi\" which does not match any of the target's property values.", + "Path \"/ff7:{deviation='/e:d'}\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module gg1 {namespace urn:gg1;prefix gg1; import e {prefix e;}" "deviation /e:b {deviate add {default e:a;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Invalid deviation adding \"default\" property which already exists (with value \"x:ba\").", "/gg1:{deviation='/e:b'}"); + CHECK_LOG_CTX("Invalid deviation adding \"default\" property which already exists (with value \"x:ba\").", "Path \"/gg1:{deviation='/e:b'}\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module gg2 {namespace urn:gg2;prefix gg2; import e {prefix e;}" "deviation /e:a {deviate add {default x:a;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Compilation of a deviated and/or refined node failed.", "/e:a", - "Default case prefix \"x\" not found in imports of \"gg2\".", "/e:a"); + CHECK_LOG_CTX("Compilation of a deviated and/or refined node failed.", "Path \"/e:a\"."); + CHECK_LOG_CTX("Default case prefix \"x\" not found in imports of \"gg2\".", "Path \"/e:a\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module gg3 {namespace urn:gg3;prefix gg3; import e {prefix e;}" "deviation /e:a {deviate add {default a;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Compilation of a deviated and/or refined node failed.", "/e:a", - "Default case \"a\" not found.", "/e:a"); + CHECK_LOG_CTX("Compilation of a deviated and/or refined node failed.", "Path \"/e:a\"."); + CHECK_LOG_CTX("Default case \"a\" not found.", "Path \"/e:a\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module gg4 {namespace urn:gg4;prefix gg4; import e {prefix e;}" "deviation /e:c {deviate add {default hi;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Invalid deviation adding \"default\" property which already exists (with value \"hello\").", "/gg4:{deviation='/e:c'}"); + CHECK_LOG_CTX("Invalid deviation adding \"default\" property which already exists (with value \"hello\").", "Path \"/gg4:{deviation='/e:c'}\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module gg4 {namespace urn:gg4;prefix gg4; import e {prefix e;}" "deviation /e:a {deviate add {default e:ac;}}}", LYS_IN_YANG, &mod)); - /*CHECK_LOG_CTX("Invalid deviation adding \"default\" property \"e:ac\" of choice - mandatory node \"ac\" under the default case.", "/gg4:{deviation='/e:a'}");*/ - CHECK_LOG_CTX("Compilation of a deviated and/or refined node failed.", "/e:a"); + CHECK_LOG_CTX("Compilation of a deviated and/or refined node failed.", "Path \"/e:a\"."); + CHECK_LOG_CTX("Mandatory node \"ac\" under the default case \"e:ac\".", "Path \"/e:a\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module gg5 {namespace urn:gg5;prefix gg5; leaf x {type string; mandatory true;}" "deviation /x {deviate add {default error;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Compilation of a deviated and/or refined node failed.", "/gg5:{deviation='/x'}", - "Invalid mandatory leaf with a default value.", "/gg5:{deviation='/x'}"); + CHECK_LOG_CTX("Compilation of a deviated and/or refined node failed.", "Path \"/gg5:{deviation='/x'}\"."); + CHECK_LOG_CTX("Invalid mandatory leaf with a default value.", "Path \"/gg5:{deviation='/x'}\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module hh1 {yang-version 1.1; namespace urn:hh1;prefix hh1; import e {prefix e;}" "deviation /e:d {deviate replace {default hi;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Invalid deviation of leaf-list node - it is not possible to replace \"default\" property.", "/hh1:{deviation='/e:d'}"); + CHECK_LOG_CTX("Invalid deviation of leaf-list node - it is not possible to replace \"default\" property.", + "Path \"/hh1:{deviation='/e:d'}\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module ii1 {namespace urn:ii1;prefix ii1; import i {prefix i;}" "deviation /i:l1 {deviate delete {unique x;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Invalid deviation deleting \"unique\" property \"x\" which does not match any of the target's property values.", "/ii1:{deviation='/i:l1'}"); + CHECK_LOG_CTX("Invalid deviation deleting \"unique\" property \"x\" which does not match any of the target's property values.", + "Path \"/ii1:{deviation='/i:l1'}\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module ii2 {namespace urn:ii2;prefix ii2; import i {prefix i;} leaf x { type string;}" "deviation /i:l2 {deviate delete {unique d;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Invalid deviation deleting \"unique\" property \"d\" which does not match any of the target's property values.", "/ii2:{deviation='/i:l2'}"); + CHECK_LOG_CTX("Invalid deviation deleting \"unique\" property \"d\" which does not match any of the target's property values.", + "Path \"/ii2:{deviation='/i:l2'}\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module ii3 {namespace urn:ii3;prefix ii3; leaf x { type string;}" "deviation /x {deviate delete {unique d;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Invalid deviation of leaf node - it is not possible to delete \"unique\" property.", "/ii3:{deviation='/x'}"); + CHECK_LOG_CTX("Invalid deviation of leaf node - it is not possible to delete \"unique\" property.", "Path \"/ii3:{deviation='/x'}\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module ii4 {namespace urn:ii4;prefix ii4; leaf x { type string;}" "deviation /x {deviate add {unique d;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Invalid deviation of leaf node - it is not possible to add \"unique\" property.", "/ii4:{deviation='/x'}"); + CHECK_LOG_CTX("Invalid deviation of leaf node - it is not possible to add \"unique\" property.", "Path \"/ii4:{deviation='/x'}\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module jj1 {namespace urn:jj1;prefix jj1; choice ch {case a {leaf a{type string;}}}" "deviation /ch/a {deviate add {config false;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Invalid deviation of case node - it is not possible to add \"config\" property.", "/jj1:{deviation='/ch/a'}"); + CHECK_LOG_CTX("Invalid deviation of case node - it is not possible to add \"config\" property.", "Path \"/jj1:{deviation='/ch/a'}\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module jj2 {namespace urn:jj2;prefix jj2; container top {config false; leaf x {type string;}}" "deviation /top/x {deviate add {config true;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Compilation of a deviated and/or refined node failed.", "/jj2:{deviation='/top/x'}", - "Configuration node cannot be child of any state data node.", "/jj2:{deviation='/top/x'}"); - assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module jj3 {namespace urn:jj3;prefix jj3; container top {leaf x {type string;}}" - "deviation /top/x {deviate replace {config false;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Invalid deviation replacing \"config\" property \"config false\" which is not present.", "/jj3:{deviation='/top/x'}"); + CHECK_LOG_CTX("Compilation of a deviated and/or refined node failed.", "Path \"/jj2:{deviation='/top/x'}\"."); + CHECK_LOG_CTX("Configuration node cannot be child of any state data node.", "Path \"/jj2:{deviation='/top/x'}\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module jj4 {namespace urn:jj4;prefix jj4; choice ch {case a {leaf a{type string;}}}" "deviation /ch/a {deviate replace {config false;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Invalid deviation of case node - it is not possible to replace \"config\" property.", "/jj4:{deviation='/ch/a'}"); + CHECK_LOG_CTX("Invalid deviation of case node - it is not possible to replace \"config\" property.", "Path \"/jj4:{deviation='/ch/a'}\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module jj5 {namespace urn:jj5;prefix jj5; container top {leaf x {type string; config true;}}" "deviation /top {deviate add {config false;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Compilation of a deviated and/or refined node failed.", "/jj5:top", - "Configuration node cannot be child of any state data node.", "/jj5:top/x"); + CHECK_LOG_CTX("Compilation of a deviated and/or refined node failed.", "Path \"/jj5:top\"."); + CHECK_LOG_CTX("Configuration node cannot be child of any state data node.", "Path \"/jj5:top/x\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module jj6 {namespace urn:jj6;prefix jj6; leaf x {config false; type string;}" "deviation /x {deviate add {config true;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Invalid deviation adding \"config\" property which already exists (with value \"config false\").", "/jj6:{deviation='/x'}"); + CHECK_LOG_CTX("Invalid deviation adding \"config\" property which already exists (with value \"config false\").", + "Path \"/jj6:{deviation='/x'}\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module kk1 {namespace urn:kk1;prefix kk1; container top {leaf a{type string;}}" "deviation /top {deviate add {mandatory true;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Invalid deviation of container node - it is not possible to add \"mandatory\" property.", "/kk1:{deviation='/top'}"); + CHECK_LOG_CTX("Invalid deviation of container node - it is not possible to add \"mandatory\" property.", "Path \"/kk1:{deviation='/top'}\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module kk2 {namespace urn:kk2;prefix kk2; container top {leaf a{type string;}}" "deviation /top {deviate replace {mandatory true;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Invalid deviation of container node - it is not possible to replace \"mandatory\" property.", "/kk2:{deviation='/top'}"); + CHECK_LOG_CTX("Invalid deviation of container node - it is not possible to replace \"mandatory\" property.", "Path \"/kk2:{deviation='/top'}\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module kk3 {namespace urn:kk3;prefix kk3; container top {leaf x {type string;}}" "deviation /top/x {deviate replace {mandatory true;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Invalid deviation replacing \"mandatory\" property \"mandatory true\" which is not present.", "/kk3:{deviation='/top/x'}"); + CHECK_LOG_CTX("Invalid deviation replacing \"mandatory\" property \"mandatory true\" which is not present.", "Path \"/kk3:{deviation='/top/x'}\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module kk4 {namespace urn:kk4;prefix kk4; leaf x {mandatory true; type string;}" "deviation /x {deviate add {mandatory false;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Invalid deviation adding \"mandatory\" property which already exists (with value \"mandatory true\").", "/kk4:{deviation='/x'}"); + CHECK_LOG_CTX("Invalid deviation adding \"mandatory\" property which already exists (with value \"mandatory true\").", + "Path \"/kk4:{deviation='/x'}\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module ll1 {namespace urn:ll1;prefix ll1; leaf x {default test; type string;}" "deviation /x {deviate add {mandatory true;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Compilation of a deviated and/or refined node failed.", "/ll1:{deviation='/x'}", - "Invalid mandatory leaf with a default value.", "/ll1:{deviation='/x'}"); + CHECK_LOG_CTX("Compilation of a deviated and/or refined node failed.", "Path \"/ll1:{deviation='/x'}\"."); + CHECK_LOG_CTX("Invalid mandatory leaf with a default value.", "Path \"/ll1:{deviation='/x'}\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module ll2 {yang-version 1.1; namespace urn:ll2;prefix ll2; leaf-list x {default test; type string;}" "deviation /x {deviate add {min-elements 1;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Compilation of a deviated and/or refined node failed.", "/ll2:{deviation='/x'}", - "The default statement is present on leaf-list with a nonzero min-elements.", "/ll2:{deviation='/x'}"); + CHECK_LOG_CTX("Compilation of a deviated and/or refined node failed.", "Path \"/ll2:{deviation='/x'}\"."); + CHECK_LOG_CTX("The default statement is present on leaf-list with a nonzero min-elements.", "Path \"/ll2:{deviation='/x'}\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module ll2 {namespace urn:ll2;prefix ll2; choice ch {default a; leaf a {type string;} leaf b {type string;}}" "deviation /ch {deviate add {mandatory true;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Compilation of a deviated and/or refined node failed.", "/ll2:ch", - "Invalid mandatory choice with a default case.", "/ll2:ch"); + CHECK_LOG_CTX("Compilation of a deviated and/or refined node failed.", "Path \"/ll2:ch\"."); + CHECK_LOG_CTX("Invalid mandatory choice with a default case.", "Path \"/ll2:ch\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module mm1 {namespace urn:mm1;prefix mm1; leaf-list x {min-elements 10; type string;}" "deviation /x {deviate add {max-elements 5;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Compilation of a deviated and/or refined node failed.", "/mm1:{deviation='/x'}", - "Leaf-list min-elements 10 is bigger than max-elements 5.", "/mm1:{deviation='/x'}"); + CHECK_LOG_CTX("Compilation of a deviated and/or refined node failed.", "Path \"/mm1:{deviation='/x'}\"."); + CHECK_LOG_CTX("Leaf-list min-elements 10 is bigger than max-elements 5.", "Path \"/mm1:{deviation='/x'}\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module mm2 {namespace urn:mm2;prefix mm2; leaf-list x {max-elements 10; type string;}" "deviation /x {deviate add {min-elements 20;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Compilation of a deviated and/or refined node failed.", "/mm2:{deviation='/x'}", - "Leaf-list min-elements 20 is bigger than max-elements 10.", "/mm2:{deviation='/x'}"); + CHECK_LOG_CTX("Compilation of a deviated and/or refined node failed.", "Path \"/mm2:{deviation='/x'}\"."); + CHECK_LOG_CTX("Leaf-list min-elements 20 is bigger than max-elements 10.", "Path \"/mm2:{deviation='/x'}\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module mm3 {namespace urn:mm3;prefix mm3; list x {min-elements 5; max-elements 10; config false;}" "deviation /x {deviate replace {max-elements 1;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Compilation of a deviated and/or refined node failed.", "/mm3:{deviation='/x'}", - "List min-elements 5 is bigger than max-elements 1.", "/mm3:{deviation='/x'}"); + CHECK_LOG_CTX("Compilation of a deviated and/or refined node failed.", "Path \"/mm3:{deviation='/x'}\"."); + CHECK_LOG_CTX("List min-elements 5 is bigger than max-elements 1.", "Path \"/mm3:{deviation='/x'}\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module mm4 {namespace urn:mm4;prefix mm4; list x {min-elements 5; max-elements 10; config false;}" "deviation /x {deviate replace {min-elements 20;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Compilation of a deviated and/or refined node failed.", "/mm4:{deviation='/x'}", - "List min-elements 20 is bigger than max-elements 10.", "/mm4:{deviation='/x'}"); + CHECK_LOG_CTX("Compilation of a deviated and/or refined node failed.", "Path \"/mm4:{deviation='/x'}\"."); + CHECK_LOG_CTX("List min-elements 20 is bigger than max-elements 10.", "Path \"/mm4:{deviation='/x'}\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module mm5 {namespace urn:mm5;prefix mm5; leaf-list x {type string; min-elements 5;}" "deviation /x {deviate add {min-elements 1;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Invalid deviation adding \"min-elements\" property which already exists (with value \"5\").", "/mm5:{deviation='/x'}"); + CHECK_LOG_CTX("Invalid deviation adding \"min-elements\" property which already exists (with value \"5\").", "Path \"/mm5:{deviation='/x'}\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module mm6 {namespace urn:mm6;prefix mm6; list x {config false; min-elements 5;}" "deviation /x {deviate add {min-elements 1;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Invalid deviation adding \"min-elements\" property which already exists (with value \"5\").", "/mm6:{deviation='/x'}"); + CHECK_LOG_CTX("Invalid deviation adding \"min-elements\" property which already exists (with value \"5\").", "Path \"/mm6:{deviation='/x'}\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module mm7 {namespace urn:mm7;prefix mm7; leaf-list x {type string; max-elements 5;}" "deviation /x {deviate add {max-elements 1;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Invalid deviation adding \"max-elements\" property which already exists (with value \"5\").", "/mm7:{deviation='/x'}"); + CHECK_LOG_CTX("Invalid deviation adding \"max-elements\" property which already exists (with value \"5\").", "Path \"/mm7:{deviation='/x'}\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module mm8 {namespace urn:mm8;prefix mm8; list x {config false; max-elements 5;}" "deviation /x {deviate add {max-elements 1;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Invalid deviation adding \"max-elements\" property which already exists (with value \"5\").", "/mm8:{deviation='/x'}"); + CHECK_LOG_CTX("Invalid deviation adding \"max-elements\" property which already exists (with value \"5\").", "Path \"/mm8:{deviation='/x'}\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module mm9 {namespace urn:mm9;prefix mm9; leaf-list x {type string;}" "deviation /x {deviate replace {min-elements 1;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Invalid deviation replacing \"min-elements\" property which is not present.", "/mm9:{deviation='/x'}"); + CHECK_LOG_CTX("Invalid deviation replacing \"min-elements\" property which is not present.", "Path \"/mm9:{deviation='/x'}\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module mm10 {namespace urn:mm10;prefix mm10; list x {config false;}" "deviation /x {deviate replace {min-elements 1;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Invalid deviation replacing \"min-elements\" property which is not present.", "/mm10:{deviation='/x'}"); + CHECK_LOG_CTX("Invalid deviation replacing \"min-elements\" property which is not present.", "Path \"/mm10:{deviation='/x'}\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module mm11 {namespace urn:mm11;prefix mm11; leaf-list x {type string;}" "deviation /x {deviate replace {max-elements 1;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Invalid deviation replacing \"max-elements\" property which is not present.", "/mm11:{deviation='/x'}"); + CHECK_LOG_CTX("Invalid deviation replacing \"max-elements\" property which is not present.", "Path \"/mm11:{deviation='/x'}\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module mm12 {namespace urn:mm12;prefix mm12; list x {config false; }" "deviation /x {deviate replace {max-elements 1;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Invalid deviation replacing \"max-elements\" property which is not present.", "/mm12:{deviation='/x'}"); + CHECK_LOG_CTX("Invalid deviation replacing \"max-elements\" property which is not present.", "Path \"/mm12:{deviation='/x'}\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module nn1 {namespace urn:nn1;prefix nn1; anyxml x;" "deviation /x {deviate replace {type string;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Invalid deviation of anyxml node - it is not possible to replace \"type\" property.", "/nn1:{deviation='/x'}"); + CHECK_LOG_CTX("Invalid deviation of anyxml node - it is not possible to replace \"type\" property.", "Path \"/nn1:{deviation='/x'}\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module nn2 {namespace urn:nn2;prefix nn2; leaf-list x {type string;}" "deviation /x {deviate replace {type empty;}}}", LYS_IN_YANG, &mod)); - CHECK_LOG_CTX("Compilation of a deviated and/or refined node failed.", "/nn2:{deviation='/x'}", - "Leaf-list of type \"empty\" is allowed only in YANG 1.1 modules.", "/nn2:{deviation='/x'}"); + CHECK_LOG_CTX("Compilation of a deviated and/or refined node failed.", "Path \"/nn2:{deviation='/x'}\"."); + CHECK_LOG_CTX("Leaf-list of type \"empty\" is allowed only in YANG 1.1 modules.", "Path \"/nn2:{deviation='/x'}\"."); assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module oo1 {namespace urn:oo1;prefix oo1; leaf x {type uint16; default 300;}" "deviation /x {deviate replace {type uint8;}}}", LYS_IN_YANG, &mod)); @@ -3563,6 +3704,7 @@ test_deviation(void **state) assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module pp1 {namespace urn:pp1;prefix pp1; import pp {prefix pp;}" "deviation /pp:c/pp:x {deviate not-supported;}}", LYS_IN_YANG, &mod)); CHECK_LOG_CTX("Target of leafref \"l\" cannot be referenced because it is disabled.", "Schema location \"/pp:l\"."); + CHECK_LOG_CTX("Not found node \"x\" in path.", "Schema location \"/pp:l\"."); } static void @@ -3755,6 +3897,55 @@ test_when(void **state) " }" "}", LYS_IN_YANG, NULL)); + + ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, + "module d1 {" + " namespace urn:d1;" + " prefix d1;" + " container ifm {" + " container interfaces {" + " list interface {" + " key \"name\";" + " leaf name {" + " type string;" + " }" + " container ethernet {" + " container main-interface {" + " container l2-attribute {" + " when \"not(/d1:ifm/d1:interfaces/d1:interface/d1:trunk/d1:members/d1:member[d1:name=current()/../../../d1:name])\";" + " presence \"\";" + " }" + " }" + " }" + " container trunk {" + " container members {" + " list member {" + " key \"name\";" + " leaf name {" + " type string;" + " }" + " }" + " }" + " }" + " }" + " }" + " }" + "}"); + assert_int_equal(LY_SUCCESS, lys_parse_mem(UTEST_LYCTX, + "module d2 {" + " namespace \"urn:d2\";" + " prefix d2;" + " import d1 {" + " prefix d1;" + " }" + " augment \"/d1:ifm/d1:interfaces/d1:interface/d1:ethernet/d1:main-interface\" {" + " when \"not(d1:l2-attribute)\";" + " container extra-attribute {" + " presence \"\";" + " }" + " }" + "}", + LYS_IN_YANG, NULL)); } static void @@ -3796,6 +3987,68 @@ test_must(void **state) LYS_IN_YANG, NULL)); /* no warnings */ CHECK_LOG_CTX(NULL, NULL); + + /* must referencing disabled leafref in another module */ + ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, + "module b-imp {" + " yang-version 1.1;" + " namespace \"urn:b-imp\";" + " prefix \"bi\";" + "" + " feature feat;" + "" + " grouping band-capabilities {" + " leaf band-number {" + " type uint16;" + " }" + "" + " container sub-band-info {" + " when \"../band-number = '46'\";" + " if-feature \"bi:feat\";" + " leaf number-of-laa-scarriers {" + " type uint8;" + " }" + " }" + " }" + "" + " container module-capability {" + " list band-capabilities {" + " key band-number;" + " config false;" + " uses band-capabilities;" + " }" + " container rw-sub-band-info {" + " if-feature \"bi:feat\";" + " leaf rw-number-of-laa-scarriers {" + " type leafref {" + " path \"/module-capability/band-capabilities/sub-band-info/number-of-laa-scarriers\";" + " require-instance false;" + " }" + " }" + " }" + " }" + "}"); + + ly_ctx_set_options(UTEST_LYCTX, LY_CTX_REF_IMPLEMENTED); + assert_int_equal(LY_SUCCESS, lys_parse_mem(UTEST_LYCTX, + "module b {" + " yang-version 1.1;" + " namespace \"urn:b\";" + " prefix \"b\";" + "" + " import b-imp {" + " prefix \"bi\";" + " }" + "" + " container laa-config {" + " must \"number-of-laa-scarriers <= /bi:module-capability/bi:rw-sub-band-info/bi:rw-number-of-laa-scarriers\";" + " }" + "}", + LYS_IN_YANG, NULL)); + ly_ctx_unset_options(UTEST_LYCTX, LY_CTX_REF_IMPLEMENTED); + + CHECK_LOG_CTX("Schema node \"number-of-laa-scarriers\" not found; in expr \"number-of-laa-scarriers\" " + "with context node \"/b:laa-config\".", NULL); } int @@ -3816,6 +4069,7 @@ main(void) UTEST(test_type_empty, setup), UTEST(test_type_union, setup), UTEST(test_type_dflt, setup), + UTEST(test_type_exts, setup), UTEST(test_status, setup), UTEST(test_node_container, setup), UTEST(test_node_leaflist, setup), diff --git a/tests/utests/schema/test_yang.c b/tests/utests/schema/test_yang.c index 78b1798..6d1c2ae 100644 --- a/tests/utests/schema/test_yang.c +++ b/tests/utests/schema/test_yang.c @@ -155,6 +155,7 @@ test_helpers(void **state) assert_int_equal(LY_EVALID, buf_store_char(YCTX, Y_IDENTIF_ARG, &p, &len, &buf, &size, 1, &prefix)); in.current = ":"; assert_int_equal(LY_EVALID, buf_store_char(YCTX, Y_IDENTIF_ARG, &p, &len, &buf, &size, 1, &prefix)); + UTEST_LOG_CTX_CLEAN; /* valid colon for prefixed identifiers */ len = size = 0; p = NULL; @@ -183,6 +184,7 @@ test_helpers(void **state) assert_int_equal(LY_SUCCESS, lysp_check_identifierchar((struct lysp_ctx *)YCTX, ':', 0, &prefix)); assert_int_equal(1, prefix); assert_int_equal(LY_EVALID, lysp_check_identifierchar((struct lysp_ctx *)YCTX, ':', 0, &prefix)); + CHECK_LOG_CTX("Invalid identifier first character ':' (0x003a).", "Line number 1."); assert_int_equal(1, prefix); assert_int_equal(LY_SUCCESS, lysp_check_identifierchar((struct lysp_ctx *)YCTX, 'b', 0, &prefix)); assert_int_equal(2, prefix); @@ -887,12 +889,18 @@ test_module(void **state) ly_ctx_set_module_imp_clb(PARSER_CUR_PMOD(YCTX)->mod->ctx, test_imp_clb, "module xxx { namespace urn:xxx; prefix x;}"); in.current = "module" SCHEMA_BEGINNING "include xxx;}"; assert_int_equal(lys_parse_mem(PARSER_CUR_PMOD(YCTX)->mod->ctx, in.current, LYS_IN_YANG, NULL), LY_EVALID); - CHECK_LOG_CTX("Parsing module \"name\" failed.", NULL, "Including \"xxx\" submodule into \"name\" failed.", NULL); + CHECK_LOG_CTX("Parsing module \"name\" failed.", NULL); + CHECK_LOG_CTX("Including \"xxx\" submodule into \"name\" failed.", NULL); + CHECK_LOG_CTX("Data model \"xxx\" not found in local searchdirs.", NULL); + CHECK_LOG_CTX("Parsing submodule failed.", NULL); + CHECK_LOG_CTX("Input data contains module in situation when a submodule is expected.", NULL); ly_ctx_set_module_imp_clb(PARSER_CUR_PMOD(YCTX)->mod->ctx, test_imp_clb, "submodule xxx {belongs-to wrong-name {prefix w;}}"); in.current = "module" SCHEMA_BEGINNING "include xxx;}"; assert_int_equal(lys_parse_mem(PARSER_CUR_PMOD(YCTX)->mod->ctx, in.current, LYS_IN_YANG, NULL), LY_EVALID); - CHECK_LOG_CTX("Parsing module \"name\" failed.", NULL, "Including \"xxx\" submodule into \"name\" failed.", NULL); + CHECK_LOG_CTX("Parsing module \"name\" failed.", NULL); + CHECK_LOG_CTX("Including \"xxx\" submodule into \"name\" failed.", NULL); + UTEST_LOG_CTX_CLEAN; ly_ctx_set_module_imp_clb(PARSER_CUR_PMOD(YCTX)->mod->ctx, test_imp_clb, "submodule xxx {belongs-to name {prefix x;}}"); TEST_GENERIC("include xxx;}", mod->includes, diff --git a/tests/utests/schema/test_yin.c b/tests/utests/schema/test_yin.c index 0ce3abc..a531b64 100644 --- a/tests/utests/schema/test_yin.c +++ b/tests/utests/schema/test_yin.c @@ -395,11 +395,13 @@ test_validate_value(void **state) YCTX->xmlctx->value = "pre:b"; YCTX->xmlctx->value_len = 5; assert_int_equal(yin_validate_value(YCTX, Y_IDENTIF_ARG), LY_EVALID); + CHECK_LOG_CTX("Invalid identifier character ':' (0x003a).", "Line number 1."); assert_int_equal(yin_validate_value(YCTX, Y_PREF_IDENTIF_ARG), LY_SUCCESS); YCTX->xmlctx->value = "pre:pre:b"; YCTX->xmlctx->value_len = 9; assert_int_equal(yin_validate_value(YCTX, Y_PREF_IDENTIF_ARG), LY_EVALID); + CHECK_LOG_CTX("Invalid identifier character ':' (0x003a).", "Line number 1."); } static void @@ -3097,7 +3099,7 @@ test_module_elem(void **state) assert_int_equal(yin_parse_mod(YCTX, lysp_mod), LY_SUCCESS); assert_string_equal(lysp_mod->mod->name, "mod"); - assert_string_equal(lysp_mod->revs, "2019-02-02"); + assert_string_equal(lysp_mod->revs[0].date, "2019-02-02"); assert_string_equal(lysp_mod->mod->ns, "ns"); assert_string_equal(lysp_mod->mod->prefix, "pref"); assert_null(lysp_mod->mod->filepath); @@ -3230,8 +3232,10 @@ test_submodule_elem(void **state) assert_int_equal(lyxml_ctx_new(UTEST_LYCTX, UTEST_IN, &YCTX->xmlctx), LY_SUCCESS); assert_int_equal(yin_parse_submod(YCTX, lysp_submod), LY_SUCCESS); + CHECK_LOG_CTX("YANG version 1.1 expects all includes in main module, includes in submodules (mod) are not necessary.", + NULL); assert_string_equal(lysp_submod->name, "mod"); - assert_string_equal(lysp_submod->revs, "2019-02-02"); + assert_string_equal(lysp_submod->revs[0].date, "2019-02-02"); assert_string_equal(lysp_submod->prefix, "pref"); assert_null(lysp_submod->filepath); assert_string_equal(lysp_submod->org, "org"); diff --git a/tests/utests/types/binary.c b/tests/utests/types/binary.c index 05b6b97..4f3ea66 100644 --- a/tests/utests/types/binary.c +++ b/tests/utests/types/binary.c @@ -52,14 +52,15 @@ test_plugin_store(void **state) struct lys_module *mod; struct lyd_value value = {0}; struct lyplg_type *type = lyplg_type_plugin_find("", NULL, ly_data_type2str[LY_TYPE_BINARY]); - struct lysc_type *lysc_type; + struct lysc_type *lysc_type, *lysc_type2; LY_ERR ly_ret; const char *schema; /* create schema. Prepare common used variables */ - schema = MODULE_CREATE_YANG("a", "leaf l {type binary;}"); + schema = MODULE_CREATE_YANG("a", "leaf l {type binary;} leaf k {type binary {length 4..8;}}"); UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod); lysc_type = ((struct lysc_node_leaf *)mod->compiled->data)->type; + lysc_type2 = ((struct lysc_node_leaf *)mod->compiled->data->next)->type; /* check proper type */ assert_string_equal("libyang 2 - binary, version 1", type->id); @@ -176,6 +177,35 @@ test_plugin_store(void **state) assert_ptr_equal(value.realtype, lysc_type); type->free(UTEST_LYCTX, &value); + /* length check */ + val = "Zm91cg=="; + dec_val = "four"; + assert_int_equal(LY_SUCCESS, type->store(UTEST_LYCTX, lysc_type2, val, strlen(val), + 0, LY_VALUE_XML, NULL, LYD_VALHINT_STRING, NULL, &value, NULL, &err)); + CHECK_LYD_VALUE(value, BINARY, val, dec_val, strlen(dec_val)); + assert_ptr_equal(value.realtype, lysc_type2); + type->free(UTEST_LYCTX, &value); + + assert_int_equal(LY_SUCCESS, type->store(UTEST_LYCTX, lysc_type2, dec_val, strlen(dec_val), + 0, LY_VALUE_LYB, NULL, 0, NULL, &value, NULL, &err)); + CHECK_LYD_VALUE(value, BINARY, val, dec_val, strlen(dec_val)); + assert_ptr_equal(value.realtype, lysc_type2); + type->free(UTEST_LYCTX, &value); + + val = "ZWlnaHQwMTI="; + dec_val = "eight012"; + assert_int_equal(LY_SUCCESS, type->store(UTEST_LYCTX, lysc_type2, val, strlen(val), + 0, LY_VALUE_XML, NULL, LYD_VALHINT_STRING, NULL, &value, NULL, &err)); + CHECK_LYD_VALUE(value, BINARY, val, dec_val, strlen(dec_val)); + assert_ptr_equal(value.realtype, lysc_type2); + type->free(UTEST_LYCTX, &value); + + assert_int_equal(LY_SUCCESS, type->store(UTEST_LYCTX, lysc_type2, dec_val, strlen(dec_val), + 0, LY_VALUE_LYB, NULL, 0, NULL, &value, NULL, &err)); + CHECK_LYD_VALUE(value, BINARY, val, dec_val, strlen(dec_val)); + assert_ptr_equal(value.realtype, lysc_type2); + type->free(UTEST_LYCTX, &value); + /* * ERROR TESTS */ @@ -194,6 +224,14 @@ test_plugin_store(void **state) assert_int_equal(LY_EVALID, ly_ret); assert_string_equal(err->msg, "Base64 encoded value length must be divisible by 4."); ly_err_free(err); + + val = "MTIz"; + err = NULL; + ly_ret = type->store(UTEST_LYCTX, lysc_type2, val, strlen(val), + 0, LY_VALUE_XML, NULL, LYD_VALHINT_STRING, NULL, &value, NULL, &err); + assert_int_equal(LY_EVALID, ly_ret); + assert_string_equal(err->msg, "Unsatisfied length - string \"MTIz\" length is not allowed."); + ly_err_free(err); } static void diff --git a/tests/utests/types/bits.c b/tests/utests/types/bits.c index 3d42ebc..eb40965 100644 --- a/tests/utests/types/bits.c +++ b/tests/utests/types/bits.c @@ -179,7 +179,7 @@ test_schema_yang(void **state) "leaf port {type my_type {" " bit ten {position 11;} bit two;}}"); UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID); - CHECK_LOG_CTX("Invalid bits - position of the item \"ten\" has changed from 10 to 11 in the derived type.", "/TERR_0:port"); + CHECK_LOG_CTX("Invalid bits - position of the item \"ten\" has changed from 10 to 11 in the derived type.", "Path \"/TERR_0:port\"."); /* add new bit */ schema = MODULE_CREATE_YANG("TERR_1", "typedef my_type{type bits {" @@ -187,15 +187,15 @@ test_schema_yang(void **state) "leaf port {type my_type {" " bit ten {position 10;} bit two; bit test;}}"); UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID); - CHECK_LOG_CTX("Invalid bits - derived type adds new item \"test\".", "/TERR_1:port"); + CHECK_LOG_CTX("Invalid bits - derived type adds new item \"test\".", "Path \"/TERR_1:port\"."); /* different max value => autoadd index */ schema = MODULE_CREATE_YANG("TERR_2", "leaf port {type bits {" " bit first {position -1;} bit second;" "}}"); UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID); - CHECK_LOG_CTX("Parsing module \"TERR_2\" failed.", NULL, - "Invalid value \"-1\" of \"position\".", "Line number 5."); + CHECK_LOG_CTX("Parsing module \"TERR_2\" failed.", NULL); + CHECK_LOG_CTX("Invalid value \"-1\" of \"position\".", "Line number 5."); /* different max value => autoadd index */ schema = MODULE_CREATE_YANG("TERR_3", "leaf port {type bits {" @@ -203,48 +203,48 @@ test_schema_yang(void **state) "}}"); UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID); CHECK_LOG_CTX("Invalid bits - it is not possible to auto-assign bit position for \"second\" since the highest value is already 4294967295.", - "/TERR_3:port"); + "Path \"/TERR_3:port\"."); schema = MODULE_CREATE_YANG("TERR_4", "leaf port {type bits {" " bit first {position 10;} bit \"\";" "}}"); UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID); - CHECK_LOG_CTX("Parsing module \"TERR_4\" failed.", NULL, - "Statement argument is required.", "Line number 5."); + CHECK_LOG_CTX("Parsing module \"TERR_4\" failed.", NULL); + CHECK_LOG_CTX("Statement argument is required.", "Line number 5."); /* wrong character */ schema = MODULE_CREATE_YANG("TERR_5", "leaf port {type bits {" " bit first {position 10;} bit abcd^;" "}}"); UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID); - CHECK_LOG_CTX("Parsing module \"TERR_5\" failed.", NULL, - "Invalid identifier character '^' (0x005e).", "Line number 5."); + CHECK_LOG_CTX("Parsing module \"TERR_5\" failed.", NULL); + CHECK_LOG_CTX("Invalid identifier character '^' (0x005e).", "Line number 5."); schema = MODULE_CREATE_YANG("TERR_6", "leaf port {type bits {" " bit hi; bit hi;" "}}"); UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID); - CHECK_LOG_CTX("Parsing module \"TERR_6\" failed.", NULL, - "Duplicate identifier \"hi\" of bit statement.", "Line number 5."); + CHECK_LOG_CTX("Parsing module \"TERR_6\" failed.", NULL); + CHECK_LOG_CTX("Duplicate identifier \"hi\" of bit statement.", "Line number 5."); /* wrong character */ schema = MODULE_CREATE_YANG("TERR_7", "leaf port {type bits {" " bit first {position 10;} bit \"ab&cd\";" "}}"); UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID); - CHECK_LOG_CTX("Parsing module \"TERR_7\" failed.", NULL, - "Invalid identifier character '&' (0x0026).", "Line number 5."); + CHECK_LOG_CTX("Parsing module \"TERR_7\" failed.", NULL); + CHECK_LOG_CTX("Invalid identifier character '&' (0x0026).", "Line number 5."); schema = MODULE_CREATE_YANG("TERR_8", "leaf port {type bits {" " bit first {position 10;} bit \"4abcd\";" "}}"); UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID); - CHECK_LOG_CTX("Parsing module \"TERR_8\" failed.", NULL, - "Invalid identifier first character '4' (0x0034).", "Line number 5."); + CHECK_LOG_CTX("Parsing module \"TERR_8\" failed.", NULL); + CHECK_LOG_CTX("Invalid identifier first character '4' (0x0034).", "Line number 5."); schema = MODULE_CREATE_YANG("TERR_9", "leaf port {type bits;}"); UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID); - CHECK_LOG_CTX("Missing bit substatement for bits type.", "/TERR_9:port"); + CHECK_LOG_CTX("Missing bit substatement for bits type.", "Path \"/TERR_9:port\"."); /* new features of YANG 1.1 in YANG 1.0 */ schema = "module TERR_10 {" @@ -256,8 +256,8 @@ test_schema_yang(void **state) " }}" "}"; UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID); - CHECK_LOG_CTX("Parsing module \"TERR_10\" failed.", NULL, - "Invalid keyword \"if-feature\" as a child of \"bit\" - the statement is allowed only in YANG 1.1 modules.", + CHECK_LOG_CTX("Parsing module \"TERR_10\" failed.", NULL); + CHECK_LOG_CTX("Invalid keyword \"if-feature\" as a child of \"bit\" - the statement is allowed only in YANG 1.1 modules.", "Line number 1."); schema = "module TERR_11 {" @@ -267,7 +267,7 @@ test_schema_yang(void **state) " leaf l {type mytype {bit one;}}" "}"; UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID); - CHECK_LOG_CTX("Bits type can be subtyped only in YANG 1.1 modules.", "/TERR_11:l"); + CHECK_LOG_CTX("Bits type can be subtyped only in YANG 1.1 modules.", "Path \"/TERR_11:l\"."); /* feature is not present */ schema = MODULE_CREATE_YANG("IF_0", "feature f;" @@ -415,7 +415,7 @@ test_schema_yin(void **state) " <bit name=\"ten\"> <position value=\"11\"/> </bit> <bit name=\"two\"/>" "</type></leaf>"); UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID); - CHECK_LOG_CTX("Invalid bits - position of the item \"ten\" has changed from 10 to 11 in the derived type.", "/TERR_0:port"); + CHECK_LOG_CTX("Invalid bits - position of the item \"ten\" has changed from 10 to 11 in the derived type.", "Path \"/TERR_0:port\"."); /* add new bit */ schema = MODULE_CREATE_YIN("TERR_1", @@ -431,7 +431,7 @@ test_schema_yin(void **state) " <bit name=\"test\"/>" "</type></leaf>"); UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID); - CHECK_LOG_CTX("Invalid bits - derived type adds new item \"test\".", "/TERR_1:port"); + CHECK_LOG_CTX("Invalid bits - derived type adds new item \"test\".", "Path \"/TERR_1:port\"."); /* different max value => autoadd index */ schema = MODULE_CREATE_YIN("TERR_2", @@ -440,8 +440,8 @@ test_schema_yin(void **state) " <bit name=\"second\">" "</type></leaf>"); UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID); - CHECK_LOG_CTX("Parsing module \"TERR_2\" failed.", NULL, - "Invalid value \"-1\" of \"value\" attribute in \"position\" element.", "Line number 8."); + CHECK_LOG_CTX("Parsing module \"TERR_2\" failed.", NULL); + CHECK_LOG_CTX("Invalid value \"-1\" of \"value\" attribute in \"position\" element.", "Line number 8."); /* different max value => autoadd index */ schema = MODULE_CREATE_YIN("TERR_3", @@ -451,7 +451,7 @@ test_schema_yin(void **state) "</type></leaf>"); UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID); CHECK_LOG_CTX("Invalid bits - it is not possible to auto-assign bit position for \"second\" since the highest value is already 4294967295.", - "/TERR_3:port"); + "Path \"/TERR_3:port\"."); schema = MODULE_CREATE_YIN("TERR_4", "<leaf name=\"port\"> <type name=\"bits\">" @@ -459,9 +459,8 @@ test_schema_yin(void **state) " <bit name=\"second\"/>" "</type></leaf>"); UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID); - CHECK_LOG_CTX("Parsing module \"TERR_4\" failed.", NULL, - "Invalid identifier first character ' ' (0x0020).", - "Line number 8."); + CHECK_LOG_CTX("Parsing module \"TERR_4\" failed.", NULL); + CHECK_LOG_CTX("Invalid identifier first character ' ' (0x0020).", "Line number 8."); schema = MODULE_CREATE_YIN("TERR_5", "<leaf name=\"port\"> <type name=\"bits\">" @@ -469,9 +468,8 @@ test_schema_yin(void **state) " <bit name=\"second\"/>" "</type></leaf>"); UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID); - CHECK_LOG_CTX("Parsing module \"TERR_5\" failed.", NULL, - "Invalid identifier character ' ' (0x0020).", - "Line number 8."); + CHECK_LOG_CTX("Parsing module \"TERR_5\" failed.", NULL); + CHECK_LOG_CTX("Invalid identifier character ' ' (0x0020).", "Line number 8."); schema = MODULE_CREATE_YIN("TERR_6", "<leaf name=\"port\"> <type name=\"bits\">" @@ -479,9 +477,8 @@ test_schema_yin(void **state) " <bit name=\"hi\"/>" "</type></leaf>"); UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID); - CHECK_LOG_CTX("Parsing module \"TERR_6\" failed.", NULL, - "Duplicate identifier \"hi\" of bit statement.", - "Line number 8."); + CHECK_LOG_CTX("Parsing module \"TERR_6\" failed.", NULL); + CHECK_LOG_CTX("Duplicate identifier \"hi\" of bit statement.", "Line number 8."); schema = MODULE_CREATE_YIN("TERR_7", "<leaf name=\"port\"> <type name=\"bits\">" @@ -489,9 +486,8 @@ test_schema_yin(void **state) " <bit name=\"second\"/>" "</type></leaf>"); UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID); - CHECK_LOG_CTX("Parsing module \"TERR_7\" failed.", NULL, - "Invalid identifier first character '4' (0x0034).", - "Line number 8."); + CHECK_LOG_CTX("Parsing module \"TERR_7\" failed.", NULL); + CHECK_LOG_CTX("Invalid identifier first character '4' (0x0034).", "Line number 8."); /* TEST EMPTY NAME*/ schema = MODULE_CREATE_YIN("TERR_8", @@ -500,9 +496,8 @@ test_schema_yin(void **state) " <bit name=\"second\"/>" "</type></leaf>"); UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID); - CHECK_LOG_CTX("Parsing module \"TERR_8\" failed.", NULL, - "Empty identifier is not allowed.", - "Line number 8."); + CHECK_LOG_CTX("Parsing module \"TERR_8\" failed.", NULL); + CHECK_LOG_CTX("Empty identifier is not allowed.", "Line number 8."); } static void @@ -954,30 +949,6 @@ test_plugin_compare(void **state) assert_int_equal(LY_ENOT, type->compare(&diff_type_val, &(values[1]))); type->free(UTEST_LYCTX, &(diff_type_val)); - /* - * derivated type add some limitations - */ - diff_type_text = val_init[2]; - diff_type = ((struct lysc_node_leaf *)mod->compiled->data->next->next)->type; - ly_ret = diff_type->plugin->store(UTEST_LYCTX, diff_type, diff_type_text, strlen(diff_type_text), - 0, LY_VALUE_XML, NULL, LYD_VALHINT_STRING, NULL, &diff_type_val, NULL, &err); - assert_int_equal(LY_SUCCESS, ly_ret); - assert_int_equal(LY_ENOT, type->compare(&diff_type_val, &(values[2]))); - assert_int_equal(LY_ENOT, type->compare(&diff_type_val, &(values[1]))); - type->free(UTEST_LYCTX, &(diff_type_val)); - - /* - * different type (STRING) - */ - diff_type_text = val_init[2]; - diff_type = ((struct lysc_node_leaf *)mod->compiled->data->next->next->next)->type; - ly_ret = diff_type->plugin->store(UTEST_LYCTX, diff_type, diff_type_text, strlen(diff_type_text), - 0, LY_VALUE_XML, NULL, LYD_VALHINT_STRING, NULL, &diff_type_val, NULL, &err); - assert_int_equal(LY_SUCCESS, ly_ret); - assert_int_equal(LY_ENOT, type->compare(&diff_type_val, &(values[2]))); - assert_int_equal(LY_ENOT, type->compare(&diff_type_val, &(values[0]))); - type->free(UTEST_LYCTX, &(diff_type_val)); - /* delete values */ for (unsigned int it = 0; it < sizeof(val_init) / sizeof(val_init[0]); it++) { type->free(UTEST_LYCTX, &(values[it])); diff --git a/tests/utests/types/identityref.c b/tests/utests/types/identityref.c index cdfe057..107164d 100644 --- a/tests/utests/types/identityref.c +++ b/tests/utests/types/identityref.c @@ -27,15 +27,6 @@ NODES \ "}\n" -#define TEST_SUCCESS_XML(MOD_NAME, NAMESPACES, NODE_NAME, DATA, TYPE, ...) \ - { \ - struct lyd_node *tree; \ - const char *data = "<" NODE_NAME " xmlns=\"urn:tests:" MOD_NAME "\" " NAMESPACES ">" DATA "</" NODE_NAME ">"; \ - CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree); \ - CHECK_LYD_NODE_TERM((struct lyd_node_term *)tree, 0, 0, 0, 0, 1, TYPE, __VA_ARGS__); \ - lyd_free_all(tree); \ - } - #define TEST_ERROR_XML(MOD_NAME, NAMESPACES, NODE_NAME, DATA) \ {\ struct lyd_node *tree; \ @@ -64,21 +55,44 @@ static void test_data_xml(void **state) { const char *schema, *schema2; + struct lyd_node *tree; + const char *data; /* xml test */ - schema = MODULE_CREATE_YANG("ident-base", "identity ident-base;" - "identity ident-imp {base ident-base;}"); + schema = "module ident-base {" + " yang-version 1.1;" + " namespace \"urn:tests:ident-base\";" + " prefix ib;" + " identity ident-base;" + " identity ident-imp {base ident-base;}" + "}"; UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL); - schema2 = MODULE_CREATE_YANG("defs", "import ident-base {prefix ib;}" - "identity ident1 {base ib:ident-base;}" - "leaf l1 {type identityref {base ib:ident-base;}}"); + schema2 = "module defs {" + " yang-version 1.1;" + " namespace \"urn:tests:defs\";" + " prefix d;" + " import ident-base {prefix ib;}" + " identity ident1 {base ib:ident-base;}" + " leaf l1 {type identityref {base ib:ident-base;}}" + "}"; UTEST_ADD_MODULE(schema2, LYS_IN_YANG, NULL, NULL); - TEST_SUCCESS_XML("defs", "", "l1", "ident1", IDENT, "defs:ident1", "ident1"); - - TEST_SUCCESS_XML("defs", "xmlns:i=\"urn:tests:ident-base\"", "l1", "i:ident-imp", IDENT, "ident-base:ident-imp", - "ident-imp"); + /* local ident, XML/JSON print */ + data = "<l1 xmlns=\"urn:tests:defs\">ident1</l1>"; + CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree); + CHECK_LYD_NODE_TERM((struct lyd_node_term *)tree, 0, 0, 0, 0, 1, IDENT, "defs:ident1", "ident1"); + CHECK_LYD_STRING_PARAM(tree, data, LYD_XML, LYD_PRINT_SHRINK); + CHECK_LYD_STRING_PARAM(tree, "{\"defs:l1\":\"ident1\"}", LYD_JSON, LYD_PRINT_SHRINK); + lyd_free_all(tree); + + /* foreign ident, XML/JSON print */ + data = "<l1 xmlns=\"urn:tests:defs\" xmlns:ib=\"urn:tests:ident-base\">ib:ident-imp</l1>"; + CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree); + CHECK_LYD_NODE_TERM((struct lyd_node_term *)tree, 0, 0, 0, 0, 1, IDENT, "ident-base:ident-imp", "ident-imp"); + CHECK_LYD_STRING_PARAM(tree, data, LYD_XML, LYD_PRINT_SHRINK); + CHECK_LYD_STRING_PARAM(tree, "{\"defs:l1\":\"ident-base:ident-imp\"}", LYD_JSON, LYD_PRINT_SHRINK); + lyd_free_all(tree); /* invalid value */ TEST_ERROR_XML("defs", "", "l1", "fast-ethernet"); diff --git a/tests/utests/types/instanceid.c b/tests/utests/types/instanceid.c index 06c8622..3126f61 100644 --- a/tests/utests/types/instanceid.c +++ b/tests/utests/types/instanceid.c @@ -79,12 +79,12 @@ static void test_data_xml(void **state) { const char *schema, *schema2; - const enum ly_path_pred_type val1[] = {LY_PATH_PREDTYPE_NONE, LY_PATH_PREDTYPE_NONE}; - const enum ly_path_pred_type val2[] = {LY_PATH_PREDTYPE_LIST, LY_PATH_PREDTYPE_NONE}; + const enum ly_path_pred_type val1[] = {0, 0}; + const enum ly_path_pred_type val2[] = {LY_PATH_PREDTYPE_LIST, 0}; const enum ly_path_pred_type val3[] = {LY_PATH_PREDTYPE_LEAFLIST}; - const enum ly_path_pred_type val4[] = {LY_PATH_PREDTYPE_LIST, LY_PATH_PREDTYPE_NONE}; - const enum ly_path_pred_type val5[] = {LY_PATH_PREDTYPE_LIST, LY_PATH_PREDTYPE_NONE}; - const enum ly_path_pred_type val6[] = {LY_PATH_PREDTYPE_LIST, LY_PATH_PREDTYPE_NONE}; + const enum ly_path_pred_type val4[] = {LY_PATH_PREDTYPE_LIST, 0}; + const enum ly_path_pred_type val5[] = {LY_PATH_PREDTYPE_LIST, 0}; + const enum ly_path_pred_type val6[] = {LY_PATH_PREDTYPE_LIST, 0}; /* xml test */ schema = MODULE_CREATE_YANG("mod", "container cont {leaf l2 {type empty;}}"); @@ -136,22 +136,23 @@ test_data_xml(void **state) TEST_ERROR_XML2("<list xmlns=\"urn:tests:defs\"><id>a</id></list>" "<list xmlns=\"urn:tests:defs\"><id>b</id><value>x</value></list>", "defs", "xmlns:xdf=\"urn:tests:defs\"", "xdf:l1", "/xdf:list[2]/xdf:value", LY_EVALID); - CHECK_LOG_CTX("Invalid instance-identifier \"/xdf:list[2]/xdf:value\" value - semantic error.", + CHECK_LOG_CTX("Invalid instance-identifier \"/xdf:list[2]/xdf:value\" value - semantic error: " + "Positional predicate defined for configuration list \"list\" in path.", "Schema location \"/defs:l1\", line number 1."); TEST_ERROR_XML2("", "defs", "xmlns:xdf=\"urn:tests:defs\"", "xdf:l1", "/t:cont/t:1l", LY_EVALID); - CHECK_LOG_CTX("Invalid instance-identifier \"/t:cont/t:1l\" value - syntax error.", + CHECK_LOG_CTX("Invalid instance-identifier \"/t:cont/t:1l\" value - syntax error: Invalid character 't'[9] of expression '/t:cont/t:1l'.", "Schema location \"/defs:l1\", line number 1."); TEST_ERROR_XML2("", "defs", "xmlns:xdf=\"urn:tests:defs\"", "xdf:l1", "/t:cont:t:1l", LY_EVALID); - CHECK_LOG_CTX("Invalid instance-identifier \"/t:cont:t:1l\" value - syntax error.", + CHECK_LOG_CTX("Invalid instance-identifier \"/t:cont:t:1l\" value - syntax error: Invalid character ':'[8] of expression '/t:cont:t:1l'.", "Schema location \"/defs:l1\", line number 1."); TEST_ERROR_XML2("", "defs", "xmlns:xdf=\"urn:tests:defs\"", "xdf:l1", "/xdf:cont/xdf:invalid/xdf:path", LY_EVALID); - CHECK_LOG_CTX("Invalid instance-identifier \"/xdf:cont/xdf:invalid/xdf:path\" value - semantic error.", + CHECK_LOG_CTX("Invalid instance-identifier \"/xdf:cont/xdf:invalid/xdf:path\" value - semantic error: Not found node \"invalid\" in path.", "Schema location \"/defs:l1\", line number 1."); /* non-existing instances, instance-identifier is here in JSON format because it is already in internal @@ -190,72 +191,72 @@ test_data_xml(void **state) /* more errors */ TEST_ERROR_XML2("<llist xmlns=\"urn:tests:defs\">x</llist>", "defs", "xmlns:t=\"urn:tests:defs\"", "t:l1", "/t:llist[1", LY_EVALID); - CHECK_LOG_CTX("Invalid instance-identifier \"/t:llist[1\" value - syntax error.", + CHECK_LOG_CTX("Invalid instance-identifier \"/t:llist[1\" value - syntax error: Unexpected XPath expression end.", "Schema location \"/defs:l1\", line number 1."); TEST_ERROR_XML2("<cont xmlns=\"urn:tests:mod\"/>", "defs", "xmlns:m=\"urn:tests:mod\"", "l1", "/m:cont[1]", LY_EVALID); - CHECK_LOG_CTX("Invalid instance-identifier \"/m:cont[1]\" value - semantic error.", + CHECK_LOG_CTX("Invalid instance-identifier \"/m:cont[1]\" value - semantic error: Positional predicate defined for container \"cont\" in path.", "Schema location \"/defs:l1\", line number 1."); TEST_ERROR_XML2("<cont xmlns=\"urn:tests:mod\"/>", "defs", "xmlns:m=\"urn:tests:mod\"", "l1", "[1]", LY_EVALID); - CHECK_LOG_CTX("Invalid instance-identifier \"[1]\" value - syntax error.", + CHECK_LOG_CTX("Invalid instance-identifier \"[1]\" value - syntax error: Unexpected XPath token \"[\" (\"[1]\"), expected \"Operator(Path)\".", "Schema location \"/defs:l1\", line number 1."); TEST_ERROR_XML2("<cont xmlns=\"urn:tests:mod\"><l2/></cont>", "defs", "xmlns:m=\"urn:tests:mod\"", "l1", "/m:cont/m:l2[l2='1']", LY_EVALID); - CHECK_LOG_CTX("Invalid instance-identifier \"/m:cont/m:l2[l2='1']\" value - syntax error.", + CHECK_LOG_CTX("Invalid instance-identifier \"/m:cont/m:l2[l2='1']\" value - syntax error: Prefix missing for \"l2\" in path.", "Schema location \"/defs:l1\", line number 1."); TEST_ERROR_XML2("<cont xmlns=\"urn:tests:mod\"><l2/></cont>", "defs", "xmlns:m=\"urn:tests:mod\"", "l1", "/m:cont/m:l2[m:l2='1']", LY_EVALID); - CHECK_LOG_CTX("Invalid instance-identifier \"/m:cont/m:l2[m:l2='1']\" value - semantic error.", + CHECK_LOG_CTX("Invalid instance-identifier \"/m:cont/m:l2[m:l2='1']\" value - semantic error: List predicate defined for leaf \"l2\" in path.", "Schema location \"/defs:l1\", line number 1."); TEST_ERROR_XML2("<llist xmlns=\"urn:tests:defs\">1</llist><llist xmlns=\"urn:tests:defs\">2</llist>", "defs", "xmlns:t=\"urn:tests:defs\"", "t:l1", "/t:llist[4]", LY_EVALID); - CHECK_LOG_CTX("Invalid instance-identifier \"/t:llist[4]\" value - semantic error.", + CHECK_LOG_CTX("Invalid instance-identifier \"/t:llist[4]\" value - semantic error: Positional predicate defined for configuration leaf-list \"llist\" in path.", "Schema location \"/defs:l1\", line number 1."); TEST_ERROR_XML2("", "defs", "xmlns:xdf=\"urn:tests:defs\"", "xdf:l2", "/t:llist[6]", LY_EVALID); - CHECK_LOG_CTX("Invalid instance-identifier \"/t:llist[6]\" value - semantic error.", + CHECK_LOG_CTX("Invalid instance-identifier \"/t:llist[6]\" value - semantic error: No module connected with the prefix \"t\" found (prefix format XML prefixes).", "Schema location \"/defs:l2\", line number 1."); TEST_ERROR_XML2("<list xmlns=\"urn:tests:defs\"><id>1</id><value>x</value></list>", "defs", "xmlns:xdf=\"urn:tests:defs\"", "xdf:l2", "/xdf:list[xdf:value='x']", LY_EVALID); - CHECK_LOG_CTX("Invalid instance-identifier \"/xdf:list[xdf:value='x']\" value - semantic error.", + CHECK_LOG_CTX("Invalid instance-identifier \"/xdf:list[xdf:value='x']\" value - semantic error: Key expected instead of leaf \"value\" in path.", "Schema location \"/defs:l2\", line number 1."); TEST_ERROR_XML2("", "defs", "xmlns:xdf=\"urn:tests:defs\"", "xdf:l2", "/xdf:list[.='x']", LY_EVALID); - CHECK_LOG_CTX("Invalid instance-identifier \"/xdf:list[.='x']\" value - semantic error.", + CHECK_LOG_CTX("Invalid instance-identifier \"/xdf:list[.='x']\" value - semantic error: Leaf-list predicate defined for list \"list\" in path.", "Schema location \"/defs:l2\", line number 1."); TEST_ERROR_XML2("<llist xmlns=\"urn:tests:defs\">1</llist>", "defs", "xmlns:t=\"urn:tests:defs\"", "t:l1", "/t:llist[.='x']", LY_EVALID); - CHECK_LOG_CTX("Invalid instance-identifier \"/t:llist[.='x']\" value - semantic error.", + CHECK_LOG_CTX("Invalid instance-identifier \"/t:llist[.='x']\" value - semantic error: Invalid type uint32 value \"x\".", "Schema location \"/defs:l1\", line number 1."); TEST_ERROR_XML2("", "defs", "xmlns:xdf=\"urn:tests:defs\"", "xdf:l2", "/t:llist[1][2]", LY_EVALID); - CHECK_LOG_CTX("Invalid instance-identifier \"/t:llist[1][2]\" value - syntax error.", + CHECK_LOG_CTX("Invalid instance-identifier \"/t:llist[1][2]\" value - syntax error: Unparsed characters \"[2]\" left at the end of path.", "Schema location \"/defs:l2\", line number 1."); TEST_ERROR_XML2("", "defs", "xmlns:xdf=\"urn:tests:defs\"", "xdf:l2", "/t:llist[.='a'][.='b']", LY_EVALID); - CHECK_LOG_CTX("Invalid instance-identifier \"/t:llist[.='a'][.='b']\" value - syntax error.", + CHECK_LOG_CTX("Invalid instance-identifier \"/t:llist[.='a'][.='b']\" value - syntax error: Unparsed characters \"[.='b']\" left at the end of path.", "Schema location \"/defs:l2\", line number 1."); TEST_ERROR_XML2("<list xmlns=\"urn:tests:defs\"><id>1</id><value>x</value></list>", "defs", "xmlns:xdf=\"urn:tests:defs\"", "xdf:l2", "/xdf:list[xdf:id='1'][xdf:id='2']/xdf:value", LY_EVALID); - CHECK_LOG_CTX("Invalid instance-identifier \"/xdf:list[xdf:id='1'][xdf:id='2']/xdf:value\" value - syntax error.", + CHECK_LOG_CTX("Invalid instance-identifier \"/xdf:list[xdf:id='1'][xdf:id='2']/xdf:value\" value - syntax error: Duplicate predicate key \"id\" in path.", "Schema location \"/defs:l2\", line number 1."); TEST_ERROR_XML2("", "defs", "xmlns:xdf=\"urn:tests:defs\"", "xdf:l2", "/xdf:list2[xdf:id='1']/xdf:value", LY_EVALID); - CHECK_LOG_CTX("Invalid instance-identifier \"/xdf:list2[xdf:id='1']/xdf:value\" value - semantic error.", + CHECK_LOG_CTX("Invalid instance-identifier \"/xdf:list2[xdf:id='1']/xdf:value\" value - semantic error: Predicate missing for a key of list \"list2\" in path.", "Schema location \"/defs:l2\", line number 1."); } diff --git a/tests/utests/types/int8.c b/tests/utests/types/int8.c index 7d0b9ad..198d1f7 100644 --- a/tests/utests/types/int8.c +++ b/tests/utests/types/int8.c @@ -240,22 +240,22 @@ test_schema_yang(void **state) /* TEST ERROR -60 .. 0 | 0 .. 127 */ schema = MODULE_CREATE_YANG("ERR0", "leaf port {type int8 {range \"-60 .. 0 | 0 .. 127\";}}"); UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EEXIST); - CHECK_LOG_CTX("Invalid range restriction - values are not in ascending order (0).", "/ERR0:port"); + CHECK_LOG_CTX("Invalid range restriction - values are not in ascending order (0).", "Path \"/ERR0:port\"."); /* TEST ERROR 0 .. 128 */ schema = MODULE_CREATE_YANG("ERR1", "leaf port {type int8 {range \"0 .. 128\";}}"); UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EDENIED); - CHECK_LOG_CTX("Invalid range restriction - value \"128\" does not fit the type limitations.", "/ERR1:port"); + CHECK_LOG_CTX("Invalid range restriction - value \"128\" does not fit the type limitations.", "Path \"/ERR1:port\"."); /* TEST ERROR -129 .. 126 */ schema = MODULE_CREATE_YANG("ERR2", "leaf port {type int8 {range \"-129 .. 0\";}}"); UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EDENIED); - CHECK_LOG_CTX("Invalid range restriction - value \"-129\" does not fit the type limitations.", "/ERR2:port"); + CHECK_LOG_CTX("Invalid range restriction - value \"-129\" does not fit the type limitations.", "Path \"/ERR2:port\"."); /* TEST ERROR 0 */ schema = MODULE_CREATE_YANG("ERR3", "leaf port {type int8 {range \"-129\";}}"); UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EDENIED); - CHECK_LOG_CTX("Invalid range restriction - value \"-129\" does not fit the type limitations.", "/ERR3:port"); + CHECK_LOG_CTX("Invalid range restriction - value \"-129\" does not fit the type limitations.", "Path \"/ERR3:port\"."); /* * TEST MODULE SUBTYPE @@ -374,7 +374,7 @@ test_schema_yang(void **state) "leaf my_leaf {type my_int_type {range \"min .. max\";}}"); UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID); CHECK_LOG_CTX("Invalid range restriction - the derived restriction (min .. max) is not equally or more limiting.", - "/TS_ERR0:my_leaf"); + "Path \"/TS_ERR0:my_leaf\"."); /* TEST SUBTYPE ERROR -80 .. 80 */ schema = MODULE_CREATE_YANG("TS_ERR1", @@ -382,7 +382,7 @@ test_schema_yang(void **state) " leaf my_leaf {type my_int_type {range \"-80 .. 80\";}}"); UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID); CHECK_LOG_CTX("Invalid range restriction - the derived restriction (-80 .. 80) is not equally or more limiting.", - "/TS_ERR1:my_leaf"); + "Path \"/TS_ERR1:my_leaf\"."); /* TEST SUBTYPE ERROR 0 .. max */ schema = MODULE_CREATE_YANG("TS_ERR2", @@ -390,7 +390,7 @@ test_schema_yang(void **state) "leaf my_leaf {type my_int_type {range \"0 .. max\";}}"); UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID); CHECK_LOG_CTX("Invalid range restriction - the derived restriction (0 .. max) is not equally or more limiting.", - "/TS_ERR2:my_leaf"); + "Path \"/TS_ERR2:my_leaf\"."); /* TEST SUBTYPE ERROR -2 .. 2 */ schema = MODULE_CREATE_YANG("TS_ERR3", @@ -398,7 +398,7 @@ test_schema_yang(void **state) "leaf my_leaf {type my_int_type {range \"-2 .. 2\";}}"); UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID); CHECK_LOG_CTX("Invalid range restriction - the derived restriction (-2 .. 2) is not equally or more limiting.", - "/TS_ERR3:my_leaf"); + "Path \"/TS_ERR3:my_leaf\"."); /* TEST SUBTYPE ERROR -2 .. 2 */ schema = MODULE_CREATE_YANG("TS_ERR4", @@ -406,7 +406,7 @@ test_schema_yang(void **state) "leaf my_leaf {type my_int_type {range \"-100 .. -90 | 100 .. 128\";}}"); UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EDENIED); CHECK_LOG_CTX("Invalid range restriction - value \"128\" does not fit the type limitations.", - "/TS_ERR4:my_leaf"); + "Path \"/TS_ERR4:my_leaf\"."); /* * TEST DEFAULT VALUE @@ -745,7 +745,7 @@ test_schema_yin(void **state) " <type name=\"int8\"> <range value = \"min .. 0 | 0 .. 12\"/> </type>" "</leaf>"); UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EEXIST); - CHECK_LOG_CTX("Invalid range restriction - values are not in ascending order (0).", "/TE0:port"); + CHECK_LOG_CTX("Invalid range restriction - values are not in ascending order (0).", "Path \"/TE0:port\"."); /* TEST ERROR 0 .. 128 */ schema = MODULE_CREATE_YIN("TE1", @@ -753,7 +753,7 @@ test_schema_yin(void **state) " <type name=\"int8\"> <range value = \"0 .. 128\"/> </type>" "</leaf>"); UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EDENIED); - CHECK_LOG_CTX("Invalid range restriction - value \"128\" does not fit the type limitations.", "/TE1:port"); + CHECK_LOG_CTX("Invalid range restriction - value \"128\" does not fit the type limitations.", "Path \"/TE1:port\"."); /* TEST ERROR -129 .. 126 */ schema = MODULE_CREATE_YIN("TE2", @@ -761,7 +761,7 @@ test_schema_yin(void **state) " <type name=\"int8\"> <range value =\"-129 .. 126\"/> </type>" "</leaf>"); UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EDENIED); - CHECK_LOG_CTX("Invalid range restriction - value \"-129\" does not fit the type limitations.", "/TE2:port"); + CHECK_LOG_CTX("Invalid range restriction - value \"-129\" does not fit the type limitations.", "Path \"/TE2:port\"."); /* TEST YIN */ schema = MODULE_CREATE_YIN("TS0", @@ -817,7 +817,7 @@ test_schema_yin(void **state) "</leaf>"); UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID); CHECK_LOG_CTX("Invalid range restriction - the derived restriction (min .. max) is not equally or more limiting.", - "/TS_ERR1:port"); + "Path \"/TS_ERR1:port\"."); /* TEST ERROR */ schema = MODULE_CREATE_YIN("TS_ERR2", @@ -829,7 +829,7 @@ test_schema_yin(void **state) "</leaf>"); UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID); CHECK_LOG_CTX("Invalid range restriction - the derived restriction (5 .. 11) is not equally or more limiting.", - "/TS_ERR2:port"); + "Path \"/TS_ERR2:port\"."); /* TEST DEFAULT VALUE */ schema = MODULE_CREATE_YIN("DF0", @@ -1243,8 +1243,14 @@ test_data_json(void **state) TEST_SUCCESS_JSON("T0", "127", INT8, "127", 127); /* leading zeros */ TEST_ERROR_JSON("T0", "015"); + CHECK_LOG_CTX("Invalid character sequence \"15}\", expected a JSON object-end or next item.", + "Line number 1."); TEST_ERROR_JSON("T0", "-015"); + CHECK_LOG_CTX("Invalid character sequence \"15}\", expected a JSON object-end or next item.", + "Line number 1."); TEST_ERROR_JSON("defs", "+50"); + CHECK_LOG_CTX("Invalid character sequence \"+50}\", expected a JSON value.", + "Line number 1."); TEST_ERROR_JSON("T0", "-129"); CHECK_LOG_CTX("Value \"-129\" is out of type int8 min/max bounds.", "Schema location \"/T0:port\", line number 1."); @@ -1510,6 +1516,7 @@ test_plugin_store(void **state) ly_ret = type->store(UTEST_LYCTX, &lysc_type_test, val_text, strlen(val_text), 0, LY_VALUE_XML, NULL, LYD_VALHINT_HEXNUM, NULL, &value, NULL, &err); assert_int_equal(LY_EINT, ly_ret); + UTEST_LOG_CTX_CLEAN; /* * ERROR TESTS @@ -1541,6 +1548,8 @@ test_plugin_store(void **state) 0, LY_VALUE_XML, NULL, LYD_VALHINT_DECNUM, NULL, &value, NULL, &err); assert_int_equal(LY_EVALID, ly_ret); ly_err_free(err); + + UTEST_LOG_CTX_CLEAN; } static void diff --git a/tests/utests/types/leafref.c b/tests/utests/types/leafref.c index c8d0cb6..21e91cd 100644 --- a/tests/utests/types/leafref.c +++ b/tests/utests/types/leafref.c @@ -209,6 +209,70 @@ test_plugin_lyb(void **state) TEST_SUCCESS_LYB("lyb", "lst", "key_str", "lref", "key_str"); } +static void +test_data_xpath_json(void **state) +{ + const char *schema, *data; + struct lyd_node *tree; + + ly_ctx_set_options(UTEST_LYCTX, LY_CTX_LEAFREF_EXTENDED); + + /* json xpath test */ + schema = MODULE_CREATE_YANG("xp_test", + "list l1 {key t1;" + "leaf t1 {type uint8;}" + "list l2 {key t2;" + "leaf t2 {type uint8;}" + "leaf-list l3 {type uint8;}" + "}}" + "leaf r1 {type leafref {path \"../l1/t1\";}}" + "leaf r2 {type leafref {path \"deref(../r1)/../l2/t2\";}}" + "leaf r3 {type leafref {path \"deref(../r2)/../l3\";}}"); + + UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL); + + data = "{" + " \"xp_test:l1\":[{\"t1\": 1,\"l2\":[{\"t2\": 2,\"l3\":[3]}]}]," + " \"xp_test:r1\": 1," + " \"xp_test:r2\": 2," + " \"xp_test:r3\": 3" + "}"; + CHECK_PARSE_LYD_PARAM(data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree); + lyd_free_all(tree); +} + +static void +test_xpath_invalid_schema(void **state) +{ + const char *schema1, *schema2; + + ly_ctx_set_options(UTEST_LYCTX, LY_CTX_LEAFREF_EXTENDED); + schema1 = MODULE_CREATE_YANG("xp_test", + "list l1 {key t1;" + "leaf t1 {type uint8;}" + "list l2 {key t2;" + "leaf t2 {type uint8;}" + "leaf-list l3 {type uint8;}" + "}}" + "leaf r1 {type leafref {path \"deref(../l1)/../l2/t2\";}}"); + + UTEST_INVALID_MODULE(schema1, LYS_IN_YANG, NULL, LY_EVALID) + CHECK_LOG_CTX("The deref function target node \"l1\" is not leaf nor leaflist", "Schema location \"/xp_test:r1\"."); + + schema2 = MODULE_CREATE_YANG("xp_test", + "list l1 {key t1;" + "leaf t1 {type uint8;}" + "list l2 {key t2;" + "leaf t2 {type uint8;}" + "leaf-list l3 {type uint8;}" + "}}" + "leaf r1 {type uint8;}" + "leaf r2 {type leafref {path \"deref(../r1)/../l2/t2\";}}"); + + UTEST_INVALID_MODULE(schema2, LYS_IN_YANG, NULL, LY_EVALID) + CHECK_LOG_CTX("The deref function target node \"r1\" is not leafref", "Schema location \"/xp_test:r2\"."); +} + int main(void) { @@ -216,6 +280,8 @@ main(void) UTEST(test_data_xml), UTEST(test_data_json), UTEST(test_plugin_lyb), + UTEST(test_data_xpath_json), + UTEST(test_xpath_invalid_schema) }; return cmocka_run_group_tests(tests, NULL, NULL); diff --git a/tests/utests/types/string.c b/tests/utests/types/string.c index d232e9d..ce5ae8d 100644 --- a/tests/utests/types/string.c +++ b/tests/utests/types/string.c @@ -200,15 +200,15 @@ test_schema_yang(void **state) /* ERROR TESTS NEGATIVE VALUE */ schema = MODULE_CREATE_YANG("ERR0", "leaf port {type string {length \"-1 .. 20\";}}"); UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EDENIED); - CHECK_LOG_CTX("Invalid length restriction - value \"-1\" does not fit the type limitations.", "/ERR0:port"); + CHECK_LOG_CTX("Invalid length restriction - value \"-1\" does not fit the type limitations.", "Path \"/ERR0:port\"."); schema = MODULE_CREATE_YANG("ERR1", "leaf port {type string {length \"100 .. 18446744073709551616\";}}"); UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID); - CHECK_LOG_CTX("Invalid length restriction - invalid value \"18446744073709551616\".", "/ERR1:port"); + CHECK_LOG_CTX("Invalid length restriction - invalid value \"18446744073709551616\".", "Path \"/ERR1:port\"."); schema = MODULE_CREATE_YANG("ERR2", "leaf port {type string {length \"10 .. 20 | 20 .. 30\";}}"); UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EEXIST); - CHECK_LOG_CTX("Invalid length restriction - values are not in ascending order (20).", "/ERR2:port"); + CHECK_LOG_CTX("Invalid length restriction - values are not in ascending order (20).", "Path \"/ERR2:port\"."); schema = MODULE_CREATE_YANG("ERR3", "typedef my_type {" @@ -216,7 +216,7 @@ test_schema_yang(void **state) "}" "leaf port {type my_type {length \"-1 .. 15\";}}"); UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EDENIED); - CHECK_LOG_CTX("Invalid length restriction - value \"-1\" does not fit the type limitations.", "/ERR3:port"); + CHECK_LOG_CTX("Invalid length restriction - value \"-1\" does not fit the type limitations.", "Path \"/ERR3:port\"."); /* * PATTERN @@ -286,7 +286,7 @@ test_schema_yang(void **state) "}}"); UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID); CHECK_LOG_CTX("Regular expression \"[a-zA-Z_[a-zA-Z0-9\\-_.*\" is not valid (\"\": missing terminating ] for character class).", - "/TPATTERN_ERR_0:port"); + "Path \"/TPATTERN_ERR_0:port\"."); schema = MODULE_CREATE_YANG("TDEFAULT_0", "typedef my_type {" @@ -323,14 +323,14 @@ test_schema_yang(void **state) "}}"); UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID); CHECK_LOG_CTX("Regular expression \"\\[a]b\" is not valid (\"]b\": character group doesn't begin with '[').", - "/TPATTERN_BC_ERR_1:port"); + "Path \"/TPATTERN_BC_ERR_1:port\"."); schema = MODULE_CREATE_YANG("TPATTERN_BC_ERR_2", "leaf port {type string {" "pattern \"\\\\[a]b\";" /* pattern "\\[a]b"; */ "}}"); UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID); CHECK_LOG_CTX("Regular expression \"\\[a]b\" is not valid (\"]b\": character group doesn't begin with '[').", - "/TPATTERN_BC_ERR_2:port"); + "Path \"/TPATTERN_BC_ERR_2:port\"."); /* PATTERN AND LENGTH */ schema = MODULE_CREATE_YANG("TPL_0", @@ -467,26 +467,26 @@ test_schema_yin(void **state) schema = MODULE_CREATE_YIN("ERR0", "<leaf name=\"port\"> <type name=\"string\">" "<length value =\"-1 .. 20\"/> </type></leaf>"); UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EDENIED); - CHECK_LOG_CTX("Invalid length restriction - value \"-1\" does not fit the type limitations.", "/ERR0:port"); + CHECK_LOG_CTX("Invalid length restriction - value \"-1\" does not fit the type limitations.", "Path \"/ERR0:port\"."); schema = MODULE_CREATE_YIN("ERR1", "<leaf name=\"port\"> <type name=\"string\">" "<length value=\"100 .. 18446744073709551616\"/>" "</type> </leaf>"); UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID); - CHECK_LOG_CTX("Invalid length restriction - invalid value \"18446744073709551616\".", "/ERR1:port"); + CHECK_LOG_CTX("Invalid length restriction - invalid value \"18446744073709551616\".", "Path \"/ERR1:port\"."); schema = MODULE_CREATE_YIN("ERR2", "<leaf name=\"port\">" "<type name=\"string\"> <length value=\"10 .. 20 | 20 .. 30\"/>" "</type> </leaf>"); UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EEXIST); - CHECK_LOG_CTX("Invalid length restriction - values are not in ascending order (20).", "/ERR2:port"); + CHECK_LOG_CTX("Invalid length restriction - values are not in ascending order (20).", "Path \"/ERR2:port\"."); schema = MODULE_CREATE_YIN("ERR3", "<typedef name=\"my_type\"> <type name=\"string\"/> </typedef>" "<leaf name=\"port\"> <type name=\"my_type\"> <length value=\"-1 .. 15\"/>" "</type> </leaf>"); UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EDENIED); - CHECK_LOG_CTX("Invalid length restriction - value \"-1\" does not fit the type limitations.", "/ERR3:port"); + CHECK_LOG_CTX("Invalid length restriction - value \"-1\" does not fit the type limitations.", "Path \"/ERR3:port\"."); /* * PATTERN @@ -557,7 +557,7 @@ test_schema_yin(void **state) "</type> </leaf>"); UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID); CHECK_LOG_CTX("Regular expression \"[a-zA-Z_][a-zA-Z0-9\\-_.*\" is not valid (\"\": missing terminating ] for character class).", - "/TPATTERN_ERR_0:port"); + "Path \"/TPATTERN_ERR_0:port\"."); /* * DEFAUT VALUE @@ -618,16 +618,8 @@ test_schema_yin(void **state) "</typedef>" "<leaf name=\"port\"> <type name=\"my_type\"/> </leaf>"); UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID); - - schema = MODULE_CREATE_YIN("TDEFAULT_2", - "<typedef name=\"my_type\">" - " <type name=\"string\">" - " <length value=\"2\"/>" - " </type>" - " <default value=\"a1i-j<\"/>" - "</typedef>" - "<leaf name=\"port\"> <type name=\"my_type\"/> </leaf>"); - UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID); + CHECK_LOG_CTX("Invalid default - value does not fit the type (Unsatisfied length - string \"a1i-j<\" length is not allowed.).", + "Schema location \"/TDEFAULT_2:port\"."); schema = MODULE_CREATE_YIN("TDEFAULT_3", "<typedef name=\"my_type\">" @@ -636,6 +628,8 @@ test_schema_yin(void **state) "</type> </typedef>" "<leaf name=\"port\"><type name=\"my_type\"> <pattern value=\"bcd.*\"/> </type></leaf>"); UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID); + CHECK_LOG_CTX("Invalid default - value does not fit the type (Unsatisfied pattern - \"a1i-j<\" does not conform to \"bcd.*\".).", + "Schema location \"/TDEFAULT_3:port\"."); } @@ -874,7 +868,7 @@ test_data_json(void **state) CHECK_LOG_CTX("Invalid character reference \"\\f\" (0x0000000c).", "Line number 1."); TEST_ERROR_JSON("T0", "\""); - CHECK_LOG_CTX("Unexpected character \"\"\" after JSON string.", "Line number 1."); + CHECK_LOG_CTX("Invalid character sequence \"\"}\", expected a JSON object-end or next item.", "Line number 1."); TEST_ERROR_JSON("T0", "aabb \\x"); CHECK_LOG_CTX("Invalid character escape sequence \\x.", "Line number 1."); @@ -1258,26 +1252,6 @@ test_plugin_compare(void **state) assert_int_equal(LY_ENOT, type->compare(&diff_type_val, &(values[1]))); type->free(UTEST_LYCTX, &(diff_type_val)); - /* original type */ - diff_type_text = "hi"; - diff_type = ((struct lysc_node_leaf *) mod->compiled->data->next->next)->type; - ly_ret = diff_type->plugin->store(UTEST_LYCTX, diff_type, diff_type_text, strlen(diff_type_text), - 0, LY_VALUE_XML, NULL, LYD_VALHINT_STRING, NULL, &diff_type_val, NULL, &err); - assert_int_equal(LY_SUCCESS, ly_ret); - assert_int_equal(LY_ENOT, type->compare(&diff_type_val, &(values[0]))); - assert_int_equal(LY_ENOT, type->compare(&diff_type_val, &(values[1]))); - type->free(UTEST_LYCTX, &(diff_type_val)); - - /* different type (UINT8) */ - diff_type_text = "20"; - diff_type = ((struct lysc_node_leaf *) mod->compiled->data->next->next->next)->type; - ly_ret = diff_type->plugin->store(UTEST_LYCTX, diff_type, diff_type_text, strlen(diff_type_text), - 0, LY_VALUE_XML, NULL, LYD_VALHINT_DECNUM, NULL, &diff_type_val, NULL, &err); - assert_int_equal(LY_SUCCESS, ly_ret); - assert_int_equal(LY_ENOT, type->compare(&diff_type_val, &(values[0]))); - assert_int_equal(LY_ENOT, type->compare(&diff_type_val, &(values[1]))); - type->free(UTEST_LYCTX, &(diff_type_val)); - /* delete values */ for (int unsigned it = 0; it < sizeof(val_init) / sizeof(val_init[0]); it++) { type->free(UTEST_LYCTX, &(values[it])); diff --git a/tests/utests/types/union.c b/tests/utests/types/union.c index 9a0705a..d23cbf1 100644 --- a/tests/utests/types/union.c +++ b/tests/utests/types/union.c @@ -104,11 +104,34 @@ test_data_xml(void **state) /* invalid value */ TEST_ERROR_XML2("", "defs", "", "un1", "123456789012345678901", LY_EVALID); - CHECK_LOG_CTX("Invalid union value \"123456789012345678901\" - no matching subtype found.", + CHECK_LOG_CTX("Invalid union value \"123456789012345678901\" - no matching subtype found:\n" + " libyang 2 - leafref, version 1: Invalid type int8 value \"123456789012345678901\".\n" + " libyang 2 - leafref, version 1: Invalid type int64 value \"123456789012345678901\".\n" + " libyang 2 - identityref, version 1: Invalid identityref \"123456789012345678901\" value - identity not found in module \"defs\".\n" + " libyang 2 - instance-identifier, version 1: Invalid instance-identifier \"123456789012345678901\" value - syntax error.\n" + " libyang 2 - string, version 1: Unsatisfied length - string \"123456789012345678901\" length is not allowed.\n", "Schema location \"/defs:un1\", line number 1."); } static void +test_data_json(void **state) +{ + const char *schema, *data; + struct lyd_node *tree; + + /* xml test */ + schema = MODULE_CREATE_YANG("defs", "leaf un21 {type union {type uint8; type string;}}" + "leaf un22 {type union {type uint16; type string;}}" + "leaf un2 {type union {type leafref {path /un21; require-instance false;} type leafref {path /un22; require-instance false;}}}"); + UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL); + + data = "{\"defs:un2\":\"str\"}"; + CHECK_PARSE_LYD_PARAM(data, LYD_JSON, LYD_PARSE_STRICT, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree); + CHECK_LYD_STRING_PARAM(tree, data, LYD_JSON, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS); + lyd_free_all(tree); +} + +static void test_plugin_lyb(void **state) { const char *schema; @@ -124,12 +147,60 @@ test_plugin_lyb(void **state) TEST_SUCCESS_LYB("lyb", "un1", ""); } +static void +test_validation(void **state) +{ + const char *schema, *data; + struct lyd_node *tree; + char *out; + + schema = MODULE_CREATE_YANG("val", + "leaf l1 {\n" + " type union {\n" + " type uint32 {\n" + " range \"0..1048575\";\n" + " }\n" + " type enumeration {\n" + " enum auto;\n" + " }\n" + " }\n" + "}\n" + "leaf int8 {type int8 {range 10..20;}}\n" + "leaf l2 {\n" + " type union {\n" + " type leafref {path /int8; require-instance true;}\n" + " type string;\n" + " }\n" + "}\n"); + UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL); + + /* parse from LYB */ + data = "<l1 xmlns=\"urn:tests:val\">auto</l1><int8 xmlns=\"urn:tests:val\">15</int8><l2 xmlns=\"urn:tests:val\">15</l2>"; + CHECK_PARSE_LYD_PARAM(data, LYD_XML, LYD_PARSE_STRICT, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree); + assert_int_equal(LY_SUCCESS, lyd_print_mem(&out, tree, LYD_LYB, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS)); + lyd_free_all(tree); + CHECK_PARSE_LYD_PARAM(out, LYD_LYB, LYD_PARSE_STRICT, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree); + free(out); + + /* validate */ + assert_int_equal(LY_SUCCESS, lyd_validate_all(&tree, NULL, LYD_VALIDATE_PRESENT, NULL)); + + /* print and compare */ + assert_int_equal(LY_SUCCESS, lyd_print_mem(&out, tree, LYD_XML, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS)); + assert_string_equal(out, data); + + free(out); + lyd_free_all(tree); +} + int main(void) { const struct CMUnitTest tests[] = { UTEST(test_data_xml), + UTEST(test_data_json), UTEST(test_plugin_lyb), + UTEST(test_validation), }; return cmocka_run_group_tests(tests, NULL, NULL); diff --git a/tests/utests/types/yang_types.c b/tests/utests/types/yang_types.c index 6ce7671..0f78455 100644 --- a/tests/utests/types/yang_types.c +++ b/tests/utests/types/yang_types.c @@ -3,7 +3,7 @@ * @author Michal Vaško <mvasko@cesnet.cz> * @brief test for ietf-yang-types values * - * Copyright (c) 2021 CESNET, z.s.p.o. + * Copyright (c) 2021 - 2023 CESNET, z.s.p.o. * * This source code is licensed under BSD 3-Clause License (the "License"). * You may not use this file except in compliance with the License. @@ -52,11 +52,11 @@ lyd_free_all(tree); \ } -#define TEST_ERROR_XML(MOD_NAME, NODE_NAME, DATA) \ +#define TEST_ERROR_XML(MOD_NAME, NODE_NAME, DATA, RET) \ {\ struct lyd_node *tree; \ const char *data = "<" NODE_NAME " xmlns=\"urn:tests:" MOD_NAME "\">" DATA "</" NODE_NAME ">"; \ - CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree); \ + CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, RET, tree); \ assert_null(tree); \ } @@ -84,14 +84,15 @@ test_data_xml(void **state) /* xml test */ schema = MODULE_CREATE_YANG("a", "leaf l {type yang:date-and-time;}" - "leaf l2 {type yang:xpath1.0;}"); + "leaf l21 {type yang:hex-string;}" + "leaf l22 {type yang:uuid;}" + "leaf l3 {type yang:xpath1.0;}"); UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL); schema = MODULE_CREATE_YANG("b", ""); UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL); /* date-and-time */ -#if defined (HAVE_TM_GMTOFF) && defined (HAVE_TIME_H_TIMEZONE) TEST_SUCCESS_XML("a", "l", "2005-05-25T23:15:15.88888Z", STRING, "2005-05-25T21:15:15.88888-02:00"); TEST_SUCCESS_XML("a", "l", "2005-05-31T23:15:15-08:59", STRING, "2005-06-01T06:14:15-02:00"); TEST_SUCCESS_XML("a", "l", "2005-05-31T23:15:15-23:00", STRING, "2005-06-01T20:15:15-02:00"); @@ -105,51 +106,44 @@ test_data_xml(void **state) /* fractional hours */ TEST_SUCCESS_XML("a", "l", "2005-05-25T23:15:15.88888+04:30", STRING, "2005-05-25T16:45:15.88888-02:00"); -#else - /* Tests run with a TZ offset of +02:00, but this platform cannot represent that in time_t, - * so libyang always returns unspecified TZ. */ - TEST_SUCCESS_XML("a", "l", "2005-05-25T23:15:15.88888Z", STRING, "2005-05-25T23:15:15.88888-00:00"); - TEST_SUCCESS_XML("a", "l", "2005-05-31T23:15:15-08:59", STRING, "2005-06-01T08:14:15-00:00"); - TEST_SUCCESS_XML("a", "l", "2005-05-31T23:15:15-23:00", STRING, "2005-06-01T22:15:15-00:00"); - - /* test 1 second before epoch (mktime returns -1, but it is a correct value), with and without DST */ - TEST_SUCCESS_XML("a", "l", "1970-01-01T00:59:59-02:00", STRING, "1970-01-01T02:59:59-00:00"); - TEST_SUCCESS_XML("a", "l", "1969-12-31T23:59:59-02:00", STRING, "1970-01-01T01:59:59-00:00"); - - /* canonize */ - TEST_SUCCESS_XML("a", "l", "2005-02-29T23:15:15-02:00", STRING, "2005-03-02T01:15:15-00:00"); - - /* fractional hours */ - TEST_SUCCESS_XML("a", "l", "2005-05-25T23:15:15.88888+04:30", STRING, "2005-05-25T18:45:15.88888-00:00"); -#endif /* unknown timezone -- timezone conversion MUST NOT happen */ TEST_SUCCESS_XML("a", "l", "2017-02-01T00:00:00-00:00", STRING, "2017-02-01T00:00:00-00:00"); TEST_SUCCESS_XML("a", "l", "2021-02-29T00:00:00-00:00", STRING, "2021-03-01T00:00:00-00:00"); - TEST_ERROR_XML("a", "l", "2005-05-31T23:15:15.-08:00"); + TEST_ERROR_XML("a", "l", "2005-05-31T23:15:15.-08:00", LY_EVALID); CHECK_LOG_CTX("Unsatisfied pattern - \"2005-05-31T23:15:15.-08:00\" does not conform to " "\"\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?(Z|[\\+\\-]\\d{2}:\\d{2})\".", "Schema location \"/a:l\", line number 1."); + TEST_ERROR_XML("a", "l", "2023-16-15T20:13:01+01:00", LY_EINVAL); + CHECK_LOG_CTX("Invalid date-and-time month \"15\".", "Schema location \"/a:l\", line number 1."); + + TEST_ERROR_XML("a", "l", "2023-10-15T20:13:01+95:00", LY_EINVAL); + CHECK_LOG_CTX("Invalid date-and-time timezone hour \"95\".", "Schema location \"/a:l\", line number 1."); + + /* hex-string */ + TEST_SUCCESS_XML("a", "l21", "DB:BA:12:54:fa", STRING, "db:ba:12:54:fa"); + TEST_SUCCESS_XML("a", "l22", "f81D4fAE-7dec-11d0-A765-00a0c91E6BF6", STRING, "f81d4fae-7dec-11d0-a765-00a0c91e6bf6"); + /* xpath1.0 */ - TEST_SUCCESS_XML("a\" xmlns:aa=\"urn:tests:a", "l2", "/aa:l2[. = '4']", STRING, "/a:l2[.='4']"); + TEST_SUCCESS_XML("a\" xmlns:aa=\"urn:tests:a", "l3", "/aa:l3[. = '4']", STRING, "/a:l3[.='4']"); TEST_SUCCESS_XML("a\" xmlns:yl=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\" " - "xmlns:ds=\"urn:ietf:params:xml:ns:yang:ietf-datastores", "l2", + "xmlns:ds=\"urn:ietf:params:xml:ns:yang:ietf-datastores", "l3", "/yl:yang-library/yl:datastore/yl:name = 'ds:running'", STRING, "/ietf-yang-library:yang-library/datastore/name='ietf-datastores:running'"); - TEST_SUCCESS_XML("a\" xmlns:a1=\"urn:tests:a\" xmlns:a2=\"urn:tests:a\" xmlns:bb=\"urn:tests:b", "l2", + TEST_SUCCESS_XML("a\" xmlns:a1=\"urn:tests:a\" xmlns:a2=\"urn:tests:a\" xmlns:bb=\"urn:tests:b", "l3", "/a1:node1/a2:node2[a1:node3/bb:node4]/bb:node5 | bb:node6 and (bb:node7)", STRING, "/a:node1/node2[node3/b:node4]/b:node5 | b:node6 and (b:node7)"); - TEST_SUCCESS_XML("a", "l2", "/l2[. = '4']", STRING, "/l2[.='4']"); - - TEST_ERROR_XML("a", "l2", "/a:l2[. = '4']"); - CHECK_LOG_CTX("Failed to resolve prefix \"a\".", "Schema location \"/a:l2\", line number 1."); - TEST_ERROR_XML("a\" xmlns:yl=\"urn:ietf:params:xml:ns:yang:ietf-yang-library", "l2", - "/yl:yang-library/yl:datastore/yl::name"); - CHECK_LOG_CTX("Storing value failed.", "Schema location \"/a:l2\", line number 1.", - "Invalid character 'y'[31] of expression '/yl:yang-library/yl:datastore/yl::name'.", - "Schema location \"/a:l2\", line number 1."); + TEST_SUCCESS_XML("a", "l3", "/l3[. = '4']", STRING, "/l3[.='4']"); + + TEST_ERROR_XML("a", "l3", "/a:l3[. = '4']", LY_EVALID); + CHECK_LOG_CTX("Failed to resolve prefix \"a\".", "Schema location \"/a:l3\", line number 1."); + TEST_ERROR_XML("a\" xmlns:yl=\"urn:ietf:params:xml:ns:yang:ietf-yang-library", "l3", + "/yl:yang-library/yl:datastore/yl::name", LY_EVALID); + CHECK_LOG_CTX("Storing value failed.", "Schema location \"/a:l3\", line number 1."); + CHECK_LOG_CTX("Invalid character 'y'[31] of expression '/yl:yang-library/yl:datastore/yl::name'.", + "Schema location \"/a:l3\", line number 1."); } static void @@ -191,6 +185,31 @@ test_print(void **state) } static void +test_duplicate(void **state) +{ + const char *schema = MODULE_CREATE_YANG("a", "leaf l1 {type yang:date-and-time;} leaf l2 {type yang:xpath1.0;}"); + const char *data, *expected; + struct lyd_node *tree, *dup; + + UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL); + + data = "<l1 xmlns=\"urn:tests:a\">2005-05-25T23:15:15.88888+04:30</l1>" + "<l2 xmlns=\"urn:tests:a\" xmlns:aa=\"urn:tests:a\">/aa:l2[. = '/aa:l2']</l2>"; + CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree); + + /* duplicate */ + assert_int_equal(LY_SUCCESS, lyd_dup_siblings(tree, NULL, 0, &dup)); + + /* print */ + expected = "<l1 xmlns=\"urn:tests:a\">2005-05-25T16:45:15.88888-02:00</l1>" + "<l2 xmlns=\"urn:tests:a\" xmlns:pref=\"urn:tests:a\">/pref:l2[.='/pref:l2']</l2>"; + CHECK_LYD_STRING_PARAM(dup, expected, LYD_XML, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS); + + lyd_free_siblings(tree); + lyd_free_siblings(dup); +} + +static void test_lyb(void **state) { const char *schema; @@ -216,6 +235,7 @@ main(void) const struct CMUnitTest tests[] = { UTEST(test_data_xml), UTEST(test_print), + UTEST(test_duplicate), UTEST(test_lyb), }; diff --git a/tests/utests/utests.h b/tests/utests/utests.h index 877d048..0e0649d 100644 --- a/tests/utests/utests.h +++ b/tests/utests/utests.h @@ -1010,7 +1010,9 @@ struct utest_context { LY_ARRAY_COUNT_TYPE arr_size = sizeof(VALUE) / sizeof(VALUE[0]); \ assert_int_equal(arr_size, LY_ARRAY_COUNT((NODE).target)); \ for (LY_ARRAY_COUNT_TYPE it = 0; it < arr_size; it++) { \ - assert_int_equal(VALUE[it], (NODE).target[it].pred_type); \ + if ((NODE).target[it].predicates) { \ + assert_int_equal(VALUE[it], (NODE).target[it].predicates[0].type); \ + } \ } \ } @@ -1224,97 +1226,32 @@ struct utest_context { _UC->in = NULL /** - * @brief Internal macro to compare error info record with the expected error message and path. - * If NULL is provided as MSG, no error info record (NULL) is expected. + * @brief Check expected last error message. * - * @param[in] ERR Error information record from libyang context. * @param[in] MSG Expected error message. - * @param[in] PATH Expected error path. - */ -#define _CHECK_LOG_CTX(ERR, MSG, PATH) \ - if (!MSG) { \ - assert_null(ERR); \ - } else { \ - assert_non_null(ERR); \ - CHECK_STRING((ERR)->msg, MSG); \ - CHECK_STRING((ERR)->path, PATH); \ - } - -/**` - * @brief Internal macro to check the last libyang's context error. - */ -#define _CHECK_LOG_CTX1(MSG, PATH) \ - _CHECK_LOG_CTX(ly_err_last(_UC->ctx), MSG, PATH) - -/** - * @brief Internal macro to check the last two libyang's context error. - */ -#define _CHECK_LOG_CTX2(MSG1, PATH1, MSG2, PATH2) \ - _CHECK_LOG_CTX(ly_err_last(_UC->ctx), MSG1, PATH1); \ - _CHECK_LOG_CTX(ly_err_last(_UC->ctx)->prev, MSG2, PATH2) - -/** - * @brief Internal macro to check the last three libyang's context error. - */ -#define _CHECK_LOG_CTX3(MSG1, PATH1, MSG2, PATH2, MSG3, PATH3) \ - _CHECK_LOG_CTX2(MSG1, PATH1, MSG2, PATH2); \ - _CHECK_LOG_CTX(ly_err_last(_UC->ctx)->prev->prev, MSG3, PATH3) - -/** - * @brief Internal macro to check the last three libyang's context error. - */ -#define _CHECK_LOG_CTX4(MSG1, PATH1, MSG2, PATH2, MSG3, PATH3, MSG4, PATH4) \ - _CHECK_LOG_CTX3(MSG1, PATH1, MSG2, PATH2, MSG3, PATH3); \ - _CHECK_LOG_CTX(ly_err_last(_UC->ctx)->prev->prev->prev, MSG4, PATH4) - -/** - * @brief Internal macro to check the last three libyang's context error. - */ -#define _CHECK_LOG_CTX5(MSG1, PATH1, MSG2, PATH2, MSG3, PATH3, MSG4, PATH4, MSG5, PATH5) \ - _CHECK_LOG_CTX4(MSG1, PATH1, MSG2, PATH2, MSG3, PATH3, MSG4, PATH4); \ - _CHECK_LOG_CTX(ly_err_last(_UC->ctx)->prev->prev->prev->prev, MSG5, PATH5) - -/** - * @brief Internal macro to check the last three libyang's context error. - */ -#define _CHECK_LOG_CTX6(MSG1, PATH1, MSG2, PATH2, MSG3, PATH3, MSG4, PATH4, MSG5, PATH5, MSG6, PATH6) \ - _CHECK_LOG_CTX5(MSG1, PATH1, MSG2, PATH2, MSG3, PATH3, MSG4, PATH4, MSG5, PATH5); \ - _CHECK_LOG_CTX(ly_err_last(_UC->ctx)->prev->prev->prev->prev->prev, MSG6, PATH6) - -/** - * @brief Internal macro to check the last three libyang's context error. - */ -#define _CHECK_LOG_CTX7(MSG1, PATH1, MSG2, PATH2, MSG3, PATH3, MSG4, PATH4, MSG5, PATH5, MSG6, PATH6, MSG7, PATH7) \ - _CHECK_LOG_CTX6(MSG1, PATH1, MSG2, PATH2, MSG3, PATH3, MSG4, PATH4, MSG5, PATH5, MSG6, PATH6); \ - _CHECK_LOG_CTX(ly_err_last(_UC->ctx)->prev->prev->prev->prev->prev->prev, MSG7, PATH7) - -/** - * @brief Internal macro to check the last three libyang's context error. */ -#define _CHECK_LOG_CTX8(MSG1, PATH1, MSG2, PATH2, MSG3, PATH3, MSG4, PATH4, MSG5, PATH5, MSG6, PATH6, MSG7, PATH7, MSG8, PATH8) \ - _CHECK_LOG_CTX7(MSG1, PATH1, MSG2, PATH2, MSG3, PATH3, MSG4, PATH4, MSG5, PATH5, MSG6, PATH6, MSG7, PATH7); \ - _CHECK_LOG_CTX(ly_err_last(_UC->ctx)->prev->prev->prev->prev->prev->prev->prev, MSG8, PATH8) +#define CHECK_LOG_LASTMSG(MSG) \ + CHECK_STRING(ly_last_errmsg(), MSG) /** - * @brief Internal helper macro to select _CHECK_LOG_CTX* macro according to the provided parameters. - */ -#define _GET_CHECK_LOG_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, NAME, ...) NAME - -/** - * @brief Check expected error(s) in libyang context. - * - * Macro has variadic parameters expected to be provided in pairs of error message and error path starting - * from the latest error. Current limit is checking at most 3 last errors. After checking, macro cleans up - * all the errors from the libyang context. + * @brief Check expected last error in libyang context, which is then cleared. Can be called repeatedly to check + * several errors. If NULL is provided as MSG, no error info record (NULL) is expected. * * @param[in] MSG Expected error message. * @param[in] PATH Expected error path. */ -#define CHECK_LOG_CTX(...) \ - _GET_CHECK_LOG_MACRO(__VA_ARGS__, _CHECK_LOG_CTX8, _INVAL, _CHECK_LOG_CTX7, _INVAL, \ - _CHECK_LOG_CTX6, _INVAL, _CHECK_LOG_CTX5, _INVAL, _CHECK_LOG_CTX4, _INVAL, \ - _CHECK_LOG_CTX3, _INVAL, _CHECK_LOG_CTX2, _INVAL, _CHECK_LOG_CTX1, DUMMY)(__VA_ARGS__); \ - ly_err_clean(_UC->ctx, NULL) +#define CHECK_LOG_CTX(MSG, PATH) \ + { \ + struct ly_err_item *_e = ly_err_last(_UC->ctx); \ + if (!MSG) { \ + assert_null(_e); \ + } else { \ + assert_non_null(_e); \ + CHECK_STRING(_e->msg, MSG); \ + CHECK_STRING(_e->path, PATH); \ + } \ + ly_err_clean(_UC->ctx, _e); \ + } /** * @brief Check expected error in libyang context including error-app-tag. @@ -1324,14 +1261,23 @@ struct utest_context { * @param[in] APPTAG Expected error-app-tag. */ #define CHECK_LOG_CTX_APPTAG(MSG, PATH, APPTAG) \ - if (!MSG) { \ - assert_null(ly_err_last(_UC->ctx)); \ - } else { \ - assert_non_null(ly_err_last(_UC->ctx)); \ - CHECK_STRING(ly_err_last(_UC->ctx)->msg, MSG); \ - CHECK_STRING(ly_err_last(_UC->ctx)->path, PATH); \ - CHECK_STRING(ly_err_last(_UC->ctx)->apptag, APPTAG); \ - } \ + { \ + struct ly_err_item *_e = ly_err_last(_UC->ctx); \ + if (!MSG) { \ + assert_null(_e); \ + } else { \ + assert_non_null(_e); \ + CHECK_STRING(_e->msg, MSG); \ + CHECK_STRING(_e->path, PATH); \ + CHECK_STRING(_e->apptag, APPTAG); \ + } \ + ly_err_clean(_UC->ctx, _e); \ + } + +/** + * @brief Clear all errors stored in the libyang context. + */ +#define UTEST_LOG_CTX_CLEAN \ ly_err_clean(_UC->ctx, NULL) /** @@ -1435,7 +1381,8 @@ utest_teardown(void **state) { *state = NULL; - /* libyang context */ + /* libyang context, no leftover messages */ + assert_null(ly_err_last(current_utest_context->ctx)); ly_ctx_destroy(current_utest_context->ctx); if (current_utest_context->orig_tz) { |