blob: ca3e57bd5a015f0a6899c0208e9f002b9eb5d383 [file] [log] [blame]
// 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.devtools.build.lib.actions.Artifact;
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.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.HostTransition;
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.SkyKey;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
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
public ConfiguredTarget create(RuleContext context) throws ActionConflictException {
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))
.add(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.BaseRule.class)
.factory(NativeTest.class)
.type(RuleClassType.TEST)
.define(
"native_test",
attr("deps", LABEL_LIST).allowedFileTypes(),
attr("host_deps", LABEL_LIST)
.cfg(HostTransition.createFactory())
.allowedFileTypes());
private static final RuleDefinition NATIVE_LIB_RULE =
(MockRule)
() ->
MockRule.ancestor(BaseRuleClasses.BaseRule.class)
.define(
"native_lib",
attr("deps", LABEL_LIST).allowedFileTypes(),
attr("host_deps", LABEL_LIST)
.cfg(HostTransition.createFactory())
.allowedFileTypes());
@Before
public void setUp() throws Exception {
setRulesAvailableInTests(NATIVE_TEST_RULE, NATIVE_LIB_RULE);
scratch.file(
"test/test.bzl",
"def _skylark_test_impl(ctx):",
" executable = ctx.actions.declare_file(ctx.label.name)",
" ctx.actions.write(executable, '#!/bin/true', is_executable=True)",
" return DefaultInfo(",
" executable=executable,",
" )",
"skylark_test = rule(",
" implementation = _skylark_test_impl,",
" test = True,",
" executable = True,",
" attrs = {",
" 'deps': attr.label_list(),",
" 'host_deps': attr.label_list(cfg='host'),",
" },",
")");
scratch.file(
"test/lib.bzl",
"def _skylark_lib_impl(ctx):",
" pass",
"skylark_lib = rule(",
" implementation = _skylark_lib_impl,",
" attrs = {",
" 'deps': attr.label_list(),",
" 'host_deps': attr.label_list(cfg='host'),",
" },",
")");
}
private void assertNumberOfConfigurationsOfTargets(
Set<SkyKey> keys, Map<String, Integer> targetsWithCounts) {
ImmutableMultiset<Label> actualSet =
keys.stream()
.filter(key -> key instanceof ConfiguredTargetKey)
.map(key -> ((ConfiguredTargetKey) key).getLabel())
.collect(toImmutableMultiset());
ImmutableMap<Label, Integer> expected =
targetsWithCounts
.entrySet()
.stream()
.collect(
toImmutableMap(
entry -> Label.parseAbsoluteUnchecked(entry.getKey()),
entry -> entry.getValue()));
ImmutableMap<Label, Integer> actual =
expected
.keySet()
.stream()
.collect(toImmutableMap(label -> label, label -> actualSet.count(label)));
assertThat(actual).containsExactlyEntriesIn(expected);
}
@Test
public void flagOffDifferentTestOptions_ResultsInDifferentCTs() throws Exception {
scratch.file(
"test/BUILD",
"load(':test.bzl', 'skylark_test')",
"load(':lib.bzl', 'skylark_lib')",
"test_suite(",
" name = 'suite',",
" tests = [':native_test', ':skylark_test'],",
")",
"native_test(",
" name = 'native_test',",
" deps = [':native_dep', ':skylark_dep'],",
")",
"skylark_test(",
" name = 'skylark_test',",
" deps = [':native_dep', ':skylark_dep'],",
")",
"native_lib(",
" name = 'native_dep',",
" deps = [':native_shared_dep', 'skylark_shared_dep'],",
")",
"skylark_lib(",
" name = 'skylark_dep',",
" deps = [':native_shared_dep', 'skylark_shared_dep'],",
")",
"native_lib(",
" name = 'native_shared_dep',",
")",
"skylark_lib(",
" name = 'skylark_shared_dep',",
")");
useConfiguration("--notrim_test_configuration", "--noexpand_test_suites", "--test_arg=TypeA");
update(
"//test:suite",
"//test:native_test",
"//test:skylark_test",
"//test:native_dep",
"//test:skylark_dep",
"//test:native_shared_dep",
"//test:skylark_shared_dep");
LinkedHashSet<SkyKey> 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:skylark_test", 1)
.put("//test:native_dep", 1)
.put("//test:skylark_dep", 1)
.put("//test:native_shared_dep", 1)
.put("//test:skylark_shared_dep", 1)
.build());
useConfiguration("--notrim_test_configuration", "--noexpand_test_suites", "--test_arg=TypeB");
update(
"//test:suite",
"//test:native_test",
"//test:skylark_test",
"//test:native_dep",
"//test:skylark_dep",
"//test:native_shared_dep",
"//test:skylark_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:skylark_test", 2)
.put("//test:native_dep", 2)
.put("//test:skylark_dep", 2)
.put("//test:native_shared_dep", 2)
.put("//test:skylark_shared_dep", 2)
.build());
}
@Test
public void flagOffDifferentTestOptions_CacheCleared() throws Exception {
scratch.file(
"test/BUILD",
"load(':test.bzl', 'skylark_test')",
"load(':lib.bzl', 'skylark_lib')",
"test_suite(",
" name = 'suite',",
" tests = [':native_test', ':skylark_test'],",
")",
"native_test(",
" name = 'native_test',",
" deps = [':native_dep', ':skylark_dep'],",
")",
"skylark_test(",
" name = 'skylark_test',",
" deps = [':native_dep', ':skylark_dep'],",
")",
"native_lib(",
" name = 'native_dep',",
" deps = [':native_shared_dep', 'skylark_shared_dep'],",
")",
"skylark_lib(",
" name = 'skylark_dep',",
" deps = [':native_shared_dep', 'skylark_shared_dep'],",
")",
"native_lib(",
" name = 'native_shared_dep',",
")",
"skylark_lib(",
" name = 'skylark_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:skylark_test", 1)
.put("//test:native_dep", 1)
.put("//test:skylark_dep", 1)
.put("//test:native_shared_dep", 1)
.put("//test:skylark_shared_dep", 1)
.build());
}
@Test
public void flagOnDifferentTestOptions_SharesCTsForNonTestRules() throws Exception {
scratch.file(
"test/BUILD",
"load(':test.bzl', 'skylark_test')",
"load(':lib.bzl', 'skylark_lib')",
"test_suite(",
" name = 'suite',",
" tests = [':native_test', ':skylark_test'],",
")",
"native_test(",
" name = 'native_test',",
" deps = [':native_dep', ':skylark_dep'],",
")",
"skylark_test(",
" name = 'skylark_test',",
" deps = [':native_dep', ':skylark_dep'],",
")",
"native_lib(",
" name = 'native_dep',",
" deps = [':native_shared_dep', 'skylark_shared_dep'],",
")",
"skylark_lib(",
" name = 'skylark_dep',",
" deps = [':native_shared_dep', 'skylark_shared_dep'],",
")",
"native_lib(",
" name = 'native_shared_dep',",
")",
"skylark_lib(",
" name = 'skylark_shared_dep',",
")");
useConfiguration("--trim_test_configuration", "--noexpand_test_suites", "--test_arg=TypeA");
update(
"//test:suite",
"//test:native_test",
"//test:skylark_test",
"//test:native_dep",
"//test:skylark_dep",
"//test:native_shared_dep",
"//test:skylark_shared_dep");
LinkedHashSet<SkyKey> 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:skylark_test", 1)
.put("//test:native_dep", 1)
.put("//test:skylark_dep", 1)
.put("//test:native_shared_dep", 1)
.put("//test:skylark_shared_dep", 1)
.build());
useConfiguration("--trim_test_configuration", "--noexpand_test_suites", "--test_arg=TypeB");
update(
"//test:suite",
"//test:native_test",
"//test:skylark_test",
"//test:native_dep",
"//test:skylark_dep",
"//test:native_shared_dep",
"//test:skylark_shared_dep");
visitedTargets.addAll(getSkyframeEvaluatedTargetKeys());
// 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(
visitedTargets,
new ImmutableMap.Builder<String, Integer>()
.put("//test:suite", 2)
.put("//test:native_test", 2)
.put("//test:skylark_test", 2)
.put("//test:native_dep", 1)
.put("//test:skylark_dep", 1)
.put("//test:native_shared_dep", 1)
.put("//test:skylark_shared_dep", 1)
.build());
}
@Test
public void flagOnDifferentTestOptions_CacheKeptBetweenRuns() throws Exception {
scratch.file(
"test/BUILD",
"load(':test.bzl', 'skylark_test')",
"load(':lib.bzl', 'skylark_lib')",
"test_suite(",
" name = 'suite',",
" tests = [':native_test', ':skylark_test'],",
")",
"native_test(",
" name = 'native_test',",
" deps = [':native_dep', ':skylark_dep'],",
")",
"skylark_test(",
" name = 'skylark_test',",
" deps = [':native_dep', ':skylark_dep'],",
")",
"native_lib(",
" name = 'native_dep',",
" deps = [':native_shared_dep', 'skylark_shared_dep'],",
")",
"skylark_lib(",
" name = 'skylark_dep',",
" deps = [':native_shared_dep', 'skylark_shared_dep'],",
")",
"native_lib(",
" name = 'native_shared_dep',",
")",
"skylark_lib(",
" name = 'skylark_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:skylark_dep", 0)
.put("//test:native_shared_dep", 0)
.put("//test:skylark_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:skylark_test", 0)
.build());
}
@Test
public void flagOnDifferentNonTestOptions_CacheCleared() throws Exception {
scratch.file(
"test/BUILD",
"load(':test.bzl', 'skylark_test')",
"load(':lib.bzl', 'skylark_lib')",
"test_suite(",
" name = 'suite',",
" tests = [':native_test', ':skylark_test'],",
")",
"native_test(",
" name = 'native_test',",
" deps = [':native_dep', ':skylark_dep'],",
")",
"skylark_test(",
" name = 'skylark_test',",
" deps = [':native_dep', ':skylark_dep'],",
")",
"native_lib(",
" name = 'native_dep',",
" deps = [':native_shared_dep', 'skylark_shared_dep'],",
")",
"skylark_lib(",
" name = 'skylark_dep',",
" deps = [':native_shared_dep', 'skylark_shared_dep'],",
")",
"native_lib(",
" name = 'native_shared_dep',",
")",
"skylark_lib(",
" name = 'skylark_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:skylark_test", 1)
.put("//test:native_dep", 1)
.put("//test:skylark_dep", 1)
.put("//test:native_shared_dep", 1)
.put("//test:skylark_shared_dep", 1)
.build());
}
@Test
public void flagOffToOn_CacheCleared() throws Exception {
scratch.file(
"test/BUILD",
"load(':test.bzl', 'skylark_test')",
"load(':lib.bzl', 'skylark_lib')",
"test_suite(",
" name = 'suite',",
" tests = [':native_test', ':skylark_test'],",
")",
"native_test(",
" name = 'native_test',",
" deps = [':native_dep', ':skylark_dep'],",
")",
"skylark_test(",
" name = 'skylark_test',",
" deps = [':native_dep', ':skylark_dep'],",
")",
"native_lib(",
" name = 'native_dep',",
" deps = [':native_shared_dep', 'skylark_shared_dep'],",
")",
"skylark_lib(",
" name = 'skylark_dep',",
" deps = [':native_shared_dep', 'skylark_shared_dep'],",
")",
"native_lib(",
" name = 'native_shared_dep',",
")",
"skylark_lib(",
" name = 'skylark_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:skylark_test", 1)
.put("//test:native_dep", 1)
.put("//test:skylark_dep", 1)
.put("//test:native_shared_dep", 1)
.put("//test:skylark_shared_dep", 1)
.build());
}
@Test
public void flagOnToOff_CacheCleared() throws Exception {
scratch.file(
"test/BUILD",
"load(':test.bzl', 'skylark_test')",
"load(':lib.bzl', 'skylark_lib')",
"test_suite(",
" name = 'suite',",
" tests = [':native_test', ':skylark_test'],",
")",
"native_test(",
" name = 'native_test',",
" deps = [':native_dep', ':skylark_dep'],",
")",
"skylark_test(",
" name = 'skylark_test',",
" deps = [':native_dep', ':skylark_dep'],",
")",
"native_lib(",
" name = 'native_dep',",
" deps = [':native_shared_dep', 'skylark_shared_dep'],",
")",
"skylark_lib(",
" name = 'skylark_dep',",
" deps = [':native_shared_dep', 'skylark_shared_dep'],",
")",
"native_lib(",
" name = 'native_shared_dep',",
")",
"skylark_lib(",
" name = 'skylark_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:skylark_test", 1)
.put("//test:native_dep", 1)
.put("//test:skylark_dep", 1)
.put("//test:native_shared_dep", 1)
.put("//test:skylark_shared_dep", 1)
.build());
}
@Test
public void flagOnDynamicConfigsNotrimHostDeps_AreNotAnalyzedAnyExtraTimes() throws Exception {
scratch.file(
"test/BUILD",
"load(':test.bzl', 'skylark_test')",
"load(':lib.bzl', 'skylark_lib')",
"native_test(",
" name = 'native_outer_test',",
" deps = [':native_test', ':skylark_test'],",
" host_deps = [':native_test', ':skylark_test'],",
")",
"skylark_test(",
" name = 'skylark_outer_test',",
" deps = [':native_test', ':skylark_test'],",
" host_deps = [':native_test', ':skylark_test'],",
")",
"native_test(",
" name = 'native_test',",
" deps = [':native_dep', ':skylark_dep'],",
" host_deps = [':native_dep', ':skylark_dep'],",
")",
"skylark_test(",
" name = 'skylark_test',",
" deps = [':native_dep', ':skylark_dep'],",
" host_deps = [':native_dep', ':skylark_dep'],",
")",
"native_lib(",
" name = 'native_dep',",
" deps = [':native_shared_dep', 'skylark_shared_dep'],",
" host_deps = [':native_shared_dep', 'skylark_shared_dep'],",
")",
"skylark_lib(",
" name = 'skylark_dep',",
" deps = [':native_shared_dep', 'skylark_shared_dep'],",
" host_deps = [':native_shared_dep', 'skylark_shared_dep'],",
")",
"native_lib(",
" name = 'native_shared_dep',",
")",
"skylark_lib(",
" name = 'skylark_shared_dep',",
")");
useConfiguration("--trim_test_configuration", "--experimental_dynamic_configs=notrim");
update(
"//test:native_outer_test",
"//test:skylark_outer_test",
"//test:native_test",
"//test:skylark_test",
"//test:native_dep",
"//test:skylark_dep",
"//test:native_shared_dep",
"//test:skylark_shared_dep");
LinkedHashSet<SkyKey> visitedTargets = new LinkedHashSet<>(getSkyframeEvaluatedTargetKeys());
assertNumberOfConfigurationsOfTargets(
visitedTargets,
new ImmutableMap.Builder<String, Integer>()
// each target should be analyzed in two and only two configurations: target and host
// there should not be a "host trimmed" and "host untrimmed" version
.put("//test:native_test", 2)
.put("//test:skylark_test", 2)
.put("//test:native_dep", 2)
.put("//test:skylark_dep", 2)
.put("//test:native_shared_dep", 2)
.put("//test:skylark_shared_dep", 2)
.build());
}
@Test
public void flagOffConfigSetting_CanInspectTestOptions() throws Exception {
scratch.file(
"test/BUILD",
"load(':test.bzl', 'skylark_test')",
"load(':lib.bzl', 'skylark_lib')",
"config_setting(",
" name = 'test_mode',",
" values = {'test_arg': 'TypeA'},",
")",
"skylark_test(",
" name = 'skylark_test',",
" deps = select({':test_mode': [':skylark_shared_dep'], '//conditions:default': []})",
")",
"skylark_lib(",
" name = 'skylark_dep',",
" deps = select({':test_mode': [':skylark_shared_dep'], '//conditions:default': []})",
")",
"skylark_lib(",
" name = 'skylark_shared_dep',",
")");
useConfiguration("--notrim_test_configuration", "--noexpand_test_suites", "--test_arg=TypeA");
update("//test:test_mode", "//test:skylark_test", "//test:skylark_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', 'skylark_test')",
"load(':lib.bzl', 'skylark_lib')",
"config_setting(",
" name = 'test_mode',",
" values = {'test_arg': 'TypeA'},",
")",
"skylark_test(",
" name = 'skylark_test',",
" deps = select({':test_mode': [':skylark_shared_dep'], '//conditions:default': []})",
")",
"skylark_lib(",
" name = 'skylark_dep',",
" deps = select({':test_mode': [':skylark_shared_dep'], '//conditions:default': []})",
")",
"skylark_lib(",
" name = 'skylark_shared_dep',",
")");
useConfiguration("--trim_test_configuration", "--noexpand_test_suites", "--test_arg=TypeA");
assertThrows(ViewCreationFailedException.class, () -> update("//test:skylark_dep"));
assertContainsEvent("unknown option: 'test_arg'");
update("//test:test_mode", "//test:skylark_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', 'skylark_test')",
"load(':lib.bzl', 'skylark_lib')",
"skylark_lib(",
" name = 'skylark_dep',",
" deps = [':skylark_test'],",
" testonly = 1,",
")",
"skylark_test(",
" name = 'skylark_test',",
")");
useConfiguration("--notrim_test_configuration", "--noexpand_test_suites", "--test_arg=TypeA");
update("//test:skylark_dep");
assertThat(getAnalysisResult().getTargetsToBuild()).isNotEmpty();
}
@Test
public void flagOnNonTestTargetWithTestDependencies_FailsAnalysis() throws Exception {
reporter.removeHandler(failFastHandler);
scratch.file(
"test/BUILD",
"load(':test.bzl', 'skylark_test')",
"load(':lib.bzl', 'skylark_lib')",
"skylark_lib(",
" name = 'skylark_dep',",
" deps = [':skylark_test'],",
" testonly = 1,",
")",
"skylark_test(",
" name = 'skylark_test',",
")");
useConfiguration("--trim_test_configuration", "--noexpand_test_suites", "--test_arg=TypeA");
assertThrows(ViewCreationFailedException.class, () -> update("//test:skylark_dep"));
assertContainsEvent(
"all rules of type skylark_test require the presence of all of "
+ "[TestConfiguration], but these were all disabled");
}
@Test
public void flagOnTestSuiteWithTestDependencies_CanBeAnalyzed() throws Exception {
scratch.file(
"test/BUILD",
"load(':test.bzl', 'skylark_test')",
"load(':lib.bzl', 'skylark_lib')",
"test_suite(",
" name = 'suite',",
" tests = [':skylark_test', ':suite_2'],",
")",
"test_suite(",
" name = 'suite_2',",
" tests = [':skylark_test_2', ':skylark_test_3'],",
")",
"skylark_test(",
" name = 'skylark_test',",
")",
"skylark_test(",
" name = 'skylark_test_2',",
")",
"skylark_test(",
" name = 'skylark_test_3',",
")");
useConfiguration("--trim_test_configuration", "--noexpand_test_suites", "--test_arg=TypeA");
update("//test:suite", "//test:suite_2");
assertThat(getAnalysisResult().getTargetsToBuild()).hasSize(2);
}
}