blob: 27b0754f6ca5a3e0107893a29ff78b90aeadf321 [file] [log] [blame]
// 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.blackbox.tests.workspace;
import static com.google.devtools.build.lib.blackbox.tests.workspace.RepoWithRuleWritingTextGenerator.callRule;
import static com.google.devtools.build.lib.blackbox.tests.workspace.RepoWithRuleWritingTextGenerator.loadRule;
import com.google.devtools.build.lib.blackbox.framework.BlackBoxTestContext;
import com.google.devtools.build.lib.blackbox.framework.BuilderRunner;
import com.google.devtools.build.lib.blackbox.framework.PathUtils;
import com.google.devtools.build.lib.blackbox.junit.AbstractBlackBoxTest;
import java.nio.file.Files;
import java.nio.file.Path;
import org.junit.Test;
/**
* Black box tests for git_repository/new_git_repository. On Windows, runs without MSYS {@link
* WorkspaceTestUtils#bazel}
*
* <p>General approach to testing:
*
* <p>We use {@link GitRepositoryHelper} and {@link RepoWithRuleWritingTextGenerator} helper
* classes.
*
* <p>1. We are creating some git repository with the preset contents, which will be used for
* fetching contents for the test. We plan to fetch contents specifying either commit hash, tag, or
* branch. For all test variants, we are creating the same repository, as the same HEAD commit is
* marked with a tag, and can be addressed with commit hash, master branch, and tag name.
*
* <p>2. The contents of the git repository working tree is generated by {@link
* RepoWithRuleWritingTextGenerator}. We pass some certain text to that generator; that exact text
* should appear as a result of the build of the generated target "call_write_text" in the file
* "out.txt".
*
* <p>3. We generate the new_git_repository repository rule, which refers to the git repository,
* created in #1, specifying different git repository attributes in each test. We call 'bazel build'
* for the "call_write_text" target of the external repository, and asserting the contents in the
* "out.txt" file.
*/
public class GitRepositoryBlackBoxTest extends AbstractBlackBoxTest {
private static final String HELLO_FROM_EXTERNAL_REPOSITORY = "Hello from GIT repository!";
private static final String HELLO_FROM_BRANCH = "Hello from branch!";
/**
* Tests usage of new_git_repository workspace rule with the "tag" attribute. Please see the
* general approach description in the class javadoc comment.
*/
@Test
public void testCloneAtTag() throws Exception {
Path repo = context().getTmpDir().resolve("ext_repo");
setupGitRepository(context(), repo);
String buildFileContent =
String.format(
"%s\n%s",
loadRule(""), callRule("call_write_text", "out.txt", HELLO_FROM_EXTERNAL_REPOSITORY));
context()
.write(
"WORKSPACE",
"load(\"@bazel_tools//tools/build_defs/repo:git.bzl\", \"new_git_repository\")",
"new_git_repository(",
" name='ext',",
String.format(" remote='%s',", PathUtils.pathToFileURI(repo.resolve(".git"))),
" tag='first',",
String.format(" build_file_content=\"\"\"%s\"\"\",", buildFileContent),
")");
// This creates Bazel without MSYS, see implementation for details.
BuilderRunner bazel = WorkspaceTestUtils.bazel(context());
bazel.build("@ext//:call_write_text");
Path outPath = context().resolveBinPath(bazel, "external/ext/out.txt");
WorkspaceTestUtils.assertLinesExactly(outPath, HELLO_FROM_EXTERNAL_REPOSITORY);
}
/**
* Tests usage of new_git_repository workspace rule with the "commit" attribute. Please see the
* general approach description in the class javadoc comment.
*/
@Test
public void testCloneAtCommit() throws Exception {
Path repo = context().getTmpDir().resolve("ext_repo");
String commit = setupGitRepository(context(), repo);
String buildFileContent =
String.format(
"%s\n%s",
loadRule(""), callRule("call_write_text", "out.txt", HELLO_FROM_EXTERNAL_REPOSITORY));
context()
.write(
"WORKSPACE",
"load(\"@bazel_tools//tools/build_defs/repo:git.bzl\", \"new_git_repository\")",
"new_git_repository(",
" name='ext',",
String.format(" remote='%s',", PathUtils.pathToFileURI(repo.resolve(".git"))),
String.format(" commit='%s',", commit),
String.format(" build_file_content=\"\"\"%s\"\"\",", buildFileContent),
")");
// This creates Bazel without MSYS, see implementation for details.
BuilderRunner bazel = WorkspaceTestUtils.bazel(context());
bazel.build("@ext//:call_write_text");
Path outPath = context().resolveBinPath(bazel, "external/ext/out.txt");
WorkspaceTestUtils.assertLinesExactly(outPath, HELLO_FROM_EXTERNAL_REPOSITORY);
}
/**
* Tests usage of new_git_repository workspace rule with the "branch" attribute. Please see the
* general approach description in the class javadoc comment.
*/
@Test
public void testCloneAtMaster() throws Exception {
Path repo = context().getTmpDir().resolve("ext_repo");
setupGitRepository(context(), repo);
String buildFileContent =
String.format(
"%s\n%s",
loadRule(""), callRule("call_write_text", "out.txt", HELLO_FROM_EXTERNAL_REPOSITORY));
context()
.write(
"WORKSPACE",
"load(\"@bazel_tools//tools/build_defs/repo:git.bzl\", \"new_git_repository\")",
"new_git_repository(",
" name='ext',",
String.format(" remote='%s',", PathUtils.pathToFileURI(repo.resolve(".git"))),
" branch='master',",
String.format(" build_file_content=\"\"\"%s\"\"\",", buildFileContent),
")");
// This creates Bazel without MSYS, see implementation for details.
BuilderRunner bazel = WorkspaceTestUtils.bazel(context());
bazel.build("@ext//:call_write_text");
Path outPath = context().resolveBinPath(bazel, "external/ext/out.txt");
WorkspaceTestUtils.assertLinesExactly(outPath, HELLO_FROM_EXTERNAL_REPOSITORY);
}
/**
* Tests usage of git_repository workspace rule in the particular use case, when only the commit
* hash is specified, and the commit is not in the HEAD-reachable subtree, on a separate branch.
*/
@Test
public void testCheckoutOfCommitFromBranch() throws Exception {
Path repo = context().getTmpDir().resolve("branch_repo");
GitRepositoryHelper gitRepository = initGitRepository(context(), repo);
context().write(repo.resolve("master.marker").toString());
gitRepository.addAll();
gitRepository.commit("Initial commit");
gitRepository.createNewBranch("demonstrate_branch");
RepoWithRuleWritingTextGenerator generator = new RepoWithRuleWritingTextGenerator(repo);
generator.withOutputText(HELLO_FROM_BRANCH).setupRepository();
gitRepository.addAll();
gitRepository.commit("Commit in branch");
String branchCommitHash = gitRepository.getHead();
gitRepository.checkout("master");
generator.withOutputText(HELLO_FROM_EXTERNAL_REPOSITORY).setupRepository();
gitRepository.addAll();
gitRepository.commit("Commit in master");
context()
.write(
"WORKSPACE",
"load(\"@bazel_tools//tools/build_defs/repo:git.bzl\", \"git_repository\")",
"git_repository(",
" name='ext',",
String.format(" remote='%s',", PathUtils.pathToFileURI(repo.resolve(".git"))),
String.format(" commit='%s',", branchCommitHash),
")");
// This creates Bazel without MSYS, see implementation for details.
BuilderRunner bazel = WorkspaceTestUtils.bazel(context());
bazel.build("@ext//:write_text");
Path outPath = context().resolveBinPath(bazel, "external/ext/out");
WorkspaceTestUtils.assertLinesExactly(outPath, HELLO_FROM_BRANCH);
}
/**
* Tests usage of git_repository workspace rule in the particular use case, when only the commit
* hash is specified, and the commit is not in the HEAD-reachable subtree, on a separate tag and
* not on any branch.
*/
@Test
public void testCheckoutOfCommitFromTag() throws Exception {
Path repo = context().getTmpDir().resolve("tag_repo");
GitRepositoryHelper gitRepository = initGitRepository(context(), repo);
context().write(repo.resolve("master.marker").toString());
gitRepository.addAll();
gitRepository.commit("Initial commit");
gitRepository.createNewBranch("demonstrate_branch");
RepoWithRuleWritingTextGenerator generator = new RepoWithRuleWritingTextGenerator(repo);
generator.withOutputText(HELLO_FROM_BRANCH).setupRepository();
gitRepository.addAll();
gitRepository.commit("Commit in tag1");
gitRepository.tag("tag1");
String tagCommitHash = gitRepository.getHead();
gitRepository.checkout("master");
// delete branch, so that the last commit is not an any branch.
gitRepository.deleteBranch("demonstrate_branch");
generator.withOutputText(HELLO_FROM_EXTERNAL_REPOSITORY).setupRepository();
gitRepository.addAll();
gitRepository.commit("Commit in master");
context()
.write(
"WORKSPACE",
"load(\"@bazel_tools//tools/build_defs/repo:git.bzl\", \"git_repository\")",
"git_repository(",
" name='ext',",
String.format(" remote='%s',", PathUtils.pathToFileURI(repo.resolve(".git"))),
String.format(" commit='%s',", tagCommitHash),
")");
// This creates Bazel without MSYS, see implementation for details.
BuilderRunner bazel = WorkspaceTestUtils.bazel(context());
bazel.build("@ext//:write_text");
Path outPath = context().resolveBinPath(bazel, "external/ext/out");
WorkspaceTestUtils.assertLinesExactly(outPath, HELLO_FROM_BRANCH);
}
private static String setupGitRepository(BlackBoxTestContext context, Path repo)
throws Exception {
GitRepositoryHelper gitRepository = initGitRepository(context, repo);
RepoWithRuleWritingTextGenerator generator = new RepoWithRuleWritingTextGenerator(repo);
generator.skipBuildFile().setupRepository();
gitRepository.addAll();
gitRepository.commit("Initial commit");
gitRepository.tag("first");
return gitRepository.getHead();
}
private static GitRepositoryHelper initGitRepository(BlackBoxTestContext context, Path repo)
throws Exception {
PathUtils.deleteTree(repo);
Files.createDirectories(repo);
GitRepositoryHelper gitRepository = new GitRepositoryHelper(context, repo);
gitRepository.init();
return gitRepository;
}
}