blob: 2d1d7dc452ccee858d51acf1dee4adf5a85cd3ee [file] [log] [blame]
Simon Glass0ed50752018-07-06 10:27:24 -06001#!/usr/bin/python
2# SPDX-License-Identifier: GPL-2.0+
3# Copyright (c) 2018 Google, Inc
4# Written by Simon Glass <sjg@chromium.org>
5#
6
Simon Glass61b88e52019-05-17 22:00:31 -06007from __future__ import print_function
8
Simon Glass0ed50752018-07-06 10:27:24 -06009from optparse import OptionParser
10import glob
11import os
12import sys
13import unittest
14
15# Bring in the patman libraries
16our_path = os.path.dirname(os.path.realpath(__file__))
17for dirname in ['../patman', '..']:
18 sys.path.insert(0, os.path.join(our_path, dirname))
19
20import command
21import fdt
22from fdt import TYPE_BYTE, TYPE_INT, TYPE_STRING, TYPE_BOOL
Simon Glass9c526332018-07-06 10:27:28 -060023import fdt_util
Simon Glass0ed50752018-07-06 10:27:24 -060024from fdt_util import fdt32_to_cpu
25import libfdt
26import test_util
27import tools
28
Simon Glass4df8a0c2018-07-06 10:27:29 -060029def _GetPropertyValue(dtb, node, prop_name):
30 """Low-level function to get the property value based on its offset
31
32 This looks directly in the device tree at the property's offset to find
33 its value. It is useful as a check that the property is in the correct
34 place.
35
36 Args:
37 node: Node to look in
38 prop_name: Property name to find
39
40 Returns:
41 Tuple:
42 Prop object found
43 Value of property as a string (found using property offset)
44 """
45 prop = node.props[prop_name]
46
47 # Add 12, which is sizeof(struct fdt_property), to get to start of data
48 offset = prop.GetOffset() + 12
49 data = dtb.GetContents()[offset:offset + len(prop.value)]
50 return prop, [chr(x) for x in data]
51
52
Simon Glass0ed50752018-07-06 10:27:24 -060053class TestFdt(unittest.TestCase):
54 """Tests for the Fdt module
55
56 This includes unit tests for some functions and functional tests for the fdt
57 module.
58 """
59 @classmethod
60 def setUpClass(cls):
61 tools.PrepareOutputDir(None)
62
63 @classmethod
64 def tearDownClass(cls):
Simon Glass752e7552018-10-01 21:12:41 -060065 tools.FinaliseOutputDir()
Simon Glass0ed50752018-07-06 10:27:24 -060066
67 def setUp(self):
68 self.dtb = fdt.FdtScan('tools/dtoc/dtoc_test_simple.dts')
69
70 def testFdt(self):
71 """Test that we can open an Fdt"""
72 self.dtb.Scan()
73 root = self.dtb.GetRoot()
74 self.assertTrue(isinstance(root, fdt.Node))
75
76 def testGetNode(self):
77 """Test the GetNode() method"""
78 node = self.dtb.GetNode('/spl-test')
79 self.assertTrue(isinstance(node, fdt.Node))
80 node = self.dtb.GetNode('/i2c@0/pmic@9')
81 self.assertTrue(isinstance(node, fdt.Node))
82 self.assertEqual('pmic@9', node.name)
Simon Glass9c526332018-07-06 10:27:28 -060083 self.assertIsNone(self.dtb.GetNode('/i2c@0/pmic@9/missing'))
Simon Glass0ed50752018-07-06 10:27:24 -060084
85 def testFlush(self):
86 """Check that we can flush the device tree out to its file"""
87 fname = self.dtb._fname
88 with open(fname) as fd:
89 data = fd.read()
90 os.remove(fname)
91 with self.assertRaises(IOError):
92 open(fname)
93 self.dtb.Flush()
94 with open(fname) as fd:
95 data = fd.read()
96
97 def testPack(self):
98 """Test that packing a device tree works"""
99 self.dtb.Pack()
100
101 def testGetFdt(self):
102 """Tetst that we can access the raw device-tree data"""
Simon Glass792d2392018-07-06 10:27:27 -0600103 self.assertTrue(isinstance(self.dtb.GetContents(), bytearray))
Simon Glass0ed50752018-07-06 10:27:24 -0600104
105 def testGetProps(self):
106 """Tests obtaining a list of properties"""
107 node = self.dtb.GetNode('/spl-test')
108 props = self.dtb.GetProps(node)
109 self.assertEqual(['boolval', 'bytearray', 'byteval', 'compatible',
Simon Glass9c526332018-07-06 10:27:28 -0600110 'intarray', 'intval', 'longbytearray', 'notstring',
Simon Glass0ed50752018-07-06 10:27:24 -0600111 'stringarray', 'stringval', 'u-boot,dm-pre-reloc'],
112 sorted(props.keys()))
113
114 def testCheckError(self):
115 """Tests the ChecKError() function"""
116 with self.assertRaises(ValueError) as e:
Simon Glass9c526332018-07-06 10:27:28 -0600117 fdt.CheckErr(-libfdt.NOTFOUND, 'hello')
Simon Glass0ed50752018-07-06 10:27:24 -0600118 self.assertIn('FDT_ERR_NOTFOUND: hello', str(e.exception))
119
Simon Glasse2d65282018-07-17 13:25:46 -0600120 def testGetFdt(self):
121 node = self.dtb.GetNode('/spl-test')
122 self.assertEqual(self.dtb, node.GetFdt())
Simon Glass0ed50752018-07-06 10:27:24 -0600123
124class TestNode(unittest.TestCase):
125 """Test operation of the Node class"""
126
127 @classmethod
128 def setUpClass(cls):
129 tools.PrepareOutputDir(None)
130
131 @classmethod
132 def tearDownClass(cls):
Simon Glass752e7552018-10-01 21:12:41 -0600133 tools.FinaliseOutputDir()
Simon Glass0ed50752018-07-06 10:27:24 -0600134
135 def setUp(self):
136 self.dtb = fdt.FdtScan('tools/dtoc/dtoc_test_simple.dts')
137 self.node = self.dtb.GetNode('/spl-test')
138
139 def testOffset(self):
140 """Tests that we can obtain the offset of a node"""
141 self.assertTrue(self.node.Offset() > 0)
142
143 def testDelete(self):
144 """Tests that we can delete a property"""
145 node2 = self.dtb.GetNode('/spl-test2')
146 offset1 = node2.Offset()
147 self.node.DeleteProp('intval')
148 offset2 = node2.Offset()
149 self.assertTrue(offset2 < offset1)
150 self.node.DeleteProp('intarray')
151 offset3 = node2.Offset()
152 self.assertTrue(offset3 < offset2)
Simon Glass9c526332018-07-06 10:27:28 -0600153 with self.assertRaises(libfdt.FdtException):
154 self.node.DeleteProp('missing')
Simon Glass0ed50752018-07-06 10:27:24 -0600155
Simon Glass4df8a0c2018-07-06 10:27:29 -0600156 def testDeleteGetOffset(self):
157 """Test that property offset update when properties are deleted"""
158 self.node.DeleteProp('intval')
159 prop, value = _GetPropertyValue(self.dtb, self.node, 'longbytearray')
160 self.assertEqual(prop.value, value)
161
Simon Glass0ed50752018-07-06 10:27:24 -0600162 def testFindNode(self):
Simon Glassaa1a5d72018-07-17 13:25:41 -0600163 """Tests that we can find a node using the FindNode() functoin"""
164 node = self.dtb.GetRoot().FindNode('i2c@0')
Simon Glass0ed50752018-07-06 10:27:24 -0600165 self.assertEqual('i2c@0', node.name)
Simon Glassaa1a5d72018-07-17 13:25:41 -0600166 subnode = node.FindNode('pmic@9')
Simon Glass0ed50752018-07-06 10:27:24 -0600167 self.assertEqual('pmic@9', subnode.name)
Simon Glassaa1a5d72018-07-17 13:25:41 -0600168 self.assertEqual(None, node.FindNode('missing'))
Simon Glass0ed50752018-07-06 10:27:24 -0600169
Simon Glass4df8a0c2018-07-06 10:27:29 -0600170 def testRefreshMissingNode(self):
171 """Test refreshing offsets when an extra node is present in dtb"""
172 # Delete it from our tables, not the device tree
173 del self.dtb._root.subnodes[-1]
174 with self.assertRaises(ValueError) as e:
175 self.dtb.Refresh()
176 self.assertIn('Internal error, offset', str(e.exception))
177
178 def testRefreshExtraNode(self):
179 """Test refreshing offsets when an expected node is missing"""
180 # Delete it from the device tre, not our tables
181 self.dtb.GetFdtObj().del_node(self.node.Offset())
182 with self.assertRaises(ValueError) as e:
183 self.dtb.Refresh()
184 self.assertIn('Internal error, node name mismatch '
185 'spl-test != spl-test2', str(e.exception))
186
187 def testRefreshMissingProp(self):
188 """Test refreshing offsets when an extra property is present in dtb"""
189 # Delete it from our tables, not the device tree
190 del self.node.props['notstring']
191 with self.assertRaises(ValueError) as e:
192 self.dtb.Refresh()
193 self.assertIn("Internal error, property 'notstring' missing, offset ",
194 str(e.exception))
195
Simon Glasse2d65282018-07-17 13:25:46 -0600196 def testLookupPhandle(self):
197 """Test looking up a single phandle"""
198 dtb = fdt.FdtScan('tools/dtoc/dtoc_test_phandle.dts')
199 node = dtb.GetNode('/phandle-source2')
200 prop = node.props['clocks']
201 target = dtb.GetNode('/phandle-target')
202 self.assertEqual(target, dtb.LookupPhandle(fdt32_to_cpu(prop.value)))
203
Simon Glass0ed50752018-07-06 10:27:24 -0600204
205class TestProp(unittest.TestCase):
206 """Test operation of the Prop class"""
207
208 @classmethod
209 def setUpClass(cls):
210 tools.PrepareOutputDir(None)
211
212 @classmethod
213 def tearDownClass(cls):
Simon Glass752e7552018-10-01 21:12:41 -0600214 tools.FinaliseOutputDir()
Simon Glass0ed50752018-07-06 10:27:24 -0600215
216 def setUp(self):
217 self.dtb = fdt.FdtScan('tools/dtoc/dtoc_test_simple.dts')
218 self.node = self.dtb.GetNode('/spl-test')
219 self.fdt = self.dtb.GetFdtObj()
220
Simon Glassc5eddc82018-07-06 10:27:30 -0600221 def testMissingNode(self):
222 self.assertEqual(None, self.dtb.GetNode('missing'))
223
Simon Glass9c526332018-07-06 10:27:28 -0600224 def testPhandle(self):
225 dtb = fdt.FdtScan('tools/dtoc/dtoc_test_phandle.dts')
Simon Glass609e2b12018-07-06 10:27:31 -0600226 node = dtb.GetNode('/phandle-source2')
227 prop = node.props['clocks']
228 self.assertTrue(fdt32_to_cpu(prop.value) > 0)
Simon Glass9c526332018-07-06 10:27:28 -0600229
230 def _ConvertProp(self, prop_name):
231 """Helper function to look up a property in self.node and return it
232
233 Args:
234 Property name to find
235
236 Return fdt.Prop object for this property
237 """
Simon Glassb474c762018-07-26 14:02:13 -0600238 p = self.fdt.getprop(self.node.Offset(), prop_name)
Simon Glass9c526332018-07-06 10:27:28 -0600239 return fdt.Prop(self.node, -1, prop_name, p)
240
241 def testMakeProp(self):
242 """Test we can convert all the the types that are supported"""
243 prop = self._ConvertProp('boolval')
244 self.assertEqual(fdt.TYPE_BOOL, prop.type)
245 self.assertEqual(True, prop.value)
246
247 prop = self._ConvertProp('intval')
248 self.assertEqual(fdt.TYPE_INT, prop.type)
249 self.assertEqual(1, fdt32_to_cpu(prop.value))
250
251 prop = self._ConvertProp('intarray')
252 self.assertEqual(fdt.TYPE_INT, prop.type)
253 val = [fdt32_to_cpu(val) for val in prop.value]
254 self.assertEqual([2, 3, 4], val)
255
256 prop = self._ConvertProp('byteval')
257 self.assertEqual(fdt.TYPE_BYTE, prop.type)
258 self.assertEqual(5, ord(prop.value))
259
260 prop = self._ConvertProp('longbytearray')
261 self.assertEqual(fdt.TYPE_BYTE, prop.type)
262 val = [ord(val) for val in prop.value]
263 self.assertEqual([9, 10, 11, 12, 13, 14, 15, 16, 17], val)
264
265 prop = self._ConvertProp('stringval')
266 self.assertEqual(fdt.TYPE_STRING, prop.type)
267 self.assertEqual('message', prop.value)
268
269 prop = self._ConvertProp('stringarray')
270 self.assertEqual(fdt.TYPE_STRING, prop.type)
271 self.assertEqual(['multi-word', 'message'], prop.value)
272
273 prop = self._ConvertProp('notstring')
274 self.assertEqual(fdt.TYPE_BYTE, prop.type)
275 val = [ord(val) for val in prop.value]
276 self.assertEqual([0x20, 0x21, 0x22, 0x10, 0], val)
277
Simon Glass0ed50752018-07-06 10:27:24 -0600278 def testGetEmpty(self):
279 """Tests the GetEmpty() function for the various supported types"""
280 self.assertEqual(True, fdt.Prop.GetEmpty(fdt.TYPE_BOOL))
281 self.assertEqual(chr(0), fdt.Prop.GetEmpty(fdt.TYPE_BYTE))
282 self.assertEqual(chr(0) * 4, fdt.Prop.GetEmpty(fdt.TYPE_INT))
283 self.assertEqual('', fdt.Prop.GetEmpty(fdt.TYPE_STRING))
284
285 def testGetOffset(self):
286 """Test we can get the offset of a property"""
Simon Glass4df8a0c2018-07-06 10:27:29 -0600287 prop, value = _GetPropertyValue(self.dtb, self.node, 'longbytearray')
288 self.assertEqual(prop.value, value)
Simon Glass0ed50752018-07-06 10:27:24 -0600289
290 def testWiden(self):
291 """Test widening of values"""
292 node2 = self.dtb.GetNode('/spl-test2')
293 prop = self.node.props['intval']
294
295 # No action
296 prop2 = node2.props['intval']
297 prop.Widen(prop2)
298 self.assertEqual(fdt.TYPE_INT, prop.type)
299 self.assertEqual(1, fdt32_to_cpu(prop.value))
300
301 # Convert singla value to array
302 prop2 = self.node.props['intarray']
303 prop.Widen(prop2)
304 self.assertEqual(fdt.TYPE_INT, prop.type)
305 self.assertTrue(isinstance(prop.value, list))
306
307 # A 4-byte array looks like a single integer. When widened by a longer
308 # byte array, it should turn into an array.
309 prop = self.node.props['longbytearray']
310 prop2 = node2.props['longbytearray']
311 self.assertFalse(isinstance(prop2.value, list))
312 self.assertEqual(4, len(prop2.value))
313 prop2.Widen(prop)
314 self.assertTrue(isinstance(prop2.value, list))
315 self.assertEqual(9, len(prop2.value))
316
317 # Similarly for a string array
318 prop = self.node.props['stringval']
319 prop2 = node2.props['stringarray']
320 self.assertFalse(isinstance(prop.value, list))
321 self.assertEqual(7, len(prop.value))
322 prop.Widen(prop2)
323 self.assertTrue(isinstance(prop.value, list))
324 self.assertEqual(3, len(prop.value))
325
326 # Enlarging an existing array
327 prop = self.node.props['stringarray']
328 prop2 = node2.props['stringarray']
329 self.assertTrue(isinstance(prop.value, list))
330 self.assertEqual(2, len(prop.value))
331 prop.Widen(prop2)
332 self.assertTrue(isinstance(prop.value, list))
333 self.assertEqual(3, len(prop.value))
334
Simon Glasse80c5562018-07-06 10:27:38 -0600335 def testAdd(self):
336 """Test adding properties"""
337 self.fdt.pack()
338 # This function should automatically expand the device tree
339 self.node.AddZeroProp('one')
340 self.node.AddZeroProp('two')
341 self.node.AddZeroProp('three')
Simon Glasseddd7292018-09-14 04:57:13 -0600342 self.dtb.Sync(auto_resize=True)
Simon Glasse80c5562018-07-06 10:27:38 -0600343
344 # Updating existing properties should be OK, since the device-tree size
345 # does not change
346 self.fdt.pack()
347 self.node.SetInt('one', 1)
348 self.node.SetInt('two', 2)
349 self.node.SetInt('three', 3)
Simon Glasseddd7292018-09-14 04:57:13 -0600350 self.dtb.Sync(auto_resize=False)
Simon Glasse80c5562018-07-06 10:27:38 -0600351
352 # This should fail since it would need to increase the device-tree size
Simon Glasseddd7292018-09-14 04:57:13 -0600353 self.node.AddZeroProp('four')
Simon Glasse80c5562018-07-06 10:27:38 -0600354 with self.assertRaises(libfdt.FdtException) as e:
Simon Glasseddd7292018-09-14 04:57:13 -0600355 self.dtb.Sync(auto_resize=False)
Simon Glasse80c5562018-07-06 10:27:38 -0600356 self.assertIn('FDT_ERR_NOSPACE', str(e.exception))
Simon Glassccd25262018-09-14 04:57:16 -0600357 self.dtb.Sync(auto_resize=True)
Simon Glasse80c5562018-07-06 10:27:38 -0600358
Simon Glasseddd7292018-09-14 04:57:13 -0600359 def testAddNode(self):
360 self.fdt.pack()
Simon Glassf3a17962018-09-14 04:57:15 -0600361 self.node.AddSubnode('subnode')
362 with self.assertRaises(libfdt.FdtException) as e:
363 self.dtb.Sync(auto_resize=False)
364 self.assertIn('FDT_ERR_NOSPACE', str(e.exception))
365
366 self.dtb.Sync(auto_resize=True)
367 offset = self.fdt.path_offset('/spl-test/subnode')
368 self.assertTrue(offset > 0)
Simon Glasseddd7292018-09-14 04:57:13 -0600369
Simon Glassccd25262018-09-14 04:57:16 -0600370 def testAddMore(self):
371 """Test various other methods for adding and setting properties"""
372 self.node.AddZeroProp('one')
373 self.dtb.Sync(auto_resize=True)
374 data = self.fdt.getprop(self.node.Offset(), 'one')
375 self.assertEqual(0, fdt32_to_cpu(data))
376
377 self.node.SetInt('one', 1)
378 self.dtb.Sync(auto_resize=False)
379 data = self.fdt.getprop(self.node.Offset(), 'one')
380 self.assertEqual(1, fdt32_to_cpu(data))
381
382 val = '123' + chr(0) + '456'
383 self.node.AddString('string', val)
384 self.dtb.Sync(auto_resize=True)
385 data = self.fdt.getprop(self.node.Offset(), 'string')
386 self.assertEqual(val + '\0', data)
387
388 self.fdt.pack()
389 self.node.SetString('string', val + 'x')
390 with self.assertRaises(libfdt.FdtException) as e:
391 self.dtb.Sync(auto_resize=False)
392 self.assertIn('FDT_ERR_NOSPACE', str(e.exception))
393 self.node.SetString('string', val[:-1])
394
395 prop = self.node.props['string']
396 prop.SetData(val)
397 self.dtb.Sync(auto_resize=False)
398 data = self.fdt.getprop(self.node.Offset(), 'string')
399 self.assertEqual(val, data)
400
401 self.node.AddEmptyProp('empty', 5)
402 self.dtb.Sync(auto_resize=True)
403 prop = self.node.props['empty']
404 prop.SetData(val)
405 self.dtb.Sync(auto_resize=False)
406 data = self.fdt.getprop(self.node.Offset(), 'empty')
407 self.assertEqual(val, data)
408
409 self.node.SetData('empty', '123')
410 self.assertEqual('123', prop.bytes)
411
Simon Glassb8a49292018-09-14 04:57:17 -0600412 def testFromData(self):
413 dtb2 = fdt.Fdt.FromData(self.dtb.GetContents())
414 self.assertEqual(dtb2.GetContents(), self.dtb.GetContents())
415
416 self.node.AddEmptyProp('empty', 5)
417 self.dtb.Sync(auto_resize=True)
418 self.assertTrue(dtb2.GetContents() != self.dtb.GetContents())
419
Simon Glass0ed50752018-07-06 10:27:24 -0600420
Simon Glass9c526332018-07-06 10:27:28 -0600421class TestFdtUtil(unittest.TestCase):
422 """Tests for the fdt_util module
423
424 This module will likely be mostly replaced at some point, once upstream
425 libfdt has better Python support. For now, this provides tests for current
426 functionality.
427 """
428 @classmethod
429 def setUpClass(cls):
430 tools.PrepareOutputDir(None)
431
Simon Glass752e7552018-10-01 21:12:41 -0600432 @classmethod
433 def tearDownClass(cls):
434 tools.FinaliseOutputDir()
435
Simon Glass9c526332018-07-06 10:27:28 -0600436 def setUp(self):
437 self.dtb = fdt.FdtScan('tools/dtoc/dtoc_test_simple.dts')
438 self.node = self.dtb.GetNode('/spl-test')
439
440 def testGetInt(self):
441 self.assertEqual(1, fdt_util.GetInt(self.node, 'intval'))
442 self.assertEqual(3, fdt_util.GetInt(self.node, 'missing', 3))
443
444 with self.assertRaises(ValueError) as e:
445 self.assertEqual(3, fdt_util.GetInt(self.node, 'intarray'))
446 self.assertIn("property 'intarray' has list value: expecting a single "
447 'integer', str(e.exception))
448
449 def testGetString(self):
450 self.assertEqual('message', fdt_util.GetString(self.node, 'stringval'))
451 self.assertEqual('test', fdt_util.GetString(self.node, 'missing',
452 'test'))
453
454 with self.assertRaises(ValueError) as e:
455 self.assertEqual(3, fdt_util.GetString(self.node, 'stringarray'))
456 self.assertIn("property 'stringarray' has list value: expecting a "
457 'single string', str(e.exception))
458
459 def testGetBool(self):
460 self.assertEqual(True, fdt_util.GetBool(self.node, 'boolval'))
461 self.assertEqual(False, fdt_util.GetBool(self.node, 'missing'))
462 self.assertEqual(True, fdt_util.GetBool(self.node, 'missing', True))
463 self.assertEqual(False, fdt_util.GetBool(self.node, 'missing', False))
464
Simon Glass53f53992018-07-17 13:25:40 -0600465 def testGetByte(self):
466 self.assertEqual(5, fdt_util.GetByte(self.node, 'byteval'))
467 self.assertEqual(3, fdt_util.GetByte(self.node, 'missing', 3))
468
469 with self.assertRaises(ValueError) as e:
470 fdt_util.GetByte(self.node, 'longbytearray')
471 self.assertIn("property 'longbytearray' has list value: expecting a "
472 'single byte', str(e.exception))
473
474 with self.assertRaises(ValueError) as e:
475 fdt_util.GetByte(self.node, 'intval')
476 self.assertIn("property 'intval' has length 4, expecting 1",
477 str(e.exception))
478
Simon Glasse2d65282018-07-17 13:25:46 -0600479 def testGetPhandleList(self):
480 dtb = fdt.FdtScan('tools/dtoc/dtoc_test_phandle.dts')
481 node = dtb.GetNode('/phandle-source2')
482 self.assertEqual([1], fdt_util.GetPhandleList(node, 'clocks'))
483 node = dtb.GetNode('/phandle-source')
484 self.assertEqual([1, 2, 11, 3, 12, 13, 1],
485 fdt_util.GetPhandleList(node, 'clocks'))
486 self.assertEqual(None, fdt_util.GetPhandleList(node, 'missing'))
487
Simon Glass91710b32018-07-17 13:25:32 -0600488 def testGetDataType(self):
489 self.assertEqual(1, fdt_util.GetDatatype(self.node, 'intval', int))
490 self.assertEqual('message', fdt_util.GetDatatype(self.node, 'stringval',
491 str))
492 with self.assertRaises(ValueError) as e:
493 self.assertEqual(3, fdt_util.GetDatatype(self.node, 'boolval',
494 bool))
Simon Glass9c526332018-07-06 10:27:28 -0600495 def testFdtCellsToCpu(self):
496 val = self.node.props['intarray'].value
497 self.assertEqual(0, fdt_util.fdt_cells_to_cpu(val, 0))
498 self.assertEqual(2, fdt_util.fdt_cells_to_cpu(val, 1))
499
500 dtb2 = fdt.FdtScan('tools/dtoc/dtoc_test_addr64.dts')
501 node2 = dtb2.GetNode('/test1')
502 val = node2.props['reg'].value
503 self.assertEqual(0x1234, fdt_util.fdt_cells_to_cpu(val, 2))
504
505 def testEnsureCompiled(self):
506 """Test a degenerate case of this function"""
507 dtb = fdt_util.EnsureCompiled('tools/dtoc/dtoc_test_simple.dts')
508 self.assertEqual(dtb, fdt_util.EnsureCompiled(dtb))
509
510 def testGetPlainBytes(self):
511 self.assertEqual('fred', fdt_util.get_plain_bytes('fred'))
512
513
514def RunTestCoverage():
515 """Run the tests and check that we get 100% coverage"""
516 test_util.RunTestCoverage('tools/dtoc/test_fdt.py', None,
517 ['tools/patman/*.py', '*test_fdt.py'], options.build_dir)
518
519
Simon Glass0ed50752018-07-06 10:27:24 -0600520def RunTests(args):
521 """Run all the test we have for the fdt model
522
523 Args:
524 args: List of positional args provided to fdt. This can hold a test
525 name to execute (as in 'fdt -t testFdt', for example)
526 """
527 result = unittest.TestResult()
528 sys.argv = [sys.argv[0]]
529 test_name = args and args[0] or None
Simon Glass9c526332018-07-06 10:27:28 -0600530 for module in (TestFdt, TestNode, TestProp, TestFdtUtil):
Simon Glass0ed50752018-07-06 10:27:24 -0600531 if test_name:
532 try:
533 suite = unittest.TestLoader().loadTestsFromName(test_name, module)
534 except AttributeError:
535 continue
536 else:
537 suite = unittest.TestLoader().loadTestsFromTestCase(module)
538 suite.run(result)
539
Simon Glass61b88e52019-05-17 22:00:31 -0600540 print(result)
Simon Glass0ed50752018-07-06 10:27:24 -0600541 for _, err in result.errors:
Simon Glass61b88e52019-05-17 22:00:31 -0600542 print(err)
Simon Glass0ed50752018-07-06 10:27:24 -0600543 for _, err in result.failures:
Simon Glass61b88e52019-05-17 22:00:31 -0600544 print(err)
Simon Glass0ed50752018-07-06 10:27:24 -0600545
546if __name__ != '__main__':
547 sys.exit(1)
548
549parser = OptionParser()
Simon Glass9c526332018-07-06 10:27:28 -0600550parser.add_option('-B', '--build-dir', type='string', default='b',
551 help='Directory containing the build output')
Simon Glass7057d022018-10-01 21:12:47 -0600552parser.add_option('-P', '--processes', type=int,
553 help='set number of processes to use for running tests')
Simon Glass0ed50752018-07-06 10:27:24 -0600554parser.add_option('-t', '--test', action='store_true', dest='test',
555 default=False, help='run tests')
Simon Glass9c526332018-07-06 10:27:28 -0600556parser.add_option('-T', '--test-coverage', action='store_true',
557 default=False, help='run tests and check for 100% coverage')
Simon Glass0ed50752018-07-06 10:27:24 -0600558(options, args) = parser.parse_args()
559
560# Run our meagre tests
561if options.test:
562 RunTests(args)
Simon Glass9c526332018-07-06 10:27:28 -0600563elif options.test_coverage:
564 RunTestCoverage()