2 # SPDX-License-Identifier: GPL-2.0+
3 # Copyright (c) 2018 Google, Inc
4 # Written by Simon Glass <sjg@chromium.org>
7 from optparse import OptionParser
15 # Bring in the patman libraries
16 our_path = os.path.dirname(os.path.realpath(__file__))
17 sys.path.insert(1, os.path.join(our_path, '..'))
19 # Bring in the libfdt module
20 sys.path.insert(2, 'scripts/dtc/pylibfdt')
21 sys.path.insert(2, os.path.join(our_path, '../../scripts/dtc/pylibfdt'))
22 sys.path.insert(2, os.path.join(our_path,
23 '../../build-sandbox_spl/scripts/dtc/pylibfdt'))
26 from dtoc import fdt_util
27 from dtoc.fdt_util import fdt32_to_cpu, fdt64_to_cpu
28 from fdt import Type, BytesToValue
30 from patman import command
31 from patman import test_util
32 from patman import tools
34 def _GetPropertyValue(dtb, node, prop_name):
35 """Low-level function to get the property value based on its offset
37 This looks directly in the device tree at the property's offset to find
38 its value. It is useful as a check that the property is in the correct
43 prop_name: Property name to find
48 Value of property as a string (found using property offset)
50 prop = node.props[prop_name]
52 # Add 12, which is sizeof(struct fdt_property), to get to start of data
53 offset = prop.GetOffset() + 12
54 data = dtb.GetContents()[offset:offset + len(prop.value)]
55 return prop, [chr(x) for x in data]
57 def find_dtb_file(dts_fname):
58 """Locate a test file in the test/ directory
61 dts_fname (str): Filename to find, e.g. 'dtoc_test_simple.dts]
64 str: Path to the test filename
66 return os.path.join('tools/dtoc/test', dts_fname)
69 class TestFdt(unittest.TestCase):
70 """Tests for the Fdt module
72 This includes unit tests for some functions and functional tests for the fdt
77 tools.prepare_output_dir(None)
80 def tearDownClass(cls):
81 tools.finalise_output_dir()
84 self.dtb = fdt.FdtScan(find_dtb_file('dtoc_test_simple.dts'))
87 """Test that we can open an Fdt"""
89 root = self.dtb.GetRoot()
90 self.assertTrue(isinstance(root, fdt.Node))
92 def testGetNode(self):
93 """Test the GetNode() method"""
94 node = self.dtb.GetNode('/spl-test')
95 self.assertTrue(isinstance(node, fdt.Node))
97 node = self.dtb.GetNode('/i2c@0/pmic@9')
98 self.assertTrue(isinstance(node, fdt.Node))
99 self.assertEqual('pmic@9', node.name)
100 self.assertIsNone(self.dtb.GetNode('/i2c@0/pmic@9/missing'))
102 node = self.dtb.GetNode('/')
103 self.assertTrue(isinstance(node, fdt.Node))
104 self.assertEqual(0, node.Offset())
107 """Check that we can flush the device tree out to its file"""
108 fname = self.dtb._fname
109 with open(fname, 'rb') as fd:
112 with self.assertRaises(IOError):
115 with open(fname, 'rb') as fd:
119 """Test that packing a device tree works"""
122 def testGetFdt(self):
123 """Tetst that we can access the raw device-tree data"""
124 self.assertTrue(isinstance(self.dtb.GetContents(), bytearray))
126 def testGetProps(self):
127 """Tests obtaining a list of properties"""
128 node = self.dtb.GetNode('/spl-test')
129 props = self.dtb.GetProps(node)
130 self.assertEqual(['boolval', 'bytearray', 'byteval', 'compatible',
131 'int64val', 'intarray', 'intval', 'longbytearray',
132 'maybe-empty-int', 'notstring', 'stringarray',
133 'stringval', 'u-boot,dm-pre-reloc'],
134 sorted(props.keys()))
136 def testCheckError(self):
137 """Tests the ChecKError() function"""
138 with self.assertRaises(ValueError) as e:
139 fdt.CheckErr(-libfdt.NOTFOUND, 'hello')
140 self.assertIn('FDT_ERR_NOTFOUND: hello', str(e.exception))
142 def testGetFdt(self):
143 node = self.dtb.GetNode('/spl-test')
144 self.assertEqual(self.dtb, node.GetFdt())
146 def testBytesToValue(self):
147 self.assertEqual(BytesToValue(b'this\0is\0'),
148 (Type.STRING, ['this', 'is']))
150 class TestNode(unittest.TestCase):
151 """Test operation of the Node class"""
155 tools.prepare_output_dir(None)
158 def tearDownClass(cls):
159 tools.finalise_output_dir()
162 self.dtb = fdt.FdtScan(find_dtb_file('dtoc_test_simple.dts'))
163 self.node = self.dtb.GetNode('/spl-test')
164 self.fdt = self.dtb.GetFdtObj()
166 def testOffset(self):
167 """Tests that we can obtain the offset of a node"""
168 self.assertTrue(self.node.Offset() > 0)
170 def testDelete(self):
171 """Tests that we can delete a property"""
172 node2 = self.dtb.GetNode('/spl-test2')
173 offset1 = node2.Offset()
174 self.node.DeleteProp('intval')
175 offset2 = node2.Offset()
176 self.assertTrue(offset2 < offset1)
177 self.node.DeleteProp('intarray')
178 offset3 = node2.Offset()
179 self.assertTrue(offset3 < offset2)
180 with self.assertRaises(libfdt.FdtException):
181 self.node.DeleteProp('missing')
183 def testDeleteGetOffset(self):
184 """Test that property offset update when properties are deleted"""
185 self.node.DeleteProp('intval')
186 prop, value = _GetPropertyValue(self.dtb, self.node, 'longbytearray')
187 self.assertEqual(prop.value, value)
189 def testFindNode(self):
190 """Tests that we can find a node using the FindNode() functoin"""
191 node = self.dtb.GetRoot().FindNode('i2c@0')
192 self.assertEqual('i2c@0', node.name)
193 subnode = node.FindNode('pmic@9')
194 self.assertEqual('pmic@9', subnode.name)
195 self.assertEqual(None, node.FindNode('missing'))
197 def testRefreshMissingNode(self):
198 """Test refreshing offsets when an extra node is present in dtb"""
199 # Delete it from our tables, not the device tree
200 del self.dtb._root.subnodes[-1]
201 with self.assertRaises(ValueError) as e:
203 self.assertIn('Internal error, offset', str(e.exception))
205 def testRefreshExtraNode(self):
206 """Test refreshing offsets when an expected node is missing"""
207 # Delete it from the device tre, not our tables
208 self.fdt.del_node(self.node.Offset())
209 with self.assertRaises(ValueError) as e:
211 self.assertIn('Internal error, node name mismatch '
212 'spl-test != spl-test2', str(e.exception))
214 def testRefreshMissingProp(self):
215 """Test refreshing offsets when an extra property is present in dtb"""
216 # Delete it from our tables, not the device tree
217 del self.node.props['notstring']
218 with self.assertRaises(ValueError) as e:
220 self.assertIn("Internal error, node '/spl-test' property 'notstring' missing, offset ",
223 def testLookupPhandle(self):
224 """Test looking up a single phandle"""
225 dtb = fdt.FdtScan(find_dtb_file('dtoc_test_phandle.dts'))
226 node = dtb.GetNode('/phandle-source2')
227 prop = node.props['clocks']
228 target = dtb.GetNode('/phandle-target')
229 self.assertEqual(target, dtb.LookupPhandle(fdt32_to_cpu(prop.value)))
231 def testAddNodeSpace(self):
232 """Test adding a single node when out of space"""
234 self.node.AddSubnode('subnode')
235 with self.assertRaises(libfdt.FdtException) as e:
236 self.dtb.Sync(auto_resize=False)
237 self.assertIn('FDT_ERR_NOSPACE', str(e.exception))
239 self.dtb.Sync(auto_resize=True)
240 offset = self.fdt.path_offset('/spl-test/subnode')
241 self.assertTrue(offset > 0)
243 def testAddNodes(self):
244 """Test adding various subnode and properies"""
245 node = self.dtb.GetNode('/i2c@0')
247 # Add one more node next to the pmic one
248 sn1 = node.AddSubnode('node-one')
249 sn1.AddInt('integer-a', 12)
250 sn1.AddInt('integer-b', 23)
252 # Sync so that everything is clean
253 self.dtb.Sync(auto_resize=True)
255 # Add two subnodes next to pmic and node-one
256 sn2 = node.AddSubnode('node-two')
257 sn2.AddInt('integer-2a', 34)
258 sn2.AddInt('integer-2b', 45)
260 sn3 = node.AddSubnode('node-three')
261 sn3.AddInt('integer-3', 123)
263 # Add a property to the node after i2c@0 to check that this is not
264 # disturbed by adding a subnode to i2c@0
265 orig_node = self.dtb.GetNode('/orig-node')
266 orig_node.AddInt('integer-4', 456)
268 # Add a property to the pmic node to check that pmic properties are not
270 pmic = self.dtb.GetNode('/i2c@0/pmic@9')
271 pmic.AddInt('integer-5', 567)
273 self.dtb.Sync(auto_resize=True)
275 def testAddOneNode(self):
276 """Testing deleting and adding a subnode before syncing"""
277 subnode = self.node.AddSubnode('subnode')
278 self.node.AddSubnode('subnode2')
279 self.dtb.Sync(auto_resize=True)
281 # Delete a node and add a new one
283 self.node.AddSubnode('subnode3')
286 def testRefreshNameMismatch(self):
287 """Test name mismatch when syncing nodes and properties"""
288 prop = self.node.AddInt('integer-a', 12)
290 wrong_offset = self.dtb.GetNode('/i2c@0')._offset
291 self.node._offset = wrong_offset
292 with self.assertRaises(ValueError) as e:
294 self.assertIn("Internal error, node '/spl-test' name mismatch 'i2c@0'",
297 with self.assertRaises(ValueError) as e:
298 self.node.Refresh(wrong_offset)
299 self.assertIn("Internal error, node '/spl-test' name mismatch 'i2c@0'",
303 class TestProp(unittest.TestCase):
304 """Test operation of the Prop class"""
308 tools.prepare_output_dir(None)
311 def tearDownClass(cls):
312 tools.finalise_output_dir()
315 self.dtb = fdt.FdtScan(find_dtb_file('dtoc_test_simple.dts'))
316 self.node = self.dtb.GetNode('/spl-test')
317 self.fdt = self.dtb.GetFdtObj()
319 def testMissingNode(self):
320 self.assertEqual(None, self.dtb.GetNode('missing'))
322 def testPhandle(self):
323 dtb = fdt.FdtScan(find_dtb_file('dtoc_test_phandle.dts'))
324 node = dtb.GetNode('/phandle-source2')
325 prop = node.props['clocks']
326 self.assertTrue(fdt32_to_cpu(prop.value) > 0)
328 def _ConvertProp(self, prop_name):
329 """Helper function to look up a property in self.node and return it
332 Property name to find
334 Return fdt.Prop object for this property
336 p = self.fdt.getprop(self.node.Offset(), prop_name)
337 return fdt.Prop(self.node, -1, prop_name, p)
339 def testMakeProp(self):
340 """Test we can convert all the the types that are supported"""
341 prop = self._ConvertProp('boolval')
342 self.assertEqual(Type.BOOL, prop.type)
343 self.assertEqual(True, prop.value)
345 prop = self._ConvertProp('intval')
346 self.assertEqual(Type.INT, prop.type)
347 self.assertEqual(1, fdt32_to_cpu(prop.value))
349 prop = self._ConvertProp('int64val')
350 self.assertEqual(Type.INT, prop.type)
351 self.assertEqual(0x123456789abcdef0, fdt64_to_cpu(prop.value))
353 prop = self._ConvertProp('intarray')
354 self.assertEqual(Type.INT, prop.type)
355 val = [fdt32_to_cpu(val) for val in prop.value]
356 self.assertEqual([2, 3, 4], val)
358 prop = self._ConvertProp('byteval')
359 self.assertEqual(Type.BYTE, prop.type)
360 self.assertEqual(5, ord(prop.value))
362 prop = self._ConvertProp('longbytearray')
363 self.assertEqual(Type.BYTE, prop.type)
364 val = [ord(val) for val in prop.value]
365 self.assertEqual([9, 10, 11, 12, 13, 14, 15, 16, 17], val)
367 prop = self._ConvertProp('stringval')
368 self.assertEqual(Type.STRING, prop.type)
369 self.assertEqual('message', prop.value)
371 prop = self._ConvertProp('stringarray')
372 self.assertEqual(Type.STRING, prop.type)
373 self.assertEqual(['multi-word', 'message'], prop.value)
375 prop = self._ConvertProp('notstring')
376 self.assertEqual(Type.BYTE, prop.type)
377 val = [ord(val) for val in prop.value]
378 self.assertEqual([0x20, 0x21, 0x22, 0x10, 0], val)
380 def testGetEmpty(self):
381 """Tests the GetEmpty() function for the various supported types"""
382 self.assertEqual(True, fdt.Prop.GetEmpty(Type.BOOL))
383 self.assertEqual(chr(0), fdt.Prop.GetEmpty(Type.BYTE))
384 self.assertEqual(tools.get_bytes(0, 4), fdt.Prop.GetEmpty(Type.INT))
385 self.assertEqual('', fdt.Prop.GetEmpty(Type.STRING))
387 def testGetOffset(self):
388 """Test we can get the offset of a property"""
389 prop, value = _GetPropertyValue(self.dtb, self.node, 'longbytearray')
390 self.assertEqual(prop.value, value)
393 """Test widening of values"""
394 node2 = self.dtb.GetNode('/spl-test2')
395 node3 = self.dtb.GetNode('/spl-test3')
396 prop = self.node.props['intval']
399 prop2 = node2.props['intval']
401 self.assertEqual(Type.INT, prop.type)
402 self.assertEqual(1, fdt32_to_cpu(prop.value))
404 # Convert single value to array
405 prop2 = self.node.props['intarray']
407 self.assertEqual(Type.INT, prop.type)
408 self.assertTrue(isinstance(prop.value, list))
410 # A 4-byte array looks like a single integer. When widened by a longer
411 # byte array, it should turn into an array.
412 prop = self.node.props['longbytearray']
413 prop2 = node2.props['longbytearray']
414 prop3 = node3.props['longbytearray']
415 self.assertFalse(isinstance(prop2.value, list))
416 self.assertEqual(4, len(prop2.value))
417 self.assertEqual(b'\x09\x0a\x0b\x0c', prop2.value)
419 self.assertTrue(isinstance(prop2.value, list))
420 self.assertEqual(9, len(prop2.value))
421 self.assertEqual(['\x09', '\x0a', '\x0b', '\x0c', '\0',
422 '\0', '\0', '\0', '\0'], prop2.value)
424 self.assertTrue(isinstance(prop3.value, list))
425 self.assertEqual(9, len(prop3.value))
426 self.assertEqual(['\x09', '\x0a', '\x0b', '\x0c', '\x0d',
427 '\x0e', '\x0f', '\x10', '\0'], prop3.value)
429 # Similarly for a string array
430 prop = self.node.props['stringval']
431 prop2 = node2.props['stringarray']
432 self.assertFalse(isinstance(prop.value, list))
433 self.assertEqual(7, len(prop.value))
435 self.assertTrue(isinstance(prop.value, list))
436 self.assertEqual(3, len(prop.value))
438 # Enlarging an existing array
439 prop = self.node.props['stringarray']
440 prop2 = node2.props['stringarray']
441 self.assertTrue(isinstance(prop.value, list))
442 self.assertEqual(2, len(prop.value))
444 self.assertTrue(isinstance(prop.value, list))
445 self.assertEqual(3, len(prop.value))
447 # Widen an array of ints with an int (should do nothing)
448 prop = self.node.props['intarray']
449 prop2 = node2.props['intval']
450 self.assertEqual(Type.INT, prop.type)
451 self.assertEqual(3, len(prop.value))
453 self.assertEqual(Type.INT, prop.type)
454 self.assertEqual(3, len(prop.value))
456 # Widen an empty bool to an int
457 prop = self.node.props['maybe-empty-int']
458 prop3 = node3.props['maybe-empty-int']
459 self.assertEqual(Type.BOOL, prop.type)
460 self.assertEqual(True, prop.value)
461 self.assertEqual(Type.INT, prop3.type)
462 self.assertFalse(isinstance(prop.value, list))
463 self.assertEqual(4, len(prop3.value))
465 self.assertEqual(Type.INT, prop.type)
466 self.assertTrue(isinstance(prop.value, list))
467 self.assertEqual(1, len(prop.value))
470 """Test adding properties"""
472 # This function should automatically expand the device tree
473 self.node.AddZeroProp('one')
474 self.node.AddZeroProp('two')
475 self.node.AddZeroProp('three')
476 self.dtb.Sync(auto_resize=True)
478 # Updating existing properties should be OK, since the device-tree size
481 self.node.SetInt('one', 1)
482 self.node.SetInt('two', 2)
483 self.node.SetInt('three', 3)
484 self.dtb.Sync(auto_resize=False)
486 # This should fail since it would need to increase the device-tree size
487 self.node.AddZeroProp('four')
488 with self.assertRaises(libfdt.FdtException) as e:
489 self.dtb.Sync(auto_resize=False)
490 self.assertIn('FDT_ERR_NOSPACE', str(e.exception))
491 self.dtb.Sync(auto_resize=True)
493 def testAddMore(self):
494 """Test various other methods for adding and setting properties"""
495 self.node.AddZeroProp('one')
496 self.dtb.Sync(auto_resize=True)
497 data = self.fdt.getprop(self.node.Offset(), 'one')
498 self.assertEqual(0, fdt32_to_cpu(data))
500 self.node.SetInt('one', 1)
501 self.dtb.Sync(auto_resize=False)
502 data = self.fdt.getprop(self.node.Offset(), 'one')
503 self.assertEqual(1, fdt32_to_cpu(data))
506 self.node.AddInt('integer', val)
507 self.dtb.Sync(auto_resize=True)
508 data = self.fdt.getprop(self.node.Offset(), 'integer')
509 self.assertEqual(val, fdt32_to_cpu(data))
511 val = '123' + chr(0) + '456'
512 self.node.AddString('string', val)
513 self.dtb.Sync(auto_resize=True)
514 data = self.fdt.getprop(self.node.Offset(), 'string')
515 self.assertEqual(tools.to_bytes(val) + b'\0', data)
518 self.node.SetString('string', val + 'x')
519 with self.assertRaises(libfdt.FdtException) as e:
520 self.dtb.Sync(auto_resize=False)
521 self.assertIn('FDT_ERR_NOSPACE', str(e.exception))
522 self.node.SetString('string', val[:-1])
524 prop = self.node.props['string']
525 prop.SetData(tools.to_bytes(val))
526 self.dtb.Sync(auto_resize=False)
527 data = self.fdt.getprop(self.node.Offset(), 'string')
528 self.assertEqual(tools.to_bytes(val), data)
530 self.node.AddEmptyProp('empty', 5)
531 self.dtb.Sync(auto_resize=True)
532 prop = self.node.props['empty']
533 prop.SetData(tools.to_bytes(val))
534 self.dtb.Sync(auto_resize=False)
535 data = self.fdt.getprop(self.node.Offset(), 'empty')
536 self.assertEqual(tools.to_bytes(val), data)
538 self.node.SetData('empty', b'123')
539 self.assertEqual(b'123', prop.bytes)
541 # Trying adding a lot of data at once
542 self.node.AddData('data', tools.get_bytes(65, 20000))
543 self.dtb.Sync(auto_resize=True)
545 def test_string_list(self):
546 """Test adding string-list property to a node"""
548 self.node.AddStringList('stringlist', val)
549 self.dtb.Sync(auto_resize=True)
550 data = self.fdt.getprop(self.node.Offset(), 'stringlist')
551 self.assertEqual(b'123\x00456\0', data)
553 def test_delete_node(self):
554 """Test deleting a node"""
555 old_offset = self.fdt.path_offset('/spl-test')
556 self.assertGreater(old_offset, 0)
559 new_offset = self.fdt.path_offset('/spl-test', libfdt.QUIET_NOTFOUND)
560 self.assertEqual(-libfdt.NOTFOUND, new_offset)
562 def testFromData(self):
563 dtb2 = fdt.Fdt.FromData(self.dtb.GetContents())
564 self.assertEqual(dtb2.GetContents(), self.dtb.GetContents())
566 self.node.AddEmptyProp('empty', 5)
567 self.dtb.Sync(auto_resize=True)
568 self.assertTrue(dtb2.GetContents() != self.dtb.GetContents())
570 def testMissingSetInt(self):
571 """Test handling of a missing property with SetInt"""
572 with self.assertRaises(ValueError) as e:
573 self.node.SetInt('one', 1)
574 self.assertIn("node '/spl-test': Missing property 'one'",
577 def testMissingSetData(self):
578 """Test handling of a missing property with SetData"""
579 with self.assertRaises(ValueError) as e:
580 self.node.SetData('one', b'data')
581 self.assertIn("node '/spl-test': Missing property 'one'",
584 def testMissingSetString(self):
585 """Test handling of a missing property with SetString"""
586 with self.assertRaises(ValueError) as e:
587 self.node.SetString('one', 1)
588 self.assertIn("node '/spl-test': Missing property 'one'",
591 def testGetFilename(self):
592 """Test the dtb filename can be provided"""
593 self.assertEqual(tools.get_output_filename('source.dtb'),
594 self.dtb.GetFilename())
597 class TestFdtUtil(unittest.TestCase):
598 """Tests for the fdt_util module
600 This module will likely be mostly replaced at some point, once upstream
601 libfdt has better Python support. For now, this provides tests for current
606 tools.prepare_output_dir(None)
609 def tearDownClass(cls):
610 tools.finalise_output_dir()
613 self.dtb = fdt.FdtScan(find_dtb_file('dtoc_test_simple.dts'))
614 self.node = self.dtb.GetNode('/spl-test')
616 def testGetInt(self):
617 self.assertEqual(1, fdt_util.GetInt(self.node, 'intval'))
618 self.assertEqual(3, fdt_util.GetInt(self.node, 'missing', 3))
620 with self.assertRaises(ValueError) as e:
621 fdt_util.GetInt(self.node, 'intarray')
622 self.assertIn("property 'intarray' has list value: expecting a single "
623 'integer', str(e.exception))
625 def testGetInt64(self):
626 self.assertEqual(0x123456789abcdef0,
627 fdt_util.GetInt64(self.node, 'int64val'))
628 self.assertEqual(3, fdt_util.GetInt64(self.node, 'missing', 3))
630 with self.assertRaises(ValueError) as e:
631 fdt_util.GetInt64(self.node, 'intarray')
633 "property 'intarray' should be a list with 2 items for 64-bit values",
636 def testGetString(self):
637 self.assertEqual('message', fdt_util.GetString(self.node, 'stringval'))
638 self.assertEqual('test', fdt_util.GetString(self.node, 'missing',
641 with self.assertRaises(ValueError) as e:
642 self.assertEqual(3, fdt_util.GetString(self.node, 'stringarray'))
643 self.assertIn("property 'stringarray' has list value: expecting a "
644 'single string', str(e.exception))
646 def testGetStringList(self):
647 self.assertEqual(['message'],
648 fdt_util.GetStringList(self.node, 'stringval'))
650 ['multi-word', 'message'],
651 fdt_util.GetStringList(self.node, 'stringarray'))
652 self.assertEqual(['test'],
653 fdt_util.GetStringList(self.node, 'missing', ['test']))
655 def testGetBool(self):
656 self.assertEqual(True, fdt_util.GetBool(self.node, 'boolval'))
657 self.assertEqual(False, fdt_util.GetBool(self.node, 'missing'))
658 self.assertEqual(True, fdt_util.GetBool(self.node, 'missing', True))
659 self.assertEqual(False, fdt_util.GetBool(self.node, 'missing', False))
661 def testGetByte(self):
662 self.assertEqual(5, fdt_util.GetByte(self.node, 'byteval'))
663 self.assertEqual(3, fdt_util.GetByte(self.node, 'missing', 3))
665 with self.assertRaises(ValueError) as e:
666 fdt_util.GetByte(self.node, 'longbytearray')
667 self.assertIn("property 'longbytearray' has list value: expecting a "
668 'single byte', str(e.exception))
670 with self.assertRaises(ValueError) as e:
671 fdt_util.GetByte(self.node, 'intval')
672 self.assertIn("property 'intval' has length 4, expecting 1",
675 def testGetBytes(self):
676 self.assertEqual(bytes([5]), fdt_util.GetBytes(self.node, 'byteval', 1))
677 self.assertEqual(None, fdt_util.GetBytes(self.node, 'missing', 3))
679 bytes([3]), fdt_util.GetBytes(self.node, 'missing', 3, bytes([3])))
681 with self.assertRaises(ValueError) as e:
682 fdt_util.GetBytes(self.node, 'longbytearray', 7)
684 "Node 'spl-test' property 'longbytearray' has length 9, expecting 7",
688 bytes([0, 0, 0, 1]), fdt_util.GetBytes(self.node, 'intval', 4))
690 bytes([3]), fdt_util.GetBytes(self.node, 'missing', 3, bytes([3])))
692 def testGetPhandleList(self):
693 dtb = fdt.FdtScan(find_dtb_file('dtoc_test_phandle.dts'))
694 node = dtb.GetNode('/phandle-source2')
695 self.assertEqual([1], fdt_util.GetPhandleList(node, 'clocks'))
696 node = dtb.GetNode('/phandle-source')
697 self.assertEqual([1, 2, 11, 3, 12, 13, 1],
698 fdt_util.GetPhandleList(node, 'clocks'))
699 self.assertEqual(None, fdt_util.GetPhandleList(node, 'missing'))
701 def testGetDataType(self):
702 self.assertEqual(1, fdt_util.GetDatatype(self.node, 'intval', int))
703 self.assertEqual('message', fdt_util.GetDatatype(self.node, 'stringval',
705 with self.assertRaises(ValueError) as e:
706 self.assertEqual(3, fdt_util.GetDatatype(self.node, 'boolval',
708 def testFdtCellsToCpu(self):
709 val = self.node.props['intarray'].value
710 self.assertEqual(0, fdt_util.fdt_cells_to_cpu(val, 0))
711 self.assertEqual(2, fdt_util.fdt_cells_to_cpu(val, 1))
713 dtb2 = fdt.FdtScan(find_dtb_file('dtoc_test_addr64.dts'))
714 node1 = dtb2.GetNode('/test1')
715 val = node1.props['reg'].value
716 self.assertEqual(0x1234, fdt_util.fdt_cells_to_cpu(val, 2))
718 node2 = dtb2.GetNode('/test2')
719 val = node2.props['reg'].value
720 self.assertEqual(0x1234567890123456, fdt_util.fdt_cells_to_cpu(val, 2))
721 self.assertEqual(0x9876543210987654, fdt_util.fdt_cells_to_cpu(val[2:],
723 self.assertEqual(0x12345678, fdt_util.fdt_cells_to_cpu(val, 1))
725 def testEnsureCompiled(self):
726 """Test a degenerate case of this function (file already compiled)"""
727 dtb = fdt_util.EnsureCompiled(find_dtb_file('dtoc_test_simple.dts'))
728 self.assertEqual(dtb, fdt_util.EnsureCompiled(dtb))
730 def testEnsureCompiledTmpdir(self):
731 """Test providing a temporary directory"""
733 old_outdir = tools.outdir
735 tmpdir = tempfile.mkdtemp(prefix='test_fdt.')
736 dtb = fdt_util.EnsureCompiled(find_dtb_file('dtoc_test_simple.dts'),
738 self.assertEqual(tmpdir, os.path.dirname(dtb))
739 shutil.rmtree(tmpdir)
741 tools.outdir= old_outdir
744 def RunTestCoverage():
745 """Run the tests and check that we get 100% coverage"""
746 test_util.run_test_coverage('tools/dtoc/test_fdt.py', None,
747 ['tools/patman/*.py', '*test_fdt.py'], options.build_dir)
751 """Run all the test we have for the fdt model
754 args: List of positional args provided to fdt. This can hold a test
755 name to execute (as in 'fdt -t testFdt', for example)
757 result = unittest.TestResult()
758 sys.argv = [sys.argv[0]]
759 test_name = args and args[0] or None
760 for module in (TestFdt, TestNode, TestProp, TestFdtUtil):
763 suite = unittest.TestLoader().loadTestsFromName(test_name, module)
764 except AttributeError:
767 suite = unittest.TestLoader().loadTestsFromTestCase(module)
771 for _, err in result.errors:
773 for _, err in result.failures:
776 if __name__ != '__main__':
779 parser = OptionParser()
780 parser.add_option('-B', '--build-dir', type='string', default='b',
781 help='Directory containing the build output')
782 parser.add_option('-P', '--processes', type=int,
783 help='set number of processes to use for running tests')
784 parser.add_option('-t', '--test', action='store_true', dest='test',
785 default=False, help='run tests')
786 parser.add_option('-T', '--test-coverage', action='store_true',
787 default=False, help='run tests and check for 100% coverage')
788 (options, args) = parser.parse_args()
790 # Run our meagre tests
793 elif options.test_coverage: