Loading core/Makefile +35 −119 Original line number Diff line number Diff line Loading @@ -3616,36 +3616,6 @@ ifeq (,$(TARGET_BUILD_APPS)) ifeq (true,$(PRODUCT_BUILD_SUPER_PARTITION)) # (1): list of items like "system", "vendor", "product", "system_ext" # return: map each item into a command ( wrapped in $$() ) that reads the size define read-size-of-partitions $(foreach image,$(call images-for-partitions,$(1)),$$($(SPARSE_IMG) --get_partition_size $(image))) endef # round result to BOARD_SUPER_PARTITION_ALIGNMENT #$(1): the calculated size ifeq (,$(BOARD_SUPER_PARTITION_ALIGNMENT)) define round-partition-size $(1) endef else define round-partition-size $$((($(1)+$(BOARD_SUPER_PARTITION_ALIGNMENT)-1)/$(BOARD_SUPER_PARTITION_ALIGNMENT)*$(BOARD_SUPER_PARTITION_ALIGNMENT))) endef endif define super-slot-suffix $(if $(filter true,$(AB_OTA_UPDATER)),$(if $(filter true,$(PRODUCT_RETROFIT_DYNAMIC_PARTITIONS)),,_a)) endef ifndef BOARD_SUPER_PARTITION_WARN_LIMIT BOARD_SUPER_PARTITION_WARN_LIMIT := $$(($(BOARD_SUPER_PARTITION_SIZE) * 95 / 100)) endif ifndef BOARD_SUPER_PARTITION_ERROR_LIMIT BOARD_SUPER_PARTITION_ERROR_LIMIT := $(BOARD_SUPER_PARTITION_SIZE) endif droid_targets: check-all-partition-sizes .PHONY: check-all-partition-sizes check-all-partition-sizes-nodeps Loading @@ -3654,103 +3624,28 @@ check_all_partition_sizes_file := $(call intermediates-dir-for,PACKAGING,check-a check-all-partition-sizes: $(check_all_partition_sizes_file) # Add image dependencies so that generated_*_image_info.txt are written before checking. $(check_all_partition_sizes_file): \ $(SPARSE_IMG) \ $(CHECK_PARTITION_SIZES) \ $(call images-for-partitions,$(BOARD_SUPER_PARTITION_PARTITION_LIST)) ifeq ($(PRODUCT_RETROFIT_DYNAMIC_PARTITIONS),true) # Check sum(super partition block devices) == super partition # Non-retrofit devices already defines BOARD_SUPER_PARTITION_SUPER_DEVICE_SIZE = BOARD_SUPER_PARTITION_SIZE define check-super-partition-size size_list="$(foreach device,$(call to-upper,$(BOARD_SUPER_PARTITION_BLOCK_DEVICES)),$(BOARD_SUPER_PARTITION_$(device)_DEVICE_SIZE))"; \ sum_sizes_expr=$$(sed -e 's/ /+/g' <<< "$${size_list}"); \ max_size_expr="$(BOARD_SUPER_PARTITION_SIZE)"; \ if [ $$(( $${sum_sizes_expr} )) -ne $$(( $${max_size_expr} )) ]; then \ echo "The sum of super partition block device sizes is not equal to BOARD_SUPER_PARTITION_SIZE:"; \ echo $${sum_sizes_expr} '!=' $${max_size_expr}; \ exit 1; \ else \ echo "The sum of super partition block device sizes is equal to BOARD_SUPER_PARTITION_SIZE:"; \ echo $${sum_sizes_expr} '==' $${max_size_expr}; \ fi endef endif # $(1): human-readable max size string # $(2): max size expression # $(3): list of partition names # $(4): human-readable warn size string # $(5): warn size expression # $(6): human readable error size string # $(7): error size expression define check-sum-of-partition-sizes partition_size_list="$$(for i in $(call read-size-of-partitions,$(3)); do \ echo $(call round-partition-size,$${i}); \ done)"; \ sum_sizes_expr=$$(tr '\n' '+' <<< "$${partition_size_list}" | sed 's/+$$//'); \ if [ $$(( $${sum_sizes_expr} )) -gt $$(( $(2) )) ]; then \ echo "The sum of sizes of [$(strip $(3))] is larger than $(strip $(1)):"; \ echo $${sum_sizes_expr} '==' $$(( $${sum_sizes_expr} )) '>' "$(2)" '==' $$(( $(2) )); \ exit 1; \ else \ if [[ ! -z "$(7)" ]] && [ $$(( $${sum_sizes_expr} )) -gt $$(( $(7) )) ]; then \ echo "!!!! ERROR !!!! The sum of sizes of [$(strip $(3))] is larger than $(strip $(6)):"; \ echo $${sum_sizes_expr} '==' $$(( $${sum_sizes_expr} )) '>' "$(7)" '==' $$(( $(7) )); \ echo "Super partition is" $$(( $$(( $$(( $${sum_sizes_expr} )) * 100)) / $$(( $(2) )) )) "percent occupied!"; \ exit 1; \ fi; \ if [[ ! -z "$(5)" ]] && [ $$(( $${sum_sizes_expr} )) -gt $$(( $(5) )) ]; then \ echo "!!!! WARNING !!!! The sum of sizes of [$(strip $(3))] is larger than $(strip $(4)):"; \ echo $${sum_sizes_expr} '==' $$(( $${sum_sizes_expr} )) '>' "$(5)" '==' $$(( $(5) )); \ echo "Super partition is" $$(( $$(( $$(( $${sum_sizes_expr} )) * 100)) / $$(( $(2) )) )) "percent occupied!"; \ fi; \ echo "The sum of sizes of [$(strip $(3))] is within $(strip $(1)):"; \ echo $${sum_sizes_expr} '==' $$(( $${sum_sizes_expr} )) '<=' "$(2)" '==' $$(( $(2) )); \ fi; endef # $(1): misc_info.txt define check-all-partition-sizes-target # Check sum(all partitions) <= super partition (/ 2 for A/B devices launched with dynamic partitions) $(if $(BOARD_SUPER_PARTITION_SIZE),$(if $(BOARD_SUPER_PARTITION_PARTITION_LIST), \ $(call check-sum-of-partition-sizes,BOARD_SUPER_PARTITION_SIZE$(if $(call super-slot-suffix), / 2), \ $(BOARD_SUPER_PARTITION_SIZE)$(if $(call super-slot-suffix), / 2),$(BOARD_SUPER_PARTITION_PARTITION_LIST), \ BOARD_SUPER_PARTITION_WARN_LIMIT$(if $(call super-slot-suffix), / 2), \ $(BOARD_SUPER_PARTITION_WARN_LIMIT)$(if $(call super-slot-suffix), / 2), \ BOARD_SUPER_PARTITION_ERROR_LIMIT$(if $(call super-slot-suffix), / 2), \ $(BOARD_SUPER_PARTITION_ERROR_LIMIT)$(if $(call super-slot-suffix), / 2)) \ )) # For each group, check sum(partitions in group) <= group size $(foreach group,$(call to-upper,$(BOARD_SUPER_PARTITION_GROUPS)), \ $(if $(BOARD_$(group)_SIZE),$(if $(BOARD_$(group)_PARTITION_LIST), \ $(call check-sum-of-partition-sizes,BOARD_$(group)_SIZE,$(BOARD_$(group)_SIZE),$(BOARD_$(group)_PARTITION_LIST))))) # Check sum(all group sizes) <= super partition (/ 2 for A/B devices launched with dynamic partitions) if [[ ! -z $(BOARD_SUPER_PARTITION_SIZE) ]]; then \ group_size_list="$(foreach group,$(call to-upper,$(BOARD_SUPER_PARTITION_GROUPS)),$(BOARD_$(group)_SIZE))"; \ sum_sizes_expr=$$(sed -e 's/ /+/g' <<< "$${group_size_list}"); \ max_size_tail=$(if $(call super-slot-suffix)," / 2"); \ max_size_expr="$(BOARD_SUPER_PARTITION_SIZE)$${max_size_tail}"; \ if [ $$(( $${sum_sizes_expr} )) -gt $$(( $${max_size_expr} )) ]; then \ echo "The sum of sizes of [$(strip $(BOARD_SUPER_PARTITION_GROUPS))] is larger than BOARD_SUPER_PARTITION_SIZE$${max_size_tail}:"; \ echo $${sum_sizes_expr} '==' $$(( $${sum_sizes_expr} )) '>' $${max_size_expr} '==' $$(( $${max_size_expr} )); \ exit 1; \ else \ echo "The sum of sizes of [$(strip $(BOARD_SUPER_PARTITION_GROUPS))] is within BOARD_SUPER_PARTITION_SIZE$${max_size_tail}:"; \ echo $${sum_sizes_expr} '==' $$(( $${sum_sizes_expr} )) '<=' $${max_size_expr} '==' $$(( $${max_size_expr} )); \ fi \ fi mkdir -p $(dir $(1)) rm -f $(1) $(call dump-super-image-info, $(1)) $(foreach partition,$(BOARD_SUPER_PARTITION_PARTITION_LIST), \ echo "$(partition)_image="$(call images-for-partitions,$(partition)) >> $(1);) $(CHECK_PARTITION_SIZES) -v $(1) endef $(check_all_partition_sizes_file): $(call check-all-partition-sizes-target) $(call check-super-partition-size) $(call check-all-partition-sizes-target, \ $(call intermediates-dir-for,PACKAGING,check-all-partition-sizes)/misc_info.txt) touch $@ check-all-partition-sizes-nodeps: $(call check-all-partition-sizes-target) $(call check-super-partition-size) $(call check-all-partition-sizes-target, \ $(call intermediates-dir-for,PACKAGING,check-all-partition-sizes-nodeps)/misc_info.txt) endif # PRODUCT_BUILD_SUPER_PARTITION Loading Loading @@ -4161,6 +4056,15 @@ define fs_config (cd $(1); find . -type d | sed 's,$$,/,'; find . \! -type d) | cut -c 3- | sort | sed 's,^,$(2),' | $(HOST_OUT_EXECUTABLES)/fs_config -C -D $(TARGET_OUT) -S $(SELINUX_FC) -R "$(2)" endef # Filter out vendor from the list for AOSP targets. # $(1): list define filter-out-missing-vendor $(if $(INSTALLED_VENDORIMAGE_TARGET),$(1),$(filter-out vendor,$(1))) endef # Information related to dynamic partitions and virtual A/B. This information # is needed for building the super image (see dump-super-image-info) and # building OTA packages. # $(1): file define dump-dynamic-partitions-info $(if $(filter true,$(PRODUCT_USE_DYNAMIC_PARTITIONS)), \ Loading @@ -4178,17 +4082,25 @@ define dump-dynamic-partitions-info $(foreach device,$(BOARD_SUPER_PARTITION_BLOCK_DEVICES), \ echo "super_$(device)_device_size=$(BOARD_SUPER_PARTITION_$(call to-upper,$(device))_DEVICE_SIZE)" >> $(1);) $(if $(BOARD_SUPER_PARTITION_PARTITION_LIST), \ echo "dynamic_partition_list=$(BOARD_SUPER_PARTITION_PARTITION_LIST)" >> $(1)) echo "dynamic_partition_list=$(call filter-out-missing-vendor, $(BOARD_SUPER_PARTITION_PARTITION_LIST))" >> $(1)) $(if $(BOARD_SUPER_PARTITION_GROUPS), echo "super_partition_groups=$(BOARD_SUPER_PARTITION_GROUPS)" >> $(1)) $(foreach group,$(BOARD_SUPER_PARTITION_GROUPS), \ echo "super_$(group)_group_size=$(BOARD_$(call to-upper,$(group))_SIZE)" >> $(1); \ $(if $(BOARD_$(call to-upper,$(group))_PARTITION_LIST), \ echo "super_$(group)_partition_list=$(BOARD_$(call to-upper,$(group))_PARTITION_LIST)" >> $(1);)) echo "super_$(group)_partition_list=$(call filter-out-missing-vendor, $(BOARD_$(call to-upper,$(group))_PARTITION_LIST))" >> $(1);)) $(if $(filter true,$(TARGET_USERIMAGES_SPARSE_EXT_DISABLED)), \ echo "build_non_sparse_super_partition=true" >> $(1)) $(if $(filter true,$(BOARD_SUPER_IMAGE_IN_UPDATE_PACKAGE)), \ echo "super_image_in_update_package=true" >> $(1)) $(if $(BOARD_SUPER_PARTITION_SIZE), \ echo "super_partition_size=$(BOARD_SUPER_PARTITION_SIZE)" >> $(1)) $(if $(BOARD_SUPER_PARTITION_ALIGNMENT), \ echo "super_partition_alignment=$(BOARD_SUPER_PARTITION_ALIGNMENT)" >> $(1)) $(if $(BOARD_SUPER_PARTITION_WARN_LIMIT), \ echo "super_partition_warn_limit=$(BOARD_SUPER_PARTITION_WARN_LIMIT)" >> $(1)) $(if $(BOARD_SUPER_PARTITION_ERROR_LIMIT), \ echo "super_partition_error_limit=$(BOARD_SUPER_PARTITION_ERROR_LIMIT)" >> $(1)) endef # By conditionally including the dependency of the target files package on the Loading Loading @@ -4765,6 +4677,10 @@ define dump-super-image-info $(call dump-dynamic-partitions-info,$(1)) $(if $(filter true,$(AB_OTA_UPDATER)), \ echo "ab_update=true" >> $(1)) $(if $(filter true,$(PRODUCT_VIRTUAL_AB_OTA)), \ echo "virtual_ab=true" >> $(1)) $(if $(filter true,$(PRODUCT_VIRTUAL_AB_OTA_RETROFIT)), \ echo "virtual_ab_retrofit=true" >> $(1)) endef endif # PRODUCT_USE_DYNAMIC_PARTITIONS Loading core/config.mk +1 −0 Original line number Diff line number Diff line Loading @@ -602,6 +602,7 @@ IMG_FROM_TARGET_FILES := $(HOST_OUT_EXECUTABLES)/img_from_target_files$(HOST_EXE MAKE_RECOVERY_PATCH := $(HOST_OUT_EXECUTABLES)/make_recovery_patch$(HOST_EXECUTABLE_SUFFIX) OTA_FROM_TARGET_FILES := $(HOST_OUT_EXECUTABLES)/ota_from_target_files$(HOST_EXECUTABLE_SUFFIX) SPARSE_IMG := $(HOST_OUT_EXECUTABLES)/sparse_img$(HOST_EXECUTABLE_SUFFIX) CHECK_PARTITION_SIZES := $(HOST_OUT_EXECUTABLES)/check_partition_sizes$(HOST_EXECUTABLE_SUFFIX) PROGUARD_HOME := external/proguard PROGUARD := $(PROGUARD_HOME)/bin/proguard.sh Loading tools/releasetools/Android.bp +14 −0 Original line number Diff line number Diff line Loading @@ -263,6 +263,19 @@ python_binary_host { ], } python_binary_host { name: "check_partition_sizes", srcs: [ "check_partition_sizes.py", ], libs: [ "releasetools_common", ], defaults: [ "releasetools_binary_defaults", ], } python_binary_host { name: "check_ota_package_signature", defaults: ["releasetools_binary_defaults"], Loading Loading @@ -419,6 +432,7 @@ python_defaults { name: "releasetools_test_defaults", srcs: [ "check_ota_package_signature.py", "check_partition_sizes.py", "check_target_files_signatures.py", "make_recovery_patch.py", "merge_target_files.py", Loading tools/releasetools/check_partition_sizes.py 0 → 100644 +262 −0 Original line number Diff line number Diff line #!/usr/bin/env python # # Copyright (C) 2019 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """ Check dynamic partition sizes. usage: check_partition_sizes [info.txt] Check dump-super-partitions-info procedure for expected keys in info.txt. In addition, *_image (e.g. system_image, vendor_image, etc.) must be defined for each partition in dynamic_partition_list. Exit code is 0 if successful and non-zero if any failures. """ from __future__ import print_function import logging import sys import common import sparse_img if sys.hexversion < 0x02070000: print("Python 2.7 or newer is required.", file=sys.stderr) sys.exit(1) logger = logging.getLogger(__name__) class Expression(object): def __init__(self, desc, expr, value=None): # Human-readable description self.desc = str(desc) # Numeric expression self.expr = str(expr) # Value of expression self.value = int(expr) if value is None else value def CheckLe(self, other, level=logging.ERROR): format_args = (self.desc, other.desc, self.expr, self.value, other.expr, other.value) if self.value <= other.value: logger.info("%s is less than or equal to %s:\n%s == %d <= %s == %d", *format_args) else: msg = "{} is greater than {}:\n{} == {} > {} == {}".format(*format_args) if level == logging.ERROR: raise RuntimeError(msg) else: logger.log(level, msg) def CheckEq(self, other): format_args = (self.desc, other.desc, self.expr, self.value, other.expr, other.value) if self.value == other.value: logger.info("%s equals %s:\n%s == %d == %s == %d", *format_args) else: raise RuntimeError("{} does not equal {}:\n{} == {} != {} == {}".format( *format_args)) # A/B feature flags class DeviceType(object): NONE = 0 AB = 1 @staticmethod def Get(info_dict): if info_dict.get("ab_update") != "true": return DeviceType.NONE return DeviceType.AB # Dynamic partition feature flags class Dap(object): NONE = 0 RDAP = 1 DAP = 2 @staticmethod def Get(info_dict): if info_dict.get("use_dynamic_partitions") != "true": return Dap.NONE if info_dict.get("dynamic_partition_retrofit") == "true": return Dap.RDAP return Dap.DAP class DynamicPartitionSizeChecker(object): def __init__(self, info_dict): if "super_partition_size" in info_dict: if "super_partition_warn_limit" not in info_dict: info_dict["super_partition_warn_limit"] = \ int(info_dict["super_partition_size"]) * 95 // 100 if "super_partition_error_limit" not in info_dict: info_dict["super_partition_error_limit"] = \ int(info_dict["super_partition_size"]) self.info_dict = info_dict def _ReadSizeOfPartition(self, name): # Tests uses *_image_size instead (to avoid creating empty sparse images # on disk) if name + "_image_size" in self.info_dict: return int(self.info_dict[name + "_image_size"]) return sparse_img.GetImagePartitionSize(self.info_dict[name + "_image"]) # Round result to BOARD_SUPER_PARTITION_ALIGNMENT def _RoundPartitionSize(self, size): alignment = self.info_dict.get("super_partition_alignment") if alignment is None: return size return (size + alignment - 1) // alignment * alignment def _CheckSuperPartitionSize(self): info_dict = self.info_dict super_block_devices = \ info_dict.get("super_block_devices", "").strip().split() size_list = [int(info_dict.get("super_{}_device_size".format(b), "0")) for b in super_block_devices] sum_size = Expression("sum of super partition block device sizes", "+".join(str(size) for size in size_list), sum(size_list)) super_partition_size = Expression("BOARD_SUPER_PARTITION_SIZE", info_dict["super_partition_size"]) sum_size.CheckEq(super_partition_size) def _CheckSumOfPartitionSizes(self, max_size, partition_names, warn_size=None, error_size=None): partition_size_list = [self._RoundPartitionSize( self._ReadSizeOfPartition(p)) for p in partition_names] sum_size = Expression("sum of sizes of {}".format(partition_names), "+".join(str(size) for size in partition_size_list), sum(partition_size_list)) sum_size.CheckLe(max_size) if error_size: sum_size.CheckLe(error_size) if warn_size: sum_size.CheckLe(warn_size, level=logging.WARNING) def _NumDeviceTypesInSuper(self): slot = DeviceType.Get(self.info_dict) dap = Dap.Get(self.info_dict) if dap == Dap.NONE: raise RuntimeError("check_partition_sizes should only be executed on " "builds with dynamic partitions enabled") # Retrofit dynamic partitions: 1 slot per "super", 2 "super"s on the device if dap == Dap.RDAP: if slot != DeviceType.AB: raise RuntimeError("Device with retrofit dynamic partitions must use " "regular (non-Virtual) A/B") return 1 # Launch DAP: 1 super on the device assert dap == Dap.DAP # DAP + A/B: 2 slots in super if slot == DeviceType.AB: return 2 # DAP + non-A/B: 1 slot in super assert slot == DeviceType.NONE return 1 def _CheckAllPartitionSizes(self): info_dict = self.info_dict num_slots = self._NumDeviceTypesInSuper() size_limit_suffix = (" / %d" % num_slots) if num_slots > 1 else "" # Check sum(all partitions) <= super partition (/ 2 for A/B devices launched # with dynamic partitions) if "super_partition_size" in info_dict and \ "dynamic_partition_list" in info_dict: max_size = Expression( "BOARD_SUPER_PARTITION_SIZE{}".format(size_limit_suffix), int(info_dict["super_partition_size"]) // num_slots) warn_limit = Expression( "BOARD_SUPER_PARTITION_WARN_LIMIT{}".format(size_limit_suffix), int(info_dict["super_partition_warn_limit"]) // num_slots) error_limit = Expression( "BOARD_SUPER_PARTITION_ERROR_LIMIT{}".format(size_limit_suffix), int(info_dict["super_partition_error_limit"]) // num_slots) self._CheckSumOfPartitionSizes( max_size, info_dict["dynamic_partition_list"].strip().split(), warn_limit, error_limit) groups = info_dict.get("super_partition_groups", "").strip().split() # For each group, check sum(partitions in group) <= group size for group in groups: if "super_{}_group_size".format(group) in info_dict and \ "super_{}_partition_list".format(group) in info_dict: group_size = Expression( "BOARD_{}_SIZE".format(group), int(info_dict["super_{}_group_size".format(group)])) self._CheckSumOfPartitionSizes( group_size, info_dict["super_{}_partition_list".format(group)].strip().split()) # Check sum(all group sizes) <= super partition (/ 2 for A/B devices # launched with dynamic partitions) if "super_partition_size" in info_dict: group_size_list = [int(info_dict.get( "super_{}_group_size".format(group), 0)) for group in groups] sum_size = Expression("sum of sizes of {}".format(groups), "+".join(str(size) for size in group_size_list), sum(group_size_list)) max_size = Expression( "BOARD_SUPER_PARTITION_SIZE{}".format(size_limit_suffix), int(info_dict["super_partition_size"]) // num_slots) sum_size.CheckLe(max_size) def Run(self): self._CheckAllPartitionSizes() if self.info_dict.get("dynamic_partition_retrofit") == "true": self._CheckSuperPartitionSize() def CheckPartitionSizes(inp): if isinstance(inp, str): info_dict = common.LoadDictionaryFromFile(inp) return DynamicPartitionSizeChecker(info_dict).Run() if isinstance(inp, dict): return DynamicPartitionSizeChecker(inp).Run() raise ValueError("{} is not a dictionary or a valid path".format(inp)) def main(argv): args = common.ParseOptions(argv, __doc__) if len(args) != 1: common.Usage(__doc__) sys.exit(1) common.InitLogging() CheckPartitionSizes(args[0]) if __name__ == "__main__": try: common.CloseInheritedPipes() main(sys.argv[1:]) except common.ExternalError: logger.exception("\n ERROR:\n") sys.exit(1) finally: common.Cleanup() tools/releasetools/test_check_partition_sizes.py 0 → 100644 +94 −0 Original line number Diff line number Diff line # # Copyright (C) 2019 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # import common import test_utils from check_partition_sizes import CheckPartitionSizes class CheckPartitionSizesTest(test_utils.ReleaseToolsTestCase): def setUp(self): self.info_dict = common.LoadDictionaryFromLines(""" use_dynamic_partitions=true ab_update=true super_block_devices=super dynamic_partition_list=system vendor product super_partition_groups=group super_group_partition_list=system vendor product super_partition_size=200 super_super_device_size=200 super_group_group_size=100 system_image_size=50 vendor_image_size=20 product_image_size=20 """.split("\n")) def test_ab(self): CheckPartitionSizes(self.info_dict) def test_non_ab(self): self.info_dict.update(common.LoadDictionaryFromLines(""" ab_update=false super_partition_size=100 super_super_device_size=100 """.split("\n"))) CheckPartitionSizes(self.info_dict) def test_non_dap(self): self.info_dict.update(common.LoadDictionaryFromLines(""" use_dynamic_partitions=false """.split("\n"))) with self.assertRaises(RuntimeError): CheckPartitionSizes(self.info_dict) def test_retrofit_dap(self): self.info_dict.update(common.LoadDictionaryFromLines(""" dynamic_partition_retrofit=true super_block_devices=system vendor super_system_device_size=75 super_vendor_device_size=25 super_partition_size=100 """.split("\n"))) CheckPartitionSizes(self.info_dict) def test_ab_partition_too_big(self): self.info_dict.update(common.LoadDictionaryFromLines(""" system_image_size=100 """.split("\n"))) with self.assertRaises(RuntimeError): CheckPartitionSizes(self.info_dict) def test_ab_group_too_big(self): self.info_dict.update(common.LoadDictionaryFromLines(""" super_group_group_size=110 """.split("\n"))) with self.assertRaises(RuntimeError): CheckPartitionSizes(self.info_dict) def test_no_image(self): del self.info_dict["system_image_size"] with self.assertRaises(KeyError): CheckPartitionSizes(self.info_dict) def test_block_devices_not_match(self): self.info_dict.update(common.LoadDictionaryFromLines(""" dynamic_partition_retrofit=true super_block_devices=system vendor super_system_device_size=80 super_vendor_device_size=25 super_partition_size=100 """.split("\n"))) with self.assertRaises(RuntimeError): CheckPartitionSizes(self.info_dict) Loading
core/Makefile +35 −119 Original line number Diff line number Diff line Loading @@ -3616,36 +3616,6 @@ ifeq (,$(TARGET_BUILD_APPS)) ifeq (true,$(PRODUCT_BUILD_SUPER_PARTITION)) # (1): list of items like "system", "vendor", "product", "system_ext" # return: map each item into a command ( wrapped in $$() ) that reads the size define read-size-of-partitions $(foreach image,$(call images-for-partitions,$(1)),$$($(SPARSE_IMG) --get_partition_size $(image))) endef # round result to BOARD_SUPER_PARTITION_ALIGNMENT #$(1): the calculated size ifeq (,$(BOARD_SUPER_PARTITION_ALIGNMENT)) define round-partition-size $(1) endef else define round-partition-size $$((($(1)+$(BOARD_SUPER_PARTITION_ALIGNMENT)-1)/$(BOARD_SUPER_PARTITION_ALIGNMENT)*$(BOARD_SUPER_PARTITION_ALIGNMENT))) endef endif define super-slot-suffix $(if $(filter true,$(AB_OTA_UPDATER)),$(if $(filter true,$(PRODUCT_RETROFIT_DYNAMIC_PARTITIONS)),,_a)) endef ifndef BOARD_SUPER_PARTITION_WARN_LIMIT BOARD_SUPER_PARTITION_WARN_LIMIT := $$(($(BOARD_SUPER_PARTITION_SIZE) * 95 / 100)) endif ifndef BOARD_SUPER_PARTITION_ERROR_LIMIT BOARD_SUPER_PARTITION_ERROR_LIMIT := $(BOARD_SUPER_PARTITION_SIZE) endif droid_targets: check-all-partition-sizes .PHONY: check-all-partition-sizes check-all-partition-sizes-nodeps Loading @@ -3654,103 +3624,28 @@ check_all_partition_sizes_file := $(call intermediates-dir-for,PACKAGING,check-a check-all-partition-sizes: $(check_all_partition_sizes_file) # Add image dependencies so that generated_*_image_info.txt are written before checking. $(check_all_partition_sizes_file): \ $(SPARSE_IMG) \ $(CHECK_PARTITION_SIZES) \ $(call images-for-partitions,$(BOARD_SUPER_PARTITION_PARTITION_LIST)) ifeq ($(PRODUCT_RETROFIT_DYNAMIC_PARTITIONS),true) # Check sum(super partition block devices) == super partition # Non-retrofit devices already defines BOARD_SUPER_PARTITION_SUPER_DEVICE_SIZE = BOARD_SUPER_PARTITION_SIZE define check-super-partition-size size_list="$(foreach device,$(call to-upper,$(BOARD_SUPER_PARTITION_BLOCK_DEVICES)),$(BOARD_SUPER_PARTITION_$(device)_DEVICE_SIZE))"; \ sum_sizes_expr=$$(sed -e 's/ /+/g' <<< "$${size_list}"); \ max_size_expr="$(BOARD_SUPER_PARTITION_SIZE)"; \ if [ $$(( $${sum_sizes_expr} )) -ne $$(( $${max_size_expr} )) ]; then \ echo "The sum of super partition block device sizes is not equal to BOARD_SUPER_PARTITION_SIZE:"; \ echo $${sum_sizes_expr} '!=' $${max_size_expr}; \ exit 1; \ else \ echo "The sum of super partition block device sizes is equal to BOARD_SUPER_PARTITION_SIZE:"; \ echo $${sum_sizes_expr} '==' $${max_size_expr}; \ fi endef endif # $(1): human-readable max size string # $(2): max size expression # $(3): list of partition names # $(4): human-readable warn size string # $(5): warn size expression # $(6): human readable error size string # $(7): error size expression define check-sum-of-partition-sizes partition_size_list="$$(for i in $(call read-size-of-partitions,$(3)); do \ echo $(call round-partition-size,$${i}); \ done)"; \ sum_sizes_expr=$$(tr '\n' '+' <<< "$${partition_size_list}" | sed 's/+$$//'); \ if [ $$(( $${sum_sizes_expr} )) -gt $$(( $(2) )) ]; then \ echo "The sum of sizes of [$(strip $(3))] is larger than $(strip $(1)):"; \ echo $${sum_sizes_expr} '==' $$(( $${sum_sizes_expr} )) '>' "$(2)" '==' $$(( $(2) )); \ exit 1; \ else \ if [[ ! -z "$(7)" ]] && [ $$(( $${sum_sizes_expr} )) -gt $$(( $(7) )) ]; then \ echo "!!!! ERROR !!!! The sum of sizes of [$(strip $(3))] is larger than $(strip $(6)):"; \ echo $${sum_sizes_expr} '==' $$(( $${sum_sizes_expr} )) '>' "$(7)" '==' $$(( $(7) )); \ echo "Super partition is" $$(( $$(( $$(( $${sum_sizes_expr} )) * 100)) / $$(( $(2) )) )) "percent occupied!"; \ exit 1; \ fi; \ if [[ ! -z "$(5)" ]] && [ $$(( $${sum_sizes_expr} )) -gt $$(( $(5) )) ]; then \ echo "!!!! WARNING !!!! The sum of sizes of [$(strip $(3))] is larger than $(strip $(4)):"; \ echo $${sum_sizes_expr} '==' $$(( $${sum_sizes_expr} )) '>' "$(5)" '==' $$(( $(5) )); \ echo "Super partition is" $$(( $$(( $$(( $${sum_sizes_expr} )) * 100)) / $$(( $(2) )) )) "percent occupied!"; \ fi; \ echo "The sum of sizes of [$(strip $(3))] is within $(strip $(1)):"; \ echo $${sum_sizes_expr} '==' $$(( $${sum_sizes_expr} )) '<=' "$(2)" '==' $$(( $(2) )); \ fi; endef # $(1): misc_info.txt define check-all-partition-sizes-target # Check sum(all partitions) <= super partition (/ 2 for A/B devices launched with dynamic partitions) $(if $(BOARD_SUPER_PARTITION_SIZE),$(if $(BOARD_SUPER_PARTITION_PARTITION_LIST), \ $(call check-sum-of-partition-sizes,BOARD_SUPER_PARTITION_SIZE$(if $(call super-slot-suffix), / 2), \ $(BOARD_SUPER_PARTITION_SIZE)$(if $(call super-slot-suffix), / 2),$(BOARD_SUPER_PARTITION_PARTITION_LIST), \ BOARD_SUPER_PARTITION_WARN_LIMIT$(if $(call super-slot-suffix), / 2), \ $(BOARD_SUPER_PARTITION_WARN_LIMIT)$(if $(call super-slot-suffix), / 2), \ BOARD_SUPER_PARTITION_ERROR_LIMIT$(if $(call super-slot-suffix), / 2), \ $(BOARD_SUPER_PARTITION_ERROR_LIMIT)$(if $(call super-slot-suffix), / 2)) \ )) # For each group, check sum(partitions in group) <= group size $(foreach group,$(call to-upper,$(BOARD_SUPER_PARTITION_GROUPS)), \ $(if $(BOARD_$(group)_SIZE),$(if $(BOARD_$(group)_PARTITION_LIST), \ $(call check-sum-of-partition-sizes,BOARD_$(group)_SIZE,$(BOARD_$(group)_SIZE),$(BOARD_$(group)_PARTITION_LIST))))) # Check sum(all group sizes) <= super partition (/ 2 for A/B devices launched with dynamic partitions) if [[ ! -z $(BOARD_SUPER_PARTITION_SIZE) ]]; then \ group_size_list="$(foreach group,$(call to-upper,$(BOARD_SUPER_PARTITION_GROUPS)),$(BOARD_$(group)_SIZE))"; \ sum_sizes_expr=$$(sed -e 's/ /+/g' <<< "$${group_size_list}"); \ max_size_tail=$(if $(call super-slot-suffix)," / 2"); \ max_size_expr="$(BOARD_SUPER_PARTITION_SIZE)$${max_size_tail}"; \ if [ $$(( $${sum_sizes_expr} )) -gt $$(( $${max_size_expr} )) ]; then \ echo "The sum of sizes of [$(strip $(BOARD_SUPER_PARTITION_GROUPS))] is larger than BOARD_SUPER_PARTITION_SIZE$${max_size_tail}:"; \ echo $${sum_sizes_expr} '==' $$(( $${sum_sizes_expr} )) '>' $${max_size_expr} '==' $$(( $${max_size_expr} )); \ exit 1; \ else \ echo "The sum of sizes of [$(strip $(BOARD_SUPER_PARTITION_GROUPS))] is within BOARD_SUPER_PARTITION_SIZE$${max_size_tail}:"; \ echo $${sum_sizes_expr} '==' $$(( $${sum_sizes_expr} )) '<=' $${max_size_expr} '==' $$(( $${max_size_expr} )); \ fi \ fi mkdir -p $(dir $(1)) rm -f $(1) $(call dump-super-image-info, $(1)) $(foreach partition,$(BOARD_SUPER_PARTITION_PARTITION_LIST), \ echo "$(partition)_image="$(call images-for-partitions,$(partition)) >> $(1);) $(CHECK_PARTITION_SIZES) -v $(1) endef $(check_all_partition_sizes_file): $(call check-all-partition-sizes-target) $(call check-super-partition-size) $(call check-all-partition-sizes-target, \ $(call intermediates-dir-for,PACKAGING,check-all-partition-sizes)/misc_info.txt) touch $@ check-all-partition-sizes-nodeps: $(call check-all-partition-sizes-target) $(call check-super-partition-size) $(call check-all-partition-sizes-target, \ $(call intermediates-dir-for,PACKAGING,check-all-partition-sizes-nodeps)/misc_info.txt) endif # PRODUCT_BUILD_SUPER_PARTITION Loading Loading @@ -4161,6 +4056,15 @@ define fs_config (cd $(1); find . -type d | sed 's,$$,/,'; find . \! -type d) | cut -c 3- | sort | sed 's,^,$(2),' | $(HOST_OUT_EXECUTABLES)/fs_config -C -D $(TARGET_OUT) -S $(SELINUX_FC) -R "$(2)" endef # Filter out vendor from the list for AOSP targets. # $(1): list define filter-out-missing-vendor $(if $(INSTALLED_VENDORIMAGE_TARGET),$(1),$(filter-out vendor,$(1))) endef # Information related to dynamic partitions and virtual A/B. This information # is needed for building the super image (see dump-super-image-info) and # building OTA packages. # $(1): file define dump-dynamic-partitions-info $(if $(filter true,$(PRODUCT_USE_DYNAMIC_PARTITIONS)), \ Loading @@ -4178,17 +4082,25 @@ define dump-dynamic-partitions-info $(foreach device,$(BOARD_SUPER_PARTITION_BLOCK_DEVICES), \ echo "super_$(device)_device_size=$(BOARD_SUPER_PARTITION_$(call to-upper,$(device))_DEVICE_SIZE)" >> $(1);) $(if $(BOARD_SUPER_PARTITION_PARTITION_LIST), \ echo "dynamic_partition_list=$(BOARD_SUPER_PARTITION_PARTITION_LIST)" >> $(1)) echo "dynamic_partition_list=$(call filter-out-missing-vendor, $(BOARD_SUPER_PARTITION_PARTITION_LIST))" >> $(1)) $(if $(BOARD_SUPER_PARTITION_GROUPS), echo "super_partition_groups=$(BOARD_SUPER_PARTITION_GROUPS)" >> $(1)) $(foreach group,$(BOARD_SUPER_PARTITION_GROUPS), \ echo "super_$(group)_group_size=$(BOARD_$(call to-upper,$(group))_SIZE)" >> $(1); \ $(if $(BOARD_$(call to-upper,$(group))_PARTITION_LIST), \ echo "super_$(group)_partition_list=$(BOARD_$(call to-upper,$(group))_PARTITION_LIST)" >> $(1);)) echo "super_$(group)_partition_list=$(call filter-out-missing-vendor, $(BOARD_$(call to-upper,$(group))_PARTITION_LIST))" >> $(1);)) $(if $(filter true,$(TARGET_USERIMAGES_SPARSE_EXT_DISABLED)), \ echo "build_non_sparse_super_partition=true" >> $(1)) $(if $(filter true,$(BOARD_SUPER_IMAGE_IN_UPDATE_PACKAGE)), \ echo "super_image_in_update_package=true" >> $(1)) $(if $(BOARD_SUPER_PARTITION_SIZE), \ echo "super_partition_size=$(BOARD_SUPER_PARTITION_SIZE)" >> $(1)) $(if $(BOARD_SUPER_PARTITION_ALIGNMENT), \ echo "super_partition_alignment=$(BOARD_SUPER_PARTITION_ALIGNMENT)" >> $(1)) $(if $(BOARD_SUPER_PARTITION_WARN_LIMIT), \ echo "super_partition_warn_limit=$(BOARD_SUPER_PARTITION_WARN_LIMIT)" >> $(1)) $(if $(BOARD_SUPER_PARTITION_ERROR_LIMIT), \ echo "super_partition_error_limit=$(BOARD_SUPER_PARTITION_ERROR_LIMIT)" >> $(1)) endef # By conditionally including the dependency of the target files package on the Loading Loading @@ -4765,6 +4677,10 @@ define dump-super-image-info $(call dump-dynamic-partitions-info,$(1)) $(if $(filter true,$(AB_OTA_UPDATER)), \ echo "ab_update=true" >> $(1)) $(if $(filter true,$(PRODUCT_VIRTUAL_AB_OTA)), \ echo "virtual_ab=true" >> $(1)) $(if $(filter true,$(PRODUCT_VIRTUAL_AB_OTA_RETROFIT)), \ echo "virtual_ab_retrofit=true" >> $(1)) endef endif # PRODUCT_USE_DYNAMIC_PARTITIONS Loading
core/config.mk +1 −0 Original line number Diff line number Diff line Loading @@ -602,6 +602,7 @@ IMG_FROM_TARGET_FILES := $(HOST_OUT_EXECUTABLES)/img_from_target_files$(HOST_EXE MAKE_RECOVERY_PATCH := $(HOST_OUT_EXECUTABLES)/make_recovery_patch$(HOST_EXECUTABLE_SUFFIX) OTA_FROM_TARGET_FILES := $(HOST_OUT_EXECUTABLES)/ota_from_target_files$(HOST_EXECUTABLE_SUFFIX) SPARSE_IMG := $(HOST_OUT_EXECUTABLES)/sparse_img$(HOST_EXECUTABLE_SUFFIX) CHECK_PARTITION_SIZES := $(HOST_OUT_EXECUTABLES)/check_partition_sizes$(HOST_EXECUTABLE_SUFFIX) PROGUARD_HOME := external/proguard PROGUARD := $(PROGUARD_HOME)/bin/proguard.sh Loading
tools/releasetools/Android.bp +14 −0 Original line number Diff line number Diff line Loading @@ -263,6 +263,19 @@ python_binary_host { ], } python_binary_host { name: "check_partition_sizes", srcs: [ "check_partition_sizes.py", ], libs: [ "releasetools_common", ], defaults: [ "releasetools_binary_defaults", ], } python_binary_host { name: "check_ota_package_signature", defaults: ["releasetools_binary_defaults"], Loading Loading @@ -419,6 +432,7 @@ python_defaults { name: "releasetools_test_defaults", srcs: [ "check_ota_package_signature.py", "check_partition_sizes.py", "check_target_files_signatures.py", "make_recovery_patch.py", "merge_target_files.py", Loading
tools/releasetools/check_partition_sizes.py 0 → 100644 +262 −0 Original line number Diff line number Diff line #!/usr/bin/env python # # Copyright (C) 2019 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """ Check dynamic partition sizes. usage: check_partition_sizes [info.txt] Check dump-super-partitions-info procedure for expected keys in info.txt. In addition, *_image (e.g. system_image, vendor_image, etc.) must be defined for each partition in dynamic_partition_list. Exit code is 0 if successful and non-zero if any failures. """ from __future__ import print_function import logging import sys import common import sparse_img if sys.hexversion < 0x02070000: print("Python 2.7 or newer is required.", file=sys.stderr) sys.exit(1) logger = logging.getLogger(__name__) class Expression(object): def __init__(self, desc, expr, value=None): # Human-readable description self.desc = str(desc) # Numeric expression self.expr = str(expr) # Value of expression self.value = int(expr) if value is None else value def CheckLe(self, other, level=logging.ERROR): format_args = (self.desc, other.desc, self.expr, self.value, other.expr, other.value) if self.value <= other.value: logger.info("%s is less than or equal to %s:\n%s == %d <= %s == %d", *format_args) else: msg = "{} is greater than {}:\n{} == {} > {} == {}".format(*format_args) if level == logging.ERROR: raise RuntimeError(msg) else: logger.log(level, msg) def CheckEq(self, other): format_args = (self.desc, other.desc, self.expr, self.value, other.expr, other.value) if self.value == other.value: logger.info("%s equals %s:\n%s == %d == %s == %d", *format_args) else: raise RuntimeError("{} does not equal {}:\n{} == {} != {} == {}".format( *format_args)) # A/B feature flags class DeviceType(object): NONE = 0 AB = 1 @staticmethod def Get(info_dict): if info_dict.get("ab_update") != "true": return DeviceType.NONE return DeviceType.AB # Dynamic partition feature flags class Dap(object): NONE = 0 RDAP = 1 DAP = 2 @staticmethod def Get(info_dict): if info_dict.get("use_dynamic_partitions") != "true": return Dap.NONE if info_dict.get("dynamic_partition_retrofit") == "true": return Dap.RDAP return Dap.DAP class DynamicPartitionSizeChecker(object): def __init__(self, info_dict): if "super_partition_size" in info_dict: if "super_partition_warn_limit" not in info_dict: info_dict["super_partition_warn_limit"] = \ int(info_dict["super_partition_size"]) * 95 // 100 if "super_partition_error_limit" not in info_dict: info_dict["super_partition_error_limit"] = \ int(info_dict["super_partition_size"]) self.info_dict = info_dict def _ReadSizeOfPartition(self, name): # Tests uses *_image_size instead (to avoid creating empty sparse images # on disk) if name + "_image_size" in self.info_dict: return int(self.info_dict[name + "_image_size"]) return sparse_img.GetImagePartitionSize(self.info_dict[name + "_image"]) # Round result to BOARD_SUPER_PARTITION_ALIGNMENT def _RoundPartitionSize(self, size): alignment = self.info_dict.get("super_partition_alignment") if alignment is None: return size return (size + alignment - 1) // alignment * alignment def _CheckSuperPartitionSize(self): info_dict = self.info_dict super_block_devices = \ info_dict.get("super_block_devices", "").strip().split() size_list = [int(info_dict.get("super_{}_device_size".format(b), "0")) for b in super_block_devices] sum_size = Expression("sum of super partition block device sizes", "+".join(str(size) for size in size_list), sum(size_list)) super_partition_size = Expression("BOARD_SUPER_PARTITION_SIZE", info_dict["super_partition_size"]) sum_size.CheckEq(super_partition_size) def _CheckSumOfPartitionSizes(self, max_size, partition_names, warn_size=None, error_size=None): partition_size_list = [self._RoundPartitionSize( self._ReadSizeOfPartition(p)) for p in partition_names] sum_size = Expression("sum of sizes of {}".format(partition_names), "+".join(str(size) for size in partition_size_list), sum(partition_size_list)) sum_size.CheckLe(max_size) if error_size: sum_size.CheckLe(error_size) if warn_size: sum_size.CheckLe(warn_size, level=logging.WARNING) def _NumDeviceTypesInSuper(self): slot = DeviceType.Get(self.info_dict) dap = Dap.Get(self.info_dict) if dap == Dap.NONE: raise RuntimeError("check_partition_sizes should only be executed on " "builds with dynamic partitions enabled") # Retrofit dynamic partitions: 1 slot per "super", 2 "super"s on the device if dap == Dap.RDAP: if slot != DeviceType.AB: raise RuntimeError("Device with retrofit dynamic partitions must use " "regular (non-Virtual) A/B") return 1 # Launch DAP: 1 super on the device assert dap == Dap.DAP # DAP + A/B: 2 slots in super if slot == DeviceType.AB: return 2 # DAP + non-A/B: 1 slot in super assert slot == DeviceType.NONE return 1 def _CheckAllPartitionSizes(self): info_dict = self.info_dict num_slots = self._NumDeviceTypesInSuper() size_limit_suffix = (" / %d" % num_slots) if num_slots > 1 else "" # Check sum(all partitions) <= super partition (/ 2 for A/B devices launched # with dynamic partitions) if "super_partition_size" in info_dict and \ "dynamic_partition_list" in info_dict: max_size = Expression( "BOARD_SUPER_PARTITION_SIZE{}".format(size_limit_suffix), int(info_dict["super_partition_size"]) // num_slots) warn_limit = Expression( "BOARD_SUPER_PARTITION_WARN_LIMIT{}".format(size_limit_suffix), int(info_dict["super_partition_warn_limit"]) // num_slots) error_limit = Expression( "BOARD_SUPER_PARTITION_ERROR_LIMIT{}".format(size_limit_suffix), int(info_dict["super_partition_error_limit"]) // num_slots) self._CheckSumOfPartitionSizes( max_size, info_dict["dynamic_partition_list"].strip().split(), warn_limit, error_limit) groups = info_dict.get("super_partition_groups", "").strip().split() # For each group, check sum(partitions in group) <= group size for group in groups: if "super_{}_group_size".format(group) in info_dict and \ "super_{}_partition_list".format(group) in info_dict: group_size = Expression( "BOARD_{}_SIZE".format(group), int(info_dict["super_{}_group_size".format(group)])) self._CheckSumOfPartitionSizes( group_size, info_dict["super_{}_partition_list".format(group)].strip().split()) # Check sum(all group sizes) <= super partition (/ 2 for A/B devices # launched with dynamic partitions) if "super_partition_size" in info_dict: group_size_list = [int(info_dict.get( "super_{}_group_size".format(group), 0)) for group in groups] sum_size = Expression("sum of sizes of {}".format(groups), "+".join(str(size) for size in group_size_list), sum(group_size_list)) max_size = Expression( "BOARD_SUPER_PARTITION_SIZE{}".format(size_limit_suffix), int(info_dict["super_partition_size"]) // num_slots) sum_size.CheckLe(max_size) def Run(self): self._CheckAllPartitionSizes() if self.info_dict.get("dynamic_partition_retrofit") == "true": self._CheckSuperPartitionSize() def CheckPartitionSizes(inp): if isinstance(inp, str): info_dict = common.LoadDictionaryFromFile(inp) return DynamicPartitionSizeChecker(info_dict).Run() if isinstance(inp, dict): return DynamicPartitionSizeChecker(inp).Run() raise ValueError("{} is not a dictionary or a valid path".format(inp)) def main(argv): args = common.ParseOptions(argv, __doc__) if len(args) != 1: common.Usage(__doc__) sys.exit(1) common.InitLogging() CheckPartitionSizes(args[0]) if __name__ == "__main__": try: common.CloseInheritedPipes() main(sys.argv[1:]) except common.ExternalError: logger.exception("\n ERROR:\n") sys.exit(1) finally: common.Cleanup()
tools/releasetools/test_check_partition_sizes.py 0 → 100644 +94 −0 Original line number Diff line number Diff line # # Copyright (C) 2019 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # import common import test_utils from check_partition_sizes import CheckPartitionSizes class CheckPartitionSizesTest(test_utils.ReleaseToolsTestCase): def setUp(self): self.info_dict = common.LoadDictionaryFromLines(""" use_dynamic_partitions=true ab_update=true super_block_devices=super dynamic_partition_list=system vendor product super_partition_groups=group super_group_partition_list=system vendor product super_partition_size=200 super_super_device_size=200 super_group_group_size=100 system_image_size=50 vendor_image_size=20 product_image_size=20 """.split("\n")) def test_ab(self): CheckPartitionSizes(self.info_dict) def test_non_ab(self): self.info_dict.update(common.LoadDictionaryFromLines(""" ab_update=false super_partition_size=100 super_super_device_size=100 """.split("\n"))) CheckPartitionSizes(self.info_dict) def test_non_dap(self): self.info_dict.update(common.LoadDictionaryFromLines(""" use_dynamic_partitions=false """.split("\n"))) with self.assertRaises(RuntimeError): CheckPartitionSizes(self.info_dict) def test_retrofit_dap(self): self.info_dict.update(common.LoadDictionaryFromLines(""" dynamic_partition_retrofit=true super_block_devices=system vendor super_system_device_size=75 super_vendor_device_size=25 super_partition_size=100 """.split("\n"))) CheckPartitionSizes(self.info_dict) def test_ab_partition_too_big(self): self.info_dict.update(common.LoadDictionaryFromLines(""" system_image_size=100 """.split("\n"))) with self.assertRaises(RuntimeError): CheckPartitionSizes(self.info_dict) def test_ab_group_too_big(self): self.info_dict.update(common.LoadDictionaryFromLines(""" super_group_group_size=110 """.split("\n"))) with self.assertRaises(RuntimeError): CheckPartitionSizes(self.info_dict) def test_no_image(self): del self.info_dict["system_image_size"] with self.assertRaises(KeyError): CheckPartitionSizes(self.info_dict) def test_block_devices_not_match(self): self.info_dict.update(common.LoadDictionaryFromLines(""" dynamic_partition_retrofit=true super_block_devices=system vendor super_system_device_size=80 super_vendor_device_size=25 super_partition_size=100 """.split("\n"))) with self.assertRaises(RuntimeError): CheckPartitionSizes(self.info_dict)