diff options
author | 2017-04-12 16:37:48 +0000 | |
---|---|---|
committer | 2017-04-13 09:36:45 +0200 | |
commit | b127fbbb9cec67407d6d19d3664d57700c085158 (patch) | |
tree | 5e99542e2eb3d983e8c1f9a6f341e2e5d84a5c9f /src/test/java/com/google | |
parent | f76ad07c5ab4984ce6836d8ac15e7265742f30c7 (diff) |
Add feature_flags attribute to Android binary rules.
This is the first actual user of the config_feature_flag rule, able to actually
set its value (and thus give a point to using it!)
This feature is not fully launched yet, but it is usable in any build
containing this change.
RELNOTES: None.
PiperOrigin-RevId: 152948153
Diffstat (limited to 'src/test/java/com/google')
-rw-r--r-- | src/test/java/com/google/devtools/build/lib/rules/android/AndroidBinaryTest.java | 214 |
1 files changed, 214 insertions, 0 deletions
diff --git a/src/test/java/com/google/devtools/build/lib/rules/android/AndroidBinaryTest.java b/src/test/java/com/google/devtools/build/lib/rules/android/AndroidBinaryTest.java index ca032eb389..9a54de5bdb 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/android/AndroidBinaryTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/android/AndroidBinaryTest.java @@ -33,6 +33,7 @@ import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.actions.util.ActionsTestUtil; import com.google.devtools.build.lib.analysis.ConfiguredTarget; import com.google.devtools.build.lib.analysis.FilesToRunProvider; +import com.google.devtools.build.lib.analysis.actions.FileWriteAction; import com.google.devtools.build.lib.analysis.actions.SpawnAction; import com.google.devtools.build.lib.cmdline.RepositoryName; import com.google.devtools.build.lib.collect.nestedset.NestedSet; @@ -2444,4 +2445,217 @@ public class AndroidBinaryTest extends AndroidBuildViewTestCase { " manifest = 'AndroidManifest.xml',", ")"); } + + @Test + public void testFeatureFlagsAttributeSetsSelectInDependency() throws Exception { + useConfiguration("--experimental_dynamic_configs=on"); + scratch.file( + "java/com/foo/BUILD", + "config_feature_flag(", + " name = 'flag1',", + " allowed_values = ['on', 'off'],", + " default_value = 'off',", + ")", + "config_setting(", + " name = 'flag1@on',", + " flag_values = {':flag1': 'on'},", + ")", + "config_feature_flag(", + " name = 'flag2',", + " allowed_values = ['on', 'off'],", + " default_value = 'off',", + ")", + "config_setting(", + " name = 'flag2@on',", + " flag_values = {':flag2': 'on'},", + ")", + "android_library(", + " name = 'lib',", + " srcs = select({", + " ':flag1@on': ['Flag1On.java'],", + " '//conditions:default': ['Flag1Off.java'],", + " }) + select({", + " ':flag2@on': ['Flag2On.java'],", + " '//conditions:default': ['Flag2Off.java'],", + " }),", + ")", + "android_binary(", + " name = 'foo',", + " manifest = 'AndroidManifest.xml',", + " deps = [':lib'],", + " feature_flags = {", + " 'flag1': 'on',", + " }", + ")"); + ConfiguredTarget binary = getConfiguredTarget("//java/com/foo"); + List<String> inputs = + actionsTestUtil() + .prettyArtifactNames(actionsTestUtil().artifactClosureOf(getFinalUnsignedApk(binary))); + + assertThat(inputs).containsAllOf("java/com/foo/Flag1On.java", "java/com/foo/Flag2Off.java"); + assertThat(inputs).containsNoneOf("java/com/foo/Flag1Off.java", "java/com/foo/Flag2On.java"); + } + + @Test + public void testFeatureFlagsAttributeSetsSelectInBinary() throws Exception { + useConfiguration("--experimental_dynamic_configs=on"); + scratch.file( + "java/com/foo/BUILD", + "config_feature_flag(", + " name = 'flag1',", + " allowed_values = ['on', 'off'],", + " default_value = 'off',", + ")", + "config_setting(", + " name = 'flag1@on',", + " flag_values = {':flag1': 'on'},", + ")", + "config_feature_flag(", + " name = 'flag2',", + " allowed_values = ['on', 'off'],", + " default_value = 'off',", + ")", + "config_setting(", + " name = 'flag2@on',", + " flag_values = {':flag2': 'on'},", + ")", + "android_binary(", + " name = 'foo',", + " manifest = 'AndroidManifest.xml',", + " srcs = select({", + " ':flag1@on': ['Flag1On.java'],", + " '//conditions:default': ['Flag1Off.java'],", + " }) + select({", + " ':flag2@on': ['Flag2On.java'],", + " '//conditions:default': ['Flag2Off.java'],", + " }),", + " feature_flags = {", + " 'flag1': 'on',", + " }", + ")"); + ConfiguredTarget binary = getConfiguredTarget("//java/com/foo"); + List<String> inputs = + actionsTestUtil() + .prettyArtifactNames(actionsTestUtil().artifactClosureOf(getFinalUnsignedApk(binary))); + + assertThat(inputs).containsAllOf("java/com/foo/Flag1On.java", "java/com/foo/Flag2Off.java"); + assertThat(inputs).containsNoneOf("java/com/foo/Flag1Off.java", "java/com/foo/Flag2On.java"); + } + + @Test + public void testFeatureFlagsAttributeFailsAnalysisIfFlagValueIsInvalid() throws Exception { + reporter.removeHandler(failFastHandler); + useConfiguration("--experimental_dynamic_configs=on"); + scratch.file( + "java/com/foo/BUILD", + "config_feature_flag(", + " name = 'flag1',", + " allowed_values = ['on', 'off'],", + " default_value = 'off',", + ")", + "config_setting(", + " name = 'flag1@on',", + " flag_values = {':flag1': 'on'},", + ")", + "android_library(", + " name = 'lib',", + " srcs = select({", + " ':flag1@on': ['Flag1On.java'],", + " '//conditions:default': ['Flag1Off.java'],", + " })", + ")", + "android_binary(", + " name = 'foo',", + " manifest = 'AndroidManifest.xml',", + " deps = [':lib'],", + " feature_flags = {", + " 'flag1': 'invalid',", + " }", + ")"); + assertThat(getConfiguredTarget("//java/com/foo")).isNull(); + assertContainsEvent( + "in config_feature_flag rule //java/com/foo:flag1: " + + "value must be one of ['off', 'on'], but was 'invalid'"); + } + + @Test + public void testFeatureFlagsAttributeFailsAnalysisIfFlagValueIsInvalidEvenIfNotUsed() + throws Exception { + reporter.removeHandler(failFastHandler); + useConfiguration("--experimental_dynamic_configs=on"); + scratch.file( + "java/com/foo/BUILD", + "config_feature_flag(", + " name = 'flag1',", + " allowed_values = ['on', 'off'],", + " default_value = 'off',", + ")", + "config_setting(", + " name = 'flag1@on',", + " flag_values = {':flag1': 'on'},", + ")", + "android_binary(", + " name = 'foo',", + " manifest = 'AndroidManifest.xml',", + " feature_flags = {", + " 'flag1': 'invalid',", + " }", + ")"); + assertThat(getConfiguredTarget("//java/com/foo")).isNull(); + assertContainsEvent( + "in config_feature_flag rule //java/com/foo:flag1: " + + "value must be one of ['off', 'on'], but was 'invalid'"); + } + + @Test + public void testFeatureFlagsAttributeSetsFeatureFlagProviderValues() throws Exception { + useConfiguration("--experimental_dynamic_configs=on"); + scratch.file( + "java/com/foo/reader.bzl", + "def _impl(ctx):", + " ctx.file_action(", + " ctx.outputs.java,", + " '\\n'.join([", + " str(target.label) + ': ' + target[config_common.FeatureFlagInfo].value", + " for target in ctx.attr.flags]))", + " return struct(files=depset([ctx.outputs.java]))", + "flag_reader = rule(", + " implementation=_impl,", + " attrs={'flags': attr.label_list(providers=[config_common.FeatureFlagInfo])},", + " outputs={'java': '%{name}.java'},", + ")"); + scratch.file( + "java/com/foo/BUILD", + "load('//java/com/foo:reader.bzl', 'flag_reader')", + "config_feature_flag(", + " name = 'flag1',", + " allowed_values = ['on', 'off'],", + " default_value = 'off',", + ")", + "config_feature_flag(", + " name = 'flag2',", + " allowed_values = ['on', 'off'],", + " default_value = 'off',", + ")", + "flag_reader(", + " name = 'FooFlags',", + " flags = [':flag1', ':flag2'],", + ")", + "android_binary(", + " name = 'foo',", + " manifest = 'AndroidManifest.xml',", + " srcs = [':FooFlags.java'],", + " feature_flags = {", + " 'flag1': 'on',", + " }", + ")"); + Artifact flagList = + getFirstArtifactEndingWith( + actionsTestUtil() + .artifactClosureOf(getFinalUnsignedApk(getConfiguredTarget("//java/com/foo"))), + "/FooFlags.java"); + FileWriteAction action = (FileWriteAction) getGeneratingAction(flagList); + assertThat(action.getFileContents()) + .isEqualTo("//java/com/foo:flag1: on\n//java/com/foo:flag2: off"); + } } |