Skip to content

Commit

Permalink
lib: fix specific entry queries
Browse files Browse the repository at this point in the history
- fix key leaf queries
- fix specific list entry with non-key leaf top element

Signed-off-by: Christian Hopps <[email protected]>
  • Loading branch information
choppsv1 committed Jan 2, 2024
1 parent 353ee7b commit 7e65956
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 2 deletions.
16 changes: 14 additions & 2 deletions lib/northbound_oper.c
Original file line number Diff line number Diff line change
Expand Up @@ -499,7 +499,11 @@ static enum nb_error nb_op_ys_init_node_infos(struct nb_op_yield_state *ys)
ret = NB_ERR_NOT_FOUND;
return ret;
}
assert(CHECK_FLAG(node->schema->nodetype, LYS_CONTAINER | LYS_LIST));
while (node &&
!CHECK_FLAG(node->schema->nodetype, LYS_CONTAINER | LYS_LIST))
node = &node->parent->node;
if (!node)
return NB_ERR_NOT_FOUND;

inner = (struct lyd_node_inner *)node;
for (len = 1; inner->parent; len++)
Expand Down Expand Up @@ -1237,9 +1241,18 @@ static enum nb_error __walk(struct nb_op_yield_state *ys, bool is_resume)
* `route-entry` element for a query
* `.../route-entry/metric` where the list element had
* no metric value.
*
* However, if the user query is for a key of a list
* element, then when we reach that list element it will
* have no non-key children, check for this condition
* and do not reap if true.
*/
if (!list_start && ni->inner &&
!lyd_child_no_keys(&ni->inner->node) &&
/* not the top element with a key match */
!((darr_ilen(ys->node_infos) ==
darr_ilen(ys->schema_path) - 1) &&
lysc_is_key((*darr_last(ys->schema_path)))) &&
/* is this at or below the base? */
darr_ilen(ys->node_infos) <= ys->query_base_level)
lyd_free_tree(&ni->inner->node);
Expand Down Expand Up @@ -1674,7 +1687,6 @@ static enum nb_error nb_op_walk_start(struct nb_op_yield_state *ys)
* Get the node_info path (stack) corresponding to the uniquely
* resolvable data nodes from the beginning of the xpath query.
*/
// I think this moves
ret = nb_op_ys_init_node_infos(ys);
if (ret != NB_OK)
return ret;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"frr-interface:lib": {
"interface": [
{
"name": "r1-eth0"
}
]
}
}
10 changes: 10 additions & 0 deletions tests/topotests/mgmt_oper/simple-results/result-intf-eth0-vrf.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"frr-interface:lib": {
"interface": [
{
"name": "r1-eth0",
"vrf": "default"
}
]
}
}
21 changes: 21 additions & 0 deletions tests/topotests/mgmt_oper/simple-results/result-intf-name.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"frr-interface:lib": {
"interface": [
{
"name": "lo"
},
{
"name": "r1-eth0"
},
{
"name": "lo-red"
},
{
"name": "r1-eth1"
},
{
"name": "red"
}
]
}
}
17 changes: 17 additions & 0 deletions tests/topotests/mgmt_oper/test_simple.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,23 @@ def test_oper_simple(tgen):
pytest.skip(tgen.errors)

query_results = [
(
# Non-key query with key specific selection
'/frr-interface:lib/interface[name="r1-eth0"]/vrf',
"simple-results/result-intf-eth0-vrf.json",
),
# Test machines will have different sets of interfaces so the test results will
# vary and need to be generated dynamically before this test is re-enabled
# (
# # Key query on generic list
# "/frr-interface:lib/interface/name",
# "simple-results/result-intf-name.json",
# ),
(
# Key query with key specific selection
'/frr-interface:lib/interface[name="r1-eth0"]/name',
"simple-results/result-intf-eth0-name.json",
),
("/frr-vrf:lib", "simple-results/result-lib.json"),
("/frr-vrf:lib/vrf", "simple-results/result-lib-vrf-nokey.json"),
(
Expand Down

0 comments on commit 7e65956

Please sign in to comment.