path FEATURE new compiled path structure (#1108)
Refactoring includes using it for
instance-identifier and for checking leafref,
it is evaluated using stanrad XPath. Predicates
used for lyd_new_list2(), tests included.
diff --git a/tests/utests/CMakeLists.txt b/tests/utests/CMakeLists.txt
index c236413..39b1854 100644
--- a/tests/utests/CMakeLists.txt
+++ b/tests/utests/CMakeLists.txt
@@ -13,6 +13,7 @@
utest:schema/test_printer_yang
utest:schema/test_printer_yin
utest:data/test_tree_data
+ utest:data/test_new
utest:data/test_parser_xml
utest:data/test_printer_xml
utest:data/test_validation
@@ -39,6 +40,7 @@
" "
" "
" "
+ " "
" ")
set(tests ${tests} ${local_tests} PARENT_SCOPE)
set(tests_wraps ${tests_wraps} ${local_tests_wraps} PARENT_SCOPE)
diff --git a/tests/utests/data/test_new.c b/tests/utests/data/test_new.c
new file mode 100644
index 0000000..766bbff
--- /dev/null
+++ b/tests/utests/data/test_new.c
@@ -0,0 +1,214 @@
+/**
+ * @file test_new.c
+ * @author: Michal Vasko <mvasko@cesnet.cz>
+ * @brief unit tests for functions for creating data
+ *
+ * Copyright (c) 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 "../../src/libyang.h"
+
+#define BUFSIZE 1024
+char logbuf[BUFSIZE] = {0};
+int store = -1; /* negative for infinite logging, positive for limited logging */
+
+struct ly_ctx *ctx; /* context for tests */
+
+/* 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
+setup(void **state)
+{
+ (void) state; /* unused */
+
+ const char *schema_a = "module a {namespace urn:tests:a;prefix a;yang-version 1.1;"
+ "list l1 { key \"a b\"; leaf a {type string;} leaf b {type string;} leaf c {type string;}}"
+ "leaf foo { type uint16;}"
+ "leaf-list ll { type string;}"
+ "container c {leaf-list x {type string;}}"
+ "anydata any {config false;}"
+ "list l2 {config false; container c{leaf x {type string;}}}}";
+
+#if ENABLE_LOGGER_CHECKING
+ ly_set_log_clb(logger, 1);
+#endif
+
+ assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, 0, &ctx));
+ assert_non_null(lys_parse_mem(ctx, schema_a, LYS_IN_YANG));
+
+ return 0;
+}
+
+static int
+teardown(void **state)
+{
+#if ENABLE_LOGGER_CHECKING
+ if (*state) {
+ fprintf(stderr, "%s\n", logbuf);
+ }
+#else
+ (void) state; /* unused */
+#endif
+
+ ly_ctx_destroy(ctx, NULL);
+ ctx = NULL;
+
+ 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_top_level(void **state)
+{
+ *state = test_top_level;
+
+ const struct lys_module *mod;
+ struct lyd_node *node;
+
+ /* we need the module first */
+ mod = ly_ctx_get_module_implemented(ctx, "a");
+ assert_non_null(mod);
+
+ /* list */
+ node = lyd_new_list(NULL, mod, "l1", "val_a", "val_b");
+ assert_non_null(node);
+ lyd_free_tree(node);
+
+ node = lyd_new_list2(NULL, mod, "l1", "[]");
+ assert_null(node);
+ logbuf_assert("Unexpected XPath token ] (]).");
+
+ node = lyd_new_list2(NULL, mod, "l1", "[key1='a'][key2='b']");
+ assert_null(node);
+ logbuf_assert("Not found node \"key1\" in path.");
+
+ node = lyd_new_list2(NULL, mod, "l1", "[a='a'][b='b'][c='c']");
+ assert_null(node);
+ logbuf_assert("Key expected instead of leaf \"c\" in path. /a:l1/c");
+
+ node = lyd_new_list2(NULL, mod, "c", "[a='a'][b='b']");
+ assert_null(node);
+ logbuf_assert("List node \"c\" not found.");
+
+ node = lyd_new_list2(NULL, mod, "l1", "[a='a'][b='b']");
+ assert_non_null(node);
+ lyd_free_tree(node);
+
+ node = lyd_new_list2(NULL, mod, "l1", "[a=''][b='']");
+ assert_non_null(node);
+ lyd_free_tree(node);
+
+ node = lyd_new_list2(NULL, mod, "l1", "[a:a='a'][a:b='b']");
+ assert_non_null(node);
+ lyd_free_tree(node);
+
+ node = lyd_new_list2(NULL, mod, "l1", "[a= 'a']\n[b =\t'b']");
+ assert_non_null(node);
+ lyd_free_tree(node);
+
+ /* leaf */
+ node = lyd_new_term(NULL, mod, "foo", "[a='a'][b='b'][c='c']");
+ assert_null(node);
+ logbuf_assert("Invalid uint16 value \"[a='a'][b='b'][c='c']\". /a:foo");
+
+ node = lyd_new_term(NULL, mod, "c", "value");
+ assert_null(node);
+ logbuf_assert("Term node \"c\" not found.");
+
+ node = lyd_new_term(NULL, mod, "foo", "256");
+ assert_non_null(node);
+ lyd_free_tree(node);
+
+ /* leaf-list */
+ node = lyd_new_term(NULL, mod, "ll", "ahoy");
+ assert_non_null(node);
+ lyd_free_tree(node);
+
+ /* container */
+ node = lyd_new_inner(NULL, mod, "c");
+ assert_non_null(node);
+ lyd_free_tree(node);
+
+ node = lyd_new_inner(NULL, mod, "l1");
+ assert_null(node);
+ logbuf_assert("Inner node (and not a list) \"l1\" not found.");
+
+ node = lyd_new_inner(NULL, mod, "l2");
+ assert_null(node);
+ logbuf_assert("Inner node (and not a list) \"l2\" not found.");
+
+ /* anydata */
+ node = lyd_new_any(NULL, mod, "any", "some-value", LYD_ANYDATA_STRING);
+ assert_non_null(node);
+ lyd_free_tree(node);
+
+ /* key-less list */
+ node = lyd_new_list2(NULL, mod, "l2", "[a='a'][b='b']");
+ assert_null(node);
+ logbuf_assert("List predicate defined for keyless list \"l2\" in path.");
+
+ node = lyd_new_list2(NULL, mod, "l2", "");
+ assert_non_null(node);
+ lyd_free_tree(node);
+
+ node = lyd_new_list2(NULL, mod, "l2", NULL);
+ assert_non_null(node);
+ lyd_free_tree(node);
+
+ node = lyd_new_list(NULL, mod, "l2");
+ assert_non_null(node);
+ lyd_free_tree(node);
+
+ *state = NULL;
+}
+
+int main(void)
+{
+ const struct CMUnitTest tests[] = {
+ cmocka_unit_test_setup_teardown(test_top_level, setup, teardown),
+ };
+
+ return cmocka_run_group_tests(tests, NULL, NULL);
+}
diff --git a/tests/utests/data/test_tree_data.c b/tests/utests/data/test_tree_data.c
index ecba711..0a1075c 100644
--- a/tests/utests/data/test_tree_data.c
+++ b/tests/utests/data/test_tree_data.c
@@ -1,4 +1,4 @@
-/*
+/**
* @file test_tree_schema.c
* @author: Radek Krejci <rkrejci@cesnet.cz>
* @brief unit tests for functions from tress_data.c
diff --git a/tests/utests/data/test_types.c b/tests/utests/data/test_types.c
index dc5db56..59368fa 100644
--- a/tests/utests/data/test_types.c
+++ b/tests/utests/data/test_types.c
@@ -21,6 +21,7 @@
#include <string.h>
#include "../../src/libyang.h"
+#include "../../src/path.h"
#define BUFSIZE 1024
char logbuf[BUFSIZE] = {0};
@@ -70,6 +71,7 @@
"list list2 {key \"id value\"; leaf id {type string;} leaf value {type string;}}"
"list list_inst {key id; leaf id {type instance-identifier {require-instance true;}} leaf value {type string;}}"
"list list_ident {key id; leaf id {type identityref {base defs:interface-type;}} leaf value {type string;}}"
+ "list list_keyless {config \"false\"; leaf id {type string;} leaf value {type string;}}"
"leaf-list leaflisttarget {type string;}"
"leaf binary {type binary {length 5 {error-message \"This base64 value must be of length 5.\";}}}"
"leaf binary-norestr {type binary;}"
@@ -858,16 +860,6 @@
assert_null(leaf->value.canonical_cache);
lyd_free_all(tree);
- data = "<list xmlns=\"urn:tests:types\"><id>a</id></list><list xmlns=\"urn:tests:types\"><id>b</id><value>x</value></list>"
- "<xdf:inst xmlns:xdf=\"urn:tests:types\">/xdf:list[2]/xdf:value</xdf:inst>";
- assert_non_null(tree = lyd_parse_mem(s->ctx, data, LYD_XML, LYD_VALOPT_DATA_ONLY));
- tree = tree->prev->prev;
- assert_int_equal(LYS_LEAF, tree->schema->nodetype);
- assert_string_equal("inst", tree->schema->name);
- leaf = (const struct lyd_node_term*)tree;
- assert_null(leaf->value.canonical_cache);
- lyd_free_all(tree);
-
data = "<list_inst xmlns=\"urn:tests:types\"><id xmlns:b=\"urn:tests:types\">/b:leaflisttarget[.='a']</id><value>x</value></list_inst>"
"<list_inst xmlns=\"urn:tests:types\"><id xmlns:b=\"urn:tests:types\">/b:leaflisttarget[.='b']</id><value>y</value></list_inst>"
"<leaflisttarget xmlns=\"urn:tests:types\">a</leaflisttarget><leaflisttarget xmlns=\"urn:tests:types\">b</leaflisttarget>"
@@ -898,10 +890,20 @@
value.realtype->plugin->free(s->ctx, &value);
lyd_free_all(tree);
- data = "<list_inst xmlns=\"urn:tests:types\"><id xmlns:b=\"urn:tests:types\">/b:leaflisttarget[1]</id><value>x</value></list_inst>"
- "<list_inst xmlns=\"urn:tests:types\"><id xmlns:b=\"urn:tests:types\">/b:leaflisttarget[2]</id><value>y</value></list_inst>"
+ data = "<list xmlns=\"urn:tests:types\"><id>a</id></list><list xmlns=\"urn:tests:types\"><id>b</id><value>x</value></list>"
+ "<xdf:inst xmlns:xdf=\"urn:tests:types\">/xdf:list[xdf:id='b']/xdf:value</xdf:inst>";
+ assert_non_null(tree = lyd_parse_mem(s->ctx, data, LYD_XML, LYD_VALOPT_DATA_ONLY));
+ tree = tree->prev->prev;
+ assert_int_equal(LYS_LEAF, tree->schema->nodetype);
+ assert_string_equal("inst", tree->schema->name);
+ leaf = (const struct lyd_node_term*)tree;
+ assert_null(leaf->value.canonical_cache);
+ lyd_free_all(tree);
+
+ data = "<list_inst xmlns=\"urn:tests:types\"><id xmlns:b=\"urn:tests:types\">/b:leaflisttarget[.='a']</id><value>x</value></list_inst>"
+ "<list_inst xmlns=\"urn:tests:types\"><id xmlns:b=\"urn:tests:types\">/b:leaflisttarget[.='b']</id><value>y</value></list_inst>"
"<leaflisttarget xmlns=\"urn:tests:types\">a</leaflisttarget><leaflisttarget xmlns=\"urn:tests:types\">b</leaflisttarget>"
- "<a:inst xmlns:a=\"urn:tests:types\">/a:list_inst[a:id=\"/a:leaflisttarget[2]\"]/a:value</a:inst>";
+ "<a:inst xmlns:a=\"urn:tests:types\">/a:list_inst[a:id=\"/a:leaflisttarget[.='a']\"]/a:value</a:inst>";
assert_non_null(tree = lyd_parse_mem(s->ctx, data, LYD_XML, LYD_VALOPT_DATA_ONLY));
tree = tree->prev->prev;
assert_int_equal(LYS_LEAF, tree->schema->nodetype);
@@ -934,7 +936,7 @@
data = "<list xmlns=\"urn:tests:types\"><id>types:xxx</id><value>x</value></list>"
"<list xmlns=\"urn:tests:types\"><id>a:xxx</id><value>y</value></list>"
- "<a:inst xmlns:a=\"urn:tests:types\">/a:list[2]/a:value</a:inst>";
+ "<a:inst xmlns:a=\"urn:tests:types\">/a:list[a:id='a:xxx']/a:value</a:inst>";
assert_non_null(tree = lyd_parse_mem(s->ctx, data, LYD_XML, LYD_VALOPT_DATA_ONLY));
tree = tree->prev->prev;
assert_int_equal(LYS_LEAF, tree->schema->nodetype);
@@ -958,25 +960,30 @@
lyd_free_all(tree);
/* invalid value */
+ data = "<list xmlns=\"urn:tests:types\"><id>a</id></list><list xmlns=\"urn:tests:types\"><id>b</id><value>x</value></list>"
+ "<xdf:inst xmlns:xdf=\"urn:tests:types\">/xdf:list[2]/xdf:value</xdf:inst>";
+ assert_null(lyd_parse_mem(s->ctx, data, LYD_XML, LYD_VALOPT_DATA_ONLY));
+ logbuf_assert("Invalid instance-identifier \"/xdf:list[2]/xdf:value\" value - semantic error. /types:inst");
+
data = "<t:inst xmlns:t=\"urn:tests:types\">/t:cont/t:1leaftarget</t:inst>";
assert_null(lyd_parse_mem(s->ctx, data, LYD_XML, LYD_VALOPT_DATA_ONLY));
- logbuf_assert("Invalid instance-identifier \"/t:cont/t:1leaftarget\" value at character 11 (1leaftarget). /types:inst");
+ logbuf_assert("Invalid instance-identifier \"/t:cont/t:1leaftarget\" value - syntax error. /types:inst");
data = "<t:inst xmlns:t=\"urn:tests:types\">/t:cont:t:1leaftarget</t:inst>";
assert_null(lyd_parse_mem(s->ctx, data, LYD_XML, LYD_VALOPT_DATA_ONLY));
- logbuf_assert("Invalid instance-identifier \"/t:cont:t:1leaftarget\" value at character 8 (:t:1leaftarget). /types:inst");
+ logbuf_assert("Invalid instance-identifier \"/t:cont:t:1leaftarget\" value - syntax error. /types:inst");
data = "<t:inst xmlns:t=\"urn:tests:types\">/t:cont/t:invalid/t:path</t:inst>";
assert_null(lyd_parse_mem(s->ctx, data, LYD_XML, LYD_VALOPT_DATA_ONLY));
- logbuf_assert("Invalid instance-identifier \"/t:cont/t:invalid/t:path\" value - path \"/t:cont/t:invalid\" does not exists in the YANG schema. /types:inst");
+ logbuf_assert("Invalid instance-identifier \"/t:cont/t:invalid/t:path\" value - semantic error. /types:inst");
data = "<inst xmlns=\"urn:tests:types\" xmlns:t=\"urn:tests:invalid\">/t:cont/t:leaftarget</inst>";
assert_null(lyd_parse_mem(s->ctx, data, LYD_XML, LYD_VALOPT_DATA_ONLY));
- logbuf_assert("Invalid instance-identifier \"/t:cont/t:leaftarget\" value - unable to map prefix \"t\" to YANG schema. /types:inst");
+ logbuf_assert("Invalid instance-identifier \"/t:cont/t:leaftarget\" value - semantic error. /types:inst");
data = "<inst xmlns=\"urn:tests:types\">/cont/leaftarget</inst>";
assert_null(lyd_parse_mem(s->ctx, data, LYD_XML, LYD_VALOPT_DATA_ONLY));
- logbuf_assert("Invalid instance-identifier \"/cont/leaftarget\" value - all node names (/cont) MUST be qualified with explicit namespace prefix. /types:inst");
+ logbuf_assert("Invalid instance-identifier \"/cont/leaftarget\" value - syntax error. /types:inst");
data = "<cont xmlns=\"urn:tests:types\"/><t:inst xmlns:t=\"urn:tests:types\">/t:cont/t:leaftarget</t:inst>";
assert_null(lyd_parse_mem(s->ctx, data, LYD_XML, LYD_VALOPT_DATA_ONLY));
@@ -990,57 +997,50 @@
data = "<leaflisttarget xmlns=\"urn:tests:types\">x</leaflisttarget><t:inst xmlns:t=\"urn:tests:types\">/t:leaflisttarget[1</t:inst>";
assert_null(lyd_parse_mem(s->ctx, data, LYD_XML, LYD_VALOPT_DATA_ONLY));
- logbuf_assert("Invalid instance-identifier \"/t:leaflisttarget[1\" value's predicate \"[1\" (Predicate (pos) is not terminated by ']' character.). /types:inst");
+ logbuf_assert("Invalid instance-identifier \"/t:leaflisttarget[1\" value - syntax error. /types:inst");
data = "<cont xmlns=\"urn:tests:types\"/><t:inst xmlns:t=\"urn:tests:types\">/t:cont[1]</t:inst>";
assert_null(lyd_parse_mem(s->ctx, data, LYD_XML, LYD_VALOPT_DATA_ONLY));
- logbuf_assert("Invalid instance-identifier \"/t:cont[1]\" value - predicate \"[1]\" for container is not accepted. /types:inst");
+ logbuf_assert("Invalid instance-identifier \"/t:cont[1]\" value - semantic error. /types:inst");
data = "<cont xmlns=\"urn:tests:types\"/><t:inst xmlns:t=\"urn:tests:types\">[1]</t:inst>";
assert_null(lyd_parse_mem(s->ctx, data, LYD_XML, LYD_VALOPT_DATA_ONLY));
- logbuf_assert("Invalid instance-identifier \"[1]\" value - instance-identifier must starts with '/'. /types:inst");
+ logbuf_assert("Invalid instance-identifier \"[1]\" value - syntax error. /types:inst");
data = "<cont xmlns=\"urn:tests:types\"><leaflisttarget>1</leaflisttarget></cont><t:inst xmlns:t=\"urn:tests:types\">/t:cont/t:leaflisttarget[id='1']</t:inst>";
assert_null(lyd_parse_mem(s->ctx, data, LYD_XML, LYD_VALOPT_DATA_ONLY));
- logbuf_assert("Invalid instance-identifier \"/t:cont/t:leaflisttarget[id='1']\" value's predicate \"[id=\" (Missing prefix of a node name.). /types:inst");
+ logbuf_assert("Invalid instance-identifier \"/t:cont/t:leaflisttarget[id='1']\" value - syntax error. /types:inst");
data = "<cont xmlns=\"urn:tests:types\"><leaflisttarget>1</leaflisttarget></cont>"
"<t:inst xmlns:t=\"urn:tests:types\">/t:cont/t:leaflisttarget[t:id='1']</t:inst>";
assert_null(lyd_parse_mem(s->ctx, data, LYD_XML, LYD_VALOPT_DATA_ONLY));
- logbuf_assert("Invalid instance-identifier \"/t:cont/t:leaflisttarget[t:id='1']\" value - key-predicate \"[t:id='1']\""
- " is accepted only for lists, not leaf-list. /types:inst");
+ logbuf_assert("Invalid instance-identifier \"/t:cont/t:leaflisttarget[t:id='1']\" value - semantic error. /types:inst");
data = "<cont xmlns=\"urn:tests:types\"><leaflisttarget>1</leaflisttarget><leaflisttarget>2</leaflisttarget></cont>"
"<t:inst xmlns:t=\"urn:tests:types\">/t:cont/t:leaflisttarget[4]</t:inst>";
assert_null(lyd_parse_mem(s->ctx, data, LYD_XML, LYD_VALOPT_DATA_ONLY));
- /* instance-identifier is here in JSON format because it is already in internal representation without original prefixes */
- logbuf_assert("Invalid instance-identifier \"/types:cont/leaflisttarget[4]\" value - required instance not found. /types:inst");
+ logbuf_assert("Invalid instance-identifier \"/t:cont/t:leaflisttarget[4]\" value - semantic error. /types:inst");
data = "<t:inst-noreq xmlns:t=\"urn:tests:types\">/t:cont/t:leaflisttarget[6]</t:inst-noreq>";
assert_null(lyd_parse_mem(s->ctx, data, LYD_XML, LYD_VALOPT_DATA_ONLY));
- logbuf_assert("Invalid instance-identifier \"/t:cont/t:leaflisttarget[6]\" value - "
- "position-predicate 6 is bigger than allowed max-elements (5). /types:inst-noreq");
+ logbuf_assert("Invalid instance-identifier \"/t:cont/t:leaflisttarget[6]\" value - semantic error. /types:inst-noreq");
data = "<cont xmlns=\"urn:tests:types\"><listtarget><id>1</id><value>x</value></listtarget></cont>"
"<t:inst xmlns:t=\"urn:tests:types\">/t:cont/t:listtarget[t:value='x']</t:inst>";
assert_null(lyd_parse_mem(s->ctx, data, LYD_XML, LYD_VALOPT_DATA_ONLY));
- logbuf_assert("Invalid instance-identifier \"/t:cont/t:listtarget[t:value='x']\" value - "
- "node \"value\" used in key-predicate \"[t:value='x']\" must be a key. /types:inst");
+ logbuf_assert("Invalid instance-identifier \"/t:cont/t:listtarget[t:value='x']\" value - semantic error. /types:inst");
logbuf_clean();
data = "<t:inst-noreq xmlns:t=\"urn:tests:types\">/t:cont/t:listtarget[t:value='x']</t:inst-noreq>";
assert_null(lyd_parse_mem(s->ctx, data, LYD_XML, LYD_VALOPT_DATA_ONLY));
- logbuf_assert("Invalid instance-identifier \"/t:cont/t:listtarget[t:value='x']\" value - "
- "node \"value\" used in key-predicate \"[t:value='x']\" must be a key. /types:inst-noreq");
+ logbuf_assert("Invalid instance-identifier \"/t:cont/t:listtarget[t:value='x']\" value - semantic error. /types:inst-noreq");
data = "<t:inst-noreq xmlns:t=\"urn:tests:types\">/t:cont/t:listtarget[t:x='x']</t:inst-noreq>";
assert_null(lyd_parse_mem(s->ctx, data, LYD_XML, LYD_VALOPT_DATA_ONLY));
- logbuf_assert("Invalid instance-identifier \"/t:cont/t:listtarget[t:x='x']\" value - "
- "path \"/t:cont/t:listtarget[t:x\" does not exists in the YANG schema. /types:inst-noreq");
+ logbuf_assert("Invalid instance-identifier \"/t:cont/t:listtarget[t:x='x']\" value - semantic error. /types:inst-noreq");
data = "<cont xmlns=\"urn:tests:types\"><listtarget><id>1</id><value>x</value></listtarget></cont>"
"<t:inst xmlns:t=\"urn:tests:types\">/t:cont/t:listtarget[.='x']</t:inst>";
assert_null(lyd_parse_mem(s->ctx, data, LYD_XML, LYD_VALOPT_DATA_ONLY));
- logbuf_assert("Invalid instance-identifier \"/t:cont/t:listtarget[.='x']\" value - "
- "leaf-list-predicate \"[.='x']\" is accepted only for leaf-lists, not list. /types:inst");
+ logbuf_assert("Invalid instance-identifier \"/t:cont/t:listtarget[.='x']\" value - semantic error. /types:inst");
data = "<cont xmlns=\"urn:tests:types\"><leaflisttarget>1</leaflisttarget></cont>"
"<t:inst xmlns:t=\"urn:tests:types\">/t:cont/t:leaflisttarget[.='2']</t:inst>";
@@ -1051,14 +1051,12 @@
data = "<cont xmlns=\"urn:tests:types\"><leaflisttarget>1</leaflisttarget></cont>"
"<t:inst xmlns:t=\"urn:tests:types\">/t:cont/t:leaflisttarget[.='x']</t:inst>";
assert_null(lyd_parse_mem(s->ctx, data, LYD_XML, LYD_VALOPT_DATA_ONLY));
- logbuf_assert("Invalid instance-identifier \"/t:cont/t:leaflisttarget[.='x']\" value - "
- "leaf-list-predicate \"[.='x']\"'s value is invalid. /types:inst");
+ logbuf_assert("Invalid instance-identifier \"/t:cont/t:leaflisttarget[.='x']\" value - semantic error. /types:inst");
data = "<cont xmlns=\"urn:tests:types\"><listtarget><id>1</id><value>x</value></listtarget></cont>"
"<t:inst xmlns:t=\"urn:tests:types\">/t:cont/t:listtarget[t:id='x']</t:inst>";
assert_null(lyd_parse_mem(s->ctx, data, LYD_XML, LYD_VALOPT_DATA_ONLY));
- logbuf_assert("Invalid instance-identifier \"/t:cont/t:listtarget[t:id='x']\" value - "
- "key-predicate \"[t:id='x']\"'s key value is invalid. /types:inst");
+ logbuf_assert("Invalid instance-identifier \"/t:cont/t:listtarget[t:id='x']\" value - semantic error. /types:inst");
data = "<cont xmlns=\"urn:tests:types\"><listtarget><id>1</id><value>x</value></listtarget></cont>"
"<t:inst xmlns:t=\"urn:tests:types\">/t:cont/t:listtarget[t:id='2']</t:inst>";
@@ -1070,29 +1068,25 @@
"<leaflisttarget xmlns=\"urn:tests:types\">b</leaflisttarget>"
"<a:inst xmlns:a=\"urn:tests:types\">/a:leaflisttarget[1][2]</a:inst>";
assert_null(lyd_parse_mem(s->ctx, data, LYD_XML, LYD_VALOPT_DATA_ONLY));
- logbuf_assert("Invalid instance-identifier \"/a:leaflisttarget[1][2]\" value - "
- "position predicate (\"[2]\") cannot be used repeatedly for a single node. /types:inst");
+ logbuf_assert("Invalid instance-identifier \"/a:leaflisttarget[1][2]\" value - syntax error. /types:inst");
data = "<leaflisttarget xmlns=\"urn:tests:types\">a</leaflisttarget>"
"<leaflisttarget xmlns=\"urn:tests:types\">b</leaflisttarget>"
"<a:inst xmlns:a=\"urn:tests:types\">/a:leaflisttarget[.='a'][.='b']</a:inst>";
assert_null(lyd_parse_mem(s->ctx, data, LYD_XML, LYD_VALOPT_DATA_ONLY));
- logbuf_assert("Invalid instance-identifier \"/a:leaflisttarget[.='a'][.='b']\" value - "
- "leaf-list-predicate (\"[.='b']\") cannot be used repeatedly for a single node. /types:inst");
+ logbuf_assert("Invalid instance-identifier \"/a:leaflisttarget[.='a'][.='b']\" value - syntax error. /types:inst");
data = "<list xmlns=\"urn:tests:types\"><id>a</id><value>x</value></list>"
"<list xmlns=\"urn:tests:types\"><id>b</id><value>y</value></list>"
"<a:inst xmlns:a=\"urn:tests:types\">/a:list[a:id='a'][a:id='b']/a:value</a:inst>";
assert_null(lyd_parse_mem(s->ctx, data, LYD_XML, LYD_VALOPT_DATA_ONLY));
- logbuf_assert("Invalid instance-identifier \"/a:list[a:id='a'][a:id='b']/a:value\" value - "
- "key \"id\" is referenced the second time in key-predicate \"[a:id='b']\". /types:inst");
+ logbuf_assert("Invalid instance-identifier \"/a:list[a:id='a'][a:id='b']/a:value\" value - syntax error. /types:inst");
data = "<list2 xmlns=\"urn:tests:types\"><id>a</id><value>x</value></list2>"
"<list2 xmlns=\"urn:tests:types\"><id>b</id><value>y</value></list2>"
"<a:inst xmlns:a=\"urn:tests:types\">/a:list2[a:id='a']/a:value</a:inst>";
assert_null(lyd_parse_mem(s->ctx, data, LYD_XML, LYD_VALOPT_DATA_ONLY));
- logbuf_assert("Invalid instance-identifier \"/a:list2[a:id='a']/a:value\" value - "
- "missing 1 key(s) for the list instance \"a:list2[a:id='a']\". /types:inst");
+ logbuf_assert("Invalid instance-identifier \"/a:list2[a:id='a']/a:value\" value - semantic error. /types:inst");
/* check for validting instance-identifier with a complete data tree */
data = "<list2 xmlns=\"urn:tests:types\"><id>a</id><value>a</value></list2>"
@@ -1103,27 +1097,24 @@
assert_non_null(tree = lyd_parse_mem(s->ctx, data, LYD_XML, LYD_VALOPT_DATA_ONLY));
/* key-predicate */
data = "/a:list2[a:id='a'][a:value='b']/a:id";
- assert_int_equal(LY_EVALID, lyd_value_validate(s->ctx, (const struct lyd_node_term*)tree->prev->prev, data, strlen(data),
+ assert_int_equal(LY_ENOTFOUND, lyd_value_validate(s->ctx, (const struct lyd_node_term*)tree->prev->prev, data, strlen(data),
test_instanceid_getprefix, tree->schema->module, LYD_XML, tree));
- logbuf_assert("Invalid instance-identifier \"/a:list2[a:id='a'][a:value='b']/a:id\" value - "
- "key-predicate \"[a:id='a'][a:value='b']\" does not match any \"list2\" instance. /");
+ logbuf_assert("Invalid instance-identifier \"/a:list2[a:id='a'][a:value='b']/a:id\" value - instance not found. /");
/* leaf-list-predicate */
data = "/a:leaflisttarget[.='c']";
- assert_int_equal(LY_EVALID, lyd_value_validate(s->ctx, (const struct lyd_node_term*)tree->prev->prev, data, strlen(data),
+ assert_int_equal(LY_ENOTFOUND, lyd_value_validate(s->ctx, (const struct lyd_node_term*)tree->prev->prev, data, strlen(data),
test_instanceid_getprefix, tree->schema->module, LYD_XML, tree));
- logbuf_assert("Invalid instance-identifier \"/a:leaflisttarget[.='c']\" value - "
- "leaf-list-predicate \"[.='c']\" does not match any \"leaflisttarget\" instance. /");
+ logbuf_assert("Invalid instance-identifier \"/a:leaflisttarget[.='c']\" value - instance not found. /");
/* position predicate */
- data = "/a:list2[4]";
- assert_int_equal(LY_EVALID, lyd_value_validate(s->ctx, (const struct lyd_node_term*)tree->prev->prev, data, strlen(data),
+ data = "/a:list_keyless[4]";
+ assert_int_equal(LY_ENOTFOUND, lyd_value_validate(s->ctx, (const struct lyd_node_term*)tree->prev->prev, data, strlen(data),
test_instanceid_getprefix, tree->schema->module, LYD_XML, tree));
- logbuf_assert("Invalid instance-identifier \"/a:list2[4]\" value - "
- "position-predicate 4 is bigger than number of instances in the data tree (2). /");
+ logbuf_assert("Invalid instance-identifier \"/a:list_keyless[4]\" value - instance not found. /");
data = "<leaflisttarget xmlns=\"urn:tests:types\">b</leaflisttarget>"
"<inst xmlns=\"urn:tests:types\">/a:leaflisttarget[1]</inst>";
assert_null(lyd_parse_mem(s->ctx, data, LYD_XML, LYD_VALOPT_DATA_ONLY));
- logbuf_assert("Invalid instance-identifier \"/a:leaflisttarget[1]\" value - unable to map prefix \"a\" to YANG schema. /types:inst");
+ logbuf_assert("Invalid instance-identifier \"/a:leaflisttarget[1]\" value - semantic error. /types:inst");
lyd_free_siblings(tree);
s->func = NULL;
@@ -1215,39 +1206,39 @@
data = "<leaflisttarget xmlns=\"urn:tests:types\">x</leaflisttarget>"
"<lref xmlns=\"urn:tests:types\">y</lref>";
assert_null(lyd_parse_mem(s->ctx, data, LYD_XML, LYD_VALOPT_DATA_ONLY));
- logbuf_assert("Invalid leafref value \"y\" - required instance \"/leaflisttarget\" with this value does not exists"
- " in the data tree(s). /types:lref");
+ logbuf_assert("Invalid leafref value \"y\" - no target instance \"/leaflisttarget\" with the same value. /types:lref");
data = "<list xmlns=\"urn:tests:types\"><id>x</id><targets>a</targets><targets>b</targets></list>"
"<list xmlns=\"urn:tests:types\"><id>y</id><targets>x</targets><targets>y</targets></list>"
"<str-norestr xmlns=\"urn:tests:types\">y</str-norestr><lref2 xmlns=\"urn:tests:types\">b</lref2>";
assert_null(lyd_parse_mem(s->ctx, data, LYD_XML, LYD_VALOPT_DATA_ONLY));
- logbuf_assert("Invalid leafref value \"b\" - required instance \"../list[id = current()/../str-norestr]/targets\""
- " with this value does not exists in the data tree(s). /types:lref2");
+ logbuf_assert("Invalid leafref value \"b\" - no target instance \"../list[id = current()/../str-norestr]/targets\" with"
+ " the same value. /types:lref2");
data = "<list xmlns=\"urn:tests:types\"><id>x</id><targets>a</targets><targets>b</targets></list>"
"<list xmlns=\"urn:tests:types\"><id>y</id><targets>x</targets><targets>y</targets></list>"
"<lref2 xmlns=\"urn:tests:types\">b</lref2>";
assert_null(lyd_parse_mem(s->ctx, data, LYD_XML, LYD_VALOPT_DATA_ONLY));
- logbuf_assert("Invalid leafref - required instance \"../list[id = current()/../str-norestr]\" does not exists"
- " in the data tree(s). /types:lref2");
+ logbuf_assert("Invalid leafref value \"b\" - no target instance \"../list[id = current()/../str-norestr]/targets\""
+ " with the same value. /types:lref2");
data = "<str-norestr xmlns=\"urn:tests:types\">y</str-norestr><lref2 xmlns=\"urn:tests:types\">b</lref2>";
assert_null(lyd_parse_mem(s->ctx, data, LYD_XML, LYD_VALOPT_DATA_ONLY));
- logbuf_assert("Invalid leafref - required instance \"../list\" does not exists in the data tree(s). /types:lref2");
+ logbuf_assert("Invalid leafref value \"b\" - no target instance \"../list[id = current()/../str-norestr]/targets\""
+ " with the same value. /types:lref2");
data = "<str-norestr xmlns=\"urn:tests:types\">y</str-norestr>"
"<c xmlns=\"urn:tests:leafrefs\"><l><id>x</id><value>x</value><lr1>a</lr1></l></c>";
assert_null(lyd_parse_mem(s->ctx, data, LYD_XML, LYD_VALOPT_DATA_ONLY));
- logbuf_assert("Invalid leafref value \"a\" - required instance \"../../../t:str-norestr\" with this value does not"
- " exists in the data tree(s). /leafrefs:c/l[id='x'][value='x']/lr1");
+ logbuf_assert("Invalid leafref value \"a\" - no target instance \"../../../t:str-norestr\" with the same value."
+ " /leafrefs:c/l[id='x'][value='x']/lr1");
data = "<str-norestr xmlns=\"urn:tests:types\">z</str-norestr>"
"<c xmlns=\"urn:tests:leafrefs\"><l><id>y</id><value>y</value></l>"
"<l><id>x</id><value>x</value><lr2>z</lr2></l></c>";
assert_null(lyd_parse_mem(s->ctx, data, LYD_XML, LYD_VALOPT_DATA_ONLY));
- logbuf_assert("Invalid leafref - required instance \"../../l[id=current()/../../../t:str-norestr][value=current()/../../../t:str-norestr]\" "
- "does not exists in the data tree(s). /leafrefs:c/l[id='x'][value='x']/lr2");
+ logbuf_assert("Invalid leafref value \"z\" - no target instance \"../../l[id=current()/../../../t:str-norestr]"
+ "[value=current()/../../../t:str-norestr]/value\" with the same value. /leafrefs:c/l[id='x'][value='x']/lr2");
s->func = NULL;
}
@@ -1359,13 +1350,13 @@
lyd_free_all(tree);
data = "<leaflisttarget xmlns=\"urn:tests:types\">x</leaflisttarget><leaflisttarget xmlns=\"urn:tests:types\">y</leaflisttarget>"
- "<un1 xmlns=\"urn:tests:types\" xmlns:a=\"urn:tests:types\">/a:leaflisttarget[2]</un1>";
+ "<un1 xmlns=\"urn:tests:types\" xmlns:a=\"urn:tests:types\">/a:leaflisttarget[.='y']</un1>";
assert_non_null(tree = lyd_parse_mem(s->ctx, data, LYD_XML, LYD_VALOPT_DATA_ONLY));
tree = tree->prev->prev;
assert_int_equal(LYS_LEAF, tree->schema->nodetype);
assert_string_equal("un1", tree->schema->name);
leaf = (struct lyd_node_term*)tree;
- assert_string_equal("/a:leaflisttarget[2]", leaf->value.original);
+ assert_string_equal("/a:leaflisttarget[.='y']", leaf->value.original);
assert_null(leaf->value.canonical_cache);
assert_non_null(leaf->value.subvalue->prefixes);
assert_int_equal(LY_TYPE_UNION, leaf->value.realtype->basetype);
diff --git a/tests/utests/data/test_validation.c b/tests/utests/data/test_validation.c
index 8934de2..04177a5 100644
--- a/tests/utests/data/test_validation.c
+++ b/tests/utests/data/test_validation.c
@@ -1356,7 +1356,8 @@
/* missing leafref */
assert_int_equal(LY_EVALID, lyd_validate_op(op_tree, NULL, LYD_VALOPT_INPUT));
- logbuf_assert("Invalid leafref - required instance \"/lf3\" does not exists in the data tree(s). /j:cont/l1[k='val1']/act/lf2");
+ logbuf_assert("Invalid leafref value \"target\" - no target instance \"/lf3\" with the same value."
+ " /j:cont/l1[k='val1']/act/lf2");
data =
"<cont xmlns=\"urn:tests:j\">"
@@ -1424,7 +1425,8 @@
/* missing leafref */
assert_int_equal(LY_EVALID, lyd_validate_op(op_tree, NULL, LYD_VALOPT_OUTPUT));
- logbuf_assert("Invalid leafref - required instance \"/lf4\" does not exists in the data tree(s). /j:cont/l1[k='val1']/act/lf2");
+ logbuf_assert("Invalid leafref value \"target\" - no target instance \"/lf4\" with the same value."
+ " /j:cont/l1[k='val1']/act/lf2");
data =
"<cont xmlns=\"urn:tests:j\">"
diff --git a/tests/utests/schema/test_parser_yin.c b/tests/utests/schema/test_parser_yin.c
index ea22333..809bfd6 100644
--- a/tests/utests/schema/test_parser_yin.c
+++ b/tests/utests/schema/test_parser_yin.c
@@ -26,6 +26,7 @@
#include "../../../src/tree_schema_internal.h"
#include "../../../src/parser_yin.h"
#include "../../../src/xml.h"
+#include "../../../src/xpath.h"
/* prototypes of static functions */
void lysp_ext_instance_free(struct ly_ctx *ctx, struct lysp_ext_instance *ext);
@@ -1656,25 +1657,6 @@
}
static void
-test_path_elem(void **state)
-{
- struct test_parser_yin_state *st = *state;
- const char *data;
- struct lysp_type type = {};
-
- data = ELEMENT_WRAPPER_START "<path value=\"p&th-val\">" EXT_SUBELEM "</path>" ELEMENT_WRAPPER_END;
- assert_int_equal(test_element_helper(st, data, &type, NULL, NULL), LY_SUCCESS);
- assert_string_equal("p&th-val", type.path);
- assert_true(type.flags & LYS_SET_PATH);
- assert_string_equal(type.exts[0].name, "urn:example:extensions:c-define");
- assert_int_equal(type.exts[0].insubstmt_index, 0);
- assert_int_equal(type.exts[0].insubstmt, LYEXT_SUBSTMT_PATH);
- lysp_type_free(st->ctx, &type);
-
- st->finished_correctly = true;
-}
-
-static void
test_pattern_elem(void **state)
{
struct test_parser_yin_state *st = *state;
@@ -2071,7 +2053,7 @@
assert_string_equal(type.enums->name, "enum");
assert_int_equal(type.fraction_digits, 2);
assert_string_equal(type.length->arg, "length");
- assert_string_equal(type.path, "path");
+ assert_string_equal(type.path->expr, "path");
assert_string_equal(type.patterns->arg, "\006pattern");
assert_string_equal(type.range->arg, "range");
assert_int_equal(type.require_instance, 1);
@@ -4337,7 +4319,6 @@
cmocka_unit_test_setup_teardown(test_length_elem, setup_element_test, teardown_element_test),
cmocka_unit_test_setup_teardown(test_modifier_elem, setup_element_test, teardown_element_test),
cmocka_unit_test_setup_teardown(test_namespace_elem, setup_element_test, teardown_element_test),
- cmocka_unit_test_setup_teardown(test_path_elem, setup_element_test, teardown_element_test),
cmocka_unit_test_setup_teardown(test_pattern_elem, setup_element_test, teardown_element_test),
cmocka_unit_test_setup_teardown(test_value_position_elem, setup_element_test, teardown_element_test),
cmocka_unit_test_setup_teardown(test_prefix_elem, setup_element_test, teardown_element_test),
diff --git a/tests/utests/schema/test_tree_schema_compile.c b/tests/utests/schema/test_tree_schema_compile.c
index b82b814..9c90ce5 100644
--- a/tests/utests/schema/test_tree_schema_compile.c
+++ b/tests/utests/schema/test_tree_schema_compile.c
@@ -311,7 +311,7 @@
/* forward reference in default */
assert_non_null(mod = lys_parse_mem(ctx, "module g {yang-version 1.1; namespace urn:g;prefix g;"
- "leaf ref {type instance-identifier {require-instance true;} default \"/g:g\";}"
+ "leaf ref {type instance-identifier {require-instance true;} default \"/g:g[.='val']\";}"
"leaf-list g {type string;}}", LYS_IN_YANG));
assert_non_null(l = (struct lysc_node_leaf*)mod->compiled->data);
assert_string_equal("ref", l->name);
@@ -338,7 +338,7 @@
assert_null(lys_parse_mem(ctx, "module ee {yang-version 1.1; namespace urn:ee;prefix ee;"
"leaf ref {type instance-identifier {require-instance true;} default \"/ee:g\";}}", LYS_IN_YANG));
logbuf_assert("Invalid default - value does not fit the type "
- "(Invalid instance-identifier \"/ee:g\" value - path \"/ee:g\" does not exists in the YANG schema.). /ee:ref");
+ "(Invalid instance-identifier \"/ee:g\" value - semantic error.). /ee:ref");
*state = NULL;
ly_ctx_destroy(ctx, NULL);
@@ -1617,7 +1617,7 @@
type = ((struct lysc_node_leaf*)mod->compiled->data)->type;
assert_non_null(type);
assert_int_equal(LY_TYPE_LEAFREF, type->basetype);
- assert_string_equal("/a:target1", ((struct lysc_type_leafref*)type)->path);
+ assert_string_equal("/a:target1", ((struct lysc_type_leafref*)type)->path->expr);
assert_ptr_equal(mod, ((struct lysc_type_leafref*)type)->path_context);
assert_non_null(((struct lysc_type_leafref*)type)->realtype);
assert_int_equal(LY_TYPE_STRING, ((struct lysc_type_leafref*)type)->realtype->basetype);
@@ -1625,7 +1625,7 @@
type = ((struct lysc_node_leaf*)mod->compiled->data->next)->type;
assert_non_null(type);
assert_int_equal(LY_TYPE_LEAFREF, type->basetype);
- assert_string_equal("/a/target2", ((struct lysc_type_leafref*)type)->path);
+ assert_string_equal("/a/target2", ((struct lysc_type_leafref*)type)->path->expr);
assert_ptr_equal(mod, ((struct lysc_type_leafref*)type)->path_context);
assert_non_null(((struct lysc_type_leafref*)type)->realtype);
assert_int_equal(LY_TYPE_UINT8, ((struct lysc_type_leafref*)type)->realtype->basetype);
@@ -1638,7 +1638,7 @@
assert_non_null(type);
assert_int_equal(1, type->refcount);
assert_int_equal(LY_TYPE_LEAFREF, type->basetype);
- assert_string_equal("/b:target", ((struct lysc_type_leafref* )type)->path);
+ assert_string_equal("/b:target", ((struct lysc_type_leafref* )type)->path->expr);
assert_ptr_equal(mod, ((struct lysc_type_leafref*)type)->path_context);
assert_non_null(((struct lysc_type_leafref*)type)->realtype);
assert_int_equal(LY_TYPE_STRING, ((struct lysc_type_leafref*)type)->realtype->basetype);
@@ -1652,7 +1652,7 @@
assert_non_null(type);
assert_int_equal(1, type->refcount);
assert_int_equal(LY_TYPE_LEAFREF, type->basetype);
- assert_string_equal("/b:target", ((struct lysc_type_leafref* )type)->path);
+ assert_string_equal("/b:target", ((struct lysc_type_leafref* )type)->path->expr);
assert_ptr_not_equal(mod, ((struct lysc_type_leafref*)type)->path_context);
assert_non_null(((struct lysc_type_leafref*)type)->realtype);
assert_int_equal(LY_TYPE_STRING, ((struct lysc_type_leafref*)type)->realtype->basetype);
@@ -1661,7 +1661,7 @@
assert_non_null(type);
assert_int_equal(1, type->refcount);
assert_int_equal(LY_TYPE_LEAFREF, type->basetype);
- assert_string_equal("/b:target", ((struct lysc_type_leafref* )type)->path);
+ assert_string_equal("/b:target", ((struct lysc_type_leafref* )type)->path->expr);
assert_ptr_not_equal(mod, ((struct lysc_type_leafref*)type)->path_context);
assert_int_equal(1, ((struct lysc_type_leafref* )type)->require_instance);
@@ -1672,7 +1672,7 @@
assert_non_null(type);
assert_int_equal(1, type->refcount);
assert_int_equal(LY_TYPE_LEAFREF, type->basetype);
- assert_string_equal("/target", ((struct lysc_type_leafref* )type)->path);
+ assert_string_equal("/target", ((struct lysc_type_leafref* )type)->path->expr);
assert_ptr_not_equal(mod, ((struct lysc_type_leafref*)type)->path_context);
assert_non_null(((struct lysc_type_leafref*)type)->realtype);
assert_int_equal(LY_TYPE_INT8, ((struct lysc_type_leafref*)type)->realtype->basetype);
@@ -1686,7 +1686,7 @@
assert_non_null(type);
assert_int_equal(1, type->refcount);
assert_int_equal(LY_TYPE_LEAFREF, type->basetype);
- assert_string_equal("/target", ((struct lysc_type_leafref* )type)->path);
+ assert_string_equal("/target", ((struct lysc_type_leafref* )type)->path->expr);
assert_ptr_equal(mod, ((struct lysc_type_leafref*)type)->path_context);
assert_non_null(((struct lysc_type_leafref*)type)->realtype);
assert_int_equal(LY_TYPE_BOOL, ((struct lysc_type_leafref*)type)->realtype->basetype);
@@ -1700,7 +1700,8 @@
assert_non_null(type);
assert_int_equal(1, type->refcount);
assert_int_equal(LY_TYPE_LEAFREF, type->basetype);
- assert_string_equal("../../interface[ name = current()/../ifname ]/address/ip", ((struct lysc_type_leafref* )type)->path);
+ assert_string_equal("../../interface[ name = current()/../ifname ]/address/ip",
+ ((struct lysc_type_leafref* )type)->path->expr);
assert_ptr_equal(mod, ((struct lysc_type_leafref*)type)->path_context);
assert_non_null(((struct lysc_type_leafref*)type)->realtype);
assert_int_equal(LY_TYPE_STRING, ((struct lysc_type_leafref*)type)->realtype->basetype);
@@ -1713,7 +1714,7 @@
assert_non_null(type);
assert_int_equal(1, type->refcount);
assert_int_equal(LY_TYPE_LEAFREF, type->basetype);
- assert_string_equal("/endpoint-parent[id=current()/../field]/endpoint/name", ((struct lysc_type_leafref* )type)->path);
+ assert_string_equal("/endpoint-parent[id=current()/../field]/endpoint/name", ((struct lysc_type_leafref* )type)->path->expr);
assert_ptr_equal(mod, ((struct lysc_type_leafref*)type)->path_context);
assert_non_null(((struct lysc_type_leafref*)type)->realtype);
assert_int_equal(LY_TYPE_STRING, ((struct lysc_type_leafref*)type)->realtype->basetype);
@@ -1754,7 +1755,7 @@
assert_non_null(type);
assert_int_equal(1, type->refcount);
assert_int_equal(LY_TYPE_LEAFREF, type->basetype);
- assert_string_equal("../target", ((struct lysc_type_leafref* )type)->path);
+ assert_string_equal("../target", ((struct lysc_type_leafref* )type)->path->expr);
assert_non_null(((struct lysc_type_leafref*)type)->realtype);
assert_int_equal(LY_TYPE_BOOL, ((struct lysc_type_leafref*)type)->realtype->basetype);
assert_non_null(((struct lysc_node_leaf*)mod->compiled->data)->dflt);
@@ -1764,24 +1765,25 @@
/* invalid paths */
assert_null(lys_parse_mem(ctx, "module aa {namespace urn:aa;prefix aa;container a {leaf target2 {type uint8;}}"
"leaf ref1 {type leafref {path ../a/invalid;}}}", LYS_IN_YANG));
- logbuf_assert("Invalid leafref path - unable to find \"../a/invalid\". /aa:ref1");
+ logbuf_assert("Not found node \"invalid\" in path.");
assert_null(lys_parse_mem(ctx, "module bb {namespace urn:bb;prefix bb;container a {leaf target2 {type uint8;}}"
"leaf ref1 {type leafref {path ../../toohigh;}}}", LYS_IN_YANG));
- logbuf_assert("Invalid leafref path \"../../toohigh\" - too many \"..\" in the path. /bb:ref1");
+ logbuf_assert("Too many parent references in path.");
assert_null(lys_parse_mem(ctx, "module cc {namespace urn:cc;prefix cc;container a {leaf target2 {type uint8;}}"
"leaf ref1 {type leafref {path /a:invalid;}}}", LYS_IN_YANG));
- logbuf_assert("Invalid leafref path - unable to find module connected with the prefix of the node \"/a:invalid\". /cc:ref1");
- assert_null(lys_parse_mem(ctx, "module dd {namespace urn:dd;prefix dd;leaf target1 {type string;}container a {leaf target2 {type uint8;}}"
- "leaf ref1 {type leafref {path '/a[target2 = current()/../target1]/target2';}}}", LYS_IN_YANG));
- logbuf_assert("Invalid leafref path - node \"/a\" is expected to be a list, but it is container. /dd:ref1");
+ logbuf_assert("Prefix \"a\" not found of a module in path.");
+ assert_null(lys_parse_mem(ctx, "module dd {namespace urn:dd;prefix dd;leaf target1 {type string;}"
+ "container a {leaf target2 {type uint8;}} leaf ref1 {type leafref {"
+ "path '/a[target2 = current()/../target1]/target2';}}}", LYS_IN_YANG));
+ logbuf_assert("List predicate defined for container \"a\" in path.");
assert_null(lys_parse_mem(ctx, "module ee {namespace urn:ee;prefix ee;container a {leaf target2 {type uint8;}}"
"leaf ref1 {type leafref {path /a!invalid;}}}", LYS_IN_YANG));
- logbuf_assert("Invalid leafref path at character 3 (/a!invalid). /ee:ref1");
+ logbuf_assert("Invalid character 0x21 ('!'), perhaps \"a\" is supposed to be a function call.");
assert_null(lys_parse_mem(ctx, "module ff {namespace urn:ff;prefix ff;container a {leaf target2 {type uint8;}}"
"leaf ref1 {type leafref {path /a;}}}", LYS_IN_YANG));
logbuf_assert("Invalid leafref path \"/a\" - target node is container instead of leaf or leaf-list. /ff:ref1");
- assert_null(lys_parse_mem(ctx, "module gg {namespace urn:gg;prefix gg;container a {leaf target2 {type uint8; status deprecated;}}"
- "leaf ref1 {type leafref {path /a/target2;}}}", LYS_IN_YANG));
+ assert_null(lys_parse_mem(ctx, "module gg {namespace urn:gg;prefix gg;container a {leaf target2 {type uint8;"
+ "status deprecated;}} leaf ref1 {type leafref {path /a/target2;}}}", LYS_IN_YANG));
logbuf_assert("A current definition \"ref1\" is not allowed to reference deprecated definition \"target2\". /gg:ref1");
assert_null(lys_parse_mem(ctx, "module hh {namespace urn:hh;prefix hh;"
"leaf ref1 {type leafref;}}", LYS_IN_YANG));
@@ -1809,109 +1811,109 @@
"leaf ifname{type leafref{ path \"../interface/name\";}}"
"leaf address {type leafref{ path \"/interface[name is current()/../ifname]/ip\";}}}",
LYS_IN_YANG));
- logbuf_assert("Invalid leafref path predicate \"[name i\" - missing \"=\" after node-identifier. /nn:address");
+ logbuf_assert("Invalid character 0x69 ('i'), perhaps \"name\" is supposed to be a function call.");
assert_null(lys_parse_mem(ctx, "module oo {namespace urn:oo;prefix oo;"
"list interface{key name;leaf name{type string;}leaf ip {type string;}}"
"leaf ifname{type leafref{ path \"../interface/name\";}}"
"leaf address {type leafref{ path \"/interface[name=current()/../ifname/ip\";}}}",
LYS_IN_YANG));
- logbuf_assert("Invalid leafref path predicate \"[name=current()/../ifname/ip\" - missing predicate termination. /oo:address");
+ logbuf_assert("Unexpected XPath expression end.");
assert_null(lys_parse_mem(ctx, "module pp {namespace urn:pp;prefix pp;"
"list interface{key name;leaf name{type string;}leaf ip {type string;}}"
"leaf ifname{type leafref{ path \"../interface/name\";}}"
"leaf address {type leafref{ path \"/interface[x:name=current()/../ifname]/ip\";}}}",
LYS_IN_YANG));
- logbuf_assert("Invalid leafref path predicate \"[x:name=current()/../ifname]\" - prefix \"x\" not defined in module \"pp\". /pp:address");
+ logbuf_assert("Prefix \"x\" not found of a module in path.");
assert_null(lys_parse_mem(ctx, "module qq {namespace urn:qq;prefix qq;"
"list interface{key name;leaf name{type string;}leaf ip {type string;}}"
"leaf ifname{type leafref{ path \"../interface/name\";}}"
"leaf address {type leafref{ path \"/interface[id=current()/../ifname]/ip\";}}}",
LYS_IN_YANG));
- logbuf_assert("Invalid leafref path predicate \"[id=current()/../ifname]\" - predicate's key node \"id\" not found. /qq:address");
+ logbuf_assert("Not found node \"id\" in path.");
assert_null(lys_parse_mem(ctx, "module rr {namespace urn:rr;prefix rr;"
"list interface{key name;leaf name{type string;}leaf ip {type string;}}"
"leaf ifname{type leafref{ path \"../interface/name\";}}leaf test{type string;}"
"leaf address {type leafref{ path \"/interface[name=current() / .. / ifname][name=current()/../test]/ip\";}}}",
LYS_IN_YANG));
- logbuf_assert("Invalid leafref path predicate \"[name=current()/../test]\" - multiple equality tests for the key \"name\". /rr:address");
+ logbuf_assert("Duplicate predicate key \"name\" in path.");
assert_null(lys_parse_mem(ctx, "module ss {namespace urn:ss;prefix ss;"
"list interface{key name;leaf name{type string;}leaf ip {type string;}}"
"leaf ifname{type leafref{ path \"../interface/name\";}}leaf test{type string;}"
"leaf address {type leafref{ path \"/interface[name = ../ifname]/ip\";}}}",
LYS_IN_YANG));
- logbuf_assert("Invalid leafref path predicate \"[name = ../ifname]\" - missing current-function-invocation. /ss:address");
+ logbuf_assert("Unexpected XPath token .. (../ifname]/ip).");
assert_null(lys_parse_mem(ctx, "module tt {namespace urn:tt;prefix tt;"
"list interface{key name;leaf name{type string;}leaf ip {type string;}}"
"leaf ifname{type leafref{ path \"../interface/name\";}}leaf test{type string;}"
"leaf address {type leafref{ path \"/interface[name = current()../ifname]/ip\";}}}",
LYS_IN_YANG));
- logbuf_assert("Invalid leafref path predicate \"[name = current()../ifname]\" - missing \"/\" after current-function-invocation. /tt:address");
+ logbuf_assert("Unexpected XPath token .. (../ifname]/ip).");
assert_null(lys_parse_mem(ctx, "module uu {namespace urn:uu;prefix uu;"
"list interface{key name;leaf name{type string;}leaf ip {type string;}}"
"leaf ifname{type leafref{ path \"../interface/name\";}}leaf test{type string;}"
"leaf address {type leafref{ path \"/interface[name = current()/..ifname]/ip\";}}}",
LYS_IN_YANG));
- logbuf_assert("Invalid leafref path predicate \"[name = current()/..ifname]\" - missing \"/\" in \"../\" rel-path-keyexpr pattern. /uu:address");
+ logbuf_assert("Invalid character number 31 of expression '/interface[name = current()/..ifname]/ip'.");
assert_null(lys_parse_mem(ctx, "module vv {namespace urn:vv;prefix vv;"
"list interface{key name;leaf name{type string;}leaf ip {type string;}}"
"leaf ifname{type leafref{ path \"../interface/name\";}}leaf test{type string;}"
"leaf address {type leafref{ path \"/interface[name = current()/ifname]/ip\";}}}",
LYS_IN_YANG));
- logbuf_assert("Invalid leafref path predicate \"[name = current()/ifname]\" - at least one \"..\" is expected in rel-path-keyexpr. /vv:address");
+ logbuf_assert("Unexpected XPath token NameTest (ifname]/ip).");
assert_null(lys_parse_mem(ctx, "module ww {namespace urn:ww;prefix ww;"
"list interface{key name;leaf name{type string;}leaf ip {type string;}}"
"leaf ifname{type leafref{ path \"../interface/name\";}}leaf test{type string;}"
"leaf address {type leafref{ path \"/interface[name = current()/../]/ip\";}}}",
LYS_IN_YANG));
- logbuf_assert("Invalid leafref path predicate \"[name = current()/../]\" - at least one node-identifier is expected in rel-path-keyexpr. /ww:address");
+ logbuf_assert("Unexpected XPath token ] (]/ip).");
assert_null(lys_parse_mem(ctx, "module xx {namespace urn:xx;prefix xx;"
"list interface{key name;leaf name{type string;}leaf ip {type string;}}"
"leaf ifname{type leafref{ path \"../interface/name\";}}leaf test{type string;}"
"leaf address {type leafref{ path \"/interface[name = current()/../$node]/ip\";}}}",
LYS_IN_YANG));
- logbuf_assert("Invalid node identifier in leafref path predicate - character 22 (of [name = current()/../$node]). /xx:address");
+ logbuf_assert("Invalid character 0x24 ('$'), perhaps \"\" is supposed to be a function call.");
assert_null(lys_parse_mem(ctx, "module yy {namespace urn:yy;prefix yy;"
"list interface{key name;leaf name{type string;}leaf ip {type string;}}"
"leaf ifname{type leafref{ path \"../interface/name\";}}"
"leaf address {type leafref{ path \"/interface[name=current()/../x:ifname]/ip\";}}}",
LYS_IN_YANG));
- logbuf_assert("Invalid leafref path predicate \"[name=current()/../x:ifname]\" - unable to find module of the node \"ifname\" in rel-path-keyexpr. /yy:address");
+ logbuf_assert("Prefix \"x\" not found of a module in path.");
assert_null(lys_parse_mem(ctx, "module zz {namespace urn:zz;prefix zz;"
"list interface{key name;leaf name{type string;}leaf ip {type string;}}"
"leaf ifname{type leafref{ path \"../interface/name\";}}"
"leaf address {type leafref{ path \"/interface[name=current()/../xxx]/ip\";}}}",
LYS_IN_YANG));
- logbuf_assert("Invalid leafref path predicate \"[name=current()/../xxx]\" - unable to find node \"current()/../xxx\" in the rel-path-keyexpr. /zz:address");
+ logbuf_assert("Not found node \"xxx\" in path.");
assert_null(lys_parse_mem(ctx, "module zza {namespace urn:zza;prefix zza;"
"list interface{key name;leaf name{type string;}leaf ip {type string;}}"
"leaf ifname{type leafref{ path \"../interface/name\";}}container c;"
"leaf address {type leafref{ path \"/interface[name=current()/../c]/ip\";}}}",
LYS_IN_YANG));
- logbuf_assert("Invalid leafref path predicate \"[name=current()/../c]\" - rel-path-keyexpr \"current()/../c\" refers container instead of leaf. /zza:address");
+ logbuf_assert("Leaf expected instead of container \"c\" in leafref predicate in path.");
assert_null(lys_parse_mem(ctx, "module zzb {namespace urn:zzb;prefix zzb;"
"list interface{key name;leaf name{type string;}leaf ip {type string;}container c;}"
"leaf ifname{type leafref{ path \"../interface/name\";}}"
"leaf address {type leafref{ path \"/interface[c=current()/../ifname]/ip\";}}}",
LYS_IN_YANG));
- logbuf_assert("Invalid leafref path predicate \"[c=current()/../ifname]\" - predicate's key node \"c\" not found. /zzb:address");
+ logbuf_assert("Key expected instead of container \"c\" in path.");
assert_null(lys_parse_mem(ctx, "module zzc {namespace urn:zzc;prefix zzc;"
"leaf source {type leafref {path \"../target\";}default true;}}", LYS_IN_YANG));
- logbuf_assert("Invalid leafref path - unable to find \"../target\". /zzc:source");
+ logbuf_assert("Not found node \"target\" in path.");
assert_null(lys_parse_mem(ctx, "module zzd {namespace urn:zzd;prefix zzd;"
"leaf source {type leafref {path \"../target\";}default true;}"
@@ -2949,24 +2951,24 @@
/* instance-identifiers with NULL canonical_cach are changed to string types with a canonical_cache value equal to the original value */
assert_non_null(mod = lys_parse_mem(ctx, "module q {yang-version 1.1; namespace urn:q;prefix q; import e {prefix e;}"
- "leaf q {type instance-identifier; default \"/e:d2\";}"
- "leaf-list ql {type instance-identifier; default \"/e:d\"; default \"/e:d2\";}}", LYS_IN_YANG));
+ "leaf q {type instance-identifier; default \"/e:d2[.='a']\";}"
+ "leaf-list ql {type instance-identifier; default \"/e:d[.='b']\"; default \"/e:d2[.='c']\";}}", LYS_IN_YANG));
assert_non_null(lys_parse_mem(ctx, "module qdev {yang-version 1.1; namespace urn:qdev;prefix qd; import q {prefix q;}"
"deviation /q:q { deviate replace {type string;}}"
"deviation /q:ql { deviate replace {type string;}}}", LYS_IN_YANG));
assert_non_null(leaf = (struct lysc_node_leaf*)mod->compiled->data);
assert_int_equal(LY_TYPE_STRING, leaf->dflt->realtype->basetype);
assert_non_null(leaf->dflt->canonical_cache);
- assert_string_equal("/e:d2", leaf->dflt->canonical_cache);
+ assert_string_equal("/e:d2[.='a']", leaf->dflt->canonical_cache);
assert_non_null(llist = (struct lysc_node_leaflist*)leaf->next);
assert_int_equal(2, LY_ARRAY_SIZE(llist->dflts));
assert_int_equal(2, LY_ARRAY_SIZE(llist->dflts_mods));
assert_ptr_equal(llist->dflts_mods[0], mod);
assert_int_equal(LY_TYPE_STRING, llist->dflts[0]->realtype->basetype);
- assert_string_equal("/e:d", llist->dflts[0]->canonical_cache);
+ assert_string_equal("/e:d[.='b']", llist->dflts[0]->canonical_cache);
assert_ptr_equal(llist->dflts_mods[1], mod);
assert_int_equal(LY_TYPE_STRING, llist->dflts[0]->realtype->basetype);
- assert_string_equal("/e:d2", llist->dflts[1]->canonical_cache);
+ assert_string_equal("/e:d2[.='c']", llist->dflts[1]->canonical_cache);
assert_non_null(mod = lys_parse_mem(ctx, "module r {yang-version 1.1; namespace urn:r;prefix r;"
"typedef mytype {type uint8; default 200;}"