Add a wrapper class PartitionBuildProp
The build prop for a partition used to be a simple key:value dictionary. But we need more fields to hold the alternative build props overriden by the 'import' statement. Therefore, add a new class as a wrapper for these props first. Bug: 152167826 Test: unittests pass Change-Id: I2fe7e93a2f4de8e55f5f8051b000b96b5efdc85a
This commit is contained in:
@@ -548,17 +548,19 @@ def AddCareMapForAbOta(output_zip, ab_partitions, image_paths):
|
|||||||
care_map_list += care_map
|
care_map_list += care_map
|
||||||
|
|
||||||
# adds fingerprint field to the care_map
|
# adds fingerprint field to the care_map
|
||||||
build_props = OPTIONS.info_dict.get(partition + ".build.prop", {})
|
# TODO(xunchang) revisit the fingerprint calculation for care_map.
|
||||||
|
partition_props = OPTIONS.info_dict.get(partition + ".build.prop")
|
||||||
prop_name_list = ["ro.{}.build.fingerprint".format(partition),
|
prop_name_list = ["ro.{}.build.fingerprint".format(partition),
|
||||||
"ro.{}.build.thumbprint".format(partition)]
|
"ro.{}.build.thumbprint".format(partition)]
|
||||||
|
|
||||||
present_props = [x for x in prop_name_list if x in build_props]
|
present_props = [x for x in prop_name_list if
|
||||||
|
partition_props and partition_props.GetProp(x)]
|
||||||
if not present_props:
|
if not present_props:
|
||||||
logger.warning("fingerprint is not present for partition %s", partition)
|
logger.warning("fingerprint is not present for partition %s", partition)
|
||||||
property_id, fingerprint = "unknown", "unknown"
|
property_id, fingerprint = "unknown", "unknown"
|
||||||
else:
|
else:
|
||||||
property_id = present_props[0]
|
property_id = present_props[0]
|
||||||
fingerprint = build_props[property_id]
|
fingerprint = partition_props.GetProp(property_id)
|
||||||
care_map_list += [property_id, fingerprint]
|
care_map_list += [property_id, fingerprint]
|
||||||
|
|
||||||
if not care_map_list:
|
if not care_map_list:
|
||||||
|
@@ -509,9 +509,9 @@ def ImagePropFromGlobalDict(glob_dict, mount_point):
|
|||||||
d = {}
|
d = {}
|
||||||
|
|
||||||
if "build.prop" in glob_dict:
|
if "build.prop" in glob_dict:
|
||||||
bp = glob_dict["build.prop"]
|
timestamp = glob_dict["build.prop"].GetProp("ro.build.date.utc")
|
||||||
if "ro.build.date.utc" in bp:
|
if timestamp:
|
||||||
d["timestamp"] = bp["ro.build.date.utc"]
|
d["timestamp"] = timestamp
|
||||||
|
|
||||||
def copy_prop(src_p, dest_p):
|
def copy_prop(src_p, dest_p):
|
||||||
"""Copy a property from the global dictionary.
|
"""Copy a property from the global dictionary.
|
||||||
|
@@ -80,8 +80,9 @@ def GetArgsForSkus(info_dict):
|
|||||||
'--property', 'ro.boot.product.vendor.sku=' + vendor_sku]
|
'--property', 'ro.boot.product.vendor.sku=' + vendor_sku]
|
||||||
for odm_sku in odm_skus for vendor_sku in vendor_skus]
|
for odm_sku in odm_skus for vendor_sku in vendor_skus]
|
||||||
|
|
||||||
|
|
||||||
def GetArgsForShippingApiLevel(info_dict):
|
def GetArgsForShippingApiLevel(info_dict):
|
||||||
shipping_api_level = info_dict['vendor.build.prop'].get(
|
shipping_api_level = info_dict['vendor.build.prop'].GetProp(
|
||||||
'ro.product.first_api_level')
|
'ro.product.first_api_level')
|
||||||
if not shipping_api_level:
|
if not shipping_api_level:
|
||||||
logger.warning('Cannot determine ro.product.first_api_level')
|
logger.warning('Cannot determine ro.product.first_api_level')
|
||||||
|
@@ -423,6 +423,14 @@ class BuildInfo(object):
|
|||||||
def items(self):
|
def items(self):
|
||||||
return self.info_dict.items()
|
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):
|
def GetPartitionBuildProp(self, prop, partition):
|
||||||
"""Returns the inquired build property for the provided partition."""
|
"""Returns the inquired build property for the provided partition."""
|
||||||
# If provided a partition for this property, only look within that
|
# If provided a partition for this property, only look within that
|
||||||
@@ -431,31 +439,33 @@ class BuildInfo(object):
|
|||||||
prop = prop.replace("ro.product", "ro.product.{}".format(partition))
|
prop = prop.replace("ro.product", "ro.product.{}".format(partition))
|
||||||
else:
|
else:
|
||||||
prop = prop.replace("ro.", "ro.{}.".format(partition))
|
prop = prop.replace("ro.", "ro.{}.".format(partition))
|
||||||
try:
|
|
||||||
return self.info_dict.get("{}.build.prop".format(partition), {})[prop]
|
prop_val = self._GetRawBuildProp(prop, partition)
|
||||||
except KeyError:
|
if prop_val is not None:
|
||||||
raise ExternalError("couldn't find %s in %s.build.prop" %
|
return prop_val
|
||||||
(prop, partition))
|
raise ExternalError("couldn't find %s in %s.build.prop" %
|
||||||
|
(prop, partition))
|
||||||
|
|
||||||
def GetBuildProp(self, prop):
|
def GetBuildProp(self, prop):
|
||||||
"""Returns the inquired build property from the standard build.prop file."""
|
"""Returns the inquired build property from the standard build.prop file."""
|
||||||
if prop in BuildInfo._RO_PRODUCT_RESOLVE_PROPS:
|
if prop in BuildInfo._RO_PRODUCT_RESOLVE_PROPS:
|
||||||
return self._ResolveRoProductBuildProp(prop)
|
return self._ResolveRoProductBuildProp(prop)
|
||||||
|
|
||||||
try:
|
prop_val = self._GetRawBuildProp(prop, None)
|
||||||
return self.info_dict.get("build.prop", {})[prop]
|
if prop_val is not None:
|
||||||
except KeyError:
|
return prop_val
|
||||||
raise ExternalError("couldn't find %s in build.prop" % (prop,))
|
|
||||||
|
raise ExternalError("couldn't find %s in build.prop" % (prop,))
|
||||||
|
|
||||||
def _ResolveRoProductBuildProp(self, prop):
|
def _ResolveRoProductBuildProp(self, prop):
|
||||||
"""Resolves the inquired ro.product.* build property"""
|
"""Resolves the inquired ro.product.* build property"""
|
||||||
prop_val = self.info_dict.get("build.prop", {}).get(prop)
|
prop_val = self._GetRawBuildProp(prop, None)
|
||||||
if prop_val:
|
if prop_val:
|
||||||
return prop_val
|
return prop_val
|
||||||
|
|
||||||
default_source_order = self._GetRoProductPropsDefaultSourceOrder()
|
default_source_order = self._GetRoProductPropsDefaultSourceOrder()
|
||||||
source_order_val = self.info_dict.get("build.prop", {}).get(
|
source_order_val = self._GetRawBuildProp(
|
||||||
"ro.product.property_source_order")
|
"ro.product.property_source_order", None)
|
||||||
if source_order_val:
|
if source_order_val:
|
||||||
source_order = source_order_val.split(",")
|
source_order = source_order_val.split(",")
|
||||||
else:
|
else:
|
||||||
@@ -466,11 +476,10 @@ class BuildInfo(object):
|
|||||||
raise ExternalError(
|
raise ExternalError(
|
||||||
"Invalid ro.product.property_source_order '{}'".format(source_order))
|
"Invalid ro.product.property_source_order '{}'".format(source_order))
|
||||||
|
|
||||||
for source in source_order:
|
for source_partition in source_order:
|
||||||
source_prop = prop.replace(
|
source_prop = prop.replace(
|
||||||
"ro.product", "ro.product.{}".format(source), 1)
|
"ro.product", "ro.product.{}".format(source_partition), 1)
|
||||||
prop_val = self.info_dict.get(
|
prop_val = self._GetRawBuildProp(source_prop, source_partition)
|
||||||
"{}.build.prop".format(source), {}).get(source_prop)
|
|
||||||
if prop_val:
|
if prop_val:
|
||||||
return prop_val
|
return prop_val
|
||||||
|
|
||||||
@@ -479,11 +488,9 @@ class BuildInfo(object):
|
|||||||
def _GetRoProductPropsDefaultSourceOrder(self):
|
def _GetRoProductPropsDefaultSourceOrder(self):
|
||||||
# NOTE: refer to CDDs and android.os.Build.VERSION for the definition and
|
# NOTE: refer to CDDs and android.os.Build.VERSION for the definition and
|
||||||
# values of these properties for each Android release.
|
# values of these properties for each Android release.
|
||||||
android_codename = self.info_dict.get("build.prop", {}).get(
|
android_codename = self._GetRawBuildProp("ro.build.version.codename", None)
|
||||||
"ro.build.version.codename")
|
|
||||||
if android_codename == "REL":
|
if android_codename == "REL":
|
||||||
android_version = self.info_dict.get("build.prop", {}).get(
|
android_version = self._GetRawBuildProp("ro.build.version.release", None)
|
||||||
"ro.build.version.release")
|
|
||||||
if android_version == "10":
|
if android_version == "10":
|
||||||
return BuildInfo._RO_PRODUCT_PROPS_DEFAULT_SOURCE_ORDER_ANDROID_10
|
return BuildInfo._RO_PRODUCT_PROPS_DEFAULT_SOURCE_ORDER_ANDROID_10
|
||||||
# NOTE: float() conversion of android_version will have rounding error.
|
# NOTE: float() conversion of android_version will have rounding error.
|
||||||
@@ -566,6 +573,20 @@ class BuildInfo(object):
|
|||||||
script.AssertOemProperty(prop, values, oem_no_mount)
|
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):
|
def LoadInfoDict(input_file, repacking=False):
|
||||||
"""Loads the key/value pairs from the given input target_files.
|
"""Loads the key/value pairs from the given input target_files.
|
||||||
|
|
||||||
@@ -603,16 +624,7 @@ def LoadInfoDict(input_file, repacking=False):
|
|||||||
"input_file must be a path str when doing repacking"
|
"input_file must be a path str when doing repacking"
|
||||||
|
|
||||||
def read_helper(fn):
|
def read_helper(fn):
|
||||||
if isinstance(input_file, zipfile.ZipFile):
|
return ReadFromInputFile(input_file, fn)
|
||||||
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:
|
try:
|
||||||
d = LoadDictionaryFromLines(read_helper("META/misc_info.txt").split("\n"))
|
d = LoadDictionaryFromLines(read_helper("META/misc_info.txt").split("\n"))
|
||||||
@@ -675,13 +687,8 @@ def LoadInfoDict(input_file, repacking=False):
|
|||||||
# system and vendor.
|
# system and vendor.
|
||||||
for partition in PARTITIONS_WITH_CARE_MAP:
|
for partition in PARTITIONS_WITH_CARE_MAP:
|
||||||
partition_prop = "{}.build.prop".format(partition)
|
partition_prop = "{}.build.prop".format(partition)
|
||||||
d[partition_prop] = LoadBuildProp(
|
d[partition_prop] = PartitionBuildProps.FromInputFile(
|
||||||
read_helper, "{}/build.prop".format(partition.upper()))
|
input_file, partition)
|
||||||
# Some partition might use /<partition>/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"]
|
d["build.prop"] = d["system.build.prop"]
|
||||||
|
|
||||||
# Set up the salt (based on fingerprint) that will be used when adding AVB
|
# Set up the salt (based on fingerprint) that will be used when adding AVB
|
||||||
@@ -696,15 +703,6 @@ def LoadInfoDict(input_file, repacking=False):
|
|||||||
return d
|
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):
|
def LoadListFromFile(file_path):
|
||||||
with open(file_path) as f:
|
with open(file_path) as f:
|
||||||
return f.read().splitlines()
|
return f.read().splitlines()
|
||||||
@@ -727,6 +725,61 @@ def LoadDictionaryFromLines(lines):
|
|||||||
return d
|
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 dictionary of build properties for the given partition.
|
||||||
|
prop_overrides: a dict of list. And each list holds the overridden values
|
||||||
|
for props_allow_override.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, input_file, name):
|
||||||
|
self.input_file = input_file
|
||||||
|
self.partition = name
|
||||||
|
self.props_allow_override = [props.format(name) for props in [
|
||||||
|
'ro.product.{}.name', 'ro.product.{}.device']]
|
||||||
|
self.build_props = {}
|
||||||
|
self.prop_overrides = {}
|
||||||
|
|
||||||
|
@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):
|
||||||
|
"""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)
|
||||||
|
props.build_props = LoadDictionaryFromLines(data.split('\n'))
|
||||||
|
return props
|
||||||
|
|
||||||
|
def GetProp(self, prop):
|
||||||
|
return self.build_props.get(prop)
|
||||||
|
|
||||||
|
|
||||||
def LoadRecoveryFSTab(read_helper, fstab_version, recovery_fstab_path,
|
def LoadRecoveryFSTab(read_helper, fstab_version, recovery_fstab_path,
|
||||||
system_root_image=False):
|
system_root_image=False):
|
||||||
class Partition(object):
|
class Partition(object):
|
||||||
|
@@ -128,13 +128,16 @@ class AddImagesToTargetFilesTest(test_utils.ReleaseToolsTestCase):
|
|||||||
'vendor_image_size' : 40960,
|
'vendor_image_size' : 40960,
|
||||||
'system_verity_block_device': '/dev/block/system',
|
'system_verity_block_device': '/dev/block/system',
|
||||||
'vendor_verity_block_device': '/dev/block/vendor',
|
'vendor_verity_block_device': '/dev/block/vendor',
|
||||||
'system.build.prop': {
|
'system.build.prop': common.PartitionBuildProps.FromDictionary(
|
||||||
'ro.system.build.fingerprint':
|
'system', {
|
||||||
'google/sailfish/12345:user/dev-keys',
|
'ro.system.build.fingerprint':
|
||||||
},
|
'google/sailfish/12345:user/dev-keys'}
|
||||||
'vendor.build.prop': {
|
),
|
||||||
'ro.vendor.build.fingerprint': 'google/sailfish/678:user/dev-keys',
|
'vendor.build.prop': common.PartitionBuildProps.FromDictionary(
|
||||||
},
|
'vendor', {
|
||||||
|
'ro.vendor.build.fingerprint':
|
||||||
|
'google/sailfish/678:user/dev-keys'}
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
# Prepare the META/ folder.
|
# Prepare the META/ folder.
|
||||||
@@ -206,18 +209,21 @@ class AddImagesToTargetFilesTest(test_utils.ReleaseToolsTestCase):
|
|||||||
"""Tests the case for device using AVB."""
|
"""Tests the case for device using AVB."""
|
||||||
image_paths = self._test_AddCareMapForAbOta()
|
image_paths = self._test_AddCareMapForAbOta()
|
||||||
OPTIONS.info_dict = {
|
OPTIONS.info_dict = {
|
||||||
'extfs_sparse_flag' : '-s',
|
'extfs_sparse_flag': '-s',
|
||||||
'system_image_size' : 65536,
|
'system_image_size': 65536,
|
||||||
'vendor_image_size' : 40960,
|
'vendor_image_size': 40960,
|
||||||
'avb_system_hashtree_enable' : 'true',
|
'avb_system_hashtree_enable': 'true',
|
||||||
'avb_vendor_hashtree_enable' : 'true',
|
'avb_vendor_hashtree_enable': 'true',
|
||||||
'system.build.prop': {
|
'system.build.prop': common.PartitionBuildProps.FromDictionary(
|
||||||
'ro.system.build.fingerprint':
|
'system', {
|
||||||
'google/sailfish/12345:user/dev-keys',
|
'ro.system.build.fingerprint':
|
||||||
},
|
'google/sailfish/12345:user/dev-keys'}
|
||||||
'vendor.build.prop': {
|
),
|
||||||
'ro.vendor.build.fingerprint': 'google/sailfish/678:user/dev-keys',
|
'vendor.build.prop': common.PartitionBuildProps.FromDictionary(
|
||||||
}
|
'vendor', {
|
||||||
|
'ro.vendor.build.fingerprint':
|
||||||
|
'google/sailfish/678:user/dev-keys'}
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
AddCareMapForAbOta(None, ['system', 'vendor'], image_paths)
|
AddCareMapForAbOta(None, ['system', 'vendor'], image_paths)
|
||||||
@@ -258,17 +264,21 @@ class AddImagesToTargetFilesTest(test_utils.ReleaseToolsTestCase):
|
|||||||
"""Tests the case for partitions with thumbprint."""
|
"""Tests the case for partitions with thumbprint."""
|
||||||
image_paths = self._test_AddCareMapForAbOta()
|
image_paths = self._test_AddCareMapForAbOta()
|
||||||
OPTIONS.info_dict = {
|
OPTIONS.info_dict = {
|
||||||
'extfs_sparse_flag' : '-s',
|
'extfs_sparse_flag': '-s',
|
||||||
'system_image_size' : 65536,
|
'system_image_size': 65536,
|
||||||
'vendor_image_size' : 40960,
|
'vendor_image_size': 40960,
|
||||||
'system_verity_block_device': '/dev/block/system',
|
'system_verity_block_device': '/dev/block/system',
|
||||||
'vendor_verity_block_device': '/dev/block/vendor',
|
'vendor_verity_block_device': '/dev/block/vendor',
|
||||||
'system.build.prop': {
|
'system.build.prop': common.PartitionBuildProps.FromDictionary(
|
||||||
'ro.system.build.thumbprint': 'google/sailfish/123:user/dev-keys',
|
'system', {
|
||||||
},
|
'ro.system.build.thumbprint':
|
||||||
'vendor.build.prop' : {
|
'google/sailfish/123:user/dev-keys'}
|
||||||
'ro.vendor.build.thumbprint': 'google/sailfish/456:user/dev-keys',
|
),
|
||||||
},
|
'vendor.build.prop': common.PartitionBuildProps.FromDictionary(
|
||||||
|
'vendor', {
|
||||||
|
'ro.vendor.build.thumbprint':
|
||||||
|
'google/sailfish/456:user/dev-keys'}
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
AddCareMapForAbOta(None, ['system', 'vendor'], image_paths)
|
AddCareMapForAbOta(None, ['system', 'vendor'], image_paths)
|
||||||
|
@@ -48,109 +48,124 @@ def get_2gb_string():
|
|||||||
class BuildInfoTest(test_utils.ReleaseToolsTestCase):
|
class BuildInfoTest(test_utils.ReleaseToolsTestCase):
|
||||||
|
|
||||||
TEST_INFO_DICT = {
|
TEST_INFO_DICT = {
|
||||||
'build.prop' : {
|
'build.prop': common.PartitionBuildProps.FromDictionary(
|
||||||
'ro.product.device' : 'product-device',
|
'system', {
|
||||||
'ro.product.name' : 'product-name',
|
'ro.product.device': 'product-device',
|
||||||
'ro.build.fingerprint' : 'build-fingerprint',
|
'ro.product.name': 'product-name',
|
||||||
'ro.build.foo' : 'build-foo',
|
'ro.build.fingerprint': 'build-fingerprint',
|
||||||
},
|
'ro.build.foo': 'build-foo'}
|
||||||
'system.build.prop' : {
|
),
|
||||||
'ro.product.system.brand' : 'product-brand',
|
'system.build.prop': common.PartitionBuildProps.FromDictionary(
|
||||||
'ro.product.system.name' : 'product-name',
|
'system', {
|
||||||
'ro.product.system.device' : 'product-device',
|
'ro.product.system.brand': 'product-brand',
|
||||||
'ro.system.build.version.release' : 'version-release',
|
'ro.product.system.name': 'product-name',
|
||||||
'ro.system.build.id' : 'build-id',
|
'ro.product.system.device': 'product-device',
|
||||||
'ro.system.build.version.incremental' : 'version-incremental',
|
'ro.system.build.version.release': 'version-release',
|
||||||
'ro.system.build.type' : 'build-type',
|
'ro.system.build.id': 'build-id',
|
||||||
'ro.system.build.tags' : 'build-tags',
|
'ro.system.build.version.incremental': 'version-incremental',
|
||||||
'ro.system.build.foo' : 'build-foo',
|
'ro.system.build.type': 'build-type',
|
||||||
},
|
'ro.system.build.tags': 'build-tags',
|
||||||
'vendor.build.prop' : {
|
'ro.system.build.foo': 'build-foo'}
|
||||||
'ro.product.vendor.brand' : 'vendor-product-brand',
|
),
|
||||||
'ro.product.vendor.name' : 'vendor-product-name',
|
'vendor.build.prop': common.PartitionBuildProps.FromDictionary(
|
||||||
'ro.product.vendor.device' : 'vendor-product-device',
|
'vendor', {
|
||||||
'ro.vendor.build.version.release' : 'vendor-version-release',
|
'ro.product.vendor.brand': 'vendor-product-brand',
|
||||||
'ro.vendor.build.id' : 'vendor-build-id',
|
'ro.product.vendor.name': 'vendor-product-name',
|
||||||
'ro.vendor.build.version.incremental' : 'vendor-version-incremental',
|
'ro.product.vendor.device': 'vendor-product-device',
|
||||||
'ro.vendor.build.type' : 'vendor-build-type',
|
'ro.vendor.build.version.release': 'vendor-version-release',
|
||||||
'ro.vendor.build.tags' : 'vendor-build-tags',
|
'ro.vendor.build.id': 'vendor-build-id',
|
||||||
},
|
'ro.vendor.build.version.incremental':
|
||||||
'property1' : 'value1',
|
'vendor-version-incremental',
|
||||||
'property2' : 4096,
|
'ro.vendor.build.type': 'vendor-build-type',
|
||||||
|
'ro.vendor.build.tags': 'vendor-build-tags'}
|
||||||
|
),
|
||||||
|
'property1': 'value1',
|
||||||
|
'property2': 4096,
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_INFO_DICT_USES_OEM_PROPS = {
|
TEST_INFO_DICT_USES_OEM_PROPS = {
|
||||||
'build.prop' : {
|
'build.prop': common.PartitionBuildProps.FromDictionary(
|
||||||
'ro.product.name' : 'product-name',
|
'system', {
|
||||||
'ro.build.thumbprint' : 'build-thumbprint',
|
'ro.product.name': 'product-name',
|
||||||
'ro.build.bar' : 'build-bar',
|
'ro.build.thumbprint': 'build-thumbprint',
|
||||||
},
|
'ro.build.bar': 'build-bar'}
|
||||||
'vendor.build.prop' : {
|
),
|
||||||
'ro.vendor.build.fingerprint' : 'vendor-build-fingerprint',
|
'vendor.build.prop': common.PartitionBuildProps.FromDictionary(
|
||||||
},
|
'vendor', {
|
||||||
'property1' : 'value1',
|
'ro.vendor.build.fingerprint': 'vendor-build-fingerprint'}
|
||||||
'property2' : 4096,
|
),
|
||||||
'oem_fingerprint_properties' : 'ro.product.device ro.product.brand',
|
'property1': 'value1',
|
||||||
|
'property2': 4096,
|
||||||
|
'oem_fingerprint_properties': 'ro.product.device ro.product.brand',
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_OEM_DICTS = [
|
TEST_OEM_DICTS = [
|
||||||
{
|
{
|
||||||
'ro.product.brand' : 'brand1',
|
'ro.product.brand': 'brand1',
|
||||||
'ro.product.device' : 'device1',
|
'ro.product.device': 'device1',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'ro.product.brand' : 'brand2',
|
'ro.product.brand': 'brand2',
|
||||||
'ro.product.device' : 'device2',
|
'ro.product.device': 'device2',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'ro.product.brand' : 'brand3',
|
'ro.product.brand': 'brand3',
|
||||||
'ro.product.device' : 'device3',
|
'ro.product.device': 'device3',
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
TEST_INFO_DICT_PROPERTY_SOURCE_ORDER = {
|
TEST_INFO_DICT_PROPERTY_SOURCE_ORDER = {
|
||||||
'build.prop' : {
|
'build.prop': common.PartitionBuildProps.FromDictionary(
|
||||||
'ro.build.fingerprint' : 'build-fingerprint',
|
'system', {
|
||||||
'ro.product.property_source_order' :
|
'ro.build.fingerprint': 'build-fingerprint',
|
||||||
'product,odm,vendor,system_ext,system',
|
'ro.product.property_source_order':
|
||||||
},
|
'product,odm,vendor,system_ext,system'}
|
||||||
'system.build.prop' : {
|
),
|
||||||
'ro.product.system.device' : 'system-product-device',
|
'system.build.prop': common.PartitionBuildProps.FromDictionary(
|
||||||
},
|
'system', {
|
||||||
'vendor.build.prop' : {
|
'ro.product.system.device': 'system-product-device'}
|
||||||
'ro.product.vendor.device' : 'vendor-product-device',
|
),
|
||||||
},
|
'vendor.build.prop': common.PartitionBuildProps.FromDictionary(
|
||||||
|
'vendor', {
|
||||||
|
'ro.product.vendor.device': 'vendor-product-device'}
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_INFO_DICT_PROPERTY_SOURCE_ORDER_ANDROID_10 = {
|
TEST_INFO_DICT_PROPERTY_SOURCE_ORDER_ANDROID_10 = {
|
||||||
'build.prop' : {
|
'build.prop': common.PartitionBuildProps.FromDictionary(
|
||||||
'ro.build.fingerprint' : 'build-fingerprint',
|
'system', {
|
||||||
'ro.product.property_source_order' :
|
'ro.build.fingerprint': 'build-fingerprint',
|
||||||
'product,product_services,odm,vendor,system',
|
'ro.product.property_source_order':
|
||||||
'ro.build.version.release' : '10',
|
'product,product_services,odm,vendor,system',
|
||||||
'ro.build.version.codename' : 'REL',
|
'ro.build.version.release': '10',
|
||||||
},
|
'ro.build.version.codename': 'REL'}
|
||||||
'system.build.prop' : {
|
),
|
||||||
'ro.product.system.device' : 'system-product-device',
|
'system.build.prop': common.PartitionBuildProps.FromDictionary(
|
||||||
},
|
'system', {
|
||||||
'vendor.build.prop' : {
|
'ro.product.system.device': 'system-product-device'}
|
||||||
'ro.product.vendor.device' : 'vendor-product-device',
|
),
|
||||||
},
|
'vendor.build.prop': common.PartitionBuildProps.FromDictionary(
|
||||||
|
'vendor', {
|
||||||
|
'ro.product.vendor.device': 'vendor-product-device'}
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_INFO_DICT_PROPERTY_SOURCE_ORDER_ANDROID_9 = {
|
TEST_INFO_DICT_PROPERTY_SOURCE_ORDER_ANDROID_9 = {
|
||||||
'build.prop' : {
|
'build.prop': common.PartitionBuildProps.FromDictionary(
|
||||||
'ro.product.device' : 'product-device',
|
'system', {
|
||||||
'ro.build.fingerprint' : 'build-fingerprint',
|
'ro.product.device': 'product-device',
|
||||||
'ro.build.version.release' : '9',
|
'ro.build.fingerprint': 'build-fingerprint',
|
||||||
'ro.build.version.codename' : 'REL',
|
'ro.build.version.release': '9',
|
||||||
},
|
'ro.build.version.codename': 'REL'}
|
||||||
'system.build.prop' : {
|
),
|
||||||
'ro.product.system.device' : 'system-product-device',
|
'system.build.prop': common.PartitionBuildProps.FromDictionary(
|
||||||
},
|
'system', {
|
||||||
'vendor.build.prop' : {
|
'ro.product.system.device': 'system-product-device'}
|
||||||
'ro.product.vendor.device' : 'vendor-product-device',
|
),
|
||||||
},
|
'vendor.build.prop': common.PartitionBuildProps.FromDictionary(
|
||||||
|
'vendor', {
|
||||||
|
'ro.product.vendor.device': 'vendor-product-device'}
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
def test_init(self):
|
def test_init(self):
|
||||||
@@ -178,25 +193,27 @@ class BuildInfoTest(test_utils.ReleaseToolsTestCase):
|
|||||||
|
|
||||||
def test_init_badFingerprint(self):
|
def test_init_badFingerprint(self):
|
||||||
info_dict = copy.deepcopy(self.TEST_INFO_DICT)
|
info_dict = copy.deepcopy(self.TEST_INFO_DICT)
|
||||||
info_dict['build.prop']['ro.build.fingerprint'] = 'bad fingerprint'
|
info_dict['build.prop'].build_props[
|
||||||
|
'ro.build.fingerprint'] = 'bad fingerprint'
|
||||||
self.assertRaises(ValueError, common.BuildInfo, info_dict, None)
|
self.assertRaises(ValueError, common.BuildInfo, info_dict, None)
|
||||||
|
|
||||||
info_dict['build.prop']['ro.build.fingerprint'] = 'bad\x80fingerprint'
|
info_dict['build.prop'].build_props[
|
||||||
|
'ro.build.fingerprint'] = 'bad\x80fingerprint'
|
||||||
self.assertRaises(ValueError, common.BuildInfo, info_dict, None)
|
self.assertRaises(ValueError, common.BuildInfo, info_dict, None)
|
||||||
|
|
||||||
def test___getitem__(self):
|
def test___getitem__(self):
|
||||||
target_info = common.BuildInfo(self.TEST_INFO_DICT, None)
|
target_info = common.BuildInfo(self.TEST_INFO_DICT, None)
|
||||||
self.assertEqual('value1', target_info['property1'])
|
self.assertEqual('value1', target_info['property1'])
|
||||||
self.assertEqual(4096, target_info['property2'])
|
self.assertEqual(4096, target_info['property2'])
|
||||||
self.assertEqual('build-foo', target_info['build.prop']['ro.build.foo'])
|
self.assertEqual('build-foo',
|
||||||
|
target_info['build.prop'].GetProp('ro.build.foo'))
|
||||||
|
|
||||||
def test___getitem__with_oem_props(self):
|
def test___getitem__with_oem_props(self):
|
||||||
target_info = common.BuildInfo(self.TEST_INFO_DICT_USES_OEM_PROPS,
|
target_info = common.BuildInfo(self.TEST_INFO_DICT_USES_OEM_PROPS,
|
||||||
self.TEST_OEM_DICTS)
|
self.TEST_OEM_DICTS)
|
||||||
self.assertEqual('value1', target_info['property1'])
|
self.assertEqual('value1', target_info['property1'])
|
||||||
self.assertEqual(4096, target_info['property2'])
|
self.assertEqual(4096, target_info['property2'])
|
||||||
self.assertRaises(KeyError,
|
self.assertIsNone(target_info['build.prop'].GetProp('ro.build.foo'))
|
||||||
lambda: target_info['build.prop']['ro.build.foo'])
|
|
||||||
|
|
||||||
def test___setitem__(self):
|
def test___setitem__(self):
|
||||||
target_info = common.BuildInfo(copy.deepcopy(self.TEST_INFO_DICT), None)
|
target_info = common.BuildInfo(copy.deepcopy(self.TEST_INFO_DICT), None)
|
||||||
@@ -204,9 +221,11 @@ class BuildInfoTest(test_utils.ReleaseToolsTestCase):
|
|||||||
target_info['property1'] = 'value2'
|
target_info['property1'] = 'value2'
|
||||||
self.assertEqual('value2', target_info['property1'])
|
self.assertEqual('value2', target_info['property1'])
|
||||||
|
|
||||||
self.assertEqual('build-foo', target_info['build.prop']['ro.build.foo'])
|
self.assertEqual('build-foo',
|
||||||
target_info['build.prop']['ro.build.foo'] = 'build-bar'
|
target_info['build.prop'].GetProp('ro.build.foo'))
|
||||||
self.assertEqual('build-bar', target_info['build.prop']['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'))
|
||||||
|
|
||||||
def test_get(self):
|
def test_get(self):
|
||||||
target_info = common.BuildInfo(self.TEST_INFO_DICT, None)
|
target_info = common.BuildInfo(self.TEST_INFO_DICT, None)
|
||||||
@@ -214,7 +233,8 @@ class BuildInfoTest(test_utils.ReleaseToolsTestCase):
|
|||||||
self.assertEqual(4096, target_info.get('property2'))
|
self.assertEqual(4096, target_info.get('property2'))
|
||||||
self.assertEqual(4096, target_info.get('property2', 1024))
|
self.assertEqual(4096, target_info.get('property2', 1024))
|
||||||
self.assertEqual(1024, target_info.get('property-nonexistent', 1024))
|
self.assertEqual(1024, target_info.get('property-nonexistent', 1024))
|
||||||
self.assertEqual('build-foo', target_info.get('build.prop')['ro.build.foo'])
|
self.assertEqual('build-foo',
|
||||||
|
target_info.get('build.prop').GetProp('ro.build.foo'))
|
||||||
|
|
||||||
def test_get_with_oem_props(self):
|
def test_get_with_oem_props(self):
|
||||||
target_info = common.BuildInfo(self.TEST_INFO_DICT_USES_OEM_PROPS,
|
target_info = common.BuildInfo(self.TEST_INFO_DICT_USES_OEM_PROPS,
|
||||||
@@ -223,9 +243,7 @@ class BuildInfoTest(test_utils.ReleaseToolsTestCase):
|
|||||||
self.assertEqual(4096, target_info.get('property2'))
|
self.assertEqual(4096, target_info.get('property2'))
|
||||||
self.assertEqual(4096, target_info.get('property2', 1024))
|
self.assertEqual(4096, target_info.get('property2', 1024))
|
||||||
self.assertEqual(1024, target_info.get('property-nonexistent', 1024))
|
self.assertEqual(1024, target_info.get('property-nonexistent', 1024))
|
||||||
self.assertIsNone(target_info.get('build.prop').get('ro.build.foo'))
|
self.assertIsNone(target_info.get('build.prop').GetProp('ro.build.foo'))
|
||||||
self.assertRaises(KeyError,
|
|
||||||
lambda: target_info.get('build.prop')['ro.build.foo'])
|
|
||||||
|
|
||||||
def test_items(self):
|
def test_items(self):
|
||||||
target_info = common.BuildInfo(self.TEST_INFO_DICT, None)
|
target_info = common.BuildInfo(self.TEST_INFO_DICT, None)
|
||||||
@@ -262,7 +280,8 @@ class BuildInfoTest(test_utils.ReleaseToolsTestCase):
|
|||||||
|
|
||||||
def test_GetPartitionFingerprint_uses_fingerprint_prop_if_available(self):
|
def test_GetPartitionFingerprint_uses_fingerprint_prop_if_available(self):
|
||||||
info_dict = copy.deepcopy(self.TEST_INFO_DICT)
|
info_dict = copy.deepcopy(self.TEST_INFO_DICT)
|
||||||
info_dict['vendor.build.prop']['ro.vendor.build.fingerprint'] = 'vendor:fingerprint'
|
info_dict['vendor.build.prop'].build_props[
|
||||||
|
'ro.vendor.build.fingerprint'] = 'vendor:fingerprint'
|
||||||
target_info = common.BuildInfo(info_dict, None)
|
target_info = common.BuildInfo(info_dict, None)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
target_info.GetPartitionFingerprint('vendor'),
|
target_info.GetPartitionFingerprint('vendor'),
|
||||||
@@ -303,14 +322,15 @@ class BuildInfoTest(test_utils.ReleaseToolsTestCase):
|
|||||||
|
|
||||||
def test_ResolveRoProductProperty_FromSystem(self):
|
def test_ResolveRoProductProperty_FromSystem(self):
|
||||||
info_dict = copy.deepcopy(self.TEST_INFO_DICT_PROPERTY_SOURCE_ORDER)
|
info_dict = copy.deepcopy(self.TEST_INFO_DICT_PROPERTY_SOURCE_ORDER)
|
||||||
del info_dict['vendor.build.prop']['ro.product.vendor.device']
|
del info_dict['vendor.build.prop'].build_props['ro.product.vendor.device']
|
||||||
info = common.BuildInfo(info_dict, None)
|
info = common.BuildInfo(info_dict, None)
|
||||||
self.assertEqual('system-product-device',
|
self.assertEqual('system-product-device',
|
||||||
info.GetBuildProp('ro.product.device'))
|
info.GetBuildProp('ro.product.device'))
|
||||||
|
|
||||||
def test_ResolveRoProductProperty_InvalidPropertySearchOrder(self):
|
def test_ResolveRoProductProperty_InvalidPropertySearchOrder(self):
|
||||||
info_dict = copy.deepcopy(self.TEST_INFO_DICT_PROPERTY_SOURCE_ORDER)
|
info_dict = copy.deepcopy(self.TEST_INFO_DICT_PROPERTY_SOURCE_ORDER)
|
||||||
info_dict['build.prop']['ro.product.property_source_order'] = 'bad-source'
|
info_dict['build.prop'].build_props[
|
||||||
|
'ro.product.property_source_order'] = 'bad-source'
|
||||||
with self.assertRaisesRegexp(common.ExternalError,
|
with self.assertRaisesRegexp(common.ExternalError,
|
||||||
'Invalid ro.product.property_source_order'):
|
'Invalid ro.product.property_source_order'):
|
||||||
info = common.BuildInfo(info_dict, None)
|
info = common.BuildInfo(info_dict, None)
|
||||||
@@ -1513,12 +1533,14 @@ class CommonUtilsTest(test_utils.ReleaseToolsTestCase):
|
|||||||
common.OPTIONS.info_dict = {
|
common.OPTIONS.info_dict = {
|
||||||
'ab_update': 'true',
|
'ab_update': 'true',
|
||||||
'avb_avbtool': 'avbtool',
|
'avb_avbtool': 'avbtool',
|
||||||
'build.prop': {
|
'build.prop': common.PartitionBuildProps.FromDictionary(
|
||||||
'ro.build.version.incremental': '6285659',
|
'system', {
|
||||||
'ro.product.device': 'coral',
|
'ro.build.version.incremental': '6285659',
|
||||||
'ro.build.fingerprint': 'google/coral/coral:R/RP1A.200311.002/'
|
'ro.product.device': 'coral',
|
||||||
'6285659:userdebug/dev-keys'
|
'ro.build.fingerprint':
|
||||||
}
|
'google/coral/coral:R/RP1A.200311.002/'
|
||||||
|
'6285659:userdebug/dev-keys'}
|
||||||
|
),
|
||||||
}
|
}
|
||||||
common.OPTIONS.aftl_tool_path = 'aftltool'
|
common.OPTIONS.aftl_tool_path = 'aftltool'
|
||||||
common.OPTIONS.aftl_server = 'log.endpoints.aftl-dev.cloud.goog:9000'
|
common.OPTIONS.aftl_server = 'log.endpoints.aftl-dev.cloud.goog:9000'
|
||||||
@@ -1551,12 +1573,14 @@ class CommonUtilsTest(test_utils.ReleaseToolsTestCase):
|
|||||||
common.OPTIONS.info_dict = {
|
common.OPTIONS.info_dict = {
|
||||||
'ab_update': 'true',
|
'ab_update': 'true',
|
||||||
'avb_avbtool': 'avbtool',
|
'avb_avbtool': 'avbtool',
|
||||||
'build.prop': {
|
'build.prop': common.PartitionBuildProps.FromDictionary(
|
||||||
'ro.build.version.incremental': '6285659',
|
'system', {
|
||||||
'ro.product.device': 'coral',
|
'ro.build.version.incremental': '6285659',
|
||||||
'ro.build.fingerprint': 'google/coral/coral:R/RP1A.200311.002/'
|
'ro.product.device': 'coral',
|
||||||
'6285659:userdebug/dev-keys'
|
'ro.build.fingerprint':
|
||||||
}
|
'google/coral/coral:R/RP1A.200311.002/'
|
||||||
|
'6285659:userdebug/dev-keys'}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
common.OPTIONS.aftl_tool_path = "aftltool"
|
common.OPTIONS.aftl_tool_path = "aftltool"
|
||||||
common.OPTIONS.aftl_server = "log.endpoints.aftl-dev.cloud.goog:9000"
|
common.OPTIONS.aftl_server = "log.endpoints.aftl-dev.cloud.goog:9000"
|
||||||
@@ -1871,3 +1895,47 @@ super_group_foo_group_size={group_foo_size}
|
|||||||
|
|
||||||
lines = self.get_op_list(self.output_path)
|
lines = self.get_op_list(self.output_path)
|
||||||
self.assertEqual(lines, ["remove foo"])
|
self.assertEqual(lines, ["remove foo"])
|
||||||
|
|
||||||
|
|
||||||
|
class PartitionBuildPropsTest(test_utils.ReleaseToolsTestCase):
|
||||||
|
def setUp(self):
|
||||||
|
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',
|
||||||
|
'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:
|
||||||
|
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({}, partition_props.prop_overrides)
|
||||||
|
@@ -108,55 +108,58 @@ class LoadOemDictsTest(test_utils.ReleaseToolsTestCase):
|
|||||||
|
|
||||||
|
|
||||||
class OtaFromTargetFilesTest(test_utils.ReleaseToolsTestCase):
|
class OtaFromTargetFilesTest(test_utils.ReleaseToolsTestCase):
|
||||||
|
|
||||||
TEST_TARGET_INFO_DICT = {
|
TEST_TARGET_INFO_DICT = {
|
||||||
'build.prop' : {
|
'build.prop': common.PartitionBuildProps.FromDictionary(
|
||||||
'ro.product.device' : 'product-device',
|
'system', {
|
||||||
'ro.build.fingerprint' : 'build-fingerprint-target',
|
'ro.product.device': 'product-device',
|
||||||
'ro.build.version.incremental' : 'build-version-incremental-target',
|
'ro.build.fingerprint': 'build-fingerprint-target',
|
||||||
'ro.build.version.sdk' : '27',
|
'ro.build.version.incremental': 'build-version-incremental-target',
|
||||||
'ro.build.version.security_patch' : '2017-12-01',
|
'ro.build.version.sdk': '27',
|
||||||
'ro.build.date.utc' : '1500000000',
|
'ro.build.version.security_patch': '2017-12-01',
|
||||||
},
|
'ro.build.date.utc': '1500000000'}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_SOURCE_INFO_DICT = {
|
TEST_SOURCE_INFO_DICT = {
|
||||||
'build.prop' : {
|
'build.prop': common.PartitionBuildProps.FromDictionary(
|
||||||
'ro.product.device' : 'product-device',
|
'system', {
|
||||||
'ro.build.fingerprint' : 'build-fingerprint-source',
|
'ro.product.device': 'product-device',
|
||||||
'ro.build.version.incremental' : 'build-version-incremental-source',
|
'ro.build.fingerprint': 'build-fingerprint-source',
|
||||||
'ro.build.version.sdk' : '25',
|
'ro.build.version.incremental': 'build-version-incremental-source',
|
||||||
'ro.build.version.security_patch' : '2016-12-01',
|
'ro.build.version.sdk': '25',
|
||||||
'ro.build.date.utc' : '1400000000',
|
'ro.build.version.security_patch': '2016-12-01',
|
||||||
},
|
'ro.build.date.utc': '1400000000'}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_INFO_DICT_USES_OEM_PROPS = {
|
TEST_INFO_DICT_USES_OEM_PROPS = {
|
||||||
'build.prop' : {
|
'build.prop': common.PartitionBuildProps.FromDictionary(
|
||||||
'ro.product.name' : 'product-name',
|
'system', {
|
||||||
'ro.build.thumbprint' : 'build-thumbprint',
|
'ro.product.name': 'product-name',
|
||||||
'ro.build.bar' : 'build-bar',
|
'ro.build.thumbprint': 'build-thumbprint',
|
||||||
},
|
'ro.build.bar': 'build-bar'}
|
||||||
'vendor.build.prop' : {
|
),
|
||||||
'ro.vendor.build.fingerprint' : 'vendor-build-fingerprint',
|
'vendor.build.prop': common.PartitionBuildProps.FromDictionary(
|
||||||
},
|
'vendor', {
|
||||||
'property1' : 'value1',
|
'ro.vendor.build.fingerprint': 'vendor-build-fingerprint'}
|
||||||
'property2' : 4096,
|
),
|
||||||
'oem_fingerprint_properties' : 'ro.product.device ro.product.brand',
|
'property1': 'value1',
|
||||||
|
'property2': 4096,
|
||||||
|
'oem_fingerprint_properties': 'ro.product.device ro.product.brand',
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_OEM_DICTS = [
|
TEST_OEM_DICTS = [
|
||||||
{
|
{
|
||||||
'ro.product.brand' : 'brand1',
|
'ro.product.brand': 'brand1',
|
||||||
'ro.product.device' : 'device1',
|
'ro.product.device': 'device1',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'ro.product.brand' : 'brand2',
|
'ro.product.brand': 'brand2',
|
||||||
'ro.product.device' : 'device2',
|
'ro.product.device': 'device2',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'ro.product.brand' : 'brand3',
|
'ro.product.brand': 'brand3',
|
||||||
'ro.product.device' : 'device3',
|
'ro.product.device': 'device3',
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -288,10 +291,10 @@ class OtaFromTargetFilesTest(test_utils.ReleaseToolsTestCase):
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _test_GetPackageMetadata_swapBuildTimestamps(target_info, source_info):
|
def _test_GetPackageMetadata_swapBuildTimestamps(target_info, source_info):
|
||||||
(target_info['build.prop']['ro.build.date.utc'],
|
(target_info['build.prop'].build_props['ro.build.date.utc'],
|
||||||
source_info['build.prop']['ro.build.date.utc']) = (
|
source_info['build.prop'].build_props['ro.build.date.utc']) = (
|
||||||
source_info['build.prop']['ro.build.date.utc'],
|
source_info['build.prop'].build_props['ro.build.date.utc'],
|
||||||
target_info['build.prop']['ro.build.date.utc'])
|
target_info['build.prop'].build_props['ro.build.date.utc'])
|
||||||
|
|
||||||
def test_GetPackageMetadata_unintentionalDowngradeDetected(self):
|
def test_GetPackageMetadata_unintentionalDowngradeDetected(self):
|
||||||
target_info_dict = copy.deepcopy(self.TEST_TARGET_INFO_DICT)
|
target_info_dict = copy.deepcopy(self.TEST_TARGET_INFO_DICT)
|
||||||
@@ -528,7 +531,7 @@ class OtaFromTargetFilesTest(test_utils.ReleaseToolsTestCase):
|
|||||||
def test_WriteFingerprintAssertion_without_oem_props(self):
|
def test_WriteFingerprintAssertion_without_oem_props(self):
|
||||||
target_info = common.BuildInfo(self.TEST_TARGET_INFO_DICT, None)
|
target_info = common.BuildInfo(self.TEST_TARGET_INFO_DICT, None)
|
||||||
source_info_dict = copy.deepcopy(self.TEST_TARGET_INFO_DICT)
|
source_info_dict = copy.deepcopy(self.TEST_TARGET_INFO_DICT)
|
||||||
source_info_dict['build.prop']['ro.build.fingerprint'] = (
|
source_info_dict['build.prop'].build_props['ro.build.fingerprint'] = (
|
||||||
'source-build-fingerprint')
|
'source-build-fingerprint')
|
||||||
source_info = common.BuildInfo(source_info_dict, None)
|
source_info = common.BuildInfo(source_info_dict, None)
|
||||||
|
|
||||||
@@ -567,7 +570,7 @@ class OtaFromTargetFilesTest(test_utils.ReleaseToolsTestCase):
|
|||||||
target_info = common.BuildInfo(self.TEST_INFO_DICT_USES_OEM_PROPS,
|
target_info = common.BuildInfo(self.TEST_INFO_DICT_USES_OEM_PROPS,
|
||||||
self.TEST_OEM_DICTS)
|
self.TEST_OEM_DICTS)
|
||||||
source_info_dict = copy.deepcopy(self.TEST_INFO_DICT_USES_OEM_PROPS)
|
source_info_dict = copy.deepcopy(self.TEST_INFO_DICT_USES_OEM_PROPS)
|
||||||
source_info_dict['build.prop']['ro.build.thumbprint'] = (
|
source_info_dict['build.prop'].build_props['ro.build.thumbprint'] = (
|
||||||
'source-build-thumbprint')
|
'source-build-thumbprint')
|
||||||
source_info = common.BuildInfo(source_info_dict, self.TEST_OEM_DICTS)
|
source_info = common.BuildInfo(source_info_dict, self.TEST_OEM_DICTS)
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user