diff options
author | John Cater <jcater@google.com> | 2017-10-20 22:03:00 +0200 |
---|---|---|
committer | Dmitry Lomov <dslomov@google.com> | 2017-10-23 17:16:12 +0200 |
commit | 6738c36265c544a116751372ce74209305f44071 (patch) | |
tree | 023e0221a1a8cf2df80cb670e7418496b6621509 /src/test/java/com/google | |
parent | b368b39f8ba1e8e8a67af50e5ade9127b2b149d7 (diff) |
Add tests for ToolchainUtil, and fix an error when there is an error and
values are missing while fetching toolchains.
Fixes #3928.
Change-Id: I4fde784f56daf544ba70c9848e006f1183c20a99
PiperOrigin-RevId: 172922687
Diffstat (limited to 'src/test/java/com/google')
5 files changed, 252 insertions, 19 deletions
diff --git a/src/test/java/com/google/devtools/build/lib/rules/platform/ToolchainTestCase.java b/src/test/java/com/google/devtools/build/lib/rules/platform/ToolchainTestCase.java index 77a9daa331..2f50ba7894 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/platform/ToolchainTestCase.java +++ b/src/test/java/com/google/devtools/build/lib/rules/platform/ToolchainTestCase.java @@ -63,29 +63,32 @@ public abstract class ToolchainTestCase extends SkylarkTestCase { @Before public void createConstraints() throws Exception { scratch.file( - "constraint/BUILD", + "constraints/BUILD", "constraint_setting(name = 'os')", "constraint_value(name = 'linux',", " constraint_setting = ':os')", "constraint_value(name = 'mac',", - " constraint_setting = ':os')", - "platform(name = 'linux_plat',", - " constraint_values = [':linux'])", - "platform(name = 'mac_plat',", - " constraint_values = [':mac'])"); + " constraint_setting = ':os')"); + + scratch.file( + "platforms/BUILD", + "platform(name = 'linux',", + " constraint_values = ['//constraints:linux'])", + "platform(name = 'mac',", + " constraint_values = ['//constraints:mac'])"); - setting = ConstraintSettingInfo.create(makeLabel("//constraint:os")); - linuxConstraint = ConstraintValueInfo.create(setting, makeLabel("//constraint:linux")); - macConstraint = ConstraintValueInfo.create(setting, makeLabel("//constraint:mac")); + setting = ConstraintSettingInfo.create(makeLabel("//constraints:os")); + linuxConstraint = ConstraintValueInfo.create(setting, makeLabel("//constraints:linux")); + macConstraint = ConstraintValueInfo.create(setting, makeLabel("//constraints:mac")); linuxPlatform = PlatformInfo.builder() - .setLabel(makeLabel("//platforms:target_platform")) + .setLabel(makeLabel("//platforms:linux")) .addConstraint(linuxConstraint) .build(); macPlatform = PlatformInfo.builder() - .setLabel(makeLabel("//platforms:host_platform")) + .setLabel(makeLabel("//platforms:mac")) .addConstraint(macConstraint) .build(); } @@ -101,14 +104,14 @@ public abstract class ToolchainTestCase extends SkylarkTestCase { "toolchain(", " name = 'toolchain_1',", " toolchain_type = ':test_toolchain',", - " exec_compatible_with = ['//constraint:linux'],", - " target_compatible_with = ['//constraint:mac'],", + " exec_compatible_with = ['//constraints:linux'],", + " target_compatible_with = ['//constraints:mac'],", " toolchain = ':test_toolchain_1')", "toolchain(", " name = 'toolchain_2',", " toolchain_type = ':test_toolchain',", - " exec_compatible_with = ['//constraint:mac'],", - " target_compatible_with = ['//constraint:linux'],", + " exec_compatible_with = ['//constraints:mac'],", + " target_compatible_with = ['//constraints:linux'],", " toolchain = ':test_toolchain_2')", "test_toolchain(", " name='test_toolchain_1',", diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/BUILD b/src/test/java/com/google/devtools/build/lib/skyframe/BUILD index 259a508bff..4fbd825c10 100644 --- a/src/test/java/com/google/devtools/build/lib/skyframe/BUILD +++ b/src/test/java/com/google/devtools/build/lib/skyframe/BUILD @@ -89,6 +89,7 @@ java_test( "//src/test/java/com/google/devtools/build/lib:packages_testutil", "//src/test/java/com/google/devtools/build/lib:testutil", "//src/test/java/com/google/devtools/build/lib/rules/platform:testutil", + "//third_party:auto_value", "//third_party:guava", "//third_party:guava-testlib", "//third_party:jsr305", diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/RegisteredToolchainsFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/RegisteredToolchainsFunctionTest.java index 6ffa290a20..49d928c993 100644 --- a/src/test/java/com/google/devtools/build/lib/skyframe/RegisteredToolchainsFunctionTest.java +++ b/src/test/java/com/google/devtools/build/lib/skyframe/RegisteredToolchainsFunctionTest.java @@ -67,8 +67,8 @@ public class RegisteredToolchainsFunctionTest extends ToolchainTestCase { "toolchain(", " name = 'extra_toolchain',", " toolchain_type = '//toolchain:test_toolchain',", - " exec_compatible_with = ['//constraint:linux'],", - " target_compatible_with = ['//constraint:linux'],", + " exec_compatible_with = ['//constraints:linux'],", + " target_compatible_with = ['//constraints:linux'],", " toolchain = ':extra_toolchain_impl')", "test_toolchain(", " name='extra_toolchain_impl',", diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/RuleContextTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/RuleContextTest.java index d5b345d3d1..8177415512 100644 --- a/src/test/java/com/google/devtools/build/lib/skyframe/RuleContextTest.java +++ b/src/test/java/com/google/devtools/build/lib/skyframe/RuleContextTest.java @@ -33,8 +33,8 @@ public class RuleContextTest extends ToolchainTestCase { public void testMockRuleContextHasToolchains() throws Exception { mockToolsConfig.create("x/BUILD", "mock_toolchain_rule(name='x')"); useConfiguration( - "--experimental_host_platform=//constraint:linux_plat", - "--experimental_platforms=//constraint:mac_plat"); + "--experimental_host_platform=//platforms:linux", + "--experimental_platforms=//platforms:mac"); RuleContext ruleContext = getRuleContext(getConfiguredTarget("//x")); assertThat(ruleContext.getToolchainContext().getResolvedToolchainLabels()) .contains(Label.parseAbsolute("//toolchain:test_toolchain_1")); diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/ToolchainUtilTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/ToolchainUtilTest.java new file mode 100644 index 0000000000..4a9866fc6b --- /dev/null +++ b/src/test/java/com/google/devtools/build/lib/skyframe/ToolchainUtilTest.java @@ -0,0 +1,229 @@ +// Copyright 2017 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.skyframe; + +import static com.google.common.truth.Truth.assertThat; +import static com.google.devtools.build.skyframe.EvaluationResultSubjectFactory.assertThatEvaluationResult; + +import com.google.auto.value.AutoValue; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.google.devtools.build.lib.analysis.BlazeDirectories; +import com.google.devtools.build.lib.analysis.ToolchainContext; +import com.google.devtools.build.lib.analysis.config.BuildConfiguration; +import com.google.devtools.build.lib.analysis.util.AnalysisMock; +import com.google.devtools.build.lib.cmdline.Label; +import com.google.devtools.build.lib.rules.platform.ToolchainTestCase; +import com.google.devtools.build.lib.skyframe.ToolchainUtil.ToolchainContextException; +import com.google.devtools.build.lib.skyframe.ToolchainUtil.UnresolvedToolchainsException; +import com.google.devtools.build.lib.skyframe.util.SkyframeExecutorTestUtils; +import com.google.devtools.build.skyframe.EvaluationResult; +import com.google.devtools.build.skyframe.SkyFunction; +import com.google.devtools.build.skyframe.SkyFunctionException; +import com.google.devtools.build.skyframe.SkyFunctionName; +import com.google.devtools.build.skyframe.SkyKey; +import com.google.devtools.build.skyframe.SkyValue; +import java.util.Set; +import javax.annotation.Nullable; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Tests for {@link ToolchainUtil}. */ +@RunWith(JUnit4.class) +public class ToolchainUtilTest extends ToolchainTestCase { + + /** + * An {@link AnalysisMock} that injects {@link CreateToolchainContextFunction} into the Skyframe + * executor. + */ + private static final class AnalysisMockWithCreateToolchainContextFunction + extends AnalysisMock.Delegate { + AnalysisMockWithCreateToolchainContextFunction() { + super(AnalysisMock.get()); + } + + @Override + public ImmutableMap<SkyFunctionName, SkyFunction> getSkyFunctions( + BlazeDirectories directories) { + return ImmutableMap.<SkyFunctionName, SkyFunction>builder() + .putAll(super.getSkyFunctions(directories)) + .put(CREATE_TOOLCHAIN_CONTEXT_FUNCTION, new CreateToolchainContextFunction()) + .build(); + } + }; + + @Override + protected AnalysisMock getAnalysisMock() { + return new AnalysisMockWithCreateToolchainContextFunction(); + } + + @Test + public void createToolchainContext() throws Exception { + useConfiguration( + "--experimental_host_platform=//platforms:linux", + "--experimental_platforms=//platforms:mac"); + CreateToolchainContextKey key = + CreateToolchainContextKey.create("test", ImmutableSet.of(testToolchainType), targetConfig); + + EvaluationResult<CreateToolchainContextValue> result = createToolchainContext(key); + + assertThatEvaluationResult(result).hasNoError(); + ToolchainContext toolchainContext = result.get(key).toolchainContext(); + assertThat(toolchainContext).isNotNull(); + + assertThat(toolchainContext.getRequiredToolchains()).containsExactly(testToolchainType); + assertThat(toolchainContext.getResolvedToolchainLabels()) + .containsExactly(Label.parseAbsoluteUnchecked("//toolchain:test_toolchain_1")); + } + + @Test + public void createToolchainContext_unavailableToolchainType_single() throws Exception { + useConfiguration( + "--experimental_host_platform=//platforms:linux", + "--experimental_platforms=//platforms:mac"); + CreateToolchainContextKey key = + CreateToolchainContextKey.create( + "test", + ImmutableSet.of( + testToolchainType, Label.parseAbsoluteUnchecked("//fake/toolchain:type_1")), + targetConfig); + + EvaluationResult<CreateToolchainContextValue> result = createToolchainContext(key); + + assertThatEvaluationResult(result) + .hasErrorEntryForKeyThat(key) + .hasExceptionThat() + .isInstanceOf(ToolchainContextException.class); + assertThatEvaluationResult(result) + .hasErrorEntryForKeyThat(key) + .hasExceptionThat() + .hasCauseThat() + .isInstanceOf(UnresolvedToolchainsException.class); + assertThatEvaluationResult(result) + .hasErrorEntryForKeyThat(key) + .hasExceptionThat() + .hasCauseThat() + .hasMessageThat() + .contains("no matching toolchains found for types //fake/toolchain:type_1"); + } + + @Test + public void createToolchainContext_unavailableToolchainType_multiple() throws Exception { + useConfiguration( + "--experimental_host_platform=//platforms:linux", + "--experimental_platforms=//platforms:mac"); + CreateToolchainContextKey key = + CreateToolchainContextKey.create( + "test", + ImmutableSet.of( + testToolchainType, + Label.parseAbsoluteUnchecked("//fake/toolchain:type_1"), + Label.parseAbsoluteUnchecked("//fake/toolchain:type_2")), + targetConfig); + + EvaluationResult<CreateToolchainContextValue> result = createToolchainContext(key); + + assertThatEvaluationResult(result) + .hasErrorEntryForKeyThat(key) + .hasExceptionThat() + .isInstanceOf(ToolchainContextException.class); + assertThatEvaluationResult(result) + .hasErrorEntryForKeyThat(key) + .hasExceptionThat() + .hasCauseThat() + .isInstanceOf(UnresolvedToolchainsException.class); + // Only one of the missing types will be reported, so do not check the specific error message. + } + + // Calls ToolchainUtil.createToolchainContext. + private static final SkyFunctionName CREATE_TOOLCHAIN_CONTEXT_FUNCTION = + SkyFunctionName.create("CREATE_TOOLCHAIN_CONTEXT_FUNCTION"); + + @AutoValue + abstract static class CreateToolchainContextKey implements SkyKey { + @Override + public SkyFunctionName functionName() { + return CREATE_TOOLCHAIN_CONTEXT_FUNCTION; + } + + abstract String targetDescription(); + + abstract Set<Label> requiredToolchains(); + + abstract BuildConfiguration configuration(); + + public static CreateToolchainContextKey create( + String targetDescription, Set<Label> requiredToolchains, BuildConfiguration configuration) { + return new AutoValue_ToolchainUtilTest_CreateToolchainContextKey( + targetDescription, requiredToolchains, configuration); + } + } + + EvaluationResult<CreateToolchainContextValue> createToolchainContext( + CreateToolchainContextKey key) throws InterruptedException { + try { + // Must re-enable analysis for Skyframe functions that create configured targets. + skyframeExecutor.getSkyframeBuildView().enableAnalysis(true); + return SkyframeExecutorTestUtils.evaluate( + skyframeExecutor, key, /*keepGoing=*/ false, reporter); + } finally { + skyframeExecutor.getSkyframeBuildView().enableAnalysis(false); + } + } + + @AutoValue + abstract static class CreateToolchainContextValue implements SkyValue { + abstract ToolchainContext toolchainContext(); + + static CreateToolchainContextValue create(ToolchainContext toolchainContext) { + return new AutoValue_ToolchainUtilTest_CreateToolchainContextValue(toolchainContext); + } + } + + private static final class CreateToolchainContextFunction implements SkyFunction { + + @Nullable + @Override + public SkyValue compute(SkyKey skyKey, Environment env) + throws SkyFunctionException, InterruptedException { + CreateToolchainContextKey key = (CreateToolchainContextKey) skyKey; + ToolchainContext toolchainContext = null; + try { + toolchainContext = + ToolchainUtil.createToolchainContext( + env, key.targetDescription(), key.requiredToolchains(), key.configuration()); + if (toolchainContext == null) { + return null; + } + return CreateToolchainContextValue.create(toolchainContext); + } catch (ToolchainContextException e) { + throw new CreateToolchainContextFunctionException(e); + } + } + + @Nullable + @Override + public String extractTag(SkyKey skyKey) { + return null; + } + } + + private static class CreateToolchainContextFunctionException extends SkyFunctionException { + public CreateToolchainContextFunctionException(ToolchainContextException e) { + super(e, Transience.PERSISTENT); + } + } +} |