diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2024-05-16 01:00:33 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2024-05-16 01:00:33 +0000 |
commit | ea61c8d031e88fed0481d2bc4264b28401d4511e (patch) | |
tree | de9927213d07f1c252483990d034da2a7571564f | |
parent | 1ed2772ce3f127fca248643918eac16e4e5ba9f2 (diff) | |
parent | 741f0e7115fbababd21b14c3e3d7c3699711a955 (diff) | |
download | soong-sdk-release.tar.gz |
Snap for 11847757 from 741f0e7115fbababd21b14c3e3d7c3699711a955 to sdk-releasesdk-release
Change-Id: I886775f3eb21dd2849f899d3b09c036ab3a17cd0
-rw-r--r-- | android/makevars.go | 1 | ||||
-rw-r--r-- | android/module_context.go | 3 | ||||
-rw-r--r-- | android/packaging.go | 23 | ||||
-rw-r--r-- | apex/apex.go | 3 | ||||
-rw-r--r-- | apex/apex_test.go | 39 | ||||
-rwxr-xr-x | bin/aninja | 25 | ||||
-rwxr-xr-x | bin/overrideflags | 100 | ||||
-rw-r--r-- | cc/cmake_ext_add_aidl_library.txt | 43 | ||||
-rw-r--r-- | cc/cmake_module_aidl.txt | 7 | ||||
-rw-r--r-- | cc/cmake_module_cc.txt | 2 | ||||
-rw-r--r-- | cc/cmake_snapshot.go | 28 | ||||
-rw-r--r-- | cc/compiler.go | 3 | ||||
-rw-r--r-- | cmd/release_config/release_config/main.go | 2 | ||||
-rw-r--r-- | cmd/release_config/release_config_lib/release_config.go | 3 | ||||
-rw-r--r-- | cmd/release_config/release_config_lib/release_configs.go | 4 | ||||
-rw-r--r-- | filesystem/filesystem_test.go | 67 |
16 files changed, 330 insertions, 23 deletions
diff --git a/android/makevars.go b/android/makevars.go index f57ac4500..f92f4581e 100644 --- a/android/makevars.go +++ b/android/makevars.go @@ -513,6 +513,7 @@ EXTRA_INSTALL_ZIPS := fmt.Fprintln(buf) } fmt.Fprintf(buf, ".KATI_READONLY := EXTRA_INSTALL_ZIPS\n") + fmt.Fprintf(buf, "$(KATI_visibility_prefix EXTRA_INSTALL_ZIPS,build/make/core/Makefile)\n") for _, symlink := range symlinks { fmt.Fprintf(buf, "%s:", symlink.to.String()) diff --git a/android/module_context.go b/android/module_context.go index 3c1e30a6c..18adb3002 100644 --- a/android/module_context.go +++ b/android/module_context.go @@ -497,6 +497,7 @@ func (m *moduleContext) packageFile(fullInstallPath InstallPath, srcPath Path, e partition: fullInstallPath.partition, skipInstall: m.skipInstall(), aconfigPaths: m.getAconfigPaths(), + archType: m.target.Arch.ArchType, } m.packagingSpecs = append(m.packagingSpecs, spec) return spec @@ -622,6 +623,7 @@ func (m *moduleContext) InstallSymlink(installPath InstallPath, name string, src partition: fullInstallPath.partition, skipInstall: m.skipInstall(), aconfigPaths: m.getAconfigPaths(), + archType: m.target.Arch.ArchType, }) return fullInstallPath @@ -665,6 +667,7 @@ func (m *moduleContext) InstallAbsoluteSymlink(installPath InstallPath, name str partition: fullInstallPath.partition, skipInstall: m.skipInstall(), aconfigPaths: m.getAconfigPaths(), + archType: m.target.Arch.ArchType, }) return fullInstallPath diff --git a/android/packaging.go b/android/packaging.go index a7260a641..383f828bd 100644 --- a/android/packaging.go +++ b/android/packaging.go @@ -51,6 +51,9 @@ type PackagingSpec struct { // Paths of aconfig files for the built artifact aconfigPaths *Paths + + // ArchType of the module which produced this packaging spec + archType ArchType } func (p *PackagingSpec) Equals(other *PackagingSpec) bool { @@ -260,11 +263,31 @@ func (p *PackagingBase) AddDeps(ctx BottomUpMutatorContext, depTag blueprint.Dep func (p *PackagingBase) GatherPackagingSpecsWithFilter(ctx ModuleContext, filter func(PackagingSpec) bool) map[string]PackagingSpec { m := make(map[string]PackagingSpec) + + var arches []ArchType + for _, target := range p.getSupportedTargets(ctx) { + arches = append(arches, target.Arch.ArchType) + } + + // filter out packaging specs for unsupported architecture + filterArch := func(ps PackagingSpec) bool { + for _, arch := range arches { + if arch == ps.archType { + return true + } + } + return false + } + ctx.VisitDirectDeps(func(child Module) { if pi, ok := ctx.OtherModuleDependencyTag(child).(PackagingItem); !ok || !pi.IsPackagingItem() { return } for _, ps := range child.TransitivePackagingSpecs() { + if !filterArch(ps) { + continue + } + if filter != nil { if !filter(ps) { continue diff --git a/apex/apex.go b/apex/apex.go index 9a80ec633..802991009 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -1636,7 +1636,8 @@ func apexFileForShBinary(ctx android.BaseModuleContext, sh *sh.ShBinary) apexFil func apexFileForPrebuiltEtc(ctx android.BaseModuleContext, prebuilt prebuilt_etc.PrebuiltEtcModule, outputFile android.Path) apexFile { dirInApex := filepath.Join(prebuilt.BaseDir(), prebuilt.SubDir()) - return newApexFile(ctx, outputFile, outputFile.Base(), dirInApex, etc, prebuilt) + makeModuleName := strings.ReplaceAll(filepath.Join(dirInApex, outputFile.Base()), "/", "_") + return newApexFile(ctx, outputFile, makeModuleName, dirInApex, etc, prebuilt) } func apexFileForCompatConfig(ctx android.BaseModuleContext, config java.PlatformCompatConfigIntf, depName string) apexFile { diff --git a/apex/apex_test.go b/apex/apex_test.go index 9a5c2b49b..74b2eec5b 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -11531,3 +11531,42 @@ func TestAconfifDeclarationsValidation(t *testing.T) { "depend on java_aconfig_library not passed as an input", aconfigFlagArgs, fmt.Sprintf("%s/%s/intermediate.pb", outDir, "quux")) } + +func TestMultiplePrebuiltsWithSameBase(t *testing.T) { + ctx := testApex(t, ` + apex { + name: "myapex", + key: "myapex.key", + prebuilts: ["myetc", "myetc2"], + min_sdk_version: "29", + } + apex_key { + name: "myapex.key", + public_key: "testkey.avbpubkey", + private_key: "testkey.pem", + } + + prebuilt_etc { + name: "myetc", + src: "myprebuilt", + filename: "myfilename", + } + prebuilt_etc { + name: "myetc2", + sub_dir: "mysubdir", + src: "myprebuilt", + filename: "myfilename", + } + `, withFiles(android.MockFS{ + "packages/modules/common/build/allowed_deps.txt": nil, + })) + + ab := ctx.ModuleForTests("myapex", "android_common_myapex").Module().(*apexBundle) + data := android.AndroidMkDataForTest(t, ctx, ab) + var builder strings.Builder + data.Custom(&builder, ab.BaseModuleName(), "TARGET_", "", data) + androidMk := builder.String() + + android.AssertStringDoesContain(t, "not found", androidMk, "LOCAL_MODULE := etc_myfilename.myapex") + android.AssertStringDoesContain(t, "not found", androidMk, "LOCAL_MODULE := etc_mysubdir_myfilename.myapex") +} diff --git a/bin/aninja b/bin/aninja new file mode 100755 index 000000000..cceb79489 --- /dev/null +++ b/bin/aninja @@ -0,0 +1,25 @@ +#!/bin/bash -e + +# Copyright (C) 2022 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. + +# Common script utilities +source $(cd $(dirname $BASH_SOURCE) &> /dev/null && pwd)/../../make/shell_utils.sh + +require_top +require_lunch + +cd $(gettop) +prebuilts/build-tools/linux-x86/bin/ninja -f out/combined-${TARGET_PRODUCT}.ninja "$@" + diff --git a/bin/overrideflags b/bin/overrideflags new file mode 100755 index 000000000..e16537b69 --- /dev/null +++ b/bin/overrideflags @@ -0,0 +1,100 @@ +#!/bin/bash -e +# Copyright (C) 2023 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. + + +source $(cd $(dirname $BASH_SOURCE) &> /dev/null && pwd)/../../make/shell_utils.sh + +require_top + +function print_help() { + echo -e "overrideflags is used to set default value for local build." + echo -e "\nOptions:" + echo -e "\t--release-config \tPath to release configuration directory. Required" + echo -e "\t--no-edit \tIf present, skip editing flag value file." + echo -e "\t-h/--help \tShow this help." +} + +function main() { + while (($# > 0)); do + case $1 in + --release-config) + if [[ $# -le 1 ]]; then + echo "--release-config requires a path" + return 1 + fi + local release_config_dir="$2" + shift 2 + ;; + --no-edit) + local no_edit="true" + shift 1 + ;; + -h|--help) + print_help + return + ;; + *) + echo "$1 is unrecognized" + print_help + return 1 + ;; + esac + done + + + + case $(uname -s) in + Darwin) + local host_arch=darwin-x86 + ;; + Linux) + local host_arch=linux-x86 + ;; + *) + >&2 echo Unknown host $(uname -s) + return + ;; + esac + + if [[ -z "${release_config_dir}" ]]; then + echo "Please provide release configuration path by --release-config" + exit 1 + elif [ ! -d "${release_config_dir}" ]; then + echo "${release_config_dir} is an invalid directory" + exit 1 + fi + local T="$(gettop)" + local aconfig_dir="${T}"/build/make/tools/aconfig/ + local overrideflag_py="${aconfig_dir}"/overrideflags/overrideflags.py + local overridefile="${release_config_dir}/aconfig/override_values.textproto" + + # Edit override file + if [[ -z "${no_edit}" ]]; then + editor="${EDITOR:-$(which vim)}" + + eval "${editor} ${overridefile}" + if [ $? -ne 0 ]; then + echo "Fail to set override values" + return 1 + fi + fi + + ${T}/prebuilts/build-tools/${host_arch}/bin/py3-cmd -u "${overrideflag_py}" \ + --overrides "${overridefile}" \ + --out "${release_config_dir}/aconfig" +} + + +main "$@" diff --git a/cc/cmake_ext_add_aidl_library.txt b/cc/cmake_ext_add_aidl_library.txt index dcf805a78..af5bdf6c0 100644 --- a/cc/cmake_ext_add_aidl_library.txt +++ b/cc/cmake_ext_add_aidl_library.txt @@ -1,35 +1,51 @@ -function(add_aidl_library NAME LANG SOURCES AIDLFLAGS) +function(add_aidl_library NAME LANG AIDLROOT SOURCES AIDLFLAGS) if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.20") cmake_policy(SET CMP0116 NEW) endif() + # Strip trailing slash + get_filename_component(AIDLROOT_TRAILING "${AIDLROOT}" NAME) + if ("${AIDLROOT_TRAILING}" STREQUAL "") + get_filename_component(AIDLROOT "${AIDLROOT}foo" DIRECTORY) + endif() + set(GEN_DIR "${CMAKE_CURRENT_BINARY_DIR}/.intermediates/${NAME}-source") set(GEN_SOURCES) - foreach(SOURCE ${SOURCES}) - get_filename_component(SOURCE_WE ${SOURCE} NAME_WE) - get_filename_component(SOURCE_ABSOLUTE ${SOURCE} ABSOLUTE) - get_filename_component(SOURCE_DIR ${SOURCE_ABSOLUTE} DIRECTORY) - set(GEN_SOURCE "${GEN_DIR}/${SOURCE_WE}.cpp") + foreach (SOURCE ${SOURCES}) + set(SOURCE_FULL ${AIDLROOT}/${SOURCE}) + get_filename_component(SOURCE_WLE ${SOURCE} NAME_WLE) + get_filename_component(SOURCE_SUBDIR ${SOURCE} DIRECTORY) + set(GEN_SOURCE "${GEN_DIR}/${SOURCE_SUBDIR}/${SOURCE_WLE}.cpp") + + file(READ "${SOURCE}" SOURCE_CONTENTS) + string(FIND "${SOURCE_CONTENTS}" "@VintfStability" VINTF_MATCH) + set(STABILITY_FLAG) + if (${VINTF_MATCH} GREATER_EQUAL 0) + set(STABILITY_FLAG --stability vintf) + endif() + set(DEPFILE_ARG) if (NOT ${CMAKE_GENERATOR} MATCHES "Unix Makefiles") set(DEPFILE_ARG DEPFILE "${GEN_SOURCE}.d") endif() + add_custom_command( OUTPUT "${GEN_SOURCE}" - MAIN_DEPENDENCY "${SOURCE_ABSOLUTE}" + MAIN_DEPENDENCY "${SOURCE_FULL}" ${DEPFILE_ARG} COMMAND "${AIDL_BIN}" ARGS --lang=${LANG} - --include="${SOURCE_DIR}" + --include="${AIDLROOT}" --dep="${GEN_SOURCE}.d" --out="${GEN_DIR}" --header_out="${GEN_DIR}/include" --ninja --structured --min_sdk_version=current + ${STABILITY_FLAG} ${AIDLFLAGS} - "${SOURCE_ABSOLUTE}" + "${SOURCE_FULL}" ) list(APPEND GEN_SOURCES "${GEN_SOURCE}") endforeach() @@ -39,9 +55,14 @@ function(add_aidl_library NAME LANG SOURCES AIDLFLAGS) target_include_directories(${NAME} PUBLIC "${GEN_DIR}/include" - "${ANDROID_BUILD_TOP}/frameworks/native/libs/binder/ndk/include_${LANG}" ) + + if (${LANG} MATCHES "ndk") + set(BINDER_LIB_NAME "libbinder_ndk_sdk") + else() + set(BINDER_LIB_NAME "libbinder_sdk") + endif() target_link_libraries(${NAME} - libbinder_sdk + ${BINDER_LIB_NAME} ) endfunction() diff --git a/cc/cmake_module_aidl.txt b/cc/cmake_module_aidl.txt index 4509a88eb..84755a32a 100644 --- a/cc/cmake_module_aidl.txt +++ b/cc/cmake_module_aidl.txt @@ -1,8 +1,11 @@ # <<.M.Name>> -<<setList .M.Name "_SRCS" "${ANDROID_BUILD_TOP}/" (getCompilerProperties .M).AidlInterface.Sources>> +<<setList .M.Name "_SRCS" "" (getAidlSources .M)>> <<setList .M.Name "_AIDLFLAGS" "" (getCompilerProperties .M).AidlInterface.Flags>> -add_aidl_library(<<.M.Name>> <<(getCompilerProperties .M).AidlInterface.Lang>> "${<<.M.Name>>_SRCS}" "${<<.M.Name>>_AIDLFLAGS}") +add_aidl_library(<<.M.Name>> <<(getCompilerProperties .M).AidlInterface.Lang>> + "${ANDROID_BUILD_TOP}/<<.Ctx.OtherModuleDir .M>>/<<(getCompilerProperties .M).AidlInterface.AidlRoot>>" + "${<<.M.Name>>_SRCS}" + "${<<.M.Name>>_AIDLFLAGS}") add_library(android::<<.M.Name>> ALIAS <<.M.Name>>) diff --git a/cc/cmake_module_cc.txt b/cc/cmake_module_cc.txt index 571f27ce5..488e5e102 100644 --- a/cc/cmake_module_cc.txt +++ b/cc/cmake_module_cc.txt @@ -1,7 +1,7 @@ <<$srcs := getSources .M>> <<$includeDirs := getIncludeDirs .Ctx .M>> <<$cflags := (getCompilerProperties .M).Cflags>> -<<$deps := mapLibraries (concat5 +<<$deps := mapLibraries .Ctx .M (concat5 (getLinkerProperties .M).Whole_static_libs (getLinkerProperties .M).Static_libs (getLinkerProperties .M).Shared_libs diff --git a/cc/cmake_snapshot.go b/cc/cmake_snapshot.go index 0635a2965..c21a46f04 100644 --- a/cc/cmake_snapshot.go +++ b/cc/cmake_snapshot.go @@ -192,13 +192,16 @@ func parseTemplate(templateContents string) *template.Template { }, "getExtraLibs": getExtraLibs, "getIncludeDirs": getIncludeDirs, - "mapLibraries": func(libs []string, mapping map[string]LibraryMappingProperty) []string { + "mapLibraries": func(ctx android.ModuleContext, m *Module, libs []string, mapping map[string]LibraryMappingProperty) []string { var mappedLibs []string for _, lib := range libs { mappedLib, exists := mapping[lib] if exists { lib = mappedLib.Mapped_name } else { + if !ctx.OtherModuleExists(lib) { + ctx.OtherModuleErrorf(m, "Dependency %s doesn't exist", lib) + } lib = "android::" + lib } if lib == "" { @@ -210,6 +213,21 @@ func parseTemplate(templateContents string) *template.Template { mappedLibs = slices.Compact(mappedLibs) return mappedLibs }, + "getAidlSources": func(m *Module) []string { + aidlInterface := m.compiler.baseCompilerProps().AidlInterface + aidlRoot := aidlInterface.AidlRoot + string(filepath.Separator) + if aidlInterface.AidlRoot == "" { + aidlRoot = "" + } + var sources []string + for _, src := range aidlInterface.Sources { + if !strings.HasPrefix(src, aidlRoot) { + panic(fmt.Sprintf("Aidl source '%v' doesn't start with '%v'", src, aidlRoot)) + } + sources = append(sources, src[len(aidlRoot):]) + } + return sources + }, } return template.Must(template.New("").Delims("<<", ">>").Funcs(funcMap).Parse(templateContents)) @@ -282,14 +300,14 @@ func (m *CmakeSnapshot) GenerateAndroidBuildActions(ctx android.ModuleContext) { var pregeneratedModules []*Module ctx.WalkDeps(func(dep_a android.Module, parent android.Module) bool { moduleName := ctx.OtherModuleName(dep_a) - dep, ok := dep_a.(*Module) - if !ok { - return false // not a cc module - } if visited := visitedModules[moduleName]; visited { return false // visit only once } visitedModules[moduleName] = true + dep, ok := dep_a.(*Module) + if !ok { + return false // not a cc module + } if mapping, ok := pprop.LibraryMapping[moduleName]; ok { if mapping.Package_pregenerated != "" { pregeneratedModules = append(pregeneratedModules, dep) diff --git a/cc/compiler.go b/cc/compiler.go index aee584daf..9187b9bfa 100644 --- a/cc/compiler.go +++ b/cc/compiler.go @@ -147,6 +147,9 @@ type BaseCompilerProperties struct { // list of aidl_interface sources Sources []string `blueprint:"mutated"` + // root directory of AIDL sources + AidlRoot string `blueprint:"mutated"` + // AIDL backend language (e.g. "cpp", "ndk") Lang string `blueprint:"mutated"` diff --git a/cmd/release_config/release_config/main.go b/cmd/release_config/release_config/main.go index 54328068a..a41183f97 100644 --- a/cmd/release_config/release_config/main.go +++ b/cmd/release_config/release_config/main.go @@ -51,7 +51,7 @@ func main() { flag.BoolVar(&textproto, "textproto", true, "write artifacts as text protobuf") flag.BoolVar(&json, "json", true, "write artifacts as json") flag.BoolVar(&pb, "pb", true, "write artifacts as binary protobuf") - flag.BoolVar(&allMake, "all_make", true, "write makefiles for all release configs") + flag.BoolVar(&allMake, "all_make", false, "write makefiles for all release configs") flag.BoolVar(&useBuildVar, "use_get_build_var", false, "use get_build_var PRODUCT_RELEASE_CONFIG_MAPS") flag.BoolVar(&guard, "guard", true, "whether to guard with RELEASE_BUILD_FLAGS_IN_PROTOBUF") diff --git a/cmd/release_config/release_config_lib/release_config.go b/cmd/release_config/release_config_lib/release_config.go index 820482239..93410a616 100644 --- a/cmd/release_config/release_config_lib/release_config.go +++ b/cmd/release_config/release_config_lib/release_config.go @@ -91,7 +91,8 @@ func (config *ReleaseConfig) InheritConfig(iConfig *ReleaseConfig) error { return fmt.Errorf("Could not inherit flag %s from %s", name, iConfig.Name) } if name == "RELEASE_ACONFIG_VALUE_SETS" { - if len(fa.Traces) > 0 { + // If there is a value assigned, add the trace. + if len(fa.Value.GetStringValue()) > 0 { myFa.Traces = append(myFa.Traces, fa.Traces...) myFa.Value = &rc_proto.Value{Val: &rc_proto.Value_StringValue{ myFa.Value.GetStringValue() + " " + fa.Value.GetStringValue()}} diff --git a/cmd/release_config/release_config_lib/release_configs.go b/cmd/release_config/release_config_lib/release_configs.go index 2487f2e99..0b6565822 100644 --- a/cmd/release_config/release_config_lib/release_configs.go +++ b/cmd/release_config/release_config_lib/release_configs.go @@ -439,7 +439,8 @@ func ReadReleaseConfigMaps(releaseConfigMapPaths StringList, targetRelease strin configs := ReleaseConfigsFactory() mapsRead := make(map[string]bool) - for idx, releaseConfigMapPath := range releaseConfigMapPaths { + var idx int + for _, releaseConfigMapPath := range releaseConfigMapPaths { // Maintain an ordered list of release config directories. configDir := filepath.Dir(releaseConfigMapPath) if mapsRead[configDir] { @@ -454,6 +455,7 @@ func ReadReleaseConfigMaps(releaseConfigMapPaths StringList, targetRelease strin if err != nil { return nil, err } + idx += 1 } // Now that we have all of the release config maps, can meld them and generate the artifacts. diff --git a/filesystem/filesystem_test.go b/filesystem/filesystem_test.go index 861918f16..015d39aab 100644 --- a/filesystem/filesystem_test.go +++ b/filesystem/filesystem_test.go @@ -497,3 +497,70 @@ func TestTrackPhonyAsRequiredDep(t *testing.T) { android.AssertStringListContains(t, "missing entry", fs.entries, e) } } + +func TestFilterOutUnsupportedArches(t *testing.T) { + result := fixture.RunTestWithBp(t, ` + android_filesystem { + name: "fs_64_only", + deps: ["foo"], + } + + android_filesystem { + name: "fs_64_32", + compile_multilib: "both", + multilib: { + first: { + deps: ["foo"], + }, + }, + } + + cc_binary { + name: "foo", + required: ["phony"], + } + + phony { + name: "phony", + required: [ + "libbar", + "app", + ], + } + + cc_library { + name: "libbar", + } + + android_app { + name: "app", + srcs: ["a.java"], + platform_apis: true, + } + `) + testcases := []struct { + fsName string + expected []string + unexpected []string + }{ + { + fsName: "fs_64_only", + expected: []string{"app/app/app.apk", "bin/foo", "lib64/libbar.so"}, + unexpected: []string{"lib/libbar.so"}, + }, + { + fsName: "fs_64_32", + expected: []string{"app/app/app.apk", "bin/foo", "lib64/libbar.so", "lib/libbar.so"}, + unexpected: []string{}, + }, + } + for _, c := range testcases { + fs := result.ModuleForTests(c.fsName, "android_common").Module().(*filesystem) + for _, e := range c.expected { + android.AssertStringListContains(t, "missing entry", fs.entries, e) + } + for _, e := range c.unexpected { + android.AssertStringListDoesNotContain(t, "unexpected entry", fs.entries, e) + } + } +} |