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); project = new Project.NameKey(projectInput.name);
createProject(projectInput); createProject(projectInput);
setRepo(cloneProject(sshSession.getUrl() + "/" + project.get())); setRepo(cloneProject(project, sshSession));
} }
private ProjectInput projectInput(Description description) { private ProjectInput projectInput(Description description) {
@@ -237,9 +237,9 @@ public abstract class AbstractDaemonTest {
return in; return in;
} }
protected void setRepo(Git git) throws Exception { protected void setRepo(TestRepository<?> testRepo) throws Exception {
this.git = git; this.git = Git.wrap(testRepo.getRepository());
testRepo = new TestRepository<>(git.getRepository()); this.testRepo = new TestRepository<>(git.getRepository());
} }
protected void createProject(String name) throws RestApiException { 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.base.Optional;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import com.google.gerrit.common.FooterConstants; 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.JSch;
import com.jcraft.jsch.JSchException; import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session; import com.jcraft.jsch.Session;
import org.eclipse.jgit.api.CloneCommand;
import org.eclipse.jgit.api.FetchCommand; import org.eclipse.jgit.api.FetchCommand;
import org.eclipse.jgit.api.Git; import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.PushCommand; import org.eclipse.jgit.api.PushCommand;
import org.eclipse.jgit.api.errors.GitAPIException; 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.junit.TestRepository;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.transport.FetchResult;
import org.eclipse.jgit.transport.JschConfigSessionFactory; import org.eclipse.jgit.transport.JschConfigSessionFactory;
import org.eclipse.jgit.transport.OpenSshConfig.Host; import org.eclipse.jgit.transport.OpenSshConfig.Host;
import org.eclipse.jgit.transport.PushResult; 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.transport.SshSessionFactory;
import org.eclipse.jgit.util.FS; import org.eclipse.jgit.util.FS;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
import java.util.Properties; import java.util.Properties;
@@ -67,17 +69,31 @@ public class GitUtil {
}); });
} }
public static Git cloneProject(String url) throws GitAPIException, IOException { public static TestRepository<InMemoryRepository> cloneProject(
return cloneProject(url, true); 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 { public static TestRepository<InMemoryRepository> cloneProject(
final File gitDir = TempFileUtil.createTempDirectory(); Project.NameKey project, SshSession sshSession) throws Exception {
final CloneCommand cloneCmd = Git.cloneRepository(); return cloneProject(project, sshSession.getUrl() + "/" + project.get());
cloneCmd.setURI(url);
cloneCmd.setDirectory(gitDir);
cloneCmd.setNoCheckout(!checkout);
return cloneCmd.call();
} }
public static void fetch(Git git, String spec) throws GitAPIException { public static void fetch(Git git, String spec) throws GitAPIException {

View File

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

View File

@@ -267,7 +267,8 @@ public class ChangeEditIT extends AbstractDaemonTest {
@Test @Test
@TestProjectInput(createEmptyCommit = false) @TestProjectInput(createEmptyCommit = false)
public void updateRootCommitMessage() throws Exception { 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()); changeId = newChange(admin.getIdent());
change = getChange(changeId); change = getChange(changeId);

View File

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

View File

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

View File

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

View File

@@ -61,15 +61,15 @@ public class ListBranchesIT extends AbstractDaemonTest {
@Test @Test
public void listBranches() throws Exception { public void listBranches() throws Exception {
pushTo("refs/heads/master"); 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"); 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"); RestResponse r = adminSession.get("/projects/" + project.get() + "/branches");
List<BranchInfo> expected = Lists.asList( List<BranchInfo> expected = Lists.asList(
new BranchInfo("refs/meta/config", null, false), new BranchInfo("refs/meta/config", null, false),
new BranchInfo[] { new BranchInfo[] {
new BranchInfo("HEAD", "master", false), 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) new BranchInfo("refs/heads/dev", devCommit, true)
}); });
List<BranchInfo> result = toBranchInfoList(r); List<BranchInfo> result = toBranchInfoList(r);
@@ -86,14 +86,14 @@ public class ListBranchesIT extends AbstractDaemonTest {
public void listBranchesSomeHidden() throws Exception { public void listBranchesSomeHidden() throws Exception {
blockRead(project, "refs/heads/dev"); blockRead(project, "refs/heads/dev");
pushTo("refs/heads/master"); 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"); pushTo("refs/heads/dev");
RestResponse r = userSession.get("/projects/" + project.get() + "/branches"); RestResponse r = userSession.get("/projects/" + project.get() + "/branches");
// refs/meta/config is hidden since user is no project owner // refs/meta/config is hidden since user is no project owner
List<BranchInfo> expected = Lists.asList( List<BranchInfo> expected = Lists.asList(
new BranchInfo("HEAD", "master", false), new BranchInfo("HEAD", "master", false),
new BranchInfo[] { new BranchInfo[] {
new BranchInfo("refs/heads/master", masterCommit, false), new BranchInfo("refs/heads/master", headCommit, false),
}); });
assertBranches(expected, toBranchInfoList(r)); assertBranches(expected, toBranchInfoList(r));
} }
@@ -103,7 +103,7 @@ public class ListBranchesIT extends AbstractDaemonTest {
blockRead(project, "refs/heads/master"); blockRead(project, "refs/heads/master");
pushTo("refs/heads/master"); pushTo("refs/heads/master");
pushTo("refs/heads/dev"); 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"); RestResponse r = userSession.get("/projects/" + project.get() + "/branches");
// refs/meta/config is hidden since user is no project owner // refs/meta/config is hidden since user is no project owner
assertBranches(Collections.singletonList(new BranchInfo("refs/heads/dev", 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", "k3", "parentValue3");
parentCfg.setString("s2", "ss", "k4", "parentValue4"); parentCfg.setString("s2", "ss", "k4", "parentValue4");
Git parentGit = TestRepository<?> parentTestRepo = cloneProject(allProjects, sshSession);
cloneProject(sshSession.getUrl() + "/" + allProjects.get(), false); Git parentGit = Git.wrap(parentTestRepo.getRepository());
TestRepository<?> parentTestRepo =
new TestRepository<>(parentGit.getRepository());
fetch(parentGit, RefNames.REFS_CONFIG + ":refs/heads/config"); fetch(parentGit, RefNames.REFS_CONFIG + ":refs/heads/config");
parentTestRepo.reset("refs/heads/config"); parentTestRepo.reset("refs/heads/config");
PushOneCommit push = PushOneCommit push =

View File

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

View File

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

View File

@@ -189,7 +189,7 @@ public class LabelTypeIT extends AbstractDaemonTest {
PushOneCommit.Result r2 = push.to("refs/for/master"); PushOneCommit.Result r2 = push.to("refs/for/master");
merge(r2); merge(r2);
git.checkout().setName(r1.getCommit().name()).call(); testRepo.reset(r1.getCommit());
push = pushFactory.create(db, admin.getIdent(), testRepo, subject, file, contents); push = pushFactory.create(db, admin.getIdent(), testRepo, subject, file, contents);
PushOneCommit.Result r3 = push.to("refs/for/master"); PushOneCommit.Result r3 = push.to("refs/for/master");
revision(r3).review(ReviewInput.recommend()); revision(r3).review(ReviewInput.recommend());
@@ -216,7 +216,7 @@ public class LabelTypeIT extends AbstractDaemonTest {
PushOneCommit.Result r2 = push.to("refs/for/master"); PushOneCommit.Result r2 = push.to("refs/for/master");
merge(r2); merge(r2);
git.checkout().setName(r1.getCommit().name()).call(); testRepo.reset(r1.getCommit());
push = pushFactory.create(db, admin.getIdent(), testRepo, subject, file, contents); push = pushFactory.create(db, admin.getIdent(), testRepo, subject, file, contents);
PushOneCommit.Result r3 = push.to("refs/for/master"); PushOneCommit.Result r3 = push.to("refs/for/master");
revision(r3).review(ReviewInput.recommend()); revision(r3).review(ReviewInput.recommend());
@@ -232,7 +232,7 @@ public class LabelTypeIT extends AbstractDaemonTest {
saveLabelConfig(); saveLabelConfig();
PushOneCommit.Result r1 = createChange(); PushOneCommit.Result r1 = createChange();
git.checkout().setName(r1.getCommit().name()).call(); testRepo.reset(r1.getCommit());
PushOneCommit push = pushFactory.create(db, admin.getIdent(), testRepo, PushOneCommit push = pushFactory.create(db, admin.getIdent(), testRepo,
PushOneCommit.SUBJECT, "b.txt", "other contents"); PushOneCommit.SUBJECT, "b.txt", "other contents");
@@ -262,7 +262,7 @@ public class LabelTypeIT extends AbstractDaemonTest {
PushOneCommit.Result r1 = createChange(); PushOneCommit.Result r1 = createChange();
git.checkout().setName(r1.getCommit().name()).call(); testRepo.reset(r1.getCommit());
PushOneCommit push = pushFactory.create(db, admin.getIdent(), testRepo, PushOneCommit push = pushFactory.create(db, admin.getIdent(), testRepo,
PushOneCommit.SUBJECT, "b.txt", "other contents"); PushOneCommit.SUBJECT, "b.txt", "other contents");
@@ -303,7 +303,7 @@ public class LabelTypeIT extends AbstractDaemonTest {
PushOneCommit.Result basePlusMMinusM = push.to("refs/for/master"); PushOneCommit.Result basePlusMMinusM = push.to("refs/for/master");
merge(basePlusMMinusM); merge(basePlusMMinusM);
git.checkout().setName(base.getCommit().name()).call(); testRepo.reset(base.getCommit());
push = pushFactory.create(db, admin.getIdent(), testRepo, push = pushFactory.create(db, admin.getIdent(), testRepo,
PushOneCommit.SUBJECT, file, contents + "MM"); PushOneCommit.SUBJECT, file, contents + "MM");
PushOneCommit.Result patchSet = push.to("refs/for/master"); 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.AbstractDaemonTest;
import com.google.gerrit.acceptance.NoHttpd; import com.google.gerrit.acceptance.NoHttpd;
import com.google.gerrit.reviewdb.client.Project;
import org.junit.Ignore; import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
@@ -50,7 +51,7 @@ public class JschVerifyFalseBugIT extends AbstractDaemonTest {
for (int i = 1; i < 100; i++) { for (int i = 1; i < 100; i++) {
String p = "p" + i; String p = "p" + i;
createProject(p); createProject(p);
cloneProject(sshSession.getUrl() + "/" + p); cloneProject(new Project.NameKey(p), sshSession);
} }
return null; return null;
} }