Merge pull request #1088 from CESNET/change_tests_splittage
Change test file organization
diff --git a/src/tree_schema_compile.c b/src/tree_schema_compile.c
index 33590c7..fd9d1b2 100644
--- a/src/tree_schema_compile.c
+++ b/src/tree_schema_compile.c
@@ -538,7 +538,7 @@
lysc_update_path(ctx, NULL, prefixed_name);
if (!ext_mod) {
- ext_mod = lys_module_find_prefix(ctx->mod_def, prefixed_name, u - 1);
+ ext_mod = u ? lys_module_find_prefix(ctx->mod_def, prefixed_name, u - 1) : ctx->mod_def;
if (!ext_mod) {
LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE,
"Invalid prefix \"%.*s\" used for extension instance identifier.", u, prefixed_name);
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 01cb370..631f577 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -15,18 +15,17 @@
set(tests)
set(tests_wraps)
-add_subdirectory(src)
-add_subdirectory(features)
+add_subdirectory(utests)
-foreach(test_name IN LISTS tests)
- message(STATUS ${test_name})
- string(REGEX REPLACE "[a-z]*_(.*)" "\\1" name "${test_name}")
- string(REGEX REPLACE "([a-z]*)_.*" "\\1" prefix "${test_name}")
- add_executable(${test_name} ${prefix}/test_${name}.c $<TARGET_OBJECTS:yangobj>)
-endforeach(test_name)
+foreach(test_id IN LISTS tests)
+ message(STATUS ${test_id})
+ string(REGEX REPLACE "([a-z]*):.*" "\\1" category "${test_id}")
+ string(REGEX REPLACE "[a-z]*:(.*)" "\\1" path "${test_id}")
+ string(REGEX REPLACE "[a-z:/]*test_(.*)" "\\1" name "${test_id}")
+ set(test_name ${category}_${name})
+ add_executable(${test_name} ${category}s/${path}.c $<TARGET_OBJECTS:yangobj>)
-# Set common attributes of all tests
-foreach(test_name IN LISTS tests)
+ # Set common attributes of all tests
target_link_libraries(${test_name} ${CMOCKA_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${PCRE2_LIBRARIES} m)
if (NOT APPLE)
list(GET tests_wraps 0 test_wrap)
@@ -37,20 +36,18 @@
# set_property(TEST ${test_name} PROPERTY ENVIRONMENT "LIBYANG_EXTENSIONS_PLUGINS_DIR=${CMAKE_BINARY_DIR}/src/extensions")
# set_property(TEST ${test_name} APPEND PROPERTY ENVIRONMENT "LIBYANG_USER_TYPES_PLUGINS_DIR=${CMAKE_BINARY_DIR}/src/user_types")
set_property(TEST ${test_name} APPEND PROPERTY ENVIRONMENT "MALLOC_CHECK_=3")
-endforeach(test_name)
-if(ENABLE_VALGRIND_TESTS)
- if(VALGRIND_FOUND)
- foreach(test_name IN LISTS tests)
+ if(ENABLE_VALGRIND_TESTS)
+ if(VALGRIND_FOUND)
add_test(${test_name}_valgrind valgrind --leak-check=full --show-leak-kinds=all --suppressions=${PROJECT_SOURCE_DIR}/tests/ld.supp --error-exitcode=1
- ${CMAKE_BINARY_DIR}/tests/${test_name})
+ ${CMAKE_BINARY_DIR}/tests/${test_name})
# set_property(TEST ${test_name}_valgrind PROPERTY ENVIRONMENT "LIBYANG_EXTENSIONS_PLUGINS_DIR=${CMAKE_BINARY_DIR}/src/extensions")
# set_property(TEST ${test_name}_valgrind APPEND PROPERTY ENVIRONMENT "LIBYANG_USER_TYPES_PLUGINS_DIR=${CMAKE_BINARY_DIR}/src/user_types")
- endforeach(test_name)
- else(VALGRIND_FOUND)
- message(WARNING "valgrind executable not found! Disabling memory leaks tests.")
- endif(VALGRIND_FOUND)
-endif()
+ else(VALGRIND_FOUND)
+ message(WARNING "valgrind executable not found! Disabling memory leaks tests.")
+ endif(VALGRIND_FOUND)
+ endif(ENABLE_VALGRIND_TESTS)
+endforeach()
if(ENABLE_COVERAGE)
# Destination
diff --git a/tests/features/CMakeLists.txt b/tests/features/CMakeLists.txt
deleted file mode 100644
index 6e4a366..0000000
--- a/tests/features/CMakeLists.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-set(local_tests
- features_types
- features_metadata
- features_nacm)
-set(local_tests_wraps
- " "
- " "
- " ")
-set(tests ${tests} ${local_tests} PARENT_SCOPE)
-set(tests_wraps ${tests_wraps} ${local_tests_wraps} PARENT_SCOPE)
diff --git a/tests/src/CMakeLists.txt b/tests/src/CMakeLists.txt
deleted file mode 100644
index 00bf835..0000000
--- a/tests/src/CMakeLists.txt
+++ /dev/null
@@ -1,36 +0,0 @@
-set(local_tests
- src_set
- src_common
- src_context
- src_hash_table
- src_xml
- src_parser_yang
- src_parser_yin
- src_tree_schema
- src_tree_schema_compile
- src_tree_schema_helpers
- src_printer_yang
- src_printer_yin
- src_tree_data
- src_parser_xml
- src_printer_xml
- src_validation)
-set(local_tests_wraps
- " "
- "-Wl,--wrap=realloc"
- " "
- " "
- " "
- " "
- " "
- " "
- " "
- " "
- " "
- " "
- " "
- " "
- " "
- " ")
-set(tests ${tests} ${local_tests} PARENT_SCOPE)
-set(tests_wraps ${tests_wraps} ${local_tests_wraps} PARENT_SCOPE)
diff --git a/tests/src/test_tree_schema.c b/tests/src/test_tree_schema.c
deleted file mode 100644
index bcee581..0000000
--- a/tests/src/test_tree_schema.c
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * @file test_tree_schema.c
- * @author: Radek Krejci <rkrejci@cesnet.cz>
- * @brief unit tests for functions from tress_schema.c
- *
- * Copyright (c) 2018-2019 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.
- * You may obtain a copy of the License at
- *
- * https://opensource.org/licenses/BSD-3-Clause
- */
-
-#include <stdarg.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <setjmp.h>
-#include <cmocka.h>
-
-#include "../../src/common.h"
-#include "../../src/tree_schema.h"
-
-#define BUFSIZE 1024
-char logbuf[BUFSIZE] = {0};
-int store = -1; /* negative for infinite logging, positive for limited logging */
-
-/* set to 0 to printing error messages to stderr instead of checking them in code */
-#define ENABLE_LOGGER_CHECKING 1
-
-#if ENABLE_LOGGER_CHECKING
-static void
-logger(LY_LOG_LEVEL level, const char *msg, const char *path)
-{
- (void) level; /* unused */
- if (store) {
- if (path && path[0]) {
- snprintf(logbuf, BUFSIZE - 1, "%s %s", msg, path);
- } else {
- strncpy(logbuf, msg, BUFSIZE - 1);
- }
- if (store > 0) {
- --store;
- }
- }
-}
-#endif
-
-static int
-logger_setup(void **state)
-{
- (void) state; /* unused */
-
- ly_set_log_clb(logger, 0);
-
- return 0;
-}
-
-static int
-logger_teardown(void **state)
-{
- (void) state; /* unused */
-#if ENABLE_LOGGER_CHECKING
- if (*state) {
- fprintf(stderr, "%s\n", logbuf);
- }
-#endif
- return 0;
-}
-
-void
-logbuf_clean(void)
-{
- logbuf[0] = '\0';
-}
-
-#if ENABLE_LOGGER_CHECKING
-# define logbuf_assert(str) assert_string_equal(logbuf, str)
-#else
-# define logbuf_assert(str)
-#endif
-
-static void
-test_getnext(void **state)
-{
- *state = test_getnext;
-
- struct ly_ctx *ctx;
- struct lys_module *mod;
- const struct lysc_node *node = NULL, *four;
- const struct lysc_node_container *cont;
- const struct lysc_action *rpc;
-
- assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, LY_CTX_DISABLE_SEARCHDIRS, &ctx));
-
- assert_non_null(mod = lys_parse_mem(ctx, "module a {yang-version 1.1; namespace urn:a;prefix a;"
- "container a { container one {presence test;} leaf two {type string;} leaf-list three {type string;}"
- " list four {config false;} choice x { leaf five {type string;} case y {leaf six {type string;}}}"
- " anyxml seven; action eight {input {leaf eight-input {type string;}} output {leaf eight-output {type string;}}}"
- " notification nine {leaf nine-data {type string;}}}"
- "leaf b {type string;} leaf-list c {type string;} list d {config false;}"
- "choice x { leaf e {type string;} case y {leaf f {type string;}}} anyxml g;"
- "rpc h {input {leaf h-input {type string;}} output {leaf h-output {type string;}}}"
- "rpc i;"
- "notification j {leaf i-data {type string;}}"
- "notification k;}", LYS_IN_YANG));
- assert_non_null(node = lys_getnext(node, NULL, mod->compiled, 0));
- assert_string_equal("a", node->name);
- cont = (const struct lysc_node_container*)node;
- assert_non_null(node = lys_getnext(node, NULL, mod->compiled, 0));
- assert_string_equal("b", node->name);
- assert_non_null(node = lys_getnext(node, NULL, mod->compiled, 0));
- assert_string_equal("c", node->name);
- assert_non_null(node = lys_getnext(node, NULL, mod->compiled, 0));
- assert_string_equal("d", node->name);
- assert_non_null(node = lys_getnext(node, NULL, mod->compiled, 0));
- assert_string_equal("e", node->name);
- assert_non_null(node = lys_getnext(node, NULL, mod->compiled, 0));
- assert_string_equal("f", node->name);
- assert_non_null(node = lys_getnext(node, NULL, mod->compiled, 0));
- assert_string_equal("g", node->name);
- assert_non_null(node = lys_getnext(node, NULL, mod->compiled, 0));
- assert_string_equal("h", node->name);
- rpc = (const struct lysc_action*)node;
- assert_non_null(node = lys_getnext(node, NULL, mod->compiled, 0));
- assert_string_equal("i", node->name);
- assert_non_null(node = lys_getnext(node, NULL, mod->compiled, 0));
- assert_string_equal("j", node->name);
- assert_non_null(node = lys_getnext(node, NULL, mod->compiled, 0));
- assert_string_equal("k", node->name);
- assert_null(node = lys_getnext(node, NULL, mod->compiled, 0));
- /* Inside container */
- assert_non_null(node = lys_getnext(node, (const struct lysc_node*)cont, mod->compiled, 0));
- assert_string_equal("one", node->name);
- assert_non_null(node = lys_getnext(node, (const struct lysc_node*)cont, mod->compiled, 0));
- assert_string_equal("two", node->name);
- assert_non_null(node = lys_getnext(node, (const struct lysc_node*)cont, mod->compiled, 0));
- assert_string_equal("three", node->name);
- assert_non_null(node = four = lys_getnext(node, (const struct lysc_node*)cont, mod->compiled, 0));
- assert_string_equal("four", node->name);
- assert_non_null(node = lys_getnext(node, (const struct lysc_node*)cont, mod->compiled, 0));
- assert_string_equal("five", node->name);
- assert_non_null(node = lys_getnext(node, (const struct lysc_node*)cont, mod->compiled, 0));
- assert_string_equal("six", node->name);
- assert_non_null(node = lys_getnext(node, (const struct lysc_node*)cont, mod->compiled, 0));
- assert_string_equal("seven", node->name);
- assert_non_null(node = lys_getnext(node, (const struct lysc_node*)cont, mod->compiled, 0));
- assert_string_equal("eight", node->name);
- assert_non_null(node = lys_getnext(node, (const struct lysc_node*)cont, mod->compiled, 0));
- assert_string_equal("nine", node->name);
- assert_null(node = lys_getnext(node, (const struct lysc_node*)cont, mod->compiled, 0));
- /* Inside RPC */
- assert_non_null(node = lys_getnext(node, (const struct lysc_node*)rpc, mod->compiled, 0));
- assert_string_equal("h-input", node->name);
- assert_null(node = lys_getnext(node, (const struct lysc_node*)rpc, mod->compiled, 0));
-
- /* options */
- assert_non_null(node = lys_getnext(four, (const struct lysc_node*)cont, mod->compiled, LYS_GETNEXT_WITHCHOICE));
- assert_string_equal("x", node->name);
- assert_non_null(node = lys_getnext(node, (const struct lysc_node*)cont, mod->compiled, LYS_GETNEXT_WITHCHOICE));
- assert_string_equal("seven", node->name);
-
- assert_non_null(node = lys_getnext(four, (const struct lysc_node*)cont, mod->compiled, LYS_GETNEXT_NOCHOICE));
- assert_string_equal("seven", node->name);
-
- assert_non_null(node = lys_getnext(four, (const struct lysc_node*)cont, mod->compiled, LYS_GETNEXT_WITHCASE));
- assert_string_equal("five", node->name);
- assert_non_null(node = lys_getnext(node, (const struct lysc_node*)cont, mod->compiled, LYS_GETNEXT_WITHCASE));
- assert_string_equal("y", node->name);
- assert_non_null(node = lys_getnext(node, (const struct lysc_node*)cont, mod->compiled, LYS_GETNEXT_WITHCASE));
- assert_string_equal("seven", node->name);
-
- assert_non_null(node = lys_getnext(NULL, NULL, mod->compiled, LYS_GETNEXT_INTONPCONT));
- assert_string_equal("one", node->name);
-
- assert_non_null(node = lys_getnext(NULL, (const struct lysc_node*)rpc, mod->compiled, LYS_GETNEXT_OUTPUT));
- assert_string_equal("h-output", node->name);
- assert_null(node = lys_getnext(node, (const struct lysc_node*)rpc, mod->compiled, LYS_GETNEXT_OUTPUT));
-
- assert_non_null(mod = lys_parse_mem(ctx, "module b {namespace urn:b;prefix b; feature f;"
- "leaf a {type string; if-feature f;}"
- "leaf b {type string;}}", LYS_IN_YANG));
- assert_non_null(node = lys_getnext(NULL, NULL, mod->compiled, 0));
- assert_string_equal("b", node->name);
- assert_non_null(node = lys_getnext(NULL, NULL, mod->compiled, LYS_GETNEXT_NOSTATECHECK));
- assert_string_equal("a", node->name);
-
- assert_non_null(mod = lys_parse_mem(ctx, "module c {namespace urn:c;prefix c; rpc c;}", LYS_IN_YANG));
- assert_non_null(node = lys_getnext(NULL, NULL, mod->compiled, 0));
- assert_string_equal("c", node->name);
- assert_null(node = lys_getnext(node, NULL, mod->compiled, LYS_GETNEXT_NOSTATECHECK));
-
- assert_non_null(mod = lys_parse_mem(ctx, "module d {namespace urn:d;prefix d; notification d;}", LYS_IN_YANG));
- assert_non_null(node = lys_getnext(NULL, NULL, mod->compiled, 0));
- assert_string_equal("d", node->name);
- assert_null(node = lys_getnext(node, NULL, mod->compiled, LYS_GETNEXT_NOSTATECHECK));
-
- *state = NULL;
- ly_ctx_destroy(ctx, NULL);
-}
-
-int main(void)
-{
- const struct CMUnitTest tests[] = {
- cmocka_unit_test_setup_teardown(test_getnext, logger_setup, logger_teardown),
- };
-
- return cmocka_run_group_tests(tests, NULL, NULL);
-}
diff --git a/tests/src/test_tree_schema_helpers.c b/tests/src/test_tree_schema_helpers.c
deleted file mode 100644
index 01fe9f4..0000000
--- a/tests/src/test_tree_schema_helpers.c
+++ /dev/null
@@ -1,275 +0,0 @@
-/*
- * @file set.c
- * @author: Radek Krejci <rkrejci@cesnet.cz>
- * @brief unit tests for functions from common.c
- *
- * Copyright (c) 2018 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.
- * You may obtain a copy of the License at
- *
- * https://opensource.org/licenses/BSD-3-Clause
- */
-
-#include <stdarg.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <setjmp.h>
-#include <cmocka.h>
-
-#include <string.h>
-
-#include "../../src/common.h"
-#include "../../src/context.h"
-#include "../../src/tree_schema_internal.h"
-
-#define BUFSIZE 1024
-char logbuf[BUFSIZE] = {0};
-int store = -1; /* negative for infinite logging, positive for limited logging */
-
-/* set to 0 to printing error messages to stderr instead of checking them in code */
-#define ENABLE_LOGGER_CHECKING 1
-
-#if ENABLE_LOGGER_CHECKING
-static void
-logger(LY_LOG_LEVEL level, const char *msg, const char *path)
-{
- (void) level; /* unused */
- if (store) {
- if (path && path[0]) {
- snprintf(logbuf, BUFSIZE - 1, "%s %s", msg, path);
- } else {
- strncpy(logbuf, msg, BUFSIZE - 1);
- }
- if (store > 0) {
- --store;
- }
- }
-}
-#endif
-
-static int
-logger_setup(void **state)
-{
- (void) state; /* unused */
-
- ly_set_log_clb(logger, 0);
-
- return 0;
-}
-
-static int
-logger_teardown(void **state)
-{
- (void) state; /* unused */
-#if ENABLE_LOGGER_CHECKING
- if (*state) {
- fprintf(stderr, "%s\n", logbuf);
- }
-#endif
- return 0;
-}
-
-void
-logbuf_clean(void)
-{
- logbuf[0] = '\0';
-}
-
-#if ENABLE_LOGGER_CHECKING
-# define logbuf_assert(str) assert_string_equal(logbuf, str)
-#else
-# define logbuf_assert(str)
-#endif
-
-static void
-test_date(void **state)
-{
- *state = test_date;
-
- assert_int_equal(LY_EINVAL, lysp_check_date(NULL, NULL, 0, "date"));
- logbuf_assert("Invalid argument date (lysp_check_date()).");
- assert_int_equal(LY_EINVAL, lysp_check_date(NULL, "x", 1, "date"));
- logbuf_assert("Invalid argument date_len (lysp_check_date()).");
- assert_int_equal(LY_EINVAL, lysp_check_date(NULL, "nonsencexx", 10, "date"));
- logbuf_assert("Invalid value \"nonsencexx\" of \"date\".");
- assert_int_equal(LY_EINVAL, lysp_check_date(NULL, "123x-11-11", 10, "date"));
- logbuf_assert("Invalid value \"123x-11-11\" of \"date\".");
- assert_int_equal(LY_EINVAL, lysp_check_date(NULL, "2018-13-11", 10, "date"));
- logbuf_assert("Invalid value \"2018-13-11\" of \"date\".");
- assert_int_equal(LY_EINVAL, lysp_check_date(NULL, "2018-11-41", 10, "date"));
- logbuf_assert("Invalid value \"2018-11-41\" of \"date\".");
- assert_int_equal(LY_EINVAL, lysp_check_date(NULL, "2018-02-29", 10, "date"));
- logbuf_assert("Invalid value \"2018-02-29\" of \"date\".");
- assert_int_equal(LY_EINVAL, lysp_check_date(NULL, "2018.02-28", 10, "date"));
- logbuf_assert("Invalid value \"2018.02-28\" of \"date\".");
- assert_int_equal(LY_EINVAL, lysp_check_date(NULL, "2018-02.28", 10, "date"));
- logbuf_assert("Invalid value \"2018-02.28\" of \"date\".");
-
- assert_int_equal(LY_SUCCESS, lysp_check_date(NULL, "2018-11-11", 10, "date"));
- assert_int_equal(LY_SUCCESS, lysp_check_date(NULL, "2018-02-28", 10, "date"));
- assert_int_equal(LY_SUCCESS, lysp_check_date(NULL, "2016-02-29", 10, "date"));
-
- *state = NULL;
-}
-
-static void
-test_revisions(void **state)
-{
- (void) state; /* unused */
-
- struct lysp_revision *revs = NULL, *rev;
-
- logbuf_clean();
- /* no error, it just does nothing */
- lysp_sort_revisions(NULL);
- logbuf_assert("");
-
- /* revisions are stored in wrong order - the newest is the last */
- LY_ARRAY_NEW_RET(NULL, revs, rev,);
- strcpy(rev->date, "2018-01-01");
- LY_ARRAY_NEW_RET(NULL, revs, rev,);
- strcpy(rev->date, "2018-12-31");
-
- assert_int_equal(2, LY_ARRAY_SIZE(revs));
- assert_string_equal("2018-01-01", &revs[0]);
- assert_string_equal("2018-12-31", &revs[1]);
- /* 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]);
-
- LY_ARRAY_FREE(revs);
-}
-
-static LY_ERR test_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,
- const char **module_data, void (**free_module_data)(void *model_data, void *user_data))
-{
- *module_data = user_data;
- *format = LYS_IN_YANG;
- *free_module_data = NULL;
- return LY_SUCCESS;
-}
-
-static void
-test_typedef(void **state)
-{
- *state = test_typedef;
-
- struct ly_ctx *ctx = NULL;
- const char *str;
-
- assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, LY_CTX_DISABLE_SEARCHDIRS, &ctx));
-
- str = "module a {namespace urn:a; prefix a; typedef binary {type string;}}";
- assert_null(lys_parse_mem(ctx, str, LYS_IN_YANG));
- logbuf_assert("Invalid name \"binary\" of typedef - name collision with a built-in type.");
- str = "module a {namespace urn:a; prefix a; typedef bits {type string;}}";
- assert_null(lys_parse_mem(ctx, str, LYS_IN_YANG));
- logbuf_assert("Invalid name \"bits\" of typedef - name collision with a built-in type.");
- str = "module a {namespace urn:a; prefix a; typedef boolean {type string;}}";
- assert_null(lys_parse_mem(ctx, str, LYS_IN_YANG));
- logbuf_assert("Invalid name \"boolean\" of typedef - name collision with a built-in type.");
- str = "module a {namespace urn:a; prefix a; typedef decimal64 {type string;}}";
- assert_null(lys_parse_mem(ctx, str, LYS_IN_YANG));
- logbuf_assert("Invalid name \"decimal64\" of typedef - name collision with a built-in type.");
- str = "module a {namespace urn:a; prefix a; typedef empty {type string;}}";
- assert_null(lys_parse_mem(ctx, str, LYS_IN_YANG));
- logbuf_assert("Invalid name \"empty\" of typedef - name collision with a built-in type.");
- str = "module a {namespace urn:a; prefix a; typedef enumeration {type string;}}";
- assert_null(lys_parse_mem(ctx, str, LYS_IN_YANG));
- logbuf_assert("Invalid name \"enumeration\" of typedef - name collision with a built-in type.");
- str = "module a {namespace urn:a; prefix a; typedef int8 {type string;}}";
- assert_null(lys_parse_mem(ctx, str, LYS_IN_YANG));
- logbuf_assert("Invalid name \"int8\" of typedef - name collision with a built-in type.");
- str = "module a {namespace urn:a; prefix a; typedef int16 {type string;}}";
- assert_null(lys_parse_mem(ctx, str, LYS_IN_YANG));
- logbuf_assert("Invalid name \"int16\" of typedef - name collision with a built-in type.");
- str = "module a {namespace urn:a; prefix a; typedef int32 {type string;}}";
- assert_null(lys_parse_mem(ctx, str, LYS_IN_YANG));
- logbuf_assert("Invalid name \"int32\" of typedef - name collision with a built-in type.");
- str = "module a {namespace urn:a; prefix a; typedef int64 {type string;}}";
- assert_null(lys_parse_mem(ctx, str, LYS_IN_YANG));
- logbuf_assert("Invalid name \"int64\" of typedef - name collision with a built-in type.");
- str = "module a {namespace urn:a; prefix a; typedef instance-identifier {type string;}}";
- assert_null(lys_parse_mem(ctx, str, LYS_IN_YANG));
- logbuf_assert("Invalid name \"instance-identifier\" of typedef - name collision with a built-in type.");
- str = "module a {namespace urn:a; prefix a; typedef identityref {type string;}}";
- assert_null(lys_parse_mem(ctx, str, LYS_IN_YANG));
- logbuf_assert("Invalid name \"identityref\" of typedef - name collision with a built-in type.");
- str = "module a {namespace urn:a; prefix a; typedef leafref {type string;}}";
- assert_null(lys_parse_mem(ctx, str, LYS_IN_YANG));
- logbuf_assert("Invalid name \"leafref\" of typedef - name collision with a built-in type.");
- str = "module a {namespace urn:a; prefix a; typedef string {type int8;}}";
- assert_null(lys_parse_mem(ctx, str, LYS_IN_YANG));
- logbuf_assert("Invalid name \"string\" of typedef - name collision with a built-in type.");
- str = "module a {namespace urn:a; prefix a; typedef union {type string;}}";
- assert_null(lys_parse_mem(ctx, str, LYS_IN_YANG));
- logbuf_assert("Invalid name \"union\" of typedef - name collision with a built-in type.");
- str = "module a {namespace urn:a; prefix a; typedef uint8 {type string;}}";
- assert_null(lys_parse_mem(ctx, str, LYS_IN_YANG));
- logbuf_assert("Invalid name \"uint8\" of typedef - name collision with a built-in type.");
- str = "module a {namespace urn:a; prefix a; typedef uint16 {type string;}}";
- assert_null(lys_parse_mem(ctx, str, LYS_IN_YANG));
- logbuf_assert("Invalid name \"uint16\" of typedef - name collision with a built-in type.");
- str = "module a {namespace urn:a; prefix a; typedef uint32 {type string;}}";
- assert_null(lys_parse_mem(ctx, str, LYS_IN_YANG));
- logbuf_assert("Invalid name \"uint32\" of typedef - name collision with a built-in type.");
- str = "module a {namespace urn:a; prefix a; typedef uint64 {type string;}}";
- assert_null(lys_parse_mem(ctx, str, LYS_IN_YANG));
- logbuf_assert("Invalid name \"uint64\" of typedef - name collision with a built-in type.");
-
- 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;}"
- "typedef int32_ {type string;} typedef int64_ {type string;} typedef instance-identifier_ {type string;} typedef identityref_ {type string;}"
- "typedef leafref_ {type string;} typedef string_ {type int8;} typedef union_ {type string;} typedef uint8_ {type string;} typedef uint16_ {type string;}"
- "typedef uint32_ {type string;} typedef uint64_ {type string;}}";
- assert_non_null(lys_parse_mem(ctx, str, LYS_IN_YANG));
-
- str = "module a {namespace urn:a; prefix a; typedef test {type string;} typedef test {type int8;}}";
- assert_null(lys_parse_mem(ctx, str, LYS_IN_YANG));
- logbuf_assert("Invalid name \"test\" of typedef - name collision with another top-level type.");
-
- str = "module a {namespace urn:a; prefix a; typedef x {type string;} container c {typedef x {type int8;}}}";
- assert_null(lys_parse_mem(ctx, str, LYS_IN_YANG));
- logbuf_assert("Invalid name \"x\" of typedef - scoped type collide with a top-level type.");
-
- str = "module a {namespace urn:a; prefix a; container c {container d {typedef y {type int8;}} typedef y {type string;}}}";
- assert_null(lys_parse_mem(ctx, str, LYS_IN_YANG));
- logbuf_assert("Invalid name \"y\" of typedef - name collision with another scoped type.");
-
- str = "module a {namespace urn:a; prefix a; container c {typedef y {type int8;} typedef y {type string;}}}";
- assert_null(lys_parse_mem(ctx, str, LYS_IN_YANG));
- logbuf_assert("Invalid name \"y\" of typedef - name collision with sibling type.");
-
- ly_ctx_set_module_imp_clb(ctx, 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_null(lys_parse_mem(ctx, str, LYS_IN_YANG));
- logbuf_assert("Invalid name \"x\" of typedef - name collision with another top-level type.");
-
- ly_ctx_set_module_imp_clb(ctx, 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_null(lys_parse_mem(ctx, str, LYS_IN_YANG));
- logbuf_assert("Invalid name \"x\" of typedef - scoped type collide with a top-level type.");
-
- ly_ctx_set_module_imp_clb(ctx, 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_null(lys_parse_mem(ctx, str, LYS_IN_YANG));
- logbuf_assert("Invalid name \"x\" of typedef - scoped type collide with a top-level type.");
-
- *state = NULL;
- ly_ctx_destroy(ctx, NULL);
-}
-
-int main(void)
-{
- const struct CMUnitTest tests[] = {
- cmocka_unit_test_setup_teardown(test_date, logger_setup, logger_teardown),
- cmocka_unit_test_setup_teardown(test_revisions, logger_setup, logger_teardown),
- cmocka_unit_test_setup_teardown(test_typedef, logger_setup, logger_teardown),
- };
-
- return cmocka_run_group_tests(tests, NULL, NULL);
-}
diff --git a/tests/utests/CMakeLists.txt b/tests/utests/CMakeLists.txt
new file mode 100644
index 0000000..04af8d4
--- /dev/null
+++ b/tests/utests/CMakeLists.txt
@@ -0,0 +1,40 @@
+set(local_tests
+ utest:test_common
+ utest:test_set
+ utest:test_hash_table
+ utest:test_context
+ utest:test_xml
+ utest:schema/test_schema
+ utest:schema/test_parser_yang
+ utest:schema/test_parser_yin
+ utest:schema/test_tree_schema_compile
+ utest:schema/test_printer_yang
+ utest:schema/test_printer_yin
+ utest:data/test_tree_data
+ utest:data/test_parser_xml
+ utest:data/test_printer_xml
+ utest:data/test_validation
+ utest:data/test_types
+ utest:extensions/test_metadata
+ utest:extensions/test_nacm)
+set(local_tests_wraps
+ "-Wl,--wrap=realloc"
+ " "
+ " "
+ " "
+ " "
+ " "
+ " "
+ " "
+ " "
+ " "
+ " "
+ " "
+ " "
+ " "
+ " "
+ " "
+ " "
+ " ")
+set(tests ${tests} ${local_tests} PARENT_SCOPE)
+set(tests_wraps ${tests_wraps} ${local_tests_wraps} PARENT_SCOPE)
diff --git a/tests/src/test_parser_xml.c b/tests/utests/data/test_parser_xml.c
similarity index 100%
rename from tests/src/test_parser_xml.c
rename to tests/utests/data/test_parser_xml.c
diff --git a/tests/src/test_printer_xml.c b/tests/utests/data/test_printer_xml.c
similarity index 100%
rename from tests/src/test_printer_xml.c
rename to tests/utests/data/test_printer_xml.c
diff --git a/tests/src/test_tree_data.c b/tests/utests/data/test_tree_data.c
similarity index 100%
rename from tests/src/test_tree_data.c
rename to tests/utests/data/test_tree_data.c
diff --git a/tests/features/test_types.c b/tests/utests/data/test_types.c
similarity index 100%
rename from tests/features/test_types.c
rename to tests/utests/data/test_types.c
diff --git a/tests/src/test_validation.c b/tests/utests/data/test_validation.c
similarity index 100%
rename from tests/src/test_validation.c
rename to tests/utests/data/test_validation.c
diff --git a/tests/features/test_metadata.c b/tests/utests/extensions/test_metadata.c
similarity index 100%
rename from tests/features/test_metadata.c
rename to tests/utests/extensions/test_metadata.c
diff --git a/tests/features/test_nacm.c b/tests/utests/extensions/test_nacm.c
similarity index 100%
rename from tests/features/test_nacm.c
rename to tests/utests/extensions/test_nacm.c
diff --git a/tests/utests/schema/macros.h b/tests/utests/schema/macros.h
new file mode 100644
index 0000000..4a0424f
--- /dev/null
+++ b/tests/utests/schema/macros.h
@@ -0,0 +1,72 @@
+/*
+ * @file macros.h
+ * @author: Radek Krejci <rkrejci@cesnet.cz>
+ * @brief macros for schema tests
+ *
+ * Copyright (c) 2018-2020 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.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ */
+#ifndef TESTS_UTESTS_SCHEMA_MACROS_H_
+#define TESTS_UTESTS_SCHEMA_MACROS_H_
+
+#define TEST_YANG_MODULE_10(MOD_NAME, MOD_PREFIX, MOD_NS, CONTENT) \
+ "module "MOD_NAME" { namespace "MOD_NS"; prefix "MOD_PREFIX"; "CONTENT"}"
+
+#define TEST_YANG_MODULE_11(MOD_NAME, MOD_PREFIX, MOD_NS, CONTENT) \
+ "module "MOD_NAME" {yang-version 1.1; namespace "MOD_NS"; prefix "MOD_PREFIX"; "CONTENT"}"
+
+#define TEST_YIN_MODULE_10(MOD_NAME, MOD_PREFIX, MOD_NS, CONTENT) \
+ "<module xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\" name=\""MOD_NAME"\">" \
+ "<namespace uri=\""MOD_NS"\"/><prefix value=\""MOD_PREFIX"\"/>"CONTENT"</module>"
+
+#define TEST_YIN_MODULE_11(MOD_NAME, MOD_PREFIX, MOD_NS, CONTENT) \
+ "<module xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\" name=\""MOD_NAME"\"><yang-version value=\"1.1\"/>" \
+ "<namespace uri=\""MOD_NS"\"/><prefix value=\""MOD_PREFIX"\"/>"CONTENT"</module>"
+
+#define TEST_SCHEMA_STR(CTX, RFC7950, YIN, MOD_NAME, CONTENT, STR) \
+ if (YIN) { \
+ if (RFC7950) { \
+ STR = TEST_YIN_MODULE_11(MOD_NAME, MOD_NAME, "urn:libyang:test:"MOD_NAME, CONTENT); \
+ } else { \
+ STR = TEST_YIN_MODULE_10(MOD_NAME, MOD_NAME, "urn:libyang:test:"MOD_NAME, CONTENT); \
+ } \
+ } else { /* YANG */ \
+ if (RFC7950) { \
+ STR = TEST_YANG_MODULE_11(MOD_NAME, MOD_NAME, "urn:libyang:test:"MOD_NAME, CONTENT); \
+ } else { \
+ STR = TEST_YANG_MODULE_10(MOD_NAME, MOD_NAME, "urn:libyang:test:"MOD_NAME, CONTENT); \
+ } \
+ }
+
+#define TEST_SCHEMA_OK(CTX, RFC7950, YIN, MOD_NAME, CONTENT, RESULT) \
+ { \
+ const char *test_str__; \
+ TEST_SCHEMA_STR(CTX, RFC7950, YIN, MOD_NAME, CONTENT, test_str__) \
+ assert_non_null(RESULT = lys_parse_mem(CTX, test_str__, YIN ? LYS_IN_YIN : LYS_IN_YANG)); \
+ }
+
+#define TEST_SCHEMA_ERR(CTX, RFC7950, YIN, MOD_NAME, CONTENT, ERRMSG) \
+ { \
+ const char *test_str__; \
+ TEST_SCHEMA_STR(CTX, RFC7950, YIN, MOD_NAME, CONTENT, test_str__) \
+ assert_null(lys_parse_mem(CTX, test_str__, YIN ? LYS_IN_YIN : LYS_IN_YANG)); \
+ logbuf_assert(ERRMSG); \
+ }
+
+#define TEST_STMT_DUP(CTX, RFC7950, YIN, STMT, MEMBER, VALUE1, VALUE2, LINE) \
+ if (YIN) { \
+ TEST_SCHEMA_ERR(CTX, RFC7950, YIN, "dup", "", "Duplicate keyword \""MEMBER"\". Line number "LINE"."); \
+ } else { \
+ TEST_SCHEMA_ERR(CTX, RFC7950, YIN, "dup", STMT"{"MEMBER" "VALUE1";"MEMBER" "VALUE2";}", \
+ "Duplicate keyword \""MEMBER"\". Line number "LINE"."); \
+ }
+
+#define TEST_STMT_SUBSTM_ERR(CTX, RFC7950, STMT, SUBSTMT, VALUE); \
+ TEST_SCHEMA_ERR(CTX, RFC7950, 0, "inv", STMT" test {"SUBSTMT" "VALUE";}", "Invalid keyword \""SUBSTMT"\" as a child of \""STMT"\". Line number 1.");
+
+#endif /* TESTS_UTESTS_SCHEMA_MACROS_H_ */
diff --git a/tests/src/test_parser_yang.c b/tests/utests/schema/test_parser_yang.c
similarity index 95%
rename from tests/src/test_parser_yang.c
rename to tests/utests/schema/test_parser_yang.c
index 6342358..6311dfc 100644
--- a/tests/src/test_parser_yang.c
+++ b/tests/utests/schema/test_parser_yang.c
@@ -20,14 +20,12 @@
#include <stdio.h>
#include <string.h>
-#include "../../src/common.h"
-#include "../../src/tree_schema.h"
-#include "../../src/tree_schema_internal.h"
+#include "../../../src/common.h"
+#include "../../../src/tree_schema.h"
+#include "../../../src/tree_schema_internal.h"
/* originally static functions from tree_schema_free.c and parser_yang.c */
void lysp_ext_instance_free(struct ly_ctx *ctx, struct lysp_ext_instance *ext);
-void lysp_ident_free(struct ly_ctx *ctx, struct lysp_ident *ident);
-void lysp_feature_free(struct ly_ctx *ctx, struct lysp_feature *feat);
void lysp_deviation_free(struct ly_ctx *ctx, struct lysp_deviation *dev);
void lysp_grp_free(struct ly_ctx *ctx, struct lysp_grp *grp);
void lysp_action_free(struct ly_ctx *ctx, struct lysp_action *action);
@@ -52,10 +50,8 @@
LY_ERR parse_container(struct lys_yang_parser_ctx *ctx, const char **data, struct lysp_node *parent, struct lysp_node **siblings);
LY_ERR parse_deviate(struct lys_yang_parser_ctx *ctx, const char **data, struct lysp_deviate **deviates);
LY_ERR parse_deviation(struct lys_yang_parser_ctx *ctx, const char **data, struct lysp_deviation **deviations);
-LY_ERR parse_feature(struct lys_yang_parser_ctx *ctx, const char **data, struct lysp_feature **features);
LY_ERR parse_grouping(struct lys_yang_parser_ctx *ctx, const char **data, struct lysp_node *parent, struct lysp_grp **groupings);
LY_ERR parse_choice(struct lys_yang_parser_ctx *ctx, const char **data, struct lysp_node *parent, struct lysp_node **siblings);
-LY_ERR parse_identity(struct lys_yang_parser_ctx *ctx, const char **data, struct lysp_ident **identities);
LY_ERR parse_leaf(struct lys_yang_parser_ctx *ctx, const char **data, struct lysp_node *parent, struct lysp_node **siblings);
LY_ERR parse_leaflist(struct lys_yang_parser_ctx *ctx, const char **data, struct lysp_node *parent, struct lysp_node **siblings);
LY_ERR parse_list(struct lys_yang_parser_ctx *ctx, const char **data, struct lysp_node *parent, struct lysp_node **siblings);
@@ -1180,97 +1176,24 @@
*state = NULL;
}
-static void
-test_identity(void **state)
-{
- *state = test_identity;
- struct lys_yang_parser_ctx ctx;
- struct lysp_ident *ident = NULL;
- const char *str;
- ctx.format = LYS_IN_YANG;
- assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, 0, &ctx.ctx));
- assert_non_null(ctx.ctx);
- ctx.pos_type = LY_VLOG_LINE;
- ctx.line = 1;
- ctx.indent = 0;
- ctx.mod_version = 2; /* simulate YANG 1.1 */
- /* invalid cardinality */
-#define TEST_DUP(MEMBER, VALUE1, VALUE2) \
- TEST_DUP_GENERIC(" test {", MEMBER, VALUE1, VALUE2, parse_identity, \
- &ident, "1", FREE_ARRAY(ctx.ctx, ident, lysp_ident_free); ident = NULL)
- TEST_DUP("description", "a", "b");
- TEST_DUP("reference", "a", "b");
- TEST_DUP("status", "current", "obsolete");
- /* full content */
- str = " test {base \"a\";base b; description text;reference \'another text\';status current; if-feature x;if-feature y;prefix:ext;} ...";
- assert_int_equal(LY_SUCCESS, parse_identity(&ctx, &str, &ident));
- assert_non_null(ident);
- assert_string_equal(" ...", str);
- FREE_ARRAY(ctx.ctx, ident, lysp_ident_free);
- ident = NULL;
- /* invalid substatement */
- str = " test {organization XXX;}";
- assert_int_equal(LY_EVALID, parse_identity(&ctx, &str, &ident));
- logbuf_assert("Invalid keyword \"organization\" as a child of \"identity\". Line number 1.");
- FREE_ARRAY(ctx.ctx, ident, lysp_ident_free);
- ident = NULL;
-#undef TEST_DUP
- *state = NULL;
- ly_ctx_destroy(ctx.ctx, NULL);
-}
-static void
-test_feature(void **state)
-{
- (void) state; /* unused */
- struct lys_yang_parser_ctx ctx;
- struct lysp_feature *features = NULL;
- const char *str;
- ctx.format = LYS_IN_YANG;
- assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, 0, &ctx.ctx));
- assert_non_null(ctx.ctx);
- ctx.pos_type = LY_VLOG_LINE;
- ctx.line = 1;
- ctx.indent = 0;
- /* invalid cardinality */
-#define TEST_DUP(MEMBER, VALUE1, VALUE2) \
- TEST_DUP_GENERIC(" test {", MEMBER, VALUE1, VALUE2, parse_feature, \
- &features, "1", FREE_ARRAY(ctx.ctx, features, lysp_feature_free); features = NULL)
- TEST_DUP("description", "a", "b");
- TEST_DUP("reference", "a", "b");
- TEST_DUP("status", "current", "obsolete");
- /* full content */
- str = " test {description text;reference \'another text\';status current; if-feature x;if-feature y;prefix:ext;} ...";
- assert_int_equal(LY_SUCCESS, parse_feature(&ctx, &str, &features));
- assert_non_null(features);
- assert_string_equal(" ...", str);
- FREE_ARRAY(ctx.ctx, features, lysp_feature_free);
- features = NULL;
- /* invalid substatement */
- str = " test {organization XXX;}";
- assert_int_equal(LY_EVALID, parse_feature(&ctx, &str, &features));
- logbuf_assert("Invalid keyword \"organization\" as a child of \"feature\". Line number 1.");
- FREE_ARRAY(ctx.ctx, features, lysp_feature_free);
- features = NULL;
-#undef TEST_DUP
- ly_ctx_destroy(ctx.ctx, NULL);
-}
+
static void
test_deviation(void **state)
@@ -2316,8 +2239,6 @@
cmocka_unit_test_setup(test_stmts, logger_setup),
cmocka_unit_test_setup_teardown(test_minmax, logger_setup, logger_teardown),
cmocka_unit_test_setup_teardown(test_module, logger_setup, logger_teardown),
- cmocka_unit_test_setup_teardown(test_identity, logger_setup, logger_teardown),
- cmocka_unit_test_setup(test_feature, logger_setup),
cmocka_unit_test_setup(test_deviation, logger_setup),
cmocka_unit_test_setup(test_deviate, logger_setup),
cmocka_unit_test_setup(test_container, logger_setup),
diff --git a/tests/src/test_parser_yin.c b/tests/utests/schema/test_parser_yin.c
similarity index 96%
rename from tests/src/test_parser_yin.c
rename to tests/utests/schema/test_parser_yin.c
index ce5f0c8..ea22333 100644
--- a/tests/src/test_parser_yin.c
+++ b/tests/utests/schema/test_parser_yin.c
@@ -21,11 +21,11 @@
#include <string.h>
#include <stdbool.h>
-#include "../../src/common.h"
-#include "../../src/tree_schema.h"
-#include "../../src/tree_schema_internal.h"
-#include "../../src/parser_yin.h"
-#include "../../src/xml.h"
+#include "../../../src/common.h"
+#include "../../../src/tree_schema.h"
+#include "../../../src/tree_schema_internal.h"
+#include "../../../src/parser_yin.h"
+#include "../../../src/xml.h"
/* prototypes of static functions */
void lysp_ext_instance_free(struct ly_ctx *ctx, struct lysp_ext_instance *ext);
@@ -53,7 +53,7 @@
#define ELEMENT_WRAPPER_START "<status xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">"
#define ELEMENT_WRAPPER_END "</status>"
-struct state {
+struct test_parser_yin_state {
struct ly_ctx *ctx;
struct lys_module *mod;
struct lysp_module *lysp_mod;
@@ -101,7 +101,7 @@
int
setup_ly_ctx(void **state)
{
- struct state *st = NULL;
+ struct test_parser_yin_state *st = NULL;
/* allocate state variable */
(*state) = st = calloc(1, sizeof(*st));
@@ -119,7 +119,7 @@
int
destroy_ly_ctx(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
ly_ctx_destroy(st->ctx, NULL);
free(st);
@@ -129,7 +129,7 @@
static int
setup_f(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
#if ENABLE_LOGGER_CHECKING
/* setup logger */
@@ -155,7 +155,7 @@
static int
teardown_f(void **state)
{
- struct state *st = *(struct state **)state;
+ struct test_parser_yin_state *st = *(struct test_parser_yin_state **)state;
struct lys_module *temp;
#if ENABLE_LOGGER_CHECKING
@@ -176,10 +176,10 @@
return EXIT_SUCCESS;
}
-static struct state*
+static struct test_parser_yin_state*
reset_state(void **state)
{
- ((struct state *)*state)->finished_correctly = true;
+ ((struct test_parser_yin_state *)*state)->finished_correctly = true;
logbuf[0] = '\0';
teardown_f(state);
setup_f(state);
@@ -210,7 +210,7 @@
static int
teardown_logger(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
#if ENABLE_LOGGER_CHECKING
/* teardown logger */
@@ -226,7 +226,7 @@
setup_element_test(void **state)
{
setup_logger(state);
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
st->yin_ctx = calloc(1, sizeof(*st->yin_ctx));
st->yin_ctx->format = LYS_IN_YIN;
@@ -237,7 +237,7 @@
static int
teardown_element_test(void **state)
{
- struct state *st = *(struct state **)state;
+ struct test_parser_yin_state *st = *(struct test_parser_yin_state **)state;
lyxml_ctx_free(st->yin_ctx->xmlctx);
free(st->yin_ctx);
@@ -250,7 +250,7 @@
static void
test_yin_match_keyword(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
const char *prefix;
size_t prefix_len;
@@ -356,7 +356,7 @@
static void
test_yin_parse_element_generic(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
struct lysp_ext_instance exts;
LY_ERR ret;
@@ -394,7 +394,7 @@
test_yin_parse_extension_instance(void **state)
{
LY_ERR ret;
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
struct lysp_ext_instance *exts = NULL;
const char *data = "<myext:ext value1=\"test\" value=\"test2\" xmlns:myext=\"urn:example:extensions\"><myext:subelem>text</myext:subelem></myext:ext>";
lyxml_ctx_new(st->ctx, data, &st->yin_ctx->xmlctx);
@@ -552,7 +552,7 @@
static void
test_yin_parse_content(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
LY_ERR ret = LY_SUCCESS;
const char *data = "<prefix value=\"a_mod\" xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">"
"<myext:custom xmlns:myext=\"urn:example:extensions\">"
@@ -724,7 +724,7 @@
static void
test_validate_value(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
const char *data = ELEMENT_WRAPPER_START ELEMENT_WRAPPER_END;
/* create some XML context */
@@ -755,7 +755,7 @@
/* helper function to simplify unit test of each element using parse_content function */
LY_ERR
-test_element_helper(struct state *st, const char *data, void *dest, const char **text, struct lysp_ext_instance **exts)
+test_element_helper(struct test_parser_yin_state *st, const char *data, void *dest, const char **text, struct lysp_ext_instance **exts)
{
const char *name, *prefix;
size_t name_len, prefix_len;
@@ -853,7 +853,7 @@
static void
test_enum_elem(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
struct lysp_type type = {};
const char *data;
data = ELEMENT_WRAPPER_START
@@ -893,7 +893,7 @@
static void
test_bit_elem(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
struct lysp_type type = {};
const char *data;
data = ELEMENT_WRAPPER_START
@@ -933,7 +933,7 @@
static void
test_meta_elem(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
char *value = NULL;
const char *data;
struct lysp_ext_instance *exts = NULL;
@@ -1032,7 +1032,7 @@
static void
test_import_elem(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
const char *data;
struct lysp_import *imports = NULL;
struct import_meta imp_meta = {"prefix", &imports};
@@ -1097,7 +1097,7 @@
static void
test_status_elem(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
const char *data;
uint16_t flags = 0;
struct lysp_ext_instance *exts = NULL;
@@ -1130,7 +1130,7 @@
static void
test_ext_elem(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
const char *data;
struct lysp_ext *ext = NULL;
@@ -1171,7 +1171,7 @@
static void
test_yin_element_elem(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
const char *data;
uint16_t flags = 0;
struct lysp_ext_instance *exts = NULL;
@@ -1198,7 +1198,7 @@
static void
test_yangversion_elem(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
const char *data;
uint8_t version = 0;
struct lysp_ext_instance *exts = NULL;
@@ -1229,7 +1229,7 @@
static void
test_mandatory_elem(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
const char *data;
uint16_t man = 0;
struct lysp_ext_instance *exts = NULL;
@@ -1258,7 +1258,7 @@
static void
test_argument_elem(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
const char *data;
uint16_t flags = 0;
const char *arg;
@@ -1300,7 +1300,7 @@
static void
test_base_elem(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
const char *data;
const char **bases = NULL;
struct lysp_ext_instance *exts = NULL;
@@ -1345,7 +1345,7 @@
static void
test_belongsto_elem(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
const char *data;
struct lysp_submodule submod;
struct lysp_ext_instance *exts = NULL;
@@ -1375,7 +1375,7 @@
static void
test_config_elem(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
const char *data;
uint16_t flags = 0;
struct lysp_ext_instance *exts = NULL;
@@ -1405,7 +1405,7 @@
static void
test_default_elem(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
const char *data;
const char *val = NULL;
struct lysp_ext_instance *exts = NULL;
@@ -1431,7 +1431,7 @@
static void
test_err_app_tag_elem(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
const char *data;
const char *val = NULL;
struct lysp_ext_instance *exts = NULL;
@@ -1457,7 +1457,7 @@
static void
test_err_msg_elem(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
const char *data;
const char *val = NULL;
struct lysp_ext_instance *exts = NULL;
@@ -1486,7 +1486,7 @@
static void
test_fracdigits_elem(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
const char *data;
struct lysp_type type = {};
@@ -1527,7 +1527,7 @@
static void
test_iffeature_elem(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
const char *data;
const char **iffeatures = NULL;
struct lysp_ext_instance *exts = NULL;
@@ -1556,7 +1556,7 @@
static void
test_length_elem(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
const char *data;
struct lysp_type type = {};
@@ -1606,7 +1606,7 @@
static void
test_modifier_elem(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
const char *data;
const char *pat = lydict_insert(st->ctx, "\006pattern", 8);
struct lysp_ext_instance *exts = NULL;
@@ -1633,7 +1633,7 @@
static void
test_namespace_elem(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
const char *data;
const char *ns;
struct lysp_ext_instance *exts = NULL;
@@ -1658,7 +1658,7 @@
static void
test_path_elem(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
const char *data;
struct lysp_type type = {};
@@ -1677,7 +1677,7 @@
static void
test_pattern_elem(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
const char *data;
struct lysp_type type = {};
@@ -1718,7 +1718,7 @@
static void
test_value_position_elem(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
const char *data;
struct lysp_type_enum en = {};
@@ -1804,7 +1804,7 @@
static void
test_prefix_elem(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
const char *data;
const char *value = NULL;
struct lysp_ext_instance *exts = NULL;
@@ -1830,7 +1830,7 @@
static void
test_range_elem(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
const char *data;
struct lysp_type type = {};
@@ -1870,7 +1870,7 @@
static void
test_reqinstance_elem(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
const char *data;
struct lysp_type type = {};
@@ -1901,7 +1901,7 @@
static void
test_revision_date_elem(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
const char *data;
char rev[LY_REV_SIZE];
struct lysp_ext_instance *exts = NULL;
@@ -1928,7 +1928,7 @@
static void
test_unique_elem(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
const char *data;
const char **values = NULL;
struct lysp_ext_instance *exts = NULL;
@@ -1957,7 +1957,7 @@
static void
test_units_elem(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
const char *data;
const char *values = NULL;
struct lysp_ext_instance *exts = NULL;
@@ -1984,7 +1984,7 @@
static void
test_when_elem(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
const char *data;
struct lysp_when *when = NULL;
@@ -2019,7 +2019,7 @@
static void
test_yin_text_value_elem(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
const char *data;
const char *val;
@@ -2044,7 +2044,7 @@
static void
test_type_elem(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
const char *data;
struct lysp_type type = {};
@@ -2104,7 +2104,7 @@
static void
test_max_elems_elem(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
const char *data;
struct lysp_node_list list = {};
struct lysp_node_leaflist llist = {};
@@ -2164,7 +2164,7 @@
static void
test_min_elems_elem(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
const char *data;
struct lysp_node_list list = {};
struct lysp_node_leaflist llist = {};
@@ -2219,7 +2219,7 @@
static void
test_ordby_elem(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
const char *data;
uint16_t flags = 0;
struct lysp_ext_instance *exts = NULL;
@@ -2246,7 +2246,7 @@
static void
test_any_elem(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
const char *data;
struct lysp_node *siblings = NULL;
struct tree_node_meta node_meta = {.parent = NULL, .nodes = &siblings};
@@ -2335,7 +2335,7 @@
static void
test_leaf_elem(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
const char *data;
struct lysp_node *siblings = NULL;
struct tree_node_meta node_meta = {.parent = NULL, .nodes = &siblings};
@@ -2396,7 +2396,7 @@
static void
test_leaf_list_elem(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
const char *data;
struct lysp_node *siblings = NULL;
struct tree_node_meta node_meta = {.parent = NULL, .nodes = &siblings};
@@ -2573,7 +2573,7 @@
static void
test_presence_elem(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
const char *data;
const char *val;
struct lysp_ext_instance *exts = NULL;
@@ -2602,7 +2602,7 @@
static void
test_key_elem(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
const char *data;
const char *val;
struct lysp_ext_instance *exts = NULL;
@@ -2631,7 +2631,7 @@
static void
test_typedef_elem(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
const char *data;
struct lysp_tpdf *tpdfs = NULL;
struct tree_node_meta typdef_meta = {NULL, (struct lysp_node **)&tpdfs};
@@ -2678,7 +2678,7 @@
static void
test_refine_elem(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
const char *data;
struct lysp_refine *refines = NULL;
@@ -2729,7 +2729,7 @@
static void
test_uses_elem(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
const char *data;
struct lysp_node *siblings = NULL;
struct tree_node_meta node_meta = {NULL, &siblings};
@@ -2780,7 +2780,7 @@
static void
test_revision_elem(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
const char *data;
struct lysp_revision *revs = NULL;
@@ -2822,7 +2822,7 @@
static void
test_include_elem(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
const char *data;
struct lysp_include *includes = NULL;
struct include_meta inc_meta = {"module-name", &includes};
@@ -2884,102 +2884,9 @@
}
static void
-test_feature_elem(void **state)
-{
- struct state *st = *state;
- const char *data;
- struct lysp_feature *features = NULL;
-
- /* max subelems */
- data = ELEMENT_WRAPPER_START
- "<feature name=\"feature-name\">"
- "<if-feature name=\"iff\"/>"
- "<status value=\"deprecated\"/>"
- "<description><text>desc</text></description>"
- "<reference><text>ref</text></reference>"
- EXT_SUBELEM
- "</feature>"
- ELEMENT_WRAPPER_END;
- assert_int_equal(test_element_helper(st, data, &features, NULL, NULL), LY_SUCCESS);
- assert_string_equal(features->name, "feature-name");
- assert_string_equal(features->dsc, "desc");
- assert_true(features->flags & LYS_STATUS_DEPRC);
- assert_string_equal(*features->iffeatures, "iff");
- assert_string_equal(features->ref, "ref");
- assert_string_equal(features->exts[0].name, "urn:example:extensions:c-define");
- assert_int_equal(features->exts[0].insubstmt_index, 0);
- assert_int_equal(features->exts[0].insubstmt, LYEXT_SUBSTMT_SELF);
- FREE_ARRAY(st->ctx, features, lysp_feature_free);
- features = NULL;
-
- /* min subelems */
- data = ELEMENT_WRAPPER_START "<feature name=\"feature-name\"/>" ELEMENT_WRAPPER_END;
- assert_int_equal(test_element_helper(st, data, &features, NULL, NULL), LY_SUCCESS);
- assert_string_equal(features->name, "feature-name");
- FREE_ARRAY(st->ctx, features, lysp_feature_free);
- features = NULL;
-
- st->finished_correctly = true;
-}
-
-static void
-test_identity_elem(void **state)
-{
- struct state *st = *state;
- const char *data;
- struct lysp_ident *identities = NULL;
-
- /* max subelems */
- st->yin_ctx->mod_version = LYS_VERSION_1_1;
- data = ELEMENT_WRAPPER_START
- "<identity name=\"ident-name\">"
- "<if-feature name=\"iff\"/>"
- "<base name=\"base-name\"/>"
- "<status value=\"deprecated\"/>"
- "<description><text>desc</text></description>"
- "<reference><text>ref</text></reference>"
- EXT_SUBELEM
- "</identity>"
- ELEMENT_WRAPPER_END;
- assert_int_equal(test_element_helper(st, data, &identities, NULL, NULL), LY_SUCCESS);
- assert_string_equal(identities->name, "ident-name");
- assert_string_equal(*identities->bases, "base-name");
- assert_string_equal(*identities->iffeatures, "iff");
- assert_string_equal(identities->dsc, "desc");
- assert_string_equal(identities->ref, "ref");
- assert_true(identities->flags & LYS_STATUS_DEPRC);
- assert_string_equal(identities->exts[0].name, "urn:example:extensions:c-define");
- assert_int_equal(identities->exts[0].insubstmt_index, 0);
- assert_int_equal(identities->exts[0].insubstmt, LYEXT_SUBSTMT_SELF);
- FREE_ARRAY(st->ctx, identities, lysp_ident_free);
- identities = NULL;
-
- /* min subelems */
- data = ELEMENT_WRAPPER_START "<identity name=\"ident-name\" />" ELEMENT_WRAPPER_END;
- assert_int_equal(test_element_helper(st, data, &identities, NULL, NULL), LY_SUCCESS);
- assert_string_equal(identities->name, "ident-name");
- FREE_ARRAY(st->ctx, identities, lysp_ident_free);
- identities = NULL;
-
- /* invalid */
- st->yin_ctx->mod_version = LYS_VERSION_1_0;
- data = ELEMENT_WRAPPER_START
- "<identity name=\"ident-name\">"
- "<if-feature name=\"iff\"/>"
- "</identity>"
- ELEMENT_WRAPPER_END;
- assert_int_equal(test_element_helper(st, data, &identities, NULL, NULL), LY_EVALID);
- logbuf_assert("Invalid sub-elemnt \"if-feature\" of \"identity\" element - this sub-element is allowed only in modules with version 1.1 or newer. Line number 1.");
- FREE_ARRAY(st->ctx, identities, lysp_ident_free);
- identities = NULL;
-
- st->finished_correctly = true;
-}
-
-static void
test_list_elem(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
const char *data;
struct lysp_node *siblings = NULL;
struct tree_node_meta node_meta = {NULL, &siblings};
@@ -3074,7 +2981,7 @@
static void
test_notification_elem(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
const char *data;
struct lysp_notif *notifs = NULL;
struct tree_node_meta notif_meta = {NULL, (struct lysp_node **)¬ifs};
@@ -3148,7 +3055,7 @@
static void
test_grouping_elem(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
const char *data;
struct lysp_grp *grps = NULL;
struct tree_node_meta grp_meta = {NULL, (struct lysp_node **)&grps};
@@ -3215,7 +3122,7 @@
static void
test_container_elem(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
const char *data;
struct lysp_node *siblings = NULL;
struct tree_node_meta node_meta = {NULL, &siblings};
@@ -3304,7 +3211,7 @@
static void
test_case_elem(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
const char *data;
struct lysp_node *siblings = NULL;
struct tree_node_meta node_meta = {NULL, &siblings};
@@ -3378,7 +3285,7 @@
static void
test_choice_elem(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
const char *data;
struct lysp_node *siblings = NULL;
struct tree_node_meta node_meta = {NULL, &siblings};
@@ -3455,7 +3362,7 @@
static void
test_inout_elem(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
const char *data;
struct lysp_action_inout inout = {};
struct inout_meta inout_meta = {NULL, &inout};
@@ -3577,7 +3484,7 @@
static void
test_action_elem(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
const char *data;
struct lysp_action *actions = NULL;
struct tree_node_meta act_meta = {NULL, (struct lysp_node **)&actions};
@@ -3663,7 +3570,7 @@
static void
test_augment_elem(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
const char *data;
struct lysp_augment *augments = NULL;
struct tree_node_meta aug_meta = {NULL, (struct lysp_node **)&augments};
@@ -3738,7 +3645,7 @@
static void
test_deviate_elem(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
const char *data;
struct lysp_deviate *deviates = NULL;
struct lysp_deviate_add *d_add;
@@ -3908,7 +3815,7 @@
static void
test_deviation_elem(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
const char *data;
struct lysp_deviation *deviations = NULL;
@@ -3957,7 +3864,7 @@
static void
test_module_elem(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
const char *data;
struct lys_module *lys_mod = NULL;
struct lysp_module *lysp_mod = NULL;
@@ -4085,7 +3992,7 @@
static void
test_submodule_elem(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
const char *data;
struct lysp_submodule *lysp_submod = NULL;
@@ -4199,7 +4106,7 @@
static void
test_yin_parse_module(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
const char *data;
struct lys_module *mod;
struct lys_yin_parser_ctx *yin_ctx = NULL;
@@ -4315,7 +4222,7 @@
static void
test_yin_parse_submodule(void **state)
{
- struct state *st = *state;
+ struct test_parser_yin_state *st = *state;
const char *data;
struct lys_yin_parser_ctx *yin_ctx = NULL;
struct lysp_submodule *submod = NULL;
@@ -4455,8 +4362,6 @@
cmocka_unit_test_setup_teardown(test_uses_elem, setup_element_test, teardown_element_test),
cmocka_unit_test_setup_teardown(test_revision_elem, setup_element_test, teardown_element_test),
cmocka_unit_test_setup_teardown(test_include_elem, setup_element_test, teardown_element_test),
- cmocka_unit_test_setup_teardown(test_feature_elem, setup_element_test, teardown_element_test),
- cmocka_unit_test_setup_teardown(test_identity_elem, setup_element_test, teardown_element_test),
cmocka_unit_test_setup_teardown(test_list_elem, setup_element_test, teardown_element_test),
cmocka_unit_test_setup_teardown(test_notification_elem, setup_element_test, teardown_element_test),
cmocka_unit_test_setup_teardown(test_grouping_elem, setup_element_test, teardown_element_test),
diff --git a/tests/src/test_printer_yang.c b/tests/utests/schema/test_printer_yang.c
similarity index 100%
rename from tests/src/test_printer_yang.c
rename to tests/utests/schema/test_printer_yang.c
diff --git a/tests/src/test_printer_yin.c b/tests/utests/schema/test_printer_yin.c
similarity index 100%
rename from tests/src/test_printer_yin.c
rename to tests/utests/schema/test_printer_yin.c
diff --git a/tests/utests/schema/test_schema.c b/tests/utests/schema/test_schema.c
new file mode 100644
index 0000000..b330a7d
--- /dev/null
+++ b/tests/utests/schema/test_schema.c
@@ -0,0 +1,112 @@
+/*
+ * @file test_schema.c
+ * @author: Radek Krejci <rkrejci@cesnet.cz>
+ * @brief unit tests for schema related functions
+ *
+ * Copyright (c) 2018-2019 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.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ */
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <setjmp.h>
+#include <cmocka.h>
+
+#include "../../../src/common.h"
+#include "../../../src/context.h"
+#include "../../../src/tree_schema.h"
+#include "../../../src/tree_schema_internal.h"
+#include "../../../src/parser_yin.h"
+#include "../../../src/xml.h"
+
+
+#define BUFSIZE 1024
+char logbuf[BUFSIZE] = {0};
+int store = -1; /* negative for infinite logging, positive for limited logging */
+
+/* set to 0 to printing error messages to stderr instead of checking them in code */
+#define ENABLE_LOGGER_CHECKING 1
+
+#if ENABLE_LOGGER_CHECKING
+static void
+logger(LY_LOG_LEVEL level, const char *msg, const char *path)
+{
+ (void) level; /* unused */
+ if (store) {
+ if (path && path[0]) {
+ snprintf(logbuf, BUFSIZE - 1, "%s %s", msg, path);
+ } else {
+ strncpy(logbuf, msg, BUFSIZE - 1);
+ }
+ if (store > 0) {
+ --store;
+ }
+ }
+}
+#endif
+
+static int
+logger_setup(void **state)
+{
+ (void) state; /* unused */
+
+#if ENABLE_LOGGER_CHECKING
+ /* setup logger */
+ ly_set_log_clb(logger, 1);
+#endif
+
+ return 0;
+}
+
+static int
+logger_teardown(void **state)
+{
+ (void) state; /* unused */
+#if ENABLE_LOGGER_CHECKING
+ if (*state) {
+ fprintf(stderr, "%s\n", logbuf);
+ }
+#endif
+ return 0;
+}
+
+void
+logbuf_clean(void)
+{
+ logbuf[0] = '\0';
+}
+
+#if ENABLE_LOGGER_CHECKING
+# define logbuf_assert(str) assert_string_equal(logbuf, str)
+#else
+# define logbuf_assert(str)
+#endif
+
+/**
+ * INCLUDE OTHER SCHEMA TESTS
+ */
+#include "test_schema_common.c"
+#include "test_schema_stmts.c"
+
+int main(void)
+{
+ const struct CMUnitTest tests[] = {
+ /** test_schema_common.c */
+ cmocka_unit_test_setup_teardown(test_getnext, logger_setup, logger_teardown),
+ cmocka_unit_test_setup_teardown(test_date, logger_setup, logger_teardown),
+ cmocka_unit_test_setup_teardown(test_revisions, logger_setup, logger_teardown),
+ cmocka_unit_test_setup_teardown(test_typedef, logger_setup, logger_teardown),
+
+ /** test_schema_stmts.c */
+ cmocka_unit_test_setup_teardown(test_identity, logger_setup, logger_teardown),
+ cmocka_unit_test_setup_teardown(test_feature, logger_setup, logger_teardown),
+ };
+
+ return cmocka_run_group_tests(tests, NULL, NULL);
+}
diff --git a/tests/utests/schema/test_schema_common.c b/tests/utests/schema/test_schema_common.c
new file mode 100644
index 0000000..9b2bc6b
--- /dev/null
+++ b/tests/utests/schema/test_schema_common.c
@@ -0,0 +1,319 @@
+/*
+ * @file set.c
+ * @author: Radek Krejci <rkrejci@cesnet.cz>
+ * @brief unit tests for functions from common.c
+ *
+ * Copyright (c) 2018 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.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ */
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <setjmp.h>
+#include <cmocka.h>
+
+#include <string.h>
+
+static void
+test_getnext(void **state)
+{
+ *state = test_getnext;
+
+ struct ly_ctx *ctx;
+ struct lys_module *mod;
+ const struct lysc_node *node = NULL, *four;
+ const struct lysc_node_container *cont;
+ const struct lysc_action *rpc;
+
+ assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, LY_CTX_DISABLE_SEARCHDIRS, &ctx));
+
+ assert_non_null(mod = lys_parse_mem(ctx, "module a {yang-version 1.1; namespace urn:a;prefix a;"
+ "container a { container one {presence test;} leaf two {type string;} leaf-list three {type string;}"
+ " list four {config false;} choice x { leaf five {type string;} case y {leaf six {type string;}}}"
+ " anyxml seven; action eight {input {leaf eight-input {type string;}} output {leaf eight-output {type string;}}}"
+ " notification nine {leaf nine-data {type string;}}}"
+ "leaf b {type string;} leaf-list c {type string;} list d {config false;}"
+ "choice x { leaf e {type string;} case y {leaf f {type string;}}} anyxml g;"
+ "rpc h {input {leaf h-input {type string;}} output {leaf h-output {type string;}}}"
+ "rpc i;"
+ "notification j {leaf i-data {type string;}}"
+ "notification k;}", LYS_IN_YANG));
+ assert_non_null(node = lys_getnext(node, NULL, mod->compiled, 0));
+ assert_string_equal("a", node->name);
+ cont = (const struct lysc_node_container*)node;
+ assert_non_null(node = lys_getnext(node, NULL, mod->compiled, 0));
+ assert_string_equal("b", node->name);
+ assert_non_null(node = lys_getnext(node, NULL, mod->compiled, 0));
+ assert_string_equal("c", node->name);
+ assert_non_null(node = lys_getnext(node, NULL, mod->compiled, 0));
+ assert_string_equal("d", node->name);
+ assert_non_null(node = lys_getnext(node, NULL, mod->compiled, 0));
+ assert_string_equal("e", node->name);
+ assert_non_null(node = lys_getnext(node, NULL, mod->compiled, 0));
+ assert_string_equal("f", node->name);
+ assert_non_null(node = lys_getnext(node, NULL, mod->compiled, 0));
+ assert_string_equal("g", node->name);
+ assert_non_null(node = lys_getnext(node, NULL, mod->compiled, 0));
+ assert_string_equal("h", node->name);
+ rpc = (const struct lysc_action*)node;
+ assert_non_null(node = lys_getnext(node, NULL, mod->compiled, 0));
+ assert_string_equal("i", node->name);
+ assert_non_null(node = lys_getnext(node, NULL, mod->compiled, 0));
+ assert_string_equal("j", node->name);
+ assert_non_null(node = lys_getnext(node, NULL, mod->compiled, 0));
+ assert_string_equal("k", node->name);
+ assert_null(node = lys_getnext(node, NULL, mod->compiled, 0));
+ /* Inside container */
+ assert_non_null(node = lys_getnext(node, (const struct lysc_node*)cont, mod->compiled, 0));
+ assert_string_equal("one", node->name);
+ assert_non_null(node = lys_getnext(node, (const struct lysc_node*)cont, mod->compiled, 0));
+ assert_string_equal("two", node->name);
+ assert_non_null(node = lys_getnext(node, (const struct lysc_node*)cont, mod->compiled, 0));
+ assert_string_equal("three", node->name);
+ assert_non_null(node = four = lys_getnext(node, (const struct lysc_node*)cont, mod->compiled, 0));
+ assert_string_equal("four", node->name);
+ assert_non_null(node = lys_getnext(node, (const struct lysc_node*)cont, mod->compiled, 0));
+ assert_string_equal("five", node->name);
+ assert_non_null(node = lys_getnext(node, (const struct lysc_node*)cont, mod->compiled, 0));
+ assert_string_equal("six", node->name);
+ assert_non_null(node = lys_getnext(node, (const struct lysc_node*)cont, mod->compiled, 0));
+ assert_string_equal("seven", node->name);
+ assert_non_null(node = lys_getnext(node, (const struct lysc_node*)cont, mod->compiled, 0));
+ assert_string_equal("eight", node->name);
+ assert_non_null(node = lys_getnext(node, (const struct lysc_node*)cont, mod->compiled, 0));
+ assert_string_equal("nine", node->name);
+ assert_null(node = lys_getnext(node, (const struct lysc_node*)cont, mod->compiled, 0));
+ /* Inside RPC */
+ assert_non_null(node = lys_getnext(node, (const struct lysc_node*)rpc, mod->compiled, 0));
+ assert_string_equal("h-input", node->name);
+ assert_null(node = lys_getnext(node, (const struct lysc_node*)rpc, mod->compiled, 0));
+
+ /* options */
+ assert_non_null(node = lys_getnext(four, (const struct lysc_node*)cont, mod->compiled, LYS_GETNEXT_WITHCHOICE));
+ assert_string_equal("x", node->name);
+ assert_non_null(node = lys_getnext(node, (const struct lysc_node*)cont, mod->compiled, LYS_GETNEXT_WITHCHOICE));
+ assert_string_equal("seven", node->name);
+
+ assert_non_null(node = lys_getnext(four, (const struct lysc_node*)cont, mod->compiled, LYS_GETNEXT_NOCHOICE));
+ assert_string_equal("seven", node->name);
+
+ assert_non_null(node = lys_getnext(four, (const struct lysc_node*)cont, mod->compiled, LYS_GETNEXT_WITHCASE));
+ assert_string_equal("five", node->name);
+ assert_non_null(node = lys_getnext(node, (const struct lysc_node*)cont, mod->compiled, LYS_GETNEXT_WITHCASE));
+ assert_string_equal("y", node->name);
+ assert_non_null(node = lys_getnext(node, (const struct lysc_node*)cont, mod->compiled, LYS_GETNEXT_WITHCASE));
+ assert_string_equal("seven", node->name);
+
+ assert_non_null(node = lys_getnext(NULL, NULL, mod->compiled, LYS_GETNEXT_INTONPCONT));
+ assert_string_equal("one", node->name);
+
+ assert_non_null(node = lys_getnext(NULL, (const struct lysc_node*)rpc, mod->compiled, LYS_GETNEXT_OUTPUT));
+ assert_string_equal("h-output", node->name);
+ assert_null(node = lys_getnext(node, (const struct lysc_node*)rpc, mod->compiled, LYS_GETNEXT_OUTPUT));
+
+ assert_non_null(mod = lys_parse_mem(ctx, "module b {namespace urn:b;prefix b; feature f;"
+ "leaf a {type string; if-feature f;}"
+ "leaf b {type string;}}", LYS_IN_YANG));
+ assert_non_null(node = lys_getnext(NULL, NULL, mod->compiled, 0));
+ assert_string_equal("b", node->name);
+ assert_non_null(node = lys_getnext(NULL, NULL, mod->compiled, LYS_GETNEXT_NOSTATECHECK));
+ assert_string_equal("a", node->name);
+
+ assert_non_null(mod = lys_parse_mem(ctx, "module c {namespace urn:c;prefix c; rpc c;}", LYS_IN_YANG));
+ assert_non_null(node = lys_getnext(NULL, NULL, mod->compiled, 0));
+ assert_string_equal("c", node->name);
+ assert_null(node = lys_getnext(node, NULL, mod->compiled, LYS_GETNEXT_NOSTATECHECK));
+
+ assert_non_null(mod = lys_parse_mem(ctx, "module d {namespace urn:d;prefix d; notification d;}", LYS_IN_YANG));
+ assert_non_null(node = lys_getnext(NULL, NULL, mod->compiled, 0));
+ assert_string_equal("d", node->name);
+ assert_null(node = lys_getnext(node, NULL, mod->compiled, LYS_GETNEXT_NOSTATECHECK));
+
+ *state = NULL;
+ ly_ctx_destroy(ctx, NULL);
+}
+static void
+test_date(void **state)
+{
+ *state = test_date;
+
+ assert_int_equal(LY_EINVAL, lysp_check_date(NULL, NULL, 0, "date"));
+ logbuf_assert("Invalid argument date (lysp_check_date()).");
+ assert_int_equal(LY_EINVAL, lysp_check_date(NULL, "x", 1, "date"));
+ logbuf_assert("Invalid argument date_len (lysp_check_date()).");
+ assert_int_equal(LY_EINVAL, lysp_check_date(NULL, "nonsencexx", 10, "date"));
+ logbuf_assert("Invalid value \"nonsencexx\" of \"date\".");
+ assert_int_equal(LY_EINVAL, lysp_check_date(NULL, "123x-11-11", 10, "date"));
+ logbuf_assert("Invalid value \"123x-11-11\" of \"date\".");
+ assert_int_equal(LY_EINVAL, lysp_check_date(NULL, "2018-13-11", 10, "date"));
+ logbuf_assert("Invalid value \"2018-13-11\" of \"date\".");
+ assert_int_equal(LY_EINVAL, lysp_check_date(NULL, "2018-11-41", 10, "date"));
+ logbuf_assert("Invalid value \"2018-11-41\" of \"date\".");
+ assert_int_equal(LY_EINVAL, lysp_check_date(NULL, "2018-02-29", 10, "date"));
+ logbuf_assert("Invalid value \"2018-02-29\" of \"date\".");
+ assert_int_equal(LY_EINVAL, lysp_check_date(NULL, "2018.02-28", 10, "date"));
+ logbuf_assert("Invalid value \"2018.02-28\" of \"date\".");
+ assert_int_equal(LY_EINVAL, lysp_check_date(NULL, "2018-02.28", 10, "date"));
+ logbuf_assert("Invalid value \"2018-02.28\" of \"date\".");
+
+ assert_int_equal(LY_SUCCESS, lysp_check_date(NULL, "2018-11-11", 10, "date"));
+ assert_int_equal(LY_SUCCESS, lysp_check_date(NULL, "2018-02-28", 10, "date"));
+ assert_int_equal(LY_SUCCESS, lysp_check_date(NULL, "2016-02-29", 10, "date"));
+
+ *state = NULL;
+}
+
+static void
+test_revisions(void **state)
+{
+ (void) state; /* unused */
+
+ struct lysp_revision *revs = NULL, *rev;
+
+ logbuf_clean();
+ /* no error, it just does nothing */
+ lysp_sort_revisions(NULL);
+ logbuf_assert("");
+
+ /* revisions are stored in wrong order - the newest is the last */
+ LY_ARRAY_NEW_RET(NULL, revs, rev,);
+ strcpy(rev->date, "2018-01-01");
+ LY_ARRAY_NEW_RET(NULL, revs, rev,);
+ strcpy(rev->date, "2018-12-31");
+
+ assert_int_equal(2, LY_ARRAY_SIZE(revs));
+ assert_string_equal("2018-01-01", &revs[0]);
+ assert_string_equal("2018-12-31", &revs[1]);
+ /* 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]);
+
+ LY_ARRAY_FREE(revs);
+}
+
+LY_ERR test_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,
+ const char **module_data, void (**free_module_data)(void *model_data, void *user_data))
+{
+ *module_data = user_data;
+ *format = LYS_IN_YANG;
+ *free_module_data = NULL;
+ return LY_SUCCESS;
+}
+
+static void
+test_typedef(void **state)
+{
+ *state = test_typedef;
+
+ struct ly_ctx *ctx = NULL;
+ const char *str;
+
+ assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, LY_CTX_DISABLE_SEARCHDIRS, &ctx));
+
+ str = "module a {namespace urn:a; prefix a; typedef binary {type string;}}";
+ assert_null(lys_parse_mem(ctx, str, LYS_IN_YANG));
+ logbuf_assert("Invalid name \"binary\" of typedef - name collision with a built-in type. Line number 1.");
+ str = "module a {namespace urn:a; prefix a; typedef bits {type string;}}";
+ assert_null(lys_parse_mem(ctx, str, LYS_IN_YANG));
+ logbuf_assert("Invalid name \"bits\" of typedef - name collision with a built-in type. Line number 1.");
+ str = "module a {namespace urn:a; prefix a; typedef boolean {type string;}}";
+ assert_null(lys_parse_mem(ctx, str, LYS_IN_YANG));
+ logbuf_assert("Invalid name \"boolean\" of typedef - name collision with a built-in type. Line number 1.");
+ str = "module a {namespace urn:a; prefix a; typedef decimal64 {type string;}}";
+ assert_null(lys_parse_mem(ctx, str, LYS_IN_YANG));
+ logbuf_assert("Invalid name \"decimal64\" of typedef - name collision with a built-in type. Line number 1.");
+ str = "module a {namespace urn:a; prefix a; typedef empty {type string;}}";
+ assert_null(lys_parse_mem(ctx, str, LYS_IN_YANG));
+ logbuf_assert("Invalid name \"empty\" of typedef - name collision with a built-in type. Line number 1.");
+ str = "module a {namespace urn:a; prefix a; typedef enumeration {type string;}}";
+ assert_null(lys_parse_mem(ctx, str, LYS_IN_YANG));
+ logbuf_assert("Invalid name \"enumeration\" of typedef - name collision with a built-in type. Line number 1.");
+ str = "module a {namespace urn:a; prefix a; typedef int8 {type string;}}";
+ assert_null(lys_parse_mem(ctx, str, LYS_IN_YANG));
+ logbuf_assert("Invalid name \"int8\" of typedef - name collision with a built-in type. Line number 1.");
+ str = "module a {namespace urn:a; prefix a; typedef int16 {type string;}}";
+ assert_null(lys_parse_mem(ctx, str, LYS_IN_YANG));
+ logbuf_assert("Invalid name \"int16\" of typedef - name collision with a built-in type. Line number 1.");
+ str = "module a {namespace urn:a; prefix a; typedef int32 {type string;}}";
+ assert_null(lys_parse_mem(ctx, str, LYS_IN_YANG));
+ logbuf_assert("Invalid name \"int32\" of typedef - name collision with a built-in type. Line number 1.");
+ str = "module a {namespace urn:a; prefix a; typedef int64 {type string;}}";
+ assert_null(lys_parse_mem(ctx, str, LYS_IN_YANG));
+ logbuf_assert("Invalid name \"int64\" of typedef - name collision with a built-in type. Line number 1.");
+ str = "module a {namespace urn:a; prefix a; typedef instance-identifier {type string;}}";
+ assert_null(lys_parse_mem(ctx, str, LYS_IN_YANG));
+ logbuf_assert("Invalid name \"instance-identifier\" of typedef - name collision with a built-in type. Line number 1.");
+ str = "module a {namespace urn:a; prefix a; typedef identityref {type string;}}";
+ assert_null(lys_parse_mem(ctx, str, LYS_IN_YANG));
+ logbuf_assert("Invalid name \"identityref\" of typedef - name collision with a built-in type. Line number 1.");
+ str = "module a {namespace urn:a; prefix a; typedef leafref {type string;}}";
+ assert_null(lys_parse_mem(ctx, str, LYS_IN_YANG));
+ logbuf_assert("Invalid name \"leafref\" of typedef - name collision with a built-in type. Line number 1.");
+ str = "module a {namespace urn:a; prefix a; typedef string {type int8;}}";
+ assert_null(lys_parse_mem(ctx, str, LYS_IN_YANG));
+ logbuf_assert("Invalid name \"string\" of typedef - name collision with a built-in type. Line number 1.");
+ str = "module a {namespace urn:a; prefix a; typedef union {type string;}}";
+ assert_null(lys_parse_mem(ctx, str, LYS_IN_YANG));
+ logbuf_assert("Invalid name \"union\" of typedef - name collision with a built-in type. Line number 1.");
+ str = "module a {namespace urn:a; prefix a; typedef uint8 {type string;}}";
+ assert_null(lys_parse_mem(ctx, str, LYS_IN_YANG));
+ logbuf_assert("Invalid name \"uint8\" of typedef - name collision with a built-in type. Line number 1.");
+ str = "module a {namespace urn:a; prefix a; typedef uint16 {type string;}}";
+ assert_null(lys_parse_mem(ctx, str, LYS_IN_YANG));
+ logbuf_assert("Invalid name \"uint16\" of typedef - name collision with a built-in type. Line number 1.");
+ str = "module a {namespace urn:a; prefix a; typedef uint32 {type string;}}";
+ assert_null(lys_parse_mem(ctx, str, LYS_IN_YANG));
+ logbuf_assert("Invalid name \"uint32\" of typedef - name collision with a built-in type. Line number 1.");
+ str = "module a {namespace urn:a; prefix a; typedef uint64 {type string;}}";
+ assert_null(lys_parse_mem(ctx, str, LYS_IN_YANG));
+ logbuf_assert("Invalid name \"uint64\" of typedef - name collision with a built-in type. Line number 1.");
+
+ 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;}"
+ "typedef int32_ {type string;} typedef int64_ {type string;} typedef instance-identifier_ {type string;} typedef identityref_ {type string;}"
+ "typedef leafref_ {type string;} typedef string_ {type int8;} typedef union_ {type string;} typedef uint8_ {type string;} typedef uint16_ {type string;}"
+ "typedef uint32_ {type string;} typedef uint64_ {type string;}}";
+ assert_non_null(lys_parse_mem(ctx, str, LYS_IN_YANG));
+
+ str = "module a {namespace urn:a; prefix a; typedef test {type string;} typedef test {type int8;}}";
+ assert_null(lys_parse_mem(ctx, str, LYS_IN_YANG));
+ logbuf_assert("Invalid name \"test\" of typedef - name collision with another top-level type. Line number 1.");
+
+ str = "module a {namespace urn:a; prefix a; typedef x {type string;} container c {typedef x {type int8;}}}";
+ assert_null(lys_parse_mem(ctx, str, LYS_IN_YANG));
+ logbuf_assert("Invalid name \"x\" of typedef - scoped type collide with a top-level type. Line number 1.");
+
+ str = "module a {namespace urn:a; prefix a; container c {container d {typedef y {type int8;}} typedef y {type string;}}}";
+ assert_null(lys_parse_mem(ctx, str, LYS_IN_YANG));
+ logbuf_assert("Invalid name \"y\" of typedef - name collision with another scoped type. Line number 1.");
+
+ str = "module a {namespace urn:a; prefix a; container c {typedef y {type int8;} typedef y {type string;}}}";
+ assert_null(lys_parse_mem(ctx, str, LYS_IN_YANG));
+ logbuf_assert("Invalid name \"y\" of typedef - name collision with sibling type. Line number 1.");
+
+ ly_ctx_set_module_imp_clb(ctx, 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_null(lys_parse_mem(ctx, str, LYS_IN_YANG));
+ logbuf_assert("Invalid name \"x\" of typedef - name collision with another top-level type. Line number 1.");
+
+ ly_ctx_set_module_imp_clb(ctx, 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_null(lys_parse_mem(ctx, str, LYS_IN_YANG));
+ logbuf_assert("Invalid name \"x\" of typedef - scoped type collide with a top-level type. Line number 1.");
+
+ ly_ctx_set_module_imp_clb(ctx, 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_null(lys_parse_mem(ctx, str, LYS_IN_YANG));
+ logbuf_assert("Invalid name \"x\" of typedef - scoped type collide with a top-level type. Line number 1.");
+
+ *state = NULL;
+ ly_ctx_destroy(ctx, NULL);
+}
diff --git a/tests/utests/schema/test_schema_stmts.c b/tests/utests/schema/test_schema_stmts.c
new file mode 100644
index 0000000..35ce06a
--- /dev/null
+++ b/tests/utests/schema/test_schema_stmts.c
@@ -0,0 +1,359 @@
+/*
+ * @file test_schema_stmts.c
+ * @author: Radek Krejci <rkrejci@cesnet.cz>
+ * @brief unit tests for YANG (YIN) statements in (sub)modules
+ *
+ * Copyright (c) 2018-2020 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.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ */
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <setjmp.h>
+#include <cmocka.h>
+
+#include <string.h>
+
+#include "macros.h"
+
+
+static void
+test_identity(void **state)
+{
+ *state = test_identity;
+
+ struct ly_ctx *ctx;
+ struct lys_module *mod, *mod_imp;
+
+ assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, 0, &ctx));
+
+ /*
+ * parsing YANG
+ */
+ TEST_STMT_DUP(ctx, 1, 0, "identity id", "description", "a", "b", "1");
+ TEST_STMT_DUP(ctx, 1, 0, "identity id", "reference", "a", "b", "1");
+ TEST_STMT_DUP(ctx, 1, 0, "identity id", "status", "current", "obsolete", "1");
+
+ /* full content */
+ TEST_SCHEMA_OK(ctx, 1, 0, "identityone",
+ "identity test {base \"a\";base b; description text;reference \'another text\';status current; if-feature x;if-feature y; identityone:ext;}"
+ "identity a; identity b; extension ext; feature x; feature y;", mod);
+ assert_non_null(mod->parsed->identities);
+ assert_int_equal(3, LY_ARRAY_SIZE(mod->parsed->identities));
+
+ /* invalid substatement */
+ TEST_STMT_SUBSTM_ERR(ctx, 0, "identity", "organization", "XXX");
+
+ /*
+ * parsing YIN
+ */
+ /* max subelems */
+ TEST_SCHEMA_OK(ctx, 1, 1, "identityone-yin", "<identity name=\"ident-name\">"
+ "<if-feature name=\"iff\"/>"
+ "<base name=\"base-name\"/>"
+ "<status value=\"deprecated\"/>"
+ "<description><text>desc</text></description>"
+ "<reference><text>ref</text></reference>"
+ "<myext:ext xmlns:myext=\"urn:libyang:test:identityone-yin\"/>"
+ "</identity><extension name=\"ext\"/><identity name=\"base-name\"/><feature name=\"iff\"/>", mod);
+ assert_int_equal(2, LY_ARRAY_SIZE(mod->parsed->identities));
+ assert_string_equal(mod->parsed->identities[0].name, "ident-name");
+ assert_string_equal(mod->parsed->identities[0].bases[0], "base-name");
+ assert_string_equal(mod->parsed->identities[0].iffeatures[0], "iff");
+ assert_string_equal(mod->parsed->identities[0].dsc, "desc");
+ assert_string_equal(mod->parsed->identities[0].ref, "ref");
+ assert_true(mod->parsed->identities[0].flags & LYS_STATUS_DEPRC);
+ assert_string_equal(mod->parsed->identities[0].exts[0].name, "ext");
+ assert_non_null(mod->parsed->identities[0].exts[0].compiled);
+ assert_int_equal(mod->parsed->identities[0].exts[0].yin, 1);
+ assert_int_equal(mod->parsed->identities[0].exts[0].insubstmt_index, 0);
+ assert_int_equal(mod->parsed->identities[0].exts[0].insubstmt, LYEXT_SUBSTMT_SELF);
+
+ /* min subelems */
+ TEST_SCHEMA_OK(ctx, 1, 1, "identitytwo-yin", "<identity name=\"ident-name\" />", mod);
+ assert_int_equal(1, LY_ARRAY_SIZE(mod->parsed->identities));
+ assert_string_equal(mod->parsed->identities[0].name, "ident-name");
+
+ /* invalid substatement */
+ TEST_SCHEMA_ERR(ctx, 0, 1, "inv", "<identity name=\"ident-name\"><if-feature name=\"iff\"/></identity>",
+ "Invalid sub-elemnt \"if-feature\" of \"identity\" element - this sub-element is allowed only in modules with version 1.1 or newer. Line number 1.");
+
+ /*
+ * compiling
+ */
+ TEST_SCHEMA_OK(ctx, 0, 0, "a", "identity a1;", mod_imp);
+ TEST_SCHEMA_OK(ctx, 1, 0, "b", "import a {prefix a;}"
+ "identity b1; identity b2; identity b3 {base b1; base b:b2; base a:a1;}"
+ "identity b4 {base b:b1; base b3;}", mod);
+ assert_non_null(mod_imp->compiled);
+ assert_non_null(mod_imp->compiled->identities);
+ assert_non_null(mod->compiled);
+ assert_non_null(mod->compiled->identities);
+ assert_non_null(mod_imp->compiled->identities[0].derived);
+ assert_int_equal(1, LY_ARRAY_SIZE(mod_imp->compiled->identities[0].derived));
+ assert_ptr_equal(mod_imp->compiled->identities[0].derived[0], &mod->compiled->identities[2]);
+ assert_non_null(mod->compiled->identities[0].derived);
+ assert_int_equal(2, LY_ARRAY_SIZE(mod->compiled->identities[0].derived));
+ assert_ptr_equal(mod->compiled->identities[0].derived[0], &mod->compiled->identities[2]);
+ assert_ptr_equal(mod->compiled->identities[0].derived[1], &mod->compiled->identities[3]);
+ assert_non_null(mod->compiled->identities[1].derived);
+ assert_int_equal(1, LY_ARRAY_SIZE(mod->compiled->identities[1].derived));
+ assert_ptr_equal(mod->compiled->identities[1].derived[0], &mod->compiled->identities[2]);
+ assert_non_null(mod->compiled->identities[2].derived);
+ assert_int_equal(1, LY_ARRAY_SIZE(mod->compiled->identities[2].derived));
+ assert_ptr_equal(mod->compiled->identities[2].derived[0], &mod->compiled->identities[3]);
+
+ TEST_SCHEMA_OK(ctx, 1, 0, "c", "identity c2 {base c1;} identity c1;", mod);
+ assert_int_equal(1, LY_ARRAY_SIZE(mod->compiled->identities[1].derived));
+ assert_ptr_equal(mod->compiled->identities[1].derived[0], &mod->compiled->identities[0]);
+
+ TEST_SCHEMA_ERR(ctx, 0, 0, "inv", "identity i1;identity i1;", "Duplicate identifier \"i1\" of identity statement. /inv:{identity='i1'}");
+
+ ly_ctx_set_module_imp_clb(ctx, test_imp_clb, "submodule inv_sub {belongs-to inv {prefix inv;} identity i1;}");
+ TEST_SCHEMA_ERR(ctx, 0, 0, "inv", "include inv_sub;identity i1;",
+ "Duplicate identifier \"i1\" of identity statement. /inv:{identity='i1'}");
+ TEST_SCHEMA_ERR(ctx, 0, 0,"inv", "identity i1 {base i2;}", "Unable to find base (i2) of identity \"i1\". /inv:{identity='i1'}");
+ TEST_SCHEMA_ERR(ctx, 0, 0,"inv", "identity i1 {base i1;}", "Identity \"i1\" is derived from itself. /inv:{identity='i1'}");
+ TEST_SCHEMA_ERR(ctx, 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'}");
+
+ /*
+ * printing
+ */
+
+ /*
+ * cleanup
+ */
+
+ *state = NULL;
+ ly_ctx_destroy(ctx, NULL);
+}
+
+
+static void
+test_feature(void **state)
+{
+ *state = test_feature;
+
+ struct ly_ctx *ctx;
+ struct lys_module *mod;
+ const struct lysc_feature *f, *f1;
+
+ assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, 0, &ctx));
+
+ /*
+ * parsing YANG
+ */
+
+ TEST_STMT_DUP(ctx, 1, 0, "feature f", "description", "a", "b", "1");
+ TEST_STMT_DUP(ctx, 1, 0, "feature f", "reference", "a", "b", "1");
+ TEST_STMT_DUP(ctx, 1, 0, "feature f", "status", "current", "obsolete", "1");
+
+ /* full content */
+ TEST_SCHEMA_OK(ctx, 1, 0, "featureone",
+ "feature test {description text;reference \'another text\';status current; if-feature x; if-feature y; featureone:ext;}"
+ "extension ext; feature x; feature y;", mod);
+ assert_non_null(mod->parsed->features);
+ assert_int_equal(3, LY_ARRAY_SIZE(mod->parsed->features));
+
+ /* invalid substatement */
+ TEST_STMT_SUBSTM_ERR(ctx, 0, "feature", "organization", "XXX");
+
+ /*
+ * parsing YIN
+ */
+ /* max subelems */
+ TEST_SCHEMA_OK(ctx, 0, 1, "featureone-yin", "<feature name=\"feature-name\">"
+ "<if-feature name=\"iff\"/>"
+ "<status value=\"deprecated\"/>"
+ "<description><text>desc</text></description>"
+ "<reference><text>ref</text></reference>"
+ "<myext:ext xmlns:myext=\"urn:libyang:test:featureone-yin\"/>"
+ "</feature><extension name=\"ext\"/><feature name=\"iff\"/>", mod);
+ assert_int_equal(2, LY_ARRAY_SIZE(mod->parsed->features));
+ assert_string_equal(mod->parsed->features[0].name, "feature-name");
+ assert_string_equal(mod->parsed->features[0].dsc, "desc");
+ assert_true(mod->parsed->features[0].flags & LYS_STATUS_DEPRC);
+ assert_string_equal(mod->parsed->features[0].iffeatures[0], "iff");
+ assert_string_equal(mod->parsed->features[0].ref, "ref");
+ assert_string_equal(mod->parsed->features[0].exts[0].name, "ext");
+ assert_int_equal(mod->parsed->features[0].exts[0].insubstmt_index, 0);
+ assert_int_equal(mod->parsed->features[0].exts[0].insubstmt, LYEXT_SUBSTMT_SELF);
+
+ /* min subelems */
+ TEST_SCHEMA_OK(ctx, 0, 1, "featuretwo-yin", "<feature name=\"feature-name\"/>", mod)
+ assert_int_equal(1, LY_ARRAY_SIZE(mod->parsed->features));
+ assert_string_equal(mod->parsed->features[0].name, "feature-name");
+
+ /* invalid substatement */
+ TEST_SCHEMA_ERR(ctx, 0, 1, "inv", "<feature name=\"feature-name\"><organization><text>org</text></organization></feature>",
+ "Unexpected sub-element \"organization\" of \"feature\" element. Line number 1.");
+
+ /*
+ * compiling
+ */
+
+ TEST_SCHEMA_OK(ctx, 1, 0, "a", "feature f1 {description test1;reference test2;status current;} feature f2; feature f3;\n"
+ "feature orfeature {if-feature \"f1 or f2\";}\n"
+ "feature andfeature {if-feature \"f1 and f2\";}\n"
+ "feature f6 {if-feature \"not f1\";}\n"
+ "feature f7 {if-feature \"(f2 and f3) or (not f1)\";}\n"
+ "feature f8 {if-feature \"f1 or f2 or f3 or orfeature or andfeature\";}\n"
+ "feature f9 {if-feature \"not not f1\";}", mod);
+ assert_non_null(mod->compiled->features);
+ assert_int_equal(9, LY_ARRAY_SIZE(mod->compiled->features));
+
+ /* all features are disabled by default */
+ LY_ARRAY_FOR(mod->compiled->features, struct lysc_feature, f) {
+ assert_int_equal(0, lysc_feature_value(f));
+ }
+ /* enable f1 */
+ assert_int_equal(LY_SUCCESS, lys_feature_enable(mod, "f1"));
+ f1 = &mod->compiled->features[0];
+ assert_int_equal(1, lysc_feature_value(f1));
+
+ /* enable orfeature */
+ f = &mod->compiled->features[3];
+ assert_int_equal(0, lysc_feature_value(f));
+ assert_int_equal(LY_SUCCESS, lys_feature_enable(mod, "orfeature"));
+ assert_int_equal(1, lysc_feature_value(f));
+
+ /* enable andfeature - no possible since f2 is disabled */
+ f = &mod->compiled->features[4];
+ assert_int_equal(0, lysc_feature_value(f));
+ assert_int_equal(LY_EDENIED, lys_feature_enable(mod, "andfeature"));
+ logbuf_assert("Feature \"andfeature\" cannot be enabled since it is disabled by its if-feature condition(s).");
+ assert_int_equal(0, lysc_feature_value(f));
+
+ /* first enable f2, so f5 can be enabled then */
+ assert_int_equal(LY_SUCCESS, lys_feature_enable(mod, "f2"));
+ assert_int_equal(LY_SUCCESS, lys_feature_enable(mod, "andfeature"));
+ assert_int_equal(1, lysc_feature_value(f));
+
+ /* f1 is enabled, so f6 cannot be enabled */
+ f = &mod->compiled->features[5];
+ assert_int_equal(0, lysc_feature_value(f));
+ assert_int_equal(LY_EDENIED, lys_feature_enable(mod, "f6"));
+ logbuf_assert("Feature \"f6\" cannot be enabled since it is disabled by its if-feature condition(s).");
+ assert_int_equal(0, lysc_feature_value(f));
+
+ /* so disable f1 - andfeature will became also disabled */
+ assert_int_equal(1, lysc_feature_value(f1));
+ assert_int_equal(LY_SUCCESS, lys_feature_disable(mod, "f1"));
+ assert_int_equal(0, lysc_feature_value(f1));
+ assert_int_equal(0, lysc_feature_value(&mod->compiled->features[4]));
+ /* while orfeature is stille enabled */
+ assert_int_equal(1, lysc_feature_value(&mod->compiled->features[3]));
+ /* and finally f6 can be enabled */
+ assert_int_equal(LY_SUCCESS, lys_feature_enable(mod, "f6"));
+ assert_int_equal(1, lysc_feature_value(&mod->compiled->features[5]));
+
+ /* complex evaluation of f7: f1 and f3 are disabled, while f2 is enabled */
+ assert_int_equal(1, lysc_iffeature_value(&mod->compiled->features[6].iffeatures[0]));
+ /* long evaluation of f8 to need to reallocate internal stack for operators */
+ assert_int_equal(1, lysc_iffeature_value(&mod->compiled->features[7].iffeatures[0]));
+
+ /* double negation of disabled f1 -> disabled */
+ assert_int_equal(0, lysc_iffeature_value(&mod->compiled->features[8].iffeatures[0]));
+
+ /* disable all features */
+ assert_int_equal(LY_SUCCESS, lys_feature_disable(mod, "*"));
+ LY_ARRAY_FOR(mod->compiled->features, struct lysc_feature, f) {
+ assert_int_equal(0, lys_feature_value(mod, f->name));
+ }
+ /* re-setting already set feature */
+ assert_int_equal(LY_SUCCESS, lys_feature_disable(mod, "f1"));
+ assert_int_equal(0, lys_feature_value(mod, "f1"));
+
+ /* enabling feature that cannot be enabled due to its if-features */
+ assert_int_equal(LY_SUCCESS, lys_feature_enable(mod, "f1"));
+ assert_int_equal(LY_EDENIED, lys_feature_enable(mod, "andfeature"));
+ logbuf_assert("Feature \"andfeature\" cannot be enabled since it is disabled by its if-feature condition(s).");
+ assert_int_equal(LY_EDENIED, lys_feature_enable(mod, "*"));
+ logbuf_assert("Feature \"f6\" cannot be enabled since it is disabled by its if-feature condition(s).");
+ /* test if not changed */
+ assert_int_equal(1, lys_feature_value(mod, "f1"));
+ assert_int_equal(0, lys_feature_value(mod, "f2"));
+
+ TEST_SCHEMA_OK(ctx, 0, 0, "b", "feature f1 {if-feature f2;}feature f2;", mod);
+ assert_non_null(mod->compiled);
+ assert_non_null(mod->compiled->features);
+ assert_int_equal(2, LY_ARRAY_SIZE(mod->compiled->features));
+ assert_non_null(mod->compiled->features[0].iffeatures);
+ assert_int_equal(1, LY_ARRAY_SIZE(mod->compiled->features[0].iffeatures));
+ assert_non_null(mod->compiled->features[0].iffeatures[0].features);
+ assert_int_equal(1, LY_ARRAY_SIZE(mod->compiled->features[0].iffeatures[0].features));
+ assert_ptr_equal(&mod->compiled->features[1], mod->compiled->features[0].iffeatures[0].features[0]);
+ assert_non_null(mod->compiled->features);
+ assert_int_equal(2, LY_ARRAY_SIZE(mod->compiled->features));
+ assert_non_null(mod->compiled->features[1].depfeatures);
+ assert_int_equal(1, LY_ARRAY_SIZE(mod->compiled->features[1].depfeatures));
+ assert_ptr_equal(&mod->compiled->features[0], mod->compiled->features[1].depfeatures[0]);
+
+ /* invalid reference */
+ assert_int_equal(LY_EINVAL, lys_feature_enable(mod, "xxx"));
+ logbuf_assert("Feature \"xxx\" not found in module \"b\".");
+
+ /* some invalid expressions */
+ TEST_SCHEMA_ERR(ctx, 1, 0, "inv", "feature f{if-feature f1;}",
+ "Invalid value \"f1\" of if-feature - unable to find feature \"f1\". /inv:{feature='f'}");
+ TEST_SCHEMA_ERR(ctx, 1, 0, "inv", "feature f1; feature f2{if-feature 'f and';}",
+ "Invalid value \"f and\" of if-feature - unexpected end of expression. /inv:{feature='f2'}");
+ TEST_SCHEMA_ERR(ctx, 1, 0, "inv", "feature f{if-feature 'or';}",
+ "Invalid value \"or\" of if-feature - unexpected end of expression. /inv:{feature='f'}");
+ TEST_SCHEMA_ERR(ctx, 1, 0, "inv", "feature f1; feature f2{if-feature '(f1';}",
+ "Invalid value \"(f1\" of if-feature - non-matching opening and closing parentheses. /inv:{feature='f2'}");
+ TEST_SCHEMA_ERR(ctx, 1, 0, "inv", "feature f1; feature f2{if-feature 'f1)';}",
+ "Invalid value \"f1)\" of if-feature - non-matching opening and closing parentheses. /inv:{feature='f2'}");
+ TEST_SCHEMA_ERR(ctx, 1, 0, "inv", "feature f1; feature f2{if-feature ---;}",
+ "Invalid value \"---\" of if-feature - unable to find feature \"---\". /inv:{feature='f2'}");
+ TEST_SCHEMA_ERR(ctx, 0, 0, "inv", "feature f1; feature f2{if-feature 'not f1';}",
+ "Invalid value \"not f1\" of if-feature - YANG 1.1 expression in YANG 1.0 module. /inv:{feature='f2'}");
+ TEST_SCHEMA_ERR(ctx, 0, 0, "inv", "feature f1; feature f1;",
+ "Duplicate identifier \"f1\" of feature statement. /inv:{feature='f1'}");
+
+ ly_ctx_set_module_imp_clb(ctx, test_imp_clb, "submodule inv_sub {belongs-to inv {prefix inv;} feature f1;}");
+ TEST_SCHEMA_ERR(ctx, 0, 0, "inv", "include inv_sub;feature f1;",
+ "Duplicate identifier \"f1\" of feature statement. /inv:{feature='f1'}");
+ TEST_SCHEMA_ERR(ctx, 0, 0, "inv", "feature f1 {if-feature f2;} feature f2 {if-feature f1;}",
+ "Feature \"f1\" is indirectly referenced from itself. /inv:{feature='f2'}");
+ TEST_SCHEMA_ERR(ctx, 0, 0, "inv", "feature f1 {if-feature f1;}",
+ "Feature \"f1\" is referenced from itself. /inv:{feature='f1'}");
+ TEST_SCHEMA_ERR(ctx, 1, 0, "inv", "feature f {if-feature ();}",
+ "Invalid value \"()\" of if-feature - number of features in expression does not match the required number of operands for the operations. /inv:{feature='f'}");
+ TEST_SCHEMA_ERR(ctx, 1, 0, "inv", "feature f1; feature f {if-feature 'f1(';}",
+ "Invalid value \"f1(\" of if-feature - non-matching opening and closing parentheses. /inv:{feature='f'}");
+ TEST_SCHEMA_ERR(ctx, 1, 0, "inv", "feature f1; feature f {if-feature 'and f1';}",
+ "Invalid value \"and f1\" of if-feature - missing feature/expression before \"and\" operation. /inv:{feature='f'}");
+ TEST_SCHEMA_ERR(ctx, 1, 0, "inv", "feature f1; feature f {if-feature 'f1 not ';}",
+ "Invalid value \"f1 not \" of if-feature - unexpected end of expression. /inv:{feature='f'}");
+ TEST_SCHEMA_ERR(ctx, 1, 0, "inv", "feature f1; feature f {if-feature 'f1 not not ';}",
+ "Invalid value \"f1 not not \" of if-feature - unexpected end of expression. /inv:{feature='f'}");
+ TEST_SCHEMA_ERR(ctx, 1, 0, "inv", "feature f1; feature f2; feature f {if-feature 'or f1 f2';}",
+ "Invalid value \"or f1 f2\" of if-feature - missing feature/expression before \"or\" operation. /inv:{feature='f'}");
+
+ /* import reference */
+ assert_non_null(mod = ly_ctx_get_module(ctx, "a", NULL));
+ assert_int_equal(LY_SUCCESS, lys_feature_enable(mod, "f1"));
+ TEST_SCHEMA_OK(ctx, 0, 0, "c", "import a {prefix a;} feature f1; feature f2{if-feature 'a:f1';}", mod);
+ assert_int_equal(LY_SUCCESS, lys_feature_enable(mod, "f2"));
+ assert_int_equal(0, lys_feature_value(mod, "f1"));
+ assert_int_equal(1, lys_feature_value(mod, "f2"));
+
+ /*
+ * printing
+ */
+
+ /*
+ * cleanup
+ */
+
+ *state = NULL;
+ ly_ctx_destroy(ctx, NULL);
+}
diff --git a/tests/src/test_tree_schema_compile.c b/tests/utests/schema/test_tree_schema_compile.c
similarity index 92%
rename from tests/src/test_tree_schema_compile.c
rename to tests/utests/schema/test_tree_schema_compile.c
index 5ad02da..81d13bb 100644
--- a/tests/src/test_tree_schema_compile.c
+++ b/tests/utests/schema/test_tree_schema_compile.c
@@ -189,269 +189,7 @@
ly_ctx_destroy(mod.ctx, NULL);
}
-static void
-test_feature(void **state)
-{
- *state = test_feature;
- struct lys_yang_parser_ctx *ctx = NULL;
- struct lys_module mod = {0}, *modp;
- const char *str;
- struct lysc_feature *f, *f1;
-
- str = "module a {namespace urn:a;prefix a;yang-version 1.1;\n"
- "feature f1 {description test1;reference test2;status current;} feature f2; feature f3;\n"
- "feature orfeature {if-feature \"f1 or f2\";}\n"
- "feature andfeature {if-feature \"f1 and f2\";}\n"
- "feature f6 {if-feature \"not f1\";}\n"
- "feature f7 {if-feature \"(f2 and f3) or (not f1)\";}\n"
- "feature f8 {if-feature \"f1 or f2 or f3 or orfeature or andfeature\";}\n"
- "feature f9 {if-feature \"not not f1\";}}";
-
- assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, 0, &mod.ctx));
- reset_mod(&mod);
-
- assert_int_equal(LY_SUCCESS, yang_parse_module(&ctx, str, &mod));
- yang_parser_ctx_free(ctx);
- assert_int_equal(LY_SUCCESS, lys_compile(&mod, 0));
- assert_non_null(mod.compiled);
- assert_non_null(mod.compiled->features);
- assert_int_equal(9, LY_ARRAY_SIZE(mod.compiled->features));
- /* all features are disabled by default */
- LY_ARRAY_FOR(mod.compiled->features, struct lysc_feature, f) {
- assert_int_equal(0, lysc_feature_value(f));
- }
- /* enable f1 */
- assert_int_equal(LY_SUCCESS, lys_feature_enable(&mod, "f1"));
- f1 = &mod.compiled->features[0];
- assert_int_equal(1, lysc_feature_value(f1));
-
- /* enable orfeature */
- f = &mod.compiled->features[3];
- assert_int_equal(0, lysc_feature_value(f));
- assert_int_equal(LY_SUCCESS, lys_feature_enable(&mod, "orfeature"));
- assert_int_equal(1, lysc_feature_value(f));
-
- /* enable andfeature - no possible since f2 is disabled */
- f = &mod.compiled->features[4];
- assert_int_equal(0, lysc_feature_value(f));
- assert_int_equal(LY_EDENIED, lys_feature_enable(&mod, "andfeature"));
- logbuf_assert("Feature \"andfeature\" cannot be enabled since it is disabled by its if-feature condition(s).");
- assert_int_equal(0, lysc_feature_value(f));
-
- /* first enable f2, so f5 can be enabled then */
- assert_int_equal(LY_SUCCESS, lys_feature_enable(&mod, "f2"));
- assert_int_equal(LY_SUCCESS, lys_feature_enable(&mod, "andfeature"));
- assert_int_equal(1, lysc_feature_value(f));
-
- /* f1 is enabled, so f6 cannot be enabled */
- f = &mod.compiled->features[5];
- assert_int_equal(0, lysc_feature_value(f));
- assert_int_equal(LY_EDENIED, lys_feature_enable(&mod, "f6"));
- logbuf_assert("Feature \"f6\" cannot be enabled since it is disabled by its if-feature condition(s).");
- assert_int_equal(0, lysc_feature_value(f));
-
- /* so disable f1 - andfeature will became also disabled */
- assert_int_equal(1, lysc_feature_value(f1));
- assert_int_equal(LY_SUCCESS, lys_feature_disable(&mod, "f1"));
- assert_int_equal(0, lysc_feature_value(f1));
- assert_int_equal(0, lysc_feature_value(&mod.compiled->features[4]));
- /* while orfeature is stille enabled */
- assert_int_equal(1, lysc_feature_value(&mod.compiled->features[3]));
- /* and finally f6 can be enabled */
- assert_int_equal(LY_SUCCESS, lys_feature_enable(&mod, "f6"));
- assert_int_equal(1, lysc_feature_value(&mod.compiled->features[5]));
-
- /* complex evaluation of f7: f1 and f3 are disabled, while f2 is enabled */
- assert_int_equal(1, lysc_iffeature_value(&mod.compiled->features[6].iffeatures[0]));
- /* long evaluation of f8 to need to reallocate internal stack for operators */
- assert_int_equal(1, lysc_iffeature_value(&mod.compiled->features[7].iffeatures[0]));
-
- /* double negation of disabled f1 -> disabled */
- assert_int_equal(0, lysc_iffeature_value(&mod.compiled->features[8].iffeatures[0]));
-
- /* disable all features */
- assert_int_equal(LY_SUCCESS, lys_feature_disable(&mod, "*"));
- LY_ARRAY_FOR(mod.compiled->features, struct lysc_feature, f) {
- assert_int_equal(0, lys_feature_value(&mod, f->name));
- }
- /* re-setting already set feature */
- assert_int_equal(LY_SUCCESS, lys_feature_disable(&mod, "f1"));
- assert_int_equal(0, lys_feature_value(&mod, "f1"));
-
- /* enabling feature that cannot be enabled due to its if-features */
- assert_int_equal(LY_SUCCESS, lys_feature_enable(&mod, "f1"));
- assert_int_equal(LY_EDENIED, lys_feature_enable(&mod, "andfeature"));
- logbuf_assert("Feature \"andfeature\" cannot be enabled since it is disabled by its if-feature condition(s).");
- assert_int_equal(LY_EDENIED, lys_feature_enable(&mod, "*"));
- logbuf_assert("Feature \"f6\" cannot be enabled since it is disabled by its if-feature condition(s).");
- /* test if not changed */
- assert_int_equal(1, lys_feature_value(&mod, "f1"));
- assert_int_equal(0, lys_feature_value(&mod, "f2"));
-
- assert_non_null(modp = lys_parse_mem(mod.ctx, "module b {namespace urn:b;prefix b;"
- "feature f1 {if-feature f2;}feature f2;}", LYS_IN_YANG));
- assert_non_null(modp->compiled);
- assert_non_null(modp->compiled->features);
- assert_int_equal(2, LY_ARRAY_SIZE(modp->compiled->features));
- assert_non_null(modp->compiled->features[0].iffeatures);
- assert_int_equal(1, LY_ARRAY_SIZE(modp->compiled->features[0].iffeatures));
- assert_non_null(modp->compiled->features[0].iffeatures[0].features);
- assert_int_equal(1, LY_ARRAY_SIZE(modp->compiled->features[0].iffeatures[0].features));
- assert_ptr_equal(&modp->compiled->features[1], modp->compiled->features[0].iffeatures[0].features[0]);
- assert_non_null(modp->compiled->features);
- assert_int_equal(2, LY_ARRAY_SIZE(modp->compiled->features));
- assert_non_null(modp->compiled->features[1].depfeatures);
- assert_int_equal(1, LY_ARRAY_SIZE(modp->compiled->features[1].depfeatures));
- assert_ptr_equal(&modp->compiled->features[0], modp->compiled->features[1].depfeatures[0]);
-
- /* invalid reference */
- assert_int_equal(LY_EINVAL, lys_feature_enable(&mod, "xxx"));
- logbuf_assert("Feature \"xxx\" not found in module \"a\".");
-
- reset_mod(&mod);
-
- /* some invalid expressions */
- assert_int_equal(LY_SUCCESS, yang_parse_module(&ctx, "module b{yang-version 1.1;namespace urn:b; prefix b; feature f{if-feature f1;}}", &mod));
- yang_parser_ctx_free(ctx);
- assert_int_equal(LY_EVALID, lys_compile(&mod, 0));
- logbuf_assert("Invalid value \"f1\" of if-feature - unable to find feature \"f1\". /b:{feature='f'}");
- reset_mod(&mod);
-
- assert_int_equal(LY_SUCCESS, yang_parse_module(&ctx, "module b{yang-version 1.1;namespace urn:b; prefix b; feature f1; feature f2{if-feature 'f and';}}", &mod));
- yang_parser_ctx_free(ctx);
- assert_int_equal(LY_EVALID, lys_compile(&mod, 0));
- logbuf_assert("Invalid value \"f and\" of if-feature - unexpected end of expression. /b:{feature='f2'}");
- reset_mod(&mod);
-
- assert_int_equal(LY_SUCCESS, yang_parse_module(&ctx, "module b{yang-version 1.1;namespace urn:b; prefix b; feature f{if-feature 'or';}}", &mod));
- yang_parser_ctx_free(ctx);
- assert_int_equal(LY_EVALID, lys_compile(&mod, 0));
- logbuf_assert("Invalid value \"or\" of if-feature - unexpected end of expression. /b:{feature='f'}");
- reset_mod(&mod);
-
- assert_int_equal(LY_SUCCESS, yang_parse_module(&ctx, "module b{yang-version 1.1;namespace urn:b; prefix b; feature f1; feature f2{if-feature '(f1';}}", &mod));
- yang_parser_ctx_free(ctx);
- assert_int_equal(LY_EVALID, lys_compile(&mod, 0));
- logbuf_assert("Invalid value \"(f1\" of if-feature - non-matching opening and closing parentheses. /b:{feature='f2'}");
- reset_mod(&mod);
-
- assert_int_equal(LY_SUCCESS, yang_parse_module(&ctx, "module b{yang-version 1.1;namespace urn:b; prefix b; feature f1; feature f2{if-feature 'f1)';}}", &mod));
- yang_parser_ctx_free(ctx);
- assert_int_equal(LY_EVALID, lys_compile(&mod, 0));
- logbuf_assert("Invalid value \"f1)\" of if-feature - non-matching opening and closing parentheses. /b:{feature='f2'}");
- reset_mod(&mod);
-
- assert_int_equal(LY_SUCCESS, yang_parse_module(&ctx, "module b{yang-version 1.1;namespace urn:b; prefix b; feature f1; feature f2{if-feature ---;}}", &mod));
- yang_parser_ctx_free(ctx);
- assert_int_equal(LY_EVALID, lys_compile(&mod, 0));
- logbuf_assert("Invalid value \"---\" of if-feature - unable to find feature \"---\". /b:{feature='f2'}");
- reset_mod(&mod);
-
- assert_int_equal(LY_SUCCESS, yang_parse_module(&ctx, "module b{namespace urn:b; prefix b; feature f1; feature f2{if-feature 'not f1';}}", &mod));
- yang_parser_ctx_free(ctx);
- assert_int_equal(LY_EVALID, lys_compile(&mod, 0));
- logbuf_assert("Invalid value \"not f1\" of if-feature - YANG 1.1 expression in YANG 1.0 module. /b:{feature='f2'}");
- reset_mod(&mod);
-
- assert_int_equal(LY_SUCCESS, yang_parse_module(&ctx, "module b{namespace urn:b; prefix b; feature f1; feature f1;}", &mod));
- yang_parser_ctx_free(ctx);
- assert_int_equal(LY_EVALID, lys_compile(&mod, 0));
- logbuf_assert("Duplicate identifier \"f1\" of feature statement. /b:{feature='f1'}");
- reset_mod(&mod);
-
- ly_ctx_set_module_imp_clb(mod.ctx, test_imp_clb, "submodule sz {belongs-to z {prefix z;} feature f1;}");
- assert_null(lys_parse_mem(mod.ctx, "module z{namespace urn:z; prefix z; include sz;feature f1;}", LYS_IN_YANG));
- logbuf_assert("Duplicate identifier \"f1\" of feature statement. /z:{feature='f1'}");
-
- assert_null(lys_parse_mem(mod.ctx, "module aa{namespace urn:aa; prefix aa; feature f1 {if-feature f2;} feature f2 {if-feature f1;}}", LYS_IN_YANG));
- logbuf_assert("Feature \"f1\" is indirectly referenced from itself. /aa:{feature='f2'}");
- assert_null(lys_parse_mem(mod.ctx, "module ab{namespace urn:ab; prefix ab; feature f1 {if-feature f1;}}", LYS_IN_YANG));
- logbuf_assert("Feature \"f1\" is referenced from itself. /ab:{feature='f1'}");
-
- assert_null(lys_parse_mem(mod.ctx, "module bb{yang-version 1.1; namespace urn:bb; prefix bb; feature f {if-feature ();}}", LYS_IN_YANG));
- logbuf_assert("Invalid value \"()\" of if-feature - number of features in expression does not match the required number "
- "of operands for the operations. /bb:{feature='f'}");
- assert_null(lys_parse_mem(mod.ctx, "module bb{yang-version 1.1; namespace urn:bb; prefix bb; feature f1; feature f {if-feature 'f1(';}}", LYS_IN_YANG));
- logbuf_assert("Invalid value \"f1(\" of if-feature - non-matching opening and closing parentheses. /bb:{feature='f'}");
- assert_null(lys_parse_mem(mod.ctx, "module bb{yang-version 1.1; namespace urn:bb; prefix bb; feature f1; feature f {if-feature 'and f1';}}", LYS_IN_YANG));
- logbuf_assert("Invalid value \"and f1\" of if-feature - missing feature/expression before \"and\" operation. /bb:{feature='f'}");
- assert_null(lys_parse_mem(mod.ctx, "module bb{yang-version 1.1; namespace urn:bb; prefix bb; feature f1; feature f {if-feature 'f1 not ';}}", LYS_IN_YANG));
- logbuf_assert("Invalid value \"f1 not \" of if-feature - unexpected end of expression. /bb:{feature='f'}");
- assert_null(lys_parse_mem(mod.ctx, "module bb{yang-version 1.1; namespace urn:bb; prefix bb; feature f1; feature f {if-feature 'f1 not not ';}}", LYS_IN_YANG));
- logbuf_assert("Invalid value \"f1 not not \" of if-feature - unexpected end of expression. /bb:{feature='f'}");
- assert_null(lys_parse_mem(mod.ctx, "module bb{yang-version 1.1; namespace urn:bb; prefix bb; feature f1; feature f2; "
- "feature f {if-feature 'or f1 f2';}}", LYS_IN_YANG));
- logbuf_assert("Invalid value \"or f1 f2\" of if-feature - missing feature/expression before \"or\" operation. /bb:{feature='f'}");
-
- /* import reference */
- assert_non_null(modp = lys_parse_mem(mod.ctx, str, LYS_IN_YANG));
- assert_int_equal(LY_SUCCESS, lys_feature_enable(modp, "f1"));
- assert_non_null(modp = lys_parse_mem(mod.ctx, "module c{namespace urn:c; prefix c; import a {prefix a;} feature f1; feature f2{if-feature 'a:f1';}}", LYS_IN_YANG));
- assert_int_equal(LY_SUCCESS, lys_feature_enable(modp, "f2"));
- assert_int_equal(0, lys_feature_value(modp, "f1"));
- assert_int_equal(1, lys_feature_value(modp, "f2"));
-
- *state = NULL;
- ly_ctx_destroy(mod.ctx, NULL);
-}
-
-static void
-test_identity(void **state)
-{
- *state = test_identity;
-
- struct ly_ctx *ctx;
- struct lys_module *mod1, *mod2;
-
- assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, LY_CTX_DISABLE_SEARCHDIRS, &ctx));
- assert_non_null(mod1 = lys_parse_mem(ctx, "module a {namespace urn:a;prefix a; identity a1;}", LYS_IN_YANG));
- assert_non_null(mod2 = lys_parse_mem(ctx, "module b {yang-version 1.1;namespace urn:b;prefix b; import a {prefix a;}"
- "identity b1; identity b2; identity b3 {base b1; base b:b2; base a:a1;}"
- "identity b4 {base b:b1; base b3;}}", LYS_IN_YANG));
-
- assert_non_null(mod1->compiled);
- assert_non_null(mod1->compiled->identities);
- assert_non_null(mod2->compiled);
- assert_non_null(mod2->compiled->identities);
-
- assert_non_null(mod1->compiled->identities[0].derived);
- assert_int_equal(1, LY_ARRAY_SIZE(mod1->compiled->identities[0].derived));
- assert_ptr_equal(mod1->compiled->identities[0].derived[0], &mod2->compiled->identities[2]);
- assert_non_null(mod2->compiled->identities[0].derived);
- assert_int_equal(2, LY_ARRAY_SIZE(mod2->compiled->identities[0].derived));
- assert_ptr_equal(mod2->compiled->identities[0].derived[0], &mod2->compiled->identities[2]);
- assert_ptr_equal(mod2->compiled->identities[0].derived[1], &mod2->compiled->identities[3]);
- assert_non_null(mod2->compiled->identities[1].derived);
- assert_int_equal(1, LY_ARRAY_SIZE(mod2->compiled->identities[1].derived));
- assert_ptr_equal(mod2->compiled->identities[1].derived[0], &mod2->compiled->identities[2]);
- assert_non_null(mod2->compiled->identities[2].derived);
- assert_int_equal(1, LY_ARRAY_SIZE(mod2->compiled->identities[2].derived));
- assert_ptr_equal(mod2->compiled->identities[2].derived[0], &mod2->compiled->identities[3]);
-
- assert_non_null(mod2 = lys_parse_mem(ctx, "module c {yang-version 1.1;namespace urn:c;prefix c;"
- "identity c2 {base c1;} identity c1;}", LYS_IN_YANG));
- assert_int_equal(1, LY_ARRAY_SIZE(mod2->compiled->identities[1].derived));
- assert_ptr_equal(mod2->compiled->identities[1].derived[0], &mod2->compiled->identities[0]);
-
- assert_null(lys_parse_mem(ctx, "module aa{namespace urn:aa; prefix aa; identity i1;identity i1;}", LYS_IN_YANG));
- logbuf_assert("Duplicate identifier \"i1\" of identity statement. /aa:{identity='i1'}");
-
- ly_ctx_set_module_imp_clb(ctx, test_imp_clb, "submodule sbb {belongs-to bb {prefix bb;} identity i1;}");
- assert_null(lys_parse_mem(ctx, "module bb{namespace urn:bb; prefix bb; include sbb;identity i1;}", LYS_IN_YANG));
- logbuf_assert("Duplicate identifier \"i1\" of identity statement. /bb:{identity='i1'}");
-
- assert_null(lys_parse_mem(ctx, "module cc{namespace urn:cc; prefix cc; identity i1 {base i2;}}", LYS_IN_YANG));
- logbuf_assert("Unable to find base (i2) of identity \"i1\". /cc:{identity='i1'}");
-
- assert_null(lys_parse_mem(ctx, "module dd{namespace urn:dd; prefix dd; identity i1 {base i1;}}", LYS_IN_YANG));
- logbuf_assert("Identity \"i1\" is derived from itself. /dd:{identity='i1'}");
- assert_null(lys_parse_mem(ctx, "module de{namespace urn:de; prefix de; identity i1 {base i2;}identity i2 {base i3;}identity i3 {base i1;}}", LYS_IN_YANG));
- logbuf_assert("Identity \"i1\" is indirectly derived from itself. /de:{identity='i3'}");
-
- *state = NULL;
- ly_ctx_destroy(ctx, NULL);
-}
static void
test_node_container(void **state)
@@ -3581,8 +3319,6 @@
{
const struct CMUnitTest tests[] = {
cmocka_unit_test_setup_teardown(test_module, logger_setup, logger_teardown),
- cmocka_unit_test_setup_teardown(test_feature, logger_setup, logger_teardown),
- cmocka_unit_test_setup_teardown(test_identity, logger_setup, logger_teardown),
cmocka_unit_test_setup_teardown(test_type_length, logger_setup, logger_teardown),
cmocka_unit_test_setup_teardown(test_type_range, logger_setup, logger_teardown),
cmocka_unit_test_setup_teardown(test_type_pattern, logger_setup, logger_teardown),
diff --git a/tests/src/test_common.c b/tests/utests/test_common.c
similarity index 100%
rename from tests/src/test_common.c
rename to tests/utests/test_common.c
diff --git a/tests/src/test_context.c b/tests/utests/test_context.c
similarity index 97%
rename from tests/src/test_context.c
rename to tests/utests/test_context.c
index a70a01a..d9b8e9f 100644
--- a/tests/src/test_context.c
+++ b/tests/utests/test_context.c
@@ -96,8 +96,8 @@
logbuf_assert("Invalid argument ctx (ly_ctx_unset_searchdirs()).");
/* readable and executable, but not a directory */
- assert_int_equal(LY_EINVAL, ly_ctx_set_searchdir(ctx, TESTS_BIN"/src_context"));
- logbuf_assert("Given search directory \""TESTS_BIN"/src_context\" is not a directory.");
+ assert_int_equal(LY_EINVAL, ly_ctx_set_searchdir(ctx, TESTS_BIN"/utest_context"));
+ logbuf_assert("Given search directory \""TESTS_BIN"/utest_context\" is not a directory.");
/* not executable */
assert_int_equal(LY_EINVAL, ly_ctx_set_searchdir(ctx, __FILE__));
logbuf_assert("Unable to fully access search directory \""__FILE__"\" (Permission denied).");
@@ -110,14 +110,14 @@
assert_int_equal(LY_SUCCESS, ly_ctx_set_searchdir(ctx, NULL));
/* correct path */
- assert_int_equal(LY_SUCCESS, ly_ctx_set_searchdir(ctx, TESTS_BIN"/src"));
+ assert_int_equal(LY_SUCCESS, ly_ctx_set_searchdir(ctx, TESTS_BIN"/utests"));
assert_int_equal(1, ctx->search_paths.count);
- assert_string_equal(TESTS_BIN"/src", ctx->search_paths.objs[0]);
+ assert_string_equal(TESTS_BIN"/utests", ctx->search_paths.objs[0]);
/* duplicated paths */
- assert_int_equal(LY_EEXIST, ly_ctx_set_searchdir(ctx, TESTS_BIN"/src"));
+ assert_int_equal(LY_EEXIST, ly_ctx_set_searchdir(ctx, TESTS_BIN"/utests"));
assert_int_equal(1, ctx->search_paths.count);
- assert_string_equal(TESTS_BIN"/src", ctx->search_paths.objs[0]);
+ assert_string_equal(TESTS_BIN"/utests", ctx->search_paths.objs[0]);
/* another paths - add 8 to fill the initial buffer of the searchpaths list */
assert_int_equal(LY_SUCCESS, ly_ctx_set_searchdir(ctx, TESTS_BIN"/CMakeFiles"));
@@ -132,7 +132,7 @@
/* get searchpaths */
list = ly_ctx_get_searchdirs(ctx);
assert_non_null(list);
- assert_string_equal(TESTS_BIN"/src", list[0]);
+ assert_string_equal(TESTS_BIN"/utests", list[0]);
assert_string_equal(TESTS_BIN"/CMakeFiles", list[1]);
assert_string_equal(TESTS_SRC, list[5]);
assert_string_equal(TESTS_BIN, list[6]);
@@ -144,8 +144,8 @@
assert_int_equal(LY_EINVAL, ly_ctx_unset_searchdirs(ctx, "/nonexistingfile"));
logbuf_assert("Invalid argument value (ly_ctx_unset_searchdirs()).");
/* first */
- assert_int_equal(LY_SUCCESS, ly_ctx_unset_searchdirs(ctx, TESTS_BIN"/src"));
- assert_string_not_equal(TESTS_BIN"/src", list[0]);
+ assert_int_equal(LY_SUCCESS, ly_ctx_unset_searchdirs(ctx, TESTS_BIN"/utests"));
+ assert_string_not_equal(TESTS_BIN"/utests", list[0]);
assert_int_equal(7, ctx->search_paths.count);
/* middle */
assert_int_equal(LY_SUCCESS, ly_ctx_unset_searchdirs(ctx, TESTS_SRC));
diff --git a/tests/src/test_hash_table.c b/tests/utests/test_hash_table.c
similarity index 100%
rename from tests/src/test_hash_table.c
rename to tests/utests/test_hash_table.c
diff --git a/tests/src/test_set.c b/tests/utests/test_set.c
similarity index 100%
rename from tests/src/test_set.c
rename to tests/utests/test_set.c
diff --git a/tests/src/test_xml.c b/tests/utests/test_xml.c
similarity index 100%
rename from tests/src/test_xml.c
rename to tests/utests/test_xml.c