From 0a8ba9ee96ffae50a9db1654b95d10171f3995f1 Mon Sep 17 00:00:00 2001 From: Christophe Dufaza Date: Thu, 17 Oct 2024 22:16:29 +0200 Subject: [PATCH] edtlib: tests: cover basics of filtering inherited properties Use-case "B includes I includes X": - X is a base binding file, specifying common properties - I is an intermediary binding file, which includes X without modification nor filter - B includes I, filtering the properties it chooses to inherit with an allowlist or a blocklist Check that the properties inherited from X via I are actually filtered as B intends to, up to the grandchild-binding level. Signed-off-by: Christophe Dufaza --- .../tests/test-bindings-include/simple.yaml | 30 +++++ .../simple_filter_allowlist.yaml | 12 ++ .../simple_filter_blocklist.yaml | 12 ++ .../test-bindings-include/simple_inherit.yaml | 5 + .../python-devicetree/tests/test_edtlib.py | 112 ++++++++++++++++++ 5 files changed, 171 insertions(+) create mode 100644 scripts/dts/python-devicetree/tests/test-bindings-include/simple.yaml create mode 100644 scripts/dts/python-devicetree/tests/test-bindings-include/simple_filter_allowlist.yaml create mode 100644 scripts/dts/python-devicetree/tests/test-bindings-include/simple_filter_blocklist.yaml create mode 100644 scripts/dts/python-devicetree/tests/test-bindings-include/simple_inherit.yaml diff --git a/scripts/dts/python-devicetree/tests/test-bindings-include/simple.yaml b/scripts/dts/python-devicetree/tests/test-bindings-include/simple.yaml new file mode 100644 index 00000000000000..9ce3fe8b1ee268 --- /dev/null +++ b/scripts/dts/python-devicetree/tests/test-bindings-include/simple.yaml @@ -0,0 +1,30 @@ +# SPDX-License-Identifier: BSD-3-Clause +# +# Base properties for testing property filters up to +# the grandchild-binding level. + +properties: + prop-1: + type: int + prop-2: + type: int + prop-3: + type: int + +child-binding: + properties: + child-prop-1: + type: int + child-prop-2: + type: int + child-prop-3: + type: int + + child-binding: + properties: + grandchild-prop-1: + type: int + grandchild-prop-2: + type: int + grandchild-prop-3: + type: int diff --git a/scripts/dts/python-devicetree/tests/test-bindings-include/simple_filter_allowlist.yaml b/scripts/dts/python-devicetree/tests/test-bindings-include/simple_filter_allowlist.yaml new file mode 100644 index 00000000000000..cae1cb2800acc3 --- /dev/null +++ b/scripts/dts/python-devicetree/tests/test-bindings-include/simple_filter_allowlist.yaml @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: BSD-3-Clause +# +# Filter inherited property specifications +# up to the grandchild-binding level. + +include: + - name: simple_inherit.yaml + property-allowlist: [prop-1] + child-binding: + property-allowlist: [child-prop-1] + child-binding: + property-allowlist: [grandchild-prop-1] diff --git a/scripts/dts/python-devicetree/tests/test-bindings-include/simple_filter_blocklist.yaml b/scripts/dts/python-devicetree/tests/test-bindings-include/simple_filter_blocklist.yaml new file mode 100644 index 00000000000000..e605c6a65dc5e7 --- /dev/null +++ b/scripts/dts/python-devicetree/tests/test-bindings-include/simple_filter_blocklist.yaml @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: BSD-3-Clause +# +# Filter inherited property specifications +# up to the grandchild-binding level. + +include: + - name: simple_inherit.yaml + property-blocklist: [prop-2, prop-3] + child-binding: + property-blocklist: [child-prop-2, child-prop-3] + child-binding: + property-blocklist: [grandchild-prop-2, grandchild-prop-3] diff --git a/scripts/dts/python-devicetree/tests/test-bindings-include/simple_inherit.yaml b/scripts/dts/python-devicetree/tests/test-bindings-include/simple_inherit.yaml new file mode 100644 index 00000000000000..8a95ef38f95115 --- /dev/null +++ b/scripts/dts/python-devicetree/tests/test-bindings-include/simple_inherit.yaml @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: BSD-3-Clause +# +# Inherits property specifications without modification. + +include: simple.yaml diff --git a/scripts/dts/python-devicetree/tests/test_edtlib.py b/scripts/dts/python-devicetree/tests/test_edtlib.py index 80709feac0907a..30fbc7c3fc36f3 100644 --- a/scripts/dts/python-devicetree/tests/test_edtlib.py +++ b/scripts/dts/python-devicetree/tests/test_edtlib.py @@ -365,6 +365,118 @@ def test_include_filters(): assert set(child.prop2specs.keys()) == {'child-prop-1', 'child-prop-2', 'x', 'z'} # root level 'y' is blocked +def test_include_filters_inherited_bindings() -> None: + '''Test the basics of filtering properties inherited via an intermediary binding file. + + Use-case "B includes I includes X": + - X is a base binding file, specifying common properties + - I is an intermediary binding file, which includes X without modification + nor filter + - B includes I, filtering the properties it chooses to inherit + with an allowlist or a blocklist + + Checks that the properties inherited from X via I are actually filtered + as B intends to. + ''' + fname2path = { + # Base binding file, specifies a few properties up to the grandchild-binding level. + "simple.yaml": "test-bindings-include/simple.yaml", + # 'include:'s the base file above, without modification nor filter + "simple_inherit.yaml": "test-bindings-include/simple_inherit.yaml", + } + with from_here(): + binding = edtlib.Binding( + # Filters inherited specifications with an allowlist. + "test-bindings-include/simple_filter_allowlist.yaml", + fname2path, + require_compatible=False, + require_description=False, + ) + # Only property allowed. + assert {"prop-1"} == set(binding.prop2specs.keys()) + + with from_here(): + binding = edtlib.Binding( + # Filters inherited specifications with a blocklist. + "test-bindings-include/simple_filter_blocklist.yaml", + fname2path, + require_compatible=False, + require_description=False, + ) + # Only non blocked property. + assert {"prop-1"} == set(binding.prop2specs.keys()) + +def test_include_filters_inherited_child_bindings() -> None: + '''Test the basics of filtering properties inherited via an intermediary binding file + (child-binding level). + + See also: test_include_filters_inherited_bindings() + ''' + fname2path = { + "simple.yaml": "test-bindings-include/simple.yaml", + "simple_inherit.yaml": "test-bindings-include/simple_inherit.yaml", + } + with from_here(): + binding = edtlib.Binding( + "test-bindings-include/simple_filter_allowlist.yaml", + fname2path, + require_compatible=False, + require_description=False, + ) + assert binding.child_binding + child_binding = binding.child_binding + # Only property allowed. + assert {"child-prop-1"} == set(child_binding.prop2specs.keys()) + + with from_here(): + binding = edtlib.Binding( + "test-bindings-include/simple_filter_blocklist.yaml", + fname2path, + require_compatible=False, + require_description=False, + ) + # Only non blocked property. + assert binding.child_binding + child_binding = binding.child_binding + assert {"child-prop-1"} == set(child_binding.prop2specs.keys()) + +def test_include_filters_inherited_grandchild_bindings() -> None: + '''Test the basics of filtering properties inherited via an intermediary binding file + (grandchild-binding level). + + See also: test_include_filters_inherited_bindings() + ''' + fname2path = { + "simple.yaml": "test-bindings-include/simple.yaml", + "simple_inherit.yaml": "test-bindings-include/simple_inherit.yaml", + } + with from_here(): + binding = edtlib.Binding( + "test-bindings-include/simple_filter_allowlist.yaml", + fname2path, + require_compatible=False, + require_description=False, + ) + assert binding.child_binding + child_binding = binding.child_binding + assert child_binding.child_binding + grandchild_binding = child_binding.child_binding + # Only property allowed. + assert {"grandchild-prop-1"} == set(grandchild_binding.prop2specs.keys()) + + with from_here(): + binding = edtlib.Binding( + "test-bindings-include/simple_filter_blocklist.yaml", + fname2path, + require_compatible=False, + require_description=False, + ) + assert binding.child_binding + child_binding = binding.child_binding + assert child_binding.child_binding + grandchild_binding = child_binding.child_binding + # Only non blocked property. + assert {"grandchild-prop-1"} == set(grandchild_binding.prop2specs.keys()) def test_bus(): '''Test 'bus:' and 'on-bus:' in bindings'''