Skip to content

Commit

Permalink
context: add support for LYD_VALIDATE_MULTI_ERROR
Browse files Browse the repository at this point in the history
Thanks to the LYD_VALIDATE_MULTI_ERROR, the validation does not stop at
the first error, but generates all the detected errors.

Add a dedicated test.

Fixes: #79
Signed-off-by: Sergei Markov <[email protected]>
Signed-off-by: Samuel Gauthier <[email protected]>
  • Loading branch information
smark28 authored and samuel-gauthier committed Jan 26, 2024
1 parent b62fb0d commit 3e3af68
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 1 deletion.
1 change: 1 addition & 0 deletions cffi/cdefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,7 @@ LY_ERR lyd_print_all(struct ly_out *, const struct lyd_node *, LYD_FORMAT, uint3
#define LYD_VALIDATE_NO_STATE ...
#define LYD_VALIDATE_PRESENT ...
#define LYD_VALIDATE_OPTS_MASK ...
#define LYD_VALIDATE_MULTI_ERROR ...

LY_ERR lyd_parse_data_mem(const struct ly_ctx *, const char *, LYD_FORMAT, uint32_t, uint32_t, struct lyd_node **);

Expand Down
9 changes: 8 additions & 1 deletion libyang/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,7 @@ def parse_data(
ordered: bool = False,
strict: bool = False,
validate_present: bool = False,
validate_multi_error: bool = False,
) -> Optional[DNode]:
if self.cdata is None:
raise RuntimeError("context already destroyed")
Expand All @@ -351,7 +352,9 @@ def parse_data(
strict=strict,
)
validation_flgs = validation_flags(
no_state=no_state, validate_present=validate_present
no_state=no_state,
validate_present=validate_present,
validate_multi_error=validate_multi_error,
)
fmt = data_format(fmt)
encode = True
Expand Down Expand Up @@ -403,6 +406,7 @@ def parse_data_mem(
ordered: bool = False,
strict: bool = False,
validate_present: bool = False,
validate_multi_error: bool = False,
) -> Optional[DNode]:
return self.parse_data(
fmt,
Expand All @@ -416,6 +420,7 @@ def parse_data_mem(
ordered=ordered,
strict=strict,
validate_present=validate_present,
validate_multi_error=validate_multi_error,
)

def parse_data_file(
Expand All @@ -430,6 +435,7 @@ def parse_data_file(
ordered: bool = False,
strict: bool = False,
validate_present: bool = False,
validate_multi_error: bool = False,
) -> Optional[DNode]:
return self.parse_data(
fmt,
Expand All @@ -443,6 +449,7 @@ def parse_data_file(
ordered=ordered,
strict=strict,
validate_present=validate_present,
validate_multi_error=validate_multi_error,
)

def __iter__(self) -> Iterator[Module]:
Expand Down
3 changes: 3 additions & 0 deletions libyang/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,12 +171,15 @@ def data_type(dtype):
def validation_flags(
no_state: bool = False,
validate_present: bool = False,
validate_multi_error: bool = False,
) -> int:
flags = 0
if no_state:
flags |= lib.LYD_VALIDATE_NO_STATE
if validate_present:
flags |= lib.LYD_VALIDATE_PRESENT
if validate_multi_error:
flags |= lib.LYD_VALIDATE_MULTI_ERROR
return flags


Expand Down
25 changes: 25 additions & 0 deletions tests/test_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,31 @@ def test_data_parse_config_xml(self):
finally:
dnode.free()

XML_CONFIG_MULTI_ERROR = """<conf xmlns="urn:yang:yolo:system">
<hostname>foo</hostname>
<url>
<proto>https</proto>
<path>/CESNET/libyang-python</path>
<enabled>abcd</enabled>
</url>
<number>2000</number>
</conf>
"""

def test_data_parse_config_xml_multi_error(self):
with self.assertRaises(Exception) as cm:
self.ctx.parse_data_mem(
self.XML_CONFIG_MULTI_ERROR,
"xml",
validate_present=True,
validate_multi_error=True,
)
self.assertEqual(
str(cm.exception),
'failed to parse data tree: Invalid boolean value "abcd".: '
'List instance is missing its key "host".',
)

XML_STATE = """<state xmlns="urn:yang:yolo:system">
<hostname>foo</hostname>
<url>
Expand Down

0 comments on commit 3e3af68

Please sign in to comment.