xref: /openbmc/u-boot/tools/dtoc/test_fdt.py (revision 2a2d91d0)
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
21*2a2d91d0SSimon Glassimport fdt_util
222ba98753SSimon Glassfrom fdt_util import fdt32_to_cpu
232ba98753SSimon Glassimport libfdt
242ba98753SSimon Glassimport test_util
252ba98753SSimon Glassimport tools
262ba98753SSimon Glass
272ba98753SSimon Glassclass TestFdt(unittest.TestCase):
282ba98753SSimon Glass    """Tests for the Fdt module
292ba98753SSimon Glass
302ba98753SSimon Glass    This includes unit tests for some functions and functional tests for the fdt
312ba98753SSimon Glass    module.
322ba98753SSimon Glass    """
332ba98753SSimon Glass    @classmethod
342ba98753SSimon Glass    def setUpClass(cls):
352ba98753SSimon Glass        tools.PrepareOutputDir(None)
362ba98753SSimon Glass
372ba98753SSimon Glass    @classmethod
382ba98753SSimon Glass    def tearDownClass(cls):
392ba98753SSimon Glass        tools._FinaliseForTest()
402ba98753SSimon Glass
412ba98753SSimon Glass    def setUp(self):
422ba98753SSimon Glass        self.dtb = fdt.FdtScan('tools/dtoc/dtoc_test_simple.dts')
432ba98753SSimon Glass
442ba98753SSimon Glass    def testFdt(self):
452ba98753SSimon Glass        """Test that we can open an Fdt"""
462ba98753SSimon Glass        self.dtb.Scan()
472ba98753SSimon Glass        root = self.dtb.GetRoot()
482ba98753SSimon Glass        self.assertTrue(isinstance(root, fdt.Node))
492ba98753SSimon Glass
502ba98753SSimon Glass    def testGetNode(self):
512ba98753SSimon Glass        """Test the GetNode() method"""
522ba98753SSimon Glass        node = self.dtb.GetNode('/spl-test')
532ba98753SSimon Glass        self.assertTrue(isinstance(node, fdt.Node))
542ba98753SSimon Glass        node = self.dtb.GetNode('/i2c@0/pmic@9')
552ba98753SSimon Glass        self.assertTrue(isinstance(node, fdt.Node))
562ba98753SSimon Glass        self.assertEqual('pmic@9', node.name)
57*2a2d91d0SSimon Glass        self.assertIsNone(self.dtb.GetNode('/i2c@0/pmic@9/missing'))
582ba98753SSimon Glass
592ba98753SSimon Glass    def testFlush(self):
602ba98753SSimon Glass        """Check that we can flush the device tree out to its file"""
612ba98753SSimon Glass        fname = self.dtb._fname
622ba98753SSimon Glass        with open(fname) as fd:
632ba98753SSimon Glass            data = fd.read()
642ba98753SSimon Glass        os.remove(fname)
652ba98753SSimon Glass        with self.assertRaises(IOError):
662ba98753SSimon Glass            open(fname)
672ba98753SSimon Glass        self.dtb.Flush()
682ba98753SSimon Glass        with open(fname) as fd:
692ba98753SSimon Glass            data = fd.read()
702ba98753SSimon Glass
712ba98753SSimon Glass    def testPack(self):
722ba98753SSimon Glass        """Test that packing a device tree works"""
732ba98753SSimon Glass        self.dtb.Pack()
742ba98753SSimon Glass
752ba98753SSimon Glass    def testGetFdt(self):
762ba98753SSimon Glass        """Tetst that we can access the raw device-tree data"""
7796066240SSimon Glass        self.assertTrue(isinstance(self.dtb.GetContents(), bytearray))
782ba98753SSimon Glass
792ba98753SSimon Glass    def testGetProps(self):
802ba98753SSimon Glass        """Tests obtaining a list of properties"""
812ba98753SSimon Glass        node = self.dtb.GetNode('/spl-test')
822ba98753SSimon Glass        props = self.dtb.GetProps(node)
832ba98753SSimon Glass        self.assertEqual(['boolval', 'bytearray', 'byteval', 'compatible',
84*2a2d91d0SSimon Glass                          'intarray', 'intval', 'longbytearray', 'notstring',
852ba98753SSimon Glass                          'stringarray', 'stringval', 'u-boot,dm-pre-reloc'],
862ba98753SSimon Glass                         sorted(props.keys()))
872ba98753SSimon Glass
882ba98753SSimon Glass    def testCheckError(self):
892ba98753SSimon Glass        """Tests the ChecKError() function"""
902ba98753SSimon Glass        with self.assertRaises(ValueError) as e:
91*2a2d91d0SSimon Glass            fdt.CheckErr(-libfdt.NOTFOUND, 'hello')
922ba98753SSimon Glass        self.assertIn('FDT_ERR_NOTFOUND: hello', str(e.exception))
932ba98753SSimon Glass
942ba98753SSimon Glass
952ba98753SSimon Glassclass TestNode(unittest.TestCase):
962ba98753SSimon Glass    """Test operation of the Node class"""
972ba98753SSimon Glass
982ba98753SSimon Glass    @classmethod
992ba98753SSimon Glass    def setUpClass(cls):
1002ba98753SSimon Glass        tools.PrepareOutputDir(None)
1012ba98753SSimon Glass
1022ba98753SSimon Glass    @classmethod
1032ba98753SSimon Glass    def tearDownClass(cls):
1042ba98753SSimon Glass        tools._FinaliseForTest()
1052ba98753SSimon Glass
1062ba98753SSimon Glass    def setUp(self):
1072ba98753SSimon Glass        self.dtb = fdt.FdtScan('tools/dtoc/dtoc_test_simple.dts')
1082ba98753SSimon Glass        self.node = self.dtb.GetNode('/spl-test')
1092ba98753SSimon Glass
1102ba98753SSimon Glass    def testOffset(self):
1112ba98753SSimon Glass        """Tests that we can obtain the offset of a node"""
1122ba98753SSimon Glass        self.assertTrue(self.node.Offset() > 0)
1132ba98753SSimon Glass
1142ba98753SSimon Glass    def testDelete(self):
1152ba98753SSimon Glass        """Tests that we can delete a property"""
1162ba98753SSimon Glass        node2 = self.dtb.GetNode('/spl-test2')
1172ba98753SSimon Glass        offset1 = node2.Offset()
1182ba98753SSimon Glass        self.node.DeleteProp('intval')
1192ba98753SSimon Glass        offset2 = node2.Offset()
1202ba98753SSimon Glass        self.assertTrue(offset2 < offset1)
1212ba98753SSimon Glass        self.node.DeleteProp('intarray')
1222ba98753SSimon Glass        offset3 = node2.Offset()
1232ba98753SSimon Glass        self.assertTrue(offset3 < offset2)
124*2a2d91d0SSimon Glass        with self.assertRaises(libfdt.FdtException):
125*2a2d91d0SSimon Glass            self.node.DeleteProp('missing')
1262ba98753SSimon Glass
1272ba98753SSimon Glass    def testFindNode(self):
1282ba98753SSimon Glass        """Tests that we can find a node using the _FindNode() functoin"""
1292ba98753SSimon Glass        node = self.dtb.GetRoot()._FindNode('i2c@0')
1302ba98753SSimon Glass        self.assertEqual('i2c@0', node.name)
1312ba98753SSimon Glass        subnode = node._FindNode('pmic@9')
1322ba98753SSimon Glass        self.assertEqual('pmic@9', subnode.name)
133*2a2d91d0SSimon Glass        self.assertEqual(None, node._FindNode('missing'))
1342ba98753SSimon Glass
1352ba98753SSimon Glass
1362ba98753SSimon Glassclass TestProp(unittest.TestCase):
1372ba98753SSimon Glass    """Test operation of the Prop class"""
1382ba98753SSimon Glass
1392ba98753SSimon Glass    @classmethod
1402ba98753SSimon Glass    def setUpClass(cls):
1412ba98753SSimon Glass        tools.PrepareOutputDir(None)
1422ba98753SSimon Glass
1432ba98753SSimon Glass    @classmethod
1442ba98753SSimon Glass    def tearDownClass(cls):
1452ba98753SSimon Glass        tools._FinaliseForTest()
1462ba98753SSimon Glass
1472ba98753SSimon Glass    def setUp(self):
1482ba98753SSimon Glass        self.dtb = fdt.FdtScan('tools/dtoc/dtoc_test_simple.dts')
1492ba98753SSimon Glass        self.node = self.dtb.GetNode('/spl-test')
1502ba98753SSimon Glass        self.fdt = self.dtb.GetFdtObj()
1512ba98753SSimon Glass
152*2a2d91d0SSimon Glass    def testPhandle(self):
153*2a2d91d0SSimon Glass        dtb = fdt.FdtScan('tools/dtoc/dtoc_test_phandle.dts')
154*2a2d91d0SSimon Glass        node = dtb.GetNode('/phandle-source')
155*2a2d91d0SSimon Glass
156*2a2d91d0SSimon Glass    def _ConvertProp(self, prop_name):
157*2a2d91d0SSimon Glass        """Helper function to look up a property in self.node and return it
158*2a2d91d0SSimon Glass
159*2a2d91d0SSimon Glass        Args:
160*2a2d91d0SSimon Glass            Property name to find
161*2a2d91d0SSimon Glass
162*2a2d91d0SSimon Glass        Return fdt.Prop object for this property
163*2a2d91d0SSimon Glass        """
164*2a2d91d0SSimon Glass        p = self.fdt.get_property(self.node.Offset(), prop_name)
165*2a2d91d0SSimon Glass        return fdt.Prop(self.node, -1, prop_name, p)
166*2a2d91d0SSimon Glass
167*2a2d91d0SSimon Glass    def testMakeProp(self):
168*2a2d91d0SSimon Glass        """Test we can convert all the the types that are supported"""
169*2a2d91d0SSimon Glass        prop = self._ConvertProp('boolval')
170*2a2d91d0SSimon Glass        self.assertEqual(fdt.TYPE_BOOL, prop.type)
171*2a2d91d0SSimon Glass        self.assertEqual(True, prop.value)
172*2a2d91d0SSimon Glass
173*2a2d91d0SSimon Glass        prop = self._ConvertProp('intval')
174*2a2d91d0SSimon Glass        self.assertEqual(fdt.TYPE_INT, prop.type)
175*2a2d91d0SSimon Glass        self.assertEqual(1, fdt32_to_cpu(prop.value))
176*2a2d91d0SSimon Glass
177*2a2d91d0SSimon Glass        prop = self._ConvertProp('intarray')
178*2a2d91d0SSimon Glass        self.assertEqual(fdt.TYPE_INT, prop.type)
179*2a2d91d0SSimon Glass        val = [fdt32_to_cpu(val) for val in prop.value]
180*2a2d91d0SSimon Glass        self.assertEqual([2, 3, 4], val)
181*2a2d91d0SSimon Glass
182*2a2d91d0SSimon Glass        prop = self._ConvertProp('byteval')
183*2a2d91d0SSimon Glass        self.assertEqual(fdt.TYPE_BYTE, prop.type)
184*2a2d91d0SSimon Glass        self.assertEqual(5, ord(prop.value))
185*2a2d91d0SSimon Glass
186*2a2d91d0SSimon Glass        prop = self._ConvertProp('longbytearray')
187*2a2d91d0SSimon Glass        self.assertEqual(fdt.TYPE_BYTE, prop.type)
188*2a2d91d0SSimon Glass        val = [ord(val) for val in prop.value]
189*2a2d91d0SSimon Glass        self.assertEqual([9, 10, 11, 12, 13, 14, 15, 16, 17], val)
190*2a2d91d0SSimon Glass
191*2a2d91d0SSimon Glass        prop = self._ConvertProp('stringval')
192*2a2d91d0SSimon Glass        self.assertEqual(fdt.TYPE_STRING, prop.type)
193*2a2d91d0SSimon Glass        self.assertEqual('message', prop.value)
194*2a2d91d0SSimon Glass
195*2a2d91d0SSimon Glass        prop = self._ConvertProp('stringarray')
196*2a2d91d0SSimon Glass        self.assertEqual(fdt.TYPE_STRING, prop.type)
197*2a2d91d0SSimon Glass        self.assertEqual(['multi-word', 'message'], prop.value)
198*2a2d91d0SSimon Glass
199*2a2d91d0SSimon Glass        prop = self._ConvertProp('notstring')
200*2a2d91d0SSimon Glass        self.assertEqual(fdt.TYPE_BYTE, prop.type)
201*2a2d91d0SSimon Glass        val = [ord(val) for val in prop.value]
202*2a2d91d0SSimon Glass        self.assertEqual([0x20, 0x21, 0x22, 0x10, 0], val)
203*2a2d91d0SSimon Glass
2042ba98753SSimon Glass    def testGetEmpty(self):
2052ba98753SSimon Glass        """Tests the GetEmpty() function for the various supported types"""
2062ba98753SSimon Glass        self.assertEqual(True, fdt.Prop.GetEmpty(fdt.TYPE_BOOL))
2072ba98753SSimon Glass        self.assertEqual(chr(0), fdt.Prop.GetEmpty(fdt.TYPE_BYTE))
2082ba98753SSimon Glass        self.assertEqual(chr(0) * 4, fdt.Prop.GetEmpty(fdt.TYPE_INT))
2092ba98753SSimon Glass        self.assertEqual('', fdt.Prop.GetEmpty(fdt.TYPE_STRING))
2102ba98753SSimon Glass
2112ba98753SSimon Glass    def testGetOffset(self):
2122ba98753SSimon Glass        """Test we can get the offset of a property"""
2132ba98753SSimon Glass        prop = self.node.props['longbytearray']
2142ba98753SSimon Glass
2152ba98753SSimon Glass        # Add 12, which is sizeof(struct fdt_property), to get to start of data
2162ba98753SSimon Glass        offset = prop.GetOffset() + 12
21796066240SSimon Glass        data = self.dtb.GetContents()[offset:offset + len(prop.value)]
2182ba98753SSimon Glass        bytes = [chr(x) for x in data]
2192ba98753SSimon Glass        self.assertEqual(bytes, prop.value)
2202ba98753SSimon Glass
2212ba98753SSimon Glass    def testWiden(self):
2222ba98753SSimon Glass        """Test widening of values"""
2232ba98753SSimon Glass        node2 = self.dtb.GetNode('/spl-test2')
2242ba98753SSimon Glass        prop = self.node.props['intval']
2252ba98753SSimon Glass
2262ba98753SSimon Glass        # No action
2272ba98753SSimon Glass        prop2 = node2.props['intval']
2282ba98753SSimon Glass        prop.Widen(prop2)
2292ba98753SSimon Glass        self.assertEqual(fdt.TYPE_INT, prop.type)
2302ba98753SSimon Glass        self.assertEqual(1, fdt32_to_cpu(prop.value))
2312ba98753SSimon Glass
2322ba98753SSimon Glass        # Convert singla value to array
2332ba98753SSimon Glass        prop2 = self.node.props['intarray']
2342ba98753SSimon Glass        prop.Widen(prop2)
2352ba98753SSimon Glass        self.assertEqual(fdt.TYPE_INT, prop.type)
2362ba98753SSimon Glass        self.assertTrue(isinstance(prop.value, list))
2372ba98753SSimon Glass
2382ba98753SSimon Glass        # A 4-byte array looks like a single integer. When widened by a longer
2392ba98753SSimon Glass        # byte array, it should turn into an array.
2402ba98753SSimon Glass        prop = self.node.props['longbytearray']
2412ba98753SSimon Glass        prop2 = node2.props['longbytearray']
2422ba98753SSimon Glass        self.assertFalse(isinstance(prop2.value, list))
2432ba98753SSimon Glass        self.assertEqual(4, len(prop2.value))
2442ba98753SSimon Glass        prop2.Widen(prop)
2452ba98753SSimon Glass        self.assertTrue(isinstance(prop2.value, list))
2462ba98753SSimon Glass        self.assertEqual(9, len(prop2.value))
2472ba98753SSimon Glass
2482ba98753SSimon Glass        # Similarly for a string array
2492ba98753SSimon Glass        prop = self.node.props['stringval']
2502ba98753SSimon Glass        prop2 = node2.props['stringarray']
2512ba98753SSimon Glass        self.assertFalse(isinstance(prop.value, list))
2522ba98753SSimon Glass        self.assertEqual(7, len(prop.value))
2532ba98753SSimon Glass        prop.Widen(prop2)
2542ba98753SSimon Glass        self.assertTrue(isinstance(prop.value, list))
2552ba98753SSimon Glass        self.assertEqual(3, len(prop.value))
2562ba98753SSimon Glass
2572ba98753SSimon Glass        # Enlarging an existing array
2582ba98753SSimon Glass        prop = self.node.props['stringarray']
2592ba98753SSimon Glass        prop2 = node2.props['stringarray']
2602ba98753SSimon Glass        self.assertTrue(isinstance(prop.value, list))
2612ba98753SSimon Glass        self.assertEqual(2, len(prop.value))
2622ba98753SSimon Glass        prop.Widen(prop2)
2632ba98753SSimon Glass        self.assertTrue(isinstance(prop.value, list))
2642ba98753SSimon Glass        self.assertEqual(3, len(prop.value))
2652ba98753SSimon Glass
2662ba98753SSimon Glass
267*2a2d91d0SSimon Glassclass TestFdtUtil(unittest.TestCase):
268*2a2d91d0SSimon Glass    """Tests for the fdt_util module
269*2a2d91d0SSimon Glass
270*2a2d91d0SSimon Glass    This module will likely be mostly replaced at some point, once upstream
271*2a2d91d0SSimon Glass    libfdt has better Python support. For now, this provides tests for current
272*2a2d91d0SSimon Glass    functionality.
273*2a2d91d0SSimon Glass    """
274*2a2d91d0SSimon Glass    @classmethod
275*2a2d91d0SSimon Glass    def setUpClass(cls):
276*2a2d91d0SSimon Glass        tools.PrepareOutputDir(None)
277*2a2d91d0SSimon Glass
278*2a2d91d0SSimon Glass    def setUp(self):
279*2a2d91d0SSimon Glass        self.dtb = fdt.FdtScan('tools/dtoc/dtoc_test_simple.dts')
280*2a2d91d0SSimon Glass        self.node = self.dtb.GetNode('/spl-test')
281*2a2d91d0SSimon Glass
282*2a2d91d0SSimon Glass    def testGetInt(self):
283*2a2d91d0SSimon Glass        self.assertEqual(1, fdt_util.GetInt(self.node, 'intval'))
284*2a2d91d0SSimon Glass        self.assertEqual(3, fdt_util.GetInt(self.node, 'missing', 3))
285*2a2d91d0SSimon Glass
286*2a2d91d0SSimon Glass        with self.assertRaises(ValueError) as e:
287*2a2d91d0SSimon Glass            self.assertEqual(3, fdt_util.GetInt(self.node, 'intarray'))
288*2a2d91d0SSimon Glass        self.assertIn("property 'intarray' has list value: expecting a single "
289*2a2d91d0SSimon Glass                      'integer', str(e.exception))
290*2a2d91d0SSimon Glass
291*2a2d91d0SSimon Glass    def testGetString(self):
292*2a2d91d0SSimon Glass        self.assertEqual('message', fdt_util.GetString(self.node, 'stringval'))
293*2a2d91d0SSimon Glass        self.assertEqual('test', fdt_util.GetString(self.node, 'missing',
294*2a2d91d0SSimon Glass                                                    'test'))
295*2a2d91d0SSimon Glass
296*2a2d91d0SSimon Glass        with self.assertRaises(ValueError) as e:
297*2a2d91d0SSimon Glass            self.assertEqual(3, fdt_util.GetString(self.node, 'stringarray'))
298*2a2d91d0SSimon Glass        self.assertIn("property 'stringarray' has list value: expecting a "
299*2a2d91d0SSimon Glass                      'single string', str(e.exception))
300*2a2d91d0SSimon Glass
301*2a2d91d0SSimon Glass    def testGetBool(self):
302*2a2d91d0SSimon Glass        self.assertEqual(True, fdt_util.GetBool(self.node, 'boolval'))
303*2a2d91d0SSimon Glass        self.assertEqual(False, fdt_util.GetBool(self.node, 'missing'))
304*2a2d91d0SSimon Glass        self.assertEqual(True, fdt_util.GetBool(self.node, 'missing', True))
305*2a2d91d0SSimon Glass        self.assertEqual(False, fdt_util.GetBool(self.node, 'missing', False))
306*2a2d91d0SSimon Glass
307*2a2d91d0SSimon Glass    def testFdtCellsToCpu(self):
308*2a2d91d0SSimon Glass        val = self.node.props['intarray'].value
309*2a2d91d0SSimon Glass        self.assertEqual(0, fdt_util.fdt_cells_to_cpu(val, 0))
310*2a2d91d0SSimon Glass        self.assertEqual(2, fdt_util.fdt_cells_to_cpu(val, 1))
311*2a2d91d0SSimon Glass
312*2a2d91d0SSimon Glass        dtb2 = fdt.FdtScan('tools/dtoc/dtoc_test_addr64.dts')
313*2a2d91d0SSimon Glass        node2 = dtb2.GetNode('/test1')
314*2a2d91d0SSimon Glass        val = node2.props['reg'].value
315*2a2d91d0SSimon Glass        self.assertEqual(0x1234, fdt_util.fdt_cells_to_cpu(val, 2))
316*2a2d91d0SSimon Glass
317*2a2d91d0SSimon Glass    def testEnsureCompiled(self):
318*2a2d91d0SSimon Glass        """Test a degenerate case of this function"""
319*2a2d91d0SSimon Glass        dtb = fdt_util.EnsureCompiled('tools/dtoc/dtoc_test_simple.dts')
320*2a2d91d0SSimon Glass        self.assertEqual(dtb, fdt_util.EnsureCompiled(dtb))
321*2a2d91d0SSimon Glass
322*2a2d91d0SSimon Glass    def testGetPlainBytes(self):
323*2a2d91d0SSimon Glass        self.assertEqual('fred', fdt_util.get_plain_bytes('fred'))
324*2a2d91d0SSimon Glass
325*2a2d91d0SSimon Glass
326*2a2d91d0SSimon Glassdef RunTestCoverage():
327*2a2d91d0SSimon Glass    """Run the tests and check that we get 100% coverage"""
328*2a2d91d0SSimon Glass    test_util.RunTestCoverage('tools/dtoc/test_fdt.py', None,
329*2a2d91d0SSimon Glass            ['tools/patman/*.py', '*test_fdt.py'], options.build_dir)
330*2a2d91d0SSimon Glass
331*2a2d91d0SSimon Glass
3322ba98753SSimon Glassdef RunTests(args):
3332ba98753SSimon Glass    """Run all the test we have for the fdt model
3342ba98753SSimon Glass
3352ba98753SSimon Glass    Args:
3362ba98753SSimon Glass        args: List of positional args provided to fdt. This can hold a test
3372ba98753SSimon Glass            name to execute (as in 'fdt -t testFdt', for example)
3382ba98753SSimon Glass    """
3392ba98753SSimon Glass    result = unittest.TestResult()
3402ba98753SSimon Glass    sys.argv = [sys.argv[0]]
3412ba98753SSimon Glass    test_name = args and args[0] or None
342*2a2d91d0SSimon Glass    for module in (TestFdt, TestNode, TestProp, TestFdtUtil):
3432ba98753SSimon Glass        if test_name:
3442ba98753SSimon Glass            try:
3452ba98753SSimon Glass                suite = unittest.TestLoader().loadTestsFromName(test_name, module)
3462ba98753SSimon Glass            except AttributeError:
3472ba98753SSimon Glass                continue
3482ba98753SSimon Glass        else:
3492ba98753SSimon Glass            suite = unittest.TestLoader().loadTestsFromTestCase(module)
3502ba98753SSimon Glass        suite.run(result)
3512ba98753SSimon Glass
3522ba98753SSimon Glass    print result
3532ba98753SSimon Glass    for _, err in result.errors:
3542ba98753SSimon Glass        print err
3552ba98753SSimon Glass    for _, err in result.failures:
3562ba98753SSimon Glass        print err
3572ba98753SSimon Glass
3582ba98753SSimon Glassif __name__ != '__main__':
3592ba98753SSimon Glass    sys.exit(1)
3602ba98753SSimon Glass
3612ba98753SSimon Glassparser = OptionParser()
362*2a2d91d0SSimon Glassparser.add_option('-B', '--build-dir', type='string', default='b',
363*2a2d91d0SSimon Glass        help='Directory containing the build output')
3642ba98753SSimon Glassparser.add_option('-t', '--test', action='store_true', dest='test',
3652ba98753SSimon Glass                  default=False, help='run tests')
366*2a2d91d0SSimon Glassparser.add_option('-T', '--test-coverage', action='store_true',
367*2a2d91d0SSimon Glass                default=False, help='run tests and check for 100% coverage')
3682ba98753SSimon Glass(options, args) = parser.parse_args()
3692ba98753SSimon Glass
3702ba98753SSimon Glass# Run our meagre tests
3712ba98753SSimon Glassif options.test:
3722ba98753SSimon Glass    RunTests(args)
373*2a2d91d0SSimon Glasselif options.test_coverage:
374*2a2d91d0SSimon Glass    RunTestCoverage()
375