releasetools: Move BuildInfo into common.
There is no change to module functionalities. Testcases are moved around
accordingly.
Bug: 134525174
Test: TreeHugger
Test: lunch a target; atest --host releasetools_test releasetools_py3_test
Change-Id: I7bc8f49cc239e7c6655fe5e375508f01c1743b94
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index 37c03ab..c384c0c 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -284,6 +284,225 @@
pass
+class BuildInfo(object):
+ """A class that holds the information for a given build.
+
+ This class wraps up the property querying for a given source or target build.
+ It abstracts away the logic of handling OEM-specific properties, and caches
+ the commonly used properties such as fingerprint.
+
+ There are two types of info dicts: a) build-time info dict, which is generated
+ at build time (i.e. included in a target_files zip); b) OEM info dict that is
+ specified at package generation time (via command line argument
+ '--oem_settings'). If a build doesn't use OEM-specific properties (i.e. not
+ having "oem_fingerprint_properties" in build-time info dict), all the queries
+ would be answered based on build-time info dict only. Otherwise if using
+ OEM-specific properties, some of them will be calculated from two info dicts.
+
+ Users can query properties similarly as using a dict() (e.g. info['fstab']),
+ or to query build properties via GetBuildProp() or GetVendorBuildProp().
+
+ Attributes:
+ info_dict: The build-time info dict.
+ is_ab: Whether it's a build that uses A/B OTA.
+ oem_dicts: A list of OEM dicts.
+ oem_props: A list of OEM properties that should be read from OEM dicts; None
+ if the build doesn't use any OEM-specific property.
+ fingerprint: The fingerprint of the build, which would be calculated based
+ on OEM properties if applicable.
+ device: The device name, which could come from OEM dicts if applicable.
+ """
+
+ _RO_PRODUCT_RESOLVE_PROPS = ["ro.product.brand", "ro.product.device",
+ "ro.product.manufacturer", "ro.product.model",
+ "ro.product.name"]
+ _RO_PRODUCT_PROPS_DEFAULT_SOURCE_ORDER = ["product", "odm", "vendor",
+ "system_ext", "system"]
+
+ def __init__(self, info_dict, oem_dicts):
+ """Initializes a BuildInfo instance with the given dicts.
+
+ Note that it only wraps up the given dicts, without making copies.
+
+ Arguments:
+ info_dict: The build-time info dict.
+ oem_dicts: A list of OEM dicts (which is parsed from --oem_settings). Note
+ that it always uses the first dict to calculate the fingerprint or the
+ device name. The rest would be used for asserting OEM properties only
+ (e.g. one package can be installed on one of these devices).
+
+ Raises:
+ ValueError: On invalid inputs.
+ """
+ self.info_dict = info_dict
+ self.oem_dicts = oem_dicts
+
+ self._is_ab = info_dict.get("ab_update") == "true"
+ self._oem_props = info_dict.get("oem_fingerprint_properties")
+
+ if self._oem_props:
+ assert oem_dicts, "OEM source required for this build"
+
+ # These two should be computed only after setting self._oem_props.
+ self._device = self.GetOemProperty("ro.product.device")
+ self._fingerprint = self.CalculateFingerprint()
+
+ # Sanity check the build fingerprint.
+ if (' ' in self._fingerprint or
+ any(ord(ch) > 127 for ch in self._fingerprint)):
+ raise ValueError(
+ 'Invalid build fingerprint: "{}". See the requirement in Android CDD '
+ '3.2.2. Build Parameters.'.format(self._fingerprint))
+
+ @property
+ def is_ab(self):
+ return self._is_ab
+
+ @property
+ def device(self):
+ return self._device
+
+ @property
+ def fingerprint(self):
+ return self._fingerprint
+
+ @property
+ def vendor_fingerprint(self):
+ return self._fingerprint_of("vendor")
+
+ @property
+ def product_fingerprint(self):
+ return self._fingerprint_of("product")
+
+ @property
+ def odm_fingerprint(self):
+ return self._fingerprint_of("odm")
+
+ def _fingerprint_of(self, partition):
+ if partition + ".build.prop" not in self.info_dict:
+ return None
+ build_prop = self.info_dict[partition + ".build.prop"]
+ if "ro." + partition + ".build.fingerprint" in build_prop:
+ return build_prop["ro." + partition + ".build.fingerprint"]
+ if "ro." + partition + ".build.thumbprint" in build_prop:
+ return build_prop["ro." + partition + ".build.thumbprint"]
+ return None
+
+ @property
+ def oem_props(self):
+ return self._oem_props
+
+ def __getitem__(self, key):
+ return self.info_dict[key]
+
+ def __setitem__(self, key, value):
+ self.info_dict[key] = value
+
+ def get(self, key, default=None):
+ return self.info_dict.get(key, default)
+
+ def items(self):
+ return self.info_dict.items()
+
+ def GetBuildProp(self, prop):
+ """Returns the inquired build property."""
+ if prop in BuildInfo._RO_PRODUCT_RESOLVE_PROPS:
+ return self._ResolveRoProductBuildProp(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.info_dict.get("build.prop", {}).get(prop)
+ if prop_val:
+ return prop_val
+
+ 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:
+ source_order = BuildInfo._RO_PRODUCT_PROPS_DEFAULT_SOURCE_ORDER
+
+ # Check that all sources in ro.product.property_source_order are valid
+ if any([x not in BuildInfo._RO_PRODUCT_PROPS_DEFAULT_SOURCE_ORDER
+ for x in source_order]):
+ raise ExternalError(
+ "Invalid ro.product.property_source_order '{}'".format(source_order))
+
+ for source in source_order:
+ source_prop = prop.replace(
+ "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
+
+ raise ExternalError("couldn't resolve {}".format(prop))
+
+ def GetVendorBuildProp(self, prop):
+ """Returns the inquired vendor build property."""
+ try:
+ return self.info_dict.get("vendor.build.prop", {})[prop]
+ except KeyError:
+ raise ExternalError(
+ "couldn't find %s in vendor.build.prop" % (prop,))
+
+ def GetOemProperty(self, key):
+ if self.oem_props is not None and key in self.oem_props:
+ return self.oem_dicts[0][key]
+ return self.GetBuildProp(key)
+
+ def CalculateFingerprint(self):
+ if self.oem_props is None:
+ try:
+ return self.GetBuildProp("ro.build.fingerprint")
+ except ExternalError:
+ return "{}/{}/{}:{}/{}/{}:{}/{}".format(
+ self.GetBuildProp("ro.product.brand"),
+ self.GetBuildProp("ro.product.name"),
+ self.GetBuildProp("ro.product.device"),
+ self.GetBuildProp("ro.build.version.release"),
+ self.GetBuildProp("ro.build.id"),
+ self.GetBuildProp("ro.build.version.incremental"),
+ self.GetBuildProp("ro.build.type"),
+ self.GetBuildProp("ro.build.tags"))
+ return "%s/%s/%s:%s" % (
+ self.GetOemProperty("ro.product.brand"),
+ self.GetOemProperty("ro.product.name"),
+ self.GetOemProperty("ro.product.device"),
+ self.GetBuildProp("ro.build.thumbprint"))
+
+ def WriteMountOemScript(self, script):
+ assert self.oem_props is not None
+ recovery_mount_options = self.info_dict.get("recovery_mount_options")
+ script.Mount("/oem", recovery_mount_options)
+
+ def WriteDeviceAssertions(self, script, oem_no_mount):
+ # Read the property directly if not using OEM properties.
+ if not self.oem_props:
+ script.AssertDevice(self.device)
+ return
+
+ # Otherwise assert OEM properties.
+ if not self.oem_dicts:
+ raise ExternalError(
+ "No OEM file provided to answer expected assertions")
+
+ for prop in self.oem_props.split():
+ values = []
+ for oem_dict in self.oem_dicts:
+ if prop in oem_dict:
+ values.append(oem_dict[prop])
+ if not values:
+ raise ExternalError(
+ "The OEM file is missing the property %s" % (prop,))
+ script.AssertOemProperty(prop, values, oem_no_mount)
+
+
def LoadInfoDict(input_file, repacking=False):
"""Loads the key/value pairs from the given input target_files.
diff --git a/tools/releasetools/ota_from_target_files.py b/tools/releasetools/ota_from_target_files.py
index 3fc3c22..1e7bb3a 100755
--- a/tools/releasetools/ota_from_target_files.py
+++ b/tools/releasetools/ota_from_target_files.py
@@ -258,225 +258,6 @@
'system_ext', 'vbmeta', 'vbmeta_system', 'vbmeta_vendor', 'vendor']
-class BuildInfo(object):
- """A class that holds the information for a given build.
-
- This class wraps up the property querying for a given source or target build.
- It abstracts away the logic of handling OEM-specific properties, and caches
- the commonly used properties such as fingerprint.
-
- There are two types of info dicts: a) build-time info dict, which is generated
- at build time (i.e. included in a target_files zip); b) OEM info dict that is
- specified at package generation time (via command line argument
- '--oem_settings'). If a build doesn't use OEM-specific properties (i.e. not
- having "oem_fingerprint_properties" in build-time info dict), all the queries
- would be answered based on build-time info dict only. Otherwise if using
- OEM-specific properties, some of them will be calculated from two info dicts.
-
- Users can query properties similarly as using a dict() (e.g. info['fstab']),
- or to query build properties via GetBuildProp() or GetVendorBuildProp().
-
- Attributes:
- info_dict: The build-time info dict.
- is_ab: Whether it's a build that uses A/B OTA.
- oem_dicts: A list of OEM dicts.
- oem_props: A list of OEM properties that should be read from OEM dicts; None
- if the build doesn't use any OEM-specific property.
- fingerprint: The fingerprint of the build, which would be calculated based
- on OEM properties if applicable.
- device: The device name, which could come from OEM dicts if applicable.
- """
-
- _RO_PRODUCT_RESOLVE_PROPS = ["ro.product.brand", "ro.product.device",
- "ro.product.manufacturer", "ro.product.model",
- "ro.product.name"]
- _RO_PRODUCT_PROPS_DEFAULT_SOURCE_ORDER = ["product", "odm", "vendor",
- "system_ext", "system"]
-
- def __init__(self, info_dict, oem_dicts):
- """Initializes a BuildInfo instance with the given dicts.
-
- Note that it only wraps up the given dicts, without making copies.
-
- Arguments:
- info_dict: The build-time info dict.
- oem_dicts: A list of OEM dicts (which is parsed from --oem_settings). Note
- that it always uses the first dict to calculate the fingerprint or the
- device name. The rest would be used for asserting OEM properties only
- (e.g. one package can be installed on one of these devices).
-
- Raises:
- ValueError: On invalid inputs.
- """
- self.info_dict = info_dict
- self.oem_dicts = oem_dicts
-
- self._is_ab = info_dict.get("ab_update") == "true"
- self._oem_props = info_dict.get("oem_fingerprint_properties")
-
- if self._oem_props:
- assert oem_dicts, "OEM source required for this build"
-
- # These two should be computed only after setting self._oem_props.
- self._device = self.GetOemProperty("ro.product.device")
- self._fingerprint = self.CalculateFingerprint()
-
- # Sanity check the build fingerprint.
- if (' ' in self._fingerprint or
- any(ord(ch) > 127 for ch in self._fingerprint)):
- raise ValueError(
- 'Invalid build fingerprint: "{}". See the requirement in Android CDD '
- '3.2.2. Build Parameters.'.format(self._fingerprint))
-
- @property
- def is_ab(self):
- return self._is_ab
-
- @property
- def device(self):
- return self._device
-
- @property
- def fingerprint(self):
- return self._fingerprint
-
- @property
- def vendor_fingerprint(self):
- return self._fingerprint_of("vendor")
-
- @property
- def product_fingerprint(self):
- return self._fingerprint_of("product")
-
- @property
- def odm_fingerprint(self):
- return self._fingerprint_of("odm")
-
- def _fingerprint_of(self, partition):
- if partition + ".build.prop" not in self.info_dict:
- return None
- build_prop = self.info_dict[partition + ".build.prop"]
- if "ro." + partition + ".build.fingerprint" in build_prop:
- return build_prop["ro." + partition + ".build.fingerprint"]
- if "ro." + partition + ".build.thumbprint" in build_prop:
- return build_prop["ro." + partition + ".build.thumbprint"]
- return None
-
- @property
- def oem_props(self):
- return self._oem_props
-
- def __getitem__(self, key):
- return self.info_dict[key]
-
- def __setitem__(self, key, value):
- self.info_dict[key] = value
-
- def get(self, key, default=None):
- return self.info_dict.get(key, default)
-
- def items(self):
- return self.info_dict.items()
-
- def GetBuildProp(self, prop):
- """Returns the inquired build property."""
- if prop in BuildInfo._RO_PRODUCT_RESOLVE_PROPS:
- return self._ResolveRoProductBuildProp(prop)
-
- try:
- return self.info_dict.get("build.prop", {})[prop]
- except KeyError:
- raise common.ExternalError("couldn't find %s in build.prop" % (prop,))
-
- def _ResolveRoProductBuildProp(self, prop):
- """Resolves the inquired ro.product.* build property"""
- prop_val = self.info_dict.get("build.prop", {}).get(prop)
- if prop_val:
- return prop_val
-
- 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:
- source_order = BuildInfo._RO_PRODUCT_PROPS_DEFAULT_SOURCE_ORDER
-
- # Check that all sources in ro.product.property_source_order are valid
- if any([x not in BuildInfo._RO_PRODUCT_PROPS_DEFAULT_SOURCE_ORDER
- for x in source_order]):
- raise common.ExternalError(
- "Invalid ro.product.property_source_order '{}'".format(source_order))
-
- for source in source_order:
- source_prop = prop.replace(
- "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
-
- raise common.ExternalError("couldn't resolve {}".format(prop))
-
- def GetVendorBuildProp(self, prop):
- """Returns the inquired vendor build property."""
- try:
- return self.info_dict.get("vendor.build.prop", {})[prop]
- except KeyError:
- raise common.ExternalError(
- "couldn't find %s in vendor.build.prop" % (prop,))
-
- def GetOemProperty(self, key):
- if self.oem_props is not None and key in self.oem_props:
- return self.oem_dicts[0][key]
- return self.GetBuildProp(key)
-
- def CalculateFingerprint(self):
- if self.oem_props is None:
- try:
- return self.GetBuildProp("ro.build.fingerprint")
- except common.ExternalError:
- return "{}/{}/{}:{}/{}/{}:{}/{}".format(
- self.GetBuildProp("ro.product.brand"),
- self.GetBuildProp("ro.product.name"),
- self.GetBuildProp("ro.product.device"),
- self.GetBuildProp("ro.build.version.release"),
- self.GetBuildProp("ro.build.id"),
- self.GetBuildProp("ro.build.version.incremental"),
- self.GetBuildProp("ro.build.type"),
- self.GetBuildProp("ro.build.tags"))
- return "%s/%s/%s:%s" % (
- self.GetOemProperty("ro.product.brand"),
- self.GetOemProperty("ro.product.name"),
- self.GetOemProperty("ro.product.device"),
- self.GetBuildProp("ro.build.thumbprint"))
-
- def WriteMountOemScript(self, script):
- assert self.oem_props is not None
- recovery_mount_options = self.info_dict.get("recovery_mount_options")
- script.Mount("/oem", recovery_mount_options)
-
- def WriteDeviceAssertions(self, script, oem_no_mount):
- # Read the property directly if not using OEM properties.
- if not self.oem_props:
- script.AssertDevice(self.device)
- return
-
- # Otherwise assert OEM properties.
- if not self.oem_dicts:
- raise common.ExternalError(
- "No OEM file provided to answer expected assertions")
-
- for prop in self.oem_props.split():
- values = []
- for oem_dict in self.oem_dicts:
- if prop in oem_dict:
- values.append(oem_dict[prop])
- if not values:
- raise common.ExternalError(
- "The OEM file is missing the property %s" % (prop,))
- script.AssertOemProperty(prop, values, oem_no_mount)
-
-
class PayloadSigner(object):
"""A class that wraps the payload signing works.
@@ -904,7 +685,7 @@
def WriteFullOTAPackage(input_zip, output_file):
- target_info = BuildInfo(OPTIONS.info_dict, OPTIONS.oem_dicts)
+ target_info = common.BuildInfo(OPTIONS.info_dict, OPTIONS.oem_dicts)
# We don't know what version it will be installed on top of. We expect the API
# just won't change very often. Similarly for fstab, it might have changed in
@@ -1130,8 +911,8 @@
Returns:
A dict to be written into package metadata entry.
"""
- assert isinstance(target_info, BuildInfo)
- assert source_info is None or isinstance(source_info, BuildInfo)
+ assert isinstance(target_info, common.BuildInfo)
+ assert source_info is None or isinstance(source_info, common.BuildInfo)
metadata = {
'post-build' : target_info.fingerprint,
@@ -1544,8 +1325,8 @@
def WriteBlockIncrementalOTAPackage(target_zip, source_zip, output_file):
- target_info = BuildInfo(OPTIONS.target_info_dict, OPTIONS.oem_dicts)
- source_info = BuildInfo(OPTIONS.source_info_dict, OPTIONS.oem_dicts)
+ target_info = common.BuildInfo(OPTIONS.target_info_dict, OPTIONS.oem_dicts)
+ source_info = common.BuildInfo(OPTIONS.source_info_dict, OPTIONS.oem_dicts)
target_api_version = target_info["recovery_api_version"]
source_api_version = source_info["recovery_api_version"]
@@ -2024,10 +1805,10 @@
compression=zipfile.ZIP_DEFLATED)
if source_file is not None:
- target_info = BuildInfo(OPTIONS.target_info_dict, OPTIONS.oem_dicts)
- source_info = BuildInfo(OPTIONS.source_info_dict, OPTIONS.oem_dicts)
+ target_info = common.BuildInfo(OPTIONS.target_info_dict, OPTIONS.oem_dicts)
+ source_info = common.BuildInfo(OPTIONS.source_info_dict, OPTIONS.oem_dicts)
else:
- target_info = BuildInfo(OPTIONS.info_dict, OPTIONS.oem_dicts)
+ target_info = common.BuildInfo(OPTIONS.info_dict, OPTIONS.oem_dicts)
source_info = None
# Metadata to comply with Android OTA package format.
diff --git a/tools/releasetools/test_common.py b/tools/releasetools/test_common.py
index c1e9d7a..59b05e9 100644
--- a/tools/releasetools/test_common.py
+++ b/tools/releasetools/test_common.py
@@ -44,6 +44,210 @@
yield b'\0' * (step_size - block_size)
+class BuildInfoTest(test_utils.ReleaseToolsTestCase):
+
+ TEST_INFO_DICT = {
+ 'build.prop' : {
+ 'ro.product.device' : 'product-device',
+ 'ro.product.name' : 'product-name',
+ 'ro.build.fingerprint' : 'build-fingerprint',
+ 'ro.build.foo' : 'build-foo',
+ },
+ 'vendor.build.prop' : {
+ 'ro.vendor.build.fingerprint' : 'vendor-build-fingerprint',
+ },
+ 'property1' : 'value1',
+ 'property2' : 4096,
+ }
+
+ TEST_INFO_DICT_USES_OEM_PROPS = {
+ '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' : 'brand2',
+ 'ro.product.device' : 'device2',
+ },
+ {
+ 'ro.product.brand' : 'brand3',
+ 'ro.product.device' : 'device3',
+ },
+ ]
+
+ def test_init(self):
+ target_info = common.BuildInfo(self.TEST_INFO_DICT, None)
+ self.assertEqual('product-device', target_info.device)
+ self.assertEqual('build-fingerprint', target_info.fingerprint)
+ self.assertFalse(target_info.is_ab)
+ self.assertIsNone(target_info.oem_props)
+
+ def test_init_with_oem_props(self):
+ target_info = common.BuildInfo(self.TEST_INFO_DICT_USES_OEM_PROPS,
+ self.TEST_OEM_DICTS)
+ self.assertEqual('device1', target_info.device)
+ self.assertEqual('brand1/product-name/device1:build-thumbprint',
+ target_info.fingerprint)
+
+ # Swap the order in oem_dicts, which would lead to different BuildInfo.
+ oem_dicts = copy.copy(self.TEST_OEM_DICTS)
+ oem_dicts[0], oem_dicts[2] = oem_dicts[2], oem_dicts[0]
+ target_info = common.BuildInfo(self.TEST_INFO_DICT_USES_OEM_PROPS,
+ oem_dicts)
+ self.assertEqual('device3', target_info.device)
+ self.assertEqual('brand3/product-name/device3:build-thumbprint',
+ target_info.fingerprint)
+
+ # Missing oem_dict should be rejected.
+ self.assertRaises(AssertionError, common.BuildInfo,
+ self.TEST_INFO_DICT_USES_OEM_PROPS, None)
+
+ def test_init_badFingerprint(self):
+ info_dict = copy.deepcopy(self.TEST_INFO_DICT)
+ info_dict['build.prop']['ro.build.fingerprint'] = 'bad fingerprint'
+ self.assertRaises(ValueError, common.BuildInfo, info_dict, None)
+
+ 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']['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.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)
+ self.assertEqual('value1', target_info['property1'])
+ target_info['property1'] = 'value2'
+ self.assertEqual('value2', target_info['property1'])
+
+ 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)
+ self.assertEqual('value1', target_info.get('property1'))
+ 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')['ro.build.foo'])
+
+ def test_get_with_oem_props(self):
+ target_info = common.BuildInfo(self.TEST_INFO_DICT_USES_OEM_PROPS,
+ self.TEST_OEM_DICTS)
+ self.assertEqual('value1', target_info.get('property1'))
+ 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').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)
+ items = target_info.items()
+ self.assertIn(('property1', 'value1'), items)
+ self.assertIn(('property2', 4096), items)
+
+ def test_GetBuildProp(self):
+ target_info = common.BuildInfo(self.TEST_INFO_DICT, None)
+ self.assertEqual('build-foo', target_info.GetBuildProp('ro.build.foo'))
+ self.assertRaises(common.ExternalError, target_info.GetBuildProp,
+ 'ro.build.nonexistent')
+
+ def test_GetBuildProp_with_oem_props(self):
+ target_info = common.BuildInfo(self.TEST_INFO_DICT_USES_OEM_PROPS,
+ self.TEST_OEM_DICTS)
+ self.assertEqual('build-bar', target_info.GetBuildProp('ro.build.bar'))
+ self.assertRaises(common.ExternalError, target_info.GetBuildProp,
+ 'ro.build.nonexistent')
+
+ def test_GetVendorBuildProp(self):
+ target_info = common.BuildInfo(self.TEST_INFO_DICT, None)
+ self.assertEqual('vendor-build-fingerprint',
+ target_info.GetVendorBuildProp(
+ 'ro.vendor.build.fingerprint'))
+ self.assertRaises(common.ExternalError, target_info.GetVendorBuildProp,
+ 'ro.build.nonexistent')
+
+ def test_GetVendorBuildProp_with_oem_props(self):
+ target_info = common.BuildInfo(self.TEST_INFO_DICT_USES_OEM_PROPS,
+ self.TEST_OEM_DICTS)
+ self.assertEqual('vendor-build-fingerprint',
+ target_info.GetVendorBuildProp(
+ 'ro.vendor.build.fingerprint'))
+ self.assertRaises(common.ExternalError, target_info.GetVendorBuildProp,
+ 'ro.build.nonexistent')
+
+ def test_vendor_fingerprint(self):
+ target_info = common.BuildInfo(self.TEST_INFO_DICT, None)
+ self.assertEqual('vendor-build-fingerprint',
+ target_info.vendor_fingerprint)
+
+ def test_vendor_fingerprint_blacklisted(self):
+ target_info_dict = copy.deepcopy(self.TEST_INFO_DICT_USES_OEM_PROPS)
+ del target_info_dict['vendor.build.prop']['ro.vendor.build.fingerprint']
+ target_info = common.BuildInfo(target_info_dict, self.TEST_OEM_DICTS)
+ self.assertIsNone(target_info.vendor_fingerprint)
+
+ def test_vendor_fingerprint_without_vendor_build_prop(self):
+ target_info_dict = copy.deepcopy(self.TEST_INFO_DICT_USES_OEM_PROPS)
+ del target_info_dict['vendor.build.prop']
+ target_info = common.BuildInfo(target_info_dict, self.TEST_OEM_DICTS)
+ self.assertIsNone(target_info.vendor_fingerprint)
+
+ def test_WriteMountOemScript(self):
+ target_info = common.BuildInfo(self.TEST_INFO_DICT_USES_OEM_PROPS,
+ self.TEST_OEM_DICTS)
+ script_writer = test_utils.MockScriptWriter()
+ target_info.WriteMountOemScript(script_writer)
+ self.assertEqual([('Mount', '/oem', None)], script_writer.lines)
+
+ def test_WriteDeviceAssertions(self):
+ target_info = common.BuildInfo(self.TEST_INFO_DICT, None)
+ script_writer = test_utils.MockScriptWriter()
+ target_info.WriteDeviceAssertions(script_writer, False)
+ self.assertEqual([('AssertDevice', 'product-device')], script_writer.lines)
+
+ def test_WriteDeviceAssertions_with_oem_props(self):
+ target_info = common.BuildInfo(self.TEST_INFO_DICT_USES_OEM_PROPS,
+ self.TEST_OEM_DICTS)
+ script_writer = test_utils.MockScriptWriter()
+ target_info.WriteDeviceAssertions(script_writer, False)
+ self.assertEqual(
+ [
+ ('AssertOemProperty', 'ro.product.device',
+ ['device1', 'device2', 'device3'], False),
+ ('AssertOemProperty', 'ro.product.brand',
+ ['brand1', 'brand2', 'brand3'], False),
+ ],
+ script_writer.lines)
+
+
class CommonZipTest(test_utils.ReleaseToolsTestCase):
def _verify(self, zip_file, zip_file_name, arcname, expected_hash,
diff --git a/tools/releasetools/test_ota_from_target_files.py b/tools/releasetools/test_ota_from_target_files.py
index dd42822..c3021a1 100644
--- a/tools/releasetools/test_ota_from_target_files.py
+++ b/tools/releasetools/test_ota_from_target_files.py
@@ -22,7 +22,7 @@
import common
import test_utils
from ota_from_target_files import (
- _LoadOemDicts, AbOtaPropertyFiles, BuildInfo, FinalizeMetadata,
+ _LoadOemDicts, AbOtaPropertyFiles, FinalizeMetadata,
GetPackageMetadata, GetTargetFilesZipForSecondaryImages,
GetTargetFilesZipWithoutPostinstallConfig, NonAbOtaPropertyFiles,
Payload, PayloadSigner, POSTINSTALL_CONFIG, PropertyFiles,
@@ -74,262 +74,6 @@
return target_files
-class BuildInfoTest(test_utils.ReleaseToolsTestCase):
-
- TEST_INFO_DICT = {
- 'build.prop' : {
- 'ro.product.device' : 'product-device',
- 'ro.product.name' : 'product-name',
- 'ro.build.fingerprint' : 'build-fingerprint',
- 'ro.build.foo' : 'build-foo',
- },
- 'vendor.build.prop' : {
- 'ro.vendor.build.fingerprint' : 'vendor-build-fingerprint',
- },
- 'property1' : 'value1',
- 'property2' : 4096,
- }
-
- TEST_INFO_DICT_USES_OEM_PROPS = {
- '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' : 'brand2',
- 'ro.product.device' : 'device2',
- },
- {
- 'ro.product.brand' : 'brand3',
- 'ro.product.device' : 'device3',
- },
- ]
-
- def test_init(self):
- target_info = BuildInfo(self.TEST_INFO_DICT, None)
- self.assertEqual('product-device', target_info.device)
- self.assertEqual('build-fingerprint', target_info.fingerprint)
- self.assertFalse(target_info.is_ab)
- self.assertIsNone(target_info.oem_props)
-
- def test_init_with_oem_props(self):
- target_info = BuildInfo(self.TEST_INFO_DICT_USES_OEM_PROPS,
- self.TEST_OEM_DICTS)
- self.assertEqual('device1', target_info.device)
- self.assertEqual('brand1/product-name/device1:build-thumbprint',
- target_info.fingerprint)
-
- # Swap the order in oem_dicts, which would lead to different BuildInfo.
- oem_dicts = copy.copy(self.TEST_OEM_DICTS)
- oem_dicts[0], oem_dicts[2] = oem_dicts[2], oem_dicts[0]
- target_info = BuildInfo(self.TEST_INFO_DICT_USES_OEM_PROPS, oem_dicts)
- self.assertEqual('device3', target_info.device)
- self.assertEqual('brand3/product-name/device3:build-thumbprint',
- target_info.fingerprint)
-
- # Missing oem_dict should be rejected.
- self.assertRaises(AssertionError, BuildInfo,
- self.TEST_INFO_DICT_USES_OEM_PROPS, None)
-
- def test_init_badFingerprint(self):
- info_dict = copy.deepcopy(self.TEST_INFO_DICT)
- info_dict['build.prop']['ro.build.fingerprint'] = 'bad fingerprint'
- self.assertRaises(ValueError, BuildInfo, info_dict, None)
-
- info_dict['build.prop']['ro.build.fingerprint'] = 'bad\x80fingerprint'
- self.assertRaises(ValueError, BuildInfo, info_dict, None)
-
- def test___getitem__(self):
- target_info = 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']['ro.build.foo'])
-
- def test___getitem__with_oem_props(self):
- target_info = 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.assertRaises(KeyError,
- lambda: target_info['build.prop']['ro.build.foo'])
-
- def test___setitem__(self):
- target_info = BuildInfo(copy.deepcopy(self.TEST_INFO_DICT), None)
- self.assertEqual('value1', target_info['property1'])
- target_info['property1'] = 'value2'
- self.assertEqual('value2', target_info['property1'])
-
- 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 = BuildInfo(self.TEST_INFO_DICT, None)
- self.assertEqual('value1', target_info.get('property1'))
- 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')['ro.build.foo'])
-
- def test_get_with_oem_props(self):
- target_info = BuildInfo(self.TEST_INFO_DICT_USES_OEM_PROPS,
- self.TEST_OEM_DICTS)
- self.assertEqual('value1', target_info.get('property1'))
- 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').get('ro.build.foo'))
- self.assertRaises(KeyError,
- lambda: target_info.get('build.prop')['ro.build.foo'])
-
- def test_items(self):
- target_info = BuildInfo(self.TEST_INFO_DICT, None)
- items = target_info.items()
- self.assertIn(('property1', 'value1'), items)
- self.assertIn(('property2', 4096), items)
-
- def test_GetBuildProp(self):
- target_info = BuildInfo(self.TEST_INFO_DICT, None)
- self.assertEqual('build-foo', target_info.GetBuildProp('ro.build.foo'))
- self.assertRaises(common.ExternalError, target_info.GetBuildProp,
- 'ro.build.nonexistent')
-
- def test_GetBuildProp_with_oem_props(self):
- target_info = BuildInfo(self.TEST_INFO_DICT_USES_OEM_PROPS,
- self.TEST_OEM_DICTS)
- self.assertEqual('build-bar', target_info.GetBuildProp('ro.build.bar'))
- self.assertRaises(common.ExternalError, target_info.GetBuildProp,
- 'ro.build.nonexistent')
-
- def test_GetVendorBuildProp(self):
- target_info = BuildInfo(self.TEST_INFO_DICT, None)
- self.assertEqual('vendor-build-fingerprint',
- target_info.GetVendorBuildProp(
- 'ro.vendor.build.fingerprint'))
- self.assertRaises(common.ExternalError, target_info.GetVendorBuildProp,
- 'ro.build.nonexistent')
-
- def test_GetVendorBuildProp_with_oem_props(self):
- target_info = BuildInfo(self.TEST_INFO_DICT_USES_OEM_PROPS,
- self.TEST_OEM_DICTS)
- self.assertEqual('vendor-build-fingerprint',
- target_info.GetVendorBuildProp(
- 'ro.vendor.build.fingerprint'))
- self.assertRaises(common.ExternalError, target_info.GetVendorBuildProp,
- 'ro.build.nonexistent')
-
- def test_vendor_fingerprint(self):
- target_info = BuildInfo(self.TEST_INFO_DICT, None)
- self.assertEqual('vendor-build-fingerprint',
- target_info.vendor_fingerprint)
-
- def test_vendor_fingerprint_blacklisted(self):
- target_info_dict = copy.deepcopy(self.TEST_INFO_DICT_USES_OEM_PROPS)
- del target_info_dict['vendor.build.prop']['ro.vendor.build.fingerprint']
- target_info = BuildInfo(target_info_dict, self.TEST_OEM_DICTS)
- self.assertIsNone(target_info.vendor_fingerprint)
-
- def test_vendor_fingerprint_without_vendor_build_prop(self):
- target_info_dict = copy.deepcopy(self.TEST_INFO_DICT_USES_OEM_PROPS)
- del target_info_dict['vendor.build.prop']
- target_info = BuildInfo(target_info_dict, self.TEST_OEM_DICTS)
- self.assertIsNone(target_info.vendor_fingerprint)
-
- def test_WriteMountOemScript(self):
- target_info = BuildInfo(self.TEST_INFO_DICT_USES_OEM_PROPS,
- self.TEST_OEM_DICTS)
- script_writer = test_utils.MockScriptWriter()
- target_info.WriteMountOemScript(script_writer)
- self.assertEqual([('Mount', '/oem', None)], script_writer.lines)
-
- def test_WriteDeviceAssertions(self):
- target_info = BuildInfo(self.TEST_INFO_DICT, None)
- script_writer = test_utils.MockScriptWriter()
- target_info.WriteDeviceAssertions(script_writer, False)
- self.assertEqual([('AssertDevice', 'product-device')], script_writer.lines)
-
- def test_WriteDeviceAssertions_with_oem_props(self):
- target_info = BuildInfo(self.TEST_INFO_DICT_USES_OEM_PROPS,
- self.TEST_OEM_DICTS)
- script_writer = test_utils.MockScriptWriter()
- target_info.WriteDeviceAssertions(script_writer, False)
- self.assertEqual(
- [
- ('AssertOemProperty', 'ro.product.device',
- ['device1', 'device2', 'device3'], False),
- ('AssertOemProperty', 'ro.product.brand',
- ['brand1', 'brand2', 'brand3'], False),
- ],
- script_writer.lines)
-
- def test_WriteFingerprintAssertion_without_oem_props(self):
- target_info = BuildInfo(self.TEST_INFO_DICT, None)
- source_info_dict = copy.deepcopy(self.TEST_INFO_DICT)
- source_info_dict['build.prop']['ro.build.fingerprint'] = (
- 'source-build-fingerprint')
- source_info = BuildInfo(source_info_dict, None)
-
- script_writer = test_utils.MockScriptWriter()
- WriteFingerprintAssertion(script_writer, target_info, source_info)
- self.assertEqual(
- [('AssertSomeFingerprint', 'source-build-fingerprint',
- 'build-fingerprint')],
- script_writer.lines)
-
- def test_WriteFingerprintAssertion_with_source_oem_props(self):
- target_info = BuildInfo(self.TEST_INFO_DICT, None)
- source_info = BuildInfo(self.TEST_INFO_DICT_USES_OEM_PROPS,
- self.TEST_OEM_DICTS)
-
- script_writer = test_utils.MockScriptWriter()
- WriteFingerprintAssertion(script_writer, target_info, source_info)
- self.assertEqual(
- [('AssertFingerprintOrThumbprint', 'build-fingerprint',
- 'build-thumbprint')],
- script_writer.lines)
-
- def test_WriteFingerprintAssertion_with_target_oem_props(self):
- target_info = BuildInfo(self.TEST_INFO_DICT_USES_OEM_PROPS,
- self.TEST_OEM_DICTS)
- source_info = BuildInfo(self.TEST_INFO_DICT, None)
-
- script_writer = test_utils.MockScriptWriter()
- WriteFingerprintAssertion(script_writer, target_info, source_info)
- self.assertEqual(
- [('AssertFingerprintOrThumbprint', 'build-fingerprint',
- 'build-thumbprint')],
- script_writer.lines)
-
- def test_WriteFingerprintAssertion_with_both_oem_props(self):
- target_info = 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']['ro.build.thumbprint'] = (
- 'source-build-thumbprint')
- source_info = BuildInfo(source_info_dict, self.TEST_OEM_DICTS)
-
- script_writer = test_utils.MockScriptWriter()
- WriteFingerprintAssertion(script_writer, target_info, source_info)
- self.assertEqual(
- [('AssertSomeThumbprint', 'build-thumbprint',
- 'source-build-thumbprint')],
- script_writer.lines)
-
-
class LoadOemDictsTest(test_utils.ReleaseToolsTestCase):
def test_NoneDict(self):
@@ -387,6 +131,35 @@
},
}
+ TEST_INFO_DICT_USES_OEM_PROPS = {
+ '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' : 'brand2',
+ 'ro.product.device' : 'device2',
+ },
+ {
+ 'ro.product.brand' : 'brand3',
+ 'ro.product.device' : 'device3',
+ },
+ ]
+
def setUp(self):
self.testdata_dir = test_utils.get_testdata_dir()
self.assertTrue(os.path.exists(self.testdata_dir))
@@ -408,7 +181,7 @@
def test_GetPackageMetadata_abOta_full(self):
target_info_dict = copy.deepcopy(self.TEST_TARGET_INFO_DICT)
target_info_dict['ab_update'] = 'true'
- target_info = BuildInfo(target_info_dict, None)
+ target_info = common.BuildInfo(target_info_dict, None)
metadata = GetPackageMetadata(target_info)
self.assertDictEqual(
{
@@ -426,8 +199,8 @@
def test_GetPackageMetadata_abOta_incremental(self):
target_info_dict = copy.deepcopy(self.TEST_TARGET_INFO_DICT)
target_info_dict['ab_update'] = 'true'
- target_info = BuildInfo(target_info_dict, None)
- source_info = BuildInfo(self.TEST_SOURCE_INFO_DICT, None)
+ target_info = common.BuildInfo(target_info_dict, None)
+ source_info = common.BuildInfo(self.TEST_SOURCE_INFO_DICT, None)
common.OPTIONS.incremental_source = ''
metadata = GetPackageMetadata(target_info, source_info)
self.assertDictEqual(
@@ -446,7 +219,7 @@
metadata)
def test_GetPackageMetadata_nonAbOta_full(self):
- target_info = BuildInfo(self.TEST_TARGET_INFO_DICT, None)
+ target_info = common.BuildInfo(self.TEST_TARGET_INFO_DICT, None)
metadata = GetPackageMetadata(target_info)
self.assertDictEqual(
{
@@ -461,8 +234,8 @@
metadata)
def test_GetPackageMetadata_nonAbOta_incremental(self):
- target_info = BuildInfo(self.TEST_TARGET_INFO_DICT, None)
- source_info = BuildInfo(self.TEST_SOURCE_INFO_DICT, None)
+ target_info = common.BuildInfo(self.TEST_TARGET_INFO_DICT, None)
+ source_info = common.BuildInfo(self.TEST_SOURCE_INFO_DICT, None)
common.OPTIONS.incremental_source = ''
metadata = GetPackageMetadata(target_info, source_info)
self.assertDictEqual(
@@ -480,7 +253,7 @@
metadata)
def test_GetPackageMetadata_wipe(self):
- target_info = BuildInfo(self.TEST_TARGET_INFO_DICT, None)
+ target_info = common.BuildInfo(self.TEST_TARGET_INFO_DICT, None)
common.OPTIONS.wipe_user_data = True
metadata = GetPackageMetadata(target_info)
self.assertDictEqual(
@@ -497,7 +270,7 @@
metadata)
def test_GetPackageMetadata_retrofitDynamicPartitions(self):
- target_info = BuildInfo(self.TEST_TARGET_INFO_DICT, None)
+ target_info = common.BuildInfo(self.TEST_TARGET_INFO_DICT, None)
common.OPTIONS.retrofit_dynamic_partitions = True
metadata = GetPackageMetadata(target_info)
self.assertDictEqual(
@@ -526,8 +299,8 @@
self._test_GetPackageMetadata_swapBuildTimestamps(
target_info_dict, source_info_dict)
- target_info = BuildInfo(target_info_dict, None)
- source_info = BuildInfo(source_info_dict, None)
+ target_info = common.BuildInfo(target_info_dict, None)
+ source_info = common.BuildInfo(source_info_dict, None)
common.OPTIONS.incremental_source = ''
self.assertRaises(RuntimeError, GetPackageMetadata, target_info,
source_info)
@@ -538,8 +311,8 @@
self._test_GetPackageMetadata_swapBuildTimestamps(
target_info_dict, source_info_dict)
- target_info = BuildInfo(target_info_dict, None)
- source_info = BuildInfo(source_info_dict, None)
+ target_info = common.BuildInfo(target_info_dict, None)
+ source_info = common.BuildInfo(source_info_dict, None)
common.OPTIONS.incremental_source = ''
common.OPTIONS.downgrade = True
common.OPTIONS.wipe_user_data = True
@@ -752,6 +525,59 @@
FinalizeMetadata(metadata, zip_file, output_file, needed_property_files)
self.assertIn('ota-test-property-files', metadata)
+ 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']['ro.build.fingerprint'] = (
+ 'source-build-fingerprint')
+ source_info = common.BuildInfo(source_info_dict, None)
+
+ script_writer = test_utils.MockScriptWriter()
+ WriteFingerprintAssertion(script_writer, target_info, source_info)
+ self.assertEqual(
+ [('AssertSomeFingerprint', 'source-build-fingerprint',
+ 'build-fingerprint-target')],
+ script_writer.lines)
+
+ def test_WriteFingerprintAssertion_with_source_oem_props(self):
+ target_info = common.BuildInfo(self.TEST_TARGET_INFO_DICT, None)
+ source_info = common.BuildInfo(self.TEST_INFO_DICT_USES_OEM_PROPS,
+ self.TEST_OEM_DICTS)
+
+ script_writer = test_utils.MockScriptWriter()
+ WriteFingerprintAssertion(script_writer, target_info, source_info)
+ self.assertEqual(
+ [('AssertFingerprintOrThumbprint', 'build-fingerprint-target',
+ 'build-thumbprint')],
+ script_writer.lines)
+
+ def test_WriteFingerprintAssertion_with_target_oem_props(self):
+ target_info = common.BuildInfo(self.TEST_INFO_DICT_USES_OEM_PROPS,
+ self.TEST_OEM_DICTS)
+ source_info = common.BuildInfo(self.TEST_TARGET_INFO_DICT, None)
+
+ script_writer = test_utils.MockScriptWriter()
+ WriteFingerprintAssertion(script_writer, target_info, source_info)
+ self.assertEqual(
+ [('AssertFingerprintOrThumbprint', 'build-fingerprint-target',
+ 'build-thumbprint')],
+ script_writer.lines)
+
+ def test_WriteFingerprintAssertion_with_both_oem_props(self):
+ 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']['ro.build.thumbprint'] = (
+ 'source-build-thumbprint')
+ source_info = common.BuildInfo(source_info_dict, self.TEST_OEM_DICTS)
+
+ script_writer = test_utils.MockScriptWriter()
+ WriteFingerprintAssertion(script_writer, target_info, source_info)
+ self.assertEqual(
+ [('AssertSomeThumbprint', 'build-thumbprint',
+ 'source-build-thumbprint')],
+ script_writer.lines)
+
class TestPropertyFiles(PropertyFiles):
"""A class that extends PropertyFiles for testing purpose."""