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 10 kB image not shown  

Quelle  soong_config_modules_test.go   Sprache: unbekannt

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

// Copyright 2019 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 (
 "testing"
)

type soongConfigTestDefaultsModule struct {
 ModuleBase
 DefaultsModuleBase
}

func soongConfigTestDefaultsModuleFactory() Module {
 m := &soongConfigTestDefaultsModule{}
 m.AddProperties(&soongConfigTestModuleProperties{})
 InitDefaultsModule(m)
 return m
}

type soongConfigTestModule struct {
 ModuleBase
 DefaultableModuleBase
 props      soongConfigTestModuleProperties
 outputPath ModuleOutPath
}

type soongConfigTestModuleProperties struct {
 Cflags []string
}

func soongConfigTestModuleFactory() Module {
 m := &soongConfigTestModule{}
 m.AddProperties(&m.props)
 InitAndroidModule(m)
 InitDefaultableModule(m)
 return m
}

func (t *soongConfigTestModule) GenerateAndroidBuildActions(ctx ModuleContext) {
 t.outputPath = PathForModuleOut(ctx, "test")
}

var prepareForSoongConfigTestModule = FixtureRegisterWithContext(func(ctx RegistrationContext) {
 ctx.RegisterModuleType("test_defaults", soongConfigTestDefaultsModuleFactory)
 ctx.RegisterModuleType("test", soongConfigTestModuleFactory)
})

func TestSoongConfigModule(t *testing.T) {
 configBp := `
  soong_config_module_type {
   name: "acme_test",
   module_type: "test",
   config_namespace: "acme",
   variables: ["board", "feature1", "FEATURE3", "unused_string_var"],
   bool_variables: ["feature2", "unused_feature", "always_true"],
   value_variables: ["size", "unused_size"],
   properties: ["cflags", "srcs", "defaults"],
  }

  soong_config_string_variable {
   name: "board",
   values: ["soc_a", "soc_b", "soc_c", "soc_d"],
  }

  soong_config_string_variable {
   name: "unused_string_var",
   values: ["a", "b"],
  }

  soong_config_bool_variable {
   name: "feature1",
  }

  soong_config_bool_variable {
   name: "FEATURE3",
  }
 `

 importBp := `
  soong_config_module_type_import {
   from: "SoongConfig.bp",
   module_types: ["acme_test"],
  }
 `

 bp := `
  test_defaults {
   name: "foo_defaults",
   cflags: ["DEFAULT"],
  }

  acme_test {
   name: "foo",
   cflags: ["-DGENERIC"],
   defaults: ["foo_defaults"],
   soong_config_variables: {
    board: {
     soc_a: {
      cflags: ["-DSOC_A"],
     },
     soc_b: {
      cflags: ["-DSOC_B"],
     },
     soc_c: {},
     conditions_default: {
      cflags: ["-DSOC_CONDITIONS_DEFAULT"],
     },
    },
    size: {
     cflags: ["-DSIZE=%s"],
     conditions_default: {
      cflags: ["-DSIZE=CONDITIONS_DEFAULT"],
     },
    },
    feature1: {
       conditions_default: {
        cflags: ["-DF1_CONDITIONS_DEFAULT"],
       },
     cflags: ["-DFEATURE1"],
    },
    feature2: {
     cflags: ["-DFEATURE2"],
      conditions_default: {
       cflags: ["-DF2_CONDITIONS_DEFAULT"],
      },
    },
    FEATURE3: {
     cflags: ["-DFEATURE3"],
    },
   },
  }

  test_defaults {
   name: "foo_defaults_a",
   cflags: ["DEFAULT_A"],
  }

  test_defaults {
   name: "foo_defaults_b",
   cflags: ["DEFAULT_B"],
  }

  test_defaults {
   name: "foo_defaults_always_true",
   cflags: ["DEFAULT_ALWAYS_TRUE"],
  }

  acme_test {
   name: "foo_with_defaults",
   cflags: ["-DGENERIC"],
   defaults: ["foo_defaults"],
   soong_config_variables: {
    board: {
     soc_a: {
      cflags: ["-DSOC_A"],
      defaults: ["foo_defaults_a"],
     },
     soc_b: {
      cflags: ["-DSOC_B"],
      defaults: ["foo_defaults_b"],
     },
     soc_c: {},
    },
    size: {
     cflags: ["-DSIZE=%s"],
    },
    feature1: {
     cflags: ["-DFEATURE1"],
    },
    feature2: {
     cflags: ["-DFEATURE2"],
    },
    FEATURE3: {
     cflags: ["-DFEATURE3"],
    },
    always_true: {
     defaults: ["foo_defaults_always_true"],
     conditions_default: {
      // verify that conditions_default is skipped if the
      // soong config variable is true by specifying a
      // non-existent module in conditions_default
      defaults: ["//nonexistent:defaults"],
     }
    },
   },
  }
    `

 fixtureForVendorVars := func(vars map[string]map[string]string) FixturePreparer {
  return FixtureModifyProductVariables(func(variables FixtureProductVariables) {
   variables.VendorVars = vars
  })
 }

 run := func(t *testing.T, bp string, fs MockFS) {
  testCases := []struct {
   name                     string
   preparer                 FixturePreparer
   fooExpectedFlags         []string
   fooDefaultsExpectedFlags []string
  }{
   {
    name: "withValues",
    preparer: fixtureForVendorVars(map[string]map[string]string{
     "acme": {
      "board":    "soc_a",
      "size":     "42",
      "feature1": "true",
      "feature2": "false",
      // FEATURE3 unset
      "unused_feature":    "true", // unused
      "unused_size":       "1",    // unused
      "unused_string_var": "a",    // unused
      "always_true":       "true",
     },
    }),
    fooExpectedFlags: []string{
     "DEFAULT",
     "-DGENERIC",
     "-DF2_CONDITIONS_DEFAULT",
     "-DSIZE=42",
     "-DSOC_A",
     "-DFEATURE1",
    },
    fooDefaultsExpectedFlags: []string{
     "DEFAULT_A",
     "DEFAULT_ALWAYS_TRUE",
     "DEFAULT",
     "-DGENERIC",
     "-DSIZE=42",
     "-DSOC_A",
     "-DFEATURE1",
    },
   },
   {
    name: "empty_prop_for_string_var",
    preparer: fixtureForVendorVars(map[string]map[string]string{
     "acme": {
      "board":       "soc_c",
      "always_true": "true",
     }}),
    fooExpectedFlags: []string{
     "DEFAULT",
     "-DGENERIC",
     "-DF2_CONDITIONS_DEFAULT",
     "-DSIZE=CONDITIONS_DEFAULT",
     "-DF1_CONDITIONS_DEFAULT",
    },
    fooDefaultsExpectedFlags: []string{
     "DEFAULT_ALWAYS_TRUE",
     "DEFAULT",
     "-DGENERIC",
    },
   },
   {
    name: "unused_string_var",
    preparer: fixtureForVendorVars(map[string]map[string]string{
     "acme": {
      "board":       "soc_d",
      "always_true": "true",
     }}),
    fooExpectedFlags: []string{
     "DEFAULT",
     "-DGENERIC",
     "-DF2_CONDITIONS_DEFAULT",
     "-DSIZE=CONDITIONS_DEFAULT",
     "-DSOC_CONDITIONS_DEFAULT", // foo does not contain a prop "soc_d", so we use the default
     "-DF1_CONDITIONS_DEFAULT",
    },
    fooDefaultsExpectedFlags: []string{
     "DEFAULT_ALWAYS_TRUE",
     "DEFAULT",
     "-DGENERIC",
    },
   },

   {
    name: "conditions_default",
    preparer: fixtureForVendorVars(map[string]map[string]string{
     "acme": {
      "always_true": "true",
     }}),
    fooExpectedFlags: []string{
     "DEFAULT",
     "-DGENERIC",
     "-DF2_CONDITIONS_DEFAULT",
     "-DSIZE=CONDITIONS_DEFAULT",
     "-DSOC_CONDITIONS_DEFAULT",
     "-DF1_CONDITIONS_DEFAULT",
    },
    fooDefaultsExpectedFlags: []string{
     "DEFAULT_ALWAYS_TRUE",
     "DEFAULT",
     "-DGENERIC",
    },
   },
  }

  for _, tc := range testCases {
   t.Run(tc.name, func(t *testing.T) {
    result := GroupFixturePreparers(
     tc.preparer,
     PrepareForTestWithDefaults,
     PrepareForTestWithSoongConfigModuleBuildComponents,
     prepareForSoongConfigTestModule,
     fs.AddToFixture(),
     FixtureWithRootAndroidBp(bp),
    ).RunTest(t)

    foo := result.ModuleForTests(t, "foo", "").Module().(*soongConfigTestModule)
    AssertDeepEquals(t, "foo cflags", tc.fooExpectedFlags, foo.props.Cflags)

    fooDefaults := result.ModuleForTests(t, "foo_with_defaults", "").Module().(*soongConfigTestModule)
    AssertDeepEquals(t, "foo_with_defaults cflags", tc.fooDefaultsExpectedFlags, fooDefaults.props.Cflags)
   })
  }
 }

 t.Run("single file", func(t *testing.T) {
  run(t, configBp+bp, nil)
 })

 t.Run("import", func(t *testing.T) {
  run(t, importBp+bp, map[string][]byte{
   "SoongConfig.bp": []byte(configBp),
  })
 })
}

func TestNonExistentPropertyInSoongConfigModule(t *testing.T) {
 bp := `
  soong_config_module_type {
   name: "acme_test",
   module_type: "test",
   config_namespace: "acme",
   bool_variables: ["feature1"],
   properties: ["made_up_property"],
  }

  acme_test {
   name: "foo",
   cflags: ["-DGENERIC"],
   soong_config_variables: {
    feature1: {
     made_up_property: true,
    },
   },
  }
    `

 fixtureForVendorVars := func(vars map[string]map[string]string) FixturePreparer {
  return FixtureModifyProductVariables(func(variables FixtureProductVariables) {
   variables.VendorVars = vars
  })
 }

 GroupFixturePreparers(
  fixtureForVendorVars(map[string]map[string]string{"acme": {"feature1": "1"}}),
  PrepareForTestWithDefaults,
  PrepareForTestWithSoongConfigModuleBuildComponents,
  prepareForSoongConfigTestModule,
  FixtureWithRootAndroidBp(bp),
 ).ExtendWithErrorHandler(FixtureExpectsAllErrorsToMatchAPattern([]string{
  `unrecognized property "soong_config_variables.feature1.made_up_property`,
 })).RunTest(t)
}

func TestDuplicateStringValueInSoongConfigStringVariable(t *testing.T) {
 bp := `
  soong_config_string_variable {
   name: "board",
   values: ["soc_a", "soc_b", "soc_c", "soc_a"],
  }

  soong_config_module_type {
   name: "acme_test",
   module_type: "test",
   config_namespace: "acme",
   variables: ["board"],
   properties: ["cflags", "srcs", "defaults"],
  }
    `

 fixtureForVendorVars := func(vars map[string]map[string]string) FixturePreparer {
  return FixtureModifyProductVariables(func(variables FixtureProductVariables) {
   variables.VendorVars = vars
  })
 }

 GroupFixturePreparers(
  fixtureForVendorVars(map[string]map[string]string{"acme": {"feature1": "1"}}),
  PrepareForTestWithDefaults,
  PrepareForTestWithSoongConfigModuleBuildComponents,
  prepareForSoongConfigTestModule,
  FixtureWithRootAndroidBp(bp),
 ).ExtendWithErrorHandler(FixtureExpectsAllErrorsToMatchAPattern([]string{
  // TODO(b/171232169): improve the error message for non-existent properties
  `Android.bp: soong_config_string_variable: values property error: duplicate value: "soc_a"`,
 })).RunTest(t)
}

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