| // Copyright 2019 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.lib.testutil.MoreAsserts.assertThrows; |
| |
| import com.google.common.collect.ImmutableList; |
| import com.google.common.collect.ImmutableMap; |
| import com.google.common.collect.ImmutableSet; |
| import com.google.devtools.build.lib.analysis.PlatformConfiguration; |
| import com.google.devtools.build.lib.analysis.PlatformOptions; |
| import com.google.devtools.build.lib.analysis.config.BuildConfiguration; |
| import com.google.devtools.build.lib.analysis.config.BuildOptions; |
| import com.google.devtools.build.lib.analysis.config.CompilationMode; |
| import com.google.devtools.build.lib.analysis.config.CoreOptions; |
| import com.google.devtools.build.lib.analysis.config.FragmentOptions; |
| import com.google.devtools.build.lib.cmdline.Label; |
| import com.google.devtools.build.lib.vfs.PathFragment; |
| import com.google.devtools.common.options.OptionsParsingException; |
| import java.util.Collection; |
| import java.util.Set; |
| import org.junit.Test; |
| import org.junit.runner.RunWith; |
| import org.junit.runners.JUnit4; |
| |
| /** Unit tests for {@link PlatformMappingValue}. */ |
| @RunWith(JUnit4.class) |
| public class PlatformMappingValueTest { |
| |
| // We don't actually care about the contents of this set other than that it is passed intact |
| // through the mapping logic. The platform fragment in it is purely an example, it could be any |
| // set of fragments. |
| private static final Set<Class<? extends BuildConfiguration.Fragment>> PLATFORM_FRAGMENT_CLASS = |
| ImmutableSet.of(PlatformConfiguration.class); |
| |
| private static final ImmutableList<Class<? extends FragmentOptions>> |
| BUILD_CONFIG_PLATFORM_OPTIONS = ImmutableList.of(CoreOptions.class, PlatformOptions.class); |
| |
| private static final Label PLATFORM1 = Label.parseAbsoluteUnchecked("//platforms:one"); |
| private static final Label PLATFORM2 = Label.parseAbsoluteUnchecked("//platforms:two"); |
| |
| private static final BuildOptions DEFAULT_BUILD_CONFIG_PLATFORM_OPTIONS = |
| getDefaultBuildConfigPlatformOptions(); |
| private static final BuildOptions.OptionsDiffForReconstruction EMPTY_DIFF = |
| BuildOptions.diffForReconstruction( |
| DEFAULT_BUILD_CONFIG_PLATFORM_OPTIONS, DEFAULT_BUILD_CONFIG_PLATFORM_OPTIONS); |
| private static final Label DEFAULT_TARGET_PLATFORM = |
| Label.parseAbsoluteUnchecked("@bazel_tools//platforms:target_platform"); |
| |
| @Test |
| public void testMapNoMappings() throws OptionsParsingException { |
| PlatformMappingValue mappingValue = |
| new PlatformMappingValue(ImmutableMap.of(), ImmutableMap.of()); |
| |
| BuildConfigurationValue.Key key = |
| BuildConfigurationValue.keyWithoutPlatformMapping(PLATFORM_FRAGMENT_CLASS, EMPTY_DIFF); |
| |
| BuildConfigurationValue.Key mapped = |
| mappingValue.map(key, DEFAULT_BUILD_CONFIG_PLATFORM_OPTIONS); |
| |
| assertThat(toMappedOptions(mapped).get(PlatformOptions.class).platforms) |
| .containsExactly(DEFAULT_TARGET_PLATFORM); |
| } |
| |
| @Test |
| public void testMapPlatformToFlags() throws Exception { |
| ImmutableMap<Label, Collection<String>> platformsToFlags = |
| ImmutableMap.of(PLATFORM1, ImmutableList.of("--cpu=one", "--compilation_mode=dbg")); |
| |
| PlatformMappingValue mappingValue = |
| new PlatformMappingValue(platformsToFlags, ImmutableMap.of()); |
| |
| BuildOptions modifiedOptions = DEFAULT_BUILD_CONFIG_PLATFORM_OPTIONS.clone(); |
| modifiedOptions.get(PlatformOptions.class).platforms = ImmutableList.of(PLATFORM1); |
| |
| BuildConfigurationValue.Key mapped = |
| mappingValue.map(keyForOptions(modifiedOptions), DEFAULT_BUILD_CONFIG_PLATFORM_OPTIONS); |
| |
| assertThat(mapped.getFragments()).isEqualTo(PLATFORM_FRAGMENT_CLASS); |
| |
| assertThat(toMappedOptions(mapped).get(CoreOptions.class).cpu).isEqualTo("one"); |
| } |
| |
| @Test |
| public void testMapFlagsToPlatform() throws Exception { |
| ImmutableMap<Collection<String>, Label> flagsToPlatforms = |
| ImmutableMap.of(ImmutableList.of("--cpu=one", "--compilation_mode=dbg"), PLATFORM1); |
| |
| PlatformMappingValue mappingValue = |
| new PlatformMappingValue(ImmutableMap.of(), flagsToPlatforms); |
| |
| BuildOptions modifiedOptions = DEFAULT_BUILD_CONFIG_PLATFORM_OPTIONS.clone(); |
| modifiedOptions.get(CoreOptions.class).cpu = "one"; |
| modifiedOptions.get(CoreOptions.class).compilationMode = CompilationMode.DBG; |
| |
| BuildConfigurationValue.Key mapped = |
| mappingValue.map(keyForOptions(modifiedOptions), DEFAULT_BUILD_CONFIG_PLATFORM_OPTIONS); |
| |
| assertThat(mapped.getFragments()).isEqualTo(PLATFORM_FRAGMENT_CLASS); |
| |
| assertThat(toMappedOptions(mapped).get(PlatformOptions.class).platforms) |
| .containsExactly(PLATFORM1); |
| } |
| |
| @Test |
| public void testMapFlagsToPlatformPriority() throws Exception { |
| ImmutableMap<Collection<String>, Label> flagsToPlatforms = |
| ImmutableMap.of( |
| ImmutableList.of("--cpu=foo", "--compilation_mode=dbg"), PLATFORM1, |
| ImmutableList.of("--cpu=foo"), PLATFORM2); |
| |
| PlatformMappingValue mappingValue = |
| new PlatformMappingValue(ImmutableMap.of(), flagsToPlatforms); |
| |
| BuildOptions modifiedOptions = DEFAULT_BUILD_CONFIG_PLATFORM_OPTIONS.clone(); |
| modifiedOptions.get(CoreOptions.class).cpu = "foo"; |
| |
| BuildConfigurationValue.Key mapped = |
| mappingValue.map(keyForOptions(modifiedOptions), DEFAULT_BUILD_CONFIG_PLATFORM_OPTIONS); |
| |
| assertThat(toMappedOptions(mapped).get(PlatformOptions.class).platforms) |
| .containsExactly(PLATFORM2); |
| } |
| |
| @Test |
| public void testMapFlagsToPlatformNoneMatching() throws Exception { |
| ImmutableMap<Collection<String>, Label> flagsToPlatforms = |
| ImmutableMap.of(ImmutableList.of("--cpu=foo", "--compilation_mode=dbg"), PLATFORM1); |
| |
| PlatformMappingValue mappingValue = |
| new PlatformMappingValue(ImmutableMap.of(), flagsToPlatforms); |
| |
| BuildOptions modifiedOptions = DEFAULT_BUILD_CONFIG_PLATFORM_OPTIONS.clone(); |
| modifiedOptions.get(CoreOptions.class).cpu = "bar"; |
| |
| BuildConfigurationValue.Key mapped = |
| mappingValue.map(keyForOptions(modifiedOptions), DEFAULT_BUILD_CONFIG_PLATFORM_OPTIONS); |
| |
| assertThat(toMappedOptions(mapped).get(PlatformOptions.class).platforms) |
| .containsExactly(DEFAULT_TARGET_PLATFORM); |
| } |
| |
| @Test |
| public void testMapNoPlatformOptions() throws Exception { |
| ImmutableMap<Collection<String>, Label> flagsToPlatforms = |
| ImmutableMap.of(ImmutableList.of("--cpu=one"), PLATFORM1); |
| |
| PlatformMappingValue mappingValue = |
| new PlatformMappingValue(ImmutableMap.of(), flagsToPlatforms); |
| |
| BuildOptions options = BuildOptions.of(ImmutableList.of(CoreOptions.class)); |
| |
| assertThrows( |
| IllegalArgumentException.class, |
| () -> mappingValue.map(keyForOptions(options), DEFAULT_BUILD_CONFIG_PLATFORM_OPTIONS)); |
| } |
| |
| @Test |
| public void testMapNoMappingIfPlatformIsSetButNotMatching() throws Exception { |
| ImmutableMap<Label, Collection<String>> platformsToFlags = |
| ImmutableMap.of(PLATFORM1, ImmutableList.of("--cpu=one", "--compilation_mode=dbg")); |
| ImmutableMap<Collection<String>, Label> flagsToPlatforms = |
| ImmutableMap.of(ImmutableList.of("--cpu=one"), PLATFORM1); |
| |
| BuildOptions modifiedOptions = DEFAULT_BUILD_CONFIG_PLATFORM_OPTIONS.clone(); |
| modifiedOptions.get(CoreOptions.class).cpu = "one"; |
| modifiedOptions.get(PlatformOptions.class).platforms = ImmutableList.of(PLATFORM2); |
| |
| PlatformMappingValue mappingValue = |
| new PlatformMappingValue(platformsToFlags, flagsToPlatforms); |
| |
| BuildConfigurationValue.Key mapped = |
| mappingValue.map(keyForOptions(modifiedOptions), DEFAULT_BUILD_CONFIG_PLATFORM_OPTIONS); |
| |
| assertThat(keyForOptions(modifiedOptions)).isEqualTo(mapped); |
| } |
| |
| @Test |
| public void testMapNoMappingIfPlatformIsSetAndNoPlatformMapping() throws Exception { |
| ImmutableMap<Collection<String>, Label> flagsToPlatforms = |
| ImmutableMap.of(ImmutableList.of("--cpu=one"), PLATFORM1); |
| |
| BuildOptions modifiedOptions = DEFAULT_BUILD_CONFIG_PLATFORM_OPTIONS.clone(); |
| modifiedOptions.get(CoreOptions.class).cpu = "one"; |
| modifiedOptions.get(PlatformOptions.class).platforms = ImmutableList.of(PLATFORM2); |
| |
| PlatformMappingValue mappingValue = |
| new PlatformMappingValue(ImmutableMap.of(), flagsToPlatforms); |
| |
| BuildConfigurationValue.Key mapped = |
| mappingValue.map(keyForOptions(modifiedOptions), DEFAULT_BUILD_CONFIG_PLATFORM_OPTIONS); |
| |
| assertThat(keyForOptions(modifiedOptions)).isEqualTo(mapped); |
| } |
| |
| @Test |
| public void testDefaultKey() { |
| PlatformMappingValue.Key key = PlatformMappingValue.Key.create(null); |
| |
| assertThat(key.getWorkspaceRelativeMappingPath()) |
| .isEqualTo(PlatformOptions.DEFAULT_PLATFORM_MAPPINGS); |
| assertThat(key.wasExplicitlySetByUser()).isFalse(); |
| } |
| |
| @Test |
| public void testCustomKey() { |
| PlatformMappingValue.Key key = PlatformMappingValue.Key.create(PathFragment.create("my/path")); |
| |
| assertThat(key.getWorkspaceRelativeMappingPath()).isEqualTo(PathFragment.create("my/path")); |
| assertThat(key.wasExplicitlySetByUser()).isTrue(); |
| } |
| |
| private BuildOptions toMappedOptions(BuildConfigurationValue.Key mapped) { |
| return DEFAULT_BUILD_CONFIG_PLATFORM_OPTIONS.applyDiff(mapped.getOptionsDiff()); |
| } |
| |
| private static BuildOptions getDefaultBuildConfigPlatformOptions() { |
| try { |
| return BuildOptions.of(BUILD_CONFIG_PLATFORM_OPTIONS); |
| } catch (OptionsParsingException e) { |
| throw new RuntimeException(e); |
| } |
| } |
| |
| private BuildConfigurationValue.Key keyForOptions(BuildOptions modifiedOptions) { |
| BuildOptions.OptionsDiffForReconstruction diff = |
| BuildOptions.diffForReconstruction(DEFAULT_BUILD_CONFIG_PLATFORM_OPTIONS, modifiedOptions); |
| |
| return BuildConfigurationValue.keyWithoutPlatformMapping(PLATFORM_FRAGMENT_CLASS, diff); |
| } |
| } |