Skip to content

Commit d166448

Browse files
committed
[test] Add device file consistency test
1 parent 94c94a0 commit d166448

File tree

5 files changed

+412
-14
lines changed

5 files changed

+412
-14
lines changed

modm_devices/device_file.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,9 @@ def to_dict(self, t):
9595
if children:
9696
dd = defaultdict(list)
9797
for dc in map(self.to_dict, children):
98+
# print(dc)
9899
for k, v in dc.items():
100+
# if k == "signal" and v.get("name") == "seg40": print(v)
99101
dd[k].append(v)
100102
dk = {}
101103
for k, v in dd.items():
@@ -111,8 +113,11 @@ def to_dict(self, t):
111113
elif len(attrib):
112114
if any(k in d[t.tag] for k in attrib.keys()):
113115
raise ParserException("Node children are overwriting attribute '{}'!".format(k))
116+
# print(attrib.items())
114117
d[t.tag].update(attrib.items())
115118
return read_only({k:read_only(v) for k,v in d.items()})
116119

117120
properties = Converter(identifier).to_dict(self.rootnode.find("device"))
121+
# print(properties)
122+
# exit(1)
118123
return properties["device"]

modm_devices/device_identifier.py

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -99,12 +99,14 @@ def __init__(self, objs=None):
9999

100100
if isinstance(objs, DeviceIdentifier):
101101
self._ids = [objs.copy()]
102-
if isinstance(objs, (list, set, tuple)):
102+
elif isinstance(objs, (list, set, tuple)):
103103
for obj in objs:
104-
if isinstance(objs, DeviceIdentifier):
105-
self._ids.append(objs)
106-
if isinstance(objs, MultiDeviceIdentifier):
104+
if isinstance(obj, DeviceIdentifier):
105+
self._ids.append(obj)
106+
elif isinstance(objs, MultiDeviceIdentifier):
107107
self._ids = [dev for dev in objs.ids]
108+
elif objs is not None:
109+
print("No known conversion of '{}' to MultiDeviceIdentifier!".format(objs))
108110

109111
@property
110112
def ids(self):
@@ -126,13 +128,14 @@ def from_list(device_ids: list):
126128
mid._ids = [dev for dev in device_ids]
127129
return mid
128130

129-
def append(self, did):
130-
assert isinstance(did, DeviceIdentifier)
131+
def append(self, *dids):
132+
for did in dids:
133+
assert isinstance(did, DeviceIdentifier)
131134

132-
self._ids.append(did)
133-
self.__dirty = True
134-
self.__string = None
135-
self.__naming_schema = None
135+
self._ids.append(did)
136+
self.__dirty = True
137+
self.__string = None
138+
self.__naming_schema = None
136139

137140
def extend(self, dids):
138141
assert isinstance(dids, (MultiDeviceIdentifier, list))
@@ -344,4 +347,4 @@ def __str__(self):
344347
return self.string
345348

346349
def __repr__(self):
347-
return self.string
350+
return self.string

test/device_file_test.py

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
2+
import unittest
3+
import glob
4+
import os
5+
6+
import modm_devices.parser
7+
8+
DEVICE_FILES = None
9+
10+
class DeviceFileTest(unittest.TestCase):
11+
12+
def setUp(self):
13+
global DEVICE_FILES
14+
if DEVICE_FILES is None:
15+
DEVICE_FILES = {}
16+
device_files = os.path.join(os.path.dirname(__file__), "../devices/**/*.xml")
17+
# device_files = os.path.join(os.path.dirname(__file__), "../devices/stm32/stm32l1-51_52_62-c_d_e.xml")
18+
device_file_names = glob.glob(device_files)
19+
20+
# Parse the files and build the :target enumeration
21+
parser = modm_devices.parser.DeviceParser()
22+
for device_file_name in device_file_names:
23+
for device in parser.parse(device_file_name).get_devices():
24+
DEVICE_FILES[device.partname] = device
25+
26+
# self.devices = {"stm32l152vdt6": DEVICE_FILES["stm32l152vdt6"]}
27+
self.devices = DEVICE_FILES
28+
29+
30+
def tearDown(self):
31+
self.devices = None
32+
33+
def get_drivers(self, device):
34+
drivers = []
35+
for d in device._properties["driver"]:
36+
if "instance" in d:
37+
drivers.extend( (d["name"], i["name"]) for i in d["instance"] )
38+
else:
39+
drivers.append( (d["name"],) )
40+
return drivers
41+
42+
def test_drivers(self):
43+
failures = 0
44+
for name, device in self.devices.items():
45+
def assertIn(key, obj):
46+
if key not in obj:
47+
print('{}: Missing "{}" key in "{}"!'.format(name, key, obj))
48+
nonlocal failures
49+
failures += 1
50+
return False
51+
return True
52+
drivers = self.get_drivers(device)
53+
gpios = device.get_driver("gpio")
54+
assertIn("gpio", gpios)
55+
for gpio in gpios.get("gpio", []):
56+
signals = []
57+
for signal in gpio.get("signal", []):
58+
# Check for name and driver keys in each signal
59+
assertIn("name", signal)
60+
if assertIn("driver", signal):
61+
# Check if the signal driver is known
62+
if "instance" in signal:
63+
driver = (signal["driver"], signal["instance"])
64+
else:
65+
driver = (signal["driver"],)
66+
signals.append( (*driver, signal["name"]) )
67+
# assertIn(driver, drivers)
68+
69+
# Check for duplicate signals
70+
if not len(signals) == len(set(signals)):
71+
duplicates = set(x for x in signals if signals.count(x) > 1)
72+
print("{}: duplicated signals for P{}{}: {}".format(
73+
name, gpio["port"].upper(), gpio["pin"], duplicates))
74+
failures += 1
75+
# print(gpio)
76+
77+
# self.assertEqual(failures, 0, "Found inconsistencies in the device files!")
78+
79+
80+
81+
82+
83+
84+

0 commit comments

Comments
 (0)