diff --git a/tools/releasetools/add_img_to_target_files.py b/tools/releasetools/add_img_to_target_files.py index 70ea967b3e..7db506c72f 100755 --- a/tools/releasetools/add_img_to_target_files.py +++ b/tools/releasetools/add_img_to_target_files.py @@ -548,19 +548,17 @@ def AddCareMapForAbOta(output_zip, ab_partitions, image_paths): care_map_list += care_map # adds fingerprint field to the care_map - # TODO(xunchang) revisit the fingerprint calculation for care_map. - partition_props = OPTIONS.info_dict.get(partition + ".build.prop") + build_props = OPTIONS.info_dict.get(partition + ".build.prop", {}) prop_name_list = ["ro.{}.build.fingerprint".format(partition), "ro.{}.build.thumbprint".format(partition)] - present_props = [x for x in prop_name_list if - partition_props and partition_props.GetProp(x)] + present_props = [x for x in prop_name_list if x in build_props] if not present_props: logger.warning("fingerprint is not present for partition %s", partition) property_id, fingerprint = "unknown", "unknown" else: property_id = present_props[0] - fingerprint = partition_props.GetProp(property_id) + fingerprint = build_props[property_id] care_map_list += [property_id, fingerprint] if not care_map_list: diff --git a/tools/releasetools/build_image.py b/tools/releasetools/build_image.py index 7567346493..f30f7876ab 100755 --- a/tools/releasetools/build_image.py +++ b/tools/releasetools/build_image.py @@ -509,9 +509,9 @@ def ImagePropFromGlobalDict(glob_dict, mount_point): d = {} if "build.prop" in glob_dict: - timestamp = glob_dict["build.prop"].GetProp("ro.build.date.utc") - if timestamp: - d["timestamp"] = timestamp + bp = glob_dict["build.prop"] + if "ro.build.date.utc" in bp: + d["timestamp"] = bp["ro.build.date.utc"] def copy_prop(src_p, dest_p): """Copy a property from the global dictionary. diff --git a/tools/releasetools/check_target_files_vintf.py b/tools/releasetools/check_target_files_vintf.py index 95d09cc177..b3d491fdfd 100755 --- a/tools/releasetools/check_target_files_vintf.py +++ b/tools/releasetools/check_target_files_vintf.py @@ -80,9 +80,8 @@ def GetArgsForSkus(info_dict): '--property', 'ro.boot.product.vendor.sku=' + vendor_sku] for odm_sku in odm_skus for vendor_sku in vendor_skus] - def GetArgsForShippingApiLevel(info_dict): - shipping_api_level = info_dict['vendor.build.prop'].GetProp( + shipping_api_level = info_dict['vendor.build.prop'].get( 'ro.product.first_api_level') if not shipping_api_level: logger.warning('Cannot determine ro.product.first_api_level') diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py index 7805e30ce8..1abf5a5cc6 100644 --- a/tools/releasetools/common.py +++ b/tools/releasetools/common.py @@ -423,14 +423,6 @@ class BuildInfo(object): def items(self): return self.info_dict.items() - def _GetRawBuildProp(self, prop, partition): - prop_file = '{}.build.prop'.format( - partition) if partition else 'build.prop' - partition_props = self.info_dict.get(prop_file) - if not partition_props: - return None - return partition_props.GetProp(prop) - def GetPartitionBuildProp(self, prop, partition): """Returns the inquired build property for the provided partition.""" # If provided a partition for this property, only look within that @@ -439,33 +431,31 @@ class BuildInfo(object): prop = prop.replace("ro.product", "ro.product.{}".format(partition)) else: prop = prop.replace("ro.", "ro.{}.".format(partition)) - - prop_val = self._GetRawBuildProp(prop, partition) - if prop_val is not None: - return prop_val - raise ExternalError("couldn't find %s in %s.build.prop" % - (prop, partition)) + try: + return self.info_dict.get("{}.build.prop".format(partition), {})[prop] + except KeyError: + raise ExternalError("couldn't find %s in %s.build.prop" % + (prop, partition)) def GetBuildProp(self, prop): """Returns the inquired build property from the standard build.prop file.""" if prop in BuildInfo._RO_PRODUCT_RESOLVE_PROPS: return self._ResolveRoProductBuildProp(prop) - prop_val = self._GetRawBuildProp(prop, None) - if prop_val is not None: - return prop_val - - raise ExternalError("couldn't find %s in build.prop" % (prop,)) + try: + return self.info_dict.get("build.prop", {})[prop] + except KeyError: + raise ExternalError("couldn't find %s in build.prop" % (prop,)) def _ResolveRoProductBuildProp(self, prop): """Resolves the inquired ro.product.* build property""" - prop_val = self._GetRawBuildProp(prop, None) + prop_val = self.info_dict.get("build.prop", {}).get(prop) if prop_val: return prop_val default_source_order = self._GetRoProductPropsDefaultSourceOrder() - source_order_val = self._GetRawBuildProp( - "ro.product.property_source_order", None) + source_order_val = self.info_dict.get("build.prop", {}).get( + "ro.product.property_source_order") if source_order_val: source_order = source_order_val.split(",") else: @@ -476,10 +466,11 @@ class BuildInfo(object): raise ExternalError( "Invalid ro.product.property_source_order '{}'".format(source_order)) - for source_partition in source_order: + for source in source_order: source_prop = prop.replace( - "ro.product", "ro.product.{}".format(source_partition), 1) - prop_val = self._GetRawBuildProp(source_prop, source_partition) + "ro.product", "ro.product.{}".format(source), 1) + prop_val = self.info_dict.get( + "{}.build.prop".format(source), {}).get(source_prop) if prop_val: return prop_val @@ -488,9 +479,11 @@ class BuildInfo(object): def _GetRoProductPropsDefaultSourceOrder(self): # NOTE: refer to CDDs and android.os.Build.VERSION for the definition and # values of these properties for each Android release. - android_codename = self._GetRawBuildProp("ro.build.version.codename", None) + android_codename = self.info_dict.get("build.prop", {}).get( + "ro.build.version.codename") if android_codename == "REL": - android_version = self._GetRawBuildProp("ro.build.version.release", None) + android_version = self.info_dict.get("build.prop", {}).get( + "ro.build.version.release") if android_version == "10": return BuildInfo._RO_PRODUCT_PROPS_DEFAULT_SOURCE_ORDER_ANDROID_10 # NOTE: float() conversion of android_version will have rounding error. @@ -573,20 +566,6 @@ class BuildInfo(object): script.AssertOemProperty(prop, values, oem_no_mount) -def ReadFromInputFile(input_file, fn): - """Reads the contents of fn from input zipfile or directory.""" - if isinstance(input_file, zipfile.ZipFile): - return input_file.read(fn).decode() - else: - path = os.path.join(input_file, *fn.split("/")) - try: - with open(path) as f: - return f.read() - except IOError as e: - if e.errno == errno.ENOENT: - raise KeyError(fn) - - def LoadInfoDict(input_file, repacking=False): """Loads the key/value pairs from the given input target_files. @@ -624,7 +603,16 @@ def LoadInfoDict(input_file, repacking=False): "input_file must be a path str when doing repacking" def read_helper(fn): - return ReadFromInputFile(input_file, fn) + if isinstance(input_file, zipfile.ZipFile): + return input_file.read(fn).decode() + else: + path = os.path.join(input_file, *fn.split("/")) + try: + with open(path) as f: + return f.read() + except IOError as e: + if e.errno == errno.ENOENT: + raise KeyError(fn) try: d = LoadDictionaryFromLines(read_helper("META/misc_info.txt").split("\n")) @@ -687,8 +675,13 @@ def LoadInfoDict(input_file, repacking=False): # system and vendor. for partition in PARTITIONS_WITH_CARE_MAP: partition_prop = "{}.build.prop".format(partition) - d[partition_prop] = PartitionBuildProps.FromInputFile( - input_file, partition) + d[partition_prop] = LoadBuildProp( + read_helper, "{}/build.prop".format(partition.upper())) + # Some partition might use //etc/build.prop as the new path. + # TODO: try new path first when majority of them switch to the new path. + if not d[partition_prop]: + d[partition_prop] = LoadBuildProp( + read_helper, "{}/etc/build.prop".format(partition.upper())) d["build.prop"] = d["system.build.prop"] # Set up the salt (based on fingerprint) that will be used when adding AVB @@ -703,6 +696,15 @@ def LoadInfoDict(input_file, repacking=False): return d +def LoadBuildProp(read_helper, prop_file): + try: + data = read_helper(prop_file) + except KeyError: + logger.warning("Failed to read %s", prop_file) + data = "" + return LoadDictionaryFromLines(data.split("\n")) + + def LoadListFromFile(file_path): with open(file_path) as f: return f.read().splitlines() @@ -725,116 +727,6 @@ def LoadDictionaryFromLines(lines): return d -class PartitionBuildProps(object): - """The class holds the build prop of a particular partition. - - This class loads the build.prop and holds the build properties for a given - partition. It also partially recognizes the 'import' statement in the - build.prop; and calculates alternative values of some specific build - properties during runtime. - - Attributes: - input_file: a zipped target-file or an unzipped target-file directory. - partition: name of the partition. - props_allow_override: a list of build properties to search for the - alternative values during runtime. - build_props: a dict of build properties for the given partition. - prop_overrides: a set of props that are overridden by import. - placeholder_values: A dict of runtime variables' values to replace the - placeholders in the build.prop file. We expect exactly one value for - each of the variables. - """ - def __init__(self, input_file, name, placeholder_values=None): - self.input_file = input_file - self.partition = name - self.props_allow_override = [props.format(name) for props in [ - 'ro.product.{}.brand', 'ro.product.{}.name', 'ro.product.{}.device']] - self.build_props = {} - self.prop_overrides = set() - self.placeholder_values = {} - if placeholder_values: - self.placeholder_values = copy.deepcopy(placeholder_values) - - @staticmethod - def FromDictionary(name, build_props): - """Constructs an instance from a build prop dictionary.""" - - props = PartitionBuildProps("unknown", name) - props.build_props = build_props.copy() - return props - - @staticmethod - def FromInputFile(input_file, name, placeholder_values=None): - """Loads the build.prop file and builds the attributes.""" - data = '' - for prop_file in ['{}/etc/build.prop'.format(name.upper()), - '{}/build.prop'.format(name.upper())]: - try: - data = ReadFromInputFile(input_file, prop_file) - break - except KeyError: - logger.warning('Failed to read %s', prop_file) - - props = PartitionBuildProps(input_file, name, placeholder_values) - props._LoadBuildProp(data) - return props - - def _LoadBuildProp(self, data): - for line in data.split('\n'): - line = line.strip() - if not line or line.startswith("#"): - continue - if line.startswith("import"): - overrides = self._ImportParser(line) - duplicates = self.prop_overrides.intersection(overrides.keys()) - if duplicates: - raise ValueError('prop {} is overridden multiple times'.format( - ','.join(duplicates))) - self.prop_overrides = self.prop_overrides.union(overrides.keys()) - self.build_props.update(overrides) - elif "=" in line: - name, value = line.split("=", 1) - if name in self.prop_overrides: - raise ValueError('prop {} is set again after overridden by import ' - 'statement'.format(name)) - self.build_props[name] = value - - def _ImportParser(self, line): - """Parses the build prop in a given import statement.""" - - tokens = line.split() - if len(tokens) != 2 or tokens[0] != 'import': - raise ValueError('Unrecognized import statement {}'.format(line)) - import_path = tokens[1] - if not re.match(r'^/{}/.*\.prop$'.format(self.partition), import_path): - raise ValueError('Unrecognized import path {}'.format(line)) - - # We only recognize a subset of import statement that the init process - # supports. And we can loose the restriction based on how the dynamic - # fingerprint is used in practice. The placeholder format should be - # ${placeholder}, and its value should be provided by the caller through - # the placeholder_values. - for prop, value in self.placeholder_values.items(): - prop_place_holder = '${{{}}}'.format(prop) - if prop_place_holder in import_path: - import_path = import_path.replace(prop_place_holder, value) - if '$' in import_path: - logger.info('Unresolved place holder in import path %s', import_path) - return {} - - import_path = import_path.replace('/{}'.format(self.partition), - self.partition.upper()) - logger.info('Parsing build props override from %s', import_path) - - lines = ReadFromInputFile(self.input_file, import_path).split('\n') - d = LoadDictionaryFromLines(lines) - return {key: val for key, val in d.items() - if key in self.props_allow_override} - - def GetProp(self, prop): - return self.build_props.get(prop) - - def LoadRecoveryFSTab(read_helper, fstab_version, recovery_fstab_path, system_root_image=False): class Partition(object): diff --git a/tools/releasetools/ota_from_target_files.py b/tools/releasetools/ota_from_target_files.py index 47ad3d8a14..92a46a20cd 100755 --- a/tools/releasetools/ota_from_target_files.py +++ b/tools/releasetools/ota_from_target_files.py @@ -193,8 +193,6 @@ A/B OTA specific options from __future__ import print_function import collections -import copy -import itertools import logging import multiprocessing import os.path @@ -231,7 +229,6 @@ OPTIONS.include_secondary = False OPTIONS.no_signing = False OPTIONS.block_based = True OPTIONS.updater_binary = None -OPTIONS.oem_dicts = None OPTIONS.oem_source = None OPTIONS.oem_no_mount = False OPTIONS.full_radio = False @@ -250,7 +247,6 @@ OPTIONS.retrofit_dynamic_partitions = False OPTIONS.skip_compatibility_check = False OPTIONS.output_metadata_path = None OPTIONS.disable_fec_computation = False -OPTIONS.boot_variable_values = None METADATA_NAME = 'META-INF/com/android/metadata' @@ -1963,36 +1959,6 @@ def GenerateNonAbOtaPackage(target_file, output_file, source_file=None): output_file) -def CalculateRuntimeFingerprints(): - """Returns a set of runtime fingerprints based on the boot variables.""" - - build_info = common.BuildInfo(OPTIONS.info_dict, OPTIONS.oem_dicts) - fingerprints = {build_info.fingerprint} - - if not OPTIONS.boot_variable_values: - return fingerprints - - # Calculate all possible combinations of the values for the boot variables. - keys = OPTIONS.boot_variable_values.keys() - value_list = OPTIONS.boot_variable_values.values() - combinations = [dict(zip(keys, values)) - for values in itertools.product(*value_list)] - for placeholder_values in combinations: - # Reload the info_dict as some build properties may change their values - # based on the value of ro.boot* properties. - info_dict = copy.deepcopy(OPTIONS.info_dict) - for partition in common.PARTITIONS_WITH_CARE_MAP: - partition_prop_key = "{}.build.prop".format(partition) - old_props = info_dict[partition_prop_key] - info_dict[partition_prop_key] = common.PartitionBuildProps.FromInputFile( - old_props.input_file, partition, placeholder_values) - info_dict["build.prop"] = info_dict["system.build.prop"] - - build_info = common.BuildInfo(info_dict, OPTIONS.oem_dicts) - fingerprints.add(build_info.fingerprint) - return fingerprints - - def main(argv): def option_handler(o, a): diff --git a/tools/releasetools/test_add_img_to_target_files.py b/tools/releasetools/test_add_img_to_target_files.py index c82a40bee4..3d0766ffda 100644 --- a/tools/releasetools/test_add_img_to_target_files.py +++ b/tools/releasetools/test_add_img_to_target_files.py @@ -128,16 +128,13 @@ class AddImagesToTargetFilesTest(test_utils.ReleaseToolsTestCase): 'vendor_image_size' : 40960, 'system_verity_block_device': '/dev/block/system', 'vendor_verity_block_device': '/dev/block/vendor', - 'system.build.prop': common.PartitionBuildProps.FromDictionary( - 'system', { - 'ro.system.build.fingerprint': - 'google/sailfish/12345:user/dev-keys'} - ), - 'vendor.build.prop': common.PartitionBuildProps.FromDictionary( - 'vendor', { - 'ro.vendor.build.fingerprint': - 'google/sailfish/678:user/dev-keys'} - ), + 'system.build.prop': { + 'ro.system.build.fingerprint': + 'google/sailfish/12345:user/dev-keys', + }, + 'vendor.build.prop': { + 'ro.vendor.build.fingerprint': 'google/sailfish/678:user/dev-keys', + }, } # Prepare the META/ folder. @@ -209,21 +206,18 @@ class AddImagesToTargetFilesTest(test_utils.ReleaseToolsTestCase): """Tests the case for device using AVB.""" image_paths = self._test_AddCareMapForAbOta() OPTIONS.info_dict = { - 'extfs_sparse_flag': '-s', - 'system_image_size': 65536, - 'vendor_image_size': 40960, - 'avb_system_hashtree_enable': 'true', - 'avb_vendor_hashtree_enable': 'true', - 'system.build.prop': common.PartitionBuildProps.FromDictionary( - 'system', { - 'ro.system.build.fingerprint': - 'google/sailfish/12345:user/dev-keys'} - ), - 'vendor.build.prop': common.PartitionBuildProps.FromDictionary( - 'vendor', { - 'ro.vendor.build.fingerprint': - 'google/sailfish/678:user/dev-keys'} - ), + 'extfs_sparse_flag' : '-s', + 'system_image_size' : 65536, + 'vendor_image_size' : 40960, + 'avb_system_hashtree_enable' : 'true', + 'avb_vendor_hashtree_enable' : 'true', + 'system.build.prop': { + 'ro.system.build.fingerprint': + 'google/sailfish/12345:user/dev-keys', + }, + 'vendor.build.prop': { + 'ro.vendor.build.fingerprint': 'google/sailfish/678:user/dev-keys', + } } AddCareMapForAbOta(None, ['system', 'vendor'], image_paths) @@ -264,21 +258,17 @@ class AddImagesToTargetFilesTest(test_utils.ReleaseToolsTestCase): """Tests the case for partitions with thumbprint.""" image_paths = self._test_AddCareMapForAbOta() OPTIONS.info_dict = { - 'extfs_sparse_flag': '-s', - 'system_image_size': 65536, - 'vendor_image_size': 40960, + 'extfs_sparse_flag' : '-s', + 'system_image_size' : 65536, + 'vendor_image_size' : 40960, 'system_verity_block_device': '/dev/block/system', 'vendor_verity_block_device': '/dev/block/vendor', - 'system.build.prop': common.PartitionBuildProps.FromDictionary( - 'system', { - 'ro.system.build.thumbprint': - 'google/sailfish/123:user/dev-keys'} - ), - 'vendor.build.prop': common.PartitionBuildProps.FromDictionary( - 'vendor', { - 'ro.vendor.build.thumbprint': - 'google/sailfish/456:user/dev-keys'} - ), + 'system.build.prop': { + 'ro.system.build.thumbprint': 'google/sailfish/123:user/dev-keys', + }, + 'vendor.build.prop' : { + 'ro.vendor.build.thumbprint': 'google/sailfish/456:user/dev-keys', + }, } AddCareMapForAbOta(None, ['system', 'vendor'], image_paths) diff --git a/tools/releasetools/test_common.py b/tools/releasetools/test_common.py index 787e6757ec..665eb513d6 100644 --- a/tools/releasetools/test_common.py +++ b/tools/releasetools/test_common.py @@ -48,124 +48,109 @@ def get_2gb_string(): class BuildInfoTest(test_utils.ReleaseToolsTestCase): TEST_INFO_DICT = { - 'build.prop': common.PartitionBuildProps.FromDictionary( - 'system', { - 'ro.product.device': 'product-device', - 'ro.product.name': 'product-name', - 'ro.build.fingerprint': 'build-fingerprint', - 'ro.build.foo': 'build-foo'} - ), - 'system.build.prop': common.PartitionBuildProps.FromDictionary( - 'system', { - 'ro.product.system.brand': 'product-brand', - 'ro.product.system.name': 'product-name', - 'ro.product.system.device': 'product-device', - 'ro.system.build.version.release': 'version-release', - 'ro.system.build.id': 'build-id', - 'ro.system.build.version.incremental': 'version-incremental', - 'ro.system.build.type': 'build-type', - 'ro.system.build.tags': 'build-tags', - 'ro.system.build.foo': 'build-foo'} - ), - 'vendor.build.prop': common.PartitionBuildProps.FromDictionary( - 'vendor', { - 'ro.product.vendor.brand': 'vendor-product-brand', - 'ro.product.vendor.name': 'vendor-product-name', - 'ro.product.vendor.device': 'vendor-product-device', - 'ro.vendor.build.version.release': 'vendor-version-release', - 'ro.vendor.build.id': 'vendor-build-id', - 'ro.vendor.build.version.incremental': - 'vendor-version-incremental', - 'ro.vendor.build.type': 'vendor-build-type', - 'ro.vendor.build.tags': 'vendor-build-tags'} - ), - 'property1': 'value1', - 'property2': 4096, + 'build.prop' : { + 'ro.product.device' : 'product-device', + 'ro.product.name' : 'product-name', + 'ro.build.fingerprint' : 'build-fingerprint', + 'ro.build.foo' : 'build-foo', + }, + 'system.build.prop' : { + 'ro.product.system.brand' : 'product-brand', + 'ro.product.system.name' : 'product-name', + 'ro.product.system.device' : 'product-device', + 'ro.system.build.version.release' : 'version-release', + 'ro.system.build.id' : 'build-id', + 'ro.system.build.version.incremental' : 'version-incremental', + 'ro.system.build.type' : 'build-type', + 'ro.system.build.tags' : 'build-tags', + 'ro.system.build.foo' : 'build-foo', + }, + 'vendor.build.prop' : { + 'ro.product.vendor.brand' : 'vendor-product-brand', + 'ro.product.vendor.name' : 'vendor-product-name', + 'ro.product.vendor.device' : 'vendor-product-device', + 'ro.vendor.build.version.release' : 'vendor-version-release', + 'ro.vendor.build.id' : 'vendor-build-id', + 'ro.vendor.build.version.incremental' : 'vendor-version-incremental', + 'ro.vendor.build.type' : 'vendor-build-type', + 'ro.vendor.build.tags' : 'vendor-build-tags', + }, + 'property1' : 'value1', + 'property2' : 4096, } TEST_INFO_DICT_USES_OEM_PROPS = { - 'build.prop': common.PartitionBuildProps.FromDictionary( - 'system', { - 'ro.product.name': 'product-name', - 'ro.build.thumbprint': 'build-thumbprint', - 'ro.build.bar': 'build-bar'} - ), - 'vendor.build.prop': common.PartitionBuildProps.FromDictionary( - 'vendor', { - 'ro.vendor.build.fingerprint': 'vendor-build-fingerprint'} - ), - 'property1': 'value1', - 'property2': 4096, - 'oem_fingerprint_properties': 'ro.product.device ro.product.brand', + 'build.prop' : { + 'ro.product.name' : 'product-name', + 'ro.build.thumbprint' : 'build-thumbprint', + 'ro.build.bar' : 'build-bar', + }, + 'vendor.build.prop' : { + 'ro.vendor.build.fingerprint' : 'vendor-build-fingerprint', + }, + 'property1' : 'value1', + 'property2' : 4096, + 'oem_fingerprint_properties' : 'ro.product.device ro.product.brand', } TEST_OEM_DICTS = [ { - 'ro.product.brand': 'brand1', - 'ro.product.device': 'device1', + 'ro.product.brand' : 'brand1', + 'ro.product.device' : 'device1', }, { - 'ro.product.brand': 'brand2', - 'ro.product.device': 'device2', + 'ro.product.brand' : 'brand2', + 'ro.product.device' : 'device2', }, { - 'ro.product.brand': 'brand3', - 'ro.product.device': 'device3', + 'ro.product.brand' : 'brand3', + 'ro.product.device' : 'device3', }, ] TEST_INFO_DICT_PROPERTY_SOURCE_ORDER = { - 'build.prop': common.PartitionBuildProps.FromDictionary( - 'system', { - 'ro.build.fingerprint': 'build-fingerprint', - 'ro.product.property_source_order': - 'product,odm,vendor,system_ext,system'} - ), - 'system.build.prop': common.PartitionBuildProps.FromDictionary( - 'system', { - 'ro.product.system.device': 'system-product-device'} - ), - 'vendor.build.prop': common.PartitionBuildProps.FromDictionary( - 'vendor', { - 'ro.product.vendor.device': 'vendor-product-device'} - ), + 'build.prop' : { + 'ro.build.fingerprint' : 'build-fingerprint', + 'ro.product.property_source_order' : + 'product,odm,vendor,system_ext,system', + }, + 'system.build.prop' : { + 'ro.product.system.device' : 'system-product-device', + }, + 'vendor.build.prop' : { + 'ro.product.vendor.device' : 'vendor-product-device', + }, } TEST_INFO_DICT_PROPERTY_SOURCE_ORDER_ANDROID_10 = { - 'build.prop': common.PartitionBuildProps.FromDictionary( - 'system', { - 'ro.build.fingerprint': 'build-fingerprint', - 'ro.product.property_source_order': - 'product,product_services,odm,vendor,system', - 'ro.build.version.release': '10', - 'ro.build.version.codename': 'REL'} - ), - 'system.build.prop': common.PartitionBuildProps.FromDictionary( - 'system', { - 'ro.product.system.device': 'system-product-device'} - ), - 'vendor.build.prop': common.PartitionBuildProps.FromDictionary( - 'vendor', { - 'ro.product.vendor.device': 'vendor-product-device'} - ), + 'build.prop' : { + 'ro.build.fingerprint' : 'build-fingerprint', + 'ro.product.property_source_order' : + 'product,product_services,odm,vendor,system', + 'ro.build.version.release' : '10', + 'ro.build.version.codename' : 'REL', + }, + 'system.build.prop' : { + 'ro.product.system.device' : 'system-product-device', + }, + 'vendor.build.prop' : { + 'ro.product.vendor.device' : 'vendor-product-device', + }, } TEST_INFO_DICT_PROPERTY_SOURCE_ORDER_ANDROID_9 = { - 'build.prop': common.PartitionBuildProps.FromDictionary( - 'system', { - 'ro.product.device': 'product-device', - 'ro.build.fingerprint': 'build-fingerprint', - 'ro.build.version.release': '9', - 'ro.build.version.codename': 'REL'} - ), - 'system.build.prop': common.PartitionBuildProps.FromDictionary( - 'system', { - 'ro.product.system.device': 'system-product-device'} - ), - 'vendor.build.prop': common.PartitionBuildProps.FromDictionary( - 'vendor', { - 'ro.product.vendor.device': 'vendor-product-device'} - ), + 'build.prop' : { + 'ro.product.device' : 'product-device', + 'ro.build.fingerprint' : 'build-fingerprint', + 'ro.build.version.release' : '9', + 'ro.build.version.codename' : 'REL', + }, + 'system.build.prop' : { + 'ro.product.system.device' : 'system-product-device', + }, + 'vendor.build.prop' : { + 'ro.product.vendor.device' : 'vendor-product-device', + }, } def test_init(self): @@ -193,27 +178,25 @@ class BuildInfoTest(test_utils.ReleaseToolsTestCase): def test_init_badFingerprint(self): info_dict = copy.deepcopy(self.TEST_INFO_DICT) - info_dict['build.prop'].build_props[ - 'ro.build.fingerprint'] = 'bad fingerprint' + info_dict['build.prop']['ro.build.fingerprint'] = 'bad fingerprint' self.assertRaises(ValueError, common.BuildInfo, info_dict, None) - info_dict['build.prop'].build_props[ - 'ro.build.fingerprint'] = 'bad\x80fingerprint' + info_dict['build.prop']['ro.build.fingerprint'] = 'bad\x80fingerprint' self.assertRaises(ValueError, common.BuildInfo, info_dict, None) def test___getitem__(self): target_info = common.BuildInfo(self.TEST_INFO_DICT, None) self.assertEqual('value1', target_info['property1']) self.assertEqual(4096, target_info['property2']) - self.assertEqual('build-foo', - target_info['build.prop'].GetProp('ro.build.foo')) + self.assertEqual('build-foo', target_info['build.prop']['ro.build.foo']) def test___getitem__with_oem_props(self): target_info = common.BuildInfo(self.TEST_INFO_DICT_USES_OEM_PROPS, self.TEST_OEM_DICTS) self.assertEqual('value1', target_info['property1']) self.assertEqual(4096, target_info['property2']) - self.assertIsNone(target_info['build.prop'].GetProp('ro.build.foo')) + self.assertRaises(KeyError, + lambda: target_info['build.prop']['ro.build.foo']) def test___setitem__(self): target_info = common.BuildInfo(copy.deepcopy(self.TEST_INFO_DICT), None) @@ -221,11 +204,9 @@ class BuildInfoTest(test_utils.ReleaseToolsTestCase): target_info['property1'] = 'value2' self.assertEqual('value2', target_info['property1']) - self.assertEqual('build-foo', - target_info['build.prop'].GetProp('ro.build.foo')) - target_info['build.prop'].build_props['ro.build.foo'] = 'build-bar' - self.assertEqual('build-bar', - target_info['build.prop'].GetProp('ro.build.foo')) + self.assertEqual('build-foo', target_info['build.prop']['ro.build.foo']) + target_info['build.prop']['ro.build.foo'] = 'build-bar' + self.assertEqual('build-bar', target_info['build.prop']['ro.build.foo']) def test_get(self): target_info = common.BuildInfo(self.TEST_INFO_DICT, None) @@ -233,8 +214,7 @@ class BuildInfoTest(test_utils.ReleaseToolsTestCase): self.assertEqual(4096, target_info.get('property2')) self.assertEqual(4096, target_info.get('property2', 1024)) self.assertEqual(1024, target_info.get('property-nonexistent', 1024)) - self.assertEqual('build-foo', - target_info.get('build.prop').GetProp('ro.build.foo')) + self.assertEqual('build-foo', target_info.get('build.prop')['ro.build.foo']) def test_get_with_oem_props(self): target_info = common.BuildInfo(self.TEST_INFO_DICT_USES_OEM_PROPS, @@ -243,7 +223,9 @@ class BuildInfoTest(test_utils.ReleaseToolsTestCase): self.assertEqual(4096, target_info.get('property2')) self.assertEqual(4096, target_info.get('property2', 1024)) self.assertEqual(1024, target_info.get('property-nonexistent', 1024)) - self.assertIsNone(target_info.get('build.prop').GetProp('ro.build.foo')) + self.assertIsNone(target_info.get('build.prop').get('ro.build.foo')) + self.assertRaises(KeyError, + lambda: target_info.get('build.prop')['ro.build.foo']) def test_items(self): target_info = common.BuildInfo(self.TEST_INFO_DICT, None) @@ -280,8 +262,7 @@ class BuildInfoTest(test_utils.ReleaseToolsTestCase): def test_GetPartitionFingerprint_uses_fingerprint_prop_if_available(self): info_dict = copy.deepcopy(self.TEST_INFO_DICT) - info_dict['vendor.build.prop'].build_props[ - 'ro.vendor.build.fingerprint'] = 'vendor:fingerprint' + info_dict['vendor.build.prop']['ro.vendor.build.fingerprint'] = 'vendor:fingerprint' target_info = common.BuildInfo(info_dict, None) self.assertEqual( target_info.GetPartitionFingerprint('vendor'), @@ -322,15 +303,14 @@ class BuildInfoTest(test_utils.ReleaseToolsTestCase): def test_ResolveRoProductProperty_FromSystem(self): info_dict = copy.deepcopy(self.TEST_INFO_DICT_PROPERTY_SOURCE_ORDER) - del info_dict['vendor.build.prop'].build_props['ro.product.vendor.device'] + del info_dict['vendor.build.prop']['ro.product.vendor.device'] info = common.BuildInfo(info_dict, None) self.assertEqual('system-product-device', info.GetBuildProp('ro.product.device')) def test_ResolveRoProductProperty_InvalidPropertySearchOrder(self): info_dict = copy.deepcopy(self.TEST_INFO_DICT_PROPERTY_SOURCE_ORDER) - info_dict['build.prop'].build_props[ - 'ro.product.property_source_order'] = 'bad-source' + info_dict['build.prop']['ro.product.property_source_order'] = 'bad-source' with self.assertRaisesRegexp(common.ExternalError, 'Invalid ro.product.property_source_order'): info = common.BuildInfo(info_dict, None) @@ -1533,14 +1513,12 @@ class CommonUtilsTest(test_utils.ReleaseToolsTestCase): common.OPTIONS.info_dict = { 'ab_update': 'true', 'avb_avbtool': 'avbtool', - 'build.prop': common.PartitionBuildProps.FromDictionary( - 'system', { - 'ro.build.version.incremental': '6285659', - 'ro.product.device': 'coral', - 'ro.build.fingerprint': - 'google/coral/coral:R/RP1A.200311.002/' - '6285659:userdebug/dev-keys'} - ), + 'build.prop': { + 'ro.build.version.incremental': '6285659', + 'ro.product.device': 'coral', + 'ro.build.fingerprint': 'google/coral/coral:R/RP1A.200311.002/' + '6285659:userdebug/dev-keys' + } } common.OPTIONS.aftl_tool_path = 'aftltool' common.OPTIONS.aftl_server = 'log.endpoints.aftl-dev.cloud.goog:9000' @@ -1573,14 +1551,12 @@ class CommonUtilsTest(test_utils.ReleaseToolsTestCase): common.OPTIONS.info_dict = { 'ab_update': 'true', 'avb_avbtool': 'avbtool', - 'build.prop': common.PartitionBuildProps.FromDictionary( - 'system', { - 'ro.build.version.incremental': '6285659', - 'ro.product.device': 'coral', - 'ro.build.fingerprint': - 'google/coral/coral:R/RP1A.200311.002/' - '6285659:userdebug/dev-keys'} - ) + 'build.prop': { + 'ro.build.version.incremental': '6285659', + 'ro.product.device': 'coral', + 'ro.build.fingerprint': 'google/coral/coral:R/RP1A.200311.002/' + '6285659:userdebug/dev-keys' + } } common.OPTIONS.aftl_tool_path = "aftltool" common.OPTIONS.aftl_server = "log.endpoints.aftl-dev.cloud.goog:9000" @@ -1895,241 +1871,3 @@ super_group_foo_group_size={group_foo_size} lines = self.get_op_list(self.output_path) self.assertEqual(lines, ["remove foo"]) - - -class PartitionBuildPropsTest(test_utils.ReleaseToolsTestCase): - def setUp(self): - self.odm_build_prop = [ - 'ro.odm.build.date.utc=1578430045', - 'ro.odm.build.fingerprint=' - 'google/coral/coral:10/RP1A.200325.001/6337676:user/dev-keys', - 'ro.product.odm.device=coral', - 'import /odm/etc/build_${ro.boot.product.device_name}.prop', - ] - - @staticmethod - def _BuildZipFile(entries): - input_file = common.MakeTempFile(prefix='target_files-', suffix='.zip') - with zipfile.ZipFile(input_file, 'w') as input_zip: - for name, content in entries.items(): - input_zip.writestr(name, content) - - return input_file - - def test_parseBuildProps_noImportStatement(self): - build_prop = [ - 'ro.odm.build.date.utc=1578430045', - 'ro.odm.build.fingerprint=' - 'google/coral/coral:10/RP1A.200325.001/6337676:user/dev-keys', - 'ro.product.odm.device=coral', - ] - input_file = self._BuildZipFile({ - 'ODM/etc/build.prop': '\n'.join(build_prop), - }) - - with zipfile.ZipFile(input_file, 'r') as input_zip: - placeholder_values = { - 'ro.boot.product.device_name': ['std', 'pro'] - } - partition_props = common.PartitionBuildProps.FromInputFile( - input_zip, 'odm', placeholder_values) - - self.assertEqual({ - 'ro.odm.build.date.utc': '1578430045', - 'ro.odm.build.fingerprint': - 'google/coral/coral:10/RP1A.200325.001/6337676:user/dev-keys', - 'ro.product.odm.device': 'coral', - }, partition_props.build_props) - - self.assertEqual(set(), partition_props.prop_overrides) - - def test_parseBuildProps_singleImportStatement(self): - build_std_prop = [ - 'ro.product.odm.device=coral', - 'ro.product.odm.name=product1', - ] - build_pro_prop = [ - 'ro.product.odm.device=coralpro', - 'ro.product.odm.name=product2', - ] - - input_file = self._BuildZipFile({ - 'ODM/etc/build.prop': '\n'.join(self.odm_build_prop), - 'ODM/etc/build_std.prop': '\n'.join(build_std_prop), - 'ODM/etc/build_pro.prop': '\n'.join(build_pro_prop), - }) - - with zipfile.ZipFile(input_file, 'r') as input_zip: - placeholder_values = { - 'ro.boot.product.device_name': 'std' - } - partition_props = common.PartitionBuildProps.FromInputFile( - input_zip, 'odm', placeholder_values) - - self.assertEqual({ - 'ro.odm.build.date.utc': '1578430045', - 'ro.odm.build.fingerprint': - 'google/coral/coral:10/RP1A.200325.001/6337676:user/dev-keys', - 'ro.product.odm.device': 'coral', - 'ro.product.odm.name': 'product1', - }, partition_props.build_props) - - with zipfile.ZipFile(input_file, 'r') as input_zip: - placeholder_values = { - 'ro.boot.product.device_name': 'pro' - } - partition_props = common.PartitionBuildProps.FromInputFile( - input_zip, 'odm', placeholder_values) - - self.assertEqual({ - 'ro.odm.build.date.utc': '1578430045', - 'ro.odm.build.fingerprint': - 'google/coral/coral:10/RP1A.200325.001/6337676:user/dev-keys', - 'ro.product.odm.device': 'coralpro', - 'ro.product.odm.name': 'product2', - }, partition_props.build_props) - - def test_parseBuildProps_noPlaceHolders(self): - build_prop = copy.copy(self.odm_build_prop) - input_file = self._BuildZipFile({ - 'ODM/etc/build.prop': '\n'.join(build_prop), - }) - - with zipfile.ZipFile(input_file, 'r') as input_zip: - partition_props = common.PartitionBuildProps.FromInputFile( - input_zip, 'odm') - - self.assertEqual({ - 'ro.odm.build.date.utc': '1578430045', - 'ro.odm.build.fingerprint': - 'google/coral/coral:10/RP1A.200325.001/6337676:user/dev-keys', - 'ro.product.odm.device': 'coral', - }, partition_props.build_props) - - self.assertEqual(set(), partition_props.prop_overrides) - - def test_parseBuildProps_multipleImportStatements(self): - build_prop = copy.deepcopy(self.odm_build_prop) - build_prop.append( - 'import /odm/etc/build_${ro.boot.product.product_name}.prop') - - build_std_prop = [ - 'ro.product.odm.device=coral', - ] - build_pro_prop = [ - 'ro.product.odm.device=coralpro', - ] - - product1_prop = [ - 'ro.product.odm.name=product1', - 'ro.product.not_care=not_care', - ] - - product2_prop = [ - 'ro.product.odm.name=product2', - 'ro.product.not_care=not_care', - ] - - input_file = self._BuildZipFile({ - 'ODM/etc/build.prop': '\n'.join(build_prop), - 'ODM/etc/build_std.prop': '\n'.join(build_std_prop), - 'ODM/etc/build_pro.prop': '\n'.join(build_pro_prop), - 'ODM/etc/build_product1.prop': '\n'.join(product1_prop), - 'ODM/etc/build_product2.prop': '\n'.join(product2_prop), - }) - - with zipfile.ZipFile(input_file, 'r') as input_zip: - placeholder_values = { - 'ro.boot.product.device_name': 'std', - 'ro.boot.product.product_name': 'product1', - 'ro.boot.product.not_care': 'not_care', - } - partition_props = common.PartitionBuildProps.FromInputFile( - input_zip, 'odm', placeholder_values) - - self.assertEqual({ - 'ro.odm.build.date.utc': '1578430045', - 'ro.odm.build.fingerprint': - 'google/coral/coral:10/RP1A.200325.001/6337676:user/dev-keys', - 'ro.product.odm.device': 'coral', - 'ro.product.odm.name': 'product1' - }, partition_props.build_props) - - with zipfile.ZipFile(input_file, 'r') as input_zip: - placeholder_values = { - 'ro.boot.product.device_name': 'pro', - 'ro.boot.product.product_name': 'product2', - 'ro.boot.product.not_care': 'not_care', - } - partition_props = common.PartitionBuildProps.FromInputFile( - input_zip, 'odm', placeholder_values) - - self.assertEqual({ - 'ro.odm.build.date.utc': '1578430045', - 'ro.odm.build.fingerprint': - 'google/coral/coral:10/RP1A.200325.001/6337676:user/dev-keys', - 'ro.product.odm.device': 'coralpro', - 'ro.product.odm.name': 'product2' - }, partition_props.build_props) - - def test_parseBuildProps_defineAfterOverride(self): - build_prop = copy.deepcopy(self.odm_build_prop) - build_prop.append('ro.product.odm.device=coral') - - build_std_prop = [ - 'ro.product.odm.device=coral', - ] - build_pro_prop = [ - 'ro.product.odm.device=coralpro', - ] - - input_file = self._BuildZipFile({ - 'ODM/etc/build.prop': '\n'.join(build_prop), - 'ODM/etc/build_std.prop': '\n'.join(build_std_prop), - 'ODM/etc/build_pro.prop': '\n'.join(build_pro_prop), - }) - - with zipfile.ZipFile(input_file, 'r') as input_zip: - placeholder_values = { - 'ro.boot.product.device_name': 'std', - } - - self.assertRaises(ValueError, common.PartitionBuildProps.FromInputFile, - input_zip, 'odm', placeholder_values) - - def test_parseBuildProps_duplicateOverride(self): - build_prop = copy.deepcopy(self.odm_build_prop) - build_prop.append( - 'import /odm/etc/build_${ro.boot.product.product_name}.prop') - - build_std_prop = [ - 'ro.product.odm.device=coral', - 'ro.product.odm.name=product1', - ] - build_pro_prop = [ - 'ro.product.odm.device=coralpro', - ] - - product1_prop = [ - 'ro.product.odm.name=product1', - ] - - product2_prop = [ - 'ro.product.odm.name=product2', - ] - - input_file = self._BuildZipFile({ - 'ODM/etc/build.prop': '\n'.join(build_prop), - 'ODM/etc/build_std.prop': '\n'.join(build_std_prop), - 'ODM/etc/build_pro.prop': '\n'.join(build_pro_prop), - 'ODM/etc/build_product1.prop': '\n'.join(product1_prop), - 'ODM/etc/build_product2.prop': '\n'.join(product2_prop), - }) - - with zipfile.ZipFile(input_file, 'r') as input_zip: - placeholder_values = { - 'ro.boot.product.device_name': 'std', - 'ro.boot.product.product_name': 'product1', - } - self.assertRaises(ValueError, common.PartitionBuildProps.FromInputFile, - input_zip, 'odm', placeholder_values) diff --git a/tools/releasetools/test_ota_from_target_files.py b/tools/releasetools/test_ota_from_target_files.py index 4077d06e69..38faf64aa6 100644 --- a/tools/releasetools/test_ota_from_target_files.py +++ b/tools/releasetools/test_ota_from_target_files.py @@ -26,8 +26,7 @@ from ota_from_target_files import ( GetPackageMetadata, GetTargetFilesZipForSecondaryImages, GetTargetFilesZipWithoutPostinstallConfig, NonAbOtaPropertyFiles, Payload, PayloadSigner, POSTINSTALL_CONFIG, PropertyFiles, - StreamingPropertyFiles, WriteFingerprintAssertion, - CalculateRuntimeFingerprints) + StreamingPropertyFiles, WriteFingerprintAssertion) def construct_target_files(secondary=False): @@ -109,58 +108,55 @@ class LoadOemDictsTest(test_utils.ReleaseToolsTestCase): class OtaFromTargetFilesTest(test_utils.ReleaseToolsTestCase): + TEST_TARGET_INFO_DICT = { - 'build.prop': common.PartitionBuildProps.FromDictionary( - 'system', { - 'ro.product.device': 'product-device', - 'ro.build.fingerprint': 'build-fingerprint-target', - 'ro.build.version.incremental': 'build-version-incremental-target', - 'ro.build.version.sdk': '27', - 'ro.build.version.security_patch': '2017-12-01', - 'ro.build.date.utc': '1500000000'} - ) + 'build.prop' : { + 'ro.product.device' : 'product-device', + 'ro.build.fingerprint' : 'build-fingerprint-target', + 'ro.build.version.incremental' : 'build-version-incremental-target', + 'ro.build.version.sdk' : '27', + 'ro.build.version.security_patch' : '2017-12-01', + 'ro.build.date.utc' : '1500000000', + }, } TEST_SOURCE_INFO_DICT = { - 'build.prop': common.PartitionBuildProps.FromDictionary( - 'system', { - 'ro.product.device': 'product-device', - 'ro.build.fingerprint': 'build-fingerprint-source', - 'ro.build.version.incremental': 'build-version-incremental-source', - 'ro.build.version.sdk': '25', - 'ro.build.version.security_patch': '2016-12-01', - 'ro.build.date.utc': '1400000000'} - ) + 'build.prop' : { + 'ro.product.device' : 'product-device', + 'ro.build.fingerprint' : 'build-fingerprint-source', + 'ro.build.version.incremental' : 'build-version-incremental-source', + 'ro.build.version.sdk' : '25', + 'ro.build.version.security_patch' : '2016-12-01', + 'ro.build.date.utc' : '1400000000', + }, } TEST_INFO_DICT_USES_OEM_PROPS = { - 'build.prop': common.PartitionBuildProps.FromDictionary( - 'system', { - 'ro.product.name': 'product-name', - 'ro.build.thumbprint': 'build-thumbprint', - 'ro.build.bar': 'build-bar'} - ), - 'vendor.build.prop': common.PartitionBuildProps.FromDictionary( - 'vendor', { - 'ro.vendor.build.fingerprint': 'vendor-build-fingerprint'} - ), - 'property1': 'value1', - 'property2': 4096, - 'oem_fingerprint_properties': 'ro.product.device ro.product.brand', + 'build.prop' : { + 'ro.product.name' : 'product-name', + 'ro.build.thumbprint' : 'build-thumbprint', + 'ro.build.bar' : 'build-bar', + }, + 'vendor.build.prop' : { + 'ro.vendor.build.fingerprint' : 'vendor-build-fingerprint', + }, + 'property1' : 'value1', + 'property2' : 4096, + 'oem_fingerprint_properties' : 'ro.product.device ro.product.brand', } TEST_OEM_DICTS = [ { - 'ro.product.brand': 'brand1', - 'ro.product.device': 'device1', + 'ro.product.brand' : 'brand1', + 'ro.product.device' : 'device1', }, { - 'ro.product.brand': 'brand2', - 'ro.product.device': 'device2', + 'ro.product.brand' : 'brand2', + 'ro.product.device' : 'device2', }, { - 'ro.product.brand': 'brand3', - 'ro.product.device': 'device3', + 'ro.product.brand' : 'brand3', + 'ro.product.device' : 'device3', }, ] @@ -292,10 +288,10 @@ class OtaFromTargetFilesTest(test_utils.ReleaseToolsTestCase): @staticmethod def _test_GetPackageMetadata_swapBuildTimestamps(target_info, source_info): - (target_info['build.prop'].build_props['ro.build.date.utc'], - source_info['build.prop'].build_props['ro.build.date.utc']) = ( - source_info['build.prop'].build_props['ro.build.date.utc'], - target_info['build.prop'].build_props['ro.build.date.utc']) + (target_info['build.prop']['ro.build.date.utc'], + source_info['build.prop']['ro.build.date.utc']) = ( + source_info['build.prop']['ro.build.date.utc'], + target_info['build.prop']['ro.build.date.utc']) def test_GetPackageMetadata_unintentionalDowngradeDetected(self): target_info_dict = copy.deepcopy(self.TEST_TARGET_INFO_DICT) @@ -532,7 +528,7 @@ class OtaFromTargetFilesTest(test_utils.ReleaseToolsTestCase): def test_WriteFingerprintAssertion_without_oem_props(self): target_info = common.BuildInfo(self.TEST_TARGET_INFO_DICT, None) source_info_dict = copy.deepcopy(self.TEST_TARGET_INFO_DICT) - source_info_dict['build.prop'].build_props['ro.build.fingerprint'] = ( + source_info_dict['build.prop']['ro.build.fingerprint'] = ( 'source-build-fingerprint') source_info = common.BuildInfo(source_info_dict, None) @@ -571,7 +567,7 @@ class OtaFromTargetFilesTest(test_utils.ReleaseToolsTestCase): target_info = common.BuildInfo(self.TEST_INFO_DICT_USES_OEM_PROPS, self.TEST_OEM_DICTS) source_info_dict = copy.deepcopy(self.TEST_INFO_DICT_USES_OEM_PROPS) - source_info_dict['build.prop'].build_props['ro.build.thumbprint'] = ( + source_info_dict['build.prop']['ro.build.thumbprint'] = ( 'source-build-thumbprint') source_info = common.BuildInfo(source_info_dict, self.TEST_OEM_DICTS) @@ -1319,125 +1315,3 @@ class PayloadTest(test_utils.ReleaseToolsTestCase): Payload.SECONDARY_PAYLOAD_PROPERTIES_TXT): continue self.assertEqual(zipfile.ZIP_STORED, entry_info.compress_type) - - -class RuntimeFingerprintTest(test_utils.ReleaseToolsTestCase): - MISC_INFO = [ - 'recovery_api_version=3', - 'fstab_version=2', - 'recovery_as_boot=true', - ] - - BUILD_PROP = [ - 'ro.build.version.release=version-release', - 'ro.build.id=build-id', - 'ro.build.version.incremental=version-incremental', - 'ro.build.type=build-type', - 'ro.build.tags=build-tags', - ] - - VENDOR_BUILD_PROP = [ - 'ro.product.vendor.brand=vendor-product-brand', - 'ro.product.vendor.name=vendor-product-name', - 'ro.product.vendor.device=vendor-product-device' - ] - - def setUp(self): - common.OPTIONS.oem_dicts = None - self.test_dir = common.MakeTempDir() - self.writeFiles({'META/misc_info.txt': '\n'.join(self.MISC_INFO)}) - - def writeFiles(self, contents_dict): - for path, content in contents_dict.items(): - abs_path = os.path.join(self.test_dir, path) - dir_name = os.path.dirname(abs_path) - if not os.path.exists(dir_name): - os.makedirs(dir_name) - with open(abs_path, 'w') as f: - f.write(content) - - @staticmethod - def constructFingerprint(prefix): - return '{}:version-release/build-id/version-incremental:' \ - 'build-type/build-tags'.format(prefix) - - def test_CalculatePossibleFingerprints_no_dynamic_fingerprint(self): - build_prop = copy.deepcopy(self.BUILD_PROP) - build_prop.extend([ - 'ro.product.brand=product-brand', - 'ro.product.name=product-name', - 'ro.product.device=product-device', - ]) - self.writeFiles({ - 'SYSTEM/build.prop': '\n'.join(build_prop), - 'VENDOR/build.prop': '\n'.join(self.VENDOR_BUILD_PROP), - }) - common.OPTIONS.info_dict = common.LoadInfoDict(self.test_dir) - - self.assertEqual({ - self.constructFingerprint('product-brand/product-name/product-device') - }, CalculateRuntimeFingerprints()) - - def test_CalculatePossibleFingerprints_single_override(self): - vendor_build_prop = copy.deepcopy(self.VENDOR_BUILD_PROP) - vendor_build_prop.extend([ - 'import /vendor/etc/build_${ro.boot.sku_name}.prop', - ]) - self.writeFiles({ - 'SYSTEM/build.prop': '\n'.join(self.BUILD_PROP), - 'VENDOR/build.prop': '\n'.join(vendor_build_prop), - 'VENDOR/etc/build_std.prop': - 'ro.product.vendor.name=vendor-product-std', - 'VENDOR/etc/build_pro.prop': - 'ro.product.vendor.name=vendor-product-pro', - }) - common.OPTIONS.info_dict = common.LoadInfoDict(self.test_dir) - common.OPTIONS.boot_variable_values = { - 'ro.boot.sku_name': ['std', 'pro'] - } - - self.assertEqual({ - self.constructFingerprint( - 'vendor-product-brand/vendor-product-name/vendor-product-device'), - self.constructFingerprint( - 'vendor-product-brand/vendor-product-std/vendor-product-device'), - self.constructFingerprint( - 'vendor-product-brand/vendor-product-pro/vendor-product-device'), - }, CalculateRuntimeFingerprints()) - - def test_CalculatePossibleFingerprints_multiple_overrides(self): - vendor_build_prop = copy.deepcopy(self.VENDOR_BUILD_PROP) - vendor_build_prop.extend([ - 'import /vendor/etc/build_${ro.boot.sku_name}.prop', - 'import /vendor/etc/build_${ro.boot.device_name}.prop', - ]) - self.writeFiles({ - 'SYSTEM/build.prop': '\n'.join(self.BUILD_PROP), - 'VENDOR/build.prop': '\n'.join(vendor_build_prop), - 'VENDOR/etc/build_std.prop': - 'ro.product.vendor.name=vendor-product-std', - 'VENDOR/etc/build_product1.prop': - 'ro.product.vendor.device=vendor-device-product1', - 'VENDOR/etc/build_pro.prop': - 'ro.product.vendor.name=vendor-product-pro', - 'VENDOR/etc/build_product2.prop': - 'ro.product.vendor.device=vendor-device-product2', - }) - common.OPTIONS.info_dict = common.LoadInfoDict(self.test_dir) - common.OPTIONS.boot_variable_values = { - 'ro.boot.sku_name': ['std', 'pro'], - 'ro.boot.device_name': ['product1', 'product2'], - } - - self.assertEqual({ - self.constructFingerprint( - 'vendor-product-brand/vendor-product-name/vendor-product-device'), - self.constructFingerprint( - 'vendor-product-brand/vendor-product-std/vendor-device-product1'), - self.constructFingerprint( - 'vendor-product-brand/vendor-product-pro/vendor-device-product1'), - self.constructFingerprint( - 'vendor-product-brand/vendor-product-std/vendor-device-product2'), - self.constructFingerprint( - 'vendor-product-brand/vendor-product-pro/vendor-device-product2'), - }, CalculateRuntimeFingerprints())