def test_GetSparseImage_systemRootImage_filenameWithExtraLeadingSlash(self): target_files = common.MakeTempFile(prefix='target_files-', suffix='.zip') with zipfile.ZipFile(target_files, 'w') as target_files_zip: target_files_zip.write( test_utils.construct_sparse_image([(0xCAC2, 16)]), arcname='IMAGES/system.img') target_files_zip.writestr( 'IMAGES/system.map', '\n'.join([ '//system/file1 1-5 9-10', '//system/file2 11-12', '/system/app/file3 13-15'])) target_files_zip.writestr('SYSTEM/file1', os.urandom(4096 * 7)) # '/system/file2' has less blocks listed (2) than actual (3). target_files_zip.writestr('SYSTEM/file2', os.urandom(4096 * 3)) # '/system/app/file3' has less blocks listed (3) than actual (4). target_files_zip.writestr('SYSTEM/app/file3', os.urandom(4096 * 4)) tempdir = common.UnzipTemp(target_files) with zipfile.ZipFile(target_files, 'r') as input_zip: sparse_image = common.GetSparseImage('system', tempdir, input_zip, False) self.assertFalse(sparse_image.file_map['//system/file1'].extra) self.assertTrue(sparse_image.file_map['//system/file2'].extra['incomplete']) self.assertTrue( sparse_image.file_map['/system/app/file3'].extra['incomplete'])
def CheckAllFiles(which): logging.info('Checking %s image.', which) # Allow having shared blocks when loading the sparse image, because allowing # that doesn't affect the checks below (we will have all the blocks on file, # unless it's skipped due to the holes). image = common.GetSparseImage(which, input_tmp, input_zip, True) prefix = '/' + which for entry in image.file_map: # Skip entries like '__NONZERO-0'. if not entry.startswith(prefix): continue # Read the blocks that the file resides. Note that it will contain the # bytes past the file length, which is expected to be padded with '\0's. ranges = image.file_map[entry] incomplete = ranges.extra.get('incomplete', False) if incomplete: logging.warning('Skipping %s that has incomplete block list', entry) continue blocks_sha1 = image.RangeSha1(ranges) # The filename under unpacked directory, such as SYSTEM/bin/sh. unpacked_name = os.path.join(input_tmp, which.upper(), entry[(len(prefix) + 1):]) unpacked_file = _ReadFile(entry, unpacked_name, True) file_sha1 = unpacked_file.sha1 assert blocks_sha1 == file_sha1, \ 'file: %s, range: %s, blocks_sha1: %s, file_sha1: %s' % ( entry, ranges, blocks_sha1, file_sha1)
def CheckAllFiles(which): logging.info('Checking %s image.', which) path = os.path.join(input_tmp, "IMAGES", which + ".img") if not IsSparseImage(path): logging.info("%s is non-sparse image", which) image = common.GetNonSparseImage(which, input_tmp) else: logging.info("%s is sparse image", which) # Allow having shared blocks when loading the sparse image, because allowing # that doesn't affect the checks below (we will have all the blocks on file, # unless it's skipped due to the holes). image = common.GetSparseImage(which, input_tmp, input_zip, True) prefix = '/' + which for entry in image.file_map: # Skip entries like '__NONZERO-0'. if not entry.startswith(prefix): continue # Read the blocks that the file resides. Note that it will contain the # bytes past the file length, which is expected to be padded with '\0's. ranges = image.file_map[entry] # Use the original RangeSet if applicable, which includes the shared # blocks. And this needs to happen before checking the monotonicity flag. if ranges.extra.get('uses_shared_blocks'): file_ranges = ranges.extra['uses_shared_blocks'] else: file_ranges = ranges incomplete = file_ranges.extra.get('incomplete', False) if incomplete: logging.warning('Skipping %s that has incomplete block list', entry) continue # If the file has non-monotonic ranges, read each range in order. if not file_ranges.monotonic: h = sha1() for file_range in file_ranges.extra['text_str'].split(' '): for data in image.ReadRangeSet( rangelib.RangeSet(file_range)): h.update(data) blocks_sha1 = h.hexdigest() else: blocks_sha1 = image.RangeSha1(file_ranges) # The filename under unpacked directory, such as SYSTEM/bin/sh. unpacked_name = os.path.join(input_tmp, which.upper(), entry[(len(prefix) + 1):]) unpacked_file = _ReadFile(entry, unpacked_name, True) file_sha1 = unpacked_file.sha1 assert blocks_sha1 == file_sha1, \ 'file: %s, range: %s, blocks_sha1: %s, file_sha1: %s' % ( entry, file_ranges, blocks_sha1, file_sha1)
def test_GetSparseImage_sharedBlocks_allowed(self): """Tests the case for target using BOARD_EXT4_SHARE_DUP_BLOCKS := true.""" target_files = common.MakeTempFile(prefix='target_files-', suffix='.zip') with zipfile.ZipFile(target_files, 'w') as target_files_zip: # Construct an image with a care_map of "0-5 9-12". target_files_zip.write( test_utils.construct_sparse_image([(0xCAC2, 16)]), arcname='IMAGES/system.img') # Block 10 is shared between two files. target_files_zip.writestr( 'IMAGES/system.map', '\n'.join([ '/system/file1 1-5 9-10', '/system/file2 10-12'])) target_files_zip.writestr('SYSTEM/file1', os.urandom(4096 * 7)) target_files_zip.writestr('SYSTEM/file2', os.urandom(4096 * 3)) tempdir = common.UnzipTemp(target_files) with zipfile.ZipFile(target_files, 'r') as input_zip: sparse_image = common.GetSparseImage('system', tempdir, input_zip, True) self.assertDictEqual( { '__COPY': RangeSet("0"), '__NONZERO-0': RangeSet("6-8 13-15"), '/system/file1': RangeSet("1-5 9-10"), '/system/file2': RangeSet("11-12"), }, sparse_image.file_map) # '/system/file2' should be marked with 'uses_shared_blocks', but not with # 'incomplete'. self.assertTrue( sparse_image.file_map['/system/file2'].extra['uses_shared_blocks']) self.assertNotIn( 'incomplete', sparse_image.file_map['/system/file2'].extra) # All other entries should look normal without any tags. self.assertFalse(sparse_image.file_map['__COPY'].extra) self.assertFalse(sparse_image.file_map['__NONZERO-0'].extra) self.assertFalse(sparse_image.file_map['/system/file1'].extra)
def test_GetSparseImage_incompleteRanges(self): """Tests the case of ext4 images with holes.""" target_files = common.MakeTempFile(prefix='target_files-', suffix='.zip') with zipfile.ZipFile(target_files, 'w') as target_files_zip: target_files_zip.write( test_utils.construct_sparse_image([(0xCAC2, 16)]), arcname='IMAGES/system.img') target_files_zip.writestr( 'IMAGES/system.map', '\n'.join([ '/system/file1 1-5 9-10', '/system/file2 11-12'])) target_files_zip.writestr('SYSTEM/file1', os.urandom(4096 * 7)) # '/system/file2' has less blocks listed (2) than actual (3). target_files_zip.writestr('SYSTEM/file2', os.urandom(4096 * 3)) tempdir = common.UnzipTemp(target_files) with zipfile.ZipFile(target_files, 'r') as input_zip: sparse_image = common.GetSparseImage('system', tempdir, input_zip, False) self.assertFalse(sparse_image.file_map['/system/file1'].extra) self.assertTrue(sparse_image.file_map['/system/file2'].extra['incomplete'])
def test_GetSparseImage_emptyBlockMapFile(self): target_files = common.MakeTempFile(prefix='target_files-', suffix='.zip') with zipfile.ZipFile(target_files, 'w') as target_files_zip: target_files_zip.write(test_utils.construct_sparse_image([ (0xCAC1, 6), (0xCAC3, 3), (0xCAC1, 4) ]), arcname='IMAGES/system.img') target_files_zip.writestr('IMAGES/system.map', '') target_files_zip.writestr('SYSTEM/file1', os.urandom(4096 * 8)) target_files_zip.writestr('SYSTEM/file2', os.urandom(4096 * 3)) tempdir = common.UnzipTemp(target_files) with zipfile.ZipFile(target_files, 'r') as input_zip: sparse_image = common.GetSparseImage('system', tempdir, input_zip, False) self.assertDictEqual( { '__COPY': RangeSet("0"), '__NONZERO-0': RangeSet("1-5 9-12"), }, sparse_image.file_map)