blob: b0320f6325d1f1ffae2407042e2bbaff0117c133 [file] [log] [blame] [edit]
// Copyright (C) 2016 The Android Open Source Project
//
// 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.gerrit.acceptance.rest.project;
import static com.google.common.truth.Truth.assertThat;
import com.google.common.base.Strings;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.PushOneCommit;
import com.google.gerrit.acceptance.RestResponse;
import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.entities.BranchNameKey;
import com.google.gerrit.extensions.api.changes.ChangeApi;
import com.google.gerrit.extensions.api.changes.CherryPickInput;
import com.google.gerrit.extensions.api.changes.ReviewInput;
import com.google.gerrit.extensions.api.projects.BranchInput;
import com.google.gerrit.extensions.common.MergeableInfo;
import com.google.inject.Inject;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.transport.RefSpec;
import org.junit.Before;
import org.junit.Test;
public class CheckMergeabilityIT extends AbstractDaemonTest {
@Inject private ProjectOperations projectOperations;
private BranchNameKey branch;
@Before
public void setUp() throws Exception {
branch = BranchNameKey.create(project, "test");
gApi.projects().name(branch.project().get()).branch(branch.branch()).create(new BranchInput());
}
@Test
public void checkMergeableCommit() throws Exception {
RevCommit initialHead = projectOperations.project(project).getHead("master");
testRepo
.branch("HEAD")
.commit()
.insertChangeId()
.message("some change in a")
.add("a.txt", "a contents ")
.create();
testRepo
.git()
.push()
.setRemote("origin")
.setRefSpecs(new RefSpec("HEAD:refs/heads/master"))
.call();
testRepo.reset(initialHead);
testRepo
.branch("HEAD")
.commit()
.insertChangeId()
.message("some change in b")
.add("b.txt", "b contents ")
.create();
testRepo
.git()
.push()
.setRemote("origin")
.setRefSpecs(new RefSpec("HEAD:refs/heads/test"))
.call();
assertMergeable("master", "test", "recursive");
}
@Test
public void checkUnMergeableCommit() throws Exception {
RevCommit initialHead = projectOperations.project(project).getHead("master");
testRepo
.branch("HEAD")
.commit()
.insertChangeId()
.message("some change in a")
.add("a.txt", "a contents ")
.create();
testRepo
.git()
.push()
.setRemote("origin")
.setRefSpecs(new RefSpec("HEAD:refs/heads/master"))
.call();
testRepo.reset(initialHead);
testRepo
.branch("HEAD")
.commit()
.insertChangeId()
.message("some change in a too")
.add("a.txt", "a contents too")
.create();
testRepo
.git()
.push()
.setRemote("origin")
.setRefSpecs(new RefSpec("HEAD:refs/heads/test"))
.call();
assertUnMergeable("master", "test", "recursive", "a.txt");
}
@Test
public void checkOursMergeStrategy() throws Exception {
RevCommit initialHead = projectOperations.project(project).getHead("master");
testRepo
.branch("HEAD")
.commit()
.insertChangeId()
.message("some change in a")
.add("a.txt", "a contents ")
.create();
testRepo
.git()
.push()
.setRemote("origin")
.setRefSpecs(new RefSpec("HEAD:refs/heads/master"))
.call();
testRepo.reset(initialHead);
testRepo
.branch("HEAD")
.commit()
.insertChangeId()
.message("some change in a too")
.add("a.txt", "a contents too")
.create();
testRepo
.git()
.push()
.setRemote("origin")
.setRefSpecs(new RefSpec("HEAD:refs/heads/test"))
.call();
assertMergeable("master", "test", "ours");
}
@Test
public void checkAlreadyMergedCommit() throws Exception {
ObjectId c0 =
testRepo
.branch("HEAD")
.commit()
.insertChangeId()
.message("first commit")
.add("a.txt", "a contents ")
.create();
testRepo
.git()
.push()
.setRemote("origin")
.setRefSpecs(new RefSpec("HEAD:refs/heads/master"))
.call();
testRepo
.branch("HEAD")
.commit()
.insertChangeId()
.message("second commit")
.add("b.txt", "b contents ")
.create();
testRepo
.git()
.push()
.setRemote("origin")
.setRefSpecs(new RefSpec("HEAD:refs/heads/master"))
.call();
assertCommitMerged("master", c0.getName(), "");
}
@Test
public void checkContentMergedCommit() throws Exception {
testRepo
.branch("HEAD")
.commit()
.insertChangeId()
.message("first commit")
.add("a.txt", "a contents ")
.create();
testRepo
.git()
.push()
.setRemote("origin")
.setRefSpecs(new RefSpec("HEAD:refs/heads/master"))
.call();
// create a change, and cherrypick into master
PushOneCommit.Result cId = createChange();
RevCommit commitId = cId.getCommit();
CherryPickInput cpi = new CherryPickInput();
cpi.destination = "master";
cpi.message = "cherry pick the commit";
ChangeApi orig = gApi.changes().id(cId.getChangeId());
ChangeApi cherry = orig.current().cherryPick(cpi);
cherry.current().review(ReviewInput.approve());
cherry.current().submit();
ObjectId remoteId = projectOperations.project(project).getHead("master");
assertThat(remoteId).isNotEqualTo(commitId);
assertContentMerged("master", commitId.getName(), "recursive");
}
@Test
public void checkInvalidSource() throws Exception {
testRepo
.branch("HEAD")
.commit()
.insertChangeId()
.message("first commit")
.add("a.txt", "a contents ")
.create();
testRepo
.git()
.push()
.setRemote("origin")
.setRefSpecs(new RefSpec("HEAD:refs/heads/master"))
.call();
assertBadRequest(
"master",
"fdsafsdf",
"recursive",
"Error resolving: 'fdsafsdf'. Do not have read permission, or failed to resolve to a commit.");
}
@Test
public void checkInvalidStrategy() throws Exception {
RevCommit initialHead = projectOperations.project(project).getHead("master");
testRepo
.branch("HEAD")
.commit()
.insertChangeId()
.message("first commit")
.add("a.txt", "a contents ")
.create();
testRepo
.git()
.push()
.setRemote("origin")
.setRefSpecs(new RefSpec("HEAD:refs/heads/master"))
.call();
testRepo.reset(initialHead);
testRepo
.branch("HEAD")
.commit()
.insertChangeId()
.message("some change in a too")
.add("a.txt", "a contents too")
.create();
testRepo
.git()
.push()
.setRemote("origin")
.setRefSpecs(new RefSpec("HEAD:refs/heads/test"))
.call();
assertBadRequest("master", "test", "octopus", "invalid merge strategy: octopus");
}
private void assertMergeable(String targetBranch, String source, String strategy)
throws Exception {
MergeableInfo mergeableInfo = getMergeableInfo(targetBranch, source, strategy);
assertThat(mergeableInfo.mergeable).isTrue();
}
private void assertUnMergeable(
String targetBranch, String source, String strategy, String... conflicts) throws Exception {
MergeableInfo mergeableInfo = getMergeableInfo(targetBranch, source, strategy);
assertThat(mergeableInfo.mergeable).isFalse();
assertThat(mergeableInfo.conflicts).containsExactly((Object[]) conflicts);
}
private void assertCommitMerged(String targetBranch, String source, String strategy)
throws Exception {
MergeableInfo mergeableInfo = getMergeableInfo(targetBranch, source, strategy);
assertThat(mergeableInfo.mergeable).isTrue();
assertThat(mergeableInfo.commitMerged).isTrue();
}
private void assertContentMerged(String targetBranch, String source, String strategy)
throws Exception {
MergeableInfo mergeableInfo = getMergeableInfo(targetBranch, source, strategy);
assertThat(mergeableInfo.mergeable).isTrue();
assertThat(mergeableInfo.contentMerged).isTrue();
}
private void assertBadRequest(String targetBranch, String source, String strategy, String errMsg)
throws Exception {
String url = "/projects/" + project.get() + "/branches/" + targetBranch;
url += "/mergeable?source=" + source;
if (!Strings.isNullOrEmpty(strategy)) {
url += "&strategy=" + strategy;
}
RestResponse r = userRestSession.get(url);
r.assertBadRequest();
assertThat(r.getEntityContent()).isEqualTo(errMsg);
}
private MergeableInfo getMergeableInfo(String targetBranch, String source, String strategy)
throws Exception {
String url = "/projects/" + project.get() + "/branches/" + targetBranch;
url += "/mergeable?source=" + source;
if (!Strings.isNullOrEmpty(strategy)) {
url += "&strategy=" + strategy;
}
RestResponse r = userRestSession.get(url);
r.assertOK();
MergeableInfo result = newGson().fromJson(r.getReader(), MergeableInfo.class);
r.consume();
return result;
}
}