Skip to content

Commit

Permalink
Dimbleby multiple bases (#354)
Browse files Browse the repository at this point in the history
* Fork here PR #248

#248

* Add ids and idrefs derived from multiple bases

* Update UnitTests to check for Identities of multiple bases

* Fix format with black
  • Loading branch information
JoseIgnacioTamayo authored Aug 5, 2024
1 parent 5ffbcbf commit 8bcdf61
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 51 deletions.
54 changes: 26 additions & 28 deletions pyangbind/helpers/identity.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ def build_store_from_definitions(self, ctx, defnd):
this_id = unresolved_identities.pop(0)
iddef = defnd[this_id]

base = iddef.search_one("base")
try:
mainmod = iddef.main_module()
except AttributeError:
Expand All @@ -89,22 +88,17 @@ def build_store_from_definitions(self, ctx, defnd):
defmod = mainmod

defining_module = defmod.arg
namespace = defmod.search_one("namespace").arg
prefix = defmod.search_one("prefix").arg

if base is None:
# Add a new identity which can be a base
tid = Identity(iddef.arg)
tid.source_module = defining_module
tid.source_namespace = namespace
tid.add_prefix(prefix)
self.add_identity(tid)
# Check we don't already have this identity defined
if self.find_identity_by_source_name(defining_module, iddef.arg) is not None:
continue

if defining_module in mod_ref_prefixes:
for i in mod_ref_prefixes[defining_module]:
tid.add_prefix(i)
namespace = defmod.search_one("namespace").arg
prefix = defmod.search_one("prefix").arg

else:
base_ids = []
bases = iddef.search("base")
for base in bases:
# Determine what the name of the base and the prefix for
# the base should be
if ":" in base.arg:
Expand All @@ -121,26 +115,30 @@ def build_store_from_definitions(self, ctx, defnd):
# and if not, then push this identity back onto the stack
unresolved_identities.append(this_id)
unresolved_identity_count[this_id] += 1
break
# FIXME(Joey Wilhelm): `unresolved_idc` and `ident` are both undefined. What is the intent of this code?
# if unresolved_identity_count[this_id] > 1000:
# if unresolved_idc[ident] > 1000:
# sys.stderr.write("could not find a match for %s base: %s\n" %
# (iddef.arg, base_name))
# error_ids.append(ident)
else:
# Check we don't already have this identity defined
if self.find_identity_by_source_name(defining_module, iddef.arg) is None:
# otherwise, create a new identity that reflects this one
tid = Identity(iddef.arg)
tid.source_module = defining_module
tid.source_namespace = namespace
tid.add_prefix(prefix)
base_id.add_child(tid)
self.add_identity(tid)

if defining_module in mod_ref_prefixes:
for i in mod_ref_prefixes[defining_module]:
tid.add_prefix(i)

base_ids.append(base_id)

else:
# We found all the bases (of which there may be none).
# Create a new identity that reflects this one.
tid = Identity(iddef.arg)
tid.source_module = defining_module
tid.source_namespace = namespace
tid.add_prefix(prefix)
self.add_identity(tid)
for base_id in base_ids:
base_id.add_child(tid)

if defining_module in mod_ref_prefixes:
for i in mod_ref_prefixes[defining_module]:
tid.add_prefix(i)

if error_ids:
raise TypeError("could not resolve identities %s" % error_ids)
Expand Down
23 changes: 16 additions & 7 deletions tests/identityref/identityref.yang
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module identityref {
yang-version "1";
yang-version "1.1";
namespace "http://rob.sh/yang/test/identityref";
prefix "foo";

Expand Down Expand Up @@ -37,6 +37,7 @@ module identityref {

identity son {
base father;
base mother;
}

identity greatgrandmother;
Expand All @@ -59,43 +60,51 @@ module identityref {

identity daughter {
base mother;
base father;
}

identity local-base;

container test-container {
leaf id1 {
leaf id_base {
type identityref {
base base-identity;
}
}

leaf idr1 {
leaf id_remote {
type identityref {
base defn:remote-base;
}
}

leaf id2 {
leaf grandfather {
type identityref {
base grandfather;
}
}

leaf id3 {
leaf greatgrandmother {
type identityref {
base greatgrandmother;
}
}

leaf id4 {
leaf mother {
type identityref {
base mother;
}
}

leaf id5 {
leaf grandmother {
type identityref {
base grandmother;
}
}

leaf grandparent {
type identityref {
base grandfather;
base grandmother;
}
}
Expand Down
51 changes: 35 additions & 16 deletions tests/identityref/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,16 @@ def setUp(self):
self.instance = self.bindings.identityref()

def test_identityref_leafs_get_created(self):
for leaf in ["id1", "idr1"]:
for leaf in ["id_base", "id_remote"]:
with self.subTest(leaf=leaf):
self.assertTrue(hasattr(self.instance.test_container, leaf))

def test_cant_assign_invalid_string_to_identityref(self):
with self.assertRaises(ValueError):
self.instance.test_container.id1 = "hello"
self.instance.test_container.grandfather = "hello"

def test_identityref_leafs_are_blank_by_default(self):
for leaf in ["id1", "idr1"]:
for leaf in ["id_base", "id_remote"]:
with self.subTest(leaf=leaf):
self.assertEqual(getattr(self.instance.test_container, leaf), "")

Expand All @@ -33,7 +33,7 @@ def test_identityref_accepts_valid_identity_values(self):
with self.subTest(identity=identity):
allowed = True
try:
self.instance.test_container.id1 = identity
self.instance.test_container.id_base = identity
except ValueError:
allowed = False
self.assertTrue(allowed)
Expand All @@ -43,7 +43,7 @@ def test_remote_identityref_accepts_valid_identity_values(self):
with self.subTest(identity=identity):
allowed = True
try:
self.instance.test_container.idr1 = identity
self.instance.test_container.id_remote = identity
except ValueError:
allowed = False
self.assertTrue(allowed)
Expand All @@ -52,6 +52,8 @@ def test_set_ancestral_identities_one(self):
for identity, valid in [
("father", True),
("son", True),
("daughter", True),
("mother", False),
("foo:father", True),
("foo:son", True),
("elephant", False),
Expand All @@ -60,10 +62,10 @@ def test_set_ancestral_identities_one(self):
with self.subTest(identity=identity, valid=valid):
allowed = True
try:
self.instance.test_container.id2 = identity
self.instance.test_container.grandfather = identity
except ValueError:
allowed = False
self.assertEqual(allowed, valid)
self.assertEqual(allowed, valid, identity)

def test_set_ancestral_identities_two(self):
for identity, valid in [
Expand All @@ -73,43 +75,60 @@ def test_set_ancestral_identities_two(self):
("aunt", True),
("cousin", True),
("daughter", True),
("son", False),
("son", True),
("father", False),
("grandfather", False),
]:
with self.subTest(identity=identity, valid=valid):
allowed = True
try:
self.instance.test_container.id3 = identity
self.instance.test_container.greatgrandmother = identity
except ValueError:
allowed = False
self.assertEqual(allowed, valid)
self.assertEqual(allowed, valid, identity)

def test_set_ancestral_identities_three(self):
for identity, valid in [("daughter", True), ("cousin", False), ("aunt", False)]:
for identity, valid in [("daughter", True), ("son", True), ("cousin", False), ("aunt", False)]:
with self.subTest(identity=identity, valid=valid):
allowed = True
try:
self.instance.test_container.id4 = identity
self.instance.test_container.mother = identity
except ValueError:
allowed = False
self.assertEqual(allowed, valid)
self.assertEqual(allowed, valid, identity)

def test_set_ancestral_identities_four(self):
for identity, valid in [
("daughter", True),
("son", True),
("cousin", True),
("mother", True),
("father", False),
("aunt", True),
("greatgrandmother", False),
]:
with self.subTest(identity=identity, valid=valid):
allowed = True
try:
self.instance.test_container.id5 = identity
self.instance.test_container.grandmother = identity
except ValueError:
allowed = False
self.assertEqual(allowed, valid)
self.assertEqual(allowed, valid, identity)

def test_set_ancestral_identities_five(self):
for identity, valid in [
("mother", False),
("father", True),
("cousin", False),
("son", True),
]:
with self.subTest(identity=identity, valid=valid):
allowed = True
try:
self.instance.test_container.grandparent = identity
except ValueError:
allowed = False
self.assertEqual(allowed, valid, identity)

def test_grouping_identity_inheritance(self):
for address_type, valid in [
Expand All @@ -135,7 +154,7 @@ def test_set_identityref_from_imported_module(self):
with self.subTest(identity=identity, valid=valid):
allowed = True
try:
self.instance.test_container.idr1 = identity
self.instance.test_container.id_remote = identity
except ValueError:
allowed = False
self.assertEqual(allowed, valid)
Expand Down

0 comments on commit 8bcdf61

Please sign in to comment.