blob: 1ed883838a476d3486c96b2dd07342ef015083ff [file] [log] [blame]
// Copyright 2017 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.bazel.e4b.integration;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.HashMap;
import java.util.Map;
import org.junit.Before;
import org.junit.BeforeClass;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
import com.google.devtools.bazel.e4b.command.Command;
/** A base class to do integration test that call Bazel */
public abstract class BazelBaseTestCase {
protected final static Joiner PATH_JOINER = Joiner.on(File.separator);
protected final static Joiner LINE_JOINER = Joiner.on("\n");
private static File tmp;
private static Map<String, File> bazelVersions;
private static File runfileDirectory = new File(System.getenv("TEST_SRCDIR"));
private File currentBazel = null;
/** The current workspace. */
protected File workspace = null;
public static class BazelTestCaseException extends Exception {
private static final long serialVersionUID = 1L;
private BazelTestCaseException(String message) {
super(message);
}
}
@BeforeClass
public static void setUpClass() throws IOException {
// Get tempdir
String _tmp = System.getenv("TEST_TMPDIR");
if (_tmp == null) {
File p = Files.createTempDirectory("e4b-tests").toFile();
p.deleteOnExit();
tmp = p;
} else {
tmp = new File(_tmp);
}
bazelVersions = new HashMap<>();
}
/** Return a file in the runfiles whose path segments are given by the arguments. */
protected static File getRunfile(String... segments) {
return new File(PATH_JOINER.join(runfileDirectory, PATH_JOINER.join(segments)));
}
private static void unpackBazel(String version)
throws BazelTestCaseException, IOException, InterruptedException {
if (!bazelVersions.containsKey(version)) {
// Get bazel location
File bazelFile = getRunfile("build_bazel_bazel_" + version.replace('.', '_') + "/bazel");
if (!bazelFile.exists()) {
throw new BazelTestCaseException(
"Bazel version " + version + " not found");
}
bazelVersions.put(version, bazelFile);
// Unzip Bazel
prepareCommand(tmp,
ImmutableList.of(bazelVersions.get(version).getCanonicalPath(),
"--output_user_root=" + tmp,
"--nomaster_bazelrc",
"--max_idle_secs=30", "--bazelrc=/dev/null", "help")).run();
}
}
/** Specify with bazel version to use, required before calling bazel. */
protected void bazelVersion(String version)
throws BazelTestCaseException, IOException, InterruptedException {
unpackBazel(version);
currentBazel = bazelVersions.get(version);
}
/** Create a new workspace, previous one can still be used. */
protected void newWorkspace() throws IOException {
this.workspace = java.nio.file.Files.createTempDirectory(tmp.toPath(), "workspace").toFile();
this.scratchFile("WORKSPACE");
}
@Before
public void setUp() throws Exception {
this.currentBazel = null;
if (System.getProperty("bazel.version") != null) {
bazelVersion(System.getProperty("bazel.version"));
}
newWorkspace();
}
/** Prepare bazel for running, and return the {@link Command} object to run it. */
protected Command bazel(String... args) throws BazelTestCaseException, IOException {
return bazel(ImmutableList.copyOf(args));
}
/** Prepare bazel for running, and return the {@link Command} object to run it. */
protected Command bazel(Iterable<String> args) throws BazelTestCaseException, IOException {
if (currentBazel == null) {
throw new BazelTestCaseException("Cannot use bazel because no version was specified, "
+ "please call bazelVersion(version) before calling bazel(...).");
}
return prepareCommand(workspace,
ImmutableList.<String>builder()
.add(currentBazel.getCanonicalPath(), "--output_user_root=" + tmp, "--nomaster_bazelrc",
"--max_idle_secs=10", "--bazelrc=/dev/null")
.addAll(args).build());
}
/**
* Copy a file from the runfiles under {@code path} into {@code destpath} under the current
* workspace.
*/
protected void copyFromRunfiles(String path, String destpath) throws IOException {
File origin = getRunfile(path);
File dest = new File(workspace, destpath);
if (!dest.getParentFile().exists()) {
dest.getParentFile().mkdirs();
}
Files.copy(origin.toPath(), dest.toPath());
}
/**
* Copy a file from the runfiles under {@code path} into {@code path} under the current workspace.
*/
protected void copyFromRunfiles(String path) throws IOException {
copyFromRunfiles(path, path);
}
/**
* Create a file under {@code path} in the current workspace, filling it with the lines given in
* {@code content}.
*/
protected void scratchFile(String path, String... content) throws IOException {
File dest = new File(workspace,path);
if (!dest.getParentFile().exists()) {
dest.getParentFile().mkdirs();
}
Files.write(dest.toPath(), LINE_JOINER.join(content).getBytes(StandardCharsets.UTF_8));
}
private static Command prepareCommand(File folder, Iterable<String> command) throws IOException {
Command.Builder builder = Command.builder(null).setConsoleName(null).setDirectory(folder);
builder.addArguments(command);
builder.setStderrLineSelector((String x) -> {
return x;
}).setStdoutLineSelector((String x) -> {
return x;
});
return builder.build();
}
}