From 40dc4b9372962a2c0de13ff3dbe7735fa0dff07a Mon Sep 17 00:00:00 2001 From: janakr Date: Mon, 22 Jan 2018 22:02:10 -0800 Subject: Add codec for TestFilter, and clean up some things: use java.util.function.Predicate and move some code that was only called by TestFilter inside it. PiperOrigin-RevId: 182884550 --- .../devtools/build/lib/pkgcache/TestFilter.java | 136 ++++++++++++++++----- 1 file changed, 105 insertions(+), 31 deletions(-) (limited to 'src/main/java/com/google/devtools/build/lib/pkgcache/TestFilter.java') diff --git a/src/main/java/com/google/devtools/build/lib/pkgcache/TestFilter.java b/src/main/java/com/google/devtools/build/lib/pkgcache/TestFilter.java index ee18660ca4..5dbed752e7 100644 --- a/src/main/java/com/google/devtools/build/lib/pkgcache/TestFilter.java +++ b/src/main/java/com/google/devtools/build/lib/pkgcache/TestFilter.java @@ -13,66 +13,84 @@ // limitations under the License. package com.google.devtools.build.lib.pkgcache; -import com.google.common.base.Predicate; -import com.google.common.base.Predicates; +import com.google.common.annotations.VisibleForTesting; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; +import com.google.devtools.build.lib.events.Event; import com.google.devtools.build.lib.events.ExtendedEventHandler; +import com.google.devtools.build.lib.packages.Rule; import com.google.devtools.build.lib.packages.Target; import com.google.devtools.build.lib.packages.TargetUtils; import com.google.devtools.build.lib.packages.TestSize; -import com.google.devtools.build.lib.packages.TestTargetUtils; import com.google.devtools.build.lib.packages.TestTimeout; +import com.google.devtools.build.lib.skyframe.serialization.ObjectCodec; +import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec; +import java.util.HashSet; import java.util.List; import java.util.Objects; import java.util.Set; +import java.util.function.Predicate; import javax.annotation.Nullable; /** - * Predicate that implements test filtering using the command-line options in {@link LoadingOptions}. - * Implements {@link #hashCode} and {@link #equals} so it can be used as a Skyframe key. + * Predicate that implements test filtering using the command-line options in {@link + * LoadingOptions}. Implements {@link #hashCode} and {@link #equals} so it can be used as a Skyframe + * key. */ -public final class TestFilter implements Predicate { +@AutoCodec +public final class TestFilter implements com.google.common.base.Predicate { + static final ObjectCodec CODEC = new TestFilter_AutoCodec(); + + private static final Predicate ALWAYS_TRUE = (t) -> true; + /** Convert the options into a test filter. */ public static TestFilter forOptions( LoadingOptions options, ExtendedEventHandler eventHandler, Set ruleNames) { - Predicate testFilter = Predicates.alwaysTrue(); - if (!options.testSizeFilterSet.isEmpty()) { - testFilter = Predicates.and(testFilter, - TestTargetUtils.testSizeFilter(options.testSizeFilterSet)); - } - if (!options.testTimeoutFilterSet.isEmpty()) { - testFilter = Predicates.and(testFilter, - TestTargetUtils.testTimeoutFilter(options.testTimeoutFilterSet)); - } - if (!options.testTagFilterList.isEmpty()) { - testFilter = Predicates.and(testFilter, - TargetUtils.tagFilter(options.testTagFilterList)); - } if (!options.testLangFilterList.isEmpty()) { - testFilter = Predicates.and(testFilter, - TestTargetUtils.testLangFilter(options.testLangFilterList, eventHandler, ruleNames)); + checkLangFilters(options.testLangFilterList, eventHandler, ruleNames); } - return new TestFilter(options.testSizeFilterSet, options.testTimeoutFilterSet, - options.testTagFilterList, options.testLangFilterList, testFilter); + return new TestFilter( + ImmutableSet.copyOf(options.testSizeFilterSet), + ImmutableSet.copyOf(options.testTimeoutFilterSet), + ImmutableList.copyOf(options.testTagFilterList), + ImmutableList.copyOf(options.testLangFilterList)); } - private final Set testSizeFilterSet; - private final Set testTimeoutFilterSet; - private final List testTagFilterList; - private final List testLangFilterList; + private final ImmutableSet testSizeFilterSet; + private final ImmutableSet testTimeoutFilterSet; + private final ImmutableList testTagFilterList; + private final ImmutableList testLangFilterList; private final Predicate impl; - private TestFilter(Set testSizeFilterSet, Set testTimeoutFilterSet, - List testTagFilterList, List testLangFilterList, Predicate impl) { + @AutoCodec.VisibleForSerialization + TestFilter( + ImmutableSet testSizeFilterSet, + ImmutableSet testTimeoutFilterSet, + ImmutableList testTagFilterList, + ImmutableList testLangFilterList) { this.testSizeFilterSet = testSizeFilterSet; this.testTimeoutFilterSet = testTimeoutFilterSet; this.testTagFilterList = testTagFilterList; this.testLangFilterList = testLangFilterList; - this.impl = impl; + Predicate testFilter = ALWAYS_TRUE; + if (!testSizeFilterSet.isEmpty()) { + testFilter = testFilter.and(testSizeFilter(testSizeFilterSet)); + } + if (!testTimeoutFilterSet.isEmpty()) { + testFilter = testFilter.and(testTimeoutFilter(testTimeoutFilterSet)); + } + if (!testTagFilterList.isEmpty()) { + testFilter = testFilter.and(TargetUtils.tagFilter(testTagFilterList)); + } + if (!testLangFilterList.isEmpty()) { + testFilter = testFilter.and(testLangFilter(testLangFilterList)); + } + impl = testFilter; } @Override public boolean apply(@Nullable Target input) { - return impl.apply(input); + return impl.test(input); } @Override @@ -95,4 +113,60 @@ public final class TestFilter implements Predicate { && f.testTagFilterList.equals(testTagFilterList) && f.testLangFilterList.equals(testLangFilterList); } + + /** + * Returns a predicate to be used for test size filtering, i.e., that only accepts tests of the + * given size. + */ + @VisibleForTesting + public static Predicate testSizeFilter(final Set allowedSizes) { + return target -> + target instanceof Rule && allowedSizes.contains(TestSize.getTestSize((Rule) target)); + } + + /** + * Returns a predicate to be used for test timeout filtering, i.e., that only accepts tests of the + * given timeout. + */ + @VisibleForTesting + public static Predicate testTimeoutFilter(final Set allowedTimeouts) { + return target -> + target instanceof Rule + && allowedTimeouts.contains(TestTimeout.getTestTimeout((Rule) target)); + } + + /** Check languages specified in --test_lang_filters and warn if any of them are unknown. */ + private static void checkLangFilters( + List langFilterList, ExtendedEventHandler reporter, Set allRuleNames) { + for (String lang : langFilterList) { + if (!allRuleNames.contains(lang + "_test")) { + reporter.handle( + Event.warn("Unknown language '" + lang + "' in --test_lang_filters option")); + } + } + } + + /** + * Returns a predicate to be used for test language filtering, i.e., that only accepts tests of + * the specified languages. + */ + private static Predicate testLangFilter(List langFilterList) { + final Set requiredLangs = new HashSet<>(); + final Set excludedLangs = new HashSet<>(); + + for (String lang : langFilterList) { + if (lang.startsWith("-")) { + lang = lang.substring(1); + excludedLangs.add(lang); + } else { + requiredLangs.add(lang); + } + } + + return rule -> { + String ruleLang = TargetUtils.getRuleLanguage(rule); + return (requiredLangs.isEmpty() || requiredLangs.contains(ruleLang)) + && !excludedLangs.contains(ruleLang); + }; + } } -- cgit v1.2.3