diff options
Diffstat (limited to 'tools/dtoc')
-rwxr-xr-x | tools/dtoc/dtoc.py | 7 | ||||
-rw-r--r-- | tools/dtoc/fdt.py | 41 | ||||
-rw-r--r-- | tools/dtoc/fdt_util.py | 12 | ||||
-rwxr-xr-x | tools/dtoc/test_fdt.py | 48 |
4 files changed, 99 insertions, 9 deletions
diff --git a/tools/dtoc/dtoc.py b/tools/dtoc/dtoc.py index c1a1d3534d..514e0dd4a3 100755 --- a/tools/dtoc/dtoc.py +++ b/tools/dtoc/dtoc.py @@ -71,6 +71,10 @@ def run_tests(args): print(err) for _, err in result.failures: print(err) + if result.errors or result.failures: + print('dtoc tests FAILED') + return 1 + return 0 def RunTestCoverage(): """Run the tests and check that we get 100% coverage""" @@ -101,7 +105,8 @@ parser.add_option('-T', '--test-coverage', action='store_true', # Run our meagre tests if options.test: - run_tests(args) + ret_code = run_tests(args) + sys.exit(ret_code) elif options.test_coverage: RunTestCoverage() diff --git a/tools/dtoc/fdt.py b/tools/dtoc/fdt.py index d9471c4381..6770be79fb 100644 --- a/tools/dtoc/fdt.py +++ b/tools/dtoc/fdt.py @@ -362,6 +362,23 @@ class Node: value = tools.GetBytes(0, len) self.props[prop_name] = Prop(self, None, prop_name, value) + def _CheckProp(self, prop_name): + """Check if a property is present + + Args: + prop_name: Name of property + + Returns: + self + + Raises: + ValueError if the property is missing + """ + if prop_name not in self.props: + raise ValueError("Fdt '%s', node '%s': Missing property '%s'" % + (self._fdt._fname, self.path, prop_name)) + return self + def SetInt(self, prop_name, val): """Update an integer property int the device tree. @@ -374,7 +391,7 @@ class Node: prop_name: Name of property val: Value to set """ - self.props[prop_name].SetInt(val) + self._CheckProp(prop_name).props[prop_name].SetInt(val) def SetData(self, prop_name, val): """Set the data value of a property @@ -386,7 +403,7 @@ class Node: prop_name: Name of property to set val: Data value to set """ - self.props[prop_name].SetData(val) + self._CheckProp(prop_name).props[prop_name].SetData(val) def SetString(self, prop_name, val): """Set the string value of a property @@ -400,7 +417,7 @@ class Node: """ if sys.version_info[0] >= 3: # pragma: no cover val = bytes(val, 'utf-8') - self.props[prop_name].SetData(val + b'\0') + self._CheckProp(prop_name).props[prop_name].SetData(val + b'\0') def AddString(self, prop_name, val): """Add a new string property to a node @@ -481,29 +498,35 @@ class Fdt: Properties: fname: Filename of fdt _root: Root of device tree (a Node object) + name: Helpful name for this Fdt for the user (useful when creating the + DT from data rather than a file) """ def __init__(self, fname): self._fname = fname self._cached_offsets = False self.phandle_to_node = {} + self.name = '' if self._fname: + self.name = self._fname self._fname = fdt_util.EnsureCompiled(self._fname) with open(self._fname, 'rb') as fd: self._fdt_obj = libfdt.Fdt(fd.read()) @staticmethod - def FromData(data): + def FromData(data, name=''): """Create a new Fdt object from the given data Args: data: Device-tree data blob + name: Helpful name for this Fdt for the user Returns: Fdt object containing the data """ fdt = Fdt(None) fdt._fdt_obj = libfdt.Fdt(bytes(data)) + fdt.name = name return fdt def LookupPhandle(self, phandle): @@ -551,6 +574,8 @@ class Fdt: parts = path.split('/') if len(parts) < 2: return None + if len(parts) == 2 and parts[1] == '': + return node for part in parts[1:]: node = node.FindNode(part) if not node: @@ -670,6 +695,14 @@ class Fdt: node = Node(fdt, parent, offset, name, path) return node + def GetFilename(self): + """Get the filename of the device tree + + Returns: + String filename + """ + return self._fname + def FdtScan(fname): """Returns a new Fdt object""" dtb = Fdt(fname) diff --git a/tools/dtoc/fdt_util.py b/tools/dtoc/fdt_util.py index f47879ac00..b105faec74 100644 --- a/tools/dtoc/fdt_util.py +++ b/tools/dtoc/fdt_util.py @@ -43,12 +43,14 @@ def fdt_cells_to_cpu(val, cells): out = out << 32 | fdt32_to_cpu(val[1]) return out -def EnsureCompiled(fname, capture_stderr=False): +def EnsureCompiled(fname, tmpdir=None, capture_stderr=False): """Compile an fdt .dts source file into a .dtb binary blob if needed. Args: fname: Filename (if .dts it will be compiled). It not it will be left alone + tmpdir: Temporary directory for output files, or None to use the + tools-module output directory Returns: Filename of resulting .dtb file @@ -57,8 +59,12 @@ def EnsureCompiled(fname, capture_stderr=False): if ext != '.dts': return fname - dts_input = tools.GetOutputFilename('source.dts') - dtb_output = tools.GetOutputFilename('source.dtb') + if tmpdir: + dts_input = os.path.join(tmpdir, 'source.dts') + dtb_output = os.path.join(tmpdir, 'source.dtb') + else: + dts_input = tools.GetOutputFilename('source.dts') + dtb_output = tools.GetOutputFilename('source.dtb') search_paths = [os.path.join(os.getcwd(), 'include')] root, _ = os.path.splitext(fname) diff --git a/tools/dtoc/test_fdt.py b/tools/dtoc/test_fdt.py index bf469dbd54..028c8cbaa8 100755 --- a/tools/dtoc/test_fdt.py +++ b/tools/dtoc/test_fdt.py @@ -9,7 +9,9 @@ from __future__ import print_function from optparse import OptionParser import glob import os +import shutil import sys +import tempfile import unittest # Bring in the patman libraries @@ -77,11 +79,16 @@ class TestFdt(unittest.TestCase): """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) self.assertIsNone(self.dtb.GetNode('/i2c@0/pmic@9/missing')) + node = self.dtb.GetNode('/') + self.assertTrue(isinstance(node, fdt.Node)) + self.assertEqual(0, node.Offset()) + def testFlush(self): """Check that we can flush the device tree out to its file""" fname = self.dtb._fname @@ -421,6 +428,32 @@ class TestProp(unittest.TestCase): self.dtb.Sync(auto_resize=True) self.assertTrue(dtb2.GetContents() != self.dtb.GetContents()) + def testMissingSetInt(self): + """Test handling of a missing property with SetInt""" + with self.assertRaises(ValueError) as e: + self.node.SetInt('one', 1) + self.assertIn("node '/spl-test': Missing property 'one'", + str(e.exception)) + + def testMissingSetData(self): + """Test handling of a missing property with SetData""" + with self.assertRaises(ValueError) as e: + self.node.SetData('one', b'data') + self.assertIn("node '/spl-test': Missing property 'one'", + str(e.exception)) + + def testMissingSetString(self): + """Test handling of a missing property with SetString""" + with self.assertRaises(ValueError) as e: + self.node.SetString('one', 1) + self.assertIn("node '/spl-test': Missing property 'one'", + str(e.exception)) + + def testGetFilename(self): + """Test the dtb filename can be provided""" + self.assertEqual(tools.GetOutputFilename('source.dtb'), + self.dtb.GetFilename()) + class TestFdtUtil(unittest.TestCase): """Tests for the fdt_util module @@ -514,10 +547,23 @@ class TestFdtUtil(unittest.TestCase): self.assertEqual(0x12345678, fdt_util.fdt_cells_to_cpu(val, 1)) def testEnsureCompiled(self): - """Test a degenerate case of this function""" + """Test a degenerate case of this function (file already compiled)""" dtb = fdt_util.EnsureCompiled('tools/dtoc/dtoc_test_simple.dts') self.assertEqual(dtb, fdt_util.EnsureCompiled(dtb)) + def testEnsureCompiledTmpdir(self): + """Test providing a temporary directory""" + try: + old_outdir = tools.outdir + tools.outdir= None + tmpdir = tempfile.mkdtemp(prefix='test_fdt.') + dtb = fdt_util.EnsureCompiled('tools/dtoc/dtoc_test_simple.dts', + tmpdir) + self.assertEqual(tmpdir, os.path.dirname(dtb)) + shutil.rmtree(tmpdir) + finally: + tools.outdir= old_outdir + def RunTestCoverage(): """Run the tests and check that we get 100% coverage""" |