Skip to content

Commit

Permalink
parser CHANGE swap default when autodelete behaviour
Browse files Browse the repository at this point in the history
Raise an error on unsatisfied when condition by default.
Refs #631
  • Loading branch information
michalvasko committed Oct 12, 2018
1 parent f33a9a4 commit bbc43b1
Show file tree
Hide file tree
Showing 22 changed files with 35 additions and 36 deletions.
6 changes: 3 additions & 3 deletions src/parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -222,10 +222,10 @@ lyp_data_check_options(struct ly_ctx *ctx, int options, const char *func)
{
int x = options & LYD_OPT_TYPEMASK;

/* LYD_OPT_NOAUTODEL can be used only with LYD_OPT_DATA or LYD_OPT_CONFIG */
if (options & LYD_OPT_NOAUTODEL) {
/* LYD_OPT_WHENAUTODEL can be used only with LYD_OPT_DATA or LYD_OPT_CONFIG */
if (options & LYD_OPT_WHENAUTODEL) {
if ((x == LYD_OPT_EDIT) || (x == LYD_OPT_NOTIF_FILTER)) {
LOGERR(ctx, LY_EINVAL, "%s: Invalid options 0x%x (LYD_OPT_DATA_NOAUTODEL can be used only with LYD_OPT_DATA or LYD_OPT_CONFIG)",
LOGERR(ctx, LY_EINVAL, "%s: Invalid options 0x%x (LYD_OPT_DATA_WHENAUTODEL can be used only with LYD_OPT_DATA or LYD_OPT_CONFIG)",
func, options);
return 1;
}
Expand Down
4 changes: 2 additions & 2 deletions src/resolve.c
Original file line number Diff line number Diff line change
Expand Up @@ -8186,7 +8186,7 @@ unres_data_add(struct unres_data *unres, struct lyd_node *node, enum UNRES_ITEM
* unresolved leafrefs/instids are accepted, when conditions are normally resolved because at least some implicit
* non-presence containers may need to be deleted).
*
* If options includes LYD_OPT_NOAUTODEL, the false resulting when condition on non-default nodes, the error is raised.
* If options includes #LYD_OPT_WHENAUTODEL, the non-default nodes with false when conditions are auto-deleted.
*
* @param[in] ctx Context used.
* @param[in] unres Unres data structure to use.
Expand Down Expand Up @@ -8272,7 +8272,7 @@ resolve_unres_data(struct ly_ctx *ctx, struct unres_data *unres, struct lyd_node
* or it was not provided (the flag would not be passed down otherwise, checked in upper functions) */
if ((unres->node[i]->when_status & LYD_WHEN_FALSE)
&& (!(when->flags & (LYS_XPCONF_DEP | LYS_XPSTATE_DEP)) || !(options & LYD_OPT_NOEXTDEPS))) {
if ((options & LYD_OPT_NOAUTODEL) && !unres->node[i]->dflt) {
if (!(options & LYD_OPT_WHENAUTODEL) && !unres->node[i]->dflt) {
/* false when condition */
goto error;
} /* follows else */
Expand Down
13 changes: 6 additions & 7 deletions src/tree_data.h
Original file line number Diff line number Diff line change
Expand Up @@ -464,8 +464,8 @@ char *lyd_path(const struct lyd_node *node);
* subtree filter data, edit-config's data or other type of data set - such data do not represent a complete data set
* and some of the validation rules can fail. Therefore there are other options (within lower 8 bits) to make parser
* to accept such a data.
* - when parser evaluates when-stmt condition to false, the constrained subtree is automatically removed. If the
* #LYD_OPT_NOAUTODEL is used, error is raised instead of silent auto delete. The option (and also this default
* - when parser evaluates when-stmt condition to false, a validation error is raised. If the
* #LYD_OPT_WHENAUTODEL is used, the invalid node is silently removed instead of an error. The option (and also this default
* behavior) takes effect only in case of #LYD_OPT_DATA or #LYD_OPT_CONFIG type of data.
* @{
*/
Expand Down Expand Up @@ -516,10 +516,9 @@ char *lyd_path(const struct lyd_node *node);
are connected with the schema, but the most validation checks (mandatory nodes,
list instance uniqueness, etc.) are not performed. This option does not make
sense for lyd_validate() so it is ignored by this function. */
#define LYD_OPT_NOAUTODEL 0x4000 /**< Avoid automatic delete of subtrees with false when-stmt condition. The flag is
applicable only in combination with #LYD_OPT_DATA and #LYD_OPT_CONFIG flags.
If used, libyang generates validation error instead of silently removing the
constrained subtree. */
#define LYD_OPT_WHENAUTODEL 0x4000 /**< Automatically delete subtrees with false when-stmt condition. The flag is
applicable only in combination with #LYD_OPT_DATA and #LYD_OPT_CONFIG flags.
If used, libyang will not generate a validation error. */
#define LYD_OPT_NOEXTDEPS 0x8000 /**< Allow external dependencies (external leafrefs, instance-identifiers, must,
and when) to not be resolved/satisfied during validation. */
#define LYD_OPT_DATA_NO_YANGLIB 0x10000 /**< Ignore (possibly) missing ietf-yang-library data. Applicable only with #LYD_OPT_DATA. */
Expand Down Expand Up @@ -1113,7 +1112,7 @@ struct lyd_node *lyd_first_sibling(struct lyd_node *node);
/**
* @brief Validate \p node data subtree.
*
* @param[in,out] node Data tree to be validated. In case the \p options does not includes #LYD_OPT_NOAUTODEL, libyang
* @param[in,out] node Data tree to be validated. In case the \p options includes #LYD_OPT_WHENAUTODEL, libyang
* can modify the provided tree including the root \p node.
* @param[in] options Options for the inserting data to the target data tree options, see @ref parseroptions.
* @param[in] var_arg Variable argument depends on \p options. If they include:
Expand Down
2 changes: 1 addition & 1 deletion tests/conformance/test_sec7_10.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ TEST_CHOICE(void **state)

for (j = 0; j < TEST_DATA_FILE_COUNT; ++j) {
sprintf(buf, TESTS_DIR "/conformance/" TEST_DIR "/data%d.xml", j + 1);
st->node = lyd_parse_path(st->ctx, buf, LYD_XML, LYD_OPT_CONFIG | LYD_OPT_NOAUTODEL);
st->node = lyd_parse_path(st->ctx, buf, LYD_XML, LYD_OPT_CONFIG);
if (data_files_fail[j]) {
assert_ptr_equal(st->node, NULL);
} else {
Expand Down
2 changes: 1 addition & 1 deletion tests/conformance/test_sec7_11.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ TEST_GROUPING(void **state)

for (j = 0; j < TEST_DATA_FILE_COUNT; ++j) {
sprintf(buf, TESTS_DIR "/conformance/" TEST_DIR "/data%d.xml", j + 1);
st->node = lyd_parse_path(st->ctx, buf, LYD_XML, LYD_OPT_CONFIG | LYD_OPT_NOAUTODEL);
st->node = lyd_parse_path(st->ctx, buf, LYD_XML, LYD_OPT_CONFIG);
if (data_files_fail[j]) {
assert_ptr_equal(st->node, NULL);
} else {
Expand Down
2 changes: 1 addition & 1 deletion tests/conformance/test_sec7_12_1.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ TEST_USES(void **state)

for (j = 0; j < TEST_DATA_FILE_COUNT; ++j) {
sprintf(buf, TESTS_DIR "/conformance/" TEST_DIR "/data%d.xml", j + 1);
st->node = lyd_parse_path(st->ctx, buf, LYD_XML, LYD_OPT_CONFIG | LYD_OPT_NOAUTODEL);
st->node = lyd_parse_path(st->ctx, buf, LYD_XML, LYD_OPT_CONFIG);
if (data_files_fail[j]) {
assert_ptr_equal(st->node, NULL);
} else {
Expand Down
2 changes: 1 addition & 1 deletion tests/conformance/test_sec7_12_2.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ TEST_USES_REFINE(void **state)

for (j = 0; j < TEST_DATA_FILE_COUNT; ++j) {
sprintf(buf, TESTS_DIR "/conformance/" TEST_DIR "/data%d.xml", j + 1);
st->node = lyd_parse_path(st->ctx, buf, LYD_XML, LYD_OPT_CONFIG | LYD_OPT_NOAUTODEL);
st->node = lyd_parse_path(st->ctx, buf, LYD_XML, LYD_OPT_CONFIG);
if (data_files_fail[j]) {
assert_ptr_equal(st->node, NULL);
} else {
Expand Down
2 changes: 1 addition & 1 deletion tests/conformance/test_sec7_13_2.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
#define TEST_SCHEMA_COUNT 1
#define TEST_SCHEMA_LOAD_FAIL 0
#define TEST_DATA_FILE_COUNT 14
#define TEST_DATA_FILE_LOAD_FAIL 0,0,0,0,1,0,0,0,1,1,1,1,1,1
#define TEST_DATA_FILE_LOAD_FAIL 1,0,0,0,1,0,0,0,1,1,1,1,1,1
#define TEST_DATA_COMPARE_FAIL 1,0,0,0,0,0,0,0
#define TEST_DATA_COMPARE "ssh", "ssh", "42", "pattern", "", "true", "", ""

Expand Down
2 changes: 1 addition & 1 deletion tests/conformance/test_sec7_13_3.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
#define TEST_SCHEMA_COUNT 1
#define TEST_SCHEMA_LOAD_FAIL 0
#define TEST_DATA_FILE_COUNT 14
#define TEST_DATA_FILE_LOAD_FAIL 0,0,0,0,1,0,0,0,1,1,1,1,1,1
#define TEST_DATA_FILE_LOAD_FAIL 1,0,0,0,1,0,0,0,1,1,1,1,1,1
#define TEST_DATA_COMPARE_FAIL 1,0,0,0,0,0,0,0
#define TEST_DATA_COMPARE "ssh", "ssh", "42", "pattern", "", "true", "", ""
#define TEST_RPC_NODE "test5", "test5", "test5", "test4", \
Expand Down
2 changes: 1 addition & 1 deletion tests/conformance/test_sec7_15.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ TEST_AUGMENT(void **state)

for (j = 0; j < TEST_DATA_FILE_COUNT; ++j) {
sprintf(buf, TESTS_DIR "/conformance/" TEST_DIR "/data%d.xml", j + 1);
st->node = lyd_parse_path(st->ctx, buf, LYD_XML, LYD_OPT_CONFIG | LYD_OPT_NOAUTODEL);
st->node = lyd_parse_path(st->ctx, buf, LYD_XML, LYD_OPT_CONFIG);
if (data_files_fail[j]) {
assert_ptr_equal(st->node, NULL);
} else {
Expand Down
2 changes: 1 addition & 1 deletion tests/conformance/test_sec7_18_1.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ TEST_FEATURE(void **state)

for (j = 0; j < TEST_DATA_FILE_COUNT; ++j) {
sprintf(buf, TESTS_DIR "/conformance/" TEST_DIR "/data%d.xml", j + 1);
st->node = lyd_parse_path(st->ctx, buf, LYD_XML, LYD_OPT_CONFIG | LYD_OPT_NOAUTODEL);
st->node = lyd_parse_path(st->ctx, buf, LYD_XML, LYD_OPT_CONFIG);
if (data_files_fail[j]) {
assert_ptr_equal(st->node, NULL);
} else {
Expand Down
2 changes: 1 addition & 1 deletion tests/conformance/test_sec7_18_3_1.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ TEST_DEVIATION(void **state)

for (j = 0; j < TEST_DATA_FILE_COUNT; ++j) {
sprintf(buf, TESTS_DIR "/conformance/" TEST_DIR "/data%d.xml", j + 1);
st->node = lyd_parse_path(st->ctx, buf, LYD_XML, LYD_OPT_CONFIG | LYD_OPT_NOAUTODEL | LYD_OPT_STRICT);
st->node = lyd_parse_path(st->ctx, buf, LYD_XML, LYD_OPT_CONFIG | LYD_OPT_STRICT);
if (data_files_fail[j]) {
assert_ptr_equal(st->node, NULL);
} else {
Expand Down
2 changes: 1 addition & 1 deletion tests/conformance/test_sec7_18_3_2.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ TEST_DEVIATION(void **state)

for (j = 0; j < TEST_DATA_FILE_COUNT; ++j) {
sprintf(buf, TESTS_DIR "/conformance/" TEST_DIR "/data%d.xml", j + 1);
st->node = lyd_parse_path(st->ctx, buf, LYD_XML, LYD_OPT_CONFIG | LYD_OPT_NOAUTODEL);
st->node = lyd_parse_path(st->ctx, buf, LYD_XML, LYD_OPT_CONFIG);
if (data_files_fail[j]) {
assert_ptr_equal(st->node, NULL);
} else {
Expand Down
2 changes: 1 addition & 1 deletion tests/conformance/test_sec7_19_5.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ TEST_WHEN(void **state)

for (j = 0; j < TEST_DATA_FILE_COUNT; ++j) {
sprintf(buf, TESTS_DIR "/conformance/" TEST_DIR "/data%d.xml", j + 1);
st->node = lyd_parse_path(st->ctx, buf, LYD_XML, LYD_OPT_CONFIG | LYD_OPT_NOAUTODEL);
st->node = lyd_parse_path(st->ctx, buf, LYD_XML, LYD_OPT_CONFIG);
if (data_files_fail[j]) {
assert_ptr_equal(st->node, NULL);
} else {
Expand Down
2 changes: 1 addition & 1 deletion tests/conformance/test_sec7_8_2.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ TEST_LIST_KEYS(void **state)

for (j = 0; j < TEST_DATA_FILE_COUNT; ++j) {
sprintf(buf, TESTS_DIR "/conformance/" TEST_DIR "/data%d.xml", j + 1);
st->node = lyd_parse_path(st->ctx, buf, LYD_XML, LYD_OPT_CONFIG | LYD_OPT_NOAUTODEL);
st->node = lyd_parse_path(st->ctx, buf, LYD_XML, LYD_OPT_CONFIG);
if (data_files_fail[j]) {
assert_ptr_equal(st->node, NULL);
} else {
Expand Down
2 changes: 1 addition & 1 deletion tests/conformance/test_sec7_8_3.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ TEST_LIST_UNIQUE(void **state)

for (j = 0; j < TEST_DATA_FILE_COUNT; ++j) {
sprintf(buf, TESTS_DIR "/conformance/" TEST_DIR "/data%d.xml", j + 1);
st->node = lyd_parse_path(st->ctx, buf, LYD_XML, LYD_OPT_CONFIG | LYD_OPT_NOAUTODEL);
st->node = lyd_parse_path(st->ctx, buf, LYD_XML, LYD_OPT_CONFIG);
if (data_files_fail[j]) {
assert_ptr_equal(st->node, NULL);
} else {
Expand Down
2 changes: 1 addition & 1 deletion tests/conformance/test_sec7_9_2.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ TEST_CHOICE_CASE(void **state)

for (j = 0; j < TEST_DATA_FILE_COUNT; ++j) {
sprintf(buf, TESTS_DIR "/conformance/" TEST_DIR "/data%d.xml", j + 1);
st->node = lyd_parse_path(st->ctx, buf, LYD_XML, LYD_OPT_CONFIG | LYD_OPT_NOAUTODEL | LYD_OPT_STRICT);
st->node = lyd_parse_path(st->ctx, buf, LYD_XML, LYD_OPT_CONFIG | LYD_OPT_STRICT);
if (data_files_fail[j]) {
assert_ptr_equal(st->node, NULL);
} else {
Expand Down
2 changes: 1 addition & 1 deletion tests/conformance/test_sec7_9_4.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ TEST_CHOICE(void **state)

for (j = 0; j < TEST_DATA_FILE_COUNT; ++j) {
sprintf(buf, TESTS_DIR "/conformance/" TEST_DIR "/data%d.xml", j + 1);
st->node = lyd_parse_path(st->ctx, buf, LYD_XML, LYD_OPT_CONFIG | LYD_OPT_NOAUTODEL);
st->node = lyd_parse_path(st->ctx, buf, LYD_XML, LYD_OPT_CONFIG);
if (data_files_fail[j]) {
assert_ptr_equal(st->node, NULL);
} else {
Expand Down
2 changes: 1 addition & 1 deletion tests/conformance/test_sec9_10.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ TEST_IDENTITYREF(void **state)

for (j = 0; j < TEST_DATA_FILE_COUNT; ++j) {
sprintf(buf, TESTS_DIR "/conformance/" TEST_DIR "/data%d.xml", j + 1);
st->node = lyd_parse_path(st->ctx, buf, LYD_XML, LYD_OPT_CONFIG | LYD_OPT_NOAUTODEL);
st->node = lyd_parse_path(st->ctx, buf, LYD_XML, LYD_OPT_CONFIG);
if (data_files_fail[j]) {
assert_ptr_equal(st->node, NULL);
} else {
Expand Down
6 changes: 3 additions & 3 deletions tests/data/test_emptycont.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ test_parse_autodel1(void **state)
const char *xml = "<topleaf xmlns=\"urn:libyang:tests:emptycont\">X</topleaf>"
"<top xmlns=\"urn:libyang:tests:emptycont\"><b><b1>B</b1></b><c><c1>C</c1></c></top>";

st->dt = lyd_parse_mem(st->ctx, xml, LYD_XML, LYD_OPT_CONFIG);
st->dt = lyd_parse_mem(st->ctx, xml, LYD_XML, LYD_OPT_CONFIG | LYD_OPT_WHENAUTODEL);
assert_ptr_not_equal(st->dt, NULL);
lyd_print_mem(&(st->xml), st->dt, LYD_XML, LYP_WITHSIBLINGS);
assert_string_equal(st->xml, "<topleaf xmlns=\"urn:libyang:tests:emptycont\">X</topleaf><top xmlns=\"urn:libyang:tests:emptycont\"><c/></top>");
Expand All @@ -111,7 +111,7 @@ test_parse_autodel2(void **state)
struct state *st = (*state);
const char *xml = "<top xmlns=\"urn:libyang:tests:emptycont\"><b><b1>B</b1></b><c><c1>C</c1></c></top>";

st->dt = lyd_parse_mem(st->ctx, xml, LYD_XML, LYD_OPT_CONFIG);
st->dt = lyd_parse_mem(st->ctx, xml, LYD_XML, LYD_OPT_CONFIG | LYD_OPT_WHENAUTODEL);
assert_ptr_not_equal(st->dt, NULL);
lyd_print_mem(&(st->xml), st->dt, LYD_XML, LYP_WITHSIBLINGS);
assert_string_equal(st->xml, "<top xmlns=\"urn:libyang:tests:emptycont\"><c/></top>");
Expand All @@ -124,7 +124,7 @@ test_parse_autodel3(void **state)
const char *xml = "<topleaf xmlns=\"urn:libyang:tests:emptycont\">X</topleaf>"
"<top xmlns=\"urn:libyang:tests:emptycont\"><b><b1>B</b1></b></top>";

st->dt = lyd_parse_mem(st->ctx, xml, LYD_XML, LYD_OPT_CONFIG);
st->dt = lyd_parse_mem(st->ctx, xml, LYD_XML, LYD_OPT_CONFIG | LYD_OPT_WHENAUTODEL);
assert_ptr_not_equal(st->dt, NULL);
lyd_print_mem(&(st->xml), st->dt, LYD_XML, LYP_WITHSIBLINGS);
assert_string_equal(st->xml, "<topleaf xmlns=\"urn:libyang:tests:emptycont\">X</topleaf>");
Expand Down
8 changes: 4 additions & 4 deletions tests/data/test_when.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,15 +99,15 @@ test_parse_autodel(void **state)
struct state *st = (*state);
const char *xml = "<top xmlns=\"urn:libyang:tests:when\"><b><b1>B</b1></b><c>C</c></top>";

st->dt = lyd_parse_mem(st->ctx, xml, LYD_XML, LYD_OPT_CONFIG);
st->dt = lyd_parse_mem(st->ctx, xml, LYD_XML, LYD_OPT_CONFIG | LYD_OPT_WHENAUTODEL);
assert_ptr_equal(st->dt, NULL);
assert_int_equal(ly_errno, LY_SUCCESS);

xml = "<topleaf xmlns=\"urn:libyang:tests:when\">X</topleaf>"
"<top xmlns=\"urn:libyang:tests:when\"><b><b1>B</b1></b><c>C</c></top>";
lyd_free_withsiblings(st->dt);

st->dt = lyd_parse_mem(st->ctx, xml, LYD_XML, LYD_OPT_CONFIG);
st->dt = lyd_parse_mem(st->ctx, xml, LYD_XML, LYD_OPT_CONFIG | LYD_OPT_WHENAUTODEL);
assert_ptr_not_equal(st->dt, NULL);
lyd_print_mem(&(st->xml), st->dt, LYD_XML, LYP_WITHSIBLINGS);
assert_string_equal(st->xml, "<topleaf xmlns=\"urn:libyang:tests:when\">X</topleaf>");
Expand Down Expand Up @@ -146,7 +146,7 @@ test_insert_autodel(void **state)
node = lyd_new(st->dt, NULL, "b");
assert_ptr_not_equal(lyd_new_leaf(node, NULL, "b1", "B"), NULL);

assert_int_equal(lyd_validate(&(st->dt), LYD_OPT_CONFIG, NULL), 0);
assert_int_equal(lyd_validate(&(st->dt), LYD_OPT_CONFIG | LYD_OPT_WHENAUTODEL, NULL), 0);
assert_ptr_equal(st->dt, NULL);

st->dt = lyd_new(NULL, st->mod, "top");
Expand All @@ -161,7 +161,7 @@ test_insert_autodel(void **state)
assert_ptr_not_equal(node, NULL);
assert_ptr_not_equal(lyd_new_leaf(node, NULL, "b1", "B"), NULL);

assert_int_equal(lyd_validate(&(st->dt), LYD_OPT_CONFIG, NULL), 0);
assert_int_equal(lyd_validate(&(st->dt), LYD_OPT_CONFIG | LYD_OPT_WHENAUTODEL, NULL), 0);
lyd_print_mem(&(st->xml), st->dt, LYD_XML, 0);
assert_string_equal(st->xml, "<topleaf xmlns=\"urn:libyang:tests:when\">X</topleaf>");
}
Expand Down
2 changes: 1 addition & 1 deletion tests/data/test_when_1.1.c
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ test_dependency_autodel(void **state)
node = lyd_new_path(st->dt, st->ctx, "/when-depend:top/e", "val_e", 0, 0);
assert_ptr_not_equal(node, NULL);

assert_int_equal(lyd_validate(&(st->dt), LYD_OPT_CONFIG, NULL), 0);
assert_int_equal(lyd_validate(&(st->dt), LYD_OPT_CONFIG | LYD_OPT_WHENAUTODEL, NULL), 0);

assert_ptr_equal(st->dt, NULL);
}
Expand Down

0 comments on commit bbc43b1

Please sign in to comment.