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
diff --git a/tools/releasetools/add_img_to_target_files.py b/tools/releasetools/add_img_to_target_files.py
index a37de66..bbb5abd 100755
--- a/tools/releasetools/add_img_to_target_files.py
+++ b/tools/releasetools/add_img_to_target_files.py
@@ -96,7 +96,16 @@
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 e449ca8..9a0f78e 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 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 @@
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)