blob: a5234ce1e88d1a6a9e6ff78d35bdaadc21d7f8cb [file] [log] [blame]
Simon Glass2ba98752018-07-06 10:27:24 -06001#!/usr/bin/python
2# SPDX-License-Identifier: GPL-2.0+
3# Copyright (c) 2018 Google, Inc
4# Written by Simon Glass <sjg@chromium.org>
5#
6
Simon Glass90a81322019-05-17 22:00:31 -06007from __future__ import print_function
8
Simon Glass2ba98752018-07-06 10:27:24 -06009from optparse import OptionParser
10import glob
11import os
12import sys
13import unittest
14
15# Bring in the patman libraries
16our_path = os.path.dirname(os.path.realpath(__file__))
17for dirname in ['../patman', '..']:
18 sys.path.insert(0, os.path.join(our_path, dirname))
19
20import command
21import fdt
22from fdt import TYPE_BYTE, TYPE_INT, TYPE_STRING, TYPE_BOOL
Simon Glass2a2d91d2018-07-06 10:27:28 -060023import fdt_util
Simon Glass2ba98752018-07-06 10:27:24 -060024from fdt_util import fdt32_to_cpu
25import libfdt
26import test_util
27import tools
28
Simon Glassf9b88b32018-07-06 10:27:29 -060029def _GetPropertyValue(dtb, node, prop_name):
30 """Low-level function to get the property value based on its offset
31
32 This looks directly in the device tree at the property's offset to find
33 its value. It is useful as a check that the property is in the correct
34 place.
35
36 Args:
37 node: Node to look in
38 prop_name: Property name to find
39
40 Returns:
41 Tuple:
42 Prop object found
43 Value of property as a string (found using property offset)
44 """
45 prop = node.props[prop_name]
46
47 # Add 12, which is sizeof(struct fdt_property), to get to start of data
48 offset = prop.GetOffset() + 12
49 data = dtb.GetContents()[offset:offset + len(prop.value)]
Simon Glassf6b64812019-05-17 22:00:36 -060050 return prop, [tools.ToChar(x) for x in data]
Simon Glassf9b88b32018-07-06 10:27:29 -060051
52
Simon Glass2ba98752018-07-06 10:27:24 -060053class TestFdt(unittest.TestCase):
54 """Tests for the Fdt module
55
56 This includes unit tests for some functions and functional tests for the fdt
57 module.
58 """
59 @classmethod
60 def setUpClass(cls):
61 tools.PrepareOutputDir(None)
62
63 @classmethod
64 def tearDownClass(cls):
Simon Glasse0e62752018-10-01 21:12:41 -060065 tools.FinaliseOutputDir()
Simon Glass2ba98752018-07-06 10:27:24 -060066
67 def setUp(self):
68 self.dtb = fdt.FdtScan('tools/dtoc/dtoc_test_simple.dts')
69
70 def testFdt(self):
71 """Test that we can open an Fdt"""
72 self.dtb.Scan()
73 root = self.dtb.GetRoot()
74 self.assertTrue(isinstance(root, fdt.Node))
75
76 def testGetNode(self):
77 """Test the GetNode() method"""
78 node = self.dtb.GetNode('/spl-test')
79 self.assertTrue(isinstance(node, fdt.Node))
80 node = self.dtb.GetNode('/i2c@0/pmic@9')
81 self.assertTrue(isinstance(node, fdt.Node))
82 self.assertEqual('pmic@9', node.name)
Simon Glass2a2d91d2018-07-06 10:27:28 -060083 self.assertIsNone(self.dtb.GetNode('/i2c@0/pmic@9/missing'))
Simon Glass2ba98752018-07-06 10:27:24 -060084
85 def testFlush(self):
86 """Check that we can flush the device tree out to its file"""
87 fname = self.dtb._fname
Simon Glass2ab6e132019-05-17 22:00:39 -060088 with open(fname, 'rb') as fd:
Simon Glass2ba98752018-07-06 10:27:24 -060089 data = fd.read()
90 os.remove(fname)
91 with self.assertRaises(IOError):
Simon Glass2ab6e132019-05-17 22:00:39 -060092 open(fname, 'rb')
Simon Glass2ba98752018-07-06 10:27:24 -060093 self.dtb.Flush()
Simon Glass2ab6e132019-05-17 22:00:39 -060094 with open(fname, 'rb') as fd:
Simon Glass2ba98752018-07-06 10:27:24 -060095 data = fd.read()
96
97 def testPack(self):
98 """Test that packing a device tree works"""
99 self.dtb.Pack()
100
101 def testGetFdt(self):
102 """Tetst that we can access the raw device-tree data"""
Simon Glass96066242018-07-06 10:27:27 -0600103 self.assertTrue(isinstance(self.dtb.GetContents(), bytearray))
Simon Glass2ba98752018-07-06 10:27:24 -0600104
105 def testGetProps(self):
106 """Tests obtaining a list of properties"""
107 node = self.dtb.GetNode('/spl-test')
108 props = self.dtb.GetProps(node)
109 self.assertEqual(['boolval', 'bytearray', 'byteval', 'compatible',
Simon Glass2a2d91d2018-07-06 10:27:28 -0600110 'intarray', 'intval', 'longbytearray', 'notstring',
Simon Glass2ba98752018-07-06 10:27:24 -0600111 'stringarray', 'stringval', 'u-boot,dm-pre-reloc'],
112 sorted(props.keys()))
113
114 def testCheckError(self):
115 """Tests the ChecKError() function"""
116 with self.assertRaises(ValueError) as e:
Simon Glass2a2d91d2018-07-06 10:27:28 -0600117 fdt.CheckErr(-libfdt.NOTFOUND, 'hello')
Simon Glass2ba98752018-07-06 10:27:24 -0600118 self.assertIn('FDT_ERR_NOTFOUND: hello', str(e.exception))
119
Simon Glass94a7c602018-07-17 13:25:46 -0600120 def testGetFdt(self):
121 node = self.dtb.GetNode('/spl-test')
122 self.assertEqual(self.dtb, node.GetFdt())
Simon Glass2ba98752018-07-06 10:27:24 -0600123
124class TestNode(unittest.TestCase):
125 """Test operation of the Node class"""
126
127 @classmethod
128 def setUpClass(cls):
129 tools.PrepareOutputDir(None)
130
131 @classmethod
132 def tearDownClass(cls):
Simon Glasse0e62752018-10-01 21:12:41 -0600133 tools.FinaliseOutputDir()
Simon Glass2ba98752018-07-06 10:27:24 -0600134
135 def setUp(self):
136 self.dtb = fdt.FdtScan('tools/dtoc/dtoc_test_simple.dts')
137 self.node = self.dtb.GetNode('/spl-test')
138
139 def testOffset(self):
140 """Tests that we can obtain the offset of a node"""
141 self.assertTrue(self.node.Offset() > 0)
142
143 def testDelete(self):
144 """Tests that we can delete a property"""
145 node2 = self.dtb.GetNode('/spl-test2')
146 offset1 = node2.Offset()
147 self.node.DeleteProp('intval')
148 offset2 = node2.Offset()
149 self.assertTrue(offset2 < offset1)
150 self.node.DeleteProp('intarray')
151 offset3 = node2.Offset()
152 self.assertTrue(offset3 < offset2)
Simon Glass2a2d91d2018-07-06 10:27:28 -0600153 with self.assertRaises(libfdt.FdtException):
154 self.node.DeleteProp('missing')
Simon Glass2ba98752018-07-06 10:27:24 -0600155
Simon Glassf9b88b32018-07-06 10:27:29 -0600156 def testDeleteGetOffset(self):
157 """Test that property offset update when properties are deleted"""
158 self.node.DeleteProp('intval')
159 prop, value = _GetPropertyValue(self.dtb, self.node, 'longbytearray')
160 self.assertEqual(prop.value, value)
161
Simon Glass2ba98752018-07-06 10:27:24 -0600162 def testFindNode(self):
Simon Glass1d858882018-07-17 13:25:41 -0600163 """Tests that we can find a node using the FindNode() functoin"""
164 node = self.dtb.GetRoot().FindNode('i2c@0')
Simon Glass2ba98752018-07-06 10:27:24 -0600165 self.assertEqual('i2c@0', node.name)
Simon Glass1d858882018-07-17 13:25:41 -0600166 subnode = node.FindNode('pmic@9')
Simon Glass2ba98752018-07-06 10:27:24 -0600167 self.assertEqual('pmic@9', subnode.name)
Simon Glass1d858882018-07-17 13:25:41 -0600168 self.assertEqual(None, node.FindNode('missing'))
Simon Glass2ba98752018-07-06 10:27:24 -0600169
Simon Glassf9b88b32018-07-06 10:27:29 -0600170 def testRefreshMissingNode(self):
171 """Test refreshing offsets when an extra node is present in dtb"""
172 # Delete it from our tables, not the device tree
173 del self.dtb._root.subnodes[-1]
174 with self.assertRaises(ValueError) as e:
175 self.dtb.Refresh()
176 self.assertIn('Internal error, offset', str(e.exception))
177
178 def testRefreshExtraNode(self):
179 """Test refreshing offsets when an expected node is missing"""
180 # Delete it from the device tre, not our tables
181 self.dtb.GetFdtObj().del_node(self.node.Offset())
182 with self.assertRaises(ValueError) as e:
183 self.dtb.Refresh()
184 self.assertIn('Internal error, node name mismatch '
185 'spl-test != spl-test2', str(e.exception))
186
187 def testRefreshMissingProp(self):
188 """Test refreshing offsets when an extra property is present in dtb"""
189 # Delete it from our tables, not the device tree
190 del self.node.props['notstring']
191 with self.assertRaises(ValueError) as e:
192 self.dtb.Refresh()
193 self.assertIn("Internal error, property 'notstring' missing, offset ",
194 str(e.exception))
195
Simon Glass94a7c602018-07-17 13:25:46 -0600196 def testLookupPhandle(self):
197 """Test looking up a single phandle"""
198 dtb = fdt.FdtScan('tools/dtoc/dtoc_test_phandle.dts')
199 node = dtb.GetNode('/phandle-source2')
200 prop = node.props['clocks']
201 target = dtb.GetNode('/phandle-target')
202 self.assertEqual(target, dtb.LookupPhandle(fdt32_to_cpu(prop.value)))
203
Simon Glass2ba98752018-07-06 10:27:24 -0600204
205class TestProp(unittest.TestCase):
206 """Test operation of the Prop class"""
207
208 @classmethod
209 def setUpClass(cls):
210 tools.PrepareOutputDir(None)
211
212 @classmethod
213 def tearDownClass(cls):
Simon Glasse0e62752018-10-01 21:12:41 -0600214 tools.FinaliseOutputDir()
Simon Glass2ba98752018-07-06 10:27:24 -0600215
216 def setUp(self):
217 self.dtb = fdt.FdtScan('tools/dtoc/dtoc_test_simple.dts')
218 self.node = self.dtb.GetNode('/spl-test')
219 self.fdt = self.dtb.GetFdtObj()
220
Simon Glassb9066ff2018-07-06 10:27:30 -0600221 def testMissingNode(self):
222 self.assertEqual(None, self.dtb.GetNode('missing'))
223
Simon Glass2a2d91d2018-07-06 10:27:28 -0600224 def testPhandle(self):
225 dtb = fdt.FdtScan('tools/dtoc/dtoc_test_phandle.dts')
Simon Glass760b7172018-07-06 10:27:31 -0600226 node = dtb.GetNode('/phandle-source2')
227 prop = node.props['clocks']
228 self.assertTrue(fdt32_to_cpu(prop.value) > 0)
Simon Glass2a2d91d2018-07-06 10:27:28 -0600229
230 def _ConvertProp(self, prop_name):
231 """Helper function to look up a property in self.node and return it
232
233 Args:
234 Property name to find
235
236 Return fdt.Prop object for this property
237 """
Simon Glass50c59522018-07-26 14:02:13 -0600238 p = self.fdt.getprop(self.node.Offset(), prop_name)
Simon Glass2a2d91d2018-07-06 10:27:28 -0600239 return fdt.Prop(self.node, -1, prop_name, p)
240
241 def testMakeProp(self):
242 """Test we can convert all the the types that are supported"""
243 prop = self._ConvertProp('boolval')
244 self.assertEqual(fdt.TYPE_BOOL, prop.type)
245 self.assertEqual(True, prop.value)
246
247 prop = self._ConvertProp('intval')
248 self.assertEqual(fdt.TYPE_INT, prop.type)
249 self.assertEqual(1, fdt32_to_cpu(prop.value))
250
251 prop = self._ConvertProp('intarray')
252 self.assertEqual(fdt.TYPE_INT, prop.type)
253 val = [fdt32_to_cpu(val) for val in prop.value]
254 self.assertEqual([2, 3, 4], val)
255
256 prop = self._ConvertProp('byteval')
257 self.assertEqual(fdt.TYPE_BYTE, prop.type)
258 self.assertEqual(5, ord(prop.value))
259
260 prop = self._ConvertProp('longbytearray')
261 self.assertEqual(fdt.TYPE_BYTE, prop.type)
262 val = [ord(val) for val in prop.value]
263 self.assertEqual([9, 10, 11, 12, 13, 14, 15, 16, 17], val)
264
265 prop = self._ConvertProp('stringval')
266 self.assertEqual(fdt.TYPE_STRING, prop.type)
267 self.assertEqual('message', prop.value)
268
269 prop = self._ConvertProp('stringarray')
270 self.assertEqual(fdt.TYPE_STRING, prop.type)
271 self.assertEqual(['multi-word', 'message'], prop.value)
272
273 prop = self._ConvertProp('notstring')
274 self.assertEqual(fdt.TYPE_BYTE, prop.type)
275 val = [ord(val) for val in prop.value]
276 self.assertEqual([0x20, 0x21, 0x22, 0x10, 0], val)
277
Simon Glass2ba98752018-07-06 10:27:24 -0600278 def testGetEmpty(self):
279 """Tests the GetEmpty() function for the various supported types"""
280 self.assertEqual(True, fdt.Prop.GetEmpty(fdt.TYPE_BOOL))
281 self.assertEqual(chr(0), fdt.Prop.GetEmpty(fdt.TYPE_BYTE))
Simon Glass194b8d52019-05-17 22:00:33 -0600282 self.assertEqual(tools.GetBytes(0, 4), fdt.Prop.GetEmpty(fdt.TYPE_INT))
Simon Glass2ba98752018-07-06 10:27:24 -0600283 self.assertEqual('', fdt.Prop.GetEmpty(fdt.TYPE_STRING))
284
285 def testGetOffset(self):
286 """Test we can get the offset of a property"""
Simon Glassf9b88b32018-07-06 10:27:29 -0600287 prop, value = _GetPropertyValue(self.dtb, self.node, 'longbytearray')
288 self.assertEqual(prop.value, value)
Simon Glass2ba98752018-07-06 10:27:24 -0600289
290 def testWiden(self):
291 """Test widening of values"""
292 node2 = self.dtb.GetNode('/spl-test2')
293 prop = self.node.props['intval']
294
295 # No action
296 prop2 = node2.props['intval']
297 prop.Widen(prop2)
298 self.assertEqual(fdt.TYPE_INT, prop.type)
299 self.assertEqual(1, fdt32_to_cpu(prop.value))
300
301 # Convert singla value to array
302 prop2 = self.node.props['intarray']
303 prop.Widen(prop2)
304 self.assertEqual(fdt.TYPE_INT, prop.type)
305 self.assertTrue(isinstance(prop.value, list))
306
307 # A 4-byte array looks like a single integer. When widened by a longer
308 # byte array, it should turn into an array.
309 prop = self.node.props['longbytearray']
310 prop2 = node2.props['longbytearray']
311 self.assertFalse(isinstance(prop2.value, list))
312 self.assertEqual(4, len(prop2.value))
313 prop2.Widen(prop)
314 self.assertTrue(isinstance(prop2.value, list))
315 self.assertEqual(9, len(prop2.value))
316
317 # Similarly for a string array
318 prop = self.node.props['stringval']
319 prop2 = node2.props['stringarray']
320 self.assertFalse(isinstance(prop.value, list))
321 self.assertEqual(7, len(prop.value))
322 prop.Widen(prop2)
323 self.assertTrue(isinstance(prop.value, list))
324 self.assertEqual(3, len(prop.value))
325
326 # Enlarging an existing array
327 prop = self.node.props['stringarray']
328 prop2 = node2.props['stringarray']
329 self.assertTrue(isinstance(prop.value, list))
330 self.assertEqual(2, len(prop.value))
331 prop.Widen(prop2)
332 self.assertTrue(isinstance(prop.value, list))
333 self.assertEqual(3, len(prop.value))
334
Simon Glass116adec2018-07-06 10:27:38 -0600335 def testAdd(self):
336 """Test adding properties"""
337 self.fdt.pack()
338 # This function should automatically expand the device tree
339 self.node.AddZeroProp('one')
340 self.node.AddZeroProp('two')
341 self.node.AddZeroProp('three')
Simon Glassfa80c252018-09-14 04:57:13 -0600342 self.dtb.Sync(auto_resize=True)
Simon Glass116adec2018-07-06 10:27:38 -0600343
344 # Updating existing properties should be OK, since the device-tree size
345 # does not change
346 self.fdt.pack()
347 self.node.SetInt('one', 1)
348 self.node.SetInt('two', 2)
349 self.node.SetInt('three', 3)
Simon Glassfa80c252018-09-14 04:57:13 -0600350 self.dtb.Sync(auto_resize=False)
Simon Glass116adec2018-07-06 10:27:38 -0600351
352 # This should fail since it would need to increase the device-tree size
Simon Glassfa80c252018-09-14 04:57:13 -0600353 self.node.AddZeroProp('four')
Simon Glass116adec2018-07-06 10:27:38 -0600354 with self.assertRaises(libfdt.FdtException) as e:
Simon Glassfa80c252018-09-14 04:57:13 -0600355 self.dtb.Sync(auto_resize=False)
Simon Glass116adec2018-07-06 10:27:38 -0600356 self.assertIn('FDT_ERR_NOSPACE', str(e.exception))
Simon Glass64349612018-09-14 04:57:16 -0600357 self.dtb.Sync(auto_resize=True)
Simon Glass116adec2018-07-06 10:27:38 -0600358
Simon Glassfa80c252018-09-14 04:57:13 -0600359 def testAddNode(self):
360 self.fdt.pack()
Simon Glasse21c27a2018-09-14 04:57:15 -0600361 self.node.AddSubnode('subnode')
362 with self.assertRaises(libfdt.FdtException) as e:
363 self.dtb.Sync(auto_resize=False)
364 self.assertIn('FDT_ERR_NOSPACE', str(e.exception))
365
366 self.dtb.Sync(auto_resize=True)
367 offset = self.fdt.path_offset('/spl-test/subnode')
368 self.assertTrue(offset > 0)
Simon Glassfa80c252018-09-14 04:57:13 -0600369
Simon Glass64349612018-09-14 04:57:16 -0600370 def testAddMore(self):
371 """Test various other methods for adding and setting properties"""
372 self.node.AddZeroProp('one')
373 self.dtb.Sync(auto_resize=True)
374 data = self.fdt.getprop(self.node.Offset(), 'one')
375 self.assertEqual(0, fdt32_to_cpu(data))
376
377 self.node.SetInt('one', 1)
378 self.dtb.Sync(auto_resize=False)
379 data = self.fdt.getprop(self.node.Offset(), 'one')
380 self.assertEqual(1, fdt32_to_cpu(data))
381
382 val = '123' + chr(0) + '456'
383 self.node.AddString('string', val)
384 self.dtb.Sync(auto_resize=True)
385 data = self.fdt.getprop(self.node.Offset(), 'string')
Simon Glassf6b64812019-05-17 22:00:36 -0600386 self.assertEqual(tools.ToBytes(val) + b'\0', data)
Simon Glass64349612018-09-14 04:57:16 -0600387
388 self.fdt.pack()
389 self.node.SetString('string', val + 'x')
390 with self.assertRaises(libfdt.FdtException) as e:
391 self.dtb.Sync(auto_resize=False)
392 self.assertIn('FDT_ERR_NOSPACE', str(e.exception))
393 self.node.SetString('string', val[:-1])
394
395 prop = self.node.props['string']
Simon Glassf6b64812019-05-17 22:00:36 -0600396 prop.SetData(tools.ToBytes(val))
Simon Glass64349612018-09-14 04:57:16 -0600397 self.dtb.Sync(auto_resize=False)
398 data = self.fdt.getprop(self.node.Offset(), 'string')
Simon Glassf6b64812019-05-17 22:00:36 -0600399 self.assertEqual(tools.ToBytes(val), data)
Simon Glass64349612018-09-14 04:57:16 -0600400
401 self.node.AddEmptyProp('empty', 5)
402 self.dtb.Sync(auto_resize=True)
403 prop = self.node.props['empty']
Simon Glassf6b64812019-05-17 22:00:36 -0600404 prop.SetData(tools.ToBytes(val))
Simon Glass64349612018-09-14 04:57:16 -0600405 self.dtb.Sync(auto_resize=False)
406 data = self.fdt.getprop(self.node.Offset(), 'empty')
Simon Glassf6b64812019-05-17 22:00:36 -0600407 self.assertEqual(tools.ToBytes(val), data)
Simon Glass64349612018-09-14 04:57:16 -0600408
Simon Glassf6b64812019-05-17 22:00:36 -0600409 self.node.SetData('empty', b'123')
410 self.assertEqual(b'123', prop.bytes)
Simon Glass64349612018-09-14 04:57:16 -0600411
Simon Glass746aee32018-09-14 04:57:17 -0600412 def testFromData(self):
413 dtb2 = fdt.Fdt.FromData(self.dtb.GetContents())
414 self.assertEqual(dtb2.GetContents(), self.dtb.GetContents())
415
416 self.node.AddEmptyProp('empty', 5)
417 self.dtb.Sync(auto_resize=True)
418 self.assertTrue(dtb2.GetContents() != self.dtb.GetContents())
419
Simon Glass2ba98752018-07-06 10:27:24 -0600420
Simon Glass2a2d91d2018-07-06 10:27:28 -0600421class TestFdtUtil(unittest.TestCase):
422 """Tests for the fdt_util module
423
424 This module will likely be mostly replaced at some point, once upstream
425 libfdt has better Python support. For now, this provides tests for current
426 functionality.
427 """
428 @classmethod
429 def setUpClass(cls):
430 tools.PrepareOutputDir(None)
431
Simon Glasse0e62752018-10-01 21:12:41 -0600432 @classmethod
433 def tearDownClass(cls):
434 tools.FinaliseOutputDir()
435
Simon Glass2a2d91d2018-07-06 10:27:28 -0600436 def setUp(self):
437 self.dtb = fdt.FdtScan('tools/dtoc/dtoc_test_simple.dts')
438 self.node = self.dtb.GetNode('/spl-test')
439
440 def testGetInt(self):
441 self.assertEqual(1, fdt_util.GetInt(self.node, 'intval'))
442 self.assertEqual(3, fdt_util.GetInt(self.node, 'missing', 3))
443
444 with self.assertRaises(ValueError) as e:
445 self.assertEqual(3, fdt_util.GetInt(self.node, 'intarray'))
446 self.assertIn("property 'intarray' has list value: expecting a single "
447 'integer', str(e.exception))
448
449 def testGetString(self):
450 self.assertEqual('message', fdt_util.GetString(self.node, 'stringval'))
451 self.assertEqual('test', fdt_util.GetString(self.node, 'missing',
452 'test'))
453
454 with self.assertRaises(ValueError) as e:
455 self.assertEqual(3, fdt_util.GetString(self.node, 'stringarray'))
456 self.assertIn("property 'stringarray' has list value: expecting a "
457 'single string', str(e.exception))
458
459 def testGetBool(self):
460 self.assertEqual(True, fdt_util.GetBool(self.node, 'boolval'))
461 self.assertEqual(False, fdt_util.GetBool(self.node, 'missing'))
462 self.assertEqual(True, fdt_util.GetBool(self.node, 'missing', True))
463 self.assertEqual(False, fdt_util.GetBool(self.node, 'missing', False))
464
Simon Glass3af8e492018-07-17 13:25:40 -0600465 def testGetByte(self):
466 self.assertEqual(5, fdt_util.GetByte(self.node, 'byteval'))
467 self.assertEqual(3, fdt_util.GetByte(self.node, 'missing', 3))
468
469 with self.assertRaises(ValueError) as e:
470 fdt_util.GetByte(self.node, 'longbytearray')
471 self.assertIn("property 'longbytearray' has list value: expecting a "
472 'single byte', str(e.exception))
473
474 with self.assertRaises(ValueError) as e:
475 fdt_util.GetByte(self.node, 'intval')
476 self.assertIn("property 'intval' has length 4, expecting 1",
477 str(e.exception))
478
Simon Glass94a7c602018-07-17 13:25:46 -0600479 def testGetPhandleList(self):
480 dtb = fdt.FdtScan('tools/dtoc/dtoc_test_phandle.dts')
481 node = dtb.GetNode('/phandle-source2')
482 self.assertEqual([1], fdt_util.GetPhandleList(node, 'clocks'))
483 node = dtb.GetNode('/phandle-source')
484 self.assertEqual([1, 2, 11, 3, 12, 13, 1],
485 fdt_util.GetPhandleList(node, 'clocks'))
486 self.assertEqual(None, fdt_util.GetPhandleList(node, 'missing'))
487
Simon Glass53af22a2018-07-17 13:25:32 -0600488 def testGetDataType(self):
489 self.assertEqual(1, fdt_util.GetDatatype(self.node, 'intval', int))
490 self.assertEqual('message', fdt_util.GetDatatype(self.node, 'stringval',
491 str))
492 with self.assertRaises(ValueError) as e:
493 self.assertEqual(3, fdt_util.GetDatatype(self.node, 'boolval',
494 bool))
Simon Glass2a2d91d2018-07-06 10:27:28 -0600495 def testFdtCellsToCpu(self):
496 val = self.node.props['intarray'].value
497 self.assertEqual(0, fdt_util.fdt_cells_to_cpu(val, 0))
498 self.assertEqual(2, fdt_util.fdt_cells_to_cpu(val, 1))
499
500 dtb2 = fdt.FdtScan('tools/dtoc/dtoc_test_addr64.dts')
Simon Glasse66d3182019-05-17 22:00:40 -0600501 node1 = dtb2.GetNode('/test1')
502 val = node1.props['reg'].value
Simon Glass2a2d91d2018-07-06 10:27:28 -0600503 self.assertEqual(0x1234, fdt_util.fdt_cells_to_cpu(val, 2))
504
Simon Glasse66d3182019-05-17 22:00:40 -0600505 node2 = dtb2.GetNode('/test2')
506 val = node2.props['reg'].value
507 self.assertEqual(0x1234567890123456, fdt_util.fdt_cells_to_cpu(val, 2))
508 self.assertEqual(0x9876543210987654, fdt_util.fdt_cells_to_cpu(val[2:],
509 2))
510 self.assertEqual(0x12345678, fdt_util.fdt_cells_to_cpu(val, 1))
511
Simon Glass2a2d91d2018-07-06 10:27:28 -0600512 def testEnsureCompiled(self):
513 """Test a degenerate case of this function"""
514 dtb = fdt_util.EnsureCompiled('tools/dtoc/dtoc_test_simple.dts')
515 self.assertEqual(dtb, fdt_util.EnsureCompiled(dtb))
516
517 def testGetPlainBytes(self):
Simon Glassf6b64812019-05-17 22:00:36 -0600518 self.assertEqual(b'fred', fdt_util.get_plain_bytes('fred'))
Simon Glass2a2d91d2018-07-06 10:27:28 -0600519
520
521def RunTestCoverage():
522 """Run the tests and check that we get 100% coverage"""
523 test_util.RunTestCoverage('tools/dtoc/test_fdt.py', None,
524 ['tools/patman/*.py', '*test_fdt.py'], options.build_dir)
525
526
Simon Glass2ba98752018-07-06 10:27:24 -0600527def RunTests(args):
528 """Run all the test we have for the fdt model
529
530 Args:
531 args: List of positional args provided to fdt. This can hold a test
532 name to execute (as in 'fdt -t testFdt', for example)
533 """
534 result = unittest.TestResult()
535 sys.argv = [sys.argv[0]]
536 test_name = args and args[0] or None
Simon Glass2a2d91d2018-07-06 10:27:28 -0600537 for module in (TestFdt, TestNode, TestProp, TestFdtUtil):
Simon Glass2ba98752018-07-06 10:27:24 -0600538 if test_name:
539 try:
540 suite = unittest.TestLoader().loadTestsFromName(test_name, module)
541 except AttributeError:
542 continue
543 else:
544 suite = unittest.TestLoader().loadTestsFromTestCase(module)
545 suite.run(result)
546
Simon Glass90a81322019-05-17 22:00:31 -0600547 print(result)
Simon Glass2ba98752018-07-06 10:27:24 -0600548 for _, err in result.errors:
Simon Glass90a81322019-05-17 22:00:31 -0600549 print(err)
Simon Glass2ba98752018-07-06 10:27:24 -0600550 for _, err in result.failures:
Simon Glass90a81322019-05-17 22:00:31 -0600551 print(err)
Simon Glass2ba98752018-07-06 10:27:24 -0600552
553if __name__ != '__main__':
554 sys.exit(1)
555
556parser = OptionParser()
Simon Glass2a2d91d2018-07-06 10:27:28 -0600557parser.add_option('-B', '--build-dir', type='string', default='b',
558 help='Directory containing the build output')
Simon Glass11ae93e2018-10-01 21:12:47 -0600559parser.add_option('-P', '--processes', type=int,
560 help='set number of processes to use for running tests')
Simon Glass2ba98752018-07-06 10:27:24 -0600561parser.add_option('-t', '--test', action='store_true', dest='test',
562 default=False, help='run tests')
Simon Glass2a2d91d2018-07-06 10:27:28 -0600563parser.add_option('-T', '--test-coverage', action='store_true',
564 default=False, help='run tests and check for 100% coverage')
Simon Glass2ba98752018-07-06 10:27:24 -0600565(options, args) = parser.parse_args()
566
567# Run our meagre tests
568if options.test:
569 RunTests(args)
Simon Glass2a2d91d2018-07-06 10:27:28 -0600570elif options.test_coverage:
571 RunTestCoverage()