Use InMemoryRepository in acceptance tests

We can no longer use CloneCommand, which always produces an on-disk
repository. Instead "clone" by setting up a remote and checking out a
detached head.

Change-Id: I94bc3d9b231526bb5740c530702f5c918c61cc03
This commit is contained in:
Dave Borowitz
2015-03-18 07:45:40 -07:00
parent d901bee35a
commit 3e027d60b8
13 changed files with 64 additions and 47 deletions

View File

@@ -211,7 +211,7 @@ public abstract class AbstractDaemonTest {
project = new Project.NameKey(projectInput.name);
createProject(projectInput);
setRepo(cloneProject(sshSession.getUrl() + "/" + project.get()));
setRepo(cloneProject(project, sshSession));
}
private ProjectInput projectInput(Description description) {
@@ -237,9 +237,9 @@ public abstract class AbstractDaemonTest {
return in;
}
protected void setRepo(Git git) throws Exception {
this.git = git;
testRepo = new TestRepository<>(git.getRepository());
protected void setRepo(TestRepository<?> testRepo) throws Exception {
this.git = Git.wrap(testRepo.getRepository());
this.testRepo = new TestRepository<>(git.getRepository());
}
protected void createProject(String name) throws RestApiException {

View File

@@ -17,20 +17,23 @@ package com.google.gerrit.acceptance;
import com.google.common.base.Optional;
import com.google.common.collect.Iterables;
import com.google.gerrit.common.FooterConstants;
import com.google.gerrit.testutil.TempFileUtil;
import com.google.gerrit.reviewdb.client.Project;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import org.eclipse.jgit.api.CloneCommand;
import org.eclipse.jgit.api.FetchCommand;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.PushCommand;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.internal.storage.dfs.DfsRepositoryDescription;
import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.transport.FetchResult;
import org.eclipse.jgit.transport.JschConfigSessionFactory;
import org.eclipse.jgit.transport.OpenSshConfig.Host;
import org.eclipse.jgit.transport.PushResult;
@@ -38,7 +41,6 @@ import org.eclipse.jgit.transport.RefSpec;
import org.eclipse.jgit.transport.SshSessionFactory;
import org.eclipse.jgit.util.FS;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Properties;
@@ -67,17 +69,31 @@ public class GitUtil {
});
}
public static Git cloneProject(String url) throws GitAPIException, IOException {
return cloneProject(url, true);
public static TestRepository<InMemoryRepository> cloneProject(
Project.NameKey project, String uri) throws Exception {
InMemoryRepository dest = new InMemoryRepository.Builder()
.setRepositoryDescription(new DfsRepositoryDescription(project.get()))
// SshTransport depends on a real FS to read ~/.ssh/config, but
// InMemoryRepository by default uses a null FS.
// TODO(dborowitz): Remove when we no longer depend on SSH.
.setFS(FS.detect())
.build();
Config cfg = dest.getConfig();
cfg.setString("remote", "origin", "url", uri);
cfg.setString("remote", "origin", "fetch",
"+refs/heads/*:refs/remotes/origin/*");
TestRepository<InMemoryRepository> testRepo = new TestRepository<>(dest);
FetchResult result = testRepo.git().fetch().setRemote("origin").call();
String originMaster = "refs/remotes/origin/master";
if (result.getTrackingRefUpdate(originMaster) != null) {
testRepo.reset(originMaster);
}
return new TestRepository<>(dest);
}
public static Git cloneProject(String url, boolean checkout) throws GitAPIException, IOException {
final File gitDir = TempFileUtil.createTempDirectory();
final CloneCommand cloneCmd = Git.cloneRepository();
cloneCmd.setURI(url);
cloneCmd.setDirectory(gitDir);
cloneCmd.setNoCheckout(!checkout);
return cloneCmd.call();
public static TestRepository<InMemoryRepository> cloneProject(
Project.NameKey project, SshSession sshSession) throws Exception {
return cloneProject(project, sshSession.getUrl() + "/" + project.get());
}
public static void fetch(Git git, String spec) throws GitAPIException {

View File

@@ -311,7 +311,7 @@ public class RevisionIT extends AbstractDaemonTest {
assertThat(canRebase).isFalse();
merge(r2);
git.checkout().setName(r1.getCommit().name()).call();
testRepo.reset(r1.getCommit());
push = pushFactory.create(db, admin.getIdent(), testRepo);
PushOneCommit.Result r3 = push.to("refs/for/master");

View File

@@ -267,7 +267,8 @@ public class ChangeEditIT extends AbstractDaemonTest {
@Test
@TestProjectInput(createEmptyCommit = false)
public void updateRootCommitMessage() throws Exception {
setRepo(cloneProject(sshSession.getUrl() + "/" + project));
// Re-clone empty repo; TestRepository doesn't let us reset to unborn head.
testRepo = cloneProject(project, sshSession);
changeId = newChange(admin.getIdent());
change = getChange(changeId);

View File

@@ -68,7 +68,7 @@ public abstract class AbstractPushForReview extends AbstractDaemonTest {
default:
throw new IllegalArgumentException("unexpected protocol: " + p);
}
setRepo(cloneProject(url + "/" + project.get()));
setRepo(cloneProject(project, url + "/" + project.get()));
}
@Test

View File

@@ -105,7 +105,7 @@ public class SubmitOnPushIT extends AbstractDaemonTest {
git.fetch().setRefSpecs(new RefSpec("refs/meta/config:refs/meta/config")).call();
ObjectId objectId = git.getRepository().getRef("refs/meta/config").getObjectId();
git.checkout().setName(objectId.getName()).call();
testRepo.reset(objectId);
PushOneCommit.Result r = pushTo("refs/for/refs/meta/config%submit");
r.assertOkStatus();
@@ -116,10 +116,9 @@ public class SubmitOnPushIT extends AbstractDaemonTest {
@Test
public void submitOnPushMergeConflict() throws Exception {
String master = "refs/heads/master";
ObjectId objectId = git.getRepository().getRef(master).getObjectId();
push(master, "one change", "a.txt", "some content");
git.checkout().setName(objectId.getName()).call();
ObjectId objectId = git.getRepository().getRef("HEAD").getObjectId();
push("refs/heads/master", "one change", "a.txt", "some content");
testRepo.reset(objectId);
grant(Permission.SUBMIT, project, "refs/for/refs/heads/master");
PushOneCommit.Result r =
@@ -132,9 +131,9 @@ public class SubmitOnPushIT extends AbstractDaemonTest {
@Test
public void submitOnPushSuccessfulMerge() throws Exception {
String master = "refs/heads/master";
ObjectId objectId = git.getRepository().getRef(master).getObjectId();
ObjectId objectId = git.getRepository().getRef("HEAD").getObjectId();
push(master, "one change", "a.txt", "some content");
git.checkout().setName(objectId.getName()).call();
testRepo.reset(objectId);
grant(Permission.SUBMIT, project, "refs/for/refs/heads/master");
PushOneCommit.Result r =

View File

@@ -53,7 +53,7 @@ public class ChangeOwnerIT extends AbstractDaemonTest {
SshSession sshSession = new SshSession(server, user);
initSsh(user);
sshSession.open();
setRepo(cloneProject(sshSession.getUrl() + "/" + project.get()));
setRepo(cloneProject(project, sshSession));
sshSession.close();
user2 = accounts.user2();
sessionDev = new RestSession(server, user2);

View File

@@ -61,15 +61,15 @@ public class ListBranchesIT extends AbstractDaemonTest {
@Test
public void listBranches() throws Exception {
pushTo("refs/heads/master");
String masterCommit = git.getRepository().getRef("master").getTarget().getObjectId().getName();
String headCommit = git.getRepository().getRef("HEAD").getTarget().getObjectId().getName();
pushTo("refs/heads/dev");
String devCommit = git.getRepository().getRef("master").getTarget().getObjectId().getName();
String devCommit = git.getRepository().getRef("HEAD").getTarget().getObjectId().getName();
RestResponse r = adminSession.get("/projects/" + project.get() + "/branches");
List<BranchInfo> expected = Lists.asList(
new BranchInfo("refs/meta/config", null, false),
new BranchInfo[] {
new BranchInfo("HEAD", "master", false),
new BranchInfo("refs/heads/master", masterCommit, false),
new BranchInfo("refs/heads/master", headCommit, false),
new BranchInfo("refs/heads/dev", devCommit, true)
});
List<BranchInfo> result = toBranchInfoList(r);
@@ -86,14 +86,14 @@ public class ListBranchesIT extends AbstractDaemonTest {
public void listBranchesSomeHidden() throws Exception {
blockRead(project, "refs/heads/dev");
pushTo("refs/heads/master");
String masterCommit = git.getRepository().getRef("master").getTarget().getObjectId().getName();
String headCommit = git.getRepository().getRef("HEAD").getTarget().getObjectId().getName();
pushTo("refs/heads/dev");
RestResponse r = userSession.get("/projects/" + project.get() + "/branches");
// refs/meta/config is hidden since user is no project owner
List<BranchInfo> expected = Lists.asList(
new BranchInfo("HEAD", "master", false),
new BranchInfo[] {
new BranchInfo("refs/heads/master", masterCommit, false),
new BranchInfo("refs/heads/master", headCommit, false),
});
assertBranches(expected, toBranchInfoList(r));
}
@@ -103,7 +103,7 @@ public class ListBranchesIT extends AbstractDaemonTest {
blockRead(project, "refs/heads/master");
pushTo("refs/heads/master");
pushTo("refs/heads/dev");
String devCommit = git.getRepository().getRef("master").getTarget().getObjectId().getName();
String devCommit = git.getRepository().getRef("HEAD").getTarget().getObjectId().getName();
RestResponse r = userSession.get("/projects/" + project.get() + "/branches");
// refs/meta/config is hidden since user is no project owner
assertBranches(Collections.singletonList(new BranchInfo("refs/heads/dev",

View File

@@ -68,10 +68,8 @@ public class ProjectLevelConfigIT extends AbstractDaemonTest {
parentCfg.setString("s2", "ss", "k3", "parentValue3");
parentCfg.setString("s2", "ss", "k4", "parentValue4");
Git parentGit =
cloneProject(sshSession.getUrl() + "/" + allProjects.get(), false);
TestRepository<?> parentTestRepo =
new TestRepository<>(parentGit.getRepository());
TestRepository<?> parentTestRepo = cloneProject(allProjects, sshSession);
Git parentGit = Git.wrap(parentTestRepo.getRepository());
fetch(parentGit, RefNames.REFS_CONFIG + ":refs/heads/config");
parentTestRepo.reset("refs/heads/config");
PushOneCommit push =

View File

@@ -99,7 +99,8 @@ public class GetRelatedIT extends AbstractDaemonTest {
// Swap the order of commits and push again.
testRepo.reset("HEAD~2");
git.cherryPick().include(c2).include(c1).call();
testRepo.cherryPick(c2);
testRepo.cherryPick(c1);
pushHead(git, "refs/for/master", false);
PatchSet.Id c1ps2 = getPatchSetId(c1);
PatchSet.Id c2ps2 = getPatchSetId(c2);
@@ -143,7 +144,8 @@ public class GetRelatedIT extends AbstractDaemonTest {
// Swap the order of commits, create a new commit on top, and push again.
testRepo.reset(initial);
git.cherryPick().include(c2).include(c1).call();
testRepo.cherryPick(c2);
testRepo.cherryPick(c1);
RevCommit c3 = commitBuilder()
.add("c.txt", "3")
.message("subject: 3")

View File

@@ -120,7 +120,7 @@ public class PatchListCacheIT extends AbstractDaemonTest {
pushHead(git, "refs/for/master", false);
// Change 1,2 (+FILE_A, -FILE_D))
git.cherryPick().include(c).call();
testRepo.cherryPick(c);
pushHead(git, "refs/for/master", false);
// Compare Change 1,2 with Base (+FILE_A, -FILE_D))
@@ -187,7 +187,7 @@ public class PatchListCacheIT extends AbstractDaemonTest {
pushHead(git, "refs/for/master", false);
// Change 1,2 (+FILE_A, +FILE_C, -FILE_D)
git.cherryPick().include(a).call();
testRepo.cherryPick(a);
RevCommit b = amendBuilder()
.add(FILE_C, "2")
.create();

View File

@@ -189,7 +189,7 @@ public class LabelTypeIT extends AbstractDaemonTest {
PushOneCommit.Result r2 = push.to("refs/for/master");
merge(r2);
git.checkout().setName(r1.getCommit().name()).call();
testRepo.reset(r1.getCommit());
push = pushFactory.create(db, admin.getIdent(), testRepo, subject, file, contents);
PushOneCommit.Result r3 = push.to("refs/for/master");
revision(r3).review(ReviewInput.recommend());
@@ -216,7 +216,7 @@ public class LabelTypeIT extends AbstractDaemonTest {
PushOneCommit.Result r2 = push.to("refs/for/master");
merge(r2);
git.checkout().setName(r1.getCommit().name()).call();
testRepo.reset(r1.getCommit());
push = pushFactory.create(db, admin.getIdent(), testRepo, subject, file, contents);
PushOneCommit.Result r3 = push.to("refs/for/master");
revision(r3).review(ReviewInput.recommend());
@@ -232,7 +232,7 @@ public class LabelTypeIT extends AbstractDaemonTest {
saveLabelConfig();
PushOneCommit.Result r1 = createChange();
git.checkout().setName(r1.getCommit().name()).call();
testRepo.reset(r1.getCommit());
PushOneCommit push = pushFactory.create(db, admin.getIdent(), testRepo,
PushOneCommit.SUBJECT, "b.txt", "other contents");
@@ -262,7 +262,7 @@ public class LabelTypeIT extends AbstractDaemonTest {
PushOneCommit.Result r1 = createChange();
git.checkout().setName(r1.getCommit().name()).call();
testRepo.reset(r1.getCommit());
PushOneCommit push = pushFactory.create(db, admin.getIdent(), testRepo,
PushOneCommit.SUBJECT, "b.txt", "other contents");
@@ -303,7 +303,7 @@ public class LabelTypeIT extends AbstractDaemonTest {
PushOneCommit.Result basePlusMMinusM = push.to("refs/for/master");
merge(basePlusMMinusM);
git.checkout().setName(base.getCommit().name()).call();
testRepo.reset(base.getCommit());
push = pushFactory.create(db, admin.getIdent(), testRepo,
PushOneCommit.SUBJECT, file, contents + "MM");
PushOneCommit.Result patchSet = push.to("refs/for/master");

View File

@@ -19,6 +19,7 @@ import static com.google.gerrit.acceptance.GitUtil.cloneProject;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.NoHttpd;
import com.google.gerrit.reviewdb.client.Project;
import org.junit.Ignore;
import org.junit.Test;
@@ -50,7 +51,7 @@ public class JschVerifyFalseBugIT extends AbstractDaemonTest {
for (int i = 1; i < 100; i++) {
String p = "p" + i;
createProject(p);
cloneProject(sshSession.getUrl() + "/" + p);
cloneProject(new Project.NameKey(p), sshSession);
}
return null;
}