| // 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.skyframe; |
| |
| import static com.google.common.truth.Truth.assertThat; |
| import static com.google.devtools.build.skyframe.EvaluationResultSubjectFactory.assertThatEvaluationResult; |
| |
| import com.google.common.collect.ImmutableList; |
| import com.google.common.testing.EqualsTester; |
| import com.google.common.truth.IterableSubject; |
| import com.google.devtools.build.lib.analysis.platform.PlatformInfo.DuplicateConstraintException; |
| import com.google.devtools.build.lib.cmdline.Label; |
| import com.google.devtools.build.lib.cmdline.PackageIdentifier; |
| import com.google.devtools.build.lib.rules.platform.ToolchainTestCase; |
| import com.google.devtools.build.lib.skyframe.PlatformLookupUtil.InvalidPlatformException; |
| import com.google.devtools.build.lib.skyframe.util.SkyframeExecutorTestUtils; |
| import com.google.devtools.build.skyframe.EvaluationResult; |
| import com.google.devtools.build.skyframe.SkyKey; |
| import java.util.List; |
| import java.util.stream.Collectors; |
| import javax.annotation.Nullable; |
| import org.junit.Test; |
| import org.junit.runner.RunWith; |
| import org.junit.runners.JUnit4; |
| |
| /** |
| * Tests for {@link RegisteredExecutionPlatformsFunction} and {@link |
| * RegisteredExecutionPlatformsValue}. |
| */ |
| @RunWith(JUnit4.class) |
| public class RegisteredExecutionPlatformsFunctionTest extends ToolchainTestCase { |
| |
| protected EvaluationResult<RegisteredExecutionPlatformsValue> |
| requestExecutionPlatformsFromSkyframe(SkyKey executionPlatformsKey) |
| throws InterruptedException { |
| try { |
| getSkyframeExecutor().getSkyframeBuildView().enableAnalysis(true); |
| return SkyframeExecutorTestUtils.evaluate( |
| getSkyframeExecutor(), executionPlatformsKey, /*keepGoing=*/ false, reporter); |
| } finally { |
| getSkyframeExecutor().getSkyframeBuildView().enableAnalysis(false); |
| } |
| } |
| |
| protected static IterableSubject assertExecutionPlatformLabels( |
| RegisteredExecutionPlatformsValue registeredExecutionPlatformsValue) { |
| return assertExecutionPlatformLabels(registeredExecutionPlatformsValue, null); |
| } |
| |
| protected static IterableSubject assertExecutionPlatformLabels( |
| RegisteredExecutionPlatformsValue registeredExecutionPlatformsValue, |
| @Nullable PackageIdentifier packageRoot) { |
| assertThat(registeredExecutionPlatformsValue).isNotNull(); |
| ImmutableList<ConfiguredTargetKey> declaredExecutionPlatformKeys = |
| registeredExecutionPlatformsValue.registeredExecutionPlatformKeys(); |
| List<Label> labels = collectExecutionPlatformLabels(declaredExecutionPlatformKeys, packageRoot); |
| return assertThat(labels); |
| } |
| |
| protected static List<Label> collectExecutionPlatformLabels( |
| List<ConfiguredTargetKey> executionPlatformKeys, @Nullable PackageIdentifier packageRoot) { |
| return executionPlatformKeys.stream() |
| .map(ConfiguredTargetKey::getLabel) |
| .filter(label -> filterLabel(packageRoot, label)) |
| .collect(Collectors.toList()); |
| } |
| |
| @Test |
| public void testRegisteredExecutionPlatforms() throws Exception { |
| // Request the executionPlatforms. |
| SkyKey executionPlatformsKey = RegisteredExecutionPlatformsValue.key(targetConfigKey); |
| EvaluationResult<RegisteredExecutionPlatformsValue> result = |
| requestExecutionPlatformsFromSkyframe(executionPlatformsKey); |
| assertThatEvaluationResult(result).hasNoError(); |
| assertThatEvaluationResult(result).hasEntryThat(executionPlatformsKey).isNotNull(); |
| |
| RegisteredExecutionPlatformsValue value = result.get(executionPlatformsKey); |
| assertThat(value.registeredExecutionPlatformKeys()).isEmpty(); |
| } |
| |
| @Test |
| public void testRegisteredExecutionPlatforms_flagOverride() throws Exception { |
| |
| // Add an extra execution platform. |
| scratch.file( |
| "extra/BUILD", |
| "platform(name = 'execution_platform_1')", |
| "platform(name = 'execution_platform_2')"); |
| |
| rewriteWorkspace("register_execution_platforms('//extra:execution_platform_2')"); |
| useConfiguration("--extra_execution_platforms=//extra:execution_platform_1"); |
| |
| SkyKey executionPlatformsKey = RegisteredExecutionPlatformsValue.key(targetConfigKey); |
| EvaluationResult<RegisteredExecutionPlatformsValue> result = |
| requestExecutionPlatformsFromSkyframe(executionPlatformsKey); |
| assertThatEvaluationResult(result).hasNoError(); |
| |
| // Verify that the target registered with the extra_execution_platforms flag is first in the |
| // list. |
| assertExecutionPlatformLabels(result.get(executionPlatformsKey)) |
| .containsAllOf( |
| makeLabel("//extra:execution_platform_1"), makeLabel("//extra:execution_platform_2")) |
| .inOrder(); |
| } |
| |
| @Test |
| public void testRegisteredExecutionPlatforms_flagOverride_multiple() throws Exception { |
| |
| // Add an extra execution platform. |
| scratch.file( |
| "extra/BUILD", |
| "platform(name = 'execution_platform_1')", |
| "platform(name = 'execution_platform_2')"); |
| |
| useConfiguration( |
| "--extra_execution_platforms=//extra:execution_platform_1", |
| "--extra_execution_platforms=//extra:execution_platform_2"); |
| |
| SkyKey executionPlatformsKey = RegisteredExecutionPlatformsValue.key(targetConfigKey); |
| EvaluationResult<RegisteredExecutionPlatformsValue> result = |
| requestExecutionPlatformsFromSkyframe(executionPlatformsKey); |
| assertThatEvaluationResult(result).hasNoError(); |
| |
| // Verify that the target registered with the extra_execution_platforms flag is first in the |
| // list. |
| assertExecutionPlatformLabels(result.get(executionPlatformsKey)) |
| .containsAllOf( |
| makeLabel("//extra:execution_platform_1"), makeLabel("//extra:execution_platform_2")) |
| .inOrder(); |
| } |
| |
| @Test |
| public void testRegisteredExecutionPlatforms_targetPattern_workspace() throws Exception { |
| |
| // Add an extra execution platform. |
| scratch.file( |
| "extra/BUILD", |
| "platform(name = 'execution_platform_1')", |
| "platform(name = 'execution_platform_2')"); |
| |
| rewriteWorkspace("register_execution_platforms('//extra/...')"); |
| |
| SkyKey executionPlatformsKey = RegisteredExecutionPlatformsValue.key(targetConfigKey); |
| EvaluationResult<RegisteredExecutionPlatformsValue> result = |
| requestExecutionPlatformsFromSkyframe(executionPlatformsKey); |
| assertThatEvaluationResult(result).hasNoError(); |
| |
| // Verify that the target registered with the extra_execution_platforms flag is first in the |
| // list. |
| assertExecutionPlatformLabels(result.get(executionPlatformsKey)) |
| .containsAllOf( |
| makeLabel("//extra:execution_platform_1"), makeLabel("//extra:execution_platform_2")) |
| .inOrder(); |
| } |
| |
| @Test |
| public void testRegisteredExecutionPlatforms_targetPattern_mixed() throws Exception { |
| |
| // Add several targets, some of which are not actually platforms. |
| scratch.file( |
| "extra/BUILD", |
| "platform(name = 'execution_platform_1')", |
| "platform(name = 'execution_platform_2')", |
| "filegroup(name = 'not_an_execution_platform')"); |
| |
| rewriteWorkspace("register_execution_platforms('//extra:all')"); |
| |
| SkyKey executionPlatformsKey = RegisteredExecutionPlatformsValue.key(targetConfigKey); |
| EvaluationResult<RegisteredExecutionPlatformsValue> result = |
| requestExecutionPlatformsFromSkyframe(executionPlatformsKey); |
| assertThatEvaluationResult(result).hasNoError(); |
| |
| // There should only be two execution platforms registered from //extra. |
| // Verify that the target registered with the extra_execution_platforms flag is first in the |
| // list. |
| assertExecutionPlatformLabels( |
| result.get(executionPlatformsKey), PackageIdentifier.createInMainRepo("extra")) |
| .containsExactly( |
| makeLabel("//extra:execution_platform_1"), makeLabel("//extra:execution_platform_2")) |
| .inOrder(); |
| } |
| |
| @Test |
| public void testRegisteredExecutionPlatforms_targetPattern_flagOverride() throws Exception { |
| |
| // Add an extra execution platform. |
| scratch.file( |
| "extra/BUILD", |
| "platform(name = 'execution_platform_1')", |
| "platform(name = 'execution_platform_2')"); |
| |
| useConfiguration("--extra_execution_platforms=//extra/..."); |
| |
| SkyKey executionPlatformsKey = RegisteredExecutionPlatformsValue.key(targetConfigKey); |
| EvaluationResult<RegisteredExecutionPlatformsValue> result = |
| requestExecutionPlatformsFromSkyframe(executionPlatformsKey); |
| assertThatEvaluationResult(result).hasNoError(); |
| |
| // Verify that the target registered with the extra_execution_platforms flag is first in the |
| // list. |
| assertExecutionPlatformLabels(result.get(executionPlatformsKey)) |
| .containsAllOf( |
| makeLabel("//extra:execution_platform_1"), makeLabel("//extra:execution_platform_2")) |
| .inOrder(); |
| } |
| |
| @Test |
| public void testRegisteredExecutionPlatforms_notExecutionPlatform() throws Exception { |
| rewriteWorkspace("register_execution_platforms(", " '//error:not_an_execution_platform')"); |
| scratch.file("error/BUILD", "filegroup(name = 'not_an_execution_platform')"); |
| |
| // Request the executionPlatforms. |
| SkyKey executionPlatformsKey = RegisteredExecutionPlatformsValue.key(targetConfigKey); |
| EvaluationResult<RegisteredExecutionPlatformsValue> result = |
| requestExecutionPlatformsFromSkyframe(executionPlatformsKey); |
| assertThatEvaluationResult(result).hasError(); |
| assertThatEvaluationResult(result) |
| .hasErrorEntryForKeyThat(executionPlatformsKey) |
| .hasExceptionThat() |
| .isInstanceOf(InvalidPlatformException.class); |
| assertThatEvaluationResult(result) |
| .hasErrorEntryForKeyThat(executionPlatformsKey) |
| .hasExceptionThat() |
| .hasMessageThat() |
| .contains("//error:not_an_execution_platform"); |
| } |
| |
| @Test |
| public void testRegisteredExecutionPlatforms_reload() throws Exception { |
| scratch.file( |
| "platform/BUILD", |
| "platform(name = 'execution_platform_1')", |
| "platform(name = 'execution_platform_2')"); |
| |
| rewriteWorkspace("register_execution_platforms('//platform:execution_platform_1')"); |
| |
| SkyKey executionPlatformsKey = RegisteredExecutionPlatformsValue.key(targetConfigKey); |
| EvaluationResult<RegisteredExecutionPlatformsValue> result = |
| requestExecutionPlatformsFromSkyframe(executionPlatformsKey); |
| assertThatEvaluationResult(result).hasNoError(); |
| assertExecutionPlatformLabels(result.get(executionPlatformsKey)) |
| .contains(makeLabel("//platform:execution_platform_1")); |
| |
| // Re-write the WORKSPACE. |
| rewriteWorkspace("register_execution_platforms('//platform:execution_platform_2')"); |
| |
| executionPlatformsKey = RegisteredExecutionPlatformsValue.key(targetConfigKey); |
| result = requestExecutionPlatformsFromSkyframe(executionPlatformsKey); |
| assertThatEvaluationResult(result).hasNoError(); |
| assertExecutionPlatformLabels(result.get(executionPlatformsKey)) |
| .contains(makeLabel("//platform:execution_platform_2")); |
| } |
| |
| @Test |
| public void testRegisteredExecutionPlatformsValue_equalsAndHashCode() |
| throws DuplicateConstraintException { |
| ConfiguredTargetKey executionPlatformKey1 = |
| ConfiguredTargetKey.of(makeLabel("//test:executionPlatform1"), null, false); |
| ConfiguredTargetKey executionPlatformKey2 = |
| ConfiguredTargetKey.of(makeLabel("//test:executionPlatform2"), null, false); |
| |
| new EqualsTester() |
| .addEqualityGroup( |
| // Two platforms registered. |
| RegisteredExecutionPlatformsValue.create( |
| ImmutableList.of(executionPlatformKey1, executionPlatformKey2)), |
| RegisteredExecutionPlatformsValue.create( |
| ImmutableList.of(executionPlatformKey1, executionPlatformKey2))) |
| .addEqualityGroup( |
| // A single platform registered. |
| RegisteredExecutionPlatformsValue.create(ImmutableList.of(executionPlatformKey1))) |
| .addEqualityGroup( |
| // A single, different, platform registered. |
| RegisteredExecutionPlatformsValue.create(ImmutableList.of(executionPlatformKey2))) |
| .addEqualityGroup( |
| // The same as the first group, but the order is different. |
| RegisteredExecutionPlatformsValue.create( |
| ImmutableList.of(executionPlatformKey2, executionPlatformKey1))) |
| .testEquals(); |
| } |
| } |