aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/test
diff options
context:
space:
mode:
authorGravatar mstaib <mstaib@google.com>2018-04-23 12:18:24 -0700
committerGravatar Copybara-Service <copybara-piper@google.com>2018-04-23 12:19:38 -0700
commita7c6786f32d8dd96a23fc23f61381b550a792fc1 (patch)
treea48f5c7fafc5757734c9d617a3ca7b27845516c6 /src/test
parent981f65bf0a53239c8d5d55a1469c17721a12b2f4 (diff)
Add the additional options to support manual trimming of feature flags.
There are effectively three different states a flag's value could be in: 1. Value is known to be non-default 2. Value is known to be default 3. Value is unknown (has been trimmed) In addition to flagValues (which covers the first state), there are now two additional sets covering the other two states. Neither of these sets are used when manual trimming is disabled or when the entire set of flags is known, in which case state 1 is represented by labels in the map, state 2 is represented by labels not in the map, and state 3 doesn't exist. This also adds the flag which controls whether manual trimming is active, but it currently has no effect. RELNOTES: None. PiperOrigin-RevId: 193964624
Diffstat (limited to 'src/test')
-rw-r--r--src/test/java/com/google/devtools/build/lib/rules/config/ConfigFeatureFlagOptionsTest.java332
1 files changed, 303 insertions, 29 deletions
diff --git a/src/test/java/com/google/devtools/build/lib/rules/config/ConfigFeatureFlagOptionsTest.java b/src/test/java/com/google/devtools/build/lib/rules/config/ConfigFeatureFlagOptionsTest.java
index 3550000216..2bc8b30f33 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/config/ConfigFeatureFlagOptionsTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/config/ConfigFeatureFlagOptionsTest.java
@@ -14,16 +14,22 @@
package com.google.devtools.build.lib.rules.config;
+import static com.google.common.collect.MoreCollectors.onlyElement;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth8.assertThat;
import static org.junit.Assert.fail;
import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Iterables;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.ImmutableSortedMap;
+import com.google.common.collect.ImmutableSortedSet;
import com.google.common.testing.EqualsTester;
import com.google.devtools.build.lib.cmdline.Label;
+import com.google.devtools.common.options.Options;
import com.google.devtools.common.options.OptionsParser;
import com.google.devtools.common.options.OptionsParsingException;
import java.util.Map;
+import java.util.Set;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@@ -33,8 +39,10 @@ import org.junit.runners.JUnit4;
public final class ConfigFeatureFlagOptionsTest {
@Test
- public void getFlagValues_startsEmpty() throws Exception {
+ public void flagState_startsEmpty() throws Exception {
assertThat(new ConfigFeatureFlagOptions().getFlagValues()).isEmpty();
+ assertThat(new ConfigFeatureFlagOptions().getKnownDefaultFlags()).isEmpty();
+ assertThat(new ConfigFeatureFlagOptions().getUnknownFlags()).isEmpty();
}
@Test
@@ -65,68 +73,334 @@ public final class ConfigFeatureFlagOptionsTest {
}
@Test
- public void getDefault_isEmpty() throws Exception {
- assertThat(
- ((ConfigFeatureFlagOptions) new ConfigFeatureFlagOptions().getDefault())
- .getFlagValues())
- .isEmpty();
+ public void replaceFlagValues_emptiesKnownDefaultFlagsAndUnknownFlags() throws Exception {
+ Map<Label, String> originalMap =
+ ImmutableMap.of(
+ Label.parseAbsoluteUnchecked("//label:a"), "value",
+ Label.parseAbsoluteUnchecked("//label:b"), "otherValue");
+ ConfigFeatureFlagOptions options = new ConfigFeatureFlagOptions();
+ options.replaceFlagValues(originalMap);
+ options.trimFlagValues(
+ ImmutableSortedSet.of(
+ Label.parseAbsoluteUnchecked("//label:a"),
+ Label.parseAbsoluteUnchecked("//label:c"),
+ Label.parseAbsoluteUnchecked("//label:d")));
+ options.replaceFlagValues(originalMap);
+ assertThat(options.getKnownDefaultFlags()).isEmpty();
+ assertThat(options.getUnknownFlags()).isEmpty();
}
@Test
- public void getHost_isEmpty() throws Exception {
- assertThat(
- ((ConfigFeatureFlagOptions) new ConfigFeatureFlagOptions().getHost()).getFlagValues())
- .isEmpty();
- assertThat(
- ((ConfigFeatureFlagOptions) new ConfigFeatureFlagOptions().getHost()).getFlagValues())
- .isEmpty();
+ public void trimFlagValues_defaults_toEmptySetProducesEmptyOptions() throws Exception {
+ ConfigFeatureFlagOptions options = new ConfigFeatureFlagOptions();
+
+ options.trimFlagValues(ImmutableSet.of());
+
+ assertThat(options.getFlagValues()).isEmpty();
+ assertThat(options.getKnownDefaultFlags()).isPresent();
+ assertThat(options.getKnownDefaultFlags().get()).isEmpty();
+ assertThat(options.getUnknownFlags()).isEmpty();
+ }
+
+ @Test
+ public void trimFlagValues_defaults_toPopulatedSetPopulatesKnownDefaultFlags() throws Exception {
+ ConfigFeatureFlagOptions options = new ConfigFeatureFlagOptions();
+
+ options.trimFlagValues(
+ ImmutableSet.of(
+ Label.parseAbsoluteUnchecked("//label:a"),
+ Label.parseAbsoluteUnchecked("//label:b"),
+ Label.parseAbsoluteUnchecked("//label:c")));
+
+ assertThat(options.getFlagValues()).isEmpty();
+ assertThat(options.getKnownDefaultFlags()).isPresent();
+ assertThat(options.getKnownDefaultFlags().get())
+ .containsExactly(
+ Label.parseAbsoluteUnchecked("//label:a"),
+ Label.parseAbsoluteUnchecked("//label:b"),
+ Label.parseAbsoluteUnchecked("//label:c"));
+ assertThat(options.getUnknownFlags()).isEmpty();
+ }
+
+ @Test
+ public void trimFlagValues_withFlagsSet_toEmptySetProducesEmptyOptions() throws Exception {
+ ConfigFeatureFlagOptions options = new ConfigFeatureFlagOptions();
+ options.replaceFlagValues(
+ ImmutableMap.of(
+ Label.parseAbsoluteUnchecked("//label:a"),
+ "value",
+ Label.parseAbsoluteUnchecked("//label:d"),
+ "otherValue"));
+
+ options.trimFlagValues(ImmutableSet.of());
+
+ assertThat(options.getFlagValues()).isEmpty();
+ assertThat(options.getKnownDefaultFlags()).isPresent();
+ assertThat(options.getKnownDefaultFlags().get()).isEmpty();
+ assertThat(options.getUnknownFlags()).isEmpty();
+ }
+
+ @Test
+ public void trimFlagValues_withFlagsSet_toPopulatedSetPopulatesFlagValuesAndKnownDefaultFlags()
+ throws Exception {
+ ConfigFeatureFlagOptions options = new ConfigFeatureFlagOptions();
+ options.replaceFlagValues(
+ ImmutableMap.of(
+ Label.parseAbsoluteUnchecked("//label:a"),
+ "value",
+ Label.parseAbsoluteUnchecked("//label:d"),
+ "otherValue"));
+
+ options.trimFlagValues(
+ ImmutableSet.of(
+ Label.parseAbsoluteUnchecked("//label:a"),
+ Label.parseAbsoluteUnchecked("//label:b"),
+ Label.parseAbsoluteUnchecked("//label:c")));
+
+ assertThat(options.getFlagValues())
+ .containsExactly(Label.parseAbsoluteUnchecked("//label:a"), "value");
+ assertThat(options.getKnownDefaultFlags()).isPresent();
+ assertThat(options.getKnownDefaultFlags().get())
+ .containsExactly(
+ Label.parseAbsoluteUnchecked("//label:b"), Label.parseAbsoluteUnchecked("//label:c"));
+ assertThat(options.getUnknownFlags()).isEmpty();
+ }
+
+ @Test
+ public void trimFlagValues_withTrimmedFlagsSet_toEmptySetProducesEmptyOptions() throws Exception {
+ ConfigFeatureFlagOptions options = new ConfigFeatureFlagOptions();
+ options.replaceFlagValues(
+ ImmutableMap.of(
+ Label.parseAbsoluteUnchecked("//label:a"),
+ "value",
+ Label.parseAbsoluteUnchecked("//label:d"),
+ "otherValue"));
+ options.trimFlagValues(
+ ImmutableSet.of(
+ Label.parseAbsoluteUnchecked("//label:a"), Label.parseAbsoluteUnchecked("//label:b")));
+
+ options.trimFlagValues(ImmutableSet.of());
+
+ assertThat(options.getFlagValues()).isEmpty();
+ assertThat(options.getKnownDefaultFlags()).isPresent();
+ assertThat(options.getKnownDefaultFlags().get()).isEmpty();
+ assertThat(options.getUnknownFlags()).isEmpty();
+ }
+
+ @Test
+ public void trimFlagValues_withTrimmedFlagsSet_toPopulatedSetPopulatesFlagState()
+ throws Exception {
+ ConfigFeatureFlagOptions options = new ConfigFeatureFlagOptions();
+ options.replaceFlagValues(
+ ImmutableMap.of(
+ Label.parseAbsoluteUnchecked("//label:a"),
+ "value",
+ Label.parseAbsoluteUnchecked("//label:d"),
+ "otherValue"));
+ options.trimFlagValues(
+ ImmutableSet.of(
+ Label.parseAbsoluteUnchecked("//label:a"), Label.parseAbsoluteUnchecked("//label:b")));
+
+ options.trimFlagValues(
+ ImmutableSet.of(
+ Label.parseAbsoluteUnchecked("//label:a"),
+ Label.parseAbsoluteUnchecked("//label:b"),
+ Label.parseAbsoluteUnchecked("//label:c")));
+
+ assertThat(options.getFlagValues())
+ .containsExactly(Label.parseAbsoluteUnchecked("//label:a"), "value");
+ assertThat(options.getKnownDefaultFlags()).isPresent();
+ assertThat(options.getKnownDefaultFlags().get())
+ .containsExactly(Label.parseAbsoluteUnchecked("//label:b"));
+ assertThat(options.getUnknownFlags())
+ .containsExactly(Label.parseAbsoluteUnchecked("//label:c"));
+ }
+
+ @Test
+ public void hostMode_clearsFlagState() throws Exception {
+ ConfigFeatureFlagOptions options = new ConfigFeatureFlagOptions();
+ options.enforceTransitiveConfigsForConfigFeatureFlag = true;
+ options.replaceFlagValues(
+ ImmutableMap.of(
+ Label.parseAbsoluteUnchecked("//label:a"),
+ "value",
+ Label.parseAbsoluteUnchecked("//label:d"),
+ "otherValue"));
+ options.trimFlagValues(
+ ImmutableSet.of(
+ Label.parseAbsoluteUnchecked("//label:a"), Label.parseAbsoluteUnchecked("//label:b")));
+ options.trimFlagValues(
+ ImmutableSet.of(
+ Label.parseAbsoluteUnchecked("//label:a"),
+ Label.parseAbsoluteUnchecked("//label:b"),
+ Label.parseAbsoluteUnchecked("//label:c")));
+
+ ConfigFeatureFlagOptions hostOptions = (ConfigFeatureFlagOptions) options.getHost();
+ assertThat(hostOptions.enforceTransitiveConfigsForConfigFeatureFlag).isFalse();
+ assertThat(hostOptions.getFlagValues()).isEmpty();
+ assertThat(hostOptions.getKnownDefaultFlags()).isEmpty();
+ assertThat(hostOptions.getUnknownFlags()).isEmpty();
}
@Test
public void equals_forEquivalentMaps() throws Exception {
new EqualsTester()
.addEqualityGroup(
+ // Empty with all flags set to default values
getOptionsWith(ImmutableMap.<Label, String>of()),
new ConfigFeatureFlagOptions(),
new ConfigFeatureFlagOptions().getDefault(),
new ConfigFeatureFlagOptions().getHost(),
new ConfigFeatureFlagOptions().getHost())
.addEqualityGroup(
- getOptionsWith(ImmutableMap.of(Label.parseAbsoluteUnchecked("//a:a"), "a")),
- getOptionsWith(ImmutableMap.of(Label.parseAbsoluteUnchecked("//a:a"), "a")))
+ // Empty with all flags trimmed
+ getOptionsAndTrim(ImmutableMap.of(), ImmutableSet.of()),
+ getOptionsAndTrim(
+ ImmutableMap.of(Label.parseAbsolute("//a:a"), "a"), ImmutableSet.of()),
+ getOptionsAndTrim(
+ ImmutableMap.of(
+ Label.parseAbsolute("//a:a"), "a", Label.parseAbsolute("//b:b"), "b"),
+ ImmutableSet.of()))
.addEqualityGroup(
- getOptionsWith(ImmutableMap.of(Label.parseAbsoluteUnchecked("//b:b"), "a")))
+ // Only //a:a => a, others default
+ getOptionsWith(ImmutableMap.of(Label.parseAbsolute("//a:a"), "a")),
+ getOptionsWith(ImmutableMap.of(Label.parseAbsolute("//a:a"), "a")))
.addEqualityGroup(
- getOptionsWith(ImmutableMap.of(Label.parseAbsoluteUnchecked("//a:a"), "b")))
+ // Error: //a:a is absent
+ getOptionsAndTrim(ImmutableMap.of(), ImmutableSet.of(Label.parseAbsolute("//a:a"))),
+ getOptionsAndTrim(
+ ImmutableMap.of(Label.parseAbsolute("//b:b"), "b"),
+ ImmutableSet.of(Label.parseAbsolute("//a:a"))))
.addEqualityGroup(
- getOptionsWith(ImmutableMap.of(Label.parseAbsoluteUnchecked("//b:b"), "b")))
+ // Only //a:a => a, others trimmed
+ getOptionsAndTrim(
+ ImmutableMap.of(Label.parseAbsolute("//a:a"), "a"),
+ ImmutableSet.of(Label.parseAbsolute("//a:a"))),
+ getOptionsAndTrim(
+ ImmutableMap.of(
+ Label.parseAbsolute("//a:a"), "a", Label.parseAbsolute("//b:b"), "b"),
+ ImmutableSet.of(Label.parseAbsolute("//a:a"))))
+ .addEqualityGroup(
+ // Only //b:b => a, others default
+ getOptionsWith(ImmutableMap.of(Label.parseAbsolute("//b:b"), "a")))
+ .addEqualityGroup(
+ // Only //a:a => b, others default
+ getOptionsWith(ImmutableMap.of(Label.parseAbsolute("//a:a"), "b")))
.addEqualityGroup(
+ // Only //b:b => b, others default
+ getOptionsWith(ImmutableMap.of(Label.parseAbsolute("//b:b"), "b")))
+ .addEqualityGroup(
+ // //a:a => b and //b:b => a, others default (order doesn't matter)
getOptionsWith(
ImmutableMap.of(
- Label.parseAbsoluteUnchecked("//a:a"), "b",
- Label.parseAbsoluteUnchecked("//b:b"), "a")),
+ Label.parseAbsolute("//a:a"), "b",
+ Label.parseAbsolute("//b:b"), "a")),
getOptionsWith(
ImmutableMap.of(
- Label.parseAbsoluteUnchecked("//b:b"), "a",
- Label.parseAbsoluteUnchecked("//a:a"), "b")))
+ Label.parseAbsolute("//b:b"), "a",
+ Label.parseAbsolute("//a:a"), "b")))
+ .addEqualityGroup(
+ // //a:a => b and //b:b => a, others trimmed (order doesn't matter)
+ getOptionsAndTrim(
+ ImmutableMap.of(
+ Label.parseAbsolute("//a:a"), "b",
+ Label.parseAbsolute("//b:b"), "a"),
+ ImmutableSet.of(Label.parseAbsolute("//a:a"), Label.parseAbsolute("//b:b"))),
+ getOptionsAndTrim(
+ ImmutableMap.of(
+ Label.parseAbsolute("//a:a"), "b",
+ Label.parseAbsolute("//b:b"), "a"),
+ ImmutableSet.of(Label.parseAbsolute("//b:b"), Label.parseAbsolute("//a:a"))),
+ getOptionsAndTrim(
+ ImmutableMap.of(
+ Label.parseAbsolute("//b:b"), "a",
+ Label.parseAbsolute("//a:a"), "b"),
+ ImmutableSet.of(Label.parseAbsolute("//a:a"), Label.parseAbsolute("//b:b"))),
+ getOptionsAndTrim(
+ ImmutableMap.of(
+ Label.parseAbsolute("//b:b"), "a",
+ Label.parseAbsolute("//a:a"), "b"),
+ ImmutableSet.of(Label.parseAbsolute("//b:b"), Label.parseAbsolute("//a:a"))))
.testEquals();
}
+ private ConfigFeatureFlagOptions getOptionsWith(Map<Label, String> values) {
+ ConfigFeatureFlagOptions result = new ConfigFeatureFlagOptions();
+ result.replaceFlagValues(values);
+ return result;
+ }
+
+ private ConfigFeatureFlagOptions getOptionsAndTrim(
+ Map<Label, String> values, Set<Label> trimming) {
+ ConfigFeatureFlagOptions result = getOptionsWith(values);
+ result.trimFlagValues(trimming);
+ return result;
+ }
+
@Test
public void parser_doesNotAllowFlagValuesToBeParsed() throws Exception {
+ ConfigFeatureFlagOptions options = Options.getDefaults(ConfigFeatureFlagOptions.class);
+ ImmutableSortedMap<Label, String> testValue =
+ ImmutableSortedMap.of(Label.parseAbsolute("//what:heck"), "something");
+ options.flagValues = testValue;
+ String flagValuesOption =
+ options
+ .asMap()
+ .entrySet()
+ .stream()
+ .filter((entry) -> testValue.equals(entry.getValue()))
+ .map(Map.Entry::getKey)
+ .collect(onlyElement());
OptionsParser parser = OptionsParser.newOptionsParser(ConfigFeatureFlagOptions.class);
try {
- parser.parse(
- "--" + Iterables.getOnlyElement(new ConfigFeatureFlagOptions().asMap().keySet()) + "={}");
+ parser.parse("--" + flagValuesOption + "={}");
fail("Flags successfully parsed despite passing a private flag.");
} catch (OptionsParsingException expected) {
assertThat(expected).hasMessageThat().contains("Unrecognized option:");
}
}
- private ConfigFeatureFlagOptions getOptionsWith(Map<Label, String> values) {
- ConfigFeatureFlagOptions result = new ConfigFeatureFlagOptions();
- result.replaceFlagValues(values);
- return result;
+ @Test
+ public void parser_doesNotAllowKnownDefaultValuesToBeParsed() throws Exception {
+ ConfigFeatureFlagOptions options = Options.getDefaults(ConfigFeatureFlagOptions.class);
+ ImmutableSortedSet<Label> testValue = ImmutableSortedSet.of(Label.parseAbsolute("//what:heck"));
+ options.knownDefaultFlags = testValue;
+ String defaultValuesOption =
+ options
+ .asMap()
+ .entrySet()
+ .stream()
+ .filter((entry) -> testValue.equals(entry.getValue()))
+ .map(Map.Entry::getKey)
+ .collect(onlyElement());
+ OptionsParser parser = OptionsParser.newOptionsParser(ConfigFeatureFlagOptions.class);
+ try {
+ parser.parse("--" + defaultValuesOption + "={}");
+ fail("Flags successfully parsed despite passing a private flag.");
+ } catch (OptionsParsingException expected) {
+ assertThat(expected).hasMessageThat().contains("Unrecognized option:");
+ }
+ }
+
+ @Test
+ public void parser_doesNotAllowUnknownValuesToBeParsed() throws Exception {
+ ConfigFeatureFlagOptions options = Options.getDefaults(ConfigFeatureFlagOptions.class);
+ ImmutableSortedSet<Label> testValue = ImmutableSortedSet.of(Label.parseAbsolute("//what:heck"));
+ options.unknownFlags = testValue;
+ String unknownFlagsOption =
+ options
+ .asMap()
+ .entrySet()
+ .stream()
+ .filter((entry) -> testValue.equals(entry.getValue()))
+ .map(Map.Entry::getKey)
+ .collect(onlyElement());
+ OptionsParser parser = OptionsParser.newOptionsParser(ConfigFeatureFlagOptions.class);
+ try {
+ parser.parse("--" + unknownFlagsOption + "={}");
+ fail("Flags successfully parsed despite passing a private flag.");
+ } catch (OptionsParsingException expected) {
+ assertThat(expected).hasMessageThat().contains("Unrecognized option:");
+ }
}
}