| // Copyright 2018 The Bazel Authors. All rights reserved. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| package com.google.devtools.build.lib.analysis.test; |
| |
| import static com.google.common.collect.ImmutableMap.toImmutableMap; |
| import static com.google.common.collect.ImmutableMultiset.toImmutableMultiset; |
| import static com.google.common.truth.Truth.assertThat; |
| import static com.google.devtools.build.lib.packages.Attribute.attr; |
| import static com.google.devtools.build.lib.packages.BuildType.LABEL_LIST; |
| import static org.junit.Assert.assertThrows; |
| |
| import com.google.common.collect.ImmutableMap; |
| import com.google.common.collect.ImmutableMultiset; |
| import com.google.common.collect.ImmutableSet; |
| import com.google.devtools.build.lib.actions.ActionLookupKey; |
| import com.google.devtools.build.lib.actions.Artifact; |
| import com.google.devtools.build.lib.actions.ArtifactOwner; |
| import com.google.devtools.build.lib.actions.MutableActionGraph.ActionConflictException; |
| import com.google.devtools.build.lib.analysis.BaseRuleClasses; |
| import com.google.devtools.build.lib.analysis.ConfiguredTarget; |
| import com.google.devtools.build.lib.analysis.ConfiguredTargetValue; |
| import com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder; |
| import com.google.devtools.build.lib.analysis.RuleConfiguredTargetFactory; |
| import com.google.devtools.build.lib.analysis.RuleContext; |
| import com.google.devtools.build.lib.analysis.RuleDefinition; |
| import com.google.devtools.build.lib.analysis.Runfiles; |
| import com.google.devtools.build.lib.analysis.RunfilesProvider; |
| import com.google.devtools.build.lib.analysis.RunfilesSupport; |
| import com.google.devtools.build.lib.analysis.ViewCreationFailedException; |
| import com.google.devtools.build.lib.analysis.actions.FileWriteAction; |
| import com.google.devtools.build.lib.analysis.config.ExecutionTransitionFactory; |
| import com.google.devtools.build.lib.analysis.util.AnalysisTestCase; |
| import com.google.devtools.build.lib.analysis.util.MockRule; |
| import com.google.devtools.build.lib.cmdline.Label; |
| import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; |
| import com.google.devtools.build.lib.collect.nestedset.Order; |
| import com.google.devtools.build.lib.packages.RuleClass.Builder.RuleClassType; |
| import com.google.devtools.build.lib.skyframe.ConfiguredTargetKey; |
| import com.google.devtools.build.skyframe.MemoizingEvaluator; |
| import java.util.LinkedHashSet; |
| import java.util.Map; |
| import java.util.Map.Entry; |
| import java.util.Set; |
| import javax.annotation.Nullable; |
| import org.junit.Before; |
| import org.junit.Test; |
| import org.junit.runner.RunWith; |
| import org.junit.runners.JUnit4; |
| |
| /** BUILD-level Tests for test_trim_configuration. */ |
| @RunWith(JUnit4.class) |
| public final class TrimTestConfigurationTest extends AnalysisTestCase { |
| |
| /** Simple native test rule. */ |
| public static final class NativeTest implements RuleConfiguredTargetFactory { |
| @Override |
| @Nullable |
| public ConfiguredTarget create(RuleContext context) |
| throws ActionConflictException, InterruptedException { |
| Artifact executable = context.getBinArtifact(context.getLabel().getName()); |
| context.registerAction(FileWriteAction.create(context, executable, "#!/bin/true", true)); |
| Runfiles runfiles = |
| new Runfiles.Builder(context.getWorkspaceName()).addArtifact(executable).build(); |
| return new RuleConfiguredTargetBuilder(context) |
| .setFilesToBuild(NestedSetBuilder.create(Order.STABLE_ORDER, executable)) |
| .addProvider(RunfilesProvider.class, RunfilesProvider.simple(runfiles)) |
| .setRunfilesSupport( |
| RunfilesSupport.withExecutable(context, runfiles, executable), executable) |
| .build(); |
| } |
| } |
| |
| private static final RuleDefinition NATIVE_TEST_RULE = |
| (MockRule) |
| () -> |
| MockRule.ancestor( |
| BaseRuleClasses.TestBaseRule.class, BaseRuleClasses.NativeBuildRule.class) |
| .factory(NativeTest.class) |
| .type(RuleClassType.TEST) |
| .define( |
| "native_test", |
| attr("deps", LABEL_LIST).allowedFileTypes(), |
| attr("exec_deps", LABEL_LIST) |
| .cfg(ExecutionTransitionFactory.createFactory()) |
| .allowedFileTypes()); |
| |
| private static final RuleDefinition NATIVE_LIB_RULE = |
| (MockRule) |
| () -> |
| MockRule.ancestor(BaseRuleClasses.NativeBuildRule.class) |
| .define( |
| "native_lib", |
| attr("deps", LABEL_LIST).allowedFileTypes(), |
| attr("exec_deps", LABEL_LIST) |
| .cfg(ExecutionTransitionFactory.createFactory()) |
| .allowedFileTypes()); |
| |
| @Before |
| public void setUp() throws Exception { |
| setRulesAvailableInTests(NATIVE_TEST_RULE, NATIVE_LIB_RULE); |
| scratch.file( |
| "test/test.bzl", |
| "def _starlark_test_impl(ctx):", |
| " executable = ctx.actions.declare_file(ctx.label.name)", |
| " ctx.actions.write(executable, '#!/bin/true', is_executable=True)", |
| " return DefaultInfo(", |
| " executable=executable,", |
| " )", |
| "starlark_test = rule(", |
| " implementation = _starlark_test_impl,", |
| " test = True,", |
| " executable = True,", |
| " attrs = {", |
| " 'deps': attr.label_list(),", |
| " 'exec_deps': attr.label_list(cfg='exec'),", |
| " },", |
| ")"); |
| scratch.file( |
| "test/lib.bzl", |
| "def _starlark_lib_impl(ctx):", |
| " pass", |
| "starlark_lib = rule(", |
| " implementation = _starlark_lib_impl,", |
| " attrs = {", |
| " 'deps': attr.label_list(),", |
| " 'exec_deps': attr.label_list(cfg='exec'),", |
| " },", |
| ")"); |
| } |
| |
| private static void assertNumberOfConfigurationsOfTargets( |
| Set<? extends ActionLookupKey> keys, Map<String, Integer> targetsWithCounts) { |
| ImmutableMultiset<Label> actualSet = |
| keys.stream() |
| .filter(key -> key instanceof ConfiguredTargetKey) |
| .map(ArtifactOwner::getLabel) |
| .collect(toImmutableMultiset()); |
| ImmutableMap<Label, Integer> expected = |
| targetsWithCounts.entrySet().stream() |
| .collect( |
| toImmutableMap( |
| entry -> Label.parseCanonicalUnchecked(entry.getKey()), Entry::getValue)); |
| ImmutableMap<Label, Integer> actual = |
| expected.keySet().stream().collect(toImmutableMap(label -> label, actualSet::count)); |
| assertThat(actual).containsExactlyEntriesIn(expected); |
| } |
| |
| @Test |
| public void flagOffDifferentTestOptions_ResultsInDifferentCTs() throws Exception { |
| scratch.file( |
| "test/BUILD", |
| "load(':test.bzl', 'starlark_test')", |
| "load(':lib.bzl', 'starlark_lib')", |
| "test_suite(", |
| " name = 'suite',", |
| " tests = [':native_test', ':starlark_test'],", |
| ")", |
| "native_test(", |
| " name = 'native_test',", |
| " deps = [':native_dep', ':starlark_dep'],", |
| ")", |
| "starlark_test(", |
| " name = 'starlark_test',", |
| " deps = [':native_dep', ':starlark_dep'],", |
| ")", |
| "native_lib(", |
| " name = 'native_dep',", |
| " deps = [':native_shared_dep', 'starlark_shared_dep'],", |
| ")", |
| "starlark_lib(", |
| " name = 'starlark_dep',", |
| " deps = [':native_shared_dep', 'starlark_shared_dep'],", |
| ")", |
| "native_lib(", |
| " name = 'native_shared_dep',", |
| ")", |
| "starlark_lib(", |
| " name = 'starlark_shared_dep',", |
| ")"); |
| useConfiguration("--notrim_test_configuration", "--noexpand_test_suites", "--test_arg=TypeA"); |
| update( |
| "//test:suite", |
| "//test:native_test", |
| "//test:starlark_test", |
| "//test:native_dep", |
| "//test:starlark_dep", |
| "//test:native_shared_dep", |
| "//test:starlark_shared_dep"); |
| LinkedHashSet<ActionLookupKey> visitedTargets = |
| new LinkedHashSet<>(getSkyframeEvaluatedTargetKeys()); |
| // asserting that the top-level targets are the same as the ones in the diamond starting at |
| // //test:suite |
| assertNumberOfConfigurationsOfTargets( |
| visitedTargets, |
| new ImmutableMap.Builder<String, Integer>() |
| .put("//test:suite", 1) |
| .put("//test:native_test", 1) |
| .put("//test:starlark_test", 1) |
| .put("//test:native_dep", 1) |
| .put("//test:starlark_dep", 1) |
| .put("//test:native_shared_dep", 1) |
| .put("//test:starlark_shared_dep", 1) |
| .build()); |
| |
| useConfiguration("--notrim_test_configuration", "--noexpand_test_suites", "--test_arg=TypeB"); |
| update( |
| "//test:suite", |
| "//test:native_test", |
| "//test:starlark_test", |
| "//test:native_dep", |
| "//test:starlark_dep", |
| "//test:native_shared_dep", |
| "//test:starlark_shared_dep"); |
| visitedTargets.addAll(getSkyframeEvaluatedTargetKeys()); |
| // asserting that we got no overlap between the two runs, we had to build different versions of |
| // all seven targets |
| assertNumberOfConfigurationsOfTargets( |
| visitedTargets, |
| new ImmutableMap.Builder<String, Integer>() |
| .put("//test:suite", 2) |
| .put("//test:native_test", 2) |
| .put("//test:starlark_test", 2) |
| .put("//test:native_dep", 2) |
| .put("//test:starlark_dep", 2) |
| .put("//test:native_shared_dep", 2) |
| .put("//test:starlark_shared_dep", 2) |
| .build()); |
| } |
| |
| @Test |
| public void flagOffDifferentTestOptions_CacheCleared() throws Exception { |
| scratch.file( |
| "test/BUILD", |
| "load(':test.bzl', 'starlark_test')", |
| "load(':lib.bzl', 'starlark_lib')", |
| "test_suite(", |
| " name = 'suite',", |
| " tests = [':native_test', ':starlark_test'],", |
| ")", |
| "native_test(", |
| " name = 'native_test',", |
| " deps = [':native_dep', ':starlark_dep'],", |
| ")", |
| "starlark_test(", |
| " name = 'starlark_test',", |
| " deps = [':native_dep', ':starlark_dep'],", |
| ")", |
| "native_lib(", |
| " name = 'native_dep',", |
| " deps = [':native_shared_dep', 'starlark_shared_dep'],", |
| ")", |
| "starlark_lib(", |
| " name = 'starlark_dep',", |
| " deps = [':native_shared_dep', 'starlark_shared_dep'],", |
| ")", |
| "native_lib(", |
| " name = 'native_shared_dep',", |
| ")", |
| "starlark_lib(", |
| " name = 'starlark_shared_dep',", |
| ")"); |
| useConfiguration("--notrim_test_configuration", "--noexpand_test_suites", "--test_arg=TypeA"); |
| update("//test:suite"); |
| useConfiguration("--notrim_test_configuration", "--noexpand_test_suites", "--test_arg=TypeB"); |
| update("//test:suite"); |
| useConfiguration("--notrim_test_configuration", "--noexpand_test_suites", "--test_arg=TypeA"); |
| update("//test:suite"); |
| // asserting that we got no overlap between the first and third runs, we had to reanalyze all |
| // seven targets |
| assertNumberOfConfigurationsOfTargets( |
| getSkyframeEvaluatedTargetKeys(), |
| new ImmutableMap.Builder<String, Integer>() |
| .put("//test:suite", 1) |
| .put("//test:native_test", 1) |
| .put("//test:starlark_test", 1) |
| .put("//test:native_dep", 1) |
| .put("//test:starlark_dep", 1) |
| .put("//test:native_shared_dep", 1) |
| .put("//test:starlark_shared_dep", 1) |
| .build()); |
| } |
| |
| @Test |
| public void flagOnDifferentTestOptions_SharesCTsForNonTestRules() throws Exception { |
| scratch.file( |
| "test/BUILD", |
| "load(':test.bzl', 'starlark_test')", |
| "load(':lib.bzl', 'starlark_lib')", |
| "test_suite(", |
| " name = 'suite',", |
| " tests = [':native_test', ':starlark_test'],", |
| ")", |
| "native_test(", |
| " name = 'native_test',", |
| " deps = [':native_dep', ':starlark_dep'],", |
| ")", |
| "starlark_test(", |
| " name = 'starlark_test',", |
| " deps = [':native_dep', ':starlark_dep'],", |
| ")", |
| "native_lib(", |
| " name = 'native_dep',", |
| " deps = [':native_shared_dep', 'starlark_shared_dep'],", |
| ")", |
| "starlark_lib(", |
| " name = 'starlark_dep',", |
| " deps = [':native_shared_dep', 'starlark_shared_dep'],", |
| ")", |
| "native_lib(", |
| " name = 'native_shared_dep',", |
| ")", |
| "starlark_lib(", |
| " name = 'starlark_shared_dep',", |
| ")"); |
| useConfiguration("--trim_test_configuration", "--noexpand_test_suites", "--test_arg=TypeA"); |
| update( |
| "//test:suite", |
| "//test:native_test", |
| "//test:starlark_test", |
| "//test:native_dep", |
| "//test:starlark_dep", |
| "//test:native_shared_dep", |
| "//test:starlark_shared_dep"); |
| var visitedTargetKeys = new LinkedHashSet<ActionLookupKey>(getEvaluatedTargetValueKeys()); |
| // asserting that the top-level targets are the same as the ones in the diamond starting at |
| // //test:suite |
| assertNumberOfConfigurationsOfTargets( |
| visitedTargetKeys, |
| new ImmutableMap.Builder<String, Integer>() |
| .put("//test:suite", 1) |
| .put("//test:native_test", 1) |
| .put("//test:starlark_test", 1) |
| .put("//test:native_dep", 1) |
| .put("//test:starlark_dep", 1) |
| .put("//test:native_shared_dep", 1) |
| .put("//test:starlark_shared_dep", 1) |
| .build()); |
| |
| useConfiguration("--trim_test_configuration", "--noexpand_test_suites", "--test_arg=TypeB"); |
| update( |
| "//test:suite", |
| "//test:native_test", |
| "//test:starlark_test", |
| "//test:native_dep", |
| "//test:starlark_dep", |
| "//test:native_shared_dep", |
| "//test:starlark_shared_dep"); |
| visitedTargetKeys.addAll(getEvaluatedTargetValueKeys()); |
| |
| // asserting that our non-test rules matched between the two runs, we had to build different |
| // versions of the three test targets but not the four non-test targets |
| assertNumberOfConfigurationsOfTargets( |
| visitedTargetKeys, |
| new ImmutableMap.Builder<String, Integer>() |
| .put("//test:suite", 2) |
| .put("//test:native_test", 2) |
| .put("//test:starlark_test", 2) |
| .put("//test:native_dep", 1) |
| .put("//test:starlark_dep", 1) |
| .put("//test:native_shared_dep", 1) |
| .put("//test:starlark_shared_dep", 1) |
| .build()); |
| } |
| |
| private ImmutableSet<ActionLookupKey> getEvaluatedTargetValueKeys() throws InterruptedException { |
| MemoizingEvaluator evaluator = skyframeExecutor.getEvaluator(); |
| var result = ImmutableSet.<ActionLookupKey>builder(); |
| for (ActionLookupKey key : getSkyframeEvaluatedTargetKeys()) { |
| result.add( |
| ((ConfiguredTargetValue) evaluator.getExistingValue(key)) |
| .getConfiguredTarget() |
| .getLookupKey()); |
| } |
| return result.build(); |
| } |
| |
| @Test |
| public void flagOnDifferentTestOptions_CacheKeptBetweenRuns() throws Exception { |
| scratch.file( |
| "test/BUILD", |
| "load(':test.bzl', 'starlark_test')", |
| "load(':lib.bzl', 'starlark_lib')", |
| "test_suite(", |
| " name = 'suite',", |
| " tests = [':native_test', ':starlark_test'],", |
| ")", |
| "native_test(", |
| " name = 'native_test',", |
| " deps = [':native_dep', ':starlark_dep'],", |
| ")", |
| "starlark_test(", |
| " name = 'starlark_test',", |
| " deps = [':native_dep', ':starlark_dep'],", |
| ")", |
| "native_lib(", |
| " name = 'native_dep',", |
| " deps = [':native_shared_dep', 'starlark_shared_dep'],", |
| ")", |
| "starlark_lib(", |
| " name = 'starlark_dep',", |
| " deps = [':native_shared_dep', 'starlark_shared_dep'],", |
| ")", |
| "native_lib(", |
| " name = 'native_shared_dep',", |
| ")", |
| "starlark_lib(", |
| " name = 'starlark_shared_dep',", |
| ")"); |
| useConfiguration("--trim_test_configuration", "--noexpand_test_suites", "--test_arg=TypeA"); |
| update("//test:suite"); |
| useConfiguration("--trim_test_configuration", "--noexpand_test_suites", "--test_arg=TypeB"); |
| update("//test:suite"); |
| // asserting that the non-test rules were cached from the last run and did not need to be run |
| // again |
| assertNumberOfConfigurationsOfTargets( |
| getSkyframeEvaluatedTargetKeys(), |
| new ImmutableMap.Builder<String, Integer>() |
| .put("//test:native_dep", 0) |
| .put("//test:starlark_dep", 0) |
| .put("//test:native_shared_dep", 0) |
| .put("//test:starlark_shared_dep", 0) |
| .build()); |
| useConfiguration("--trim_test_configuration", "--noexpand_test_suites", "--test_arg=TypeA"); |
| update("//test:suite"); |
| // asserting that the test rules were cached from the first run and did not need to be run again |
| assertNumberOfConfigurationsOfTargets( |
| getSkyframeEvaluatedTargetKeys(), |
| new ImmutableMap.Builder<String, Integer>() |
| .put("//test:suite", 0) |
| .put("//test:native_test", 0) |
| .put("//test:starlark_test", 0) |
| .build()); |
| } |
| |
| @Test |
| public void flagOnDifferentNonTestOptions_CacheCleared() throws Exception { |
| scratch.file( |
| "test/BUILD", |
| "load(':test.bzl', 'starlark_test')", |
| "load(':lib.bzl', 'starlark_lib')", |
| "test_suite(", |
| " name = 'suite',", |
| " tests = [':native_test', ':starlark_test'],", |
| ")", |
| "native_test(", |
| " name = 'native_test',", |
| " deps = [':native_dep', ':starlark_dep'],", |
| ")", |
| "starlark_test(", |
| " name = 'starlark_test',", |
| " deps = [':native_dep', ':starlark_dep'],", |
| ")", |
| "native_lib(", |
| " name = 'native_dep',", |
| " deps = [':native_shared_dep', 'starlark_shared_dep'],", |
| ")", |
| "starlark_lib(", |
| " name = 'starlark_dep',", |
| " deps = [':native_shared_dep', 'starlark_shared_dep'],", |
| ")", |
| "native_lib(", |
| " name = 'native_shared_dep',", |
| ")", |
| "starlark_lib(", |
| " name = 'starlark_shared_dep',", |
| ")"); |
| useConfiguration("--trim_test_configuration", "--noexpand_test_suites", "--define=Test=TypeA"); |
| update("//test:suite"); |
| useConfiguration("--trim_test_configuration", "--noexpand_test_suites", "--define=Test=TypeB"); |
| update("//test:suite"); |
| useConfiguration("--trim_test_configuration", "--noexpand_test_suites", "--define=Test=TypeA"); |
| update("//test:suite"); |
| // asserting that we got no overlap between the first and third runs, we had to reanalyze all |
| // seven targets |
| assertNumberOfConfigurationsOfTargets( |
| getSkyframeEvaluatedTargetKeys(), |
| new ImmutableMap.Builder<String, Integer>() |
| .put("//test:suite", 1) |
| .put("//test:native_test", 1) |
| .put("//test:starlark_test", 1) |
| .put("//test:native_dep", 1) |
| .put("//test:starlark_dep", 1) |
| .put("//test:native_shared_dep", 1) |
| .put("//test:starlark_shared_dep", 1) |
| .build()); |
| } |
| |
| @Test |
| public void flagOffToOn_CacheCleared() throws Exception { |
| scratch.file( |
| "test/BUILD", |
| "load(':test.bzl', 'starlark_test')", |
| "load(':lib.bzl', 'starlark_lib')", |
| "test_suite(", |
| " name = 'suite',", |
| " tests = [':native_test', ':starlark_test'],", |
| ")", |
| "native_test(", |
| " name = 'native_test',", |
| " deps = [':native_dep', ':starlark_dep'],", |
| ")", |
| "starlark_test(", |
| " name = 'starlark_test',", |
| " deps = [':native_dep', ':starlark_dep'],", |
| ")", |
| "native_lib(", |
| " name = 'native_dep',", |
| " deps = [':native_shared_dep', 'starlark_shared_dep'],", |
| ")", |
| "starlark_lib(", |
| " name = 'starlark_dep',", |
| " deps = [':native_shared_dep', 'starlark_shared_dep'],", |
| ")", |
| "native_lib(", |
| " name = 'native_shared_dep',", |
| ")", |
| "starlark_lib(", |
| " name = 'starlark_shared_dep',", |
| ")"); |
| useConfiguration("--notrim_test_configuration", "--noexpand_test_suites"); |
| update("//test:suite"); |
| useConfiguration("--trim_test_configuration", "--noexpand_test_suites"); |
| update("//test:suite"); |
| // asserting that we got no overlap between the first and second runs, we had to reanalyze all |
| // seven targets |
| assertNumberOfConfigurationsOfTargets( |
| getSkyframeEvaluatedTargetKeys(), |
| new ImmutableMap.Builder<String, Integer>() |
| .put("//test:suite", 1) |
| .put("//test:native_test", 1) |
| .put("//test:starlark_test", 1) |
| .put("//test:native_dep", 1) |
| .put("//test:starlark_dep", 1) |
| .put("//test:native_shared_dep", 1) |
| .put("//test:starlark_shared_dep", 1) |
| .build()); |
| } |
| |
| @Test |
| public void flagOnToOff_CacheCleared() throws Exception { |
| scratch.file( |
| "test/BUILD", |
| "load(':test.bzl', 'starlark_test')", |
| "load(':lib.bzl', 'starlark_lib')", |
| "test_suite(", |
| " name = 'suite',", |
| " tests = [':native_test', ':starlark_test'],", |
| ")", |
| "native_test(", |
| " name = 'native_test',", |
| " deps = [':native_dep', ':starlark_dep'],", |
| ")", |
| "starlark_test(", |
| " name = 'starlark_test',", |
| " deps = [':native_dep', ':starlark_dep'],", |
| ")", |
| "native_lib(", |
| " name = 'native_dep',", |
| " deps = [':native_shared_dep', 'starlark_shared_dep'],", |
| ")", |
| "starlark_lib(", |
| " name = 'starlark_dep',", |
| " deps = [':native_shared_dep', 'starlark_shared_dep'],", |
| ")", |
| "native_lib(", |
| " name = 'native_shared_dep',", |
| ")", |
| "starlark_lib(", |
| " name = 'starlark_shared_dep',", |
| ")"); |
| useConfiguration("--trim_test_configuration", "--noexpand_test_suites"); |
| update("//test:suite"); |
| useConfiguration("--notrim_test_configuration", "--noexpand_test_suites"); |
| update("//test:suite"); |
| // asserting that we got no overlap between the first and second runs, we had to reanalyze all |
| // seven targets |
| assertNumberOfConfigurationsOfTargets( |
| getSkyframeEvaluatedTargetKeys(), |
| new ImmutableMap.Builder<String, Integer>() |
| .put("//test:suite", 1) |
| .put("//test:native_test", 1) |
| .put("//test:starlark_test", 1) |
| .put("//test:native_dep", 1) |
| .put("//test:starlark_dep", 1) |
| .put("//test:native_shared_dep", 1) |
| .put("//test:starlark_shared_dep", 1) |
| .build()); |
| } |
| |
| @Test |
| public void flagOnDynamicConfigsNotrimExecDeps_AreNotAnalyzedAnyExtraTimes() throws Exception { |
| scratch.file( |
| "test/BUILD", |
| "load(':test.bzl', 'starlark_test')", |
| "load(':lib.bzl', 'starlark_lib')", |
| "native_test(", |
| " name = 'native_outer_test',", |
| " deps = [':native_test', ':starlark_test'],", |
| " exec_deps = [':native_test', ':starlark_test'],", |
| ")", |
| "starlark_test(", |
| " name = 'starlark_outer_test',", |
| " deps = [':native_test', ':starlark_test'],", |
| " exec_deps = [':native_test', ':starlark_test'],", |
| ")", |
| "native_test(", |
| " name = 'native_test',", |
| " deps = [':native_dep', ':starlark_dep'],", |
| " exec_deps = [':native_dep', ':starlark_dep'],", |
| ")", |
| "starlark_test(", |
| " name = 'starlark_test',", |
| " deps = [':native_dep', ':starlark_dep'],", |
| " exec_deps = [':native_dep', ':starlark_dep'],", |
| ")", |
| "native_lib(", |
| " name = 'native_dep',", |
| " deps = [':native_shared_dep', 'starlark_shared_dep'],", |
| " exec_deps = [':native_shared_dep', 'starlark_shared_dep'],", |
| ")", |
| "starlark_lib(", |
| " name = 'starlark_dep',", |
| " deps = [':native_shared_dep', 'starlark_shared_dep'],", |
| " exec_deps = [':native_shared_dep', 'starlark_shared_dep'],", |
| ")", |
| "native_lib(", |
| " name = 'native_shared_dep',", |
| ")", |
| "starlark_lib(", |
| " name = 'starlark_shared_dep',", |
| ")"); |
| useConfiguration("--trim_test_configuration"); |
| update( |
| "//test:native_outer_test", |
| "//test:starlark_outer_test", |
| "//test:native_test", |
| "//test:starlark_test", |
| "//test:native_dep", |
| "//test:starlark_dep", |
| "//test:native_shared_dep", |
| "//test:starlark_shared_dep"); |
| LinkedHashSet<ActionLookupKey> visitedTargets = |
| new LinkedHashSet<>(getSkyframeEvaluatedTargetKeys()); |
| assertNumberOfConfigurationsOfTargets( |
| visitedTargets, |
| new ImmutableMap.Builder<String, Integer>() |
| // Top-level and exec. |
| .put("//test:native_test", 2) |
| .put("//test:starlark_test", 2) |
| // Target and exec. |
| .put("//test:native_dep", 2) |
| .put("//test:starlark_dep", 2) |
| .put("//test:native_shared_dep", 2) |
| .put("//test:starlark_shared_dep", 2) |
| .build()); |
| } |
| |
| @Test |
| public void flagOffConfigSetting_CanInspectTestOptions() throws Exception { |
| scratch.file( |
| "test/BUILD", |
| "load(':test.bzl', 'starlark_test')", |
| "load(':lib.bzl', 'starlark_lib')", |
| "config_setting(", |
| " name = 'test_mode',", |
| " values = {'test_arg': 'TypeA'},", |
| ")", |
| "starlark_test(", |
| " name = 'starlark_test',", |
| " deps = select({':test_mode': [':starlark_shared_dep'], '//conditions:default': []})", |
| ")", |
| "starlark_lib(", |
| " name = 'starlark_dep',", |
| " deps = select({':test_mode': [':starlark_shared_dep'], '//conditions:default': []})", |
| ")", |
| "starlark_lib(", |
| " name = 'starlark_shared_dep',", |
| ")"); |
| useConfiguration("--notrim_test_configuration", "--noexpand_test_suites", "--test_arg=TypeA"); |
| update("//test:test_mode", "//test:starlark_test", "//test:starlark_dep"); |
| // All 3 targets (top level, under a test, under a non-test) should successfully analyze. |
| assertThat(getAnalysisResult().getTargetsToBuild()).hasSize(3); |
| } |
| |
| @Test |
| public void flagOnConfigSetting_FailsTryingToInspectTestOptions() throws Exception { |
| reporter.removeHandler(failFastHandler); |
| scratch.file( |
| "test/BUILD", |
| "load(':test.bzl', 'starlark_test')", |
| "load(':lib.bzl', 'starlark_lib')", |
| "config_setting(", |
| " name = 'test_mode',", |
| " values = {'test_arg': 'TypeA'},", |
| ")", |
| "starlark_test(", |
| " name = 'starlark_test',", |
| " deps = select({':test_mode': [':starlark_shared_dep'], '//conditions:default': []})", |
| ")", |
| "starlark_lib(", |
| " name = 'starlark_dep',", |
| " deps = select({':test_mode': [':starlark_shared_dep'], '//conditions:default': []})", |
| ")", |
| "starlark_lib(", |
| " name = 'starlark_shared_dep',", |
| ")"); |
| useConfiguration("--trim_test_configuration", "--noexpand_test_suites", "--test_arg=TypeA"); |
| assertThrows(ViewCreationFailedException.class, () -> update("//test:starlark_dep")); |
| assertContainsEvent("unknown option: 'test_arg'"); |
| |
| update("//test:test_mode", "//test:starlark_test"); |
| // When reached through only test targets (top level, under a test) analysis should succeed |
| assertThat(getAnalysisResult().getTargetsToBuild()).hasSize(2); |
| } |
| |
| @Test |
| public void flagOffNonTestTargetWithTestDependencies_IsPermitted() throws Exception { |
| scratch.file( |
| "test/BUILD", |
| "load(':test.bzl', 'starlark_test')", |
| "load(':lib.bzl', 'starlark_lib')", |
| "starlark_lib(", |
| " name = 'starlark_dep',", |
| " deps = [':starlark_test'],", |
| " testonly = 1,", |
| ")", |
| "starlark_test(", |
| " name = 'starlark_test',", |
| ")"); |
| useConfiguration("--notrim_test_configuration", "--noexpand_test_suites", "--test_arg=TypeA"); |
| update("//test:starlark_dep"); |
| assertThat(getAnalysisResult().getTargetsToBuild()).isNotEmpty(); |
| } |
| |
| @Test |
| public void flagOnNonTestTargetWithTestDependencies_IsPermitted() throws Exception { |
| reporter.removeHandler(failFastHandler); |
| scratch.file( |
| "test/BUILD", |
| "load(':test.bzl', 'starlark_test')", |
| "load(':lib.bzl', 'starlark_lib')", |
| "starlark_lib(", |
| " name = 'starlark_dep',", |
| " deps = [':starlark_test'],", |
| " testonly = 1,", |
| ")", |
| "starlark_test(", |
| " name = 'starlark_test',", |
| ")"); |
| useConfiguration("--trim_test_configuration", "--noexpand_test_suites", "--test_arg=TypeA"); |
| update("//test:starlark_dep"); |
| assertThat(getAnalysisResult().getTargetsToBuild()).isNotEmpty(); |
| } |
| |
| @Test |
| public void flagOnNonTestTargetWithTestSuiteDependencies_IsPermitted() throws Exception { |
| // reporter.removeHandler(failFastHandler); |
| scratch.file( |
| "test/BUILD", |
| "load(':test.bzl', 'starlark_test')", |
| "load(':lib.bzl', 'starlark_lib')", |
| "starlark_lib(", |
| " name = 'starlark_dep',", |
| " deps = [':a_test_suite'],", |
| " testonly = 1,", |
| ")", |
| "starlark_test(", |
| " name = 'starlark_test',", |
| ")", |
| "test_suite(", |
| " name = 'a_test_suite',", |
| " tests = [':starlark_test'],", |
| ")"); |
| useConfiguration("--trim_test_configuration", "--noexpand_test_suites", "--test_arg=TypeA"); |
| update("//test:starlark_dep"); |
| assertThat(getAnalysisResult().getTargetsToBuild()).isNotEmpty(); |
| } |
| |
| @Test |
| public void flagOnNonTestTargetWithJavaTestDependencies_IsPermitted() throws Exception { |
| // reporter.removeHandler(failFastHandler); |
| scratch.file( |
| "test/BUILD", |
| "load(':lib.bzl', 'starlark_lib')", |
| "starlark_lib(", |
| " name = 'starlark_dep',", |
| " deps = [':JavaTest'],", |
| " testonly = 1,", |
| ")", |
| "java_test(", |
| " name = 'JavaTest',", |
| " srcs = ['JavaTest.java'],", |
| " test_class = 'test.JavaTest',", |
| ")"); |
| useConfiguration( |
| "--trim_test_configuration", |
| "--noexpand_test_suites", |
| "--test_arg=TypeA", |
| "--experimental_google_legacy_api"); |
| update("//test:starlark_dep"); |
| assertThat(getAnalysisResult().getTargetsToBuild()).isNotEmpty(); |
| } |
| |
| @Test |
| public void flagOnTestSuiteWithTestDependencies_CanBeAnalyzed() throws Exception { |
| scratch.file( |
| "test/BUILD", |
| "load(':test.bzl', 'starlark_test')", |
| "load(':lib.bzl', 'starlark_lib')", |
| "test_suite(", |
| " name = 'suite',", |
| " tests = [':starlark_test', ':suite_2'],", |
| ")", |
| "test_suite(", |
| " name = 'suite_2',", |
| " tests = [':starlark_test_2', ':starlark_test_3'],", |
| ")", |
| "starlark_test(", |
| " name = 'starlark_test',", |
| ")", |
| "starlark_test(", |
| " name = 'starlark_test_2',", |
| ")", |
| "starlark_test(", |
| " name = 'starlark_test_3',", |
| ")"); |
| useConfiguration("--trim_test_configuration", "--noexpand_test_suites", "--test_arg=TypeA"); |
| update("//test:suite", "//test:suite_2"); |
| assertThat(getAnalysisResult().getTargetsToBuild()).hasSize(2); |
| } |
| |
| @Test |
| public void flagOnNonTestTargetWithTestDependencies_isTrimmed() throws Exception { |
| scratch.file( |
| "test/BUILD", |
| "load(':test.bzl', 'starlark_test')", |
| "load(':lib.bzl', 'starlark_lib')", |
| "starlark_lib(", |
| " name = 'starlark_dep',", |
| " deps = [':starlark_test'],", |
| " testonly = 1,", |
| ")", |
| "starlark_test(", |
| " name = 'starlark_test',", |
| ")"); |
| useConfiguration( |
| "--trim_test_configuration", "--noexperimental_retain_test_configuration_across_testonly"); |
| update("//test:starlark_dep"); |
| ConfiguredTarget top = getConfiguredTarget("//test:starlark_dep"); |
| assertThat(getConfiguration(top).hasFragment(TestConfiguration.class)).isFalse(); |
| } |
| |
| @Test |
| public void flagOnNonTestTargetWithTestDependencies_isNotTrimmedWithExperimentalFlag() |
| throws Exception { |
| scratch.file( |
| "test/BUILD", |
| "load(':test.bzl', 'starlark_test')", |
| "load(':lib.bzl', 'starlark_lib')", |
| "starlark_lib(", |
| " name = 'starlark_dep',", |
| " deps = [':starlark_test'],", |
| " testonly = 1,", |
| ")", |
| "starlark_test(", |
| " name = 'starlark_test',", |
| ")"); |
| useConfiguration( |
| "--trim_test_configuration", "--experimental_retain_test_configuration_across_testonly"); |
| update("//test:starlark_dep"); |
| ConfiguredTarget top = getConfiguredTarget("//test:starlark_dep"); |
| assertThat(getConfiguration(top).hasFragment(TestConfiguration.class)).isTrue(); |
| } |
| |
| @Test |
| public void flagOnNonTestTargetWithMagicTransitiveConfigs_isNotTrimmed() throws Exception { |
| scratch.file( |
| "test/BUILD", |
| "load(':test.bzl', 'starlark_test')", |
| "load(':lib.bzl', 'starlark_lib')", |
| "starlark_lib(", |
| " name = 'starlark_dep',", |
| " deps = [],", |
| " testonly = 1,", |
| " transitive_configs = ['//command_line_option/fragment:test'],", |
| ")"); |
| useConfiguration("--trim_test_configuration"); |
| update("//test:starlark_dep"); |
| ConfiguredTarget top = getConfiguredTarget("//test:starlark_dep"); |
| assertThat(getConfiguration(top).hasFragment(TestConfiguration.class)).isTrue(); |
| } |
| } |