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 212ba98753SSimon Glassfrom fdt_util import fdt32_to_cpu 222ba98753SSimon Glassimport libfdt 232ba98753SSimon Glassimport test_util 242ba98753SSimon Glassimport tools 252ba98753SSimon Glass 262ba98753SSimon Glassclass TestFdt(unittest.TestCase): 272ba98753SSimon Glass """Tests for the Fdt module 282ba98753SSimon Glass 292ba98753SSimon Glass This includes unit tests for some functions and functional tests for the fdt 302ba98753SSimon Glass module. 312ba98753SSimon Glass """ 322ba98753SSimon Glass @classmethod 332ba98753SSimon Glass def setUpClass(cls): 342ba98753SSimon Glass tools.PrepareOutputDir(None) 352ba98753SSimon Glass 362ba98753SSimon Glass @classmethod 372ba98753SSimon Glass def tearDownClass(cls): 382ba98753SSimon Glass tools._FinaliseForTest() 392ba98753SSimon Glass 402ba98753SSimon Glass def setUp(self): 412ba98753SSimon Glass self.dtb = fdt.FdtScan('tools/dtoc/dtoc_test_simple.dts') 422ba98753SSimon Glass 432ba98753SSimon Glass def testFdt(self): 442ba98753SSimon Glass """Test that we can open an Fdt""" 452ba98753SSimon Glass self.dtb.Scan() 462ba98753SSimon Glass root = self.dtb.GetRoot() 472ba98753SSimon Glass self.assertTrue(isinstance(root, fdt.Node)) 482ba98753SSimon Glass 492ba98753SSimon Glass def testGetNode(self): 502ba98753SSimon Glass """Test the GetNode() method""" 512ba98753SSimon Glass node = self.dtb.GetNode('/spl-test') 522ba98753SSimon Glass self.assertTrue(isinstance(node, fdt.Node)) 532ba98753SSimon Glass node = self.dtb.GetNode('/i2c@0/pmic@9') 542ba98753SSimon Glass self.assertTrue(isinstance(node, fdt.Node)) 552ba98753SSimon Glass self.assertEqual('pmic@9', node.name) 562ba98753SSimon Glass 572ba98753SSimon Glass def testFlush(self): 582ba98753SSimon Glass """Check that we can flush the device tree out to its file""" 592ba98753SSimon Glass fname = self.dtb._fname 602ba98753SSimon Glass with open(fname) as fd: 612ba98753SSimon Glass data = fd.read() 622ba98753SSimon Glass os.remove(fname) 632ba98753SSimon Glass with self.assertRaises(IOError): 642ba98753SSimon Glass open(fname) 652ba98753SSimon Glass self.dtb.Flush() 662ba98753SSimon Glass with open(fname) as fd: 672ba98753SSimon Glass data = fd.read() 682ba98753SSimon Glass 692ba98753SSimon Glass def testPack(self): 702ba98753SSimon Glass """Test that packing a device tree works""" 712ba98753SSimon Glass self.dtb.Pack() 722ba98753SSimon Glass 732ba98753SSimon Glass def testGetFdt(self): 742ba98753SSimon Glass """Tetst that we can access the raw device-tree data""" 75*96066240SSimon Glass self.assertTrue(isinstance(self.dtb.GetContents(), bytearray)) 762ba98753SSimon Glass 772ba98753SSimon Glass def testGetProps(self): 782ba98753SSimon Glass """Tests obtaining a list of properties""" 792ba98753SSimon Glass node = self.dtb.GetNode('/spl-test') 802ba98753SSimon Glass props = self.dtb.GetProps(node) 812ba98753SSimon Glass self.assertEqual(['boolval', 'bytearray', 'byteval', 'compatible', 822ba98753SSimon Glass 'intarray', 'intval', 'longbytearray', 832ba98753SSimon Glass 'stringarray', 'stringval', 'u-boot,dm-pre-reloc'], 842ba98753SSimon Glass sorted(props.keys())) 852ba98753SSimon Glass 862ba98753SSimon Glass def testCheckError(self): 872ba98753SSimon Glass """Tests the ChecKError() function""" 882ba98753SSimon Glass with self.assertRaises(ValueError) as e: 892ba98753SSimon Glass self.dtb.CheckErr(-libfdt.NOTFOUND, 'hello') 902ba98753SSimon Glass self.assertIn('FDT_ERR_NOTFOUND: hello', str(e.exception)) 912ba98753SSimon Glass 922ba98753SSimon Glass 932ba98753SSimon Glassclass TestNode(unittest.TestCase): 942ba98753SSimon Glass """Test operation of the Node class""" 952ba98753SSimon Glass 962ba98753SSimon Glass @classmethod 972ba98753SSimon Glass def setUpClass(cls): 982ba98753SSimon Glass tools.PrepareOutputDir(None) 992ba98753SSimon Glass 1002ba98753SSimon Glass @classmethod 1012ba98753SSimon Glass def tearDownClass(cls): 1022ba98753SSimon Glass tools._FinaliseForTest() 1032ba98753SSimon Glass 1042ba98753SSimon Glass def setUp(self): 1052ba98753SSimon Glass self.dtb = fdt.FdtScan('tools/dtoc/dtoc_test_simple.dts') 1062ba98753SSimon Glass self.node = self.dtb.GetNode('/spl-test') 1072ba98753SSimon Glass 1082ba98753SSimon Glass def testOffset(self): 1092ba98753SSimon Glass """Tests that we can obtain the offset of a node""" 1102ba98753SSimon Glass self.assertTrue(self.node.Offset() > 0) 1112ba98753SSimon Glass 1122ba98753SSimon Glass def testDelete(self): 1132ba98753SSimon Glass """Tests that we can delete a property""" 1142ba98753SSimon Glass node2 = self.dtb.GetNode('/spl-test2') 1152ba98753SSimon Glass offset1 = node2.Offset() 1162ba98753SSimon Glass self.node.DeleteProp('intval') 1172ba98753SSimon Glass offset2 = node2.Offset() 1182ba98753SSimon Glass self.assertTrue(offset2 < offset1) 1192ba98753SSimon Glass self.node.DeleteProp('intarray') 1202ba98753SSimon Glass offset3 = node2.Offset() 1212ba98753SSimon Glass self.assertTrue(offset3 < offset2) 1222ba98753SSimon Glass 1232ba98753SSimon Glass def testFindNode(self): 1242ba98753SSimon Glass """Tests that we can find a node using the _FindNode() functoin""" 1252ba98753SSimon Glass node = self.dtb.GetRoot()._FindNode('i2c@0') 1262ba98753SSimon Glass self.assertEqual('i2c@0', node.name) 1272ba98753SSimon Glass subnode = node._FindNode('pmic@9') 1282ba98753SSimon Glass self.assertEqual('pmic@9', subnode.name) 1292ba98753SSimon Glass 1302ba98753SSimon Glass 1312ba98753SSimon Glassclass TestProp(unittest.TestCase): 1322ba98753SSimon Glass """Test operation of the Prop class""" 1332ba98753SSimon Glass 1342ba98753SSimon Glass @classmethod 1352ba98753SSimon Glass def setUpClass(cls): 1362ba98753SSimon Glass tools.PrepareOutputDir(None) 1372ba98753SSimon Glass 1382ba98753SSimon Glass @classmethod 1392ba98753SSimon Glass def tearDownClass(cls): 1402ba98753SSimon Glass tools._FinaliseForTest() 1412ba98753SSimon Glass 1422ba98753SSimon Glass def setUp(self): 1432ba98753SSimon Glass self.dtb = fdt.FdtScan('tools/dtoc/dtoc_test_simple.dts') 1442ba98753SSimon Glass self.node = self.dtb.GetNode('/spl-test') 1452ba98753SSimon Glass self.fdt = self.dtb.GetFdtObj() 1462ba98753SSimon Glass 1472ba98753SSimon Glass def testGetEmpty(self): 1482ba98753SSimon Glass """Tests the GetEmpty() function for the various supported types""" 1492ba98753SSimon Glass self.assertEqual(True, fdt.Prop.GetEmpty(fdt.TYPE_BOOL)) 1502ba98753SSimon Glass self.assertEqual(chr(0), fdt.Prop.GetEmpty(fdt.TYPE_BYTE)) 1512ba98753SSimon Glass self.assertEqual(chr(0) * 4, fdt.Prop.GetEmpty(fdt.TYPE_INT)) 1522ba98753SSimon Glass self.assertEqual('', fdt.Prop.GetEmpty(fdt.TYPE_STRING)) 1532ba98753SSimon Glass 1542ba98753SSimon Glass def testGetOffset(self): 1552ba98753SSimon Glass """Test we can get the offset of a property""" 1562ba98753SSimon Glass prop = self.node.props['longbytearray'] 1572ba98753SSimon Glass 1582ba98753SSimon Glass # Add 12, which is sizeof(struct fdt_property), to get to start of data 1592ba98753SSimon Glass offset = prop.GetOffset() + 12 160*96066240SSimon Glass data = self.dtb.GetContents()[offset:offset + len(prop.value)] 1612ba98753SSimon Glass bytes = [chr(x) for x in data] 1622ba98753SSimon Glass self.assertEqual(bytes, prop.value) 1632ba98753SSimon Glass 1642ba98753SSimon Glass def testWiden(self): 1652ba98753SSimon Glass """Test widening of values""" 1662ba98753SSimon Glass node2 = self.dtb.GetNode('/spl-test2') 1672ba98753SSimon Glass prop = self.node.props['intval'] 1682ba98753SSimon Glass 1692ba98753SSimon Glass # No action 1702ba98753SSimon Glass prop2 = node2.props['intval'] 1712ba98753SSimon Glass prop.Widen(prop2) 1722ba98753SSimon Glass self.assertEqual(fdt.TYPE_INT, prop.type) 1732ba98753SSimon Glass self.assertEqual(1, fdt32_to_cpu(prop.value)) 1742ba98753SSimon Glass 1752ba98753SSimon Glass # Convert singla value to array 1762ba98753SSimon Glass prop2 = self.node.props['intarray'] 1772ba98753SSimon Glass prop.Widen(prop2) 1782ba98753SSimon Glass self.assertEqual(fdt.TYPE_INT, prop.type) 1792ba98753SSimon Glass self.assertTrue(isinstance(prop.value, list)) 1802ba98753SSimon Glass 1812ba98753SSimon Glass # A 4-byte array looks like a single integer. When widened by a longer 1822ba98753SSimon Glass # byte array, it should turn into an array. 1832ba98753SSimon Glass prop = self.node.props['longbytearray'] 1842ba98753SSimon Glass prop2 = node2.props['longbytearray'] 1852ba98753SSimon Glass self.assertFalse(isinstance(prop2.value, list)) 1862ba98753SSimon Glass self.assertEqual(4, len(prop2.value)) 1872ba98753SSimon Glass prop2.Widen(prop) 1882ba98753SSimon Glass self.assertTrue(isinstance(prop2.value, list)) 1892ba98753SSimon Glass self.assertEqual(9, len(prop2.value)) 1902ba98753SSimon Glass 1912ba98753SSimon Glass # Similarly for a string array 1922ba98753SSimon Glass prop = self.node.props['stringval'] 1932ba98753SSimon Glass prop2 = node2.props['stringarray'] 1942ba98753SSimon Glass self.assertFalse(isinstance(prop.value, list)) 1952ba98753SSimon Glass self.assertEqual(7, len(prop.value)) 1962ba98753SSimon Glass prop.Widen(prop2) 1972ba98753SSimon Glass self.assertTrue(isinstance(prop.value, list)) 1982ba98753SSimon Glass self.assertEqual(3, len(prop.value)) 1992ba98753SSimon Glass 2002ba98753SSimon Glass # Enlarging an existing array 2012ba98753SSimon Glass prop = self.node.props['stringarray'] 2022ba98753SSimon Glass prop2 = node2.props['stringarray'] 2032ba98753SSimon Glass self.assertTrue(isinstance(prop.value, list)) 2042ba98753SSimon Glass self.assertEqual(2, len(prop.value)) 2052ba98753SSimon Glass prop.Widen(prop2) 2062ba98753SSimon Glass self.assertTrue(isinstance(prop.value, list)) 2072ba98753SSimon Glass self.assertEqual(3, len(prop.value)) 2082ba98753SSimon Glass 2092ba98753SSimon Glass 2102ba98753SSimon Glassdef RunTests(args): 2112ba98753SSimon Glass """Run all the test we have for the fdt model 2122ba98753SSimon Glass 2132ba98753SSimon Glass Args: 2142ba98753SSimon Glass args: List of positional args provided to fdt. This can hold a test 2152ba98753SSimon Glass name to execute (as in 'fdt -t testFdt', for example) 2162ba98753SSimon Glass """ 2172ba98753SSimon Glass result = unittest.TestResult() 2182ba98753SSimon Glass sys.argv = [sys.argv[0]] 2192ba98753SSimon Glass test_name = args and args[0] or None 2202ba98753SSimon Glass for module in (TestFdt, TestNode, TestProp): 2212ba98753SSimon Glass if test_name: 2222ba98753SSimon Glass try: 2232ba98753SSimon Glass suite = unittest.TestLoader().loadTestsFromName(test_name, module) 2242ba98753SSimon Glass except AttributeError: 2252ba98753SSimon Glass continue 2262ba98753SSimon Glass else: 2272ba98753SSimon Glass suite = unittest.TestLoader().loadTestsFromTestCase(module) 2282ba98753SSimon Glass suite.run(result) 2292ba98753SSimon Glass 2302ba98753SSimon Glass print result 2312ba98753SSimon Glass for _, err in result.errors: 2322ba98753SSimon Glass print err 2332ba98753SSimon Glass for _, err in result.failures: 2342ba98753SSimon Glass print err 2352ba98753SSimon Glass 2362ba98753SSimon Glassif __name__ != '__main__': 2372ba98753SSimon Glass sys.exit(1) 2382ba98753SSimon Glass 2392ba98753SSimon Glassparser = OptionParser() 2402ba98753SSimon Glassparser.add_option('-t', '--test', action='store_true', dest='test', 2412ba98753SSimon Glass default=False, help='run tests') 2422ba98753SSimon Glass(options, args) = parser.parse_args() 2432ba98753SSimon Glass 2442ba98753SSimon Glass# Run our meagre tests 2452ba98753SSimon Glassif options.test: 2462ba98753SSimon Glass RunTests(args) 247