twister: Fix inconsistency among DT compat filters

This small change concerns the following filter functions:

   1. `dt_compat_enabled(C)`:
      There's a node with compatible `C` and status "okay".

   2. `dt_enabled_alias_with_parent_compat(A, C)`:
      There's a node with alias `A` and status "okay", and its parent
      has compatible `C`.

   3. `dt_label_with_parent_compat_enabled(L, C)`:
      There's a node with label `L`, and its parent has compatible `C`
      and status "okay".

All three functions involve checking whether some node or its parent has
a given compatible, but the way this has been checked is inconsistent.
Function (1) has done it with this Python conditional:

   compat in node.compats

while (2) and (3) have used:

   parent.matching_compat == compat

The first check works well with nodes that have multiple compatibles,
and it is more aligned with the notion of "has_compat" as seen in the
devicetree macros for C, CMake, and Kconfig.

Arguably, `matching_compat` shouldn't have been used here, because it is
actually a property of a node's binding, moreso than of the node itself.
In practice, it's usually equal to the first compatible for which edtlib
has found a binding, which at first glance is just more constrained than
the `node.compats` check. However, there also exist obscure cases where
the `node.compats` are empty, while the `node.matching_compat` is not.

For now, the three functions can use a combined check, to improve
consistency and utility while avoiding breakage:

   node.matching_compat == compat or compat in node.compats

Signed-off-by: Grzegorz Swiderski <grzegorz.swiderski@nordicsemi.no>
This commit is contained in:
Grzegorz Swiderski 2024-07-08 06:26:39 +02:00 committed by Fabio Baltieri
parent 89bf698d90
commit eadc3d08c2

View file

@ -227,7 +227,7 @@ def ast_expr(ast, env, edt):
elif ast[0] == "dt_compat_enabled":
compat = ast[1][0]
for node in edt.nodes:
if compat in node.compats and node.status == "okay":
if (node.matching_compat == compat or compat in node.compats) and node.status == "okay":
return True
return False
elif ast[0] == "dt_alias_exists":
@ -247,7 +247,8 @@ def ast_expr(ast, env, edt):
parent = node.parent
if parent is None:
continue
if node.status == "okay" and alias in node.aliases and parent.matching_compat == compat:
if node.status == "okay" and alias in node.aliases and \
(parent.matching_compat == compat or compat in parent.compats):
return True
return False
elif ast[0] == "dt_label_with_parent_compat_enabled":
@ -258,7 +259,8 @@ def ast_expr(ast, env, edt):
parent = node.parent
else:
return False
return parent is not None and parent.status == 'okay' and parent.matching_compat == compat
return parent is not None and parent.status == 'okay' and \
(parent.matching_compat == compat or compat in parent.compats)
elif ast[0] == "dt_chosen_enabled":
chosen = ast[1][0]
node = edt.chosen_node(chosen)