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/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\">"