Add unit test for parsing avb info
Bug: 328195652 Test: atest --host releasetools_test Test: sign_target_files_apks Change-Id: Ie38c3883907bc70c794606b20caf55a70dbcdf7c
This commit is contained in:
@@ -822,6 +822,52 @@ def ProcessTargetFiles(input_tf_zip: zipfile.ZipFile, output_tf_zip, misc_info,
|
|||||||
# Write back misc_info with the latest values.
|
# Write back misc_info with the latest values.
|
||||||
ReplaceMiscInfoTxt(input_tf_zip, output_tf_zip, misc_info)
|
ReplaceMiscInfoTxt(input_tf_zip, output_tf_zip, misc_info)
|
||||||
|
|
||||||
|
# Parse string output of `avbtool info_image`.
|
||||||
|
def ParseAvbInfo(info_raw):
|
||||||
|
# line_matcher is for parsing each output line of `avbtool info_image`.
|
||||||
|
# example string input: " Hash Algorithm: sha1"
|
||||||
|
# example matched input: (" ", "Hash Algorithm", "sha1")
|
||||||
|
line_matcher = re.compile(r'^(\s*)([^:]+):\s*(.*)$')
|
||||||
|
# prop_matcher is for parsing value part of 'Prop' in `avbtool info_image`.
|
||||||
|
# example string input: "example_prop_key -> 'example_prop_value'"
|
||||||
|
# example matched output: ("example_prop_key", "example_prop_value")
|
||||||
|
prop_matcher = re.compile(r"(.+)\s->\s'(.+)'")
|
||||||
|
info = {}
|
||||||
|
indent_stack = [[-1, info]]
|
||||||
|
for line_info_raw in info_raw.split('\n'):
|
||||||
|
# Parse the line
|
||||||
|
line_info_parsed = line_matcher.match(line_info_raw)
|
||||||
|
if not line_info_parsed:
|
||||||
|
continue
|
||||||
|
indent = len(line_info_parsed.group(1))
|
||||||
|
key = line_info_parsed.group(2).strip()
|
||||||
|
value = line_info_parsed.group(3).strip()
|
||||||
|
|
||||||
|
# Pop indentation stack
|
||||||
|
while indent <= indent_stack[-1][0]:
|
||||||
|
del indent_stack[-1]
|
||||||
|
|
||||||
|
# Insert information into 'info'.
|
||||||
|
cur_info = indent_stack[-1][1]
|
||||||
|
if value == "":
|
||||||
|
if key == "Descriptors":
|
||||||
|
empty_list = []
|
||||||
|
cur_info[key] = empty_list
|
||||||
|
indent_stack.append([indent, empty_list])
|
||||||
|
else:
|
||||||
|
empty_dict = {}
|
||||||
|
cur_info.append({key:empty_dict})
|
||||||
|
indent_stack.append([indent, empty_dict])
|
||||||
|
elif key == "Prop":
|
||||||
|
prop_parsed = prop_matcher.match(value)
|
||||||
|
if not prop_parsed:
|
||||||
|
raise ValueError(
|
||||||
|
"Failed to parse prop while getting avb information.")
|
||||||
|
cur_info.append({key:{prop_parsed.group(1):prop_parsed.group(2)}})
|
||||||
|
else:
|
||||||
|
cur_info[key] = value
|
||||||
|
return info
|
||||||
|
|
||||||
def ReplaceKeyInAvbHashtreeFooter(image, new_key, new_algorithm, misc_info):
|
def ReplaceKeyInAvbHashtreeFooter(image, new_key, new_algorithm, misc_info):
|
||||||
# Get avb information about the image by parsing avbtool info_image.
|
# Get avb information about the image by parsing avbtool info_image.
|
||||||
def GetAvbInfo(avbtool, image_name):
|
def GetAvbInfo(avbtool, image_name):
|
||||||
@@ -830,51 +876,7 @@ def ReplaceKeyInAvbHashtreeFooter(image, new_key, new_algorithm, misc_info):
|
|||||||
avbtool, 'info_image',
|
avbtool, 'info_image',
|
||||||
'--image', image_name
|
'--image', image_name
|
||||||
])
|
])
|
||||||
|
return ParseAvbInfo(info_raw)
|
||||||
# line_matcher is for parsing each output line of `avbtool info_image`.
|
|
||||||
# example string input: " Hash Algorithm: sha1"
|
|
||||||
# example matched input: (" ", "Hash Algorithm", "sha1")
|
|
||||||
line_matcher = re.compile(r'^(\s*)([^:]+):\s*(.*)$')
|
|
||||||
# prop_matcher is for parsing value part of 'Prop' in `avbtool info_image`.
|
|
||||||
# example string input: "example_prop_key -> 'example_prop_value'"
|
|
||||||
# example matched output: ("example_prop_key", "example_prop_value")
|
|
||||||
prop_matcher = re.compile(r"(.+)\s->\s'(.+)'")
|
|
||||||
info = {}
|
|
||||||
indent_stack = [[-1, info]]
|
|
||||||
for line_info_raw in info_raw.split('\n'):
|
|
||||||
# Parse the line
|
|
||||||
line_info_parsed = line_matcher.match(line_info_raw)
|
|
||||||
if not line_info_parsed:
|
|
||||||
continue
|
|
||||||
indent = len(line_info_parsed.group(1))
|
|
||||||
key = line_info_parsed.group(2).strip()
|
|
||||||
value = line_info_parsed.group(3).strip()
|
|
||||||
|
|
||||||
# Pop indentation stack
|
|
||||||
while indent <= indent_stack[-1][0]:
|
|
||||||
del indent_stack[-1]
|
|
||||||
|
|
||||||
# Insert information into 'info'.
|
|
||||||
cur_info = indent_stack[-1][1]
|
|
||||||
if value == "":
|
|
||||||
if key == "Descriptors":
|
|
||||||
empty_list = []
|
|
||||||
cur_info[key] = empty_list
|
|
||||||
indent_stack.append([indent, empty_list])
|
|
||||||
else:
|
|
||||||
empty_dict = {}
|
|
||||||
cur_info.append({key:empty_dict})
|
|
||||||
indent_stack.append([indent, empty_dict])
|
|
||||||
elif key == "Prop":
|
|
||||||
prop_parsed = prop_matcher.match(value)
|
|
||||||
if not prop_parsed:
|
|
||||||
raise ValueError(
|
|
||||||
"Failed to parse prop while getting avb information.")
|
|
||||||
cur_info.append({key:{prop_parsed.group(1):prop_parsed.group(2)}})
|
|
||||||
else:
|
|
||||||
cur_info[key] = value
|
|
||||||
|
|
||||||
return info
|
|
||||||
|
|
||||||
# Get hashtree descriptor from info
|
# Get hashtree descriptor from info
|
||||||
def GetAvbHashtreeDescriptor(avb_info):
|
def GetAvbHashtreeDescriptor(avb_info):
|
||||||
|
@@ -22,8 +22,9 @@ import zipfile
|
|||||||
import common
|
import common
|
||||||
import test_utils
|
import test_utils
|
||||||
from sign_target_files_apks import (
|
from sign_target_files_apks import (
|
||||||
CheckApkAndApexKeysAvailable, EditTags, GetApkFileInfo, ReadApexKeysInfo,
|
CheckApkAndApexKeysAvailable, EditTags, GetApkFileInfo, ParseAvbInfo,
|
||||||
ReplaceCerts, RewriteAvbProps, RewriteProps, WriteOtacerts)
|
ReadApexKeysInfo, ReplaceCerts, RewriteAvbProps, RewriteProps,
|
||||||
|
WriteOtacerts)
|
||||||
|
|
||||||
|
|
||||||
class SignTargetFilesApksTest(test_utils.ReleaseToolsTestCase):
|
class SignTargetFilesApksTest(test_utils.ReleaseToolsTestCase):
|
||||||
@@ -535,3 +536,86 @@ name="apex.apexd_test_different_app.apex" public_key="system/apex/apexd/apexd_te
|
|||||||
'system/apex/apexd/apexd_testdata/com.android.apex.test_package_2.pem',
|
'system/apex/apexd/apexd_testdata/com.android.apex.test_package_2.pem',
|
||||||
'build/make/target/product/security/testkey', None),
|
'build/make/target/product/security/testkey', None),
|
||||||
}, keys_info)
|
}, keys_info)
|
||||||
|
|
||||||
|
def test_ParseAvbInfo(self):
|
||||||
|
avb_info_string = """
|
||||||
|
Footer version: 1.0
|
||||||
|
Image size: 9999999 bytes
|
||||||
|
Original image size: 8888888 bytes
|
||||||
|
VBMeta offset: 7777777
|
||||||
|
VBMeta size: 1111 bytes
|
||||||
|
--
|
||||||
|
Minimum libavb version: 1.0
|
||||||
|
Header Block: 222 bytes
|
||||||
|
Authentication Block: 333 bytes
|
||||||
|
Auxiliary Block: 888 bytes
|
||||||
|
Public key (sha1): abababababababababababababababababababab
|
||||||
|
Algorithm: SHA256_RSA2048
|
||||||
|
Rollback Index: 0
|
||||||
|
Flags: 0
|
||||||
|
Rollback Index Location: 0
|
||||||
|
Release String: 'avbtool 1.3.0'
|
||||||
|
Descriptors:
|
||||||
|
Hashtree descriptor:
|
||||||
|
Version of dm-verity: 1
|
||||||
|
Image Size: 8888888 bytes
|
||||||
|
Tree Offset: 8888888
|
||||||
|
Tree Size: 44444 bytes
|
||||||
|
Data Block Size: 4444 bytes
|
||||||
|
Hash Block Size: 4444 bytes
|
||||||
|
FEC num roots: 0
|
||||||
|
FEC offset: 0
|
||||||
|
FEC size: 0 bytes
|
||||||
|
Hash Algorithm: sha1
|
||||||
|
Partition Name: partition-name
|
||||||
|
Salt: cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd
|
||||||
|
Root Digest: efefefefefefefefefefefefefefefefefef
|
||||||
|
Flags: 0
|
||||||
|
Prop: prop.key -> 'prop.value'
|
||||||
|
"""
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
{
|
||||||
|
'Footer version': '1.0',
|
||||||
|
'Image size': '9999999 bytes',
|
||||||
|
'Original image size': '8888888 bytes',
|
||||||
|
'VBMeta offset': '7777777',
|
||||||
|
'VBMeta size': '1111 bytes',
|
||||||
|
'Minimum libavb version': '1.0',
|
||||||
|
'Header Block': '222 bytes',
|
||||||
|
'Authentication Block': '333 bytes',
|
||||||
|
'Auxiliary Block': '888 bytes',
|
||||||
|
'Public key (sha1)': 'abababababababababababababababababababab',
|
||||||
|
'Algorithm': 'SHA256_RSA2048',
|
||||||
|
'Rollback Index': '0',
|
||||||
|
'Flags': '0',
|
||||||
|
'Rollback Index Location': '0',
|
||||||
|
'Release String': "'avbtool 1.3.0'",
|
||||||
|
'Descriptors': [
|
||||||
|
{
|
||||||
|
'Hashtree descriptor': {
|
||||||
|
'Version of dm-verity': '1',
|
||||||
|
'Image Size': '8888888 bytes',
|
||||||
|
'Tree Offset': '8888888',
|
||||||
|
'Tree Size': '44444 bytes',
|
||||||
|
'Data Block Size': '4444 bytes',
|
||||||
|
'Hash Block Size': '4444 bytes',
|
||||||
|
'FEC num roots': '0',
|
||||||
|
'FEC offset': '0',
|
||||||
|
'FEC size': '0 bytes',
|
||||||
|
'Hash Algorithm': 'sha1',
|
||||||
|
'Partition Name': 'partition-name',
|
||||||
|
'Salt': 'cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd',
|
||||||
|
'Root Digest': 'efefefefefefefefefefefefefefefefefef',
|
||||||
|
'Flags': '0',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'Prop': {
|
||||||
|
'prop.key': 'prop.value',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
ParseAvbInfo(avb_info_string),
|
||||||
|
)
|
Reference in New Issue
Block a user