Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Android/build/build/soong/android/   (Android Betriebssystem Version 17©)  Datei vom 26.5.2026 mit Größe 13 kB image not shown  

Quelle  packaging_test.go   Sprache: unbekannt

 
Spracherkennung für: .go vermutete Sprache: Unknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen]

// Copyright 2020 Google Inc. All rights reserved.
//
// 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.

package android

import (
 "strings"
 "testing"

 "github.com/google/blueprint"
 "github.com/google/blueprint/proptools"
)

// Module to be packaged
type componentTestModule struct {
 ModuleBase
 props struct {
  Deps         []string
  Skip_install *bool
  Overrides    []string
 }
}

// dep tag used in this test. All dependencies are considered as installable.
type installDepTag struct {
 blueprint.BaseDependencyTag
 InstallAlwaysNeededDependencyTag
}

func componentTestModuleFactory() Module {
 m := &componentTestModule{}
 m.AddProperties(&m.props)
 InitAndroidArchModule(m, HostAndDeviceSupported, MultilibBoth)
 return m
}

func (m *componentTestModule) DepsMutator(ctx BottomUpMutatorContext) {
 ctx.AddDependency(ctx.Module(), installDepTag{}, m.props.Deps...)
}

func (m *componentTestModule) GenerateAndroidBuildActions(ctx ModuleContext) {
 builtFile := PathForModuleOut(ctx, m.Name())
 dir := ctx.Target().Arch.ArchType.Multilib
 installDir := PathForModuleInstall(ctx, dir)
 if proptools.Bool(m.props.Skip_install) {
  m.SkipInstall()
 }
 ctx.InstallFile(installDir, m.Name(), builtFile)
}

// Module that itself is a package
type packageTestModule struct {
 ModuleBase
 PackagingBase
 blueprint.ModuleUsesIncrementalWalkDeps
 properties struct {
  Install_deps []string
 }
 entries []string
}

func packageTestModuleFactory(multiTarget bool, depsCollectFirstTargetOnly bool) Module {
 module := &packageTestModule{}
 InitPackageModule(module)
 module.DepsCollectFirstTargetOnly = depsCollectFirstTargetOnly
 if multiTarget {
  InitAndroidMultiTargetsArchModule(module, DeviceSupported, MultilibCommon)
 } else {
  InitAndroidArchModule(module, DeviceSupported, MultilibBoth)
 }
 module.AddProperties(&module.properties)
 return module
}

type packagingDepTag struct {
 blueprint.BaseDependencyTag
 PackagingItemAlwaysDepTag
}

func (m *packageTestModule) DepsMutator(ctx BottomUpMutatorContext) {
 m.AddDeps(ctx, packagingDepTag{})
 ctx.AddDependency(ctx.Module(), installDepTag{}, m.properties.Install_deps...)
}

func (m *packageTestModule) GenerateAndroidBuildActions(ctx ModuleContext) {
 zipFile := PathForModuleOut(ctx, "myzip.zip")
 m.entries = m.CopyDepsToZip(ctx, m.GatherPackagingSpecs(ctx), zipFile)
}

type testConfig struct {
 multiTarget                bool
 depsCollectFirstTargetOnly bool
 debuggable                 bool
}

func runPackagingTest(t *testing.T, config testConfig, bp string, expected []string) {
 t.Helper()

 var archVariant string
 if config.multiTarget {
  archVariant = "android_common"
 } else {
  archVariant = "android_arm64_armv8-a"
 }

 moduleFactory := func() Module {
  return packageTestModuleFactory(config.multiTarget, config.depsCollectFirstTargetOnly)
 }

 result := GroupFixturePreparers(
  PrepareForTestWithDefaults,
  PrepareForTestWithArchMutator,
  FixtureRegisterWithContext(func(ctx RegistrationContext) {
   ctx.RegisterModuleType("component", componentTestModuleFactory)
   ctx.RegisterModuleType("package_module", moduleFactory)
  }),
  FixtureModifyProductVariables(func(variables FixtureProductVariables) {
   variables.Debuggable = proptools.BoolPtr(config.debuggable)
  }),
  FixtureWithRootAndroidBp(bp),
 ).RunTest(t)

 p := result.Module("package", archVariant).(*packageTestModule)
 actual := p.entries
 actual = SortedUniqueStrings(actual)
 expected = SortedUniqueStrings(expected)
 AssertDeepEquals(t, "package entries", expected, actual)
}

func TestPackagingBaseMultiTarget(t *testing.T) {
 config := testConfig{
  multiTarget:                true,
  depsCollectFirstTargetOnly: false,
 }
 runPackagingTest(t, config,
  `
  component {
   name: "foo",
  }

  package_module {
   name: "package",
   deps: ["foo"],
  }
  `, []string{"lib64/foo"})

 runPackagingTest(t, config,
  `
  component {
   name: "foo",
   deps: ["bar"],
  }

  component {
   name: "bar",
  }

  package_module {
   name: "package",
   deps: ["foo"],
  }
  `, []string{"lib64/foo", "lib64/bar"})

 runPackagingTest(t, config,
  `
  component {
   name: "foo",
   deps: ["bar"],
  }

  component {
   name: "bar",
  }

  package_module {
   name: "package",
   deps: ["foo"],
   compile_multilib: "both",
  }
  `, []string{"lib32/foo", "lib32/bar", "lib64/foo", "lib64/bar"})

 runPackagingTest(t, config,
  `
  component {
   name: "foo",
  }

  component {
   name: "bar",
   compile_multilib: "32",
  }

  package_module {
   name: "package",
   deps: ["foo"],
   multilib: {
    lib32: {
     deps: ["bar"],
    },
   },
   compile_multilib: "both",
  }
  `, []string{"lib32/foo", "lib32/bar", "lib64/foo"})

 runPackagingTest(t, config,
  `
  component {
   name: "foo",
  }

  component {
   name: "bar",
  }

  package_module {
   name: "package",
   deps: ["foo"],
   multilib: {
    first: {
     deps: ["bar"],
    },
   },
   compile_multilib: "both",
  }
  `, []string{"lib32/foo", "lib64/foo", "lib64/bar"})

 runPackagingTest(t, config,
  `
  component {
   name: "foo",
  }

  component {
   name: "bar",
  }

  component {
   name: "baz",
  }

  package_module {
   name: "package",
   deps: ["foo"],
   arch: {
    arm64: {
     deps: ["bar"],
    },
    x86_64: {
     deps: ["baz"],
    },
   },
   compile_multilib: "both",
  }
  `, []string{"lib32/foo", "lib64/foo", "lib64/bar"})
}

func TestPackagingBaseSingleTarget(t *testing.T) {
 config := testConfig{
  multiTarget:                false,
  depsCollectFirstTargetOnly: false,
 }
 runPackagingTest(t, config,
  `
  component {
   name: "foo",
  }

  package_module {
   name: "package",
   deps: ["foo"],
  }
  `, []string{"lib64/foo"})

 runPackagingTest(t, config,
  `
  component {
   name: "foo",
   deps: ["bar"],
  }

  component {
   name: "bar",
  }

  package_module {
   name: "package",
   deps: ["foo"],
  }
  `, []string{"lib64/foo", "lib64/bar"})

 runPackagingTest(t, config,
  `
  component {
   name: "foo",
  }

  component {
   name: "bar",
   compile_multilib: "32",
  }

  package_module {
   name: "package",
   deps: ["foo"],
   multilib: {
    lib32: {
     deps: ["bar"],
    },
   },
  }
  `, []string{"lib64/foo"})

 runPackagingTest(t, config,
  `
  component {
   name: "foo",
  }

  component {
   name: "bar",
  }

  package_module {
   name: "package",
   deps: ["foo"],
   multilib: {
    lib64: {
     deps: ["bar"],
    },
   },
  }
  `, []string{"lib64/foo", "lib64/bar"})

 runPackagingTest(t, config,
  `
  component {
   name: "foo",
  }

  component {
   name: "bar",
  }

  component {
   name: "baz",
  }

  package_module {
   name: "package",
   deps: ["foo"],
   arch: {
    arm64: {
     deps: ["bar"],
    },
    x86_64: {
     deps: ["baz"],
    },
   },
  }
  `, []string{"lib64/foo", "lib64/bar"})

 runPackagingTest(t, config,
  `
  component {
   name: "foo",
  }

  component {
   name: "bar",
  }

  package_module {
   name: "package",
   deps: ["foo"],
   install_deps: ["bar"],
  }
  `, []string{"lib64/foo"})
}

func TestPackagingWithSkipInstallDeps(t *testing.T) {
 // package -[dep]-> foo -[dep]-> bar      -[dep]-> baz
 // Packaging should continue transitively through modules that are not installed.
 config := testConfig{
  multiTarget:                false,
  depsCollectFirstTargetOnly: false,
 }
 runPackagingTest(t, config,
  `
  component {
   name: "foo",
   deps: ["bar"],
  }

  component {
   name: "bar",
   deps: ["baz"],
   skip_install: true,
  }

  component {
   name: "baz",
  }

  package_module {
   name: "package",
   deps: ["foo"],
  }
  `, []string{"lib64/foo", "lib64/bar", "lib64/baz"})
}

func TestPackagingWithDepsCollectFirstTargetOnly(t *testing.T) {
 config := testConfig{
  multiTarget:                true,
  depsCollectFirstTargetOnly: true,
 }
 runPackagingTest(t, config,
  `
  component {
   name: "foo",
  }

  package_module {
   name: "package",
   deps: ["foo"],
  }
  `, []string{"lib64/foo"})

 runPackagingTest(t, config,
  `
  component {
   name: "foo",
   deps: ["bar"],
  }

  component {
   name: "bar",
  }

  package_module {
   name: "package",
   deps: ["foo"],
  }
  `, []string{"lib64/foo", "lib64/bar"})

 runPackagingTest(t, config,
  `
  component {
   name: "foo",
   deps: ["bar"],
  }

  component {
   name: "bar",
  }

  package_module {
   name: "package",
   deps: ["foo"],
   compile_multilib: "both",
  }
  `, []string{"lib64/foo", "lib64/bar"})

 runPackagingTest(t, config,
  `
  component {
   name: "foo",
  }

  component {
   name: "bar",
   compile_multilib: "32",
  }

  package_module {
   name: "package",
   deps: ["foo"],
   multilib: {
    lib32: {
     deps: ["bar"],
    },
   },
   compile_multilib: "both",
  }
  `, []string{"lib32/bar", "lib64/foo"})

 runPackagingTest(t, config,
  `
  component {
   name: "foo",
  }

  component {
   name: "bar",
  }

  package_module {
   name: "package",
   deps: ["foo"],
   multilib: {
    both: {
     deps: ["bar"],
    },
   },
   compile_multilib: "both",
  }
  `, []string{"lib64/foo", "lib32/bar", "lib64/bar"})

 runPackagingTest(t, config,
  `
  component {
   name: "foo",
  }

  component {
   name: "bar",
  }

  component {
   name: "baz",
  }

  package_module {
   name: "package",
   deps: ["foo"],
   arch: {
    arm64: {
     deps: ["bar"],
    },
    x86_64: {
     deps: ["baz"],
    },
   },
   compile_multilib: "both",
  }
  `, []string{"lib64/foo", "lib64/bar"})
}

func TestDebuggableDeps(t *testing.T) {
 bp := `
  component {
   name: "foo",
  }

  component {
   name: "bar",
   deps: ["baz"],
  }

  component {
   name: "baz",
  }

  package_module {
   name: "package",
   deps: ["foo"] + select(product_variable("debuggable"), {
    true: ["bar"],
    default: [],
   }),
  }`
 testcases := []struct {
  debuggable bool
  expected   []string
 }{
  {
   debuggable: true,
   expected:   []string{"lib64/foo", "lib64/bar", "lib64/baz"},
  },
  {
   debuggable: false,
   expected:   []string{"lib64/foo"},
  },
 }
 for _, tc := range testcases {
  config := testConfig{
   debuggable: tc.debuggable,
  }
  runPackagingTest(t, config, bp, tc.expected)
 }
}

func TestPrefer32Deps(t *testing.T) {
 bpTemplate := `
  component {
   name: "foo",
   compile_multilib: "both", // not needed but for clarity
  }

  component {
   name: "foo_32only",
   compile_multilib: "prefer32",
  }

  component {
   name: "foo_64only",
   compile_multilib: "64",
  }

  package_module {
   name: "package",
   compile_multilib: "%COMPILE_MULTILIB%",
   multilib: {
    prefer32: {
     deps: %DEPS%,
    },
   },
  }
 `

 testcases := []struct {
  compileMultilib string
  deps            []string
  expected        []string
 }{
  {
   compileMultilib: "first",
   deps:            []string{"foo", "foo_64only"},
   expected:        []string{"lib64/foo", "lib64/foo_64only"},
  },
  {
   compileMultilib: "64",
   deps:            []string{"foo", "foo_64only"},
   expected:        []string{"lib64/foo", "lib64/foo_64only"},
  },
  {
   compileMultilib: "32",
   deps:            []string{"foo", "foo_32only"},
   expected:        []string{"lib32/foo", "lib32/foo_32only"},
  },
  {
   compileMultilib: "both",
   deps:            []string{"foo", "foo_32only", "foo_64only"},
   expected:        []string{"lib32/foo", "lib32/foo_32only", "lib64/foo_64only"},
  },
 }
 for _, tc := range testcases {
  config := testConfig{
   multiTarget:                true,
   depsCollectFirstTargetOnly: true,
  }
  bp := strings.Replace(bpTemplate, "%COMPILE_MULTILIB%", tc.compileMultilib, -1)
  bp = strings.Replace(bp, "%DEPS%", `["`+strings.Join(tc.deps, `", "`)+`"]`, -1)
  runPackagingTest(t, config, bp, tc.expected)
 }
}

func TestOverrides(t *testing.T) {
 bpTemplate := `
  component {
   name: "foo",
   deps: ["bar"],
  }

  component {
   name: "bar",
  }

  component {
   name: "bar_override",
   overrides: ["bar"],
  }

  component {
   name: "baz",
   deps: ["bar_override"],
  }

  package_module {
   name: "package",
   deps: %DEPS%,
  }
 `
 testcases := []struct {
  deps     []string
  expected []string
 }{
  {
   deps:     []string{"foo"},
   expected: []string{"lib64/foo", "lib64/bar"},
  },
  {
   deps:     []string{"foo", "bar_override"},
   expected: []string{"lib64/foo", "lib64/bar_override"},
  },
  {
   deps:     []string{"foo", "bar", "bar_override"},
   expected: []string{"lib64/foo", "lib64/bar_override"},
  },
  {
   deps:     []string{"bar", "bar_override"},
   expected: []string{"lib64/bar_override"},
  },
  {
   deps:     []string{"foo", "baz"},
   expected: []string{"lib64/foo", "lib64/baz", "lib64/bar_override"},
  },
 }
 for _, tc := range testcases {
  config := testConfig{
   multiTarget:                true,
   depsCollectFirstTargetOnly: false,
  }
  bp := strings.Replace(bpTemplate, "%DEPS%", `["`+strings.Join(tc.deps, `", "`)+`"]`, -1)
  runPackagingTest(t, config, bp, tc.expected)
 }
}

[Dauer der Verarbeitung: 0.23 Sekunden, vorverarbeitet 2026-06-28]