diff options
Diffstat (limited to 'tools/binman/ftest.py')
| -rw-r--r-- | tools/binman/ftest.py | 255 | 
1 files changed, 229 insertions, 26 deletions
| diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py index e4da04030a5..93f3d22cf57 100644 --- a/tools/binman/ftest.py +++ b/tools/binman/ftest.py @@ -7,6 +7,7 @@  #    python -m unittest func_test.TestFunctional.testHelp  import collections +import glob  import gzip  import hashlib  from optparse import OptionParser @@ -546,7 +547,7 @@ class TestFunctional(unittest.TestCase):              dtb_data = self._SetupDtb(fname)              # For testing purposes, make a copy of the DT for SPL and TPL. Add -            # a node indicating which it is, so aid verification. +            # a node indicating which it is, to aid verification.              for name in ['spl', 'tpl', 'vpl']:                  dtb_fname = '%s/u-boot-%s.dtb' % (name, name)                  outfile = os.path.join(self._indir, dtb_fname) @@ -4180,8 +4181,8 @@ class TestFunctional(unittest.TestCase):          data = self._DoReadFile('172_scp.dts')          self.assertEqual(SCP_DATA, data[:len(SCP_DATA)]) -    def testFitFdt(self): -        """Test an image with an FIT with multiple FDT images""" +    def CheckFitFdt(self, dts='170_fit_fdt.dts', use_fdt_list=True): +        """Check an image with an FIT with multiple FDT images"""          def _CheckFdt(seq, expected_data):              """Check the FDT nodes @@ -4220,11 +4221,12 @@ class TestFunctional(unittest.TestCase):              self.assertEqual('fdt-%d' % seq, fnode.props['fdt'].value)          entry_args = { -            'of-list': 'test-fdt1 test-fdt2',              'default-dt': 'test-fdt2',          } +        if use_fdt_list: +            entry_args['of-list'] = 'test-fdt1 test-fdt2'          data = self._DoReadFileDtb( -            '170_fit_fdt.dts', +            dts,              entry_args=entry_args,              extra_indirs=[os.path.join(self._indir, TEST_FDT_SUBDIR)])[0]          self.assertEqual(U_BOOT_NODTB_DATA, data[-len(U_BOOT_NODTB_DATA):]) @@ -4243,6 +4245,10 @@ class TestFunctional(unittest.TestCase):          _CheckConfig(1, TEST_FDT1_DATA)          _CheckConfig(2, TEST_FDT2_DATA) +    def testFitFdt(self): +        """Test an image with an FIT with multiple FDT images""" +        self.CheckFitFdt() +      def testFitFdtMissingList(self):          """Test handling of a missing 'of-list' entry arg"""          with self.assertRaises(ValueError) as e: @@ -7175,27 +7181,24 @@ fdt         fdtmap                Extract the devicetree blob from the fdtmap      def testSplPubkeyDtb(self): -         """Test u_boot_spl_pubkey_dtb etype""" -         data = tools.read_file(self.TestFile("key.pem")) -         self._MakeInputFile("key.crt", data) -         self._DoReadFileRealDtb('306_spl_pubkey_dtb.dts') -         image = control.images['image'] -         entries = image.GetEntries() -         dtb_entry = entries['u-boot-spl-pubkey-dtb'] -         dtb_data = dtb_entry.GetData() -         dtb = fdt.Fdt.FromData(dtb_data) -         dtb.Scan() - -         signature_node = dtb.GetNode('/signature') -         self.assertIsNotNone(signature_node) -         key_node = signature_node.FindNode("key-key") -         self.assertIsNotNone(key_node) -         self.assertEqual(fdt_util.GetString(key_node, "required"), -                          "conf") -         self.assertEqual(fdt_util.GetString(key_node, "algo"), -                          "sha384,rsa4096") -         self.assertEqual(fdt_util.GetString(key_node, "key-name-hint"), -                          "key") +        """Test u_boot_spl_pubkey_dtb etype""" +        data = tools.read_file(self.TestFile("key.pem")) +        self._MakeInputFile("key.crt", data) +        self._DoReadFileRealDtb('306_spl_pubkey_dtb.dts') +        image = control.images['image'] +        entries = image.GetEntries() +        dtb_entry = entries['u-boot-spl-pubkey-dtb'] +        dtb_data = dtb_entry.GetData() +        dtb = fdt.Fdt.FromData(dtb_data) +        dtb.Scan() + +        signature_node = dtb.GetNode('/signature') +        self.assertIsNotNone(signature_node) +        key_node = signature_node.FindNode("key-key") +        self.assertIsNotNone(key_node) +        self.assertEqual(fdt_util.GetString(key_node, "required"), "conf") +        self.assertEqual(fdt_util.GetString(key_node, "algo"), "sha384,rsa4096") +        self.assertEqual(fdt_util.GetString(key_node, "key-name-hint"), "key")      def testXilinxBootgenSigning(self):          """Test xilinx-bootgen etype""" @@ -7487,6 +7490,206 @@ fdt         fdtmap                Extract the devicetree blob from the fdtmap              err,              "Image '.*' is missing external blobs and is non-functional: .*") +    def SetupAlternateDts(self): +        """Compile the .dts test files for alternative-fdt + +        Returns: +            tuple: +                str: Test directory created +                list of str: '.bin' files which we expect Binman to create +        """ +        testdir = TestFunctional._MakeInputDir('dtb') +        dtb_list = [] +        for fname in glob.glob(f'{self.TestFile("alt_dts")}/*.dts'): +            tmp_fname = fdt_util.EnsureCompiled(fname, testdir) +            base = os.path.splitext(os.path.basename(fname))[0] +            dtb_list.append(base + '.bin') +            shutil.move(tmp_fname, os.path.join(testdir, base + '.dtb')) + +        return testdir, dtb_list + +    def CheckAlternates(self, dts, phase, xpl_data): +        """Run the test for the alterative-fdt etype + +        Args: +            dts (str): Devicetree file to process +            phase (str): Phase to process ('spl', 'tpl' or 'vpl') +            xpl_data (bytes): Expected data for the phase's binary + +        Returns: +            dict of .dtb files produced +                key: str filename +                value: Fdt object +        """ +        dtb_list = self.SetupAlternateDts()[1] + +        entry_args = { +            f'{phase}-dtb': '1', +            f'{phase}-bss-pad': 'y', +            'of-spl-remove-props': 'prop-to-remove another-prop-to-get-rid-of', +        } +        data = self._DoReadFileDtb(dts, use_real_dtb=True, update_dtb=True, +                                   use_expanded=True, entry_args=entry_args)[0] +        self.assertEqual(xpl_data, data[:len(xpl_data)]) +        rest = data[len(xpl_data):] +        pad_len = 10 +        self.assertEqual(tools.get_bytes(0, pad_len), rest[:pad_len]) + +        # Check the dtb is using the test file +        dtb_data = rest[pad_len:] +        dtb = fdt.Fdt.FromData(dtb_data) +        dtb.Scan() +        fdt_size = dtb.GetFdtObj().totalsize() +        self.assertEqual('model-not-set', +                         fdt_util.GetString(dtb.GetRoot(), 'compatible')) + +        pad_len = 10 + +        # Check the other output files +        dtbs = {} +        for fname in dtb_list: +            pathname = tools.get_output_filename(fname) +            self.assertTrue(os.path.exists(pathname)) + +            data = tools.read_file(pathname) +            self.assertEqual(xpl_data, data[:len(xpl_data)]) +            rest = data[len(xpl_data):] + +            self.assertEqual(tools.get_bytes(0, pad_len), rest[:pad_len]) +            rest = rest[pad_len:] + +            dtb = fdt.Fdt.FromData(rest) +            dtb.Scan() +            dtbs[fname] = dtb + +            expected = 'one' if '1' in fname else 'two' +            self.assertEqual(f'u-boot,model-{expected}', +                             fdt_util.GetString(dtb.GetRoot(), 'compatible')) + +            # Make sure the FDT is the same size as the 'main' one +            rest = rest[fdt_size:] + +            self.assertEqual(b'', rest) +        return dtbs + +    def testAlternatesFdt(self): +        """Test handling of alternates-fdt etype""" +        self._SetupTplElf() +        dtbs = self.CheckAlternates('328_alternates_fdt.dts', 'tpl', +                                    U_BOOT_TPL_NODTB_DATA) +        for dtb in dtbs.values(): +            # Check for the node with the tag +            node = dtb.GetNode('/node') +            self.assertIsNotNone(node) +            self.assertEqual(5, len(node.props.keys())) + +            # Make sure the other node is still there +            self.assertIsNotNone(dtb.GetNode('/node/other-node')) + +    def testAlternatesFdtgrep(self): +        """Test handling of alternates-fdt etype using fdtgrep""" +        self._SetupTplElf() +        dtbs = self.CheckAlternates('329_alternates_fdtgrep.dts', 'tpl', +                                    U_BOOT_TPL_NODTB_DATA) +        for dtb in dtbs.values(): +            # Check for the node with the tag +            node = dtb.GetNode('/node') +            self.assertIsNotNone(node) +            self.assertEqual({'some-prop', 'not-a-prop-to-remove'}, +                             node.props.keys()) + +            # Make sure the other node is gone +            self.assertIsNone(dtb.GetNode('/node/other-node')) + +    def testAlternatesFdtgrepVpl(self): +        """Test handling of alternates-fdt etype using fdtgrep with vpl""" +        self._SetupVplElf() +        dtbs = self.CheckAlternates('330_alternates_vpl.dts', 'vpl', +                                    U_BOOT_VPL_NODTB_DATA) + +    def testAlternatesFdtgrepSpl(self): +        """Test handling of alternates-fdt etype using fdtgrep with spl""" +        self._SetupSplElf() +        dtbs = self.CheckAlternates('331_alternates_spl.dts', 'spl', +                                    U_BOOT_SPL_NODTB_DATA) + +    def testAlternatesFdtgrepInval(self): +        """Test alternates-fdt etype using fdtgrep with invalid phase""" +        self._SetupSplElf() +        with self.assertRaises(ValueError) as e: +            dtbs = self.CheckAlternates('332_alternates_inval.dts', 'spl', +                                        U_BOOT_SPL_NODTB_DATA) +        self.assertIn("Invalid U-Boot phase 'bad-phase': Use tpl/vpl/spl", +                      str(e.exception)) + +    def testFitFdtListDir(self): +        """Test an image with an FIT with FDT images using fit,fdt-list-dir""" +        self.CheckFitFdt('333_fit_fdt_dir.dts', False) + +    def testFitFdtCompat(self): +        """Test an image with an FIT with compatible in the config nodes""" +        entry_args = { +            'of-list': 'model1 model2', +            'default-dt': 'model2', +            } +        testdir, dtb_list = self.SetupAlternateDts() +        data = self._DoReadFileDtb( +            '334_fit_fdt_compat.dts', use_real_dtb=True, update_dtb=True, +            entry_args=entry_args, extra_indirs=[testdir])[0] + +        fit_data = data[len(U_BOOT_DATA):-len(U_BOOT_NODTB_DATA)] + +        fit = fdt.Fdt.FromData(fit_data) +        fit.Scan() + +        cnode = fit.GetNode('/configurations') +        self.assertIn('default', cnode.props) +        self.assertEqual('config-2', cnode.props['default'].value) + +        for seq in range(1, 2): +            name = f'config-{seq}' +            fnode = fit.GetNode('/configurations/%s' % name) +            self.assertIsNotNone(fnode) +            self.assertIn('compatible', fnode.props.keys()) +            expected = 'one' if seq == 1 else 'two' +            self.assertEqual(f'u-boot,model-{expected}', +                             fnode.props['compatible'].value) + +    def testFitFdtPhase(self): +        """Test an image with an FIT with fdt-phase in the fdt nodes""" +        phase = 'tpl' +        entry_args = { +            f'{phase}-dtb': '1', +            f'{phase}-bss-pad': 'y', +            'of-spl-remove-props': 'prop-to-remove another-prop-to-get-rid-of', +            'of-list': 'model1 model2', +            'default-dt': 'model2', +            } +        testdir, dtb_list = self.SetupAlternateDts() +        data = self._DoReadFileDtb( +            '335_fit_fdt_phase.dts', use_real_dtb=True, update_dtb=True, +            entry_args=entry_args, extra_indirs=[testdir])[0] +        fit_data = data[len(U_BOOT_DATA):-len(U_BOOT_NODTB_DATA)] +        fit = fdt.Fdt.FromData(fit_data) +        fit.Scan() + +        # Check that each FDT has only the expected properties for the phase +        for seq in range(1, 2): +            fnode = fit.GetNode(f'/images/fdt-{seq}') +            self.assertIsNotNone(fnode) +            dtb = fdt.Fdt.FromData(fnode.props['data'].bytes) +            dtb.Scan() + +            # Make sure that the 'bootph-pre-sram' tag in /node protects it from +            # removal +            node = dtb.GetNode('/node') +            self.assertIsNotNone(node) +            self.assertEqual({'some-prop', 'not-a-prop-to-remove'}, +                             node.props.keys()) + +            # Make sure the other node is gone +            self.assertIsNone(dtb.GetNode('/node/other-node')) +  if __name__ == "__main__":      unittest.main() | 
