|
@@ -16,6 +16,7 @@ package android
|
|
|
|
|
|
import (
|
|
|
"fmt"
|
|
|
+ "path/filepath"
|
|
|
"testing"
|
|
|
)
|
|
|
|
|
@@ -34,7 +35,8 @@ func soongConfigTestDefaultsModuleFactory() Module {
|
|
|
type soongConfigTestModule struct {
|
|
|
ModuleBase
|
|
|
DefaultableModuleBase
|
|
|
- props soongConfigTestModuleProperties
|
|
|
+ props soongConfigTestModuleProperties
|
|
|
+ outputPath ModuleOutPath
|
|
|
}
|
|
|
|
|
|
type soongConfigTestModuleProperties struct {
|
|
@@ -49,7 +51,9 @@ func soongConfigTestModuleFactory() Module {
|
|
|
return m
|
|
|
}
|
|
|
|
|
|
-func (t soongConfigTestModule) GenerateAndroidBuildActions(ModuleContext) {}
|
|
|
+func (t *soongConfigTestModule) GenerateAndroidBuildActions(ctx ModuleContext) {
|
|
|
+ t.outputPath = PathForModuleOut(ctx, "test")
|
|
|
+}
|
|
|
|
|
|
var prepareForSoongConfigTestModule = FixtureRegisterWithContext(func(ctx RegistrationContext) {
|
|
|
ctx.RegisterModuleType("test_defaults", soongConfigTestDefaultsModuleFactory)
|
|
@@ -503,3 +507,197 @@ func TestSoongConfigModuleSingletonModule(t *testing.T) {
|
|
|
})
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+func TestSoongConfigModuleTrace(t *testing.T) {
|
|
|
+ bp := `
|
|
|
+ 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_module_type {
|
|
|
+ name: "acme_test_defaults",
|
|
|
+ module_type: "test_defaults",
|
|
|
+ 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"],
|
|
|
+ }
|
|
|
+
|
|
|
+ soong_config_string_variable {
|
|
|
+ name: "unused_string_var",
|
|
|
+ values: ["a", "b"],
|
|
|
+ }
|
|
|
+
|
|
|
+ soong_config_bool_variable {
|
|
|
+ name: "feature1",
|
|
|
+ }
|
|
|
+
|
|
|
+ soong_config_bool_variable {
|
|
|
+ name: "FEATURE3",
|
|
|
+ }
|
|
|
+
|
|
|
+ test_defaults {
|
|
|
+ name: "test_defaults",
|
|
|
+ cflags: ["DEFAULT"],
|
|
|
+ }
|
|
|
+
|
|
|
+ test {
|
|
|
+ name: "normal",
|
|
|
+ defaults: ["test_defaults"],
|
|
|
+ }
|
|
|
+
|
|
|
+ acme_test {
|
|
|
+ name: "board_1",
|
|
|
+ defaults: ["test_defaults"],
|
|
|
+ soong_config_variables: {
|
|
|
+ board: {
|
|
|
+ soc_a: {
|
|
|
+ cflags: ["-DSOC_A"],
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ }
|
|
|
+
|
|
|
+ acme_test {
|
|
|
+ name: "board_2",
|
|
|
+ defaults: ["test_defaults"],
|
|
|
+ soong_config_variables: {
|
|
|
+ board: {
|
|
|
+ soc_a: {
|
|
|
+ cflags: ["-DSOC_A"],
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ }
|
|
|
+
|
|
|
+ acme_test {
|
|
|
+ name: "size",
|
|
|
+ defaults: ["test_defaults"],
|
|
|
+ soong_config_variables: {
|
|
|
+ size: {
|
|
|
+ cflags: ["-DSIZE=%s"],
|
|
|
+ },
|
|
|
+ },
|
|
|
+ }
|
|
|
+
|
|
|
+ acme_test {
|
|
|
+ name: "board_and_size",
|
|
|
+ defaults: ["test_defaults"],
|
|
|
+ soong_config_variables: {
|
|
|
+ board: {
|
|
|
+ soc_a: {
|
|
|
+ cflags: ["-DSOC_A"],
|
|
|
+ },
|
|
|
+ },
|
|
|
+ size: {
|
|
|
+ cflags: ["-DSIZE=%s"],
|
|
|
+ },
|
|
|
+ },
|
|
|
+ }
|
|
|
+
|
|
|
+ acme_test_defaults {
|
|
|
+ name: "board_defaults",
|
|
|
+ soong_config_variables: {
|
|
|
+ board: {
|
|
|
+ soc_a: {
|
|
|
+ cflags: ["-DSOC_A"],
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ }
|
|
|
+
|
|
|
+ acme_test_defaults {
|
|
|
+ name: "size_defaults",
|
|
|
+ soong_config_variables: {
|
|
|
+ size: {
|
|
|
+ cflags: ["-DSIZE=%s"],
|
|
|
+ },
|
|
|
+ },
|
|
|
+ }
|
|
|
+
|
|
|
+ test {
|
|
|
+ name: "board_and_size_with_defaults",
|
|
|
+ defaults: ["board_defaults", "size_defaults"],
|
|
|
+ }
|
|
|
+ `
|
|
|
+
|
|
|
+ fixtureForVendorVars := func(vars map[string]map[string]string) FixturePreparer {
|
|
|
+ return FixtureModifyProductVariables(func(variables FixtureProductVariables) {
|
|
|
+ variables.VendorVars = vars
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ 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",
|
|
|
+ },
|
|
|
+ })
|
|
|
+
|
|
|
+ t.Run("soong config trace hash", func(t *testing.T) {
|
|
|
+ result := GroupFixturePreparers(
|
|
|
+ preparer,
|
|
|
+ PrepareForTestWithDefaults,
|
|
|
+ PrepareForTestWithSoongConfigModuleBuildComponents,
|
|
|
+ prepareForSoongConfigTestModule,
|
|
|
+ FixtureRegisterWithContext(func(ctx RegistrationContext) {
|
|
|
+ ctx.FinalDepsMutators(registerSoongConfigTraceMutator)
|
|
|
+ }),
|
|
|
+ FixtureWithRootAndroidBp(bp),
|
|
|
+ ).RunTest(t)
|
|
|
+
|
|
|
+ // Hashes of modules not using soong config should be empty
|
|
|
+ normal := result.ModuleForTests("normal", "").Module().(*soongConfigTestModule)
|
|
|
+ AssertDeepEquals(t, "normal hash", normal.base().commonProperties.SoongConfigTraceHash, "")
|
|
|
+ AssertDeepEquals(t, "normal hash out", normal.outputPath.RelativeToTop().String(), "out/soong/.intermediates/normal/test")
|
|
|
+
|
|
|
+ board1 := result.ModuleForTests("board_1", "").Module().(*soongConfigTestModule)
|
|
|
+ board2 := result.ModuleForTests("board_2", "").Module().(*soongConfigTestModule)
|
|
|
+ size := result.ModuleForTests("size", "").Module().(*soongConfigTestModule)
|
|
|
+
|
|
|
+ // Trace mutator sets soong config trace hash correctly
|
|
|
+ board1Hash := board1.base().commonProperties.SoongConfigTrace.hash()
|
|
|
+ board1Output := board1.outputPath.RelativeToTop().String()
|
|
|
+ AssertDeepEquals(t, "board hash calc", board1Hash, board1.base().commonProperties.SoongConfigTraceHash)
|
|
|
+ AssertDeepEquals(t, "board hash path", board1Output, filepath.Join("out/soong/.intermediates/board_1", board1Hash, "test"))
|
|
|
+
|
|
|
+ sizeHash := size.base().commonProperties.SoongConfigTrace.hash()
|
|
|
+ sizeOutput := size.outputPath.RelativeToTop().String()
|
|
|
+ AssertDeepEquals(t, "size hash calc", sizeHash, size.base().commonProperties.SoongConfigTraceHash)
|
|
|
+ AssertDeepEquals(t, "size hash path", sizeOutput, filepath.Join("out/soong/.intermediates/size", sizeHash, "test"))
|
|
|
+
|
|
|
+ // Trace should be identical for modules using the same set of variables
|
|
|
+ AssertDeepEquals(t, "board trace", board1.base().commonProperties.SoongConfigTrace, board2.base().commonProperties.SoongConfigTrace)
|
|
|
+ AssertDeepEquals(t, "board hash", board1.base().commonProperties.SoongConfigTraceHash, board2.base().commonProperties.SoongConfigTraceHash)
|
|
|
+
|
|
|
+ // Trace hash should be different for different sets of soong variables
|
|
|
+ AssertBoolEquals(t, "board hash not equal to size hash", board1.base().commonProperties.SoongConfigTraceHash == size.commonProperties.SoongConfigTraceHash, false)
|
|
|
+
|
|
|
+ boardSize := result.ModuleForTests("board_and_size", "").Module().(*soongConfigTestModule)
|
|
|
+ boardSizeDefaults := result.ModuleForTests("board_and_size_with_defaults", "").Module()
|
|
|
+
|
|
|
+ // Trace should propagate
|
|
|
+ AssertDeepEquals(t, "board_size hash calc", boardSize.base().commonProperties.SoongConfigTrace.hash(), boardSize.base().commonProperties.SoongConfigTraceHash)
|
|
|
+ AssertDeepEquals(t, "board_size trace", boardSize.base().commonProperties.SoongConfigTrace, boardSizeDefaults.base().commonProperties.SoongConfigTrace)
|
|
|
+ AssertDeepEquals(t, "board_size hash", boardSize.base().commonProperties.SoongConfigTraceHash, boardSizeDefaults.base().commonProperties.SoongConfigTraceHash)
|
|
|
+ })
|
|
|
+}
|