// 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.api.change; import static com.google.common.truth.Truth.assertThat; import static com.google.gerrit.reviewdb.client.Patch.MERGE_LIST; import static java.nio.charset.StandardCharsets.UTF_8; import static org.eclipse.jgit.lib.Constants.HEAD; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.gerrit.acceptance.AbstractDaemonTest; import com.google.gerrit.acceptance.NoHttpd; import com.google.gerrit.acceptance.PushOneCommit; import com.google.gerrit.common.RawInputUtil; import com.google.gerrit.extensions.api.changes.RevisionApi; import com.google.gerrit.extensions.common.CommitInfo; import com.google.gerrit.extensions.common.DiffInfo; import com.google.gerrit.extensions.restapi.BinaryResult; import com.google.gerrit.extensions.restapi.ResourceConflictException; import java.io.ByteArrayOutputStream; import java.util.List; import java.util.Set; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.revwalk.RevCommit; import org.junit.Before; import org.junit.Test; @NoHttpd public class MergeListIT extends AbstractDaemonTest { private String changeId; private RevCommit merge; private RevCommit parent1; private RevCommit grandParent1; private RevCommit parent2; private RevCommit grandParent2; @Before public void setup() throws Exception { ObjectId initial = repo().exactRef(HEAD).getLeaf().getObjectId(); PushOneCommit.Result gp1 = pushFactory .create( db, admin.getIdent(), testRepo, "grand parent 1", ImmutableMap.of("foo", "foo-1.1", "bar", "bar-1.1")) .to("refs/for/master"); grandParent1 = gp1.getCommit(); PushOneCommit.Result p1 = pushFactory .create( db, admin.getIdent(), testRepo, "parent 1", ImmutableMap.of("foo", "foo-1.2", "bar", "bar-1.2")) .to("refs/for/master"); parent1 = p1.getCommit(); // reset HEAD in order to create a sibling of the first change testRepo.reset(initial); PushOneCommit.Result gp2 = pushFactory .create( db, admin.getIdent(), testRepo, "grand parent 2", ImmutableMap.of("foo", "foo-2.1", "bar", "bar-2.1")) .to("refs/for/master"); grandParent2 = gp2.getCommit(); PushOneCommit.Result p2 = pushFactory .create( db, admin.getIdent(), testRepo, "parent 2", ImmutableMap.of("foo", "foo-2.2", "bar", "bar-2.2")) .to("refs/for/master"); parent2 = p2.getCommit(); PushOneCommit m = pushFactory.create( db, admin.getIdent(), testRepo, "merge", ImmutableMap.of("foo", "foo-1", "bar", "bar-2")); m.setParents(ImmutableList.of(p1.getCommit(), p2.getCommit())); PushOneCommit.Result result = m.to("refs/for/master"); result.assertOkStatus(); merge = result.getCommit(); changeId = result.getChangeId(); } @Test public void getMergeList() throws Exception { List<CommitInfo> mergeList = current(changeId).getMergeList().get(); assertThat(mergeList).hasSize(2); assertThat(mergeList.get(0).commit).isEqualTo(parent2.name()); assertThat(mergeList.get(1).commit).isEqualTo(grandParent2.name()); mergeList = current(changeId).getMergeList().withUninterestingParent(2).get(); assertThat(mergeList).hasSize(2); assertThat(mergeList.get(0).commit).isEqualTo(parent1.name()); assertThat(mergeList.get(1).commit).isEqualTo(grandParent1.name()); } @Test public void getMergeListContent() throws Exception { BinaryResult bin = current(changeId).file(MERGE_LIST).content(); ByteArrayOutputStream os = new ByteArrayOutputStream(); bin.writeTo(os); String content = new String(os.toByteArray(), UTF_8); assertThat(content).isEqualTo(getMergeListContent(parent2, grandParent2)); } @Test public void getFileList() throws Exception { assertThat(getFiles(changeId)).contains(MERGE_LIST); assertThat(getFiles(changeId, 1)).contains(MERGE_LIST); assertThat(getFiles(changeId, 2)).contains(MERGE_LIST); assertThat(getFiles(createChange().getChangeId())).doesNotContain(MERGE_LIST); } @Test public void getDiffForMergeList() throws Exception { DiffInfo diff = getMergeListDiff(changeId); assertDiffForNewFile(diff, merge, MERGE_LIST, getMergeListContent(parent2, grandParent2)); diff = getMergeListDiff(changeId, 1); assertDiffForNewFile(diff, merge, MERGE_LIST, getMergeListContent(parent2, grandParent2)); diff = getMergeListDiff(changeId, 2); assertDiffForNewFile(diff, merge, MERGE_LIST, getMergeListContent(parent1, grandParent1)); } @Test public void editMergeList() throws Exception { gApi.changes().id(changeId).edit().create(); exception.expect(ResourceConflictException.class); exception.expectMessage("Invalid path: " + MERGE_LIST); gApi.changes().id(changeId).edit().modifyFile(MERGE_LIST, RawInputUtil.create("new content")); } @Test public void deleteMergeList() throws Exception { gApi.changes().id(changeId).edit().create(); exception.expect(ResourceConflictException.class); exception.expectMessage("no changes were made"); gApi.changes().id(changeId).edit().deleteFile(MERGE_LIST); } private String getMergeListContent(RevCommit... commits) { StringBuilder mergeList = new StringBuilder("Merge List:\n\n"); for (RevCommit c : commits) { mergeList .append("* ") .append(c.abbreviate(8).name()) .append(" ") .append(c.getShortMessage()) .append("\n"); } return mergeList.toString(); } private Set<String> getFiles(String changeId) throws Exception { return current(changeId).files().keySet(); } private Set<String> getFiles(String changeId, int parent) throws Exception { return current(changeId).files(parent).keySet(); } private DiffInfo getMergeListDiff(String changeId) throws Exception { return current(changeId).file(MERGE_LIST).diff(); } private DiffInfo getMergeListDiff(String changeId, int parent) throws Exception { return current(changeId).file(MERGE_LIST).diff(parent); } private RevisionApi current(String changeId) throws Exception { return gApi.changes().id(changeId).current(); } }