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
13 # Bring in the patman libraries
14 our_path = os.path.dirname(os.path.realpath(__file__))
15 for dirname in ['../patman', '..']:
16 sys.path.insert(0, os.path.join(our_path, dirname))
20 from fdt import TYPE_BYTE, TYPE_INT, TYPE_STRING, TYPE_BOOL
21 from fdt_util import fdt32_to_cpu
26 class TestFdt(unittest.TestCase):
27 """Tests for the Fdt module
29 This includes unit tests for some functions and functional tests for the fdt
34 tools.PrepareOutputDir(None)
37 def tearDownClass(cls):
38 tools._FinaliseForTest()
41 self.dtb = fdt.FdtScan('tools/dtoc/dtoc_test_simple.dts')
44 """Test that we can open an Fdt"""
46 root = self.dtb.GetRoot()
47 self.assertTrue(isinstance(root, fdt.Node))
49 def testGetNode(self):
50 """Test the GetNode() method"""
51 node = self.dtb.GetNode('/spl-test')
52 self.assertTrue(isinstance(node, fdt.Node))
53 node = self.dtb.GetNode('/i2c@0/pmic@9')
54 self.assertTrue(isinstance(node, fdt.Node))
55 self.assertEqual('pmic@9', node.name)
58 """Check that we can flush the device tree out to its file"""
59 fname = self.dtb._fname
60 with open(fname) as fd:
63 with self.assertRaises(IOError):
66 with open(fname) as fd:
70 """Test that packing a device tree works"""
74 """Tetst that we can access the raw device-tree data"""
75 self.assertTrue(isinstance(self.dtb.GetFdt(), bytearray))
77 def testGetProps(self):
78 """Tests obtaining a list of properties"""
79 node = self.dtb.GetNode('/spl-test')
80 props = self.dtb.GetProps(node)
81 self.assertEqual(['boolval', 'bytearray', 'byteval', 'compatible',
82 'intarray', 'intval', 'longbytearray',
83 'stringarray', 'stringval', 'u-boot,dm-pre-reloc'],
86 def testCheckError(self):
87 """Tests the ChecKError() function"""
88 with self.assertRaises(ValueError) as e:
89 self.dtb.CheckErr(-libfdt.NOTFOUND, 'hello')
90 self.assertIn('FDT_ERR_NOTFOUND: hello', str(e.exception))
93 class TestNode(unittest.TestCase):
94 """Test operation of the Node class"""
98 tools.PrepareOutputDir(None)
101 def tearDownClass(cls):
102 tools._FinaliseForTest()
105 self.dtb = fdt.FdtScan('tools/dtoc/dtoc_test_simple.dts')
106 self.node = self.dtb.GetNode('/spl-test')
108 def testOffset(self):
109 """Tests that we can obtain the offset of a node"""
110 self.assertTrue(self.node.Offset() > 0)
112 def testDelete(self):
113 """Tests that we can delete a property"""
114 node2 = self.dtb.GetNode('/spl-test2')
115 offset1 = node2.Offset()
116 self.node.DeleteProp('intval')
117 offset2 = node2.Offset()
118 self.assertTrue(offset2 < offset1)
119 self.node.DeleteProp('intarray')
120 offset3 = node2.Offset()
121 self.assertTrue(offset3 < offset2)
123 def testFindNode(self):
124 """Tests that we can find a node using the _FindNode() functoin"""
125 node = self.dtb.GetRoot()._FindNode('i2c@0')
126 self.assertEqual('i2c@0', node.name)
127 subnode = node._FindNode('pmic@9')
128 self.assertEqual('pmic@9', subnode.name)
131 class TestProp(unittest.TestCase):
132 """Test operation of the Prop class"""
136 tools.PrepareOutputDir(None)
139 def tearDownClass(cls):
140 tools._FinaliseForTest()
143 self.dtb = fdt.FdtScan('tools/dtoc/dtoc_test_simple.dts')
144 self.node = self.dtb.GetNode('/spl-test')
145 self.fdt = self.dtb.GetFdtObj()
147 def testGetEmpty(self):
148 """Tests the GetEmpty() function for the various supported types"""
149 self.assertEqual(True, fdt.Prop.GetEmpty(fdt.TYPE_BOOL))
150 self.assertEqual(chr(0), fdt.Prop.GetEmpty(fdt.TYPE_BYTE))
151 self.assertEqual(chr(0) * 4, fdt.Prop.GetEmpty(fdt.TYPE_INT))
152 self.assertEqual('', fdt.Prop.GetEmpty(fdt.TYPE_STRING))
154 def testGetOffset(self):
155 """Test we can get the offset of a property"""
156 prop = self.node.props['longbytearray']
158 # Add 12, which is sizeof(struct fdt_property), to get to start of data
159 offset = prop.GetOffset() + 12
160 data = self.dtb._fdt[offset:offset + len(prop.value)]
161 bytes = [chr(x) for x in data]
162 self.assertEqual(bytes, prop.value)
165 """Test widening of values"""
166 node2 = self.dtb.GetNode('/spl-test2')
167 prop = self.node.props['intval']
170 prop2 = node2.props['intval']
172 self.assertEqual(fdt.TYPE_INT, prop.type)
173 self.assertEqual(1, fdt32_to_cpu(prop.value))
175 # Convert singla value to array
176 prop2 = self.node.props['intarray']
178 self.assertEqual(fdt.TYPE_INT, prop.type)
179 self.assertTrue(isinstance(prop.value, list))
181 # A 4-byte array looks like a single integer. When widened by a longer
182 # byte array, it should turn into an array.
183 prop = self.node.props['longbytearray']
184 prop2 = node2.props['longbytearray']
185 self.assertFalse(isinstance(prop2.value, list))
186 self.assertEqual(4, len(prop2.value))
188 self.assertTrue(isinstance(prop2.value, list))
189 self.assertEqual(9, len(prop2.value))
191 # Similarly for a string array
192 prop = self.node.props['stringval']
193 prop2 = node2.props['stringarray']
194 self.assertFalse(isinstance(prop.value, list))
195 self.assertEqual(7, len(prop.value))
197 self.assertTrue(isinstance(prop.value, list))
198 self.assertEqual(3, len(prop.value))
200 # Enlarging an existing array
201 prop = self.node.props['stringarray']
202 prop2 = node2.props['stringarray']
203 self.assertTrue(isinstance(prop.value, list))
204 self.assertEqual(2, len(prop.value))
206 self.assertTrue(isinstance(prop.value, list))
207 self.assertEqual(3, len(prop.value))
211 """Run all the test we have for the fdt model
214 args: List of positional args provided to fdt. This can hold a test
215 name to execute (as in 'fdt -t testFdt', for example)
217 result = unittest.TestResult()
218 sys.argv = [sys.argv[0]]
219 test_name = args and args[0] or None
220 for module in (TestFdt, TestNode, TestProp):
223 suite = unittest.TestLoader().loadTestsFromName(test_name, module)
224 except AttributeError:
227 suite = unittest.TestLoader().loadTestsFromTestCase(module)
231 for _, err in result.errors:
233 for _, err in result.failures:
236 if __name__ != '__main__':
239 parser = OptionParser()
240 parser.add_option('-t', '--test', action='store_true', dest='test',
241 default=False, help='run tests')
242 (options, args) = parser.parse_args()
244 # Run our meagre tests