123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246 |
- #!/usr/bin/python
- # SPDX-License-Identifier: GPL-2.0+
- # Copyright (c) 2018 Google, Inc
- # Written by Simon Glass <sjg@chromium.org>
- #
- from optparse import OptionParser
- import glob
- import os
- import sys
- import unittest
- # Bring in the patman libraries
- our_path = os.path.dirname(os.path.realpath(__file__))
- for dirname in ['../patman', '..']:
- sys.path.insert(0, os.path.join(our_path, dirname))
- import command
- import fdt
- from fdt import TYPE_BYTE, TYPE_INT, TYPE_STRING, TYPE_BOOL
- from fdt_util import fdt32_to_cpu
- import libfdt
- import test_util
- import tools
- class TestFdt(unittest.TestCase):
- """Tests for the Fdt module
- This includes unit tests for some functions and functional tests for the fdt
- module.
- """
- @classmethod
- def setUpClass(cls):
- tools.PrepareOutputDir(None)
- @classmethod
- def tearDownClass(cls):
- tools._FinaliseForTest()
- def setUp(self):
- self.dtb = fdt.FdtScan('tools/dtoc/dtoc_test_simple.dts')
- def testFdt(self):
- """Test that we can open an Fdt"""
- self.dtb.Scan()
- root = self.dtb.GetRoot()
- self.assertTrue(isinstance(root, fdt.Node))
- def testGetNode(self):
- """Test the GetNode() method"""
- node = self.dtb.GetNode('/spl-test')
- self.assertTrue(isinstance(node, fdt.Node))
- node = self.dtb.GetNode('/i2c@0/pmic@9')
- self.assertTrue(isinstance(node, fdt.Node))
- self.assertEqual('pmic@9', node.name)
- def testFlush(self):
- """Check that we can flush the device tree out to its file"""
- fname = self.dtb._fname
- with open(fname) as fd:
- data = fd.read()
- os.remove(fname)
- with self.assertRaises(IOError):
- open(fname)
- self.dtb.Flush()
- with open(fname) as fd:
- data = fd.read()
- def testPack(self):
- """Test that packing a device tree works"""
- self.dtb.Pack()
- def testGetFdt(self):
- """Tetst that we can access the raw device-tree data"""
- self.assertTrue(isinstance(self.dtb.GetFdt(), bytearray))
- def testGetProps(self):
- """Tests obtaining a list of properties"""
- node = self.dtb.GetNode('/spl-test')
- props = self.dtb.GetProps(node)
- self.assertEqual(['boolval', 'bytearray', 'byteval', 'compatible',
- 'intarray', 'intval', 'longbytearray',
- 'stringarray', 'stringval', 'u-boot,dm-pre-reloc'],
- sorted(props.keys()))
- def testCheckError(self):
- """Tests the ChecKError() function"""
- with self.assertRaises(ValueError) as e:
- self.dtb.CheckErr(-libfdt.NOTFOUND, 'hello')
- self.assertIn('FDT_ERR_NOTFOUND: hello', str(e.exception))
- class TestNode(unittest.TestCase):
- """Test operation of the Node class"""
- @classmethod
- def setUpClass(cls):
- tools.PrepareOutputDir(None)
- @classmethod
- def tearDownClass(cls):
- tools._FinaliseForTest()
- def setUp(self):
- self.dtb = fdt.FdtScan('tools/dtoc/dtoc_test_simple.dts')
- self.node = self.dtb.GetNode('/spl-test')
- def testOffset(self):
- """Tests that we can obtain the offset of a node"""
- self.assertTrue(self.node.Offset() > 0)
- def testDelete(self):
- """Tests that we can delete a property"""
- node2 = self.dtb.GetNode('/spl-test2')
- offset1 = node2.Offset()
- self.node.DeleteProp('intval')
- offset2 = node2.Offset()
- self.assertTrue(offset2 < offset1)
- self.node.DeleteProp('intarray')
- offset3 = node2.Offset()
- self.assertTrue(offset3 < offset2)
- def testFindNode(self):
- """Tests that we can find a node using the _FindNode() functoin"""
- node = self.dtb.GetRoot()._FindNode('i2c@0')
- self.assertEqual('i2c@0', node.name)
- subnode = node._FindNode('pmic@9')
- self.assertEqual('pmic@9', subnode.name)
- class TestProp(unittest.TestCase):
- """Test operation of the Prop class"""
- @classmethod
- def setUpClass(cls):
- tools.PrepareOutputDir(None)
- @classmethod
- def tearDownClass(cls):
- tools._FinaliseForTest()
- def setUp(self):
- self.dtb = fdt.FdtScan('tools/dtoc/dtoc_test_simple.dts')
- self.node = self.dtb.GetNode('/spl-test')
- self.fdt = self.dtb.GetFdtObj()
- def testGetEmpty(self):
- """Tests the GetEmpty() function for the various supported types"""
- self.assertEqual(True, fdt.Prop.GetEmpty(fdt.TYPE_BOOL))
- self.assertEqual(chr(0), fdt.Prop.GetEmpty(fdt.TYPE_BYTE))
- self.assertEqual(chr(0) * 4, fdt.Prop.GetEmpty(fdt.TYPE_INT))
- self.assertEqual('', fdt.Prop.GetEmpty(fdt.TYPE_STRING))
- def testGetOffset(self):
- """Test we can get the offset of a property"""
- prop = self.node.props['longbytearray']
- # Add 12, which is sizeof(struct fdt_property), to get to start of data
- offset = prop.GetOffset() + 12
- data = self.dtb._fdt[offset:offset + len(prop.value)]
- bytes = [chr(x) for x in data]
- self.assertEqual(bytes, prop.value)
- def testWiden(self):
- """Test widening of values"""
- node2 = self.dtb.GetNode('/spl-test2')
- prop = self.node.props['intval']
- # No action
- prop2 = node2.props['intval']
- prop.Widen(prop2)
- self.assertEqual(fdt.TYPE_INT, prop.type)
- self.assertEqual(1, fdt32_to_cpu(prop.value))
- # Convert singla value to array
- prop2 = self.node.props['intarray']
- prop.Widen(prop2)
- self.assertEqual(fdt.TYPE_INT, prop.type)
- self.assertTrue(isinstance(prop.value, list))
- # A 4-byte array looks like a single integer. When widened by a longer
- # byte array, it should turn into an array.
- prop = self.node.props['longbytearray']
- prop2 = node2.props['longbytearray']
- self.assertFalse(isinstance(prop2.value, list))
- self.assertEqual(4, len(prop2.value))
- prop2.Widen(prop)
- self.assertTrue(isinstance(prop2.value, list))
- self.assertEqual(9, len(prop2.value))
- # Similarly for a string array
- prop = self.node.props['stringval']
- prop2 = node2.props['stringarray']
- self.assertFalse(isinstance(prop.value, list))
- self.assertEqual(7, len(prop.value))
- prop.Widen(prop2)
- self.assertTrue(isinstance(prop.value, list))
- self.assertEqual(3, len(prop.value))
- # Enlarging an existing array
- prop = self.node.props['stringarray']
- prop2 = node2.props['stringarray']
- self.assertTrue(isinstance(prop.value, list))
- self.assertEqual(2, len(prop.value))
- prop.Widen(prop2)
- self.assertTrue(isinstance(prop.value, list))
- self.assertEqual(3, len(prop.value))
- def RunTests(args):
- """Run all the test we have for the fdt model
- Args:
- args: List of positional args provided to fdt. This can hold a test
- name to execute (as in 'fdt -t testFdt', for example)
- """
- result = unittest.TestResult()
- sys.argv = [sys.argv[0]]
- test_name = args and args[0] or None
- for module in (TestFdt, TestNode, TestProp):
- if test_name:
- try:
- suite = unittest.TestLoader().loadTestsFromName(test_name, module)
- except AttributeError:
- continue
- else:
- suite = unittest.TestLoader().loadTestsFromTestCase(module)
- suite.run(result)
- print result
- for _, err in result.errors:
- print err
- for _, err in result.failures:
- print err
- if __name__ != '__main__':
- sys.exit(1)
- parser = OptionParser()
- parser.add_option('-t', '--test', action='store_true', dest='test',
- default=False, help='run tests')
- (options, args) = parser.parse_args()
- # Run our meagre tests
- if options.test:
- RunTests(args)
|