def test_invalid_driver(self): """Test output from a device tree file with an invalid driver""" dtb_file = get_dtb_file('dtoc_test_invalid_driver.dts') output = tools.GetOutputFilename('output') with test_util.capture_sys_output() as _: dtb_platdata.run_steps(['struct'], dtb_file, False, output, []) with open(output) as infile: data = infile.read() self._check_strings(HEADER + ''' struct dtd_invalid { }; ''', data) with test_util.capture_sys_output() as _: dtb_platdata.run_steps(['platdata'], dtb_file, False, output, []) with open(output) as infile: data = infile.read() self._check_strings(C_HEADER + ''' /* Node /spl-test index 0 */ static struct dtd_invalid dtv_spl_test = { }; U_BOOT_DRVINFO(spl_test) = { \t.name\t\t= "invalid", \t.plat\t= &dtv_spl_test, \t.plat_size\t= sizeof(dtv_spl_test), \t.parent_idx\t= -1, }; ''', data)
def test_invalid_driver(self): """Test output from a device tree file with an invalid driver""" dtb_file = get_dtb_file('dtoc_test_invalid_driver.dts') output = tools.GetOutputFilename('output') with test_util.capture_sys_output() as (stdout, stderr): dtb_platdata.run_steps(['struct'], dtb_file, False, output) with open(output) as infile: data = infile.read() self._CheckStrings(HEADER + ''' struct dtd_invalid { }; ''', data) with test_util.capture_sys_output() as (stdout, stderr): dtb_platdata.run_steps(['platdata'], dtb_file, False, output) with open(output) as infile: data = infile.read() self._CheckStrings( C_HEADER + ''' static struct dtd_invalid dtv_spl_test = { }; U_BOOT_DEVICE(spl_test) = { \t.name\t\t= "invalid", \t.platdata\t= &dtv_spl_test, \t.platdata_size\t= sizeof(dtv_spl_test), }; void dm_populate_phandle_data(void) { } ''', data)
def test_branch(self): """Test creating patches from a branch""" repo = self.make_git_tree() target = repo.lookup_reference('refs/heads/first') # pylint doesn't seem to find this # pylint: disable=E1101 self.repo.checkout(target, strategy=pygit2.GIT_CHECKOUT_FORCE) control.setup() try: orig_dir = os.getcwd() os.chdir(self.gitdir) # Check that it can detect the current branch self.assertEqual(2, gitutil.count_commits_to_branch(None)) col = terminal.Color() with capture_sys_output() as _: _, cover_fname, patch_files = control.prepare_patches( col, branch=None, count=-1, start=0, end=0, ignore_binary=False, signoff=True) self.assertIsNone(cover_fname) self.assertEqual(2, len(patch_files)) # Check that it can detect a different branch self.assertEqual(3, gitutil.count_commits_to_branch('second')) with capture_sys_output() as _: _, cover_fname, patch_files = control.prepare_patches( col, branch='second', count=-1, start=0, end=0, ignore_binary=False, signoff=True) self.assertIsNotNone(cover_fname) self.assertEqual(3, len(patch_files)) # Check that it can skip patches at the end with capture_sys_output() as _: _, cover_fname, patch_files = control.prepare_patches( col, branch='second', count=-1, start=0, end=1, ignore_binary=False, signoff=True) self.assertIsNotNone(cover_fname) self.assertEqual(2, len(patch_files)) finally: os.chdir(orig_dir)
def test_version(self): """Check handling of a tool being present or absent""" btest = Bintool.create('_testing') with test_util.capture_sys_output() as (stdout, _): btest.show() self.assertFalse(btest.is_present()) self.assertIn('-', stdout.getvalue()) btest.present = True self.assertTrue(btest.is_present()) self.assertEqual('123', btest.version()) with test_util.capture_sys_output() as (stdout, _): btest.show() self.assertIn('123', stdout.getvalue())
def test_all_bintools(self): """Test that all bintools can handle all available fetch types""" def handle_download(_): """Take the tools.Download() function by writing a file""" tools.WriteFile(fname, expected) return fname, dirname def fake_run(*cmd): if cmd[0] == 'make': # See Bintool.build_from_git() tmpdir = cmd[2] self.fname = os.path.join(tmpdir, 'pathname') tools.WriteFile(self.fname, b'hello') expected = b'this is a test' dirname = os.path.join(self._indir, 'download_dir') os.mkdir(dirname) fname = os.path.join(dirname, 'downloaded') with unittest.mock.patch.object(tools, 'Run', side_effect=fake_run): with unittest.mock.patch.object(tools, 'Download', side_effect=handle_download): with test_util.capture_sys_output() as _: for name in Bintool.get_tool_list(): btool = Bintool.create(name) for method in range(bintool.FETCH_COUNT): result = btool.fetch(method) self.assertTrue(result is not False) if result is not True and result is not None: result_fname, _ = result self.assertTrue(os.path.exists(result_fname)) data = tools.ReadFile(result_fname) self.assertEqual(expected, data) os.remove(result_fname)
def check_build_method(self, write_file): """Check the output from fetching using the BUILD method Args: write_file (bool): True to write the output file when 'make' is called Returns: tuple: str: Filename of written file (or missing 'make' output) str: Contents of stdout """ def fake_run(*cmd): if cmd[0] == 'make': # See Bintool.build_from_git() tmpdir = cmd[2] self.fname = os.path.join(tmpdir, 'pathname') if write_file: tools.WriteFile(self.fname, b'hello') btest = Bintool.create('_testing') col = terminal.Color() self.fname = None with unittest.mock.patch.object(bintool, 'DOWNLOAD_DESTDIR', self._indir): with unittest.mock.patch.object(tools, 'Run', side_effect=fake_run): with test_util.capture_sys_output() as (stdout, _): btest.fetch_tool(bintool.FETCH_BUILD, col, False) fname = os.path.join(self._indir, '_testing') return fname if write_file else self.fname, stdout.getvalue()
def test_fetch_pass_fail(self): """Test fetching multiple tools with some passing and some failing""" def handle_download(_): """Take the tools.Download() function by writing a file""" if self.seq: raise urllib.error.URLError('not found') self.seq += 1 tools.WriteFile(fname, expected) return fname, dirname expected = b'this is a test' dirname = os.path.join(self._indir, 'download_dir') os.mkdir(dirname) fname = os.path.join(dirname, 'downloaded') destdir = os.path.join(self._indir, 'dest_dir') os.mkdir(destdir) dest_fname = os.path.join(destdir, '_testing') self.seq = 0 with unittest.mock.patch.object(bintool, 'DOWNLOAD_DESTDIR', destdir): with unittest.mock.patch.object(tools, 'Download', side_effect=handle_download): with test_util.capture_sys_output() as (stdout, _): Bintool.fetch_tools(bintool.FETCH_ANY, ['_testing'] * 2) self.assertTrue(os.path.exists(dest_fname)) data = tools.ReadFile(dest_fname) self.assertEqual(expected, data) lines = stdout.getvalue().splitlines() self.assertTrue(len(lines) > 2) self.assertEqual('Tools fetched: 1: _testing', lines[-2]) self.assertEqual('Failures: 1: _testing', lines[-1])
def test_dup_drivers(self): """Test handling of duplicate drivers""" name = 'nvidia_tegra114_i2c' scan, drv1, driver2, node = self.setup_dup_drivers(name) self.assertEqual('', drv1.phase) # The driver should not have a duplicate yet self.assertEqual([], drv1.dups) scan._parse_driver('file2.c', driver2) # The first driver should now be a duplicate of the second drv2 = scan._drivers[name] self.assertEqual('', drv2.phase) self.assertEqual(1, len(drv2.dups)) self.assertEqual([drv1], drv2.dups) # There is no way to distinguish them, so we should expect a warning self.assertTrue(drv2.warn_dups) # We should see a warning with test_util.capture_sys_output() as (stdout, _): scan.mark_used([node]) self.assertEqual( "Warning: Duplicate driver name 'nvidia_tegra114_i2c' (orig=file2.c, dups=file1.c)", stdout.getvalue().strip())
def test_cbfs_bad_attribute(self): """Check handling of bad attribute tag""" if not self.have_lz4: self.skipTest('lz4 --no-frame-crc not available') size = 0x140 cbw = CbfsWriter(size) cbw.add_file_raw('u-boot', COMPRESS_DATA, None, compress=cbfs_util.COMPRESS_LZ4) data = cbw.get_data() # Search the CBFS for the expected compression tag with io.BytesIO(data) as fd: while True: pos = fd.tell() tag, = struct.unpack('>I', fd.read(4)) if tag == cbfs_util.FILE_ATTR_TAG_COMPRESSION: break # Create a new CBFS with the tag changed to something invalid newdata = data[:pos] + struct.pack('>I', 0x123) + data[pos + 4:] with test_util.capture_sys_output() as (stdout, _stderr): cbfs_util.CbfsReader(newdata) self.assertEqual('Unknown attribute tag 123\n', stdout.getvalue())
def test_cbfs_missing_attribute(self): """Check handling of an incomplete attribute tag""" if not self.have_lz4: self.skipTest('lz4 --no-frame-crc not available') size = 0x140 cbw = CbfsWriter(size) cbw.add_file_raw('u-boot', COMPRESS_DATA, None, compress=cbfs_util.COMPRESS_LZ4) data = cbw.get_data() # Read in the CBFS master header (only), then stop cbr = cbfs_util.CbfsReader(data, read=False) with io.BytesIO(data) as fd: self.assertTrue(cbr._find_and_read_header(fd, len(data))) pos = fd.tell() # Create a new CBFS with only the first 4 bytes of the compression tag, # then try to read the file tag_pos = pos + cbfs_util.FILE_HEADER_LEN + cbfs_util.FILENAME_ALIGN newdata = data[:tag_pos + 4] with test_util.capture_sys_output() as (stdout, _stderr): with io.BytesIO(newdata) as fd: fd.seek(pos) self.assertEqual(False, cbr._read_next_file(fd)) self.assertIn('Attribute tag at %x ran out of data' % tag_pos, stdout.getvalue())
def testScanDrivers(self): """Test running dtoc with additional drivers to scan""" dtb_file = get_dtb_file('dtoc_test_simple.dts') output = tools.GetOutputFilename('output') with test_util.capture_sys_output() as (stdout, stderr): dtb_platdata.run_steps(['struct'], dtb_file, False, output, True, [None, '', 'tools/dtoc/dtoc_test_scan_drivers.cxx'])
def test_fiptool_errors(self): """Check some error reporting from fiptool""" with self.assertRaises(Exception) as err: with test_util.capture_sys_output(): fip_util.fiptool('create', '--fred') self.assertIn("Failed to run (error 1): 'fiptool create --fred'", str(err.exception))
def test_normalized_name(self): """Test operation of get_normalized_compat_name()""" prop = FakeProp() prop.name = 'compatible' prop.value = 'rockchip,rk3288-grf' node = FakeNode() node.props = {'compatible': prop} # get_normalized_compat_name() uses this to check for root node node.parent = FakeNode() scan = src_scan.Scanner(None, None) with test_util.capture_sys_output() as (stdout, _): name, aliases = scan.get_normalized_compat_name(node) self.assertEqual('rockchip_rk3288_grf', name) self.assertEqual([], aliases) self.assertEqual(1, len(scan._missing_drivers)) self.assertEqual({'rockchip_rk3288_grf'}, scan._missing_drivers) self.assertEqual('', stdout.getvalue().strip()) self.assertEqual(EXPECT_WARN, scan._warnings) i2c = 'I2C_UCLASS' compat = { 'rockchip,rk3288-grf': 'ROCKCHIP_SYSCON_GRF', 'rockchip,rk3288-srf': None } drv = src_scan.Driver('fred', 'fred.c') drv.uclass_id = i2c drv.compat = compat scan._drivers['rockchip_rk3288_grf'] = drv scan._driver_aliases['rockchip_rk3288_srf'] = 'rockchip_rk3288_grf' with test_util.capture_sys_output() as (stdout, _): name, aliases = scan.get_normalized_compat_name(node) self.assertEqual('', stdout.getvalue().strip()) self.assertEqual('rockchip_rk3288_grf', name) self.assertEqual([], aliases) self.assertEqual(EXPECT_WARN, scan._warnings) prop.value = 'rockchip,rk3288-srf' with test_util.capture_sys_output() as (stdout, _): name, aliases = scan.get_normalized_compat_name(node) self.assertEqual('', stdout.getvalue().strip()) self.assertEqual('rockchip_rk3288_grf', name) self.assertEqual(['rockchip_rk3288_srf'], aliases) self.assertEqual(EXPECT_WARN, scan._warnings)
def testThreadExceptions(self): """Test that exceptions in threads are reported""" with test_util.capture_sys_output() as (stdout, stderr): self.assertEqual(102, self._RunControl('-o', self._output_dir, test_thread_exceptions=True)) self.assertIn( 'Thread exception (use -T0 to run without threads): test exception', stdout.getvalue())
def test_status_mismatch(self): """Test Patchwork patches not matching the series""" series = Series() with capture_sys_output() as (_, err): status.collect_patches(series, 1234, None, self._fake_patchwork) self.assertIn('Warning: Patchwork reports 1 patches, series has 0', err.getvalue())
def testToolchainDownload(self): """Test that we can download toolchains""" if use_network: with test_util.capture_sys_output() as (stdout, stderr): url = self.toolchains.LocateArchUrl('arm') self.assertRegexpMatches(url, 'https://www.kernel.org/pub/tools/' 'crosstool/files/bin/x86_64/.*/' 'x86_64-gcc-.*-nolibc[-_]arm-.*linux-gnueabi.tar.xz')
def test_no_fetch(self): """Test fetching when there is no method""" btest = Bintool.create('_testing') btest.disable = True col = terminal.Color() with test_util.capture_sys_output() as _: result = btest.fetch_tool(bintool.FETCH_BIN, col, False) self.assertEqual(bintool.FAIL, result)
def test_struct_scan_errors(self): """Test scanning a header file with an invalid unicode file""" output = tools.GetOutputFilename('output.h') tools.WriteFile(output, b'struct this is a test \x81 of bad unicode') scan = src_scan.Scanner(None, None) with test_util.capture_sys_output() as (stdout, _): scan.scan_header(output) self.assertIn('due to unicode error', stdout.getvalue())
def testMissingSymbolOptional(self): image = Image('name', 'node', test=True) image._entries = {} with capture_sys_output() as (stdout, stderr): val = image.LookupSymbol('_binman_type_prop_pname', True, 'msg', 0) self.assertEqual(val, None) self.assertEqual("Warning: msg: Entry 'type' not found in list ()\n", stderr.getvalue()) self.assertEqual('', stdout.getvalue())
def test_install(self): """Test fetching using the install method""" btest = Bintool.create('_testing') btest.install = True col = terminal.Color() with unittest.mock.patch.object(tools, 'Run', return_value=None): with test_util.capture_sys_output() as _: result = btest.fetch_tool(bintool.FETCH_BIN, col, False) self.assertEqual(bintool.FETCHED, result)
def test_changes(self): """Check handling of a source file that does/doesn't need changes""" self.setup_readme() self.setup_macro() self.setup_name() # Check generating the file when changes are needed tools.WriteFile(self.src_file, ''' # This is taken from tbbr_config.c in ARM Trusted Firmware FIP_TYPE_LIST = [ # ToC Entry UUIDs FipType('scp-fwu-cfg', 'SCP Firmware Updater Configuration FWU SCP_BL2U', [0x65, 0x92, 0x27, 0x03, 0x2f, 0x74, 0xe6, 0x44, 0x8d, 0xff, 0x57, 0x9a, 0xc1, 0xff, 0x06, 0x10]), ] # end blah de blah ''', binary=False) with test_util.capture_sys_output() as (stdout, _): fip_util.main(self.args, self.src_file) self.assertIn('Needs update', stdout.getvalue()) # Check generating the file when no changes are needed tools.WriteFile(self.src_file, ''' # This is taken from tbbr_config.c in ARM Trusted Firmware FIP_TYPE_LIST = [ # ToC Entry UUIDs FipType('scp-fwu-cfg', 'SCP Firmware Updater Configuration FWU SCP_BL2U', [0x65, 0x92, 0x27, 0x03, 0x2f, 0x74, 0xe6, 0x44, 0x8d, 0xff, 0x57, 0x9a, 0xc1, 0xff, 0x06, 0x10]), FipType('ap-fwu-cfg', 'AP Firmware Updater Configuration BL2U', [0x60, 0xb3, 0xeb, 0x37, 0xc1, 0xe5, 0xea, 0x41, 0x9d, 0xf3, 0x19, 0xed, 0xa1, 0x1f, 0x68, 0x01]), ] # end blah blah''', binary=False) with test_util.capture_sys_output() as (stdout, _): fip_util.main(self.args, self.src_file) self.assertIn('is up-to-date', stdout.getvalue())
def test_no_debug(self): """Test running without the -D flag""" self.setup_readme() self.setup_macro() self.setup_name() args = self.args.copy() args.remove('-D') tools.WriteFile(self.src_file, '', binary=False) with test_util.capture_sys_output(): fip_util.main(args, self.src_file)
def testDebug(self): """Check that enabling debug in the elf module produced debug output""" try: tout.Init(tout.DEBUG) entry = FakeEntry(20) section = FakeSection() elf_fname = self.ElfTestFile('u_boot_binman_syms') with test_util.capture_sys_output() as (stdout, stderr): syms = elf.LookupAndWriteSymbols(elf_fname, entry, section) self.assertTrue(len(stdout.getvalue()) > 0) finally: tout.Init(tout.WARNING)
def test_cbfs_debug(self): """Check debug output""" size = 0x70 cbw = CbfsWriter(size) cbw.add_file_raw('u-boot', U_BOOT_DATA) data = cbw.get_data() try: cbfs_util.DEBUG = True with test_util.capture_sys_output() as (stdout, _stderr): cbfs_util.CbfsReader(data) self.assertEqual('name u-boot\ndata %s\n' % U_BOOT_DATA, stdout.getvalue()) finally: cbfs_util.DEBUG = False
def test_cbfs_bad_header(self): """Check handling of a bad master header""" size = 0x70 cbw = CbfsWriter(size) cbw.add_file_raw('u-boot', U_BOOT_DATA) data = cbw.get_data() # Drop most of the header and try reading the modified CBFS newdata = data[:cbw._header_offset + 4] with test_util.capture_sys_output() as (stdout, _stderr): with self.assertRaises(ValueError) as e: cbfs_util.CbfsReader(newdata) self.assertIn('Relative offset seems wrong', stdout.getvalue()) self.assertIn('Cannot find master header', str(e.exception))
def testUnicodeError(self): """Test running dtoc with an invalid unicode file To be able to perform this test without adding a weird text file which would produce issues when using checkpatch.pl or patman, generate the file at runtime and then process it. """ dtb_file = get_dtb_file('dtoc_test_simple.dts') output = tools.GetOutputFilename('output') driver_fn = '/tmp/' + next(tempfile._get_candidate_names()) with open(driver_fn, 'wb+') as df: df.write(b'\x81') with test_util.capture_sys_output() as (stdout, stderr): dtb_platdata.run_steps(['struct'], dtb_file, False, output, True, [driver_fn])
def test_cbfstool_failure(self): """Test failure to run cbfstool""" if not self.have_cbfstool: self.skipTest('No cbfstool available') try: # In verbose mode this test fails since stderr is not captured. Fix # this by turning off verbosity. old_verbose = cbfs_util.VERBOSE cbfs_util.VERBOSE = False with test_util.capture_sys_output() as (_stdout, stderr): with self.assertRaises(Exception) as e: cbfs_util.cbfstool('missing-file', 'bad-command') finally: cbfs_util.VERBOSE = old_verbose self.assertIn('Unknown command', stderr.getvalue()) self.assertIn('Failed to run', str(e.exception))
def test_cbfs_bad_header_ptr(self): """Check handling of a bad master-header pointer""" size = 0x70 cbw = CbfsWriter(size) cbw.add_file_raw('u-boot', U_BOOT_DATA) data = cbw.get_data() # Add one to the pointer to make it invalid newdata = data[:-4] + struct.pack('<I', cbw._header_offset + 1) # We should still be able to find the master header by searching with test_util.capture_sys_output() as (stdout, _stderr): cbfs = cbfs_util.CbfsReader(newdata) self.assertIn('Relative offset seems wrong', stdout.getvalue()) self.assertIn('u-boot', cbfs.files) self.assertEqual(size, cbfs.rom_size)
def test_unicode_error(self): """Test running dtoc with an invalid unicode file To be able to perform this test without adding a weird text file which would produce issues when using checkpatch.pl or patman, generate the file at runtime and then process it. """ driver_fn = '/tmp/' + next(tempfile._get_candidate_names()) with open(driver_fn, 'wb+') as fout: fout.write(b'\x81') scan = src_scan.Scanner(None, [driver_fn]) with test_util.capture_sys_output() as (stdout, _): scan.scan_drivers() self.assertRegex(stdout.getvalue(), r"Skipping file '.*' due to unicode error\s*")
def test_uuid_not_in_tbbr_config_c(self): """Check handling a UUID in the header file that's not in the .c file""" self.setup_readme() self.setup_macro(self.macro_contents + ''' #define UUID_TRUSTED_OS_FW_KEY_CERT \\ {{0x94, 0x77, 0xd6, 0x03}, {0xfb, 0x60}, {0xe4, 0x11}, 0x85, 0xdd, {0xb7, 0x10, 0x5b, 0x8c, 0xee, 0x04} } ''') self.setup_name() macros = fip_util.parse_macros(self._indir) names = fip_util.parse_names(self._indir) with test_util.capture_sys_output() as (stdout, _): fip_util.create_code_output(macros, names) self.assertIn( "UUID 'UUID_TRUSTED_OS_FW_KEY_CERT' is not mentioned in tbbr_config.c file", stdout.getvalue())