diff options
author | 2016-08-08 15:47:58 +0000 | |
---|---|---|
committer | 2016-08-09 09:00:24 +0000 | |
commit | d3d3266a33335fe232c84a0db4251aefa5bfe2e8 (patch) | |
tree | 4e8649f203fe1951c59391e8644f284ce268104d /src/test | |
parent | 4257ff9d3d24ceb10d1d88166c0a8a8d6a30d2b5 (diff) |
Add a builder-like mechanism for writing targets to a Scratch instance that is
usable across front-end types.
--
MOS_MIGRATED_REVID=129633711
Diffstat (limited to 'src/test')
3 files changed, 245 insertions, 15 deletions
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewTestCase.java b/src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewTestCase.java index 4fdde18aab..8f80ee614d 100644 --- a/src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewTestCase.java +++ b/src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewTestCase.java @@ -669,12 +669,12 @@ public abstract class BuildViewTestCase extends FoundationTestCase { } /** - * Returns the ConfiguredTarget for the specified label, configured for the - * "build" (aka "target") configuration. + * Returns the ConfiguredTarget for the specified label, configured for the "build" (aka "target") + * configuration. */ - protected ConfiguredTarget getConfiguredTarget(String label) - throws NoSuchPackageException, NoSuchTargetException, - LabelSyntaxException, InterruptedException { + public ConfiguredTarget getConfiguredTarget(String label) + throws NoSuchPackageException, NoSuchTargetException, LabelSyntaxException, + InterruptedException { return getConfiguredTarget(label, targetConfig); } diff --git a/src/test/java/com/google/devtools/build/lib/analysis/util/ScratchAttributeWriter.java b/src/test/java/com/google/devtools/build/lib/analysis/util/ScratchAttributeWriter.java new file mode 100644 index 0000000000..bec2ce7c2b --- /dev/null +++ b/src/test/java/com/google/devtools/build/lib/analysis/util/ScratchAttributeWriter.java @@ -0,0 +1,226 @@ +// Copyright 2016 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.util; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.devtools.build.lib.analysis.ConfiguredTarget; +import com.google.devtools.build.lib.analysis.config.BuildConfiguration; +import com.google.devtools.build.lib.cmdline.Label; +import com.google.devtools.build.lib.testutil.Scratch; +import java.io.IOException; +import java.util.Arrays; + +/** + * A writer for a scratch build target and associated source files. Can be parameterized with a rule + * type for which to write a mock target. + * + * <p>For example, the snippet: + * + * <pre>{@code + * new ScratchAttributeWriter(testCase, "cc_library", "//x:x") + * .setList("srcs", "a.cc", "b.cc") + * .setList("hdrs", "hdr.h") + * .write(); + * }</pre> + * + * <p>Would create the BUILD file "x/BUILD" with contents: + * + * <pre>{@code + * cc_library( + * name = 'x', + * srcs = ['a.cc', 'b.cc'], + * hdrs = ['hdr.h'], + * ) + * }</pre> + */ +public class ScratchAttributeWriter { + + private abstract static class ScratchAttribute<T> { + protected String attributeName; + protected T attributeValue; + + abstract StringBuilder appendLine(StringBuilder builder); + } + + /** A plain string attribute. */ + private static class StringAttribute extends ScratchAttribute<String> { + public StringAttribute(String attributeName, String attributeValue) { + this.attributeName = attributeName; + this.attributeValue = attributeValue; + } + + @Override + StringBuilder appendLine(StringBuilder builder) { + return builder.append(String.format("%s=%s,", attributeName, attributeValue)); + } + } + + /** An integer attribute, such as "alwayslink" */ + private static class IntegerAttribute extends ScratchAttribute<Integer> { + + public IntegerAttribute(String attributeName, Integer attributeValue) { + this.attributeName = attributeName; + this.attributeValue = attributeValue; + } + + @Override + StringBuilder appendLine(StringBuilder builder) { + return builder.append(String.format("%s=%d,", attributeName, attributeValue)); + } + } + + /** A list attribute, such as "srcs" */ + private static class StringListAttribute extends ScratchAttribute<Iterable<String>> { + + public StringListAttribute(String attributeName, Iterable<String> attributeValue) { + this.attributeName = attributeName; + this.attributeValue = attributeValue; + } + + @Override + StringBuilder appendLine(StringBuilder builder) { + builder.append(String.format("%s=[", attributeName)); + for (String value : attributeValue) { + builder.append(String.format("'%s',", value)); + } + builder.append("],"); + return builder; + } + } + + /** The name of the package. */ + private final String packageName; + + /** The name of the target. */ + private final String targetName; + + /** The test case for which to write this target. */ + private final BuildViewTestCase testCase; + + /** The name of the rule for this target */ + private final String ruleName; + + /** An ordered list of the attributes to be written for this scratch target */ + StringBuilder buildString; + + /** + * Creates a ScratchAttributeWriter for a given test case, package name, and target name. The + * provided rule name will determine the type of the target written. + */ + private ScratchAttributeWriter( + BuildViewTestCase testCase, String ruleName, String packageName, String targetName) { + this.testCase = checkNotNull(testCase); + this.ruleName = checkNotNull(ruleName); + this.packageName = checkNotNull(packageName); + this.targetName = checkNotNull(targetName); + this.buildString = + new StringBuilder() + .append(String.format("%s(", this.ruleName)) + .append(String.format("name='%s',", this.targetName)); + } + + /** + * Creates a ScratchAttributeWriter for a given test case and label. The provided rule name will + * determine the type of the target written. + */ + public static ScratchAttributeWriter fromLabel( + BuildViewTestCase testCase, String ruleName, Label label) { + return new ScratchAttributeWriter(testCase, ruleName, label.getPackageName(), label.getName()); + } + + /** + * Creates a ScratchAttributeWriter for a given test case and label string. The provided rule name + * will determine the type of the target written. + */ + public static ScratchAttributeWriter fromLabelString( + BuildViewTestCase testCase, String ruleName, String labelString) { + return fromLabel(testCase, ruleName, Label.parseAbsoluteUnchecked(labelString)); + } + + /** + * Writes this scratch target to this ScratchAttributeWriter's Scratch instance, and returns the + * target in the given configuration. + */ + public ConfiguredTarget write(BuildConfiguration config) throws Exception { + Scratch scratch = testCase.getScratch(); + + buildString.append(")"); + + scratch.file(String.format("%s/BUILD", packageName), buildString.toString()); + return testCase.getConfiguredTarget(String.format("//%s:%s", packageName, targetName), config); + } + + /** + * Writes this scratch target to this ScratchAttributeWriter's Scratch instance, and returns the + * target in the target configuration. + */ + public ConfiguredTarget write() throws Exception { + return write(testCase.getTargetConfiguration()); + } + + private void createSource(String source) throws IOException { + testCase.getScratch().file(String.format("%s/%s", packageName, source)); + } + + /** Sets a string attribute (like ios_application.app_icon) for this target. */ + public ScratchAttributeWriter set(String name, String value) { + new StringAttribute(name, value).appendLine(this.buildString); + return this; + } + + /** Sets a list attribute (like cc_library.srcs) for this target. */ + public ScratchAttributeWriter setList(String name, Iterable<String> value) { + new StringListAttribute(name, value).appendLine(this.buildString); + return this; + } + + /** Sets a list attribute (like cc_library.srcs) for this target */ + public ScratchAttributeWriter setList(String name, String... value) { + return setList(name, Arrays.asList(value)); + } + + /** Sets an integer attribute (like cc_binary.linkstatic) for this target. */ + public ScratchAttributeWriter set(String name, int value) { + new IntegerAttribute(name, value).appendLine(this.buildString); + return this; + } + + /** + * Sets a list attribute (link cc_library.srcs) for this target. For each string in 'value', + * writes an empty file to this writer's package with that name. + * + * <p>Usually, an analysis-time should not require that referenced files actually be written, in + * which case ScratchAttributeWriter#set should be used instead. + */ + public ScratchAttributeWriter setAndCreateFiles(String name, Iterable<String> value) + throws IOException { + for (String source : value) { + createSource(source); + } + return setList(name, value); + } + + /** + * Sets a list attribute (link cc_library.srcs) for this target. For each string in 'value', + * writes an empty file to this writer's package with that name. + * + * <p>Usually, an analysis-time should not require that referenced files actually be written, in + * which case ScratchAttributeWriter#set should be used instead. + */ + public ScratchAttributeWriter setAndCreateFiles(String name, String... value) throws IOException { + return setAndCreateFiles(name, Arrays.asList(value)); + } +} diff --git a/src/test/java/com/google/devtools/build/lib/testutil/FoundationTestCase.java b/src/test/java/com/google/devtools/build/lib/testutil/FoundationTestCase.java index 689b822878..098a4dd5c6 100644 --- a/src/test/java/com/google/devtools/build/lib/testutil/FoundationTestCase.java +++ b/src/test/java/com/google/devtools/build/lib/testutil/FoundationTestCase.java @@ -24,12 +24,10 @@ import com.google.devtools.build.lib.util.BlazeClock; import com.google.devtools.build.lib.vfs.FileSystem; import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.lib.vfs.inmemoryfs.InMemoryFileSystem; - +import java.util.Set; import org.junit.After; import org.junit.Before; -import java.util.Set; - /** * A helper class for implementing tests of the "foundation" library. */ @@ -42,16 +40,22 @@ public abstract class FoundationTestCase { protected EventCollector eventCollector; protected Scratch scratch; + /** Returns the Scratch instance for this test case. */ + public Scratch getScratch() { + return scratch; + } + // Individual tests can opt-out of this handler if they expect an error, by // calling reporter.removeHandler(failFastHandler). - protected static final EventHandler failFastHandler = new EventHandler() { - @Override - public void handle(Event event) { - if (EventKind.ERRORS.contains(event.getKind())) { - fail(event.toString()); + protected static final EventHandler failFastHandler = + new EventHandler() { + @Override + public void handle(Event event) { + if (EventKind.ERRORS.contains(event.getKind())) { + fail(event.toString()); + } } - } - }; + }; protected static final EventHandler printHandler = new EventHandler() { @Override |