diff options
author | Dmitry Lomov <dslomov@google.com> | 2015-11-23 18:07:34 +0000 |
---|---|---|
committer | Philipp Wollermann <philwo@google.com> | 2015-11-24 14:40:59 +0000 |
commit | 18212f10f2bbb6a29c5c1f112e0a43b92071b11c (patch) | |
tree | 89f61f3efd93b7012484002445c34269befb8cd3 /src | |
parent | f4cd47590f24c4ff5ebc681b8fc9a483d8da6251 (diff) |
Open-source CompilationHelperTest.
--
MOS_MIGRATED_REVID=108516475
Diffstat (limited to 'src')
-rw-r--r-- | src/test/java/com/google/devtools/build/lib/analysis/CompilationHelperTest.java | 170 | ||||
-rw-r--r-- | src/test/java/com/google/devtools/build/lib/analysis/mock/BazelAnalysisMock.java | 10 |
2 files changed, 178 insertions, 2 deletions
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/CompilationHelperTest.java b/src/test/java/com/google/devtools/build/lib/analysis/CompilationHelperTest.java new file mode 100644 index 0000000000..d5f08d51f5 --- /dev/null +++ b/src/test/java/com/google/devtools/build/lib/analysis/CompilationHelperTest.java @@ -0,0 +1,170 @@ +// Copyright 2015 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; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.collect.Iterables; +import com.google.devtools.build.lib.actions.Artifact; +import com.google.devtools.build.lib.actions.util.ActionsTestUtil; +import com.google.devtools.build.lib.actions.util.ActionsTestUtil.UncheckedActionConflictException; +import com.google.devtools.build.lib.analysis.config.BuildConfiguration; +import com.google.devtools.build.lib.analysis.util.AnalysisTestUtil; +import com.google.devtools.build.lib.analysis.util.BuildViewTestCase; +import com.google.devtools.build.lib.rules.cpp.CppHelper; + +import java.io.IOException; +import java.util.List; + +/** + * Unit tests for the {@link CompilationHelper} class. + */ +public class CompilationHelperTest extends BuildViewTestCase { + private AnalysisTestUtil.CollectingAnalysisEnvironment analysisEnvironment; + + @Override + protected void setUp() throws Exception { + super.setUp(); + analysisEnvironment = + new AnalysisTestUtil.CollectingAnalysisEnvironment(getTestAnalysisEnvironment()); + } + + private List<Artifact> getAggregatingMiddleman( + ConfiguredTarget rule, BuildConfiguration configuration, boolean withSolib) throws Exception { + return CppHelper.getAggregatingMiddlemanForTesting( + analysisEnvironment, + getRuleContext(rule), + ActionsTestUtil.NULL_ACTION_OWNER, + "middleman", + rule, + withSolib, + configuration); + } + + private List<Artifact> getAggregatingMiddleman(ConfiguredTarget rule, boolean withSolib) + throws Exception { + return getAggregatingMiddleman(rule, rule.getConfiguration(), withSolib); + } + + /** + * Tests that duplicate calls to + * {@link com.google.devtools.build.lib.analysis.CompilationHelper#getAggregatingMiddleman} + * with identical parameters return the same artifact. + */ + public void testDuplicateCallsReturnSameObject() throws Exception { + ConfiguredTarget rule = + scratchConfiguredTarget("package", "a", "cc_binary(name = 'a'," + " srcs = ['a.cc'])"); + List<Artifact> middleman1 = getAggregatingMiddleman(rule, false); + assertThat(middleman1).hasSize(1); + List<Artifact> middleman2 = getAggregatingMiddleman(rule, false); + assertThat(middleman2).hasSize(1); + assertEquals(middleman1.get(0), middleman2.get(0)); + } + + /** + * Tests that + * {@link com.google.devtools.build.lib.analysis.CompilationHelper#getAggregatingMiddleman} + * returns distinct artifacts even when called with identical rules, depending on + * whether solib symlink are created. + */ + public void testMiddlemanAndSolibMiddlemanAreDistinct() throws Exception { + ConfiguredTarget rule = + scratchConfiguredTarget("package", "a", "cc_binary(name = 'a'," + " srcs = ['a.cc'])"); + + List<Artifact> middleman = getAggregatingMiddleman(rule, false); + assertThat(middleman).hasSize(1); + List<Artifact> middlemanWithSymlinks = getAggregatingMiddleman(rule, true); + assertThat(middlemanWithSymlinks).hasSize(1); + assertNotSame(middleman.get(0), middlemanWithSymlinks.get(0)); + } + + /** + * Regression test: tests that Python CPU configurations are taken into account + * when generating a rule's aggregating middleman, so that otherwise equivalent rules can sustain + * distinct middlemen. + */ + public void testPythonCcConfigurations() throws Exception { + setupJavaPythonCcConfigurationFiles(); + + // Equivalent cc / Python configurations: + + ConfiguredTarget ccRuleA = getConfiguredTarget("//foo:a"); + List<Artifact> middleman1 = getAggregatingMiddleman(ccRuleA, true); + try { + ConfiguredTarget ccRuleB = getConfiguredTarget("//foo:b"); + getAggregatingMiddleman(ccRuleB, true); + analysisEnvironment.registerWith(getMutableActionGraph()); + fail("Expected ActionConflictException due to same middleman artifact with different files"); + } catch (UncheckedActionConflictException e) { + // Expected failure: same "purpose" and root directory sent to the middleman generator + // (which results in the same output artifact), but different rules / middleman inputs. + } + + // This should succeed because the py_binary's middleman is under the Python configuration's + // internal directory, while the cc_binary's middleman is under the cc config's directory, + // and both configurations are the same. + ConfiguredTarget pyRuleC = getConfiguredTarget("//foo:c"); + List<Artifact> middleman2 = getAggregatingMiddleman(pyRuleC, true); + assertEquals( + Iterables.getOnlyElement(middleman1).getExecPathString(), + Iterables.getOnlyElement(middleman2).getExecPathString()); + } + + /** + * Regression test: tests that Java CPU configurations are taken into account when + * generating a rule's aggregating middleman, so that otherwise equivalent rules can sustain + * distinct middlemen. + */ + public void testJavaCcConfigurations() throws Exception { + setupJavaPythonCcConfigurationFiles(); + + // Equivalent cc / Java configurations: + + ConfiguredTarget ccRuleA = getConfiguredTarget("//foo:a"); + List<Artifact> middleman1 = getAggregatingMiddleman(ccRuleA, true); + try { + ConfiguredTarget ccRuleB = getConfiguredTarget("//foo:b"); + getAggregatingMiddleman(ccRuleB, true); + analysisEnvironment.registerWith(getMutableActionGraph()); + fail("Expected ActionConflictException due to same middleman artifact with different files"); + } catch (UncheckedActionConflictException e) { + // Expected failure: same "purpose" and root directory sent to the middleman generator + // (which results in the same output artifact), but different rules / middleman inputs. + } + + // This should succeed because the java_binary's middleman is under the Java configuration's + // internal directory, while the cc_binary's middleman is under the cc config's directory. + ConfiguredTarget javaRuleD = getConfiguredTarget("//foo:d"); + List<Artifact> middleman2 = getAggregatingMiddleman(javaRuleD, false); + assertFalse( + Iterables.getOnlyElement(middleman1) + .getExecPathString() + .equals(Iterables.getOnlyElement(middleman2).getExecPathString())); + } + + private void setupJavaPythonCcConfigurationFiles() throws IOException { + scratch.file( + "foo/BUILD", + "cc_binary(name = 'a',", + " srcs = ['a.cc'])", + "cc_binary(name = 'b',", + " srcs = ['b.cc'])", + "py_binary(name = 'c',", + " srcs = ['c.py'])", + "java_binary(name = 'd',", + " srcs = ['d.java'],", + " main_class = 'd')"); + } +} diff --git a/src/test/java/com/google/devtools/build/lib/analysis/mock/BazelAnalysisMock.java b/src/test/java/com/google/devtools/build/lib/analysis/mock/BazelAnalysisMock.java index be529acddb..65f4c90824 100644 --- a/src/test/java/com/google/devtools/build/lib/analysis/mock/BazelAnalysisMock.java +++ b/src/test/java/com/google/devtools/build/lib/analysis/mock/BazelAnalysisMock.java @@ -71,8 +71,8 @@ public final class BazelAnalysisMock extends AnalysisMock { " actual = '//objcproto:ProtocolBuffersCPP_lib',", ")", "bind(name = 'android/sdk', actual='//tools/android:sdk')", - "bind(name = 'tools/cpp', actual='//tools/cpp')" - )); + "bind(name = 'tools/cpp', actual='//tools/cpp')", + "bind(name = 'tools/python', actual='//tools/python')")); config.overwrite("WORKSPACE", workspaceContents.toArray(new String[workspaceContents.size()])); config.create("tools/jdk/BUILD", @@ -140,6 +140,12 @@ public final class BazelAnalysisMock extends AnalysisMock { " jars = [ 'jarjar.jar' ])"); config.create("tools/test/BUILD", "filegroup(name = 'runtime')"); + + config.create( + "tools/python/BUILD", + "package(default_visibility=['//visibility:public'])", + "exports_files(['precompile.py'])", + "sh_binary(name='2to3', srcs=['2to3.sh'])"); } private ImmutableList<String> createAndroidBuildContents() { |