X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;ds=sidebyside;f=tools%2Fbinman%2Fftest.py;h=999d8884acacc3ecdafe4a161c61815f46009c6e;hb=69f7cb31a083c697ef0a4180a30219d2258b3662;hp=5bde8aa30a11bd0092f5c2a70cfc181360102430;hpb=e073d4e14ff76f545a71dc40fa324618ce80adcb;p=oweals%2Fu-boot.git diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py index 5bde8aa30a..999d8884ac 100644 --- a/tools/binman/ftest.py +++ b/tools/binman/ftest.py @@ -155,7 +155,7 @@ class TestFunctional(unittest.TestCase): @classmethod def setup_test_args(cls, preserve_indir=False, preserve_outdirs=False, - toolpath=None): + toolpath=None, verbosity=None): """Accept arguments controlling test execution Args: @@ -169,6 +169,7 @@ class TestFunctional(unittest.TestCase): cls.preserve_indir = preserve_indir cls.preserve_outdirs = preserve_outdirs cls.toolpath = toolpath + cls.verbosity = verbosity def _CheckLz4(self): if not self.have_lz4: @@ -192,19 +193,6 @@ class TestFunctional(unittest.TestCase): TestFunctional._MakeInputFile('spl/u-boot-spl.dtb', U_BOOT_SPL_DTB_DATA) TestFunctional._MakeInputFile('tpl/u-boot-tpl.dtb', U_BOOT_TPL_DTB_DATA) - def _GetVerbosity(self): - """Check if verbosity should be enabled - - Returns: - list containing either: - - Verbosity flag (e.g. '-v2') if it is present on the cmd line - - nothing if the flag is not present - """ - for arg in sys.argv[1:]: - if arg.startswith('-v'): - return [arg] - return [] - def _RunBinman(self, *args, **kwargs): """Run binman using the command line @@ -219,7 +207,7 @@ class TestFunctional(unittest.TestCase): result.stdout + result.stderr)) return result - def _DoBinman(self, *args): + def _DoBinman(self, *argv): """Run binman using directly (in the same process) Args: @@ -227,16 +215,14 @@ class TestFunctional(unittest.TestCase): Returns: Return value (0 for success) """ - args = list(args) - if '-D' in sys.argv: - args = args + ['-D'] - (options, args) = cmdline.ParseArgs(args) - options.pager = 'binman-invalid-pager' - options.build_dir = self._indir + argv = list(argv) + args = cmdline.ParseArgs(argv) + args.pager = 'binman-invalid-pager' + args.build_dir = self._indir # For testing, you can force an increase in verbosity here - # options.verbosity = tout.DEBUG - return control.Binman(options, args) + # args.verbosity = tout.DEBUG + return control.Binman(args) def _DoTestFile(self, fname, debug=False, map=False, update_dtb=False, entry_args=None, images=None, use_real_dtb=False, @@ -254,28 +240,29 @@ class TestFunctional(unittest.TestCase): value: value of that arg images: List of image names to build """ - args = ['-p', '-I', self._indir, '-d', self.TestFile(fname)] + args = [] if debug: args.append('-D') + if verbosity is not None: + args.append('-v%d' % verbosity) + elif self.verbosity: + args.append('-v%d' % self.verbosity) + if self.toolpath: + for path in self.toolpath: + args += ['--toolpath', path] + args += ['build', '-p', '-I', self._indir, '-d', self.TestFile(fname)] if map: args.append('-m') if update_dtb: args.append('-u') if not use_real_dtb: args.append('--fake-dtb') - if verbosity is not None: - args.append('-v%d' % verbosity) - else: - args += self._GetVerbosity() if entry_args: for arg, value in entry_args.items(): args.append('-a%s=%s' % (arg, value)) if images: for image in images: args += ['-i', image] - if self.toolpath: - for path in self.toolpath: - args += ['--toolpath', path] return self._DoBinman(*args) def _SetupDtb(self, fname, outfile='u-boot.dtb'): @@ -380,6 +367,17 @@ class TestFunctional(unittest.TestCase): if reset_dtbs and use_real_dtb: self._ResetDtbs() + def _DoReadFileRealDtb(self, fname): + """Run binman with a real .dtb file and return the resulting data + + Args: + fname: DT source filename to use (e.g. 082_fdt_update_all.dts) + + Returns: + Resulting image contents + """ + return self._DoReadFileDtb(fname, use_real_dtb=True, update_dtb=True)[0] + def _DoReadFile(self, fname, use_real_dtb=False): """Helper function which discards the device-tree binary @@ -476,16 +474,16 @@ class TestFunctional(unittest.TestCase): """ return struct.unpack('>L', dtb[4:8])[0] - def _GetPropTree(self, dtb, prop_names): + def _GetPropTree(self, dtb, prop_names, prefix='/binman/'): def AddNode(node, path): if node.name != '/': path += '/' + node.name + for prop in node.props.values(): + if prop.name in prop_names: + prop_path = path + ':' + prop.name + tree[prop_path[len(prefix):]] = fdt_util.fdt32_to_cpu( + prop.value) for subnode in node.subnodes: - for prop in subnode.props.values(): - if prop.name in prop_names: - prop_path = path + '/' + subnode.name + ':' + prop.name - tree[prop_path[len('/binman/'):]] = fdt_util.fdt32_to_cpu( - prop.value) AddNode(subnode, path) tree = {} @@ -527,20 +525,20 @@ class TestFunctional(unittest.TestCase): """Test that we can run it with a specific board""" self._SetupDtb('005_simple.dts', 'sandbox/u-boot.dtb') TestFunctional._MakeInputFile('sandbox/u-boot.bin', U_BOOT_DATA) - result = self._DoBinman('-b', 'sandbox') + result = self._DoBinman('build', '-b', 'sandbox') self.assertEqual(0, result) def testNeedBoard(self): """Test that we get an error when no board ius supplied""" with self.assertRaises(ValueError) as e: - result = self._DoBinman() + result = self._DoBinman('build') self.assertIn("Must provide a board to process (use -b )", str(e.exception)) def testMissingDt(self): """Test that an invalid device-tree file generates an error""" with self.assertRaises(Exception) as e: - self._RunBinman('-d', 'missing_file') + self._RunBinman('build', '-d', 'missing_file') # We get one error from libfdt, and a different one from fdtget. self.AssertInList(["Couldn't open blob from 'missing_file'", 'No such file or directory'], str(e.exception)) @@ -552,26 +550,26 @@ class TestFunctional(unittest.TestCase): will come from the device-tree compiler (dtc). """ with self.assertRaises(Exception) as e: - self._RunBinman('-d', self.TestFile('001_invalid.dts')) + self._RunBinman('build', '-d', self.TestFile('001_invalid.dts')) self.assertIn("FATAL ERROR: Unable to parse input tree", str(e.exception)) def testMissingNode(self): """Test that a device tree without a 'binman' node generates an error""" with self.assertRaises(Exception) as e: - self._DoBinman('-d', self.TestFile('002_missing_node.dts')) + self._DoBinman('build', '-d', self.TestFile('002_missing_node.dts')) self.assertIn("does not have a 'binman' node", str(e.exception)) def testEmpty(self): """Test that an empty binman node works OK (i.e. does nothing)""" - result = self._RunBinman('-d', self.TestFile('003_empty.dts')) + result = self._RunBinman('build', '-d', self.TestFile('003_empty.dts')) self.assertEqual(0, len(result.stderr)) self.assertEqual(0, result.return_code) def testInvalidEntry(self): """Test that an invalid entry is flagged""" with self.assertRaises(Exception) as e: - result = self._RunBinman('-d', + result = self._RunBinman('build', '-d', self.TestFile('004_invalid_entry.dts')) self.assertIn("Unknown entry type 'not-a-valid-type' in node " "'/binman/not-a-valid-type'", str(e.exception)) @@ -1222,10 +1220,14 @@ class TestFunctional(unittest.TestCase): def testBadChangeSize(self): """Test that trying to change the size of an entry fails""" - with self.assertRaises(ValueError) as e: - self._DoReadFile('059_change_size.dts', True) - self.assertIn("Node '/binman/_testing': Cannot update entry size from " - '2 to 1', str(e.exception)) + try: + state.SetAllowEntryExpansion(False) + with self.assertRaises(ValueError) as e: + self._DoReadFile('059_change_size.dts', True) + self.assertIn("Node '/binman/_testing': Cannot update entry size from 1 to 2", + str(e.exception)) + finally: + state.SetAllowEntryExpansion(True) def testUpdateFdt(self): """Test that we can update the device tree with offset/size info""" @@ -1302,7 +1304,8 @@ class TestFunctional(unittest.TestCase): def testEntryArgsInvalidFormat(self): """Test that an invalid entry-argument format is detected""" - args = ['-d', self.TestFile('064_entry_args_required.dts'), '-ano-value'] + args = ['build', '-d', self.TestFile('064_entry_args_required.dts'), + '-ano-value'] with self.assertRaises(ValueError) as e: self._DoBinman(*args) self.assertIn("Invalid entry arguemnt 'no-value'", str(e.exception)) @@ -1547,8 +1550,7 @@ class TestFunctional(unittest.TestCase): def testUpdateFdtAll(self): """Test that all device trees are updated with offset/size info""" - data, _, _, _ = self._DoReadFileDtb('082_fdt_update_all.dts', - use_real_dtb=True, update_dtb=True) + data = self._DoReadFileRealDtb('082_fdt_update_all.dts') base_expected = { 'section:image-pos': 0, @@ -2034,6 +2036,155 @@ class TestFunctional(unittest.TestCase): self.assertEqual(U_BOOT_DTB_DATA, cfile2.data) self.assertEqual(0x140, cfile2.cbfs_offset) + def testFdtmap(self): + """Test an FDT map can be inserted in the image""" + data = self.data = self._DoReadFileRealDtb('115_fdtmap.dts') + fdtmap_data = data[len(U_BOOT_DATA):] + magic = fdtmap_data[:8] + self.assertEqual('_FDTMAP_', magic) + self.assertEqual(tools.GetBytes(0, 8), fdtmap_data[8:16]) + + fdt_data = fdtmap_data[16:] + dtb = fdt.Fdt.FromData(fdt_data) + dtb.Scan() + props = self._GetPropTree(dtb, ['offset', 'size', 'image-pos'], + prefix='/') + self.assertEqual({ + 'image-pos': 0, + 'offset': 0, + 'u-boot:offset': 0, + 'u-boot:size': len(U_BOOT_DATA), + 'u-boot:image-pos': 0, + 'fdtmap:image-pos': 4, + 'fdtmap:offset': 4, + 'fdtmap:size': len(fdtmap_data), + 'size': len(data), + }, props) + + def testFdtmapNoMatch(self): + """Check handling of an FDT map when the section cannot be found""" + self.data = self._DoReadFileRealDtb('115_fdtmap.dts') + + # Mangle the section name, which should cause a mismatch between the + # correct FDT path and the one expected by the section + image = control.images['image'] + image._node.path += '-suffix' + entries = image.GetEntries() + fdtmap = entries['fdtmap'] + with self.assertRaises(ValueError) as e: + fdtmap._GetFdtmap() + self.assertIn("Cannot locate node for path '/binman-suffix'", + str(e.exception)) + + def testFdtmapHeader(self): + """Test an FDT map and image header can be inserted in the image""" + data = self.data = self._DoReadFileRealDtb('116_fdtmap_hdr.dts') + fdtmap_pos = len(U_BOOT_DATA) + fdtmap_data = data[fdtmap_pos:] + fdt_data = fdtmap_data[16:] + dtb = fdt.Fdt.FromData(fdt_data) + fdt_size = dtb.GetFdtObj().totalsize() + hdr_data = data[-8:] + self.assertEqual('BinM', hdr_data[:4]) + offset = struct.unpack('