diff options
Diffstat (limited to 'gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/PushForReviewIT.java')
-rw-r--r-- | gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/PushForReviewIT.java | 309 |
1 files changed, 309 insertions, 0 deletions
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/PushForReviewIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/PushForReviewIT.java new file mode 100644 index 0000000000..f90535078f --- /dev/null +++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/PushForReviewIT.java @@ -0,0 +1,309 @@ +// Copyright (C) 2013 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.git; + +import static com.google.gerrit.acceptance.git.GitUtil.add; +import static com.google.gerrit.acceptance.git.GitUtil.cloneProject; +import static com.google.gerrit.acceptance.git.GitUtil.createCommit; +import static com.google.gerrit.acceptance.git.GitUtil.createProject; +import static com.google.gerrit.acceptance.git.GitUtil.initSsh; +import static com.google.gerrit.acceptance.git.GitUtil.pushHead; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import com.google.common.base.Function; +import com.google.common.base.Strings; +import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; +import com.google.gerrit.acceptance.AbstractDaemonTest; +import com.google.gerrit.acceptance.AccountCreator; +import com.google.gerrit.acceptance.SshSession; +import com.google.gerrit.acceptance.TestAccount; +import com.google.gerrit.reviewdb.client.Account; +import com.google.gerrit.reviewdb.client.Change; +import com.google.gerrit.reviewdb.client.PatchSetApproval; +import com.google.gerrit.reviewdb.client.Project; +import com.google.gerrit.reviewdb.server.ReviewDb; +import com.google.gwtorm.server.OrmException; +import com.google.gwtorm.server.SchemaFactory; +import com.google.inject.Inject; + +import com.jcraft.jsch.JSchException; + +import org.eclipse.jgit.api.Git; +import org.eclipse.jgit.api.errors.GitAPIException; +import org.eclipse.jgit.transport.PushResult; +import org.eclipse.jgit.transport.RemoteRefUpdate; +import org.eclipse.jgit.transport.RemoteRefUpdate.Status; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; + +import java.io.IOException; +import java.util.Arrays; +import java.util.List; +import java.util.Set; + +@RunWith(Parameterized.class) +public class PushForReviewIT extends AbstractDaemonTest { + + private enum Protocol { + SSH, HTTP + } + + @Parameters(name="{0}") + public static List<Object[]> getParam() { + List<Object[]> params = Lists.newArrayList(); + for(Protocol p : Protocol.values()) { + params.add(new Object[] {p}); + } + return params; + } + + @Inject + private AccountCreator accounts; + + @Inject + private SchemaFactory<ReviewDb> reviewDbProvider; + + private TestAccount admin; + private Project.NameKey project; + private Git git; + private ReviewDb db; + private Protocol protocol; + + public PushForReviewIT(Protocol p) { + this.protocol = p; + } + + @Before + public void setUp() throws Exception { + admin = + accounts.create("admin", "admin@example.com", "Administrator", + "Administrators"); + + project = new Project.NameKey("p"); + initSsh(admin); + SshSession sshSession = new SshSession(admin); + createProject(sshSession, project.get()); + String url; + switch (protocol) { + case SSH: + url = sshSession.getUrl(); + break; + case HTTP: + url = admin.getHttpUrl(); + break; + default: + throw new IllegalStateException("unexpected protocol: " + protocol); + } + git = cloneProject(url + "/" + project.get()); + sshSession.close(); + + db = reviewDbProvider.open(); + } + + @After + public void cleanup() { + db.close(); + } + + @Test + public void testPushForMaster() throws GitAPIException, OrmException, + IOException { + PushOneCommit push = new PushOneCommit(); + String ref = "refs/for/master"; + PushResult r = push.to(ref); + assertOkStatus(r, ref); + assertChange(push.changeId, Change.Status.NEW, PushOneCommit.SUBJECT, null); + } + + @Test + public void testPushForMasterWithTopic() throws GitAPIException, + OrmException, IOException { + // specify topic in ref + PushOneCommit push = new PushOneCommit(); + String topic = "my/topic"; + String ref = "refs/for/master/" + topic; + PushResult r = push.to(ref); + assertOkStatus(r, ref); + assertChange(push.changeId, Change.Status.NEW, PushOneCommit.SUBJECT, topic); + + // specify topic as option + push = new PushOneCommit(); + ref = "refs/for/master%topic=" + topic; + r = push.to(ref); + assertOkStatus(r, ref); + assertChange(push.changeId, Change.Status.NEW, PushOneCommit.SUBJECT, topic); + } + + @Test + public void testPushForMasterWithCc() throws GitAPIException, OrmException, + IOException, JSchException { + // cc one user + TestAccount user = accounts.create("user", "user@example.com", "User"); + PushOneCommit push = new PushOneCommit(); + String topic = "my/topic"; + String ref = "refs/for/master/" + topic + "%cc=" + user.email; + PushResult r = push.to(ref); + assertOkStatus(r, ref); + assertChange(push.changeId, Change.Status.NEW, PushOneCommit.SUBJECT, topic); + + // cc several users + TestAccount user2 = + accounts.create("another-user", "another.user@example.com", "Another User"); + push = new PushOneCommit(); + ref = "refs/for/master/" + topic + "%cc=" + admin.email + ",cc=" + user.email + + ",cc=" + user2.email; + r = push.to(ref); + assertOkStatus(r, ref); + assertChange(push.changeId, Change.Status.NEW, PushOneCommit.SUBJECT, topic); + + // cc non-existing user + String nonExistingEmail = "non.existing@example.com"; + push = new PushOneCommit(); + ref = "refs/for/master/" + topic + "%cc=" + admin.email + ",cc=" + + nonExistingEmail + ",cc=" + user.email; + r = push.to(ref); + assertErrorStatus(r, "user \"" + nonExistingEmail + "\" not found", ref); + } + + @Test + public void testPushForMasterWithReviewer() throws GitAPIException, + OrmException, IOException, JSchException { + // add one reviewer + TestAccount user = accounts.create("user", "user@example.com", "User"); + PushOneCommit push = new PushOneCommit(); + String topic = "my/topic"; + String ref = "refs/for/master/" + topic + "%r=" + user.email; + PushResult r = push.to(ref); + assertOkStatus(r, ref); + assertChange(push.changeId, Change.Status.NEW, PushOneCommit.SUBJECT, + topic, user); + + // add several reviewers + TestAccount user2 = + accounts.create("another-user", "another.user@example.com", "Another User"); + push = new PushOneCommit(); + ref = "refs/for/master/" + topic + "%r=" + admin.email + ",r=" + user.email + + ",r=" + user2.email; + r = push.to(ref); + assertOkStatus(r, ref); + // admin is the owner of the change and should not appear as reviewer + assertChange(push.changeId, Change.Status.NEW, PushOneCommit.SUBJECT, + topic, user, user2); + + // add non-existing user as reviewer + String nonExistingEmail = "non.existing@example.com"; + push = new PushOneCommit(); + ref = "refs/for/master/" + topic + "%r=" + admin.email + ",r=" + + nonExistingEmail + ",r=" + user.email; + r = push.to(ref); + assertErrorStatus(r, "user \"" + nonExistingEmail + "\" not found", ref); + } + + @Test + public void testPushForMasterAsDraft() throws GitAPIException, OrmException, + IOException { + // create draft by pushing to 'refs/drafts/' + PushOneCommit push = new PushOneCommit(); + String ref = "refs/drafts/master"; + PushResult r = push.to(ref); + assertOkStatus(r, ref); + assertChange(push.changeId, Change.Status.DRAFT, PushOneCommit.SUBJECT, null); + + // create draft by using 'draft' option + push = new PushOneCommit(); + ref = "refs/for/master%draft"; + r = push.to(ref); + assertOkStatus(r, ref); + assertChange(push.changeId, Change.Status.DRAFT, PushOneCommit.SUBJECT, null); + } + + @Test + public void testPushForNonExistingBranch() throws GitAPIException, + OrmException, IOException { + PushOneCommit push = new PushOneCommit(); + String branchName = "non-existing"; + String ref = "refs/for/" + branchName; + PushResult r = push.to(ref); + assertErrorStatus(r, "branch " + branchName + " not found", ref); + } + + private void assertChange(String changeId, Change.Status expectedStatus, + String expectedSubject, String expectedTopic, + TestAccount... expectedReviewers) throws OrmException { + Change c = + Iterables.getOnlyElement(db.changes().byKey(new Change.Key(changeId)).toList()); + assertEquals(expectedSubject, c.getSubject()); + assertEquals(expectedStatus, c.getStatus()); + assertEquals(expectedTopic, Strings.emptyToNull(c.getTopic())); + assertReviewers(c, expectedReviewers); + } + + private void assertReviewers(Change c, TestAccount... expectedReviewers) + throws OrmException { + Set<Account.Id> expectedReviewerIds = + Sets.newHashSet(Lists.transform(Arrays.asList(expectedReviewers), + new Function<TestAccount, Account.Id>() { + @Override + public Account.Id apply(TestAccount a) { + return a.id; + } + })); + + for (PatchSetApproval psa : db.patchSetApprovals().byPatchSet( + c.currentPatchSetId())) { + assertTrue("unexpected reviewer " + psa.getAccountId(), + expectedReviewerIds.remove(psa.getAccountId())); + } + assertTrue("missing reviewers: " + expectedReviewerIds, + expectedReviewerIds.isEmpty()); + } + + private static void assertOkStatus(PushResult result, String ref) { + assertStatus(Status.OK, null, result, ref); + } + + private static void assertErrorStatus(PushResult result, + String expectedMessage, String ref) { + assertStatus(Status.REJECTED_OTHER_REASON, expectedMessage, result, ref); + } + + private static void assertStatus(Status expectedStatus, + String expectedMessage, PushResult result, String ref) { + RemoteRefUpdate refUpdate = result.getRemoteUpdate(ref); + assertEquals(refUpdate.getMessage() + "\n" + result.getMessages(), + expectedStatus, refUpdate.getStatus()); + assertEquals(expectedMessage, refUpdate.getMessage()); + } + + private class PushOneCommit { + final static String FILE_NAME = "a.txt"; + final static String FILE_CONTENT = "some content"; + final static String SUBJECT = "test commit"; + String changeId; + + public PushResult to(String ref) throws GitAPIException, IOException { + add(git, FILE_NAME, FILE_CONTENT); + changeId = createCommit(git, admin.getIdent(), SUBJECT); + return pushHead(git, ref); + } + } +} |