scripts: check_init_priorities: rework the error messages
The current error messages are a bit cryptic, rework them to make them more meaningful: - add an extra message on the first error to explain what the errors refer to. - rework the error message to be more explicit. - rework the priority string print to use a LEVEL+offset format to somehow highlight that the number is the offset from the level, not the actual priority. - print the init function name in addition to the devicetree path. Signed-off-by: Fabio Baltieri <fabiobaltieri@google.com>
This commit is contained in:
parent
2a70c31945
commit
dd178ce311
3 changed files with 30 additions and 21 deletions
|
@ -77,7 +77,7 @@ class Priority:
|
||||||
_DEVICE_INIT_LEVELS[self._level], self._priority)
|
_DEVICE_INIT_LEVELS[self._level], self._priority)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "%s %d" % (_DEVICE_INIT_LEVELS[self._level], self._priority)
|
return "%s+%d" % (_DEVICE_INIT_LEVELS[self._level], self._priority)
|
||||||
|
|
||||||
def __lt__(self, other):
|
def __lt__(self, other):
|
||||||
return self._level_priority < other._level_priority
|
return self._level_priority < other._level_priority
|
||||||
|
@ -214,7 +214,7 @@ class ZephyrInitLevels:
|
||||||
ordinal = self._device_ord_from_name(arg1_name)
|
ordinal = self._device_ord_from_name(arg1_name)
|
||||||
if ordinal:
|
if ordinal:
|
||||||
prio = Priority(level, priority)
|
prio = Priority(level, priority)
|
||||||
self.devices[ordinal] = prio
|
self.devices[ordinal] = (prio, arg0_name)
|
||||||
|
|
||||||
addr += size
|
addr += size
|
||||||
priority += 1
|
priority += 1
|
||||||
|
@ -267,8 +267,8 @@ class Validator():
|
||||||
self.log.info(f"Swapped priority: {dev_compat}, {dep_compat}")
|
self.log.info(f"Swapped priority: {dev_compat}, {dep_compat}")
|
||||||
dev_ord, dep_ord = dep_ord, dev_ord
|
dev_ord, dep_ord = dep_ord, dev_ord
|
||||||
|
|
||||||
dev_prio = self._obj.devices.get(dev_ord, None)
|
dev_prio, dev_init = self._obj.devices.get(dev_ord, (None, None))
|
||||||
dep_prio = self._obj.devices.get(dep_ord, None)
|
dep_prio, dep_init = self._obj.devices.get(dep_ord, (None, None))
|
||||||
|
|
||||||
if not dev_prio or not dep_prio:
|
if not dev_prio or not dep_prio:
|
||||||
return
|
return
|
||||||
|
@ -277,12 +277,18 @@ class Validator():
|
||||||
raise ValueError(f"{dev_node.path} and {dep_node.path} have the "
|
raise ValueError(f"{dev_node.path} and {dep_node.path} have the "
|
||||||
f"same priority: {dev_prio}")
|
f"same priority: {dev_prio}")
|
||||||
elif dev_prio < dep_prio:
|
elif dev_prio < dep_prio:
|
||||||
|
if not self.errors:
|
||||||
|
self.log.error("Device initialization priority validation failed, "
|
||||||
|
"the sequence of initialization calls does not match "
|
||||||
|
"the devicetree dependencies.")
|
||||||
self.errors += 1
|
self.errors += 1
|
||||||
self.log.error(
|
self.log.error(
|
||||||
f"{dev_node.path} {dev_prio} < {dep_node.path} {dep_prio}")
|
f"{dev_node.path} <{dev_init}> is initialized before its dependency "
|
||||||
|
f"{dep_node.path} <{dep_init}> ({dev_prio} < {dep_prio})")
|
||||||
else:
|
else:
|
||||||
self.log.info(
|
self.log.info(
|
||||||
f"{dev_node.path} {dev_prio} > {dep_node.path} {dep_prio}")
|
f"{dev_node.path} <{dev_init}> {dev_prio} > "
|
||||||
|
f"{dep_node.path} <{dep_init}> {dep_prio}")
|
||||||
|
|
||||||
def check_edt(self):
|
def check_edt(self):
|
||||||
"""Scan through all known devices and validate the init priorities."""
|
"""Scan through all known devices and validate the init priorities."""
|
||||||
|
|
|
@ -49,7 +49,7 @@ class TestPriority(unittest.TestCase):
|
||||||
|
|
||||||
def test_priority_strings(self):
|
def test_priority_strings(self):
|
||||||
prio = check_init_priorities.Priority("POST_KERNEL", 12)
|
prio = check_init_priorities.Priority("POST_KERNEL", 12)
|
||||||
self.assertEqual(str(prio), "POST_KERNEL 12")
|
self.assertEqual(str(prio), "POST_KERNEL+12")
|
||||||
self.assertEqual(repr(prio), "<Priority POST_KERNEL 12>")
|
self.assertEqual(repr(prio), "<Priority POST_KERNEL 12>")
|
||||||
|
|
||||||
class testZephyrInitLevels(unittest.TestCase):
|
class testZephyrInitLevels(unittest.TestCase):
|
||||||
|
@ -236,8 +236,8 @@ class testZephyrInitLevels(unittest.TestCase):
|
||||||
"SMP": [],
|
"SMP": [],
|
||||||
})
|
})
|
||||||
self.assertDictEqual(obj.devices, {
|
self.assertDictEqual(obj.devices, {
|
||||||
11: check_init_priorities.Priority("PRE_KERNEL_2", 0),
|
11: (check_init_priorities.Priority("PRE_KERNEL_2", 0), "i0"),
|
||||||
22: check_init_priorities.Priority("PRE_KERNEL_2", 1),
|
22: (check_init_priorities.Priority("PRE_KERNEL_2", 1), "i1"),
|
||||||
})
|
})
|
||||||
|
|
||||||
class testValidator(unittest.TestCase):
|
class testValidator(unittest.TestCase):
|
||||||
|
@ -280,10 +280,10 @@ class testValidator(unittest.TestCase):
|
||||||
validator._ord2node[1]._binding = None
|
validator._ord2node[1]._binding = None
|
||||||
validator._ord2node[2]._binding = None
|
validator._ord2node[2]._binding = None
|
||||||
|
|
||||||
validator._obj.devices = {1: 10}
|
validator._obj.devices = {1: (10, "i1")}
|
||||||
validator._check_dep(1, 2)
|
validator._check_dep(1, 2)
|
||||||
|
|
||||||
validator._obj.devices = {2: 20}
|
validator._obj.devices = {2: (20, "i2")}
|
||||||
validator._check_dep(1, 2)
|
validator._check_dep(1, 2)
|
||||||
|
|
||||||
self.assertFalse(validator.log.info.called)
|
self.assertFalse(validator.log.info.called)
|
||||||
|
@ -303,13 +303,15 @@ class testValidator(unittest.TestCase):
|
||||||
validator._ord2node[2]._binding = None
|
validator._ord2node[2]._binding = None
|
||||||
validator._ord2node[2].path = "/2"
|
validator._ord2node[2].path = "/2"
|
||||||
|
|
||||||
validator._obj.devices = {1: 10, 2: 20}
|
validator._obj.devices = {1: (10, "i1"), 2: (20, "i2")}
|
||||||
|
|
||||||
validator._check_dep(2, 1)
|
validator._check_dep(2, 1)
|
||||||
validator._check_dep(1, 2)
|
validator._check_dep(1, 2)
|
||||||
|
|
||||||
validator.log.info.assert_called_once_with("/2 20 > /1 10")
|
validator.log.info.assert_called_once_with("/2 <i2> 20 > /1 <i1> 10")
|
||||||
validator.log.error.assert_called_once_with("/1 10 < /2 20")
|
validator.log.error.assert_has_calls([
|
||||||
|
mock.call("/1 <i1> is initialized before its dependency /2 <i2> (10 < 20)")
|
||||||
|
])
|
||||||
self.assertEqual(validator.errors, 1)
|
self.assertEqual(validator.errors, 1)
|
||||||
|
|
||||||
@mock.patch("check_init_priorities.Validator.__init__", return_value=None)
|
@mock.patch("check_init_priorities.Validator.__init__", return_value=None)
|
||||||
|
@ -325,7 +327,7 @@ class testValidator(unittest.TestCase):
|
||||||
validator._ord2node[2]._binding = None
|
validator._ord2node[2]._binding = None
|
||||||
validator._ord2node[2].path = "/2"
|
validator._ord2node[2].path = "/2"
|
||||||
|
|
||||||
validator._obj.devices = {1: 10, 2: 10}
|
validator._obj.devices = {1: (10, "i1"), 2: (10, "i2")}
|
||||||
|
|
||||||
with self.assertRaises(ValueError):
|
with self.assertRaises(ValueError):
|
||||||
validator._check_dep(1, 2)
|
validator._check_dep(1, 2)
|
||||||
|
@ -347,13 +349,13 @@ class testValidator(unittest.TestCase):
|
||||||
validator._ord2node[3]._binding.compatible = "compat-3"
|
validator._ord2node[3]._binding.compatible = "compat-3"
|
||||||
validator._ord2node[3].path = "/3"
|
validator._ord2node[3].path = "/3"
|
||||||
|
|
||||||
validator._obj.devices = {1: 20, 3: 10}
|
validator._obj.devices = {1: (20, "i1"), 3: (10, "i3")}
|
||||||
|
|
||||||
validator._check_dep(3, 1)
|
validator._check_dep(3, 1)
|
||||||
|
|
||||||
self.assertListEqual(validator.log.info.call_args_list, [
|
self.assertListEqual(validator.log.info.call_args_list, [
|
||||||
mock.call("Swapped priority: compat-3, compat-1"),
|
mock.call("Swapped priority: compat-3, compat-1"),
|
||||||
mock.call("/3 20 > /1 10"),
|
mock.call("/3 <i1> 20 > /1 <i3> 10"),
|
||||||
])
|
])
|
||||||
self.assertEqual(validator.errors, 0)
|
self.assertEqual(validator.errors, 0)
|
||||||
|
|
||||||
|
|
|
@ -8,10 +8,11 @@
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
REFERENCE_OUTPUT = [
|
REFERENCE_OUTPUT = [
|
||||||
"ERROR: /i2c@11112222/test-i2c-dev@10 PRE_KERNEL_1 0 < /gpio@ffff PRE_KERNEL_1 1",
|
"ERROR: Device initialization priority validation failed, the sequence of initialization calls does not match the devicetree dependencies.",
|
||||||
"ERROR: /i2c@11112222/test-i2c-dev@10 PRE_KERNEL_1 0 < /i2c@11112222 PRE_KERNEL_1 2",
|
"ERROR: /i2c@11112222/test-i2c-dev@10 <NULL> is initialized before its dependency /gpio@ffff <NULL> (PRE_KERNEL_1+0 < PRE_KERNEL_1+1)",
|
||||||
"INFO: /i2c@11112222/test-i2c-dev@11 PRE_KERNEL_1 3 > /gpio@ffff PRE_KERNEL_1 1",
|
"ERROR: /i2c@11112222/test-i2c-dev@10 <NULL> is initialized before its dependency /i2c@11112222 <NULL> (PRE_KERNEL_1+0 < PRE_KERNEL_1+2)",
|
||||||
"INFO: /i2c@11112222/test-i2c-dev@11 PRE_KERNEL_1 3 > /i2c@11112222 PRE_KERNEL_1 2",
|
"INFO: /i2c@11112222/test-i2c-dev@11 <NULL> PRE_KERNEL_1+3 > /gpio@ffff <NULL> PRE_KERNEL_1+1",
|
||||||
|
"INFO: /i2c@11112222/test-i2c-dev@11 <NULL> PRE_KERNEL_1+3 > /i2c@11112222 <NULL> PRE_KERNEL_1+2",
|
||||||
]
|
]
|
||||||
|
|
||||||
if len(sys.argv) != 2:
|
if len(sys.argv) != 2:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue