// 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.GitUtil.cloneProject; import static org.junit.Assert.assertEquals; import com.google.gerrit.acceptance.AbstractDaemonTest; import com.google.gerrit.acceptance.PushOneCommit; import com.google.gerrit.acceptance.TestAccount; import com.google.gerrit.extensions.common.ChangeInfo; import com.google.gerrit.extensions.common.LabelInfo; import com.google.gerrit.extensions.restapi.RestApiException; import com.google.gerrit.reviewdb.client.Change; import com.google.gwtorm.server.OrmException; import com.jcraft.jsch.JSchException; import org.eclipse.jgit.api.errors.GitAPIException; import org.junit.Before; import org.junit.Test; import java.io.IOException; public abstract class AbstractPushForReview extends AbstractDaemonTest { protected enum Protocol { SSH, HTTP } private String sshUrl; @Before public void setUp() throws Exception { sshUrl = sshSession.getUrl(); } protected void selectProtocol(Protocol p) throws GitAPIException, IOException { String url; switch (p) { case SSH: url = sshUrl; break; case HTTP: url = admin.getHttpUrl(server); break; default: throw new IllegalArgumentException("unexpected protocol: " + p); } git = cloneProject(url + "/" + project.get()); } @Test public void testPushForMaster() throws GitAPIException, OrmException, IOException { PushOneCommit.Result r = pushTo("refs/for/master"); r.assertOkStatus(); r.assertChange(Change.Status.NEW, null); } @Test public void testPushForMasterWithTopic() throws GitAPIException, OrmException, IOException { // specify topic in ref String topic = "my/topic"; PushOneCommit.Result r = pushTo("refs/for/master/" + topic); r.assertOkStatus(); r.assertChange(Change.Status.NEW, topic); // specify topic as option r = pushTo("refs/for/master%topic=" + topic); r.assertOkStatus(); r.assertChange(Change.Status.NEW, topic); } @Test public void testPushForMasterWithCc() throws GitAPIException, OrmException, IOException, JSchException { // cc one user String topic = "my/topic"; PushOneCommit.Result r = pushTo("refs/for/master/" + topic + "%cc=" + user.email); r.assertOkStatus(); r.assertChange(Change.Status.NEW, topic); // cc several users TestAccount user2 = accounts.create("another-user", "another.user@example.com", "Another User"); r = pushTo("refs/for/master/" + topic + "%cc=" + admin.email + ",cc=" + user.email + ",cc=" + user2.email); r.assertOkStatus(); r.assertChange(Change.Status.NEW, topic); // cc non-existing user String nonExistingEmail = "non.existing@example.com"; r = pushTo("refs/for/master/" + topic + "%cc=" + admin.email + ",cc=" + nonExistingEmail + ",cc=" + user.email); r.assertErrorStatus("user \"" + nonExistingEmail + "\" not found"); } @Test public void testPushForMasterWithReviewer() throws GitAPIException, OrmException, IOException, JSchException { // add one reviewer String topic = "my/topic"; PushOneCommit.Result r = pushTo("refs/for/master/" + topic + "%r=" + user.email); r.assertOkStatus(); r.assertChange(Change.Status.NEW, topic, user); // add several reviewers TestAccount user2 = accounts.create("another-user", "another.user@example.com", "Another User"); r = pushTo("refs/for/master/" + topic + "%r=" + admin.email + ",r=" + user.email + ",r=" + user2.email); r.assertOkStatus(); // admin is the owner of the change and should not appear as reviewer r.assertChange(Change.Status.NEW, topic, user, user2); // add non-existing user as reviewer String nonExistingEmail = "non.existing@example.com"; r = pushTo("refs/for/master/" + topic + "%r=" + admin.email + ",r=" + nonExistingEmail + ",r=" + user.email); r.assertErrorStatus("user \"" + nonExistingEmail + "\" not found"); } @Test public void testPushForMasterAsDraft() throws GitAPIException, OrmException, IOException { // create draft by pushing to 'refs/drafts/' PushOneCommit.Result r = pushTo("refs/drafts/master"); r.assertOkStatus(); r.assertChange(Change.Status.DRAFT, null); // create draft by using 'draft' option r = pushTo("refs/for/master%draft"); r.assertOkStatus(); r.assertChange(Change.Status.DRAFT, null); } @Test public void testPushForMasterWithApprovals() throws GitAPIException, IOException, RestApiException { PushOneCommit.Result r = pushTo("refs/for/master/%l=Code-Review"); r.assertOkStatus(); ChangeInfo ci = get(r.getChangeId()); LabelInfo cr = ci.labels.get("Code-Review"); assertEquals(1, cr.all.size()); assertEquals("Administrator", cr.all.get(0).name); assertEquals(1, cr.all.get(0).value.intValue()); PushOneCommit push = pushFactory.create(db, admin.getIdent(), PushOneCommit.SUBJECT, "b.txt", "anotherContent", r.getChangeId()); r = push.to(git, "refs/for/master/%l=Code-Review+2"); ci = get(r.getChangeId()); cr = ci.labels.get("Code-Review"); assertEquals(1, cr.all.size()); assertEquals("Administrator", cr.all.get(0).name); assertEquals(2, cr.all.get(0).value.intValue()); } @Test public void testPushForMasterWithApprovals_MissingLabel() throws GitAPIException, IOException { PushOneCommit.Result r = pushTo("refs/for/master/%l=Verify"); r.assertErrorStatus("label \"Verify\" is not a configured label"); } @Test public void testPushForMasterWithApprovals_ValueOutOfRange() throws GitAPIException, IOException, RestApiException { PushOneCommit.Result r = pushTo("refs/for/master/%l=Code-Review-3"); r.assertErrorStatus("label \"Code-Review\": -3 is not a valid value"); } @Test public void testPushForNonExistingBranch() throws GitAPIException, OrmException, IOException { String branchName = "non-existing"; PushOneCommit.Result r = pushTo("refs/for/" + branchName); r.assertErrorStatus("branch " + branchName + " not found"); } private PushOneCommit.Result pushTo(String ref) throws GitAPIException, IOException { PushOneCommit push = pushFactory.create(db, admin.getIdent()); return push.to(git, ref); } }