From 63c18fead80fc7a710380f157529f01ea6500d48 Mon Sep 17 00:00:00 2001 From: Tao Bao Date: Wed, 21 Feb 2018 23:45:43 -0800 Subject: [PATCH] releasetools: Add unittests for GetCareMap() and AddCareMapTxtForAbOta(). With test_utils.construct_sparse_image(), creating valid sparse image is no longer a blocker for testing these functions. Test: python -m unittest test_add_img_to_target_files Change-Id: Iff1f15837cc744bad52e2120f9a9ad94d7db50d5 --- tools/releasetools/add_img_to_target_files.py | 11 +- .../test_add_img_to_target_files.py | 173 +++++++++++++++++- 2 files changed, 182 insertions(+), 2 deletions(-) diff --git a/tools/releasetools/add_img_to_target_files.py b/tools/releasetools/add_img_to_target_files.py index a37de6613..bbb5abd0d 100755 --- a/tools/releasetools/add_img_to_target_files.py +++ b/tools/releasetools/add_img_to_target_files.py @@ -96,7 +96,16 @@ class OutputFile(object): def GetCareMap(which, imgname): - """Generates the care_map for the given partition.""" + """Returns the care_map string for the given partition. + + Args: + which: The partition name, must be listed in PARTITIONS_WITH_CARE_MAP. + imgname: The filename of the image. + + Returns: + (which, care_map_ranges): care_map_ranges is the raw string of the care_map + RangeSet. + """ assert which in PARTITIONS_WITH_CARE_MAP simg = sparse_img.SparseImage(imgname) diff --git a/tools/releasetools/test_add_img_to_target_files.py b/tools/releasetools/test_add_img_to_target_files.py index e449ca8fe..9a0f78ed1 100644 --- a/tools/releasetools/test_add_img_to_target_files.py +++ b/tools/releasetools/test_add_img_to_target_files.py @@ -20,7 +20,11 @@ import unittest import zipfile import common -from add_img_to_target_files import AddPackRadioImages, AddRadioImagesForAbOta +import test_utils +from add_img_to_target_files import ( + AddCareMapTxtForAbOta, AddPackRadioImages, AddRadioImagesForAbOta, + GetCareMap) +from rangelib import RangeSet OPTIONS = common.OPTIONS @@ -166,3 +170,170 @@ class AddImagesToTargetFilesTest(unittest.TestCase): self.assertRaises(AssertionError, AddPackRadioImages, None, images + ['baz']) + + @staticmethod + def _test_AddCareMapTxtForAbOta(): + """Helper function to set up the test for test_AddCareMapTxtForAbOta().""" + OPTIONS.info_dict = { + 'system_verity_block_device' : '/dev/block/system', + 'vendor_verity_block_device' : '/dev/block/vendor', + } + + # Prepare the META/ folder. + meta_path = os.path.join(OPTIONS.input_tmp, 'META') + if not os.path.exists(meta_path): + os.mkdir(meta_path) + + system_image = test_utils.construct_sparse_image([ + (0xCAC1, 6), + (0xCAC3, 4), + (0xCAC1, 6)]) + vendor_image = test_utils.construct_sparse_image([ + (0xCAC2, 10)]) + + image_paths = { + 'system' : system_image, + 'vendor' : vendor_image, + } + return image_paths + + def test_AddCareMapTxtForAbOta(self): + image_paths = self._test_AddCareMapTxtForAbOta() + + AddCareMapTxtForAbOta(None, ['system', 'vendor'], image_paths) + + care_map_file = os.path.join(OPTIONS.input_tmp, 'META', 'care_map.txt') + with open(care_map_file, 'r') as verify_fp: + care_map = verify_fp.read() + + lines = care_map.split('\n') + self.assertEqual(4, len(lines)) + self.assertEqual('system', lines[0]) + self.assertEqual(RangeSet("0-5 10-15").to_string_raw(), lines[1]) + self.assertEqual('vendor', lines[2]) + self.assertEqual(RangeSet("0-9").to_string_raw(), lines[3]) + + def test_AddCareMapTxtForAbOta_withNonCareMapPartitions(self): + """Partitions without care_map should be ignored.""" + image_paths = self._test_AddCareMapTxtForAbOta() + + AddCareMapTxtForAbOta( + None, ['boot', 'system', 'vendor', 'vbmeta'], image_paths) + + care_map_file = os.path.join(OPTIONS.input_tmp, 'META', 'care_map.txt') + with open(care_map_file, 'r') as verify_fp: + care_map = verify_fp.read() + + lines = care_map.split('\n') + self.assertEqual(4, len(lines)) + self.assertEqual('system', lines[0]) + self.assertEqual(RangeSet("0-5 10-15").to_string_raw(), lines[1]) + self.assertEqual('vendor', lines[2]) + self.assertEqual(RangeSet("0-9").to_string_raw(), lines[3]) + + def test_AddCareMapTxtForAbOta_withAvb(self): + """Tests the case for device using AVB.""" + image_paths = self._test_AddCareMapTxtForAbOta() + OPTIONS.info_dict = { + 'avb_system_hashtree_enable' : 'true', + 'avb_vendor_hashtree_enable' : 'true', + } + + AddCareMapTxtForAbOta(None, ['system', 'vendor'], image_paths) + + care_map_file = os.path.join(OPTIONS.input_tmp, 'META', 'care_map.txt') + with open(care_map_file, 'r') as verify_fp: + care_map = verify_fp.read() + + lines = care_map.split('\n') + self.assertEqual(4, len(lines)) + self.assertEqual('system', lines[0]) + self.assertEqual(RangeSet("0-5 10-15").to_string_raw(), lines[1]) + self.assertEqual('vendor', lines[2]) + self.assertEqual(RangeSet("0-9").to_string_raw(), lines[3]) + + def test_AddCareMapTxtForAbOta_verityNotEnabled(self): + """No care_map.txt should be generated if verity not enabled.""" + image_paths = self._test_AddCareMapTxtForAbOta() + OPTIONS.info_dict = {} + AddCareMapTxtForAbOta(None, ['system', 'vendor'], image_paths) + + care_map_file = os.path.join(OPTIONS.input_tmp, 'META', 'care_map.txt') + self.assertFalse(os.path.exists(care_map_file)) + + def test_AddCareMapTxtForAbOta_missingImageFile(self): + """Missing image file should be considered fatal.""" + image_paths = self._test_AddCareMapTxtForAbOta() + image_paths['vendor'] = '' + self.assertRaises(AssertionError, AddCareMapTxtForAbOta, None, + ['system', 'vendor'], image_paths) + + def test_AddCareMapTxtForAbOta_zipOutput(self): + """Tests the case with ZIP output.""" + image_paths = self._test_AddCareMapTxtForAbOta() + + output_file = common.MakeTempFile(suffix='.zip') + with zipfile.ZipFile(output_file, 'w') as output_zip: + AddCareMapTxtForAbOta(output_zip, ['system', 'vendor'], image_paths) + + with zipfile.ZipFile(output_file, 'r') as verify_zip: + care_map = verify_zip.read('META/care_map.txt').decode('ascii') + + lines = care_map.split('\n') + self.assertEqual(4, len(lines)) + self.assertEqual('system', lines[0]) + self.assertEqual(RangeSet("0-5 10-15").to_string_raw(), lines[1]) + self.assertEqual('vendor', lines[2]) + self.assertEqual(RangeSet("0-9").to_string_raw(), lines[3]) + + def test_AddCareMapTxtForAbOta_zipOutput_careMapEntryExists(self): + """Tests the case with ZIP output which already has care_map entry.""" + image_paths = self._test_AddCareMapTxtForAbOta() + + output_file = common.MakeTempFile(suffix='.zip') + with zipfile.ZipFile(output_file, 'w') as output_zip: + # Create an existing META/care_map.txt entry. + common.ZipWriteStr(output_zip, 'META/care_map.txt', 'dummy care_map.txt') + + # Request to add META/care_map.txt again. + AddCareMapTxtForAbOta(output_zip, ['system', 'vendor'], image_paths) + + # The one under OPTIONS.input_tmp must have been replaced. + care_map_file = os.path.join(OPTIONS.input_tmp, 'META', 'care_map.txt') + with open(care_map_file, 'r') as verify_fp: + care_map = verify_fp.read() + + lines = care_map.split('\n') + self.assertEqual(4, len(lines)) + self.assertEqual('system', lines[0]) + self.assertEqual(RangeSet("0-5 10-15").to_string_raw(), lines[1]) + self.assertEqual('vendor', lines[2]) + self.assertEqual(RangeSet("0-9").to_string_raw(), lines[3]) + + # The existing entry should be scheduled to be replaced. + self.assertIn('META/care_map.txt', OPTIONS.replace_updated_files_list) + + def test_GetCareMap(self): + sparse_image = test_utils.construct_sparse_image([ + (0xCAC1, 6), + (0xCAC3, 4), + (0xCAC1, 6)]) + OPTIONS.info_dict = { + 'system_adjusted_partition_size' : 12, + } + name, care_map = GetCareMap('system', sparse_image) + self.assertEqual('system', name) + self.assertEqual(RangeSet("0-5 10-12").to_string_raw(), care_map) + + def test_GetCareMap_invalidPartition(self): + self.assertRaises(AssertionError, GetCareMap, 'oem', None) + + def test_GetCareMap_invalidAdjustedPartitionSize(self): + sparse_image = test_utils.construct_sparse_image([ + (0xCAC1, 6), + (0xCAC3, 4), + (0xCAC1, 6)]) + OPTIONS.info_dict = { + 'system_adjusted_partition_size' : -12, + } + self.assertRaises(AssertionError, GetCareMap, 'system', sparse_image)