Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fccbf585 authored by Yifan Hong's avatar Yifan Hong Committed by android-build-merger
Browse files

Merge changes from topic "dap_size_check_python" am: bfcfa8c1 am: 7441a6bb

am: 98285321

Change-Id: I0dd0872e98bf437747417a35a91425dd52e8ad0a
parents 6442896a 98285321
Loading
Loading
Loading
Loading
+35 −119
Original line number Diff line number Diff line
@@ -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
@@ -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

@@ -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)), \
@@ -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
@@ -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
+1 −0
Original line number Diff line number Diff line
@@ -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
+14 −0
Original line number Diff line number Diff line
@@ -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"],
@@ -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",
+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()
+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)