Add "exported" mode to xx_aconfig_library build rules
Test: added unit tests and CI
Bug: 309990433
Change-Id: Iae1b85265d9780bde7d41ec2ec6e8e441c2b3814
diff --git a/aconfig/cc_aconfig_library.go b/aconfig/cc_aconfig_library.go
index 5b0fb4a..8aa696b 100644
--- a/aconfig/cc_aconfig_library.go
+++ b/aconfig/cc_aconfig_library.go
@@ -39,7 +39,14 @@
Aconfig_declarations string
// whether to generate test mode version of the library
+ // TODO: remove "Test" property when "Mode" can be used in all the branches
Test *bool
+
+ // default mode is "production", the other accepted modes are:
+ // "test": to generate test mode version of the library
+ // "exported": to generate exported mode version of the library
+ // an error will be thrown if the mode is not supported
+ Mode *string
}
type CcAconfigLibraryCallbacks struct {
@@ -121,11 +128,16 @@
}
declarations := ctx.OtherModuleProvider(declarationsModules[0], declarationsProviderKey).(declarationsProviderData)
- var mode string
+ if this.properties.Mode != nil && this.properties.Test != nil {
+ ctx.PropertyErrorf("test", "test prop should not be specified when mode prop is set")
+ }
+ mode := proptools.StringDefault(this.properties.Mode, "production")
+ if !isModeSupported(mode) {
+ ctx.PropertyErrorf("mode", "%q is not a supported mode", mode)
+ }
+ // TODO: remove "Test" property
if proptools.Bool(this.properties.Test) {
mode = "test"
- } else {
- mode = "production"
}
ctx.Build(pctx, android.BuildParams{
Rule: cppRule,
diff --git a/aconfig/cc_aconfig_library_test.go b/aconfig/cc_aconfig_library_test.go
index 6f17c75..9a819e5 100644
--- a/aconfig/cc_aconfig_library_test.go
+++ b/aconfig/cc_aconfig_library_test.go
@@ -22,16 +22,17 @@
"android/soong/cc"
)
-var codegenModeTestData = []struct {
+var ccCodegenModeTestData = []struct {
setting, expected string
}{
{"", "production"},
- {"test: false,", "production"},
- {"test: true,", "test"},
+ {"mode: `production`,", "production"},
+ {"mode: `test`,", "test"},
+ {"mode: `exported`,", "exported"},
}
func TestCCCodegenMode(t *testing.T) {
- for _, testData := range codegenModeTestData {
+ for _, testData := range ccCodegenModeTestData {
testCCCodegenModeHelper(t, testData.setting, testData.expected)
}
}
@@ -65,3 +66,43 @@
rule := module.Rule("cc_aconfig_library")
android.AssertStringEquals(t, "rule must contain test mode", rule.Args["mode"], ruleMode)
}
+
+var incorrectCCCodegenModeTestData = []struct {
+ setting, expectedErr string
+}{
+ {"mode: `unsupported`,", "mode: \"unsupported\" is not a supported mode"},
+ // TODO: remove this test case when test prop is removed
+ {"mode: `test`, test: true", "test prop should not be specified when mode prop is set"},
+}
+
+func TestIncorrectCCCodegenMode(t *testing.T) {
+ for _, testData := range incorrectCCCodegenModeTestData {
+ testIncorrectCCCodegenModeHelper(t, testData.setting, testData.expectedErr)
+ }
+}
+
+func testIncorrectCCCodegenModeHelper(t *testing.T, bpMode string, err string) {
+ t.Helper()
+ android.GroupFixturePreparers(
+ PrepareForTestWithAconfigBuildComponents,
+ cc.PrepareForTestWithCcDefaultModules).
+ ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(err)).
+ RunTestWithBp(t, fmt.Sprintf(`
+ aconfig_declarations {
+ name: "my_aconfig_declarations",
+ package: "com.example.package",
+ srcs: ["foo.aconfig"],
+ }
+
+ cc_library {
+ name: "server_configurable_flags",
+ srcs: ["server_configurable_flags.cc"],
+ }
+
+ cc_aconfig_library {
+ name: "my_cc_aconfig_library",
+ aconfig_declarations: "my_aconfig_declarations",
+ %s
+ }
+ `, bpMode))
+}
diff --git a/aconfig/java_aconfig_library.go b/aconfig/java_aconfig_library.go
index f7f8db8..b6c90fc 100644
--- a/aconfig/java_aconfig_library.go
+++ b/aconfig/java_aconfig_library.go
@@ -30,12 +30,21 @@
var declarationsTag = declarationsTagType{}
+var aconfigSupportedModes = []string{"production", "test", "exported"}
+
type JavaAconfigDeclarationsLibraryProperties struct {
// name of the aconfig_declarations module to generate a library for
Aconfig_declarations string
// whether to generate test mode version of the library
+ // TODO: remove "Test" property when "Mode" can be used in all the branches
Test *bool
+
+ // default mode is "production", the other accepted modes are:
+ // "test": to generate test mode version of the library
+ // "exported": to generate exported mode version of the library
+ // an error will be thrown if the mode is not supported
+ Mode *string
}
type JavaAconfigDeclarationsLibraryCallbacks struct {
@@ -72,12 +81,19 @@
// Generate the action to build the srcjar
srcJarPath := android.PathForModuleGen(ctx, ctx.ModuleName()+".srcjar")
- var mode string
+
+ if callbacks.properties.Mode != nil && callbacks.properties.Test != nil {
+ ctx.PropertyErrorf("test", "test prop should not be specified when mode prop is set")
+ }
+ mode := proptools.StringDefault(callbacks.properties.Mode, "production")
+ if !isModeSupported(mode) {
+ ctx.PropertyErrorf("mode", "%q is not a supported mode", mode)
+ }
+ // TODO: remove "Test" property
if proptools.Bool(callbacks.properties.Test) {
mode = "test"
- } else {
- mode = "production"
}
+
ctx.Build(pctx, android.BuildParams{
Rule: javaRule,
Input: declarations.IntermediatePath,
@@ -95,9 +111,12 @@
return srcJarPath
}
+func isModeSupported(mode string) bool {
+ return android.InList(mode, aconfigSupportedModes)
+}
+
type bazelJavaAconfigLibraryAttributes struct {
Aconfig_declarations bazel.LabelAttribute
- Test *bool
Sdk_version *string
Libs bazel.LabelListAttribute
}
@@ -138,7 +157,6 @@
attrs := bazelJavaAconfigLibraryAttributes{
Aconfig_declarations: *bazel.MakeLabelAttribute(android.BazelLabelForModuleDepSingle(ctx, callbacks.properties.Aconfig_declarations).Label),
- Test: callbacks.properties.Test,
Sdk_version: &sdkVersion,
Libs: libs,
}
diff --git a/aconfig/java_aconfig_library_test.go b/aconfig/java_aconfig_library_test.go
index af50848..05532e7 100644
--- a/aconfig/java_aconfig_library_test.go
+++ b/aconfig/java_aconfig_library_test.go
@@ -178,14 +178,48 @@
android.AssertStringEquals(t, "rule must contain test mode", rule.Args["mode"], ruleMode)
}
+func testCodegenModeWithError(t *testing.T, bpMode string, err string) {
+ android.GroupFixturePreparers(
+ PrepareForTestWithAconfigBuildComponents,
+ java.PrepareForTestWithJavaDefaultModules).
+ ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(err)).
+ RunTestWithBp(t, fmt.Sprintf(`
+ aconfig_declarations {
+ name: "my_aconfig_declarations",
+ package: "com.example.package",
+ srcs: ["foo.aconfig"],
+ }
+
+ java_aconfig_library {
+ name: "my_java_aconfig_library",
+ aconfig_declarations: "my_aconfig_declarations",
+ %s
+ }
+ `, bpMode))
+}
+
func TestDefaultProdMode(t *testing.T) {
testCodegenMode(t, "", "production")
}
func TestProdMode(t *testing.T) {
- testCodegenMode(t, "test: false,", "production")
+ testCodegenMode(t, "mode: `production`,", "production")
}
func TestTestMode(t *testing.T) {
- testCodegenMode(t, "test: true,", "test")
+ testCodegenMode(t, "mode: `test`,", "test")
+}
+
+func TestExportedMode(t *testing.T) {
+ testCodegenMode(t, "mode: `exported`,", "exported")
+}
+
+func TestUnsupportedMode(t *testing.T) {
+ testCodegenModeWithError(t, "mode: `unsupported`,", "mode: \"unsupported\" is not a supported mode")
+}
+
+// TODO: remove this test case when test prop is removed
+func TestBothModeAndTestAreSet(t *testing.T) {
+ testCodegenModeWithError(t, "mode: `test`, test: true",
+ "test prop should not be specified when mode prop is set")
}
diff --git a/aconfig/rust_aconfig_library.go b/aconfig/rust_aconfig_library.go
index 71918dd..43078b6 100644
--- a/aconfig/rust_aconfig_library.go
+++ b/aconfig/rust_aconfig_library.go
@@ -1,9 +1,10 @@
package aconfig
import (
+ "fmt"
+
"android/soong/android"
"android/soong/rust"
- "fmt"
"github.com/google/blueprint"
"github.com/google/blueprint/proptools"
@@ -18,7 +19,16 @@
type RustAconfigLibraryProperties struct {
// name of the aconfig_declarations module to generate a library for
Aconfig_declarations string
- Test *bool
+
+ // whether to generate test mode version of the library
+ // TODO: remove "Test" property when "Mode" can be used in all the branches
+ Test *bool
+
+ // default mode is "production", the other accepted modes are:
+ // "test": to generate test mode version of the library
+ // "exported": to generate exported mode version of the library
+ // an error will be thrown if the mode is not supported
+ Mode *string
}
type aconfigDecorator struct {
@@ -60,7 +70,15 @@
}
declarations := ctx.OtherModuleProvider(declarationsModules[0], declarationsProviderKey).(declarationsProviderData)
- mode := "production"
+ if a.Properties.Mode != nil && a.Properties.Test != nil {
+ ctx.PropertyErrorf("test", "test prop should not be specified when mode prop is set")
+ }
+ mode := proptools.StringDefault(a.Properties.Mode, "production")
+ if !isModeSupported(mode) {
+ ctx.PropertyErrorf("mode", "%q is not a supported mode", mode)
+ }
+
+ // TODO: remove "Test" property
if proptools.Bool(a.Properties.Test) {
mode = "test"
}
diff --git a/aconfig/rust_aconfig_library_test.go b/aconfig/rust_aconfig_library_test.go
index a10da2d..5e630b5 100644
--- a/aconfig/rust_aconfig_library_test.go
+++ b/aconfig/rust_aconfig_library_test.go
@@ -1,10 +1,11 @@
package aconfig
import (
- "android/soong/android"
- "android/soong/rust"
"fmt"
"testing"
+
+ "android/soong/android"
+ "android/soong/rust"
)
func TestRustAconfigLibrary(t *testing.T) {
@@ -63,3 +64,98 @@
)
}
}
+
+var rustCodegenModeTestData = []struct {
+ setting, expected string
+}{
+ {"", "production"},
+ {"mode: `production`,", "production"},
+ {"mode: `test`,", "test"},
+ {"mode: `exported`,", "exported"},
+}
+
+func TestRustCodegenMode(t *testing.T) {
+ for _, testData := range rustCodegenModeTestData {
+ testRustCodegenModeHelper(t, testData.setting, testData.expected)
+ }
+}
+
+func testRustCodegenModeHelper(t *testing.T, bpMode string, ruleMode string) {
+ t.Helper()
+ result := android.GroupFixturePreparers(
+ PrepareForTestWithAconfigBuildComponents,
+ rust.PrepareForTestWithRustIncludeVndk).
+ ExtendWithErrorHandler(android.FixtureExpectsNoErrors).
+ RunTestWithBp(t, fmt.Sprintf(`
+ rust_library {
+ name: "libflags_rust", // test mock
+ crate_name: "flags_rust",
+ srcs: ["lib.rs"],
+ }
+ rust_library {
+ name: "liblazy_static", // test mock
+ crate_name: "lazy_static",
+ srcs: ["src/lib.rs"],
+ }
+ aconfig_declarations {
+ name: "my_aconfig_declarations",
+ package: "com.example.package",
+ srcs: ["foo.aconfig"],
+ }
+ rust_aconfig_library {
+ name: "libmy_rust_aconfig_library",
+ crate_name: "my_rust_aconfig_library",
+ aconfig_declarations: "my_aconfig_declarations",
+ %s
+ }
+ `, bpMode))
+
+ module := result.ModuleForTests("libmy_rust_aconfig_library", "android_arm64_armv8-a_source")
+ rule := module.Rule("rust_aconfig_library")
+ android.AssertStringEquals(t, "rule must contain test mode", rule.Args["mode"], ruleMode)
+}
+
+var incorrectRustCodegenModeTestData = []struct {
+ setting, expectedErr string
+}{
+ {"mode: `unsupported`,", "mode: \"unsupported\" is not a supported mode"},
+ // TODO: remove this test case when test prop is removed
+ {"mode: `test`, test: true", "test prop should not be specified when mode prop is set"},
+}
+
+func TestIncorrectRustCodegenMode(t *testing.T) {
+ for _, testData := range incorrectRustCodegenModeTestData {
+ testIncorrectRustCodegenModeHelper(t, testData.setting, testData.expectedErr)
+ }
+}
+
+func testIncorrectRustCodegenModeHelper(t *testing.T, bpMode string, err string) {
+ t.Helper()
+ android.GroupFixturePreparers(
+ PrepareForTestWithAconfigBuildComponents,
+ rust.PrepareForTestWithRustIncludeVndk).
+ ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(err)).
+ RunTestWithBp(t, fmt.Sprintf(`
+ rust_library {
+ name: "libflags_rust", // test mock
+ crate_name: "flags_rust",
+ srcs: ["lib.rs"],
+ }
+ rust_library {
+ name: "liblazy_static", // test mock
+ crate_name: "lazy_static",
+ srcs: ["src/lib.rs"],
+ }
+ aconfig_declarations {
+ name: "my_aconfig_declarations",
+ package: "com.example.package",
+ srcs: ["foo.aconfig"],
+ }
+ rust_aconfig_library {
+ name: "libmy_rust_aconfig_library",
+ crate_name: "my_rust_aconfig_library",
+ aconfig_declarations: "my_aconfig_declarations",
+ %s
+ }
+ `, bpMode))
+}