blob: 571d1a5d5dba18c9b2c85dc5139645b5ba5a470c [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2013, 2016 Tasktop Technologies and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Tasktop Technologies - initial API and implementation
*******************************************************************************/
package org.eclipse.mylyn.internal.gerrit.core.remote;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.sameInstance;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
import java.io.File;
import java.math.BigInteger;
import java.net.Proxy;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.lang.StringUtils;
import org.eclipse.jgit.api.CommitCommand;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.mylyn.commons.net.IProxyProvider;
import org.eclipse.mylyn.commons.net.WebLocation;
import org.eclipse.mylyn.commons.net.WebUtil;
import org.eclipse.mylyn.commons.repositories.core.auth.UserCredentials;
import org.eclipse.mylyn.commons.sdk.util.CommonTestUtil.PrivilegeLevel;
import org.eclipse.mylyn.gerrit.tests.support.GerritFixture;
import org.eclipse.mylyn.gerrit.tests.support.GerritHarness;
import org.eclipse.mylyn.gerrit.tests.support.GerritProject.CommitResult;
import org.eclipse.mylyn.internal.gerrit.core.client.GerritChange;
import org.eclipse.mylyn.internal.gerrit.core.client.GerritClient;
import org.eclipse.mylyn.internal.gerrit.core.client.GerritException;
import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin;
import org.eclipse.mylyn.reviews.core.model.IRepository;
import org.eclipse.mylyn.reviews.core.model.IReview;
import org.eclipse.mylyn.reviews.core.model.IReviewItemSet;
import org.eclipse.mylyn.reviews.core.spi.remote.JobRemoteService;
import org.eclipse.mylyn.reviews.core.spi.remote.emf.RemoteEmfConsumer;
import org.eclipse.mylyn.tasks.core.TaskRepository;
class ReviewHarness {
private static final Pattern SHORT_ID_PATTERN = Pattern.compile("(\\d+).*", Pattern.DOTALL);
//The maximum difference between two dates to account for clock skew between test machines
private static final long CREATION_TIME_DELTA = 30 * 60 * 1000; //30 Minutes
private static final String DEFAULT_TEST_FILE = "testFile1.txt";
private TestRemoteObserver<IRepository, IReview, String, Date> listener;
private RemoteEmfConsumer<IRepository, IReview, String, GerritChange, String, Date> consumer;
private String shortId;
private String commitId;
private String changeId;
private final Git git;
private final GerritClient client;
private GerritClient adminClient;
private final GerritRemoteFactoryProvider provider;
private final TaskRepository taskRepository;
private final GerritHarness gerritHarness;
ReviewHarness() throws Exception {
this.changeId = generateChangeId();
gerritHarness = GerritFixture.current().harness();
git = gerritHarness.project().getGitProject(PrivilegeLevel.USER);
taskRepository = GerritFixture.current().singleRepository();
client = gerritHarness.client(PrivilegeLevel.USER);
provider = new GerritRemoteFactoryProvider(client);
provider.setService(new JobRemoteService());
provider.setDataLocator(new TestDataLocator());
}
static String generateChangeId() throws NoSuchAlgorithmException {
byte[] bytes = new byte[22];
new Random().nextBytes(bytes);
return "I" + new BigInteger(bytes).toString(16).replace("-", "").substring(0, 40);
}
ReviewHarness duplicate() throws Exception {
ReviewHarness reviewHarness = new ReviewHarness();
reviewHarness.changeId = this.changeId;
return reviewHarness;
}
void retrieve() {
consumer.retrieve(false);
listener.waitForResponse();
}
void init() throws Exception {
init("HEAD:refs/for/master", PrivilegeLevel.USER, DEFAULT_TEST_FILE, true);
}
void init(String refSpec, PrivilegeLevel privilegeLevel, String fileName, boolean wait) throws Exception {
provider.open();
assertThat(getRepository().getReviews().size(), is(0));
pushFileToReview(refSpec, privilegeLevel, fileName);
listener = new TestRemoteObserver<IRepository, IReview, String, Date>(provider.getReviewFactory());
consumer = provider.getReviewFactory().getConsumerForRemoteKey(getRepository(), getShortId());
consumer.setAsynchronous(false);
consumer.addObserver(listener);
if (!wait) {
return;
}
retrieve();
assertThat(getRepository().getReviews().size(), is(1));
IReview review = getRepository().getReviews().get(0);
IReview reviewDirect = provider.open(getShortId());
assertThat(review, sameInstance(reviewDirect));
assertThat(review, notNullValue());
assertThat(review.getId(), is(getShortId()));
assertThat(review.getKey(), is(changeId));
assertThat(review.getSubject(), is("Test Change " + changeId));
assertThat(review.getOwner().getDisplayName(), is("tests"));
assertIsRecent(review.getCreationDate());
}
public void pushFileToReview(String refSpec, PrivilegeLevel privilegeLevel) throws Exception {
pushFileToReview(refSpec, privilegeLevel, DEFAULT_TEST_FILE);
}
public void pushFileToReview(String refSpec, PrivilegeLevel privilegeLevel, String fileName) throws Exception {
CommitCommand command = createCommitCommand(changeId);
addFile(fileName);
CommitResult result = commitAndPush(command, refSpec, privilegeLevel);
shortId = parseShortId(result.push.getMessages());
commitId = result.commit.getId().toString();
assertThat("Bad Push: " + result.push.getMessages(), getShortId().length(), greaterThan(0));
}
static String parseShortId(String messages) {
String tail = StringUtils.trimToEmpty(StringUtils.substringAfterLast(messages, "/"));
Matcher m = SHORT_ID_PATTERN.matcher(tail);
if (m.matches()) {
return m.group(1);
}
fail("ShortId could not be parsed from \"" + tail + "\". Messages was: " + messages);
return null;
}
void assertIsRecent(Date date) {
long timeDelta = System.currentTimeMillis() - date.getTime();
assertThat("Creation delta out of range : " + timeDelta + " ms",
timeDelta > -CREATION_TIME_DELTA && timeDelta < CREATION_TIME_DELTA, is(true));
}
public void dispose() throws GerritException {
if (listener != null) {
consumer.removeObserver(listener);
}
if (consumer != null) {
consumer.release();
}
gerritHarness.dispose();
}
CommitCommand createCommitCommand() {
return createCommitCommand(changeId).setAmend(true);
}
CommitCommand createCommitCommand(String changeId) {
return git.commit().setAll(true).setMessage("Test Change " + changeId + "\n\nChange-Id: " + changeId);
}
void addFile(String fileName) throws Exception {
gerritHarness.project().addFile(fileName);
}
void addFile(String fileName, String text) throws Exception {
gerritHarness.project().addFile(fileName, text);
}
void addFile(String fileName, File file) throws Exception {
gerritHarness.project().addFile(fileName, file);
}
void removeFile(String fileName) throws Exception {
gerritHarness.project().removeFile(fileName);
}
CommitResult commitAndPush(CommitCommand command) throws Exception {
return gerritHarness.project().commitAndPush(command);
}
CommitResult commitAndPush(CommitCommand command, String refSpec, PrivilegeLevel privilegeLevel) throws Exception {
return gerritHarness.project().commitAndPush(command, refSpec, privilegeLevel);
}
void checkoutPatchSet(int number) throws Exception {
IReviewItemSet patchSet = getReview().getSets().get(0);
ObjectId ref = git.getRepository().resolve(patchSet.getRevision());
RevWalk walker = new RevWalk(git.getRepository());
RevCommit targetCommit = walker.parseCommit(ref);
//make sure to checkout the correct commit
assertThat(targetCommit.toString(), is(commitId));
git.checkout()
.setCreateBranch(true)
.setName("change" + "/" + getReview().getId() + "/" + number)
.setStartPoint(targetCommit)
.call();
}
GerritClient getClient() {
return client;
}
GerritClient getAdminClient() {
if (adminClient == null) {
UserCredentials credentials = GerritFixture.current().getCredentials(PrivilegeLevel.ADMIN);
WebLocation location = new WebLocation(GerritFixture.current().getRepositoryUrl(),
credentials.getUserName(), credentials.getPassword(), new IProxyProvider() {
public Proxy getProxyForHost(String host, String proxyType) {
return WebUtil.getProxyForUrl(GerritFixture.current().getRepositoryUrl());
}
});
TaskRepository repository = TasksUiPlugin.getRepositoryManager()
.getRepository(GerritFixture.current().getRepositoryUrl());
adminClient = GerritClient.create(repository, location);
}
return adminClient;
}
IReview getReview() {
return consumer.getModelObject();
}
IRepository getRepository() {
return provider.getRoot();
}
public TaskRepository getTaskRepository() {
return taskRepository;
}
String getShortId() {
return shortId;
}
GerritRemoteFactoryProvider getProvider() {
return provider;
}
}