# Copyright (C) 2020 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Test manifest split."""
import json import os import re import subprocess import tempfile import unittest import unittest.mock import xml.etree.ElementTree as ET
@unittest.mock.patch.object(subprocess, 'check_output', autospec=True) def test_get_kati_makefiles(self, mock_check_output): with tempfile.TemporaryDirectory() as temp_dir:
os.chdir(temp_dir)
makefiles = [ 'device/oem1/product1.mk', 'device/oem2/product2.mk', 'device/google/google_product.mk', 'overlays/oem_overlay/device/oem3/product3.mk', 'packages/apps/Camera/Android.mk',
] for makefile in makefiles:
os.makedirs(os.path.dirname(makefile))
os.mknod(makefile)
symlink_src = os.path.join(temp_dir, 'vendor/oem4/symlink_src.mk')
os.makedirs(os.path.dirname(symlink_src))
os.mknod(symlink_src)
symlink_dest = 'device/oem4/symlink_dest.mk'
os.makedirs(os.path.dirname(symlink_dest))
os.symlink(symlink_src, symlink_dest) # Only append the symlink destination, not where the symlink points to. # (The Kati stamp file does not resolve symlink sources.)
makefiles.append(symlink_dest)
# Mock the output of ckati --dump_stamp_tool:
mock_check_output.return_value = '\n'.join(makefiles).encode()
kati_makefiles = manifest_split.get_kati_makefiles( 'stamp-file', ['overlays/oem_overlay/'])
self.assertEqual(
kati_makefiles,
set([ # Regular product makefiles 'device/oem1/product1.mk', 'device/oem2/product2.mk', # Product makefile remapped from an overlay 'device/oem3/product3.mk', # Product makefile symlink and its source 'device/oem4/symlink_dest.mk', 'vendor/oem4/symlink_src.mk',
]))
@unittest.mock.patch.object(subprocess, 'check_output', autospec=True) def test_create_split_manifest(self, mock_check_output): with tempfile.NamedTemporaryFile('w+t') as repo_list_file, \
tempfile.NamedTemporaryFile('w+t') as manifest_file, \
tempfile.NamedTemporaryFile('w+t') as module_info_file, \
tempfile.NamedTemporaryFile('w+t') as config_file, \
tempfile.NamedTemporaryFile('w+t') as split_manifest_file, \
tempfile.TemporaryDirectory() as temp_dir:
# droid needs inputs from project1 and project3
ninja_inputs_droid = b"""
system/project1/file1
system/project1/file2
system/project3/file1 """
# target_b (indirectly included due to being in project3) needs inputs # from project3 and project4
ninja_inputs_target_b = b"""
system/project3/file2
system/project4/file1 """
# target_c (indirectly included due to being in project4) needs inputs # from only project4
ninja_inputs_target_c = b"""
system/project4/file2
system/project4/file3 """
# The config file says to manually include project6
config_file.write("""
<config>
<add_project name="platform/project6" />
</config>""")
config_file.flush()
debug_file = os.path.join(temp_dir, 'debug.json')
manifest_split.create_split_manifest(
['droid'], manifest_file.name, split_manifest_file.name,
[config_file.name], repo_list_file.name, 'build-target.ninja', 'ninja', module_info_file.name, 'unused kati stamp',
['unused overlay'], [], debug_file)
split_manifest = ET.parse(split_manifest_file.name)
split_manifest_projects = [
child.attrib['name'] for child in split_manifest.getroot().findall('project')
]
self.assertEqual(
split_manifest_projects,
[ # From droid 'platform/project1', # From droid 'platform/project3', # From target_b (module within project3, indirect dependency) 'platform/project4', # Manual inclusion from config file 'platform/project6', # From target_b (depends on target_f header library) 'platform/project7', # Inclusion from the Kati makefile stamp 'vendor/project1',
])
with open(debug_file) as debug_fp:
debug_data = json.load(debug_fp)
# Dependency for droid, but no other adjacent modules
self.assertTrue(debug_data['platform/project1']['direct_input'])
self.assertFalse(debug_data['platform/project1']['adjacent_input'])
self.assertFalse(debug_data['platform/project1']['deps_input'])
# Dependency for droid and an adjacent module
self.assertTrue(debug_data['platform/project3']['direct_input'])
self.assertTrue(debug_data['platform/project3']['adjacent_input'])
self.assertFalse(debug_data['platform/project3']['deps_input'])
# Dependency only for an adjacent module
self.assertFalse(debug_data['platform/project4']['direct_input'])
self.assertTrue(debug_data['platform/project4']['adjacent_input'])
self.assertFalse(debug_data['platform/project4']['deps_input'])
# Included via header library
self.assertFalse(debug_data['platform/project7']['direct_input'])
self.assertFalse(debug_data['platform/project7']['adjacent_input'])
self.assertTrue(debug_data['platform/project7']['deps_input'])
# Included due to the config file
self.assertEqual(
debug_data['platform/project6']['manual_add_config'],
config_file.name)
# Included due to the Kati makefile stamp
self.assertEqual(debug_data['vendor/project1']['kati_makefiles'][0],
product_makefile)
@unittest.mock.patch.object(manifest_split, 'get_ninja_inputs', autospec=True)
@unittest.mock.patch.object(manifest_split, 'get_kati_makefiles', autospec=True)
@unittest.mock.patch.object(manifest_split.ModuleInfo, '__init__', autospec=True) def test_create_split_manifest_skip_kati_module_info(self, mock_init,
mock_get_kati_makefiles,
mock_get_ninja_inputs): with tempfile.NamedTemporaryFile('w+t') as repo_list_file, \
tempfile.NamedTemporaryFile('w+t') as manifest_file, \
tempfile.NamedTemporaryFile('w+t') as module_info_file, \
tempfile.NamedTemporaryFile('w+t') as config_file, \
tempfile.NamedTemporaryFile('w+t') as split_manifest_file, \
tempfile.TemporaryDirectory() as temp_dir:
# The purpose of this test is to verify that create_split_manifests treats # installed prebuilts as projects, even though the installed prebuilts are # not in the manifest. This use case occurs when installed prebuilts # contribute modules to the build, but the installed prebuilts themselves # aren't sourced from the manifest.
with tempfile.NamedTemporaryFile('w+t') as repo_list_file, \
tempfile.NamedTemporaryFile('w+t') as manifest_file, \
tempfile.NamedTemporaryFile('w+t') as module_info_file, \
tempfile.NamedTemporaryFile('w+t') as split_manifest_file, \
tempfile.TemporaryDirectory() as temp_dir:
# Here's the module_info.json file. It contains modules whose paths are # "prebuilt/project3" and "prebult/project4", which are not found in the # manifest. Normally create_split_manifest doesn't tolerate a path that # doesn't correspond to a manifest project. However, this test verifies # that you can use these modules if you tell create_split_manifest about # the installed prebuilts via a parameter.
# This is a key part of the test. Passing these two "projects" as # prebuilts allows create_split_manifest to recognize them as # projects even though they are not in the manifest.
split_manifest_projects = [
child.attrib['name'] for child in split_manifest.getroot().findall('project')
]
# Note that the installed prebuilts do not appear in the final split # manfiest output because they were not in the manifest to begin with.
self.assertEqual(
split_manifest_projects,
[ # From droid 'platform/project1', # Inclusion from the Kati makefile stamp 'vendor/project1',
])
with open(debug_file) as debug_fp:
debug_data = json.load(debug_fp)
# Dependency for droid, but no other adjacent modules
self.assertTrue(debug_data['platform/project1']['direct_input'])
self.assertFalse(debug_data['platform/project1']['adjacent_input'])
self.assertFalse(debug_data['platform/project1']['deps_input'])
# Included due to the Kati makefile stamp
self.assertEqual(debug_data['vendor/project1']['kati_makefiles'][0],
product_makefile)
if __name__ == '__main__':
unittest.main()
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.2 Sekunden
(vorverarbeitet am 2026-06-27)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.