Skip to content

Commit 634fc34

Browse files
Adrien Vasseurrjarry
authored andcommitted
schema: add state method for conditional if-features
Accessing feature states is useful to enable/disable leafs. However, when a if-feature contain a condition (not/or/and keywords), there is currently no way to get the state resulting of the expression. Add a state method to all IfFeatureExpr objects so a state of the entire if-feature expression can be evaluated. Test all basic cases (one operator).
1 parent 19fb38b commit 634fc34

File tree

4 files changed

+87
-4
lines changed

4 files changed

+87
-4
lines changed

libyang/schema.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -793,6 +793,9 @@ def __init__(self, context: "libyang.Context", cdata):
793793
def feature(self) -> Feature:
794794
return Feature(self.context, self.cdata)
795795

796+
def state(self) -> bool:
797+
return self.feature().state()
798+
796799
def dump(self, indent: int = 0) -> str:
797800
feat = self.feature()
798801
return "%s%s [%s]\n" % (" " * indent, feat.name(), feat.description())
@@ -810,6 +813,9 @@ def __init__(self, context: "libyang.Context", child: IfFeatureExprTree):
810813
self.context = context
811814
self.child = child
812815

816+
def state(self) -> bool:
817+
return not self.child.state()
818+
813819
def dump(self, indent: int = 0) -> str:
814820
return " " * indent + "NOT\n" + self.child.dump(indent + 1)
815821

@@ -829,6 +835,9 @@ def __init__(
829835
self.a = a
830836
self.b = b
831837

838+
def state(self) -> bool:
839+
return self.a.state() and self.b.state()
840+
832841
def dump(self, indent: int = 0) -> str:
833842
s = " " * indent + "AND\n"
834843
s += self.a.dump(indent + 1)
@@ -851,6 +860,9 @@ def __init__(
851860
self.a = a
852861
self.b = b
853862

863+
def state(self) -> bool:
864+
return self.a.state() or self.b.state()
865+
854866
def dump(self, indent: int = 0) -> str:
855867
s = " " * indent + "OR\n"
856868
s += self.a.dump(indent + 1)

tests/test_diff.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ class DiffTest(unittest.TestCase):
3838
(NodeTypeAdded, "/yolo-system:state/number"),
3939
(NodeTypeRemoved, "/yolo-system:conf/number"),
4040
(NodeTypeRemoved, "/yolo-system:state/number"),
41+
(SNodeAdded, "/yolo-system:conf/full"),
42+
(SNodeAdded, "/yolo-system:state/full"),
4143
(SNodeAdded, "/yolo-system:conf/hostname-ref"),
4244
(SNodeAdded, "/yolo-system:conf/url/enabled"),
4345
(SNodeAdded, "/yolo-system:conf/url/fetch"),

tests/test_schema.py

Lines changed: 59 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,8 @@ def test_rev_extensions(self):
135135
class IfFeatureTest(unittest.TestCase):
136136
def setUp(self):
137137
self.ctx = Context(YANG_DIR)
138-
mod = self.ctx.load_module("yolo-system")
139-
mod.feature_enable_all()
138+
self.mod = self.ctx.load_module("yolo-system")
139+
self.mod.feature_enable_all()
140140
self.leaf = next(
141141
self.ctx.find_path("/yolo-system:conf/yolo-system:isolation-level")
142142
)
@@ -158,6 +158,61 @@ def test_iffeature_tree(self):
158158
self.assertEqual(tree.a.feature().name(), "turbo-boost")
159159
self.assertEqual(tree.b.feature().name(), "networking")
160160

161+
def test_iffeature_state(self):
162+
def feature_disable_only(feature):
163+
self.mod.feature_disable_all()
164+
for f in self.mod.features():
165+
if f.name() == feature:
166+
continue
167+
self.mod.feature_enable(f.name())
168+
169+
leaf_simple = next(self.ctx.find_path("/yolo-system:conf/yolo-system:speed"))
170+
171+
self.mod.feature_disable_all()
172+
leaf_not = next(self.ctx.find_path("/yolo-system:conf/yolo-system:offline"))
173+
self.mod.feature_enable_all()
174+
175+
leaf_and = next(self.ctx.find_path("/yolo-system:conf/yolo-system:full"))
176+
leaf_or = next(
177+
self.ctx.find_path("/yolo-system:conf/yolo-system:isolation-level")
178+
)
179+
180+
# if-feature is just a feature
181+
tree = next(leaf_simple.if_features()).tree()
182+
self.mod.feature_enable_all()
183+
self.assertEqual(tree.state(), True)
184+
self.mod.feature_disable_all()
185+
self.assertEqual(tree.state(), False)
186+
187+
# if-feature is "NOT networking"
188+
tree = next(leaf_not.if_features()).tree()
189+
self.mod.feature_enable_all()
190+
self.assertEqual(tree.state(), False)
191+
self.mod.feature_disable_all()
192+
self.assertEqual(tree.state(), True)
193+
194+
# if-feature is "turbo-boost AND networking"
195+
tree = next(leaf_and.if_features()).tree()
196+
self.mod.feature_enable_all()
197+
self.assertEqual(tree.state(), True)
198+
self.mod.feature_disable_all()
199+
self.assertEqual(tree.state(), False)
200+
feature_disable_only("turbo-boost")
201+
self.assertEqual(tree.state(), False)
202+
feature_disable_only("networking")
203+
self.assertEqual(tree.state(), False)
204+
205+
# if-feature is "turbo-boost OR networking"
206+
tree = next(leaf_or.if_features()).tree()
207+
self.mod.feature_enable_all()
208+
self.assertEqual(tree.state(), True)
209+
self.mod.feature_disable_all()
210+
self.assertEqual(tree.state(), False)
211+
feature_disable_only("turbo-boost")
212+
self.assertEqual(tree.state(), True)
213+
feature_disable_only("networking")
214+
self.assertEqual(tree.state(), True)
215+
161216
def test_iffeature_str(self):
162217
iff = next(self.leaf.if_features())
163218
self.assertEqual(str(iff), "turbo-boost OR networking")
@@ -203,11 +258,11 @@ def test_cont_attrs(self):
203258

204259
def test_cont_iter(self):
205260
children = list(iter(self.container))
206-
self.assertEqual(len(children), 8)
261+
self.assertEqual(len(children), 9)
207262

208263
def test_cont_children_leafs(self):
209264
leafs = list(self.container.children(types=(SNode.LEAF,)))
210-
self.assertEqual(len(leafs), 6)
265+
self.assertEqual(len(leafs), 7)
211266

212267
def test_cont_parent(self):
213268
self.assertIsNone(self.container.parent())

tests/yang/yolo/yolo-system.yang

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,20 @@ module yolo-system {
106106
type uint32;
107107
}
108108

109+
leaf offline {
110+
description
111+
"When networking is disabled.";
112+
if-feature "not networking";
113+
type uint32;
114+
}
115+
116+
leaf full {
117+
description
118+
"Fast and online.";
119+
if-feature "turbo-boost and networking";
120+
type uint32;
121+
}
122+
109123
leaf isolation-level {
110124
description
111125
"The level of isolation.";

0 commit comments

Comments
 (0)