xref: /openbmc/u-boot/tools/dtoc/test_fdt.py (revision 3af8e49c)
12ba98753SSimon Glass#!/usr/bin/python
22ba98753SSimon Glass# SPDX-License-Identifier: GPL-2.0+
32ba98753SSimon Glass# Copyright (c) 2018 Google, Inc
42ba98753SSimon Glass# Written by Simon Glass <sjg@chromium.org>
52ba98753SSimon Glass#
62ba98753SSimon Glass
72ba98753SSimon Glassfrom optparse import OptionParser
82ba98753SSimon Glassimport glob
92ba98753SSimon Glassimport os
102ba98753SSimon Glassimport sys
112ba98753SSimon Glassimport unittest
122ba98753SSimon Glass
132ba98753SSimon Glass# Bring in the patman libraries
142ba98753SSimon Glassour_path = os.path.dirname(os.path.realpath(__file__))
152ba98753SSimon Glassfor dirname in ['../patman', '..']:
162ba98753SSimon Glass    sys.path.insert(0, os.path.join(our_path, dirname))
172ba98753SSimon Glass
182ba98753SSimon Glassimport command
192ba98753SSimon Glassimport fdt
202ba98753SSimon Glassfrom fdt import TYPE_BYTE, TYPE_INT, TYPE_STRING, TYPE_BOOL
212a2d91d0SSimon Glassimport fdt_util
222ba98753SSimon Glassfrom fdt_util import fdt32_to_cpu
232ba98753SSimon Glassimport libfdt
242ba98753SSimon Glassimport test_util
252ba98753SSimon Glassimport tools
262ba98753SSimon Glass
27f9b88b3aSSimon Glassdef _GetPropertyValue(dtb, node, prop_name):
28f9b88b3aSSimon Glass    """Low-level function to get the property value based on its offset
29f9b88b3aSSimon Glass
30f9b88b3aSSimon Glass    This looks directly in the device tree at the property's offset to find
31f9b88b3aSSimon Glass    its value. It is useful as a check that the property is in the correct
32f9b88b3aSSimon Glass    place.
33f9b88b3aSSimon Glass
34f9b88b3aSSimon Glass    Args:
35f9b88b3aSSimon Glass        node: Node to look in
36f9b88b3aSSimon Glass        prop_name: Property name to find
37f9b88b3aSSimon Glass
38f9b88b3aSSimon Glass    Returns:
39f9b88b3aSSimon Glass        Tuple:
40f9b88b3aSSimon Glass            Prop object found
41f9b88b3aSSimon Glass            Value of property as a string (found using property offset)
42f9b88b3aSSimon Glass    """
43f9b88b3aSSimon Glass    prop = node.props[prop_name]
44f9b88b3aSSimon Glass
45f9b88b3aSSimon Glass    # Add 12, which is sizeof(struct fdt_property), to get to start of data
46f9b88b3aSSimon Glass    offset = prop.GetOffset() + 12
47f9b88b3aSSimon Glass    data = dtb.GetContents()[offset:offset + len(prop.value)]
48f9b88b3aSSimon Glass    return prop, [chr(x) for x in data]
49f9b88b3aSSimon Glass
50f9b88b3aSSimon Glass
512ba98753SSimon Glassclass TestFdt(unittest.TestCase):
522ba98753SSimon Glass    """Tests for the Fdt module
532ba98753SSimon Glass
542ba98753SSimon Glass    This includes unit tests for some functions and functional tests for the fdt
552ba98753SSimon Glass    module.
562ba98753SSimon Glass    """
572ba98753SSimon Glass    @classmethod
582ba98753SSimon Glass    def setUpClass(cls):
592ba98753SSimon Glass        tools.PrepareOutputDir(None)
602ba98753SSimon Glass
612ba98753SSimon Glass    @classmethod
622ba98753SSimon Glass    def tearDownClass(cls):
632ba98753SSimon Glass        tools._FinaliseForTest()
642ba98753SSimon Glass
652ba98753SSimon Glass    def setUp(self):
662ba98753SSimon Glass        self.dtb = fdt.FdtScan('tools/dtoc/dtoc_test_simple.dts')
672ba98753SSimon Glass
682ba98753SSimon Glass    def testFdt(self):
692ba98753SSimon Glass        """Test that we can open an Fdt"""
702ba98753SSimon Glass        self.dtb.Scan()
712ba98753SSimon Glass        root = self.dtb.GetRoot()
722ba98753SSimon Glass        self.assertTrue(isinstance(root, fdt.Node))
732ba98753SSimon Glass
742ba98753SSimon Glass    def testGetNode(self):
752ba98753SSimon Glass        """Test the GetNode() method"""
762ba98753SSimon Glass        node = self.dtb.GetNode('/spl-test')
772ba98753SSimon Glass        self.assertTrue(isinstance(node, fdt.Node))
782ba98753SSimon Glass        node = self.dtb.GetNode('/i2c@0/pmic@9')
792ba98753SSimon Glass        self.assertTrue(isinstance(node, fdt.Node))
802ba98753SSimon Glass        self.assertEqual('pmic@9', node.name)
812a2d91d0SSimon Glass        self.assertIsNone(self.dtb.GetNode('/i2c@0/pmic@9/missing'))
822ba98753SSimon Glass
832ba98753SSimon Glass    def testFlush(self):
842ba98753SSimon Glass        """Check that we can flush the device tree out to its file"""
852ba98753SSimon Glass        fname = self.dtb._fname
862ba98753SSimon Glass        with open(fname) as fd:
872ba98753SSimon Glass            data = fd.read()
882ba98753SSimon Glass        os.remove(fname)
892ba98753SSimon Glass        with self.assertRaises(IOError):
902ba98753SSimon Glass            open(fname)
912ba98753SSimon Glass        self.dtb.Flush()
922ba98753SSimon Glass        with open(fname) as fd:
932ba98753SSimon Glass            data = fd.read()
942ba98753SSimon Glass
952ba98753SSimon Glass    def testPack(self):
962ba98753SSimon Glass        """Test that packing a device tree works"""
972ba98753SSimon Glass        self.dtb.Pack()
982ba98753SSimon Glass
992ba98753SSimon Glass    def testGetFdt(self):
1002ba98753SSimon Glass        """Tetst that we can access the raw device-tree data"""
10196066240SSimon Glass        self.assertTrue(isinstance(self.dtb.GetContents(), bytearray))
1022ba98753SSimon Glass
1032ba98753SSimon Glass    def testGetProps(self):
1042ba98753SSimon Glass        """Tests obtaining a list of properties"""
1052ba98753SSimon Glass        node = self.dtb.GetNode('/spl-test')
1062ba98753SSimon Glass        props = self.dtb.GetProps(node)
1072ba98753SSimon Glass        self.assertEqual(['boolval', 'bytearray', 'byteval', 'compatible',
1082a2d91d0SSimon Glass                          'intarray', 'intval', 'longbytearray', 'notstring',
1092ba98753SSimon Glass                          'stringarray', 'stringval', 'u-boot,dm-pre-reloc'],
1102ba98753SSimon Glass                         sorted(props.keys()))
1112ba98753SSimon Glass
1122ba98753SSimon Glass    def testCheckError(self):
1132ba98753SSimon Glass        """Tests the ChecKError() function"""
1142ba98753SSimon Glass        with self.assertRaises(ValueError) as e:
1152a2d91d0SSimon Glass            fdt.CheckErr(-libfdt.NOTFOUND, 'hello')
1162ba98753SSimon Glass        self.assertIn('FDT_ERR_NOTFOUND: hello', str(e.exception))
1172ba98753SSimon Glass
1182ba98753SSimon Glass
1192ba98753SSimon Glassclass TestNode(unittest.TestCase):
1202ba98753SSimon Glass    """Test operation of the Node class"""
1212ba98753SSimon Glass
1222ba98753SSimon Glass    @classmethod
1232ba98753SSimon Glass    def setUpClass(cls):
1242ba98753SSimon Glass        tools.PrepareOutputDir(None)
1252ba98753SSimon Glass
1262ba98753SSimon Glass    @classmethod
1272ba98753SSimon Glass    def tearDownClass(cls):
1282ba98753SSimon Glass        tools._FinaliseForTest()
1292ba98753SSimon Glass
1302ba98753SSimon Glass    def setUp(self):
1312ba98753SSimon Glass        self.dtb = fdt.FdtScan('tools/dtoc/dtoc_test_simple.dts')
1322ba98753SSimon Glass        self.node = self.dtb.GetNode('/spl-test')
1332ba98753SSimon Glass
1342ba98753SSimon Glass    def testOffset(self):
1352ba98753SSimon Glass        """Tests that we can obtain the offset of a node"""
1362ba98753SSimon Glass        self.assertTrue(self.node.Offset() > 0)
1372ba98753SSimon Glass
1382ba98753SSimon Glass    def testDelete(self):
1392ba98753SSimon Glass        """Tests that we can delete a property"""
1402ba98753SSimon Glass        node2 = self.dtb.GetNode('/spl-test2')
1412ba98753SSimon Glass        offset1 = node2.Offset()
1422ba98753SSimon Glass        self.node.DeleteProp('intval')
1432ba98753SSimon Glass        offset2 = node2.Offset()
1442ba98753SSimon Glass        self.assertTrue(offset2 < offset1)
1452ba98753SSimon Glass        self.node.DeleteProp('intarray')
1462ba98753SSimon Glass        offset3 = node2.Offset()
1472ba98753SSimon Glass        self.assertTrue(offset3 < offset2)
1482a2d91d0SSimon Glass        with self.assertRaises(libfdt.FdtException):
1492a2d91d0SSimon Glass            self.node.DeleteProp('missing')
1502ba98753SSimon Glass
151f9b88b3aSSimon Glass    def testDeleteGetOffset(self):
152f9b88b3aSSimon Glass        """Test that property offset update when properties are deleted"""
153f9b88b3aSSimon Glass        self.node.DeleteProp('intval')
154f9b88b3aSSimon Glass        prop, value = _GetPropertyValue(self.dtb, self.node, 'longbytearray')
155f9b88b3aSSimon Glass        self.assertEqual(prop.value, value)
156f9b88b3aSSimon Glass
1572ba98753SSimon Glass    def testFindNode(self):
1582ba98753SSimon Glass        """Tests that we can find a node using the _FindNode() functoin"""
1592ba98753SSimon Glass        node = self.dtb.GetRoot()._FindNode('i2c@0')
1602ba98753SSimon Glass        self.assertEqual('i2c@0', node.name)
1612ba98753SSimon Glass        subnode = node._FindNode('pmic@9')
1622ba98753SSimon Glass        self.assertEqual('pmic@9', subnode.name)
1632a2d91d0SSimon Glass        self.assertEqual(None, node._FindNode('missing'))
1642ba98753SSimon Glass
165f9b88b3aSSimon Glass    def testRefreshMissingNode(self):
166f9b88b3aSSimon Glass        """Test refreshing offsets when an extra node is present in dtb"""
167f9b88b3aSSimon Glass        # Delete it from our tables, not the device tree
168f9b88b3aSSimon Glass        del self.dtb._root.subnodes[-1]
169f9b88b3aSSimon Glass        with self.assertRaises(ValueError) as e:
170f9b88b3aSSimon Glass            self.dtb.Refresh()
171f9b88b3aSSimon Glass        self.assertIn('Internal error, offset', str(e.exception))
172f9b88b3aSSimon Glass
173f9b88b3aSSimon Glass    def testRefreshExtraNode(self):
174f9b88b3aSSimon Glass        """Test refreshing offsets when an expected node is missing"""
175f9b88b3aSSimon Glass        # Delete it from the device tre, not our tables
176f9b88b3aSSimon Glass        self.dtb.GetFdtObj().del_node(self.node.Offset())
177f9b88b3aSSimon Glass        with self.assertRaises(ValueError) as e:
178f9b88b3aSSimon Glass            self.dtb.Refresh()
179f9b88b3aSSimon Glass        self.assertIn('Internal error, node name mismatch '
180f9b88b3aSSimon Glass                      'spl-test != spl-test2', str(e.exception))
181f9b88b3aSSimon Glass
182f9b88b3aSSimon Glass    def testRefreshMissingProp(self):
183f9b88b3aSSimon Glass        """Test refreshing offsets when an extra property is present in dtb"""
184f9b88b3aSSimon Glass        # Delete it from our tables, not the device tree
185f9b88b3aSSimon Glass        del self.node.props['notstring']
186f9b88b3aSSimon Glass        with self.assertRaises(ValueError) as e:
187f9b88b3aSSimon Glass            self.dtb.Refresh()
188f9b88b3aSSimon Glass        self.assertIn("Internal error, property 'notstring' missing, offset ",
189f9b88b3aSSimon Glass                      str(e.exception))
190f9b88b3aSSimon Glass
1912ba98753SSimon Glass
1922ba98753SSimon Glassclass TestProp(unittest.TestCase):
1932ba98753SSimon Glass    """Test operation of the Prop class"""
1942ba98753SSimon Glass
1952ba98753SSimon Glass    @classmethod
1962ba98753SSimon Glass    def setUpClass(cls):
1972ba98753SSimon Glass        tools.PrepareOutputDir(None)
1982ba98753SSimon Glass
1992ba98753SSimon Glass    @classmethod
2002ba98753SSimon Glass    def tearDownClass(cls):
2012ba98753SSimon Glass        tools._FinaliseForTest()
2022ba98753SSimon Glass
2032ba98753SSimon Glass    def setUp(self):
2042ba98753SSimon Glass        self.dtb = fdt.FdtScan('tools/dtoc/dtoc_test_simple.dts')
2052ba98753SSimon Glass        self.node = self.dtb.GetNode('/spl-test')
2062ba98753SSimon Glass        self.fdt = self.dtb.GetFdtObj()
2072ba98753SSimon Glass
208b9066ffcSSimon Glass    def testMissingNode(self):
209b9066ffcSSimon Glass        self.assertEqual(None, self.dtb.GetNode('missing'))
210b9066ffcSSimon Glass
2112a2d91d0SSimon Glass    def testPhandle(self):
2122a2d91d0SSimon Glass        dtb = fdt.FdtScan('tools/dtoc/dtoc_test_phandle.dts')
213760b7170SSimon Glass        node = dtb.GetNode('/phandle-source2')
214760b7170SSimon Glass        prop = node.props['clocks']
215760b7170SSimon Glass        self.assertTrue(fdt32_to_cpu(prop.value) > 0)
2162a2d91d0SSimon Glass
2172a2d91d0SSimon Glass    def _ConvertProp(self, prop_name):
2182a2d91d0SSimon Glass        """Helper function to look up a property in self.node and return it
2192a2d91d0SSimon Glass
2202a2d91d0SSimon Glass        Args:
2212a2d91d0SSimon Glass            Property name to find
2222a2d91d0SSimon Glass
2232a2d91d0SSimon Glass        Return fdt.Prop object for this property
2242a2d91d0SSimon Glass        """
2252a2d91d0SSimon Glass        p = self.fdt.get_property(self.node.Offset(), prop_name)
2262a2d91d0SSimon Glass        return fdt.Prop(self.node, -1, prop_name, p)
2272a2d91d0SSimon Glass
2282a2d91d0SSimon Glass    def testMakeProp(self):
2292a2d91d0SSimon Glass        """Test we can convert all the the types that are supported"""
2302a2d91d0SSimon Glass        prop = self._ConvertProp('boolval')
2312a2d91d0SSimon Glass        self.assertEqual(fdt.TYPE_BOOL, prop.type)
2322a2d91d0SSimon Glass        self.assertEqual(True, prop.value)
2332a2d91d0SSimon Glass
2342a2d91d0SSimon Glass        prop = self._ConvertProp('intval')
2352a2d91d0SSimon Glass        self.assertEqual(fdt.TYPE_INT, prop.type)
2362a2d91d0SSimon Glass        self.assertEqual(1, fdt32_to_cpu(prop.value))
2372a2d91d0SSimon Glass
2382a2d91d0SSimon Glass        prop = self._ConvertProp('intarray')
2392a2d91d0SSimon Glass        self.assertEqual(fdt.TYPE_INT, prop.type)
2402a2d91d0SSimon Glass        val = [fdt32_to_cpu(val) for val in prop.value]
2412a2d91d0SSimon Glass        self.assertEqual([2, 3, 4], val)
2422a2d91d0SSimon Glass
2432a2d91d0SSimon Glass        prop = self._ConvertProp('byteval')
2442a2d91d0SSimon Glass        self.assertEqual(fdt.TYPE_BYTE, prop.type)
2452a2d91d0SSimon Glass        self.assertEqual(5, ord(prop.value))
2462a2d91d0SSimon Glass
2472a2d91d0SSimon Glass        prop = self._ConvertProp('longbytearray')
2482a2d91d0SSimon Glass        self.assertEqual(fdt.TYPE_BYTE, prop.type)
2492a2d91d0SSimon Glass        val = [ord(val) for val in prop.value]
2502a2d91d0SSimon Glass        self.assertEqual([9, 10, 11, 12, 13, 14, 15, 16, 17], val)
2512a2d91d0SSimon Glass
2522a2d91d0SSimon Glass        prop = self._ConvertProp('stringval')
2532a2d91d0SSimon Glass        self.assertEqual(fdt.TYPE_STRING, prop.type)
2542a2d91d0SSimon Glass        self.assertEqual('message', prop.value)
2552a2d91d0SSimon Glass
2562a2d91d0SSimon Glass        prop = self._ConvertProp('stringarray')
2572a2d91d0SSimon Glass        self.assertEqual(fdt.TYPE_STRING, prop.type)
2582a2d91d0SSimon Glass        self.assertEqual(['multi-word', 'message'], prop.value)
2592a2d91d0SSimon Glass
2602a2d91d0SSimon Glass        prop = self._ConvertProp('notstring')
2612a2d91d0SSimon Glass        self.assertEqual(fdt.TYPE_BYTE, prop.type)
2622a2d91d0SSimon Glass        val = [ord(val) for val in prop.value]
2632a2d91d0SSimon Glass        self.assertEqual([0x20, 0x21, 0x22, 0x10, 0], val)
2642a2d91d0SSimon Glass
2652ba98753SSimon Glass    def testGetEmpty(self):
2662ba98753SSimon Glass        """Tests the GetEmpty() function for the various supported types"""
2672ba98753SSimon Glass        self.assertEqual(True, fdt.Prop.GetEmpty(fdt.TYPE_BOOL))
2682ba98753SSimon Glass        self.assertEqual(chr(0), fdt.Prop.GetEmpty(fdt.TYPE_BYTE))
2692ba98753SSimon Glass        self.assertEqual(chr(0) * 4, fdt.Prop.GetEmpty(fdt.TYPE_INT))
2702ba98753SSimon Glass        self.assertEqual('', fdt.Prop.GetEmpty(fdt.TYPE_STRING))
2712ba98753SSimon Glass
2722ba98753SSimon Glass    def testGetOffset(self):
2732ba98753SSimon Glass        """Test we can get the offset of a property"""
274f9b88b3aSSimon Glass        prop, value = _GetPropertyValue(self.dtb, self.node, 'longbytearray')
275f9b88b3aSSimon Glass        self.assertEqual(prop.value, value)
2762ba98753SSimon Glass
2772ba98753SSimon Glass    def testWiden(self):
2782ba98753SSimon Glass        """Test widening of values"""
2792ba98753SSimon Glass        node2 = self.dtb.GetNode('/spl-test2')
2802ba98753SSimon Glass        prop = self.node.props['intval']
2812ba98753SSimon Glass
2822ba98753SSimon Glass        # No action
2832ba98753SSimon Glass        prop2 = node2.props['intval']
2842ba98753SSimon Glass        prop.Widen(prop2)
2852ba98753SSimon Glass        self.assertEqual(fdt.TYPE_INT, prop.type)
2862ba98753SSimon Glass        self.assertEqual(1, fdt32_to_cpu(prop.value))
2872ba98753SSimon Glass
2882ba98753SSimon Glass        # Convert singla value to array
2892ba98753SSimon Glass        prop2 = self.node.props['intarray']
2902ba98753SSimon Glass        prop.Widen(prop2)
2912ba98753SSimon Glass        self.assertEqual(fdt.TYPE_INT, prop.type)
2922ba98753SSimon Glass        self.assertTrue(isinstance(prop.value, list))
2932ba98753SSimon Glass
2942ba98753SSimon Glass        # A 4-byte array looks like a single integer. When widened by a longer
2952ba98753SSimon Glass        # byte array, it should turn into an array.
2962ba98753SSimon Glass        prop = self.node.props['longbytearray']
2972ba98753SSimon Glass        prop2 = node2.props['longbytearray']
2982ba98753SSimon Glass        self.assertFalse(isinstance(prop2.value, list))
2992ba98753SSimon Glass        self.assertEqual(4, len(prop2.value))
3002ba98753SSimon Glass        prop2.Widen(prop)
3012ba98753SSimon Glass        self.assertTrue(isinstance(prop2.value, list))
3022ba98753SSimon Glass        self.assertEqual(9, len(prop2.value))
3032ba98753SSimon Glass
3042ba98753SSimon Glass        # Similarly for a string array
3052ba98753SSimon Glass        prop = self.node.props['stringval']
3062ba98753SSimon Glass        prop2 = node2.props['stringarray']
3072ba98753SSimon Glass        self.assertFalse(isinstance(prop.value, list))
3082ba98753SSimon Glass        self.assertEqual(7, len(prop.value))
3092ba98753SSimon Glass        prop.Widen(prop2)
3102ba98753SSimon Glass        self.assertTrue(isinstance(prop.value, list))
3112ba98753SSimon Glass        self.assertEqual(3, len(prop.value))
3122ba98753SSimon Glass
3132ba98753SSimon Glass        # Enlarging an existing array
3142ba98753SSimon Glass        prop = self.node.props['stringarray']
3152ba98753SSimon Glass        prop2 = node2.props['stringarray']
3162ba98753SSimon Glass        self.assertTrue(isinstance(prop.value, list))
3172ba98753SSimon Glass        self.assertEqual(2, len(prop.value))
3182ba98753SSimon Glass        prop.Widen(prop2)
3192ba98753SSimon Glass        self.assertTrue(isinstance(prop.value, list))
3202ba98753SSimon Glass        self.assertEqual(3, len(prop.value))
3212ba98753SSimon Glass
322116adecbSSimon Glass    def testAdd(self):
323116adecbSSimon Glass        """Test adding properties"""
324116adecbSSimon Glass        self.fdt.pack()
325116adecbSSimon Glass        # This function should automatically expand the device tree
326116adecbSSimon Glass        self.node.AddZeroProp('one')
327116adecbSSimon Glass        self.node.AddZeroProp('two')
328116adecbSSimon Glass        self.node.AddZeroProp('three')
329116adecbSSimon Glass
330116adecbSSimon Glass        # Updating existing properties should be OK, since the device-tree size
331116adecbSSimon Glass        # does not change
332116adecbSSimon Glass        self.fdt.pack()
333116adecbSSimon Glass        self.node.SetInt('one', 1)
334116adecbSSimon Glass        self.node.SetInt('two', 2)
335116adecbSSimon Glass        self.node.SetInt('three', 3)
336116adecbSSimon Glass
337116adecbSSimon Glass        # This should fail since it would need to increase the device-tree size
338116adecbSSimon Glass        with self.assertRaises(libfdt.FdtException) as e:
339116adecbSSimon Glass            self.node.SetInt('four', 4)
340116adecbSSimon Glass        self.assertIn('FDT_ERR_NOSPACE', str(e.exception))
341116adecbSSimon Glass
3422ba98753SSimon Glass
3432a2d91d0SSimon Glassclass TestFdtUtil(unittest.TestCase):
3442a2d91d0SSimon Glass    """Tests for the fdt_util module
3452a2d91d0SSimon Glass
3462a2d91d0SSimon Glass    This module will likely be mostly replaced at some point, once upstream
3472a2d91d0SSimon Glass    libfdt has better Python support. For now, this provides tests for current
3482a2d91d0SSimon Glass    functionality.
3492a2d91d0SSimon Glass    """
3502a2d91d0SSimon Glass    @classmethod
3512a2d91d0SSimon Glass    def setUpClass(cls):
3522a2d91d0SSimon Glass        tools.PrepareOutputDir(None)
3532a2d91d0SSimon Glass
3542a2d91d0SSimon Glass    def setUp(self):
3552a2d91d0SSimon Glass        self.dtb = fdt.FdtScan('tools/dtoc/dtoc_test_simple.dts')
3562a2d91d0SSimon Glass        self.node = self.dtb.GetNode('/spl-test')
3572a2d91d0SSimon Glass
3582a2d91d0SSimon Glass    def testGetInt(self):
3592a2d91d0SSimon Glass        self.assertEqual(1, fdt_util.GetInt(self.node, 'intval'))
3602a2d91d0SSimon Glass        self.assertEqual(3, fdt_util.GetInt(self.node, 'missing', 3))
3612a2d91d0SSimon Glass
3622a2d91d0SSimon Glass        with self.assertRaises(ValueError) as e:
3632a2d91d0SSimon Glass            self.assertEqual(3, fdt_util.GetInt(self.node, 'intarray'))
3642a2d91d0SSimon Glass        self.assertIn("property 'intarray' has list value: expecting a single "
3652a2d91d0SSimon Glass                      'integer', str(e.exception))
3662a2d91d0SSimon Glass
3672a2d91d0SSimon Glass    def testGetString(self):
3682a2d91d0SSimon Glass        self.assertEqual('message', fdt_util.GetString(self.node, 'stringval'))
3692a2d91d0SSimon Glass        self.assertEqual('test', fdt_util.GetString(self.node, 'missing',
3702a2d91d0SSimon Glass                                                    'test'))
3712a2d91d0SSimon Glass
3722a2d91d0SSimon Glass        with self.assertRaises(ValueError) as e:
3732a2d91d0SSimon Glass            self.assertEqual(3, fdt_util.GetString(self.node, 'stringarray'))
3742a2d91d0SSimon Glass        self.assertIn("property 'stringarray' has list value: expecting a "
3752a2d91d0SSimon Glass                      'single string', str(e.exception))
3762a2d91d0SSimon Glass
3772a2d91d0SSimon Glass    def testGetBool(self):
3782a2d91d0SSimon Glass        self.assertEqual(True, fdt_util.GetBool(self.node, 'boolval'))
3792a2d91d0SSimon Glass        self.assertEqual(False, fdt_util.GetBool(self.node, 'missing'))
3802a2d91d0SSimon Glass        self.assertEqual(True, fdt_util.GetBool(self.node, 'missing', True))
3812a2d91d0SSimon Glass        self.assertEqual(False, fdt_util.GetBool(self.node, 'missing', False))
3822a2d91d0SSimon Glass
383*3af8e49cSSimon Glass    def testGetByte(self):
384*3af8e49cSSimon Glass        self.assertEqual(5, fdt_util.GetByte(self.node, 'byteval'))
385*3af8e49cSSimon Glass        self.assertEqual(3, fdt_util.GetByte(self.node, 'missing', 3))
386*3af8e49cSSimon Glass
387*3af8e49cSSimon Glass        with self.assertRaises(ValueError) as e:
388*3af8e49cSSimon Glass            fdt_util.GetByte(self.node, 'longbytearray')
389*3af8e49cSSimon Glass        self.assertIn("property 'longbytearray' has list value: expecting a "
390*3af8e49cSSimon Glass                      'single byte', str(e.exception))
391*3af8e49cSSimon Glass
392*3af8e49cSSimon Glass        with self.assertRaises(ValueError) as e:
393*3af8e49cSSimon Glass            fdt_util.GetByte(self.node, 'intval')
394*3af8e49cSSimon Glass        self.assertIn("property 'intval' has length 4, expecting 1",
395*3af8e49cSSimon Glass                      str(e.exception))
396*3af8e49cSSimon Glass
39753af22a9SSimon Glass    def testGetDataType(self):
39853af22a9SSimon Glass        self.assertEqual(1, fdt_util.GetDatatype(self.node, 'intval', int))
39953af22a9SSimon Glass        self.assertEqual('message', fdt_util.GetDatatype(self.node, 'stringval',
40053af22a9SSimon Glass                                                         str))
40153af22a9SSimon Glass        with self.assertRaises(ValueError) as e:
40253af22a9SSimon Glass            self.assertEqual(3, fdt_util.GetDatatype(self.node, 'boolval',
40353af22a9SSimon Glass                                                     bool))
4042a2d91d0SSimon Glass    def testFdtCellsToCpu(self):
4052a2d91d0SSimon Glass        val = self.node.props['intarray'].value
4062a2d91d0SSimon Glass        self.assertEqual(0, fdt_util.fdt_cells_to_cpu(val, 0))
4072a2d91d0SSimon Glass        self.assertEqual(2, fdt_util.fdt_cells_to_cpu(val, 1))
4082a2d91d0SSimon Glass
4092a2d91d0SSimon Glass        dtb2 = fdt.FdtScan('tools/dtoc/dtoc_test_addr64.dts')
4102a2d91d0SSimon Glass        node2 = dtb2.GetNode('/test1')
4112a2d91d0SSimon Glass        val = node2.props['reg'].value
4122a2d91d0SSimon Glass        self.assertEqual(0x1234, fdt_util.fdt_cells_to_cpu(val, 2))
4132a2d91d0SSimon Glass
4142a2d91d0SSimon Glass    def testEnsureCompiled(self):
4152a2d91d0SSimon Glass        """Test a degenerate case of this function"""
4162a2d91d0SSimon Glass        dtb = fdt_util.EnsureCompiled('tools/dtoc/dtoc_test_simple.dts')
4172a2d91d0SSimon Glass        self.assertEqual(dtb, fdt_util.EnsureCompiled(dtb))
4182a2d91d0SSimon Glass
4192a2d91d0SSimon Glass    def testGetPlainBytes(self):
4202a2d91d0SSimon Glass        self.assertEqual('fred', fdt_util.get_plain_bytes('fred'))
4212a2d91d0SSimon Glass
4222a2d91d0SSimon Glass
4232a2d91d0SSimon Glassdef RunTestCoverage():
4242a2d91d0SSimon Glass    """Run the tests and check that we get 100% coverage"""
4252a2d91d0SSimon Glass    test_util.RunTestCoverage('tools/dtoc/test_fdt.py', None,
4262a2d91d0SSimon Glass            ['tools/patman/*.py', '*test_fdt.py'], options.build_dir)
4272a2d91d0SSimon Glass
4282a2d91d0SSimon Glass
4292ba98753SSimon Glassdef RunTests(args):
4302ba98753SSimon Glass    """Run all the test we have for the fdt model
4312ba98753SSimon Glass
4322ba98753SSimon Glass    Args:
4332ba98753SSimon Glass        args: List of positional args provided to fdt. This can hold a test
4342ba98753SSimon Glass            name to execute (as in 'fdt -t testFdt', for example)
4352ba98753SSimon Glass    """
4362ba98753SSimon Glass    result = unittest.TestResult()
4372ba98753SSimon Glass    sys.argv = [sys.argv[0]]
4382ba98753SSimon Glass    test_name = args and args[0] or None
4392a2d91d0SSimon Glass    for module in (TestFdt, TestNode, TestProp, TestFdtUtil):
4402ba98753SSimon Glass        if test_name:
4412ba98753SSimon Glass            try:
4422ba98753SSimon Glass                suite = unittest.TestLoader().loadTestsFromName(test_name, module)
4432ba98753SSimon Glass            except AttributeError:
4442ba98753SSimon Glass                continue
4452ba98753SSimon Glass        else:
4462ba98753SSimon Glass            suite = unittest.TestLoader().loadTestsFromTestCase(module)
4472ba98753SSimon Glass        suite.run(result)
4482ba98753SSimon Glass
4492ba98753SSimon Glass    print result
4502ba98753SSimon Glass    for _, err in result.errors:
4512ba98753SSimon Glass        print err
4522ba98753SSimon Glass    for _, err in result.failures:
4532ba98753SSimon Glass        print err
4542ba98753SSimon Glass
4552ba98753SSimon Glassif __name__ != '__main__':
4562ba98753SSimon Glass    sys.exit(1)
4572ba98753SSimon Glass
4582ba98753SSimon Glassparser = OptionParser()
4592a2d91d0SSimon Glassparser.add_option('-B', '--build-dir', type='string', default='b',
4602a2d91d0SSimon Glass        help='Directory containing the build output')
4612ba98753SSimon Glassparser.add_option('-t', '--test', action='store_true', dest='test',
4622ba98753SSimon Glass                  default=False, help='run tests')
4632a2d91d0SSimon Glassparser.add_option('-T', '--test-coverage', action='store_true',
4642a2d91d0SSimon Glass                default=False, help='run tests and check for 100% coverage')
4652ba98753SSimon Glass(options, args) = parser.parse_args()
4662ba98753SSimon Glass
4672ba98753SSimon Glass# Run our meagre tests
4682ba98753SSimon Glassif options.test:
4692ba98753SSimon Glass    RunTests(args)
4702a2d91d0SSimon Glasselif options.test_coverage:
4712a2d91d0SSimon Glass    RunTestCoverage()
472