X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=tools%2Fbinman%2Fftest.py;h=6b0ab7fdc2a830a91ef8697265a2f5c35bcce731;hb=bf4d0e284267067a65000f37c66cd4f05253381f;hp=bb8862662775c3ff01151250a8b984c29c8f422f;hpb=6ccbfcdd96b9eade93379ad00ee11c7d055d1690;p=oweals%2Fu-boot.git diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py index bb88626627..6b0ab7fdc2 100644 --- a/tools/binman/ftest.py +++ b/tools/binman/ftest.py @@ -23,6 +23,7 @@ import cmdline import command import control import elf +import elf_test import fdt from etype import fdtmap from etype import image_header @@ -39,7 +40,7 @@ import tout U_BOOT_DATA = b'1234' U_BOOT_IMG_DATA = b'img' U_BOOT_SPL_DATA = b'56780123456789abcde' -U_BOOT_TPL_DATA = b'tpl' +U_BOOT_TPL_DATA = b'tpl9876543210fedcb' BLOB_DATA = b'89' ME_DATA = b'0abcd' VGA_DATA = b'vga' @@ -49,6 +50,9 @@ U_BOOT_TPL_DTB_DATA = b'tpldtb' X86_START16_DATA = b'start16' X86_START16_SPL_DATA = b'start16spl' X86_START16_TPL_DATA = b'start16tpl' +X86_RESET16_DATA = b'reset16' +X86_RESET16_SPL_DATA = b'reset16spl' +X86_RESET16_TPL_DATA = b'reset16tpl' PPC_MPC85XX_BR_DATA = b'ppcmpc85xxbr' U_BOOT_NODTB_DATA = b'nodtb with microcode pointer somewhere in here' U_BOOT_SPL_NODTB_DATA = b'splnodtb with microcode pointer somewhere in here' @@ -75,6 +79,9 @@ EXTRACT_DTB_SIZE = 0x3c9 # Properties expected to be in the device tree when update_dtb is used BASE_DTB_PROPS = ['offset', 'size', 'image-pos'] +# Extra properties expected to be in the device tree when allow-repack is used +REPACK_DTB_PROPS = ['orig-offset', 'orig-size'] + class TestFunctional(unittest.TestCase): """Functional tests for binman @@ -91,16 +98,16 @@ class TestFunctional(unittest.TestCase): the test/ diurectory. """ @classmethod - def setUpClass(self): + def setUpClass(cls): global entry import entry # Handle the case where argv[0] is 'python' - self._binman_dir = os.path.dirname(os.path.realpath(sys.argv[0])) - self._binman_pathname = os.path.join(self._binman_dir, 'binman') + cls._binman_dir = os.path.dirname(os.path.realpath(sys.argv[0])) + cls._binman_pathname = os.path.join(cls._binman_dir, 'binman') # Create a temporary directory for input files - self._indir = tempfile.mkdtemp(prefix='binmant.') + cls._indir = tempfile.mkdtemp(prefix='binmant.') # Create some test files TestFunctional._MakeInputFile('u-boot.bin', U_BOOT_DATA) @@ -110,13 +117,23 @@ class TestFunctional(unittest.TestCase): TestFunctional._MakeInputFile('blobfile', BLOB_DATA) TestFunctional._MakeInputFile('me.bin', ME_DATA) TestFunctional._MakeInputFile('vga.bin', VGA_DATA) - self._ResetDtbs() - TestFunctional._MakeInputFile('u-boot-x86-16bit.bin', X86_START16_DATA) + cls._ResetDtbs() + TestFunctional._MakeInputFile('u-boot-br.bin', PPC_MPC85XX_BR_DATA) - TestFunctional._MakeInputFile('spl/u-boot-x86-16bit-spl.bin', + + TestFunctional._MakeInputFile('u-boot-x86-start16.bin', X86_START16_DATA) + TestFunctional._MakeInputFile('spl/u-boot-x86-start16-spl.bin', X86_START16_SPL_DATA) - TestFunctional._MakeInputFile('tpl/u-boot-x86-16bit-tpl.bin', + TestFunctional._MakeInputFile('tpl/u-boot-x86-start16-tpl.bin', X86_START16_TPL_DATA) + + TestFunctional._MakeInputFile('u-boot-x86-reset16.bin', + X86_RESET16_DATA) + TestFunctional._MakeInputFile('spl/u-boot-x86-reset16-spl.bin', + X86_RESET16_SPL_DATA) + TestFunctional._MakeInputFile('tpl/u-boot-x86-reset16-tpl.bin', + X86_RESET16_TPL_DATA) + TestFunctional._MakeInputFile('u-boot-nodtb.bin', U_BOOT_NODTB_DATA) TestFunctional._MakeInputFile('spl/u-boot-spl-nodtb.bin', U_BOOT_SPL_NODTB_DATA) @@ -131,36 +148,39 @@ class TestFunctional(unittest.TestCase): TestFunctional._MakeInputFile('bmpblk.bin', BMPBLK_DATA) TestFunctional._MakeInputFile('refcode.bin', REFCODE_DATA) + cls._elf_testdir = os.path.join(cls._indir, 'elftest') + elf_test.BuildElfTestFiles(cls._elf_testdir) + # ELF file with a '_dt_ucode_base_size' symbol - with open(self.TestFile('u_boot_ucode_ptr'), 'rb') as fd: - TestFunctional._MakeInputFile('u-boot', fd.read()) + TestFunctional._MakeInputFile('u-boot', + tools.ReadFile(cls.ElfTestFile('u_boot_ucode_ptr'))) # Intel flash descriptor file - with open(self.TestFile('descriptor.bin'), 'rb') as fd: + with open(cls.TestFile('descriptor.bin'), 'rb') as fd: TestFunctional._MakeInputFile('descriptor.bin', fd.read()) - shutil.copytree(self.TestFile('files'), - os.path.join(self._indir, 'files')) + shutil.copytree(cls.TestFile('files'), + os.path.join(cls._indir, 'files')) TestFunctional._MakeInputFile('compress', COMPRESS_DATA) # Travis-CI may have an old lz4 - self.have_lz4 = True + cls.have_lz4 = True try: tools.Run('lz4', '--no-frame-crc', '-c', - os.path.join(self._indir, 'u-boot.bin')) + os.path.join(cls._indir, 'u-boot.bin')) except: - self.have_lz4 = False + cls.have_lz4 = False @classmethod - def tearDownClass(self): + def tearDownClass(cls): """Remove the temporary input directory and its contents""" - if self.preserve_indir: - print('Preserving input dir: %s' % self._indir) + if cls.preserve_indir: + print('Preserving input dir: %s' % cls._indir) else: - if self._indir: - shutil.rmtree(self._indir) - self._indir = None + if cls._indir: + shutil.rmtree(cls._indir) + cls._indir = None @classmethod def setup_test_args(cls, preserve_indir=False, preserve_outdirs=False, @@ -184,6 +204,13 @@ class TestFunctional(unittest.TestCase): if not self.have_lz4: self.skipTest('lz4 --no-frame-crc not available') + def _CleanupOutputDir(self): + """Remove the temporary output directory""" + if self.preserve_outdirs: + print('Preserving output dir: %s' % tools.outdir) + else: + tools._FinaliseForTest() + def setUp(self): # Enable this to turn on debugging output # tout.Init(tout.DEBUG) @@ -191,13 +218,32 @@ class TestFunctional(unittest.TestCase): def tearDown(self): """Remove the temporary output directory""" - if self.preserve_outdirs: - print('Preserving output dir: %s' % tools.outdir) - else: - tools._FinaliseForTest() + self._CleanupOutputDir() + + def _SetupImageInTmpdir(self): + """Set up the output image in a new temporary directory + + This is used when an image has been generated in the output directory, + but we want to run binman again. This will create a new output + directory and fail to delete the original one. + + This creates a new temporary directory, copies the image to it (with a + new name) and removes the old output directory. + + Returns: + Tuple: + Temporary directory to use + New image filename + """ + image_fname = tools.GetOutputFilename('image.bin') + tmpdir = tempfile.mkdtemp(prefix='binman.') + updated_fname = os.path.join(tmpdir, 'image-updated.bin') + tools.WriteFile(updated_fname, tools.ReadFile(image_fname)) + self._CleanupOutputDir() + return tmpdir, updated_fname @classmethod - def _ResetDtbs(self): + def _ResetDtbs(cls): TestFunctional._MakeInputFile('u-boot.dtb', U_BOOT_DTB_DATA) TestFunctional._MakeInputFile('spl/u-boot-spl.dtb', U_BOOT_SPL_DTB_DATA) TestFunctional._MakeInputFile('tpl/u-boot-tpl.dtb', U_BOOT_TPL_DTB_DATA) @@ -287,12 +333,12 @@ class TestFunctional(unittest.TestCase): Returns: Contents of device-tree binary """ - tools.PrepareOutputDir(None) - dtb = fdt_util.EnsureCompiled(self.TestFile(fname)) + tmpdir = tempfile.mkdtemp(prefix='binmant.') + dtb = fdt_util.EnsureCompiled(self.TestFile(fname), tmpdir) with open(dtb, 'rb') as fd: data = fd.read() TestFunctional._MakeInputFile(outfile, data) - tools.FinaliseOutputDir() + shutil.rmtree(tmpdir) return data def _GetDtbContentsForSplTpl(self, dtb_data, name): @@ -403,7 +449,7 @@ class TestFunctional(unittest.TestCase): return self._DoReadFileDtb(fname, use_real_dtb)[0] @classmethod - def _MakeInputFile(self, fname, contents): + def _MakeInputFile(cls, fname, contents): """Create a new test input file, creating directories as needed Args: @@ -412,7 +458,7 @@ class TestFunctional(unittest.TestCase): Returns: Full pathname of file created """ - pathname = os.path.join(self._indir, fname) + pathname = os.path.join(cls._indir, fname) dirname = os.path.dirname(pathname) if dirname and not os.path.exists(dirname): os.makedirs(dirname) @@ -421,7 +467,7 @@ class TestFunctional(unittest.TestCase): return pathname @classmethod - def _MakeInputDir(self, dirname): + def _MakeInputDir(cls, dirname): """Create a new test input directory, creating directories as needed Args: @@ -430,24 +476,38 @@ class TestFunctional(unittest.TestCase): Returns: Full pathname of directory created """ - pathname = os.path.join(self._indir, dirname) + pathname = os.path.join(cls._indir, dirname) if not os.path.exists(pathname): os.makedirs(pathname) return pathname @classmethod - def _SetupSplElf(self, src_fname='bss_data'): + def _SetupSplElf(cls, src_fname='bss_data'): """Set up an ELF file with a '_dt_ucode_base_size' symbol Args: Filename of ELF file to use as SPL """ - with open(self.TestFile(src_fname), 'rb') as fd: - TestFunctional._MakeInputFile('spl/u-boot-spl', fd.read()) + TestFunctional._MakeInputFile('spl/u-boot-spl', + tools.ReadFile(cls.ElfTestFile(src_fname))) + + @classmethod + def _SetupTplElf(cls, src_fname='bss_data'): + """Set up an ELF file with a '_dt_ucode_base_size' symbol + + Args: + Filename of ELF file to use as TPL + """ + TestFunctional._MakeInputFile('tpl/u-boot-tpl', + tools.ReadFile(cls.ElfTestFile(src_fname))) + + @classmethod + def TestFile(cls, fname): + return os.path.join(cls._binman_dir, 'test', fname) @classmethod - def TestFile(self, fname): - return os.path.join(self._binman_dir, 'test', fname) + def ElfTestFile(cls, fname): + return os.path.join(cls._elf_testdir, fname) def AssertInList(self, grep_list, target): """Assert that at least one of a list of things is in a target @@ -846,7 +906,7 @@ class TestFunctional(unittest.TestCase): """Test that the end-at-4gb and skip-at-size property can't be used together""" with self.assertRaises(ValueError) as e: - self._DoTestFile('80_4gb_and_skip_at_start_together.dts') + self._DoTestFile('098_4gb_and_skip_at_start_together.dts') self.assertIn("Image '/binman': Provide either 'end-at-4gb' or " "'skip-at-start'", str(e.exception)) @@ -861,7 +921,7 @@ class TestFunctional(unittest.TestCase): def testPackX86Rom(self): """Test that a basic x86 ROM can be created""" self._SetupSplElf() - data = self._DoReadFile('029_x86-rom.dts') + data = self._DoReadFile('029_x86_rom.dts') self.assertEqual(U_BOOT_DATA + tools.GetBytes(0, 7) + U_BOOT_SPL_DATA + tools.GetBytes(0, 2), data) @@ -869,21 +929,21 @@ class TestFunctional(unittest.TestCase): """Test that an invalid Intel descriptor entry is detected""" TestFunctional._MakeInputFile('descriptor.bin', b'') with self.assertRaises(ValueError) as e: - self._DoTestFile('031_x86-rom-me.dts') + self._DoTestFile('031_x86_rom_me.dts') self.assertIn("Node '/binman/intel-descriptor': Cannot find Intel Flash Descriptor (FD) signature", str(e.exception)) def testPackX86RomBadDesc(self): """Test that the Intel requires a descriptor entry""" with self.assertRaises(ValueError) as e: - self._DoTestFile('030_x86-rom-me-no-desc.dts') + self._DoTestFile('030_x86_rom_me_no_desc.dts') self.assertIn("Node '/binman/intel-me': No offset set with " "offset-unset: should another entry provide this correct " "offset?", str(e.exception)) def testPackX86RomMe(self): """Test that an x86 ROM with an ME region can be created""" - data = self._DoReadFile('031_x86-rom-me.dts') + data = self._DoReadFile('031_x86_rom_me.dts') expected_desc = tools.ReadFile(self.TestFile('descriptor.bin')) if data[:0x1000] != expected_desc: self.fail('Expected descriptor binary at start of image') @@ -891,18 +951,18 @@ class TestFunctional(unittest.TestCase): def testPackVga(self): """Test that an image with a VGA binary can be created""" - data = self._DoReadFile('032_intel-vga.dts') + data = self._DoReadFile('032_intel_vga.dts') self.assertEqual(VGA_DATA, data[:len(VGA_DATA)]) def testPackStart16(self): """Test that an image with an x86 start16 region can be created""" - data = self._DoReadFile('033_x86-start16.dts') + data = self._DoReadFile('033_x86_start16.dts') self.assertEqual(X86_START16_DATA, data[:len(X86_START16_DATA)]) def testPackPowerpcMpc85xxBootpgResetvec(self): """Test that an image with powerpc-mpc85xx-bootpg-resetvec can be created""" - data = self._DoReadFile('81_powerpc_mpc85xx_bootpg_resetvec.dts') + data = self._DoReadFile('150_powerpc_mpc85xx_bootpg_resetvec.dts') self.assertEqual(PPC_MPC85XX_BR_DATA, data[:len(PPC_MPC85XX_BR_DATA)]) def _RunMicrocodeTest(self, dts_fname, nodtb_data, ucode_second=False): @@ -1037,8 +1097,8 @@ class TestFunctional(unittest.TestCase): """Test that a U-Boot binary without the microcode symbol is detected""" # ELF file without a '_dt_ucode_base_size' symbol try: - with open(self.TestFile('u_boot_no_ucode_ptr'), 'rb') as fd: - TestFunctional._MakeInputFile('u-boot', fd.read()) + TestFunctional._MakeInputFile('u-boot', + tools.ReadFile(self.ElfTestFile('u_boot_no_ucode_ptr'))) with self.assertRaises(ValueError) as e: self._RunPackUbootSingleMicrocode() @@ -1047,8 +1107,8 @@ class TestFunctional(unittest.TestCase): finally: # Put the original file back - with open(self.TestFile('u_boot_ucode_ptr'), 'rb') as fd: - TestFunctional._MakeInputFile('u-boot', fd.read()) + TestFunctional._MakeInputFile('u-boot', + tools.ReadFile(self.ElfTestFile('u_boot_ucode_ptr'))) def testMicrocodeNotInImage(self): """Test that microcode must be placed within the image""" @@ -1060,8 +1120,8 @@ class TestFunctional(unittest.TestCase): def testWithoutMicrocode(self): """Test that we can cope with an image without microcode (e.g. qemu)""" - with open(self.TestFile('u_boot_no_ucode_ptr'), 'rb') as fd: - TestFunctional._MakeInputFile('u-boot', fd.read()) + TestFunctional._MakeInputFile('u-boot', + tools.ReadFile(self.ElfTestFile('u_boot_no_ucode_ptr'))) data, dtb, _, _ = self._DoReadFileDtb('044_x86_optional_ucode.dts', True) # Now check the device tree has no microcode @@ -1084,17 +1144,17 @@ class TestFunctional(unittest.TestCase): def testPackFsp(self): """Test that an image with a FSP binary can be created""" - data = self._DoReadFile('042_intel-fsp.dts') + data = self._DoReadFile('042_intel_fsp.dts') self.assertEqual(FSP_DATA, data[:len(FSP_DATA)]) def testPackCmc(self): """Test that an image with a CMC binary can be created""" - data = self._DoReadFile('043_intel-cmc.dts') + data = self._DoReadFile('043_intel_cmc.dts') self.assertEqual(CMC_DATA, data[:len(CMC_DATA)]) def testPackVbt(self): """Test that an image with a VBT binary can be created""" - data = self._DoReadFile('046_intel-vbt.dts') + data = self._DoReadFile('046_intel_vbt.dts') self.assertEqual(VBT_DATA, data[:len(VBT_DATA)]) def testSplBssPad(self): @@ -1115,7 +1175,7 @@ class TestFunctional(unittest.TestCase): def testPackStart16Spl(self): """Test that an image with an x86 start16 SPL region can be created""" - data = self._DoReadFile('048_x86-start16-spl.dts') + data = self._DoReadFile('048_x86_start16_spl.dts') self.assertEqual(X86_START16_SPL_DATA, data[:len(X86_START16_SPL_DATA)]) def _PackUbootSplMicrocode(self, dts, ucode_second=False): @@ -1169,14 +1229,14 @@ class TestFunctional(unittest.TestCase): def testSymbols(self): """Test binman can assign symbols embedded in U-Boot""" - elf_fname = self.TestFile('u_boot_binman_syms') + elf_fname = self.ElfTestFile('u_boot_binman_syms') syms = elf.GetSymbols(elf_fname, ['binman', 'image']) addr = elf.GetSymbolAddress(elf_fname, '__image_copy_start') self.assertEqual(syms['_binman_u_boot_spl_prop_offset'].address, addr) self._SetupSplElf('u_boot_binman_syms') data = self._DoReadFile('053_symbols.dts') - sym_values = struct.pack('