diff options
author | 2015-11-26 15:31:32 +0000 | |
---|---|---|
committer | 2015-11-30 18:25:37 +0000 | |
commit | 886ee6497cc76b6edc0415b3e887dce15b50f6ed (patch) | |
tree | 86bc676404d602e73ab7b3205c0df5238ebe9582 /src/test/java/com/google | |
parent | 10df952870cfc453421af5a61798a2eeaa1bb53a (diff) |
Open-source some tests for cpp rules.
--
MOS_MIGRATED_REVID=108794003
Diffstat (limited to 'src/test/java/com/google')
5 files changed, 814 insertions, 0 deletions
diff --git a/src/test/java/com/google/devtools/build/lib/BUILD b/src/test/java/com/google/devtools/build/lib/BUILD index fdb1029b73..c12e7f17c9 100644 --- a/src/test/java/com/google/devtools/build/lib/BUILD +++ b/src/test/java/com/google/devtools/build/lib/BUILD @@ -829,6 +829,28 @@ java_test( ) java_test( + name = "cpp-rules-tests", + srcs = glob(["rules/cpp/*.java"]), + args = ["com.google.devtools.build.lib.AllTests"], + tags = ["rules"], + deps = [ + ":actions_testutil", + ":analysis_testutil", + ":testutil", + "//src/main/java/com/google/devtools/build/lib:analysis-exec-rules-skyframe", + "//src/main/java/com/google/devtools/build/lib:bazel-core", + "//src/main/java/com/google/devtools/build/lib:vfs", + "//src/main/protobuf:crosstool_config_proto", + "//third_party:guava", + "//third_party:guava-testlib", + "//third_party:jsr305", + "//third_party:junit4", + "//third_party:protobuf", + "//third_party:truth", + ], +) + +java_test( name = "bazel-rules-tests", srcs = glob([ "bazel/rules/**/*.java", diff --git a/src/test/java/com/google/devtools/build/lib/rules/cpp/CcToolchainFeaturesTest.java b/src/test/java/com/google/devtools/build/lib/rules/cpp/CcToolchainFeaturesTest.java new file mode 100644 index 0000000000..f06f34bf82 --- /dev/null +++ b/src/test/java/com/google/devtools/build/lib/rules/cpp/CcToolchainFeaturesTest.java @@ -0,0 +1,545 @@ +// Copyright 2014 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.rules.cpp; + +import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.fail; + +import com.google.common.base.Joiner; +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Multimap; +import com.google.devtools.build.lib.analysis.config.InvalidConfigurationException; +import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.ExpansionException; +import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.FeatureConfiguration; +import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.Variables; +import com.google.devtools.build.lib.testutil.Suite; +import com.google.devtools.build.lib.testutil.TestSpec; +import com.google.devtools.build.lib.testutil.TestUtils; +import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.CToolchain; +import com.google.protobuf.TextFormat; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Set; + +/** + * Tests for toolchain features. + */ +@RunWith(JUnit4.class) +@TestSpec(size = Suite.MEDIUM_TESTS) +public class CcToolchainFeaturesTest { + + /** + * Creates a {@code Variables} configuration from a list of key/value pairs. + * + * <p>If there are multiple entries with the same key, the variable will be treated as sequence + * type. + */ + private Variables createVariables(String... entries) { + if (entries.length % 2 != 0) { + throw new IllegalArgumentException( + "createVariables takes an even number of arguments (key/value pairs)"); + } + Multimap<String, String> entryMap = ArrayListMultimap.create(); + for (int i = 0; i < entries.length; i += 2) { + entryMap.put(entries[i], entries[i + 1]); + } + Variables.Builder variables = new Variables.Builder(); + for (String name : entryMap.keySet()) { + Collection<String> value = entryMap.get(name); + if (value.size() > 1) { + variables.addSequenceVariable(name, value); + } else { + variables.addVariable(name, value.iterator().next()); + } + } + return variables.build(); + } + + private CcToolchainFeatures buildFeatures(String... toolchain) throws Exception { + CToolchain.Builder toolchainBuilder = CToolchain.newBuilder(); + TextFormat.merge(Joiner.on("").join(toolchain), toolchainBuilder); + return new CcToolchainFeatures(toolchainBuilder.buildPartial()); + } + + private Set<String> getEnabledFeatures(CcToolchainFeatures features, + String... requestedFeatures) throws Exception { + FeatureConfiguration configuration = + features.getFeatureConfiguration(Arrays.asList(requestedFeatures)); + ImmutableSet.Builder<String> enabledFeatures = ImmutableSet.builder(); + for (String feature : features.getFeatureNames()) { + if (configuration.isEnabled(feature)) { + enabledFeatures.add(feature); + } + } + return enabledFeatures.build(); + } + + @Test + public void testUnconditionalFeature() throws Exception { + assertThat(buildFeatures("").getFeatureConfiguration("a") + .isEnabled("a")).isFalse(); + assertThat(buildFeatures("feature { name: 'a' }").getFeatureConfiguration("b") + .isEnabled("a")).isFalse(); + assertThat(buildFeatures("feature { name: 'a' }").getFeatureConfiguration("a") + .isEnabled("a")).isTrue(); + } + + @Test + public void testUnsupportedAction() throws Exception { + FeatureConfiguration configuration = buildFeatures("").getFeatureConfiguration(); + assertThat(configuration.getCommandLine("invalid-action", createVariables())).isEmpty(); + } + + @Test + public void testFlagOrderEqualsSpecOrder() throws Exception { + FeatureConfiguration configuration = buildFeatures( + "feature {", + " name: 'a'", + " flag_set {", + " action: 'c++-compile'", + " flag_group { flag: '-a-c++-compile' }", + " }", + " flag_set {", + " action: 'link'", + " flag_group { flag: '-a-c++-compile' }", + " }", + "}", + "feature {", + " name: 'b'", + " flag_set {", + " action: 'c++-compile'", + " flag_group { flag: '-b-c++-compile' }", + " }", + " flag_set {", + " action: 'link'", + " flag_group { flag: '-b-link' }", + " }", + "}").getFeatureConfiguration("a", "b"); + List<String> commandLine = configuration.getCommandLine( + CppCompileAction.CPP_COMPILE, createVariables()); + assertThat(commandLine).containsExactly("-a-c++-compile", "-b-c++-compile").inOrder(); + } + + private String getExpansionOfFlag(String value) throws Exception { + return getExpansionOfFlag(value, createVariables()); + } + + private List<String> getCommandLineForFlagGroups(String groups, Variables variables) + throws Exception { + FeatureConfiguration configuration = buildFeatures( + "feature {", + " name: 'a'", + " flag_set {", + " action: 'c++-compile'", + " " + groups, + " }", + "}").getFeatureConfiguration("a"); + return configuration.getCommandLine(CppCompileAction.CPP_COMPILE, variables); + } + + private List<String> getCommandLineForFlag(String value, Variables variables) throws Exception { + return getCommandLineForFlagGroups("flag_group { flag: '" + value + "' }", variables); + } + + private String getExpansionOfFlag(String value, Variables variables) throws Exception { + return getCommandLineForFlag(value, variables).get(0); + } + + private String getFlagParsingError(String value) throws Exception { + try { + getExpansionOfFlag(value); + fail("Expected InvalidConfigurationException"); + return ""; + } catch (InvalidConfigurationException e) { + return e.getMessage(); + } + } + + private String getFlagExpansionError(String value, Variables variables) throws Exception { + try { + getExpansionOfFlag(value, variables); + fail("Expected ExpansionException"); + return ""; + } catch (ExpansionException e) { + return e.getMessage(); + } + } + + @Test + public void testVariableExpansion() throws Exception { + assertThat(getExpansionOfFlag("%%")).isEqualTo("%"); + assertThat(getExpansionOfFlag("%% a %% b %%")).isEqualTo("% a % b %"); + assertThat(getExpansionOfFlag("%%{var}")).isEqualTo("%{var}"); + assertThat(getExpansionOfFlag("%{v}", createVariables("v", "<flag>"))).isEqualTo("<flag>"); + assertThat(getExpansionOfFlag(" %{v1} %{v2} ", createVariables("v1", "1", "v2", "2"))) + .isEqualTo(" 1 2 "); + assertThat(getFlagParsingError("%")).contains("expected '{'"); + assertThat(getFlagParsingError("% ")).contains("expected '{'"); + assertThat(getFlagParsingError("%{")).contains("expected variable name"); + assertThat(getFlagParsingError("%{}")).contains("expected variable name"); + assertThat(getCommandLineForFlag("%{v}", + new Variables.Builder().addSequenceVariable("v", ImmutableList.<String>of()).build())) + .isEmpty(); + assertThat(getFlagExpansionError("%{v}", createVariables())).contains("unknown variable 'v'"); + assertThat(getFlagExpansionError("%{v}", new Variables.Builder() + .addSequenceVariable("v", ImmutableList.<String>of("1")) + .addVariable("v", "2").build())) + .contains("variable 'v'"); + } + + @Test + public void testListVariableExpansion() throws Exception { + assertThat(getCommandLineForFlag("%{v}", createVariables("v", "1", "v", "2"))) + .containsExactly("1", "2"); + assertThat(getCommandLineForFlag("%{v1} %{v2}", + createVariables("v1", "a1", "v1", "a2", "v2", "b"))) + .containsExactly("a1 b", "a2 b"); + assertThat(getFlagExpansionError("%{v1} %{v2}", + createVariables("v1", "a1", "v1", "a2", "v2", "b1", "v2", "b2"))) + .contains("'v1' and 'v2'"); + } + + @Test + public void testFlagGroupVariableExpansion() throws Exception { + assertThat(getCommandLineForFlagGroups( + "flag_group { flag: '-f' flag: '%{v}' } flag_group { flag: '-end' }", + createVariables("v", "1", "v", "2"))) + .containsExactly("-f", "1", "-f", "2", "-end"); + assertThat(getCommandLineForFlagGroups( + "flag_group { flag: '-f' flag: '%{v}' } flag_group { flag: '%{v}' }", + createVariables("v", "1", "v", "2"))) + .containsExactly("-f", "1", "-f", "2", "1", "2"); + assertThat(getCommandLineForFlagGroups( + "flag_group { flag: '-f' flag: '%{v}' } flag_group { flag: '%{v}' }", + createVariables("v", "1", "v", "2"))) + .containsExactly("-f", "1", "-f", "2", "1", "2"); + try { + getCommandLineForFlagGroups( + "flag_group { flag: '%{v1}' flag: '%{v2}' }", + createVariables("v1", "1", "v1", "2", "v2", "1", "v2", "2")); + fail("Expected ExpansionException"); + } catch (ExpansionException e) { + assertThat(e.getMessage()).contains("'v1' and 'v2'"); + } + } + + private Variables.NestedSequence createNestedSequence(int depth, int count, String prefix) { + Variables.NestedSequence.Builder builder = new Variables.NestedSequence.Builder(); + for (int i = 0; i < count; ++i) { + String value = prefix + String.valueOf(i); + if (depth == 0) { + builder.addValue(value); + } else { + builder.addSequence(createNestedSequence(depth - 1, count, value)); + } + } + return builder.build(); + } + + private Variables createNestedVariables(String name, int depth, int count) { + return new Variables.Builder() + .addSequence(name, createNestedSequence(depth, count, "")).build(); + } + + @Test + public void testFlagTreeVariableExpansion() throws Exception { + String nestedGroup = + "" + + "flag_group {" + + " flag_group { flag: '-a' }" + + " flag_group {" + + " flag: '%{v}'" + + " }" + + " flag_group { flag: '-b' }" + + "}"; + assertThat(getCommandLineForFlagGroups(nestedGroup, createNestedVariables("v", 1, 3))) + .containsExactly( + "-a", "00", "01", "02", "-b", "-a", "10", "11", "12", "-b", "-a", "20", "21", "22", + "-b"); + + assertThat(getCommandLineForFlagGroups(nestedGroup, createNestedVariables("v", 0, 3))) + .containsExactly("-a", "0", "-b", "-a", "1", "-b", "-a", "2", "-b"); + + try { + getCommandLineForFlagGroups(nestedGroup, createNestedVariables("v", 2, 3)); + fail("Expected ExpansionException"); + } catch (ExpansionException e) { + assertThat(e.getMessage()).contains("'v'"); + } + + try { + buildFeatures( + "feature {", + " name: 'a'", + " flag_set {", + " action: 'c++-compile'", + " flag_group {", + " flag_group { flag: '-f' }", + " flag: '-f'", + " }", + " }", + "}"); + fail("Expected ExpansionException"); + } catch (ExpansionException e) { + assertThat(e.getMessage()).contains("Invalid toolchain configuration"); + } + } + + @Test + public void testImplies() throws Exception { + CcToolchainFeatures features = buildFeatures( + "feature { name: 'a' implies: 'b' implies: 'c' }", + "feature { name: 'b' }", + "feature { name: 'c' implies: 'd' }", + "feature { name: 'd' }", + "feature { name: 'e' }"); + assertThat(getEnabledFeatures(features, "a")).containsExactly("a", "b", "c", "d"); + } + + @Test + public void testRequires() throws Exception { + CcToolchainFeatures features = buildFeatures( + "feature { name: 'a' requires: { feature: 'b' } }", + "feature { name: 'b' requires: { feature: 'c' } }", + "feature { name: 'c' }"); + assertThat(getEnabledFeatures(features, "a")).isEmpty(); + assertThat(getEnabledFeatures(features, "a", "b")).isEmpty(); + assertThat(getEnabledFeatures(features, "a", "c")).containsExactly("c"); + assertThat(getEnabledFeatures(features, "a", "b", "c")).containsExactly("a", "b", "c"); + } + + @Test + public void testDisabledRequirementChain() throws Exception { + CcToolchainFeatures features = buildFeatures( + "feature { name: 'a' }", + "feature { name: 'b' requires: { feature: 'c' } implies: 'a' }", + "feature { name: 'c' }"); + assertThat(getEnabledFeatures(features, "b")).isEmpty(); + features = buildFeatures( + "feature { name: 'a' }", + "feature { name: 'b' requires: { feature: 'a' } implies: 'c' }", + "feature { name: 'c' }", + "feature { name: 'd' requires: { feature: 'c' } implies: 'e' }", + "feature { name: 'e' }"); + assertThat(getEnabledFeatures(features, "b", "d")).isEmpty(); + } + + @Test + public void testEnabledRequirementChain() throws Exception { + CcToolchainFeatures features = buildFeatures( + "feature { name: '0' implies: 'a' }", + "feature { name: 'a' }", + "feature { name: 'b' requires: { feature: 'a' } implies: 'c' }", + "feature { name: 'c' }", + "feature { name: 'd' requires: { feature: 'c' } implies: 'e' }", + "feature { name: 'e' }"); + assertThat(getEnabledFeatures(features, "0", "b", "d")).containsExactly( + "0", "a", "b", "c", "d", "e"); + } + + @Test + public void testLogicInRequirements() throws Exception { + CcToolchainFeatures features = buildFeatures( + "feature { name: 'a' requires: { feature: 'b' feature: 'c' } requires: { feature: 'd' } }", + "feature { name: 'b' }", + "feature { name: 'c' }", + "feature { name: 'd' }"); + assertThat(getEnabledFeatures(features, "a", "b", "c")).containsExactly("a", "b", "c"); + assertThat(getEnabledFeatures(features, "a", "b")).containsExactly("b"); + assertThat(getEnabledFeatures(features, "a", "c")).containsExactly("c"); + assertThat(getEnabledFeatures(features, "a", "d")).containsExactly("a", "d"); + } + + @Test + public void testImpliesImpliesRequires() throws Exception { + CcToolchainFeatures features = buildFeatures( + "feature { name: 'a' implies: 'b' }", + "feature { name: 'b' requires: { feature: 'c' } }", + "feature { name: 'c' }"); + assertThat(getEnabledFeatures(features, "a")).isEmpty(); + } + + @Test + public void testMultipleImplies() throws Exception { + CcToolchainFeatures features = buildFeatures( + "feature { name: 'a' implies: 'b' implies: 'c' implies: 'd' }", + "feature { name: 'b' }", + "feature { name: 'c' requires: { feature: 'e' } }", + "feature { name: 'd' }", + "feature { name: 'e' }"); + assertThat(getEnabledFeatures(features, "a")).isEmpty(); + assertThat(getEnabledFeatures(features, "a", "e")).containsExactly("a", "b", "c", "d", "e"); + } + + @Test + public void testDisabledFeaturesDoNotEnableImplications() throws Exception { + CcToolchainFeatures features = buildFeatures( + "feature { name: 'a' implies: 'b' requires: { feature: 'c' } }", + "feature { name: 'b' }", + "feature { name: 'c' }"); + assertThat(getEnabledFeatures(features, "a")).isEmpty(); + } + + @Test + public void testFeatureNameCollision() throws Exception { + try { + buildFeatures( + "feature { name: '<<<collision>>>' }", + "feature { name: '<<<collision>>>' }"); + fail("Expected InvalidConfigurationException"); + } catch (InvalidConfigurationException e) { + assertThat(e.getMessage()).contains("<<<collision>>>"); + } + } + + @Test + public void testReferenceToUndefinedFeature() throws Exception { + try { + buildFeatures("feature { name: 'a' implies: '<<<undefined>>>' }"); + fail("Expected InvalidConfigurationException"); + } catch (InvalidConfigurationException e) { + assertThat(e.getMessage()).contains("<<<undefined>>>"); + } + } + + @Test + public void testImpliesWithCycle() throws Exception { + CcToolchainFeatures features = buildFeatures( + "feature { name: 'a' implies: 'b' }", + "feature { name: 'b' implies: 'a' }"); + assertThat(getEnabledFeatures(features, "a")).containsExactly("a", "b"); + assertThat(getEnabledFeatures(features, "b")).containsExactly("a", "b"); + } + + @Test + public void testMultipleImpliesCycle() throws Exception { + CcToolchainFeatures features = buildFeatures( + "feature { name: 'a' implies: 'b' implies: 'c' implies: 'd' }", + "feature { name: 'b' }", + "feature { name: 'c' requires: { feature: 'e' } }", + "feature { name: 'd' requires: { feature: 'f' } }", + "feature { name: 'e' requires: { feature: 'c' } }", + "feature { name: 'f' }"); + assertThat(getEnabledFeatures(features, "a", "e")).isEmpty(); + assertThat(getEnabledFeatures(features, "a", "e", "f")).containsExactly( + "a", "b", "c", "d", "e", "f"); + } + + @Test + public void testRequiresWithCycle() throws Exception { + CcToolchainFeatures features = buildFeatures( + "feature { name: 'a' requires: { feature: 'b' } }", + "feature { name: 'b' requires: { feature: 'a' } }", + "feature { name: 'c' implies: 'a' }", + "feature { name: 'd' implies: 'b' }"); + assertThat(getEnabledFeatures(features, "c")).isEmpty(); + assertThat(getEnabledFeatures(features, "d")).isEmpty(); + assertThat(getEnabledFeatures(features, "c", "d")).containsExactly("a", "b", "c", "d"); + } + + @Test + public void testImpliedByOneEnabledAndOneDisabledFeature() throws Exception { + CcToolchainFeatures features = buildFeatures( + "feature { name: 'a' }", + "feature { name: 'b' requires: { feature: 'a' } implies: 'd' }", + "feature { name: 'c' implies: 'd' }", + "feature { name: 'd' }"); + assertThat(getEnabledFeatures(features, "b", "c")).containsExactly("c", "d"); + } + + @Test + public void testRequiresOneEnabledAndOneUnsupportedFeature() throws Exception { + CcToolchainFeatures features = buildFeatures( + "feature { name: 'a' requires: { feature: 'b' } requires: { feature: 'c' } }", + "feature { name: 'b' }", + "feature { name: 'c' requires: { feature: 'd' } }", + "feature { name: 'd' }"); + assertThat(getEnabledFeatures(features, "a", "b", "c")).containsExactly("a", "b"); + } + + @Test + public void testSuppressionViaMissingBuildVariable() throws Exception { + FeatureConfiguration configuration = + buildFeatures( + "feature {", + " name: 'a'", + " flag_set {", + " action: 'c++-compile'", + " expand_if_all_available: 'v'", + " flag_group { flag: '%{v}' }", + " }", + " flag_set {", + " action: 'c++-compile'", + " expand_if_all_available: 'v'", + " expand_if_all_available: 'w'", + " flag_group { flag: '%{v}%{w}' }", + " }", + " flag_set {", + " action: 'c++-compile'", + " flag_group { flag: 'unconditional' }", + " }", + "}") + .getFeatureConfiguration("a"); + + assertThat(configuration.getCommandLine(CppCompileAction.CPP_COMPILE, createVariables())) + .containsExactly("unconditional"); + assertThat( + configuration.getCommandLine(CppCompileAction.CPP_COMPILE, createVariables("v", "1"))) + .containsExactly("1", "unconditional"); + assertThat( + configuration.getCommandLine( + CppCompileAction.CPP_COMPILE, createVariables("v", "1", "v", "2"))) + .containsExactly("1", "2", "unconditional") + .inOrder(); + assertThat( + configuration.getCommandLine( + CppCompileAction.CPP_COMPILE, createVariables("v", "1", "v", "2", "w", "3"))) + .containsExactly("1", "2", "13", "23", "unconditional") + .inOrder(); + } + + @Test + public void testConfiguration() throws Exception { + CcToolchainFeatures features = buildFeatures( + "feature {", + " name: 'a'", + " flag_set {", + " action: 'c++-compile'", + " flag_group {", + " flag: '-f'", + " flag: '%{v}'", + " }", + " }", + "}", + "feature { name: 'b' implies: 'a' }"); + assertThat(getEnabledFeatures(features, "b")).containsExactly("a", "b"); + assertThat(features.getFeatureConfiguration("b").getCommandLine(CppCompileAction.CPP_COMPILE, + createVariables("v", "1"))).containsExactly("-f", "1"); + byte[] serialized = TestUtils.serializeObject(features); + CcToolchainFeatures deserialized = + (CcToolchainFeatures) TestUtils.deserializeObject(serialized); + assertThat(getEnabledFeatures(deserialized, "b")).containsExactly("a", "b"); + assertThat(features.getFeatureConfiguration("b").getCommandLine(CppCompileAction.CPP_COMPILE, + createVariables("v", "1"))).containsExactly("-f", "1"); + } +} diff --git a/src/test/java/com/google/devtools/build/lib/rules/cpp/CcToolchainSuiteTest.java b/src/test/java/com/google/devtools/build/lib/rules/cpp/CcToolchainSuiteTest.java new file mode 100644 index 0000000000..6cca877891 --- /dev/null +++ b/src/test/java/com/google/devtools/build/lib/rules/cpp/CcToolchainSuiteTest.java @@ -0,0 +1,118 @@ +// Copyright 2014 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.rules.cpp; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.devtools.build.lib.analysis.util.BuildViewTestCaseForJunit4; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** + * Unit tests for the {@code cc_toolchain_suite} rule. + */ +@RunWith(JUnit4.class) +public class CcToolchainSuiteTest extends BuildViewTestCaseForJunit4 { + @Test + public void testSmoke() throws Exception { + scratch.file("cc/BUILD", + "cc_toolchain_suite(", + " name = 'suite',", + " toolchains = { ", + " 'cpu': ':cc-toolchain', 'k8': ':cc-toolchain', 'darwin': ':cc-toolchain' ", + " },", + " proto = \"\"\"", + "major_version: 'v1'", + "minor_version: '0'", + "default_target_cpu: 'cpu'", + "default_toolchain {", + " cpu: 'cpu'", + " toolchain_identifier: 'cpu-toolchain'", + "}", + "default_toolchain {", + " cpu: 'darwin'", + " toolchain_identifier: 'cpu-toolchain'", + "}", + "default_toolchain {", + " cpu: 'k8'", + " toolchain_identifier: 'k8-toolchain'", + "}", + "toolchain {", + " compiler: 'cpu-compiler'", + " target_cpu: 'cpu'", + " toolchain_identifier: 'cpu-toolchain'", + " host_system_name: 'linux'", + " target_system_name: 'linux'", + " abi_version: 'cpu-abi'", + " abi_libc_version: ''", + " target_libc: ''", + " builtin_sysroot: 'sysroot'", + " default_grte_top: '//cc:grtetop'", + " tool_path { name: 'cpu-compiler', path: 'cpu/compiler' }", + " tool_path { name: 'ar', path: 'cpu/ar' }", + " tool_path { name: 'cpp', path: 'cpu/cpp' }", + " tool_path { name: 'gcc', path: 'cpu/gcc' }", + " tool_path { name: 'gcov', path: 'cpu/gcov' }", + " tool_path { name: 'ld', path: 'cpu/ld' }", + " tool_path { name: 'nm', path: 'cpu/nm' }", + " tool_path { name: 'objcopy', path: 'cpu/objcopy' }", + " tool_path { name: 'objdump', path: 'cpu/objdump' }", + " tool_path { name: 'strip', path: 'cpu/strip' }", + "}", + "toolchain {", + " compiler: 'k8-compiler'", + " target_cpu: 'k8'", + " toolchain_identifier: 'k8-toolchain'", + " host_system_name: 'linux'", + " target_system_name: 'linux'", + " abi_version: ''", + " abi_libc_version: ''", + " target_libc: ''", + " builtin_sysroot: 'sysroot'", + " default_grte_top: '//cc:grtetop'", + " tool_path { name: 'k8-compiler', path: 'k8/compiler' }", + " tool_path { name: 'ar', path: 'k8/ar' }", + " tool_path { name: 'cpp', path: 'k8/cpp' }", + " tool_path { name: 'gcc', path: 'k8/gcc' }", + " tool_path { name: 'gcov', path: 'k8/gcov' }", + " tool_path { name: 'ld', path: 'k8/ld' }", + " tool_path { name: 'nm', path: 'k8/nm' }", + " tool_path { name: 'objcopy', path: 'k8/objcopy' }", + " tool_path { name: 'objdump', path: 'k8/objdump' }", + " tool_path { name: 'strip', path: 'k8/strip' }", + "}", + "\"\"\")", + "cc_toolchain(", + " name = 'cc-toolchain',", + " module_map = 'map',", + " cpu = 'cpu',", + " compiler_files = 'compile',", + " dwp_files = 'dwp',", + " linker_files = 'link',", + " strip_files = ':strip',", + " objcopy_files = 'objcopy',", + " all_files = ':every-file',", + " dynamic_runtime_libs = ['dynamic-runtime-libs'],", + " static_runtime_libs = ['static-runtime-libs'])"); + + invalidatePackages(); + useConfiguration("--crosstool_top=//cc:suite"); + CppConfiguration cppConfig = getTargetConfiguration().getFragment(CppConfiguration.class); + assertThat(cppConfig.getTargetCpu()).isEqualTo("cpu"); + assertThat(cppConfig.getAbi()).isEqualTo("cpu-abi"); + } +} diff --git a/src/test/java/com/google/devtools/build/lib/rules/cpp/CcToolchainTest.java b/src/test/java/com/google/devtools/build/lib/rules/cpp/CcToolchainTest.java new file mode 100644 index 0000000000..9099dbd721 --- /dev/null +++ b/src/test/java/com/google/devtools/build/lib/rules/cpp/CcToolchainTest.java @@ -0,0 +1,79 @@ +// Copyright 2014 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.rules.cpp; + +import com.google.devtools.build.lib.analysis.util.BuildViewTestCaseForJunit4; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** + * Tests for toolchain features. + */ +@RunWith(JUnit4.class) +public class CcToolchainTest extends BuildViewTestCaseForJunit4 { + + @Test + public void testModuleMapAttribute() throws Exception { + scratchConfiguredTarget("modules/map", "c", + "cc_toolchain(", + " name = 'c',", + " module_map = 'map',", + " cpu = 'cherry',", + " compiler_files = 'compile-cherry',", + " dwp_files = 'dwp-cherry',", + " linker_files = 'link-cherry',", + " strip_files = ':every-file',", + " objcopy_files = 'objcopy-cherry',", + " all_files = ':every-file',", + " dynamic_runtime_libs = ['dynamic-runtime-libs-cherry'],", + " static_runtime_libs = ['static-runtime-libs-cherry'])"); + } + + @Test + public void testModuleMapAttributeOptional() throws Exception { + scratchConfiguredTarget("modules/map", "c", + "cc_toolchain(", + " name = 'c',", + " cpu = 'cherry',", + " compiler_files = 'compile-cherry',", + " dwp_files = 'dwp-cherry',", + " linker_files = 'link-cherry',", + " strip_files = ':every-file',", + " objcopy_files = 'objcopy-cherry',", + " all_files = ':every-file',", + " dynamic_runtime_libs = ['dynamic-runtime-libs-cherry'],", + " static_runtime_libs = ['static-runtime-libs-cherry'])"); + } + + @Test + public void testFailWithMultipleModuleMaps() throws Exception { + checkError("modules/multiple", "c", "expected a single artifact", + "filegroup(name = 'multiple-maps', srcs = ['a.cppmap', 'b.cppmap'])", + "cc_toolchain(", + " name = 'c',", + " module_map = ':multiple-maps',", + " cpu = 'cherry',", + " compiler_files = 'compile-cherry',", + " dwp_files = 'dwp-cherry',", + " linker_files = 'link-cherry',", + " strip_files = ':every-file',", + " objcopy_files = 'objcopy-cherry',", + " all_files = ':every-file',", + " dynamic_runtime_libs = ['dynamic-runtime-libs-cherry'],", + " static_runtime_libs = ['static-runtime-libs-cherry'])"); + } +} diff --git a/src/test/java/com/google/devtools/build/lib/rules/cpp/CppFileTypesTest.java b/src/test/java/com/google/devtools/build/lib/rules/cpp/CppFileTypesTest.java new file mode 100644 index 0000000000..7970273005 --- /dev/null +++ b/src/test/java/com/google/devtools/build/lib/rules/cpp/CppFileTypesTest.java @@ -0,0 +1,50 @@ +// Copyright 2014 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.rules.cpp; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** + * Test for {@link CppFileTypes}. + */ +@RunWith(JUnit4.class) +public class CppFileTypesTest { + + @Test + public void testTwoDotExtensions() { + assertTrue(CppFileTypes.OBJECT_FILE.matches("test.o")); + assertTrue(CppFileTypes.PIC_OBJECT_FILE.matches("test.pic.o")); + assertFalse(CppFileTypes.OBJECT_FILE.matches("test.pic.o")); + } + + @Test + public void testVersionedSharedLibraries() { + assertTrue(CppFileTypes.SHARED_LIBRARY.matches("somelibrary.so")); + assertTrue(CppFileTypes.VERSIONED_SHARED_LIBRARY.matches("somelibrary.so.2")); + assertTrue(CppFileTypes.VERSIONED_SHARED_LIBRARY.matches("somelibrary.so.20")); + assertTrue(CppFileTypes.VERSIONED_SHARED_LIBRARY.matches("somelibrary.so.20.2")); + assertTrue(CppFileTypes.VERSIONED_SHARED_LIBRARY.matches("a/somelibrary.so.2")); + assertFalse(CppFileTypes.VERSIONED_SHARED_LIBRARY.matches("somelibrary.so.e")); + assertFalse(CppFileTypes.VERSIONED_SHARED_LIBRARY.matches("somelibrary.so.2e")); + assertFalse(CppFileTypes.VERSIONED_SHARED_LIBRARY.matches("somelibrary.so.e2")); + assertFalse(CppFileTypes.VERSIONED_SHARED_LIBRARY.matches("somelibrary.so.20.e2")); + assertFalse(CppFileTypes.VERSIONED_SHARED_LIBRARY.matches("somelibrary.a.2")); + } +} |