Format all Java files with google-java-format

Having a standard tool for formatting saves reviewers' valuable time.
google-java-format is Google's standard formatter and is somewhat
inspired by gofmt[1]. This commit formats everything using
google-java-format version 1.2.

The downside of this one-off formatting is breaking blame. This can be
somewhat hacked around with a tool like git-hyper-blame[2], but it's
definitely not optimal until/unless this kind of feature makes its way
to git core.

Not in this change:
* Tool support, e.g. Eclipse. The command must be run manually [3].
* Documentation of best practice, e.g. new 100-column default.

[1] https://talks.golang.org/2015/gofmt-en.slide#3
[2] https://commondatastorage.googleapis.com/chrome-infra-docs/flat/depot_tools/docs/html/git-hyper-blame.html
[3] git ls-files | grep java$ | xargs google-java-format -i

Change-Id: Id5f3c6de95ce0b68b41f0a478b5c99a93675aaa3
Signed-off-by: David Pursehouse <dpursehouse@collab.net>
This commit is contained in:
Dave Borowitz
2016-11-13 09:56:32 -08:00
committed by David Pursehouse
parent 6723b6d0fa
commit 292fa154c1
2443 changed files with 54816 additions and 57825 deletions

View File

@@ -45,10 +45,6 @@ import com.google.gerrit.testutil.FakeEmailSender;
import com.google.gerrit.testutil.FakeEmailSender.Message;
import com.google.inject.Inject;
import com.google.inject.Provider;
import org.junit.Before;
import org.junit.Test;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.HashMap;
@@ -57,18 +53,17 @@ import java.util.Map;
import java.util.function.Supplier;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.junit.Before;
import org.junit.Test;
@NoHttpd
public class CommentsIT extends AbstractDaemonTest {
@Inject
private Provider<ChangesCollection> changes;
@Inject private Provider<ChangesCollection> changes;
@Inject
private Provider<PostReview> postReview;
@Inject private Provider<PostReview> postReview;
@Inject
private FakeEmailSender email;
@Inject private FakeEmailSender email;
private final Integer[] lines = {0, 1};
@@ -129,14 +124,13 @@ public class CommentsIT extends AbstractDaemonTest {
for (Integer line : lines) {
String file = "file";
String contents = "contents " + line;
PushOneCommit push = pushFactory.create(db, admin.getIdent(), testRepo,
"first subject", file, contents);
PushOneCommit push =
pushFactory.create(db, admin.getIdent(), testRepo, "first subject", file, contents);
PushOneCommit.Result r = push.to("refs/for/master");
String changeId = r.getChangeId();
String revId = r.getCommit().getName();
ReviewInput input = new ReviewInput();
CommentInput comment =
newComment(file, Side.REVISION, line, "comment 1", false);
CommentInput comment = newComment(file, Side.REVISION, line, "comment 1", false);
input.comments = new HashMap<>();
input.comments.put(comment.path, Lists.newArrayList(comment));
revision(r).review(input);
@@ -144,8 +138,8 @@ public class CommentsIT extends AbstractDaemonTest {
assertThat(result).isNotEmpty();
CommentInfo actual = Iterables.getOnlyElement(result.get(comment.path));
assertThat(comment).isEqualTo(infoToInput(file).apply(actual));
assertThat(comment).isEqualTo(infoToInput(file).apply(
getPublishedComment(changeId, revId, actual.id)));
assertThat(comment)
.isEqualTo(infoToInput(file).apply(getPublishedComment(changeId, revId, actual.id)));
}
}
@@ -154,19 +148,17 @@ public class CommentsIT extends AbstractDaemonTest {
for (Integer line : lines) {
String file = "file";
String contents = "contents " + line;
PushOneCommit push = pushFactory.create(db, admin.getIdent(), testRepo,
"first subject", file, contents);
PushOneCommit push =
pushFactory.create(db, admin.getIdent(), testRepo, "first subject", file, contents);
PushOneCommit.Result r = push.to("refs/for/master");
String changeId = r.getChangeId();
String revId = r.getCommit().getName();
ReviewInput input = new ReviewInput();
CommentInput comment =
newComment(file, Side.REVISION, line, "comment 1", false);
CommentInput comment = newComment(file, Side.REVISION, line, "comment 1", false);
input.comments = new HashMap<>();
input.comments.put(comment.path, Lists.newArrayList(comment));
revision(r).review(input);
Map<String, List<CommentInfo>> result =
getPublishedComments(changeId, revId);
Map<String, List<CommentInfo>> result = getPublishedComments(changeId, revId);
CommentInfo actual = Iterables.getOnlyElement(result.get(comment.path));
input = new ReviewInput();
@@ -178,8 +170,8 @@ public class CommentsIT extends AbstractDaemonTest {
result = getPublishedComments(changeId, revId);
actual = result.get(comment.path).get(1);
assertThat(comment).isEqualTo(infoToInput(file).apply(actual));
assertThat(comment).isEqualTo(infoToInput(file).apply(
getPublishedComment(changeId, revId, actual.id)));
assertThat(comment)
.isEqualTo(infoToInput(file).apply(getPublishedComment(changeId, revId, actual.id)));
}
}
@@ -188,14 +180,13 @@ public class CommentsIT extends AbstractDaemonTest {
for (Integer line : lines) {
String file = "file";
String contents = "contents " + line;
PushOneCommit push = pushFactory.create(db, admin.getIdent(), testRepo,
"first subject", file, contents);
PushOneCommit push =
pushFactory.create(db, admin.getIdent(), testRepo, "first subject", file, contents);
PushOneCommit.Result r = push.to("refs/for/master");
String changeId = r.getChangeId();
String revId = r.getCommit().getName();
ReviewInput input = new ReviewInput();
CommentInput comment =
newComment(file, Side.REVISION, line, "comment 1", true);
CommentInput comment = newComment(file, Side.REVISION, line, "comment 1", true);
input.comments = new HashMap<>();
input.comments.put(comment.path, Lists.newArrayList(comment));
revision(r).review(input);
@@ -203,8 +194,8 @@ public class CommentsIT extends AbstractDaemonTest {
assertThat(result).isNotEmpty();
CommentInfo actual = Iterables.getOnlyElement(result.get(comment.path));
assertThat(comment).isEqualTo(infoToInput(file).apply(actual));
assertThat(comment).isEqualTo(infoToInput(file).apply(
getPublishedComment(changeId, revId, actual.id)));
assertThat(comment)
.isEqualTo(infoToInput(file).apply(getPublishedComment(changeId, revId, actual.id)));
}
}
@@ -217,8 +208,7 @@ public class CommentsIT extends AbstractDaemonTest {
String revId = r.getCommit().getName();
ReviewInput input = new ReviewInput();
CommentInput c1 = newComment(file, Side.REVISION, line, "ps-1", false);
CommentInput c2 =
newComment(file, Side.PARENT, line, "auto-merge of ps-1", false);
CommentInput c2 = newComment(file, Side.PARENT, line, "auto-merge of ps-1", false);
CommentInput c3 = newCommentOnParent(file, 1, line, "parent-1 of ps-1");
CommentInput c4 = newCommentOnParent(file, 2, line, "parent-2 of ps-1");
input.comments = new HashMap<>();
@@ -245,8 +235,7 @@ public class CommentsIT extends AbstractDaemonTest {
revision(r).review(input);
Map<String, List<CommentInfo>> result = getPublishedComments(changeId, revId);
assertThat(result).isNotEmpty();
assertThat(Lists.transform(result.get(file), infoToInput(file)))
.containsExactly(c1, c2, c3);
assertThat(Lists.transform(result.get(file), infoToInput(file))).containsExactly(c1, c2, c3);
}
}
@@ -254,21 +243,19 @@ public class CommentsIT extends AbstractDaemonTest {
public void postCommentOnCommitMessageOnAutoMerge() throws Exception {
PushOneCommit.Result r = createMergeCommitChange("refs/for/master");
ReviewInput input = new ReviewInput();
CommentInput c = newComment(Patch.COMMIT_MSG, Side.PARENT, 0,
"comment on auto-merge", false);
CommentInput c = newComment(Patch.COMMIT_MSG, Side.PARENT, 0, "comment on auto-merge", false);
input.comments = new HashMap<>();
input.comments.put(Patch.COMMIT_MSG, ImmutableList.of(c));
exception.expect(BadRequestException.class);
exception.expectMessage(
"cannot comment on " + Patch.COMMIT_MSG + " on auto-merge");
exception.expectMessage("cannot comment on " + Patch.COMMIT_MSG + " on auto-merge");
revision(r).review(input);
}
@Test
public void listComments() throws Exception {
String file = "file";
PushOneCommit push = pushFactory.create(db, admin.getIdent(), testRepo,
"first subject", file, "contents");
PushOneCommit push =
pushFactory.create(db, admin.getIdent(), testRepo, "first subject", file, "contents");
PushOneCommit.Result r = push.to("refs/for/master");
String changeId = r.getChangeId();
String revId = r.getCommit().getName();
@@ -277,8 +264,7 @@ public class CommentsIT extends AbstractDaemonTest {
List<CommentInput> expectedComments = new ArrayList<>();
for (Integer line : lines) {
ReviewInput input = new ReviewInput();
CommentInput comment =
newComment(file, Side.REVISION, line, "comment " + line, false);
CommentInput comment = newComment(file, Side.REVISION, line, "comment " + line, false);
expectedComments.add(comment);
input.comments = new HashMap<>();
input.comments.put(comment.path, Lists.newArrayList(comment));
@@ -313,8 +299,7 @@ public class CommentsIT extends AbstractDaemonTest {
assertThat(comment).isEqualTo(infoToDraft(path).apply(actual));
// Posting a draft comment doesn't cause lastUpdatedOn to change.
assertThat(r.getChange().change().getLastUpdatedOn())
.isEqualTo(origLastUpdated);
assertThat(r.getChange().change().getLastUpdatedOn()).isEqualTo(origLastUpdated);
}
}
@@ -347,8 +332,7 @@ public class CommentsIT extends AbstractDaemonTest {
String changeId = r.getChangeId();
String revId = r.getCommit().getName();
String path = "file1";
DraftInput comment = newDraft(
path, Side.REVISION, line, "comment 1");
DraftInput comment = newDraft(path, Side.REVISION, line, "comment 1");
CommentInfo returned = addDraft(changeId, revId, comment);
CommentInfo actual = getDraftComment(changeId, revId, returned.id);
assertThat(comment).isEqualTo(infoToDraft(path).apply(actual));
@@ -369,8 +353,7 @@ public class CommentsIT extends AbstractDaemonTest {
assertThat(drafts).isEmpty();
// Deleting a draft comment doesn't cause lastUpdatedOn to change.
assertThat(r.getChange().change().getLastUpdatedOn())
.isEqualTo(origLastUpdated);
assertThat(r.getChange().change().getLastUpdatedOn()).isEqualTo(origLastUpdated);
}
}
@@ -380,24 +363,21 @@ public class CommentsIT extends AbstractDaemonTest {
for (Integer line : lines) {
String file = "file";
String contents = "contents " + line;
PushOneCommit push = pushFactory.create(db, admin.getIdent(), testRepo,
"first subject", file, contents);
PushOneCommit push =
pushFactory.create(db, admin.getIdent(), testRepo, "first subject", file, contents);
PushOneCommit.Result r = push.to("refs/for/master");
String changeId = r.getChangeId();
String revId = r.getCommit().getName();
Timestamp origLastUpdated = r.getChange().change().getLastUpdatedOn();
ReviewInput input = new ReviewInput();
CommentInput comment =
newComment(file, Side.REVISION, line, "comment 1", false);
CommentInput comment = newComment(file, Side.REVISION, line, "comment 1", false);
comment.updated = timestamp;
input.comments = new HashMap<>();
input.comments.put(comment.path, Lists.newArrayList(comment));
ChangeResource changeRsrc =
changes.get().parse(TopLevelResource.INSTANCE,
IdString.fromDecoded(changeId));
RevisionResource revRsrc =
revisions.parse(changeRsrc, IdString.fromDecoded(revId));
changes.get().parse(TopLevelResource.INSTANCE, IdString.fromDecoded(changeId));
RevisionResource revRsrc = revisions.parse(changeRsrc, IdString.fromDecoded(revId));
postReview.get().apply(revRsrc, input, timestamp);
Map<String, List<CommentInfo>> result = getPublishedComments(changeId, revId);
assertThat(result).isNotEmpty();
@@ -405,12 +385,10 @@ public class CommentsIT extends AbstractDaemonTest {
CommentInput ci = infoToInput(file).apply(actual);
ci.updated = comment.updated;
assertThat(comment).isEqualTo(ci);
assertThat(actual.updated)
.isEqualTo(gApi.changes().id(r.getChangeId()).info().created);
assertThat(actual.updated).isEqualTo(gApi.changes().id(r.getChangeId()).info().created);
// Updating historic comments doesn't cause lastUpdatedOn to regress.
assertThat(r.getChange().change().getLastUpdatedOn())
.isEqualTo(origLastUpdated);
assertThat(r.getChange().change().getLastUpdatedOn()).isEqualTo(origLastUpdated);
}
}
@@ -427,9 +405,10 @@ public class CommentsIT extends AbstractDaemonTest {
result = getPublishedComments(changeId, revId);
assertThat(result.get(FILE_NAME)).hasSize(2);
PushOneCommit.Result r2 = pushFactory.create(
db, admin.getIdent(), testRepo, SUBJECT, FILE_NAME, "content")
.to("refs/for/master");
PushOneCommit.Result r2 =
pushFactory
.create(db, admin.getIdent(), testRepo, SUBJECT, FILE_NAME, "content")
.to("refs/for/master");
changeId = r2.getChangeId();
revId = r2.getCommit().getName();
addComment(r2, "nit: trailing whitespace", true);
@@ -441,25 +420,30 @@ public class CommentsIT extends AbstractDaemonTest {
public void listChangeDrafts() throws Exception {
PushOneCommit.Result r1 = createChange();
PushOneCommit.Result r2 = pushFactory.create(
db, admin.getIdent(), testRepo, SUBJECT, FILE_NAME, "new content",
r1.getChangeId())
.to("refs/for/master");
PushOneCommit.Result r2 =
pushFactory
.create(
db, admin.getIdent(), testRepo, SUBJECT, FILE_NAME, "new content", r1.getChangeId())
.to("refs/for/master");
setApiUser(admin);
addDraft(r1.getChangeId(), r1.getCommit().getName(),
addDraft(
r1.getChangeId(),
r1.getCommit().getName(),
newDraft(FILE_NAME, Side.REVISION, 1, "nit: trailing whitespace"));
addDraft(r2.getChangeId(), r2.getCommit().getName(),
addDraft(
r2.getChangeId(),
r2.getCommit().getName(),
newDraft(FILE_NAME, Side.REVISION, 1, "typo: content"));
setApiUser(user);
addDraft(r2.getChangeId(), r2.getCommit().getName(),
addDraft(
r2.getChangeId(),
r2.getCommit().getName(),
newDraft(FILE_NAME, Side.REVISION, 1, "+1, please fix"));
setApiUser(admin);
Map<String, List<CommentInfo>> actual =
gApi.changes().id(r1.getChangeId()).drafts();
Map<String, List<CommentInfo>> actual = gApi.changes().id(r1.getChangeId()).drafts();
assertThat(actual.keySet()).containsExactly(FILE_NAME);
List<CommentInfo> comments = actual.get(FILE_NAME);
assertThat(comments).hasSize(2);
@@ -483,17 +467,16 @@ public class CommentsIT extends AbstractDaemonTest {
public void listChangeComments() throws Exception {
PushOneCommit.Result r1 = createChange();
PushOneCommit.Result r2 = pushFactory.create(
db, admin.getIdent(), testRepo, SUBJECT, FILE_NAME, "new cntent",
r1.getChangeId())
.to("refs/for/master");
PushOneCommit.Result r2 =
pushFactory
.create(
db, admin.getIdent(), testRepo, SUBJECT, FILE_NAME, "new cntent", r1.getChangeId())
.to("refs/for/master");
addComment(r1, "nit: trailing whitespace");
addComment(r2, "typo: content");
Map<String, List<CommentInfo>> actual = gApi.changes()
.id(r2.getChangeId())
.comments();
Map<String, List<CommentInfo>> actual = gApi.changes().id(r2.getChangeId()).comments();
assertThat(actual.keySet()).containsExactly(FILE_NAME);
List<CommentInfo> comments = actual.get(FILE_NAME);
@@ -520,11 +503,9 @@ public class CommentsIT extends AbstractDaemonTest {
PushOneCommit.Result r = createChange();
String changeId = r.getChangeId();
String revId = r.getCommit().getName();
DraftInput comment = newDraft(
"file1", Side.REVISION, line, "comment 1");
DraftInput comment = newDraft("file1", Side.REVISION, line, "comment 1");
addDraft(changeId, revId, comment);
assertThat(gApi.changes().query(
"change:" + changeId + " has:draft").get()).hasSize(1);
assertThat(gApi.changes().query("change:" + changeId + " has:draft").get()).hasSize(1);
}
}
@@ -532,52 +513,65 @@ public class CommentsIT extends AbstractDaemonTest {
public void publishCommentsAllRevisions() throws Exception {
PushOneCommit.Result r1 = createChange();
PushOneCommit.Result r2 = pushFactory.create(
db, admin.getIdent(), testRepo, SUBJECT, FILE_NAME, "new\ncntent\n",
r1.getChangeId())
.to("refs/for/master");
PushOneCommit.Result r2 =
pushFactory
.create(
db,
admin.getIdent(),
testRepo,
SUBJECT,
FILE_NAME,
"new\ncntent\n",
r1.getChangeId())
.to("refs/for/master");
addDraft(r1.getChangeId(), r1.getCommit().getName(),
addDraft(
r1.getChangeId(),
r1.getCommit().getName(),
newDraft(FILE_NAME, Side.REVISION, 1, "nit: trailing whitespace"));
addDraft(r1.getChangeId(), r1.getCommit().getName(),
addDraft(
r1.getChangeId(),
r1.getCommit().getName(),
newDraft(FILE_NAME, Side.PARENT, 2, "what happened to this?"));
addDraft(r2.getChangeId(), r2.getCommit().getName(),
addDraft(
r2.getChangeId(),
r2.getCommit().getName(),
newDraft(FILE_NAME, Side.REVISION, 1, "join lines"));
addDraft(r2.getChangeId(), r2.getCommit().getName(),
addDraft(
r2.getChangeId(),
r2.getCommit().getName(),
newDraft(FILE_NAME, Side.REVISION, 2, "typo: content"));
addDraft(r2.getChangeId(), r2.getCommit().getName(),
addDraft(
r2.getChangeId(),
r2.getCommit().getName(),
newDraft(FILE_NAME, Side.PARENT, 1, "comment 1 on base"));
addDraft(r2.getChangeId(), r2.getCommit().getName(),
addDraft(
r2.getChangeId(),
r2.getCommit().getName(),
newDraft(FILE_NAME, Side.PARENT, 2, "comment 2 on base"));
PushOneCommit.Result other = createChange();
// Drafts on other changes aren't returned.
addDraft(other.getChangeId(), other.getCommit().getName(),
addDraft(
other.getChangeId(),
other.getCommit().getName(),
newDraft(FILE_NAME, Side.REVISION, 1, "unrelated comment"));
setApiUser(admin);
// Drafts by other users aren't returned.
addDraft(r2.getChangeId(), r2.getCommit().getName(),
newDraft(FILE_NAME, Side.REVISION, 2, "oops"));
addDraft(
r2.getChangeId(), r2.getCommit().getName(), newDraft(FILE_NAME, Side.REVISION, 2, "oops"));
setApiUser(user);
ReviewInput reviewInput = new ReviewInput();
reviewInput.drafts = DraftHandling.PUBLISH_ALL_REVISIONS;
reviewInput.message = "comments";
gApi.changes()
.id(r2.getChangeId())
.current()
.review(reviewInput);
gApi.changes().id(r2.getChangeId()).current().review(reviewInput);
assertThat(gApi.changes()
.id(r1.getChangeId())
.revision(r1.getCommit().name())
.drafts())
assertThat(gApi.changes().id(r1.getChangeId()).revision(r1.getCommit().name()).drafts())
.isEmpty();
Map<String, List<CommentInfo>> ps1Map = gApi.changes()
.id(r1.getChangeId())
.revision(r1.getCommit().name())
.comments();
Map<String, List<CommentInfo>> ps1Map =
gApi.changes().id(r1.getChangeId()).revision(r1.getCommit().name()).comments();
assertThat(ps1Map.keySet()).containsExactly(FILE_NAME);
List<CommentInfo> ps1List = ps1Map.get(FILE_NAME);
assertThat(ps1List).hasSize(2);
@@ -586,15 +580,10 @@ public class CommentsIT extends AbstractDaemonTest {
assertThat(ps1List.get(1).message).isEqualTo("nit: trailing whitespace");
assertThat(ps1List.get(1).side).isNull();
assertThat(gApi.changes()
.id(r2.getChangeId())
.revision(r2.getCommit().name())
.drafts())
assertThat(gApi.changes().id(r2.getChangeId()).revision(r2.getCommit().name()).drafts())
.isEmpty();
Map<String, List<CommentInfo>> ps2Map = gApi.changes()
.id(r2.getChangeId())
.revision(r2.getCommit().name())
.comments();
Map<String, List<CommentInfo>> ps2Map =
gApi.changes().id(r2.getChangeId()).revision(r2.getCommit().name()).comments();
assertThat(ps2Map.keySet()).containsExactly(FILE_NAME);
List<CommentInfo> ps2List = ps2Map.get(FILE_NAME);
assertThat(ps2List).hasSize(4);
@@ -607,49 +596,74 @@ public class CommentsIT extends AbstractDaemonTest {
assertThat(messages).hasSize(1);
String url = canonicalWebUrl.get();
int c = r1.getChange().getId().get();
assertThat(extractComments(messages.get(0).body())).isEqualTo(
"Patch Set 2:\n"
+ "\n"
+ "(6 comments)\n"
+ "\n"
+ "comments\n"
+ "\n"
+ url + "#/c/" + c + "/1/a.txt\n"
+ "File a.txt:\n"
+ "\n"
+ url + "#/c/" + c + "/1/a.txt@a2\n"
+ "PS1, Line 2: \n"
+ "what happened to this?\n"
+ "\n"
+ "\n"
+ url + "#/c/" + c + "/1/a.txt@1\n"
+ "PS1, Line 1: ew\n"
+ "nit: trailing whitespace\n"
+ "\n"
+ "\n"
+ url + "#/c/" + c + "/2/a.txt\n"
+ "File a.txt:\n"
+ "\n"
+ url + "#/c/" + c + "/2/a.txt@a1\n"
+ "PS2, Line 1: \n"
+ "comment 1 on base\n"
+ "\n"
+ "\n"
+ url + "#/c/" + c + "/2/a.txt@a2\n"
+ "PS2, Line 2: \n"
+ "comment 2 on base\n"
+ "\n"
+ "\n"
+ url + "#/c/" + c + "/2/a.txt@1\n"
+ "PS2, Line 1: ew\n"
+ "join lines\n"
+ "\n"
+ "\n"
+ url + "#/c/" + c + "/2/a.txt@2\n"
+ "PS2, Line 2: nten\n"
+ "typo: content\n"
+ "\n"
+ "\n");
assertThat(extractComments(messages.get(0).body()))
.isEqualTo(
"Patch Set 2:\n"
+ "\n"
+ "(6 comments)\n"
+ "\n"
+ "comments\n"
+ "\n"
+ url
+ "#/c/"
+ c
+ "/1/a.txt\n"
+ "File a.txt:\n"
+ "\n"
+ url
+ "#/c/"
+ c
+ "/1/a.txt@a2\n"
+ "PS1, Line 2: \n"
+ "what happened to this?\n"
+ "\n"
+ "\n"
+ url
+ "#/c/"
+ c
+ "/1/a.txt@1\n"
+ "PS1, Line 1: ew\n"
+ "nit: trailing whitespace\n"
+ "\n"
+ "\n"
+ url
+ "#/c/"
+ c
+ "/2/a.txt\n"
+ "File a.txt:\n"
+ "\n"
+ url
+ "#/c/"
+ c
+ "/2/a.txt@a1\n"
+ "PS2, Line 1: \n"
+ "comment 1 on base\n"
+ "\n"
+ "\n"
+ url
+ "#/c/"
+ c
+ "/2/a.txt@a2\n"
+ "PS2, Line 2: \n"
+ "comment 2 on base\n"
+ "\n"
+ "\n"
+ url
+ "#/c/"
+ c
+ "/2/a.txt@1\n"
+ "PS2, Line 1: ew\n"
+ "join lines\n"
+ "\n"
+ "\n"
+ url
+ "#/c/"
+ c
+ "/2/a.txt@2\n"
+ "PS2, Line 2: nten\n"
+ "typo: content\n"
+ "\n"
+ "\n");
}
@Test
@@ -664,8 +678,7 @@ public class CommentsIT extends AbstractDaemonTest {
rin.tag = "tag1";
gApi.changes().id(r.getChangeId()).current().review(rin);
List<CommentInfo> comments =
gApi.changes().id(r.getChangeId()).current().commentsAsList();
List<CommentInfo> comments = gApi.changes().id(r.getChangeId()).current().commentsAsList();
assertThat(comments).hasSize(1);
assertThat(comments.get(0).tag).isEqualTo("tag1");
@@ -676,8 +689,7 @@ public class CommentsIT extends AbstractDaemonTest {
draft.tag = "tag2";
addDraft(r.getChangeId(), r.getCommit().name(), draft);
List<CommentInfo> drafts =
gApi.changes().id(r.getChangeId()).current().draftsAsList();
List<CommentInfo> drafts = gApi.changes().id(r.getChangeId()).current().draftsAsList();
assertThat(drafts).hasSize(1);
assertThat(drafts.get(0).tag).isEqualTo("tag2");
}
@@ -696,88 +708,77 @@ public class CommentsIT extends AbstractDaemonTest {
return in;
}
private void addComment(PushOneCommit.Result r, String message)
throws Exception {
private void addComment(PushOneCommit.Result r, String message) throws Exception {
addComment(r, message, false);
}
private void addComment(PushOneCommit.Result r, String message,
boolean omitDuplicateComments) throws Exception {
private void addComment(PushOneCommit.Result r, String message, boolean omitDuplicateComments)
throws Exception {
CommentInput c = new CommentInput();
c.line = 1;
c.message = message;
c.path = FILE_NAME;
ReviewInput in = newInput(c);
in.omitDuplicateComments = omitDuplicateComments;
gApi.changes()
.id(r.getChangeId())
.revision(r.getCommit().name())
.review(in);
gApi.changes().id(r.getChangeId()).revision(r.getCommit().name()).review(in);
}
private CommentInfo addDraft(String changeId, String revId, DraftInput in)
throws Exception {
private CommentInfo addDraft(String changeId, String revId, DraftInput in) throws Exception {
return gApi.changes().id(changeId).revision(revId).createDraft(in).get();
}
private void updateDraft(String changeId, String revId, DraftInput in,
String uuid) throws Exception {
private void updateDraft(String changeId, String revId, DraftInput in, String uuid)
throws Exception {
gApi.changes().id(changeId).revision(revId).draft(uuid).update(in);
}
private void deleteDraft(String changeId, String revId, String uuid)
throws Exception {
private void deleteDraft(String changeId, String revId, String uuid) throws Exception {
gApi.changes().id(changeId).revision(revId).draft(uuid).delete();
}
private CommentInfo getPublishedComment(String changeId, String revId,
String uuid) throws Exception {
private CommentInfo getPublishedComment(String changeId, String revId, String uuid)
throws Exception {
return gApi.changes().id(changeId).revision(revId).comment(uuid).get();
}
private Map<String, List<CommentInfo>> getPublishedComments(String changeId,
String revId) throws Exception {
private Map<String, List<CommentInfo>> getPublishedComments(String changeId, String revId)
throws Exception {
return gApi.changes().id(changeId).revision(revId).comments();
}
private Map<String, List<CommentInfo>> getDraftComments(String changeId,
String revId) throws Exception {
private Map<String, List<CommentInfo>> getDraftComments(String changeId, String revId)
throws Exception {
return gApi.changes().id(changeId).revision(revId).drafts();
}
private CommentInfo getDraftComment(String changeId, String revId,
String uuid) throws Exception {
private CommentInfo getDraftComment(String changeId, String revId, String uuid) throws Exception {
return gApi.changes().id(changeId).revision(revId).draft(uuid).get();
}
private static CommentInput newComment(String path, Side side, int line,
String message, Boolean unresolved) {
private static CommentInput newComment(
String path, Side side, int line, String message, Boolean unresolved) {
CommentInput c = new CommentInput();
return populate(c, path, side, null, line, message, unresolved);
}
private static CommentInput newCommentOnParent(String path, int parent,
int line, String message) {
private static CommentInput newCommentOnParent(
String path, int parent, int line, String message) {
CommentInput c = new CommentInput();
return populate(c, path, Side.PARENT, Integer.valueOf(parent), line,
message, false);
return populate(c, path, Side.PARENT, Integer.valueOf(parent), line, message, false);
}
private DraftInput newDraft(String path, Side side, int line,
String message) {
private DraftInput newDraft(String path, Side side, int line, String message) {
DraftInput d = new DraftInput();
return populate(d, path, side, null, line, message, false);
}
private DraftInput newDraftOnParent(String path, int parent, int line,
String message) {
private DraftInput newDraftOnParent(String path, int parent, int line, String message) {
DraftInput d = new DraftInput();
return populate(d, path, Side.PARENT, Integer.valueOf(parent), line,
message, false);
return populate(d, path, Side.PARENT, Integer.valueOf(parent), line, message, false);
}
private static <C extends Comment> C populate(C c, String path, Side side,
Integer parent, int line, String message, Boolean unresolved) {
private static <C extends Comment> C populate(
C c, String path, Side side, Integer parent, int line, String message, Boolean unresolved) {
c.path = path;
c.side = side;
c.parent = parent;

View File

@@ -57,7 +57,10 @@ import com.google.gerrit.testutil.TestChanges;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.Provider;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.ObjectId;
@@ -68,40 +71,25 @@ import org.eclipse.jgit.transport.ReceiveCommand;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@NoHttpd
public class ConsistencyCheckerIT extends AbstractDaemonTest {
@Inject
private ChangeControl.GenericFactory changeControlFactory;
@Inject private ChangeControl.GenericFactory changeControlFactory;
@Inject
private Provider<ConsistencyChecker> checkerProvider;
@Inject private Provider<ConsistencyChecker> checkerProvider;
@Inject
private IdentifiedUser.GenericFactory userFactory;
@Inject private IdentifiedUser.GenericFactory userFactory;
@Inject
private BatchUpdate.Factory updateFactory;
@Inject private BatchUpdate.Factory updateFactory;
@Inject
private ChangeInserter.Factory changeInserterFactory;
@Inject private ChangeInserter.Factory changeInserterFactory;
@Inject
private PatchSetInserter.Factory patchSetInserterFactory;
@Inject private PatchSetInserter.Factory patchSetInserterFactory;
@Inject
private ChangeNoteUtil noteUtil;
@Inject private ChangeNoteUtil noteUtil;
@Inject
@AnonymousCowardName
private String anonymousCowardName;
@Inject @AnonymousCowardName private String anonymousCowardName;
@Inject
private Sequences sequences;
@Inject private Sequences sequences;
private RevCommit tip;
private Account.Id adminId;
@@ -110,10 +98,9 @@ public class ConsistencyCheckerIT extends AbstractDaemonTest {
@Before
public void setUp() throws Exception {
// Ignore client clone of project; repurpose as server-side TestRepository.
testRepo = new TestRepository<>(
(InMemoryRepository) repoManager.openRepository(project));
tip = testRepo.getRevWalk().parseCommit(
testRepo.getRepository().exactRef("HEAD").getObjectId());
testRepo = new TestRepository<>((InMemoryRepository) repoManager.openRepository(project));
tip =
testRepo.getRevWalk().parseCommit(testRepo.getRepository().exactRef("HEAD").getObjectId());
adminId = admin.getId();
checker = checkerProvider.get();
}
@@ -135,8 +122,7 @@ public class ConsistencyCheckerIT extends AbstractDaemonTest {
ChangeControl ctl = insertChange(owner);
db.accounts().deleteKeys(singleton(owner.getId()));
assertProblems(ctl, null,
problem("Missing change owner: " + owner.getId()));
assertProblems(ctl, null, problem("Missing change owner: " + owner.getId()));
}
@Test
@@ -148,9 +134,7 @@ public class ConsistencyCheckerIT extends AbstractDaemonTest {
Project.NameKey name = ctl.getProject().getNameKey();
((InMemoryRepositoryManager) repoManager).deleteRepository(name);
assertProblems(
ctl, null,
problem("Destination repository not found: " + name));
assertProblems(ctl, null, problem("Destination repository not found: " + name));
}
@Test
@@ -160,16 +144,17 @@ public class ConsistencyCheckerIT extends AbstractDaemonTest {
assume().that(notesMigration.enabled()).isFalse();
ChangeControl ctl = insertChange();
PatchSet ps = newPatchSet(
ctl.getChange().currentPatchSetId(),
"fooooooooooooooooooooooooooooooooooooooo",
adminId);
PatchSet ps =
newPatchSet(
ctl.getChange().currentPatchSetId(),
"fooooooooooooooooooooooooooooooooooooooo",
adminId);
db.patchSets().update(singleton(ps));
assertProblems(
ctl, null,
problem("Invalid revision on patch set 1:"
+ " fooooooooooooooooooooooooooooooooooooooo"));
ctl,
null,
problem("Invalid revision on patch set 1:" + " fooooooooooooooooooooooooooooooooooooooo"));
}
// No test for ref existing but object missing; InMemoryRepository won't let
@@ -182,11 +167,10 @@ public class ConsistencyCheckerIT extends AbstractDaemonTest {
PatchSet ps = insertMissingPatchSet(ctl, rev);
ctl = reload(ctl);
assertProblems(
ctl, null,
ctl,
null,
problem("Ref missing: " + ps.getId().toRefName()),
problem(
"Object missing: patch set 2:"
+ " deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"));
problem("Object missing: patch set 2:" + " deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"));
}
@Test
@@ -198,7 +182,8 @@ public class ConsistencyCheckerIT extends AbstractDaemonTest {
String refName = ps.getId().toRefName();
assertProblems(
ctl, new FixInput(),
ctl,
new FixInput(),
problem("Ref missing: " + refName),
problem("Object missing: patch set 2: " + rev));
}
@@ -208,8 +193,7 @@ public class ConsistencyCheckerIT extends AbstractDaemonTest {
ChangeControl ctl = insertChange();
testRepo.update(
"refs/other/foo",
ObjectId.fromString(
psUtil.current(db, ctl.getNotes()).getRevision().get()));
ObjectId.fromString(psUtil.current(db, ctl.getNotes()).getRevision().get()));
String refName = ctl.getChange().currentPatchSetId().toRefName();
deleteRef(refName);
@@ -225,15 +209,12 @@ public class ConsistencyCheckerIT extends AbstractDaemonTest {
deleteRef(refName);
assertProblems(
ctl, new FixInput(),
problem("Ref missing: " + refName, FIXED, "Repaired patch set ref"));
assertThat(testRepo.getRepository().exactRef(refName).getObjectId().name())
.isEqualTo(rev);
ctl, new FixInput(), problem("Ref missing: " + refName, FIXED, "Repaired patch set ref"));
assertThat(testRepo.getRepository().exactRef(refName).getObjectId().name()).isEqualTo(rev);
}
@Test
public void patchSetObjectAndRefMissingWithDeletingPatchSet()
throws Exception {
public void patchSetObjectAndRefMissingWithDeletingPatchSet() throws Exception {
ChangeControl ctl = insertChange();
PatchSet ps1 = psUtil.current(db, ctl.getNotes());
@@ -244,10 +225,10 @@ public class ConsistencyCheckerIT extends AbstractDaemonTest {
FixInput fix = new FixInput();
fix.deletePatchSetIfCommitMissing = true;
assertProblems(
ctl, fix,
ctl,
fix,
problem("Ref missing: " + ps2.getId().toRefName()),
problem("Object missing: patch set 2: " + rev2,
FIXED, "Deleted patch set"));
problem("Object missing: patch set 2: " + rev2, FIXED, "Deleted patch set"));
ctl = reload(ctl);
assertThat(ctl.getChange().currentPatchSetId().get()).isEqualTo(1);
@@ -256,8 +237,7 @@ public class ConsistencyCheckerIT extends AbstractDaemonTest {
}
@Test
public void patchSetMultipleObjectsMissingWithDeletingPatchSets()
throws Exception {
public void patchSetMultipleObjectsMissingWithDeletingPatchSets() throws Exception {
ChangeControl ctl = insertChange();
PatchSet ps1 = psUtil.current(db, ctl.getNotes());
@@ -274,13 +254,12 @@ public class ConsistencyCheckerIT extends AbstractDaemonTest {
FixInput fix = new FixInput();
fix.deletePatchSetIfCommitMissing = true;
assertProblems(
ctl, fix,
ctl,
fix,
problem("Ref missing: " + ps2.getId().toRefName()),
problem("Object missing: patch set 2: " + rev2,
FIXED, "Deleted patch set"),
problem("Object missing: patch set 2: " + rev2, FIXED, "Deleted patch set"),
problem("Ref missing: " + ps4.getId().toRefName()),
problem("Object missing: patch set 4: " + rev4,
FIXED, "Deleted patch set"));
problem("Object missing: patch set 4: " + rev4, FIXED, "Deleted patch set"));
ctl = reload(ctl);
assertThat(ctl.getChange().currentPatchSetId().get()).isEqualTo(3);
@@ -292,8 +271,7 @@ public class ConsistencyCheckerIT extends AbstractDaemonTest {
@Test
public void onlyPatchSetObjectMissingWithFix() throws Exception {
Change c = TestChanges.newChange(
project, admin.getId(), sequences.nextChangeId());
Change c = TestChanges.newChange(project, admin.getId(), sequences.nextChangeId());
PatchSet.Id psId = c.currentPatchSetId();
String rev = "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef";
PatchSet ps = newPatchSet(psId, rev, adminId);
@@ -307,23 +285,33 @@ public class ConsistencyCheckerIT extends AbstractDaemonTest {
"Create change\n"
+ "\n"
+ "Patch-set: 1\n"
+ "Branch: " + c.getDest().get() + "\n"
+ "Change-id: " + c.getKey().get() + "\n"
+ "Branch: "
+ c.getDest().get()
+ "\n"
+ "Change-id: "
+ c.getKey().get()
+ "\n"
+ "Subject: Bogus subject\n"
+ "Commit: " + rev + "\n"
+ "Groups: " + rev + "\n");
+ "Commit: "
+ rev
+ "\n"
+ "Groups: "
+ rev
+ "\n");
indexer.index(db, c.getProject(), c.getId());
IdentifiedUser user = userFactory.create(admin.getId());
ChangeControl ctl = changeControlFactory.controlFor(
db, c.getProject(), c.getId(), user);
ChangeControl ctl = changeControlFactory.controlFor(db, c.getProject(), c.getId(), user);
FixInput fix = new FixInput();
fix.deletePatchSetIfCommitMissing = true;
assertProblems(
ctl, fix,
ctl,
fix,
problem("Ref missing: " + ps.getId().toRefName()),
problem("Object missing: patch set 1: " + rev,
FIX_FAILED, "Cannot delete patch set; no patch sets would remain"));
problem(
"Object missing: patch set 1: " + rev,
FIX_FAILED,
"Cannot delete patch set; no patch sets would remain"));
ctl = reload(ctl);
assertThat(ctl.getChange().currentPatchSetId().get()).isEqualTo(1);
@@ -346,12 +334,9 @@ public class ConsistencyCheckerIT extends AbstractDaemonTest {
PatchSet ps1 = psUtil.current(db, ctl.getNotes());
String rev = ps1.getRevision().get();
ctl = incrementPatchSet(
ctl, testRepo.getRevWalk().parseCommit(ObjectId.fromString(rev)));
ctl = incrementPatchSet(ctl, testRepo.getRevWalk().parseCommit(ObjectId.fromString(rev)));
assertProblems(
ctl, null,
problem("Multiple patch sets pointing to " + rev + ": [1, 2]"));
assertProblems(ctl, null, problem("Multiple patch sets pointing to " + rev + ": [1, 2]"));
}
@Test
@@ -365,9 +350,7 @@ public class ConsistencyCheckerIT extends AbstractDaemonTest {
ru.setForceUpdate(true);
assertThat(ru.delete()).isEqualTo(RefUpdate.Result.FORCED);
assertProblems(
ctl, null,
problem("Destination ref not found (may be new branch): " + ref));
assertProblems(ctl, null, problem("Destination ref not found (may be new branch): " + ref));
}
@Test
@@ -375,15 +358,16 @@ public class ConsistencyCheckerIT extends AbstractDaemonTest {
ChangeControl ctl = insertChange();
try (BatchUpdate bu = newUpdate(adminId)) {
bu.addOp(ctl.getId(), new BatchUpdate.Op() {
@Override
public boolean updateChange(ChangeContext ctx) throws OrmException {
ctx.getChange().setStatus(Change.Status.MERGED);
ctx.getUpdate(ctx.getChange().currentPatchSetId())
.fixStatus(Change.Status.MERGED);
return true;
}
});
bu.addOp(
ctl.getId(),
new BatchUpdate.Op() {
@Override
public boolean updateChange(ChangeContext ctx) throws OrmException {
ctx.getChange().setStatus(Change.Status.MERGED);
ctx.getUpdate(ctx.getChange().currentPatchSetId()).fixStatus(Change.Status.MERGED);
return true;
}
});
bu.execute();
}
ctl = reload(ctl);
@@ -391,10 +375,14 @@ public class ConsistencyCheckerIT extends AbstractDaemonTest {
String rev = psUtil.current(db, ctl.getNotes()).getRevision().get();
ObjectId tip = getDestRef(ctl);
assertProblems(
ctl, null,
ctl,
null,
problem(
"Patch set 1 (" + rev + ") is not merged into destination ref"
+ " refs/heads/master (" + tip.name()
"Patch set 1 ("
+ rev
+ ") is not merged into destination ref"
+ " refs/heads/master ("
+ tip.name()
+ "), but change status is MERGED"));
}
@@ -402,14 +390,19 @@ public class ConsistencyCheckerIT extends AbstractDaemonTest {
public void newChangeIsMerged() throws Exception {
ChangeControl ctl = insertChange();
String rev = psUtil.current(db, ctl.getNotes()).getRevision().get();
testRepo.branch(ctl.getChange().getDest().get())
testRepo
.branch(ctl.getChange().getDest().get())
.update(testRepo.getRevWalk().parseCommit(ObjectId.fromString(rev)));
assertProblems(
ctl, null,
ctl,
null,
problem(
"Patch set 1 (" + rev + ") is merged into destination ref"
+ " refs/heads/master (" + rev
"Patch set 1 ("
+ rev
+ ") is merged into destination ref"
+ " refs/heads/master ("
+ rev
+ "), but change status is NEW"));
}
@@ -417,16 +410,22 @@ public class ConsistencyCheckerIT extends AbstractDaemonTest {
public void newChangeIsMergedWithFix() throws Exception {
ChangeControl ctl = insertChange();
String rev = psUtil.current(db, ctl.getNotes()).getRevision().get();
testRepo.branch(ctl.getChange().getDest().get())
testRepo
.branch(ctl.getChange().getDest().get())
.update(testRepo.getRevWalk().parseCommit(ObjectId.fromString(rev)));
assertProblems(
ctl, new FixInput(),
ctl,
new FixInput(),
problem(
"Patch set 1 (" + rev + ") is merged into destination ref"
+ " refs/heads/master (" + rev
"Patch set 1 ("
+ rev
+ ") is merged into destination ref"
+ " refs/heads/master ("
+ rev
+ "), but change status is NEW",
FIXED, "Marked change as merged"));
FIXED,
"Marked change as merged"));
ctl = reload(ctl);
assertThat(ctl.getChange().getStatus()).isEqualTo(Change.Status.MERGED);
@@ -437,17 +436,14 @@ public class ConsistencyCheckerIT extends AbstractDaemonTest {
public void extensionApiReturnsUpdatedValueAfterFix() throws Exception {
ChangeControl ctl = insertChange();
String rev = psUtil.current(db, ctl.getNotes()).getRevision().get();
testRepo.branch(ctl.getChange().getDest().get())
testRepo
.branch(ctl.getChange().getDest().get())
.update(testRepo.getRevWalk().parseCommit(ObjectId.fromString(rev)));
ChangeInfo info = gApi.changes()
.id(ctl.getId().get())
.info();
ChangeInfo info = gApi.changes().id(ctl.getId().get()).info();
assertThat(info.status).isEqualTo(ChangeStatus.NEW);
info = gApi.changes()
.id(ctl.getId().get())
.check(new FixInput());
info = gApi.changes().id(ctl.getId().get()).check(new FixInput());
assertThat(info.status).isEqualTo(ChangeStatus.MERGED);
}
@@ -455,17 +451,24 @@ public class ConsistencyCheckerIT extends AbstractDaemonTest {
public void expectedMergedCommitIsLatestPatchSet() throws Exception {
ChangeControl ctl = insertChange();
String rev = psUtil.current(db, ctl.getNotes()).getRevision().get();
testRepo.branch(ctl.getChange().getDest().get())
testRepo
.branch(ctl.getChange().getDest().get())
.update(testRepo.getRevWalk().parseCommit(ObjectId.fromString(rev)));
FixInput fix = new FixInput();
fix.expectMergedAs = rev;
assertProblems(
ctl, fix,
ctl,
fix,
problem(
"Patch set 1 (" + rev + ") is merged into destination ref"
+ " refs/heads/master (" + rev + "), but change status is NEW",
FIXED, "Marked change as merged"));
"Patch set 1 ("
+ rev
+ ") is merged into destination ref"
+ " refs/heads/master ("
+ rev
+ "), but change status is NEW",
FIXED,
"Marked change as merged"));
ctl = reload(ctl);
assertThat(ctl.getChange().getStatus()).isEqualTo(Change.Status.MERGED);
@@ -476,33 +479,33 @@ public class ConsistencyCheckerIT extends AbstractDaemonTest {
public void expectedMergedCommitNotMergedIntoDestination() throws Exception {
ChangeControl ctl = insertChange();
String rev = psUtil.current(db, ctl.getNotes()).getRevision().get();
RevCommit commit =
testRepo.getRevWalk().parseCommit(ObjectId.fromString(rev));
RevCommit commit = testRepo.getRevWalk().parseCommit(ObjectId.fromString(rev));
testRepo.branch(ctl.getChange().getDest().get()).update(commit);
FixInput fix = new FixInput();
RevCommit other =
testRepo.commit().message(commit.getFullMessage()).create();
RevCommit other = testRepo.commit().message(commit.getFullMessage()).create();
fix.expectMergedAs = other.name();
assertProblems(
ctl, fix,
ctl,
fix,
problem(
"Expected merged commit " + other.name()
"Expected merged commit "
+ other.name()
+ " is not merged into destination ref refs/heads/master"
+ " (" + commit.name() + ")"));
+ " ("
+ commit.name()
+ ")"));
}
@Test
public void createNewPatchSetForExpectedMergeCommitWithNoChangeId()
throws Exception {
public void createNewPatchSetForExpectedMergeCommitWithNoChangeId() throws Exception {
ChangeControl ctl = insertChange();
String dest = ctl.getChange().getDest().get();
String rev = psUtil.current(db, ctl.getNotes()).getRevision().get();
RevCommit commit =
testRepo.getRevWalk().parseCommit(ObjectId.fromString(rev));
RevCommit commit = testRepo.getRevWalk().parseCommit(ObjectId.fromString(rev));
RevCommit mergedAs = testRepo.commit().parent(commit.getParent(0))
.message(commit.getShortMessage()).create();
RevCommit mergedAs =
testRepo.commit().parent(commit.getParent(0)).message(commit.getShortMessage()).create();
testRepo.getRevWalk().parseBody(mergedAs);
assertThat(mergedAs.getFooterLines(FooterConstants.CHANGE_ID)).isEmpty();
testRepo.update(dest, mergedAs);
@@ -512,14 +515,16 @@ public class ConsistencyCheckerIT extends AbstractDaemonTest {
FixInput fix = new FixInput();
fix.expectMergedAs = mergedAs.name();
assertProblems(
ctl, fix,
ctl,
fix,
problem(
"No patch set found for merged commit " + mergedAs.name(),
FIXED, "Marked change as merged"),
FIXED,
"Marked change as merged"),
problem(
"Expected merged commit " + mergedAs.name()
+ " has no associated patch set",
FIXED, "Inserted as patch set 2"));
"Expected merged commit " + mergedAs.name() + " has no associated patch set",
FIXED,
"Inserted as patch set 2"));
ctl = reload(ctl);
PatchSet.Id psId2 = new PatchSet.Id(ctl.getId(), 2);
@@ -531,18 +536,24 @@ public class ConsistencyCheckerIT extends AbstractDaemonTest {
}
@Test
public void createNewPatchSetForExpectedMergeCommitWithChangeId()
throws Exception {
public void createNewPatchSetForExpectedMergeCommitWithChangeId() throws Exception {
ChangeControl ctl = insertChange();
String dest = ctl.getChange().getDest().get();
String rev = psUtil.current(db, ctl.getNotes()).getRevision().get();
RevCommit commit =
testRepo.getRevWalk().parseCommit(ObjectId.fromString(rev));
RevCommit commit = testRepo.getRevWalk().parseCommit(ObjectId.fromString(rev));
RevCommit mergedAs = testRepo.commit().parent(commit.getParent(0))
.message(commit.getShortMessage() + "\n"
+ "\n"
+ "Change-Id: " + ctl.getChange().getKey().get() + "\n").create();
RevCommit mergedAs =
testRepo
.commit()
.parent(commit.getParent(0))
.message(
commit.getShortMessage()
+ "\n"
+ "\n"
+ "Change-Id: "
+ ctl.getChange().getKey().get()
+ "\n")
.create();
testRepo.getRevWalk().parseBody(mergedAs);
assertThat(mergedAs.getFooterLines(FooterConstants.CHANGE_ID))
.containsExactly(ctl.getChange().getKey().get());
@@ -553,14 +564,16 @@ public class ConsistencyCheckerIT extends AbstractDaemonTest {
FixInput fix = new FixInput();
fix.expectMergedAs = mergedAs.name();
assertProblems(
ctl, fix,
ctl,
fix,
problem(
"No patch set found for merged commit " + mergedAs.name(),
FIXED, "Marked change as merged"),
FIXED,
"Marked change as merged"),
problem(
"Expected merged commit " + mergedAs.name()
+ " has no associated patch set",
FIXED, "Inserted as patch set 2"));
"Expected merged commit " + mergedAs.name() + " has no associated patch set",
FIXED,
"Inserted as patch set 2"));
ctl = reload(ctl);
PatchSet.Id psId2 = new PatchSet.Id(ctl.getId(), 2);
@@ -572,31 +585,36 @@ public class ConsistencyCheckerIT extends AbstractDaemonTest {
}
@Test
public void expectedMergedCommitIsOldPatchSetOfSameChange()
throws Exception {
public void expectedMergedCommitIsOldPatchSetOfSameChange() throws Exception {
ChangeControl ctl = insertChange();
PatchSet ps1 = psUtil.current(db, ctl.getNotes());
String rev1 = ps1.getRevision().get();
ctl = incrementPatchSet(ctl);
PatchSet ps2 = psUtil.current(db, ctl.getNotes());
testRepo.branch(ctl.getChange().getDest().get())
testRepo
.branch(ctl.getChange().getDest().get())
.update(testRepo.getRevWalk().parseCommit(ObjectId.fromString(rev1)));
FixInput fix = new FixInput();
fix.expectMergedAs = rev1;
assertProblems(
ctl, fix,
ctl,
fix,
problem("No patch set found for merged commit " + rev1, FIXED, "Marked change as merged"),
problem(
"No patch set found for merged commit " + rev1,
FIXED, "Marked change as merged"),
problem(
"Expected merge commit " + rev1 + " corresponds to patch set 1,"
"Expected merge commit "
+ rev1
+ " corresponds to patch set 1,"
+ " not the current patch set 2",
FIXED, "Deleted patch set"),
FIXED,
"Deleted patch set"),
problem(
"Expected merge commit " + rev1 + " corresponds to patch set 1,"
"Expected merge commit "
+ rev1
+ " corresponds to patch set 1,"
+ " not the current patch set 2",
FIXED, "Inserted as patch set 3"));
FIXED,
"Inserted as patch set 3"));
ctl = reload(ctl);
PatchSet.Id psId3 = new PatchSet.Id(ctl.getId(), 3);
@@ -604,13 +622,11 @@ public class ConsistencyCheckerIT extends AbstractDaemonTest {
assertThat(ctl.getChange().getStatus()).isEqualTo(Change.Status.MERGED);
assertThat(psUtil.byChangeAsMap(db, ctl.getNotes()).keySet())
.containsExactly(ps2.getId(), psId3);
assertThat(psUtil.get(db, ctl.getNotes(), psId3).getRevision().get())
.isEqualTo(rev1);
assertThat(psUtil.get(db, ctl.getNotes(), psId3).getRevision().get()).isEqualTo(rev1);
}
@Test
public void expectedMergedCommitIsDanglingPatchSetOlderThanCurrent()
throws Exception {
public void expectedMergedCommitIsDanglingPatchSetOlderThanCurrent() throws Exception {
ChangeControl ctl = insertChange();
PatchSet ps1 = psUtil.current(db, ctl.getNotes());
@@ -624,24 +640,30 @@ public class ConsistencyCheckerIT extends AbstractDaemonTest {
PatchSet ps3 = psUtil.current(db, ctl.getNotes());
assertThat(ps3.getId().get()).isEqualTo(3);
testRepo.branch(ctl.getChange().getDest().get())
testRepo
.branch(ctl.getChange().getDest().get())
.update(testRepo.getRevWalk().parseCommit(ObjectId.fromString(rev2)));
FixInput fix = new FixInput();
fix.expectMergedAs = rev2;
assertProblems(
ctl, fix,
ctl,
fix,
problem("No patch set found for merged commit " + rev2, FIXED, "Marked change as merged"),
problem(
"No patch set found for merged commit " + rev2,
FIXED, "Marked change as merged"),
problem(
"Expected merge commit " + rev2 + " corresponds to patch set 2,"
"Expected merge commit "
+ rev2
+ " corresponds to patch set 2,"
+ " not the current patch set 3",
FIXED, "Deleted patch set"),
FIXED,
"Deleted patch set"),
problem(
"Expected merge commit " + rev2 + " corresponds to patch set 2,"
"Expected merge commit "
+ rev2
+ " corresponds to patch set 2,"
+ " not the current patch set 3",
FIXED, "Inserted as patch set 4"));
FIXED,
"Inserted as patch set 4"));
ctl = reload(ctl);
PatchSet.Id psId4 = new PatchSet.Id(ctl.getId(), 4);
@@ -649,13 +671,11 @@ public class ConsistencyCheckerIT extends AbstractDaemonTest {
assertThat(ctl.getChange().getStatus()).isEqualTo(Change.Status.MERGED);
assertThat(psUtil.byChangeAsMap(db, ctl.getNotes()).keySet())
.containsExactly(ps1.getId(), ps3.getId(), psId4);
assertThat(psUtil.get(db, ctl.getNotes(), psId4).getRevision().get())
.isEqualTo(rev2);
assertThat(psUtil.get(db, ctl.getNotes(), psId4).getRevision().get()).isEqualTo(rev2);
}
@Test
public void expectedMergedCommitIsDanglingPatchSetNewerThanCurrent()
throws Exception {
public void expectedMergedCommitIsDanglingPatchSetNewerThanCurrent() throws Exception {
ChangeControl ctl = insertChange();
PatchSet ps1 = psUtil.current(db, ctl.getNotes());
@@ -665,50 +685,50 @@ public class ConsistencyCheckerIT extends AbstractDaemonTest {
String rev2 = commit2.name();
testRepo.branch(psId2.toRefName()).update(commit2);
testRepo.branch(ctl.getChange().getDest().get())
testRepo
.branch(ctl.getChange().getDest().get())
.update(testRepo.getRevWalk().parseCommit(ObjectId.fromString(rev2)));
FixInput fix = new FixInput();
fix.expectMergedAs = rev2;
assertProblems(
ctl, fix,
ctl,
fix,
problem("No patch set found for merged commit " + rev2, FIXED, "Marked change as merged"),
problem(
"No patch set found for merged commit " + rev2,
FIXED, "Marked change as merged"),
problem(
"Expected merge commit " + rev2 + " corresponds to patch set 2,"
"Expected merge commit "
+ rev2
+ " corresponds to patch set 2,"
+ " not the current patch set 1",
FIXED, "Inserted as patch set 2"));
FIXED,
"Inserted as patch set 2"));
ctl = reload(ctl);
assertThat(ctl.getChange().currentPatchSetId()).isEqualTo(psId2);
assertThat(ctl.getChange().getStatus()).isEqualTo(Change.Status.MERGED);
assertThat(psUtil.byChangeAsMap(db, ctl.getNotes()).keySet())
.containsExactly(ps1.getId(), psId2);
assertThat(psUtil.get(db, ctl.getNotes(), psId2).getRevision().get())
.isEqualTo(rev2);
assertThat(psUtil.get(db, ctl.getNotes(), psId2).getRevision().get()).isEqualTo(rev2);
}
@Test
public void expectedMergedCommitWithMismatchedChangeId() throws Exception {
ChangeControl ctl = insertChange();
String dest = ctl.getChange().getDest().get();
RevCommit parent =
testRepo.branch(dest).commit().message("parent").create();
RevCommit parent = testRepo.branch(dest).commit().message("parent").create();
String rev = psUtil.current(db, ctl.getNotes()).getRevision().get();
RevCommit commit =
testRepo.getRevWalk().parseCommit(ObjectId.fromString(rev));
RevCommit commit = testRepo.getRevWalk().parseCommit(ObjectId.fromString(rev));
testRepo.branch(dest).update(commit);
String badId = "I0000000000000000000000000000000000000000";
RevCommit mergedAs = testRepo.commit().parent(parent)
.message(commit.getShortMessage() + "\n"
+ "\n"
+ "Change-Id: " + badId + "\n")
.create();
RevCommit mergedAs =
testRepo
.commit()
.parent(parent)
.message(commit.getShortMessage() + "\n" + "\n" + "Change-Id: " + badId + "\n")
.create();
testRepo.getRevWalk().parseBody(mergedAs);
assertThat(mergedAs.getFooterLines(FooterConstants.CHANGE_ID))
.containsExactly(badId);
assertThat(mergedAs.getFooterLines(FooterConstants.CHANGE_ID)).containsExactly(badId);
testRepo.update(dest, mergedAs);
assertNoProblems(ctl, null);
@@ -716,21 +736,24 @@ public class ConsistencyCheckerIT extends AbstractDaemonTest {
FixInput fix = new FixInput();
fix.expectMergedAs = mergedAs.name();
assertProblems(
ctl, fix,
ctl,
fix,
problem(
"Expected merged commit " + mergedAs.name() + " has Change-Id: "
+ badId + ", but expected " + ctl.getChange().getKey().get()));
"Expected merged commit "
+ mergedAs.name()
+ " has Change-Id: "
+ badId
+ ", but expected "
+ ctl.getChange().getKey().get()));
}
@Test
public void expectedMergedCommitMatchesMultiplePatchSets()
throws Exception {
public void expectedMergedCommitMatchesMultiplePatchSets() throws Exception {
ChangeControl ctl1 = insertChange();
PatchSet.Id psId1 = psUtil.current(db, ctl1.getNotes()).getId();
String dest = ctl1.getChange().getDest().get();
String rev = psUtil.current(db, ctl1.getNotes()).getRevision().get();
RevCommit commit =
testRepo.getRevWalk().parseCommit(ObjectId.fromString(rev));
RevCommit commit = testRepo.getRevWalk().parseCommit(ObjectId.fromString(rev));
testRepo.branch(dest).update(commit);
ChangeControl ctl2 = insertChange();
@@ -744,62 +767,67 @@ public class ConsistencyCheckerIT extends AbstractDaemonTest {
FixInput fix = new FixInput();
fix.expectMergedAs = commit.name();
assertProblems(
ctl1, fix,
ctl1,
fix,
problem(
"Multiple patch sets for expected merged commit " + commit.name()
+ ": [" + psId1 + ", " + psId2 + ", " + psId3 + "]"));
"Multiple patch sets for expected merged commit "
+ commit.name()
+ ": ["
+ psId1
+ ", "
+ psId2
+ ", "
+ psId3
+ "]"));
}
private BatchUpdate newUpdate(Account.Id owner) {
return updateFactory.create(
db, project, userFactory.create(owner), TimeUtil.nowTs());
return updateFactory.create(db, project, userFactory.create(owner), TimeUtil.nowTs());
}
private ChangeControl insertChange() throws Exception {
return insertChange(admin);
}
private ChangeControl insertChange(TestAccount owner) throws Exception {
return insertChange(owner, "refs/heads/master");
}
private ChangeControl insertChange(TestAccount owner, String dest)
throws Exception {
private ChangeControl insertChange(TestAccount owner, String dest) throws Exception {
Change.Id id = new Change.Id(sequences.nextChangeId());
ChangeInserter ins;
try (BatchUpdate bu = newUpdate(owner.getId())) {
RevCommit commit = patchSetCommit(new PatchSet.Id(id, 1));
ins = changeInserterFactory
.create(id, commit, dest)
.setValidatePolicy(CommitValidators.Policy.NONE)
.setNotify(NotifyHandling.NONE)
.setFireRevisionCreated(false)
.setSendMail(false);
ins =
changeInserterFactory
.create(id, commit, dest)
.setValidatePolicy(CommitValidators.Policy.NONE)
.setNotify(NotifyHandling.NONE)
.setFireRevisionCreated(false)
.setSendMail(false);
bu.insertChange(ins).execute();
}
// Return control for admin regardless of owner.
return changeControlFactory.controlFor(
db, ins.getChange(), userFactory.create(adminId));
return changeControlFactory.controlFor(db, ins.getChange(), userFactory.create(adminId));
}
private PatchSet.Id nextPatchSetId(ChangeControl ctl) throws Exception {
return ChangeUtil.nextPatchSetId(
testRepo.getRepository(), ctl.getChange().currentPatchSetId());
return ChangeUtil.nextPatchSetId(testRepo.getRepository(), ctl.getChange().currentPatchSetId());
}
private ChangeControl incrementPatchSet(ChangeControl ctl) throws Exception {
return incrementPatchSet(ctl, patchSetCommit(nextPatchSetId(ctl)));
}
private ChangeControl incrementPatchSet(ChangeControl ctl,
RevCommit commit) throws Exception {
private ChangeControl incrementPatchSet(ChangeControl ctl, RevCommit commit) throws Exception {
PatchSetInserter ins;
try (BatchUpdate bu = newUpdate(ctl.getChange().getOwner())) {
ins = patchSetInserterFactory.create(ctl, nextPatchSetId(ctl), commit)
.setValidatePolicy(CommitValidators.Policy.NONE)
.setFireRevisionCreated(false)
.setNotify(NotifyHandling.NONE);
ins =
patchSetInserterFactory
.create(ctl, nextPatchSetId(ctl), commit)
.setValidatePolicy(CommitValidators.Policy.NONE)
.setFireRevisionCreated(false)
.setNotify(NotifyHandling.NONE);
bu.addOp(ctl.getId(), ins).execute();
}
return reload(ctl);
@@ -811,16 +839,11 @@ public class ConsistencyCheckerIT extends AbstractDaemonTest {
}
private RevCommit patchSetCommit(PatchSet.Id psId) throws Exception {
RevCommit c = testRepo
.commit()
.parent(tip)
.message("Change " + psId)
.create();
RevCommit c = testRepo.commit().parent(tip).message("Change " + psId).create();
return testRepo.parseBody(c);
}
private PatchSet insertMissingPatchSet(ChangeControl ctl, String rev)
throws Exception {
private PatchSet insertMissingPatchSet(ChangeControl ctl, String rev) throws Exception {
// Don't use BatchUpdate since we're manually updating the meta ref rather
// than using ChangeUpdate.
String subject = "Subject for missing commit";
@@ -836,11 +859,19 @@ public class ConsistencyCheckerIT extends AbstractDaemonTest {
addNoteDbCommit(
c.getId(),
"Update patch set " + psId.get() + "\n"
"Update patch set "
+ psId.get()
+ "\n"
+ "Patch-set: " + psId.get() + "\n"
+ "Commit: " + rev + "\n"
+ "Subject: " + subject + "\n");
+ "\n"
+ "Patch-set: "
+ psId.get()
+ "\n"
+ "Commit: "
+ rev
+ "\n"
+ "Subject: "
+ subject
+ "\n");
indexer.index(db, c.getProject(), c.getId());
return ps;
@@ -852,18 +883,19 @@ public class ConsistencyCheckerIT extends AbstractDaemonTest {
assertThat(ru.delete()).isEqualTo(RefUpdate.Result.FORCED);
}
private void addNoteDbCommit(Change.Id id, String commitMessage)
throws Exception {
private void addNoteDbCommit(Change.Id id, String commitMessage) throws Exception {
if (!notesMigration.commitChangeWrites()) {
return;
}
PersonIdent committer = serverIdent.get();
PersonIdent author = noteUtil.newIdent(
accountCache.get(admin.getId()).getAccount(),
committer.getWhen(),
committer,
anonymousCowardName);
testRepo.branch(RefNames.changeMetaRef(id))
PersonIdent author =
noteUtil.newIdent(
accountCache.get(admin.getId()).getAccount(),
committer.getWhen(),
committer,
anonymousCowardName);
testRepo
.branch(RefNames.changeMetaRef(id))
.commit()
.author(author)
.committer(committer)
@@ -872,32 +904,31 @@ public class ConsistencyCheckerIT extends AbstractDaemonTest {
}
private ObjectId getDestRef(ChangeControl ctl) throws Exception {
return testRepo.getRepository()
.exactRef(ctl.getChange().getDest().get())
.getObjectId();
return testRepo.getRepository().exactRef(ctl.getChange().getDest().get()).getObjectId();
}
private ChangeControl mergeChange(ChangeControl ctl) throws Exception {
final ObjectId oldId = getDestRef(ctl);
final ObjectId newId = ObjectId.fromString(
psUtil.current(db, ctl.getNotes()).getRevision().get());
final ObjectId newId =
ObjectId.fromString(psUtil.current(db, ctl.getNotes()).getRevision().get());
final String dest = ctl.getChange().getDest().get();
try (BatchUpdate bu = newUpdate(adminId)) {
bu.addOp(ctl.getId(), new BatchUpdate.Op() {
@Override
public void updateRepo(RepoContext ctx) throws IOException {
ctx.addRefUpdate(new ReceiveCommand(oldId, newId, dest));
}
bu.addOp(
ctl.getId(),
new BatchUpdate.Op() {
@Override
public void updateRepo(RepoContext ctx) throws IOException {
ctx.addRefUpdate(new ReceiveCommand(oldId, newId, dest));
}
@Override
public boolean updateChange(ChangeContext ctx) throws OrmException {
ctx.getChange().setStatus(Change.Status.MERGED);
ctx.getUpdate(ctx.getChange().currentPatchSetId())
.fixStatus(Change.Status.MERGED);
return true;
}
});
@Override
public boolean updateChange(ChangeContext ctx) throws OrmException {
ctx.getChange().setStatus(Change.Status.MERGED);
ctx.getUpdate(ctx.getChange().currentPatchSetId()).fixStatus(Change.Status.MERGED);
return true;
}
});
bu.execute();
}
return reload(ctl);
@@ -909,22 +940,19 @@ public class ConsistencyCheckerIT extends AbstractDaemonTest {
return p;
}
private static ProblemInfo problem(String message,
ProblemInfo.Status status, String outcome) {
private static ProblemInfo problem(String message, ProblemInfo.Status status, String outcome) {
ProblemInfo p = problem(message);
p.status = checkNotNull(status);
p.outcome = checkNotNull(outcome);
return p;
}
private void assertProblems(ChangeControl ctl, @Nullable FixInput fix,
ProblemInfo first, ProblemInfo... rest) {
private void assertProblems(
ChangeControl ctl, @Nullable FixInput fix, ProblemInfo first, ProblemInfo... rest) {
List<ProblemInfo> expected = new ArrayList<>(1 + rest.length);
expected.add(first);
expected.addAll(Arrays.asList(rest));
assertThat(checker.check(ctl, fix).problems())
.containsExactlyElementsIn(expected)
.inOrder();
assertThat(checker.check(ctl, fix).problems()).containsExactlyElementsIn(expected).inOrder();
}
private void assertNoProblems(ChangeControl ctl, @Nullable FixInput fix) {

View File

@@ -40,16 +40,14 @@ import com.google.gerrit.server.query.change.ChangeData;
import com.google.gerrit.testutil.TestTimeUtil;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import java.util.List;
import java.util.Optional;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.revwalk.RevCommit;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.util.List;
import java.util.Optional;
public class GetRelatedIT extends AbstractDaemonTest {
private String systemTimeZone;
@@ -65,11 +63,9 @@ public class GetRelatedIT extends AbstractDaemonTest {
System.setProperty("user.timezone", systemTimeZone);
}
@Inject
private BatchUpdate.Factory updateFactory;
@Inject private BatchUpdate.Factory updateFactory;
@Inject
private ChangesCollection changes;
@Inject private ChangesCollection changes;
@Test
public void getRelatedNoResult() throws Exception {
@@ -80,36 +76,22 @@ public class GetRelatedIT extends AbstractDaemonTest {
@Test
public void getRelatedLinear() throws Exception {
// 1,1---2,1
RevCommit c1_1 = commitBuilder()
.add("a.txt", "1")
.message("subject: 1")
.create();
RevCommit c2_1 = commitBuilder()
.add("b.txt", "2")
.message("subject: 2")
.create();
RevCommit c1_1 = commitBuilder().add("a.txt", "1").message("subject: 1").create();
RevCommit c2_1 = commitBuilder().add("b.txt", "2").message("subject: 2").create();
pushHead(testRepo, "refs/for/master", false);
PatchSet.Id ps1_1 = getPatchSetId(c1_1);
PatchSet.Id ps2_1 = getPatchSetId(c2_1);
for (PatchSet.Id ps : ImmutableList.of(ps2_1, ps1_1)) {
assertRelated(ps,
changeAndCommit(ps2_1, c2_1, 1),
changeAndCommit(ps1_1, c1_1, 1));
assertRelated(ps, changeAndCommit(ps2_1, c2_1, 1), changeAndCommit(ps1_1, c1_1, 1));
}
}
@Test
public void getRelatedLinearSeparatePushes() throws Exception {
// 1,1---2,1
RevCommit c1_1 = commitBuilder()
.add("a.txt", "1")
.message("subject: 1")
.create();
RevCommit c2_1 = commitBuilder()
.add("b.txt", "2")
.message("subject: 2")
.create();
RevCommit c1_1 = commitBuilder().add("a.txt", "1").message("subject: 1").create();
RevCommit c2_1 = commitBuilder().add("b.txt", "2").message("subject: 2").create();
testRepo.reset(c1_1);
pushHead(testRepo, "refs/for/master", false);
@@ -121,13 +103,10 @@ public class GetRelatedIT extends AbstractDaemonTest {
PatchSet.Id ps2_1 = getPatchSetId(c2_1);
// Push of change 2 should not affect groups (or anything else) of change 1.
assertThat(changes.parse(ps1_1.getParentKey()).getETag())
.isEqualTo(oldETag);
assertThat(changes.parse(ps1_1.getParentKey()).getETag()).isEqualTo(oldETag);
for (PatchSet.Id ps : ImmutableList.of(ps2_1, ps1_1)) {
assertRelated(ps,
changeAndCommit(ps2_1, c2_1, 1),
changeAndCommit(ps1_1, c1_1, 1));
assertRelated(ps, changeAndCommit(ps2_1, c2_1, 1), changeAndCommit(ps1_1, c1_1, 1));
}
}
@@ -138,14 +117,8 @@ public class GetRelatedIT extends AbstractDaemonTest {
// 2,2---1,2
// Create two commits and push.
RevCommit c1_1 = commitBuilder()
.add("a.txt", "1")
.message("subject: 1")
.create();
RevCommit c2_1 = commitBuilder()
.add("b.txt", "2")
.message("subject: 2")
.create();
RevCommit c1_1 = commitBuilder().add("a.txt", "1").message("subject: 1").create();
RevCommit c2_1 = commitBuilder().add("b.txt", "2").message("subject: 2").create();
pushHead(testRepo, "refs/for/master", false);
PatchSet.Id ps1_1 = getPatchSetId(c1_1);
PatchSet.Id ps2_1 = getPatchSetId(c2_1);
@@ -159,15 +132,11 @@ public class GetRelatedIT extends AbstractDaemonTest {
PatchSet.Id ps2_2 = getPatchSetId(c2_1);
for (PatchSet.Id ps : ImmutableList.of(ps2_2, ps1_2)) {
assertRelated(ps,
changeAndCommit(ps1_2, c1_2, 2),
changeAndCommit(ps2_2, c2_2, 2));
assertRelated(ps, changeAndCommit(ps1_2, c1_2, 2), changeAndCommit(ps2_2, c2_2, 2));
}
for (PatchSet.Id ps : ImmutableList.of(ps2_1, ps1_1)) {
assertRelated(ps,
changeAndCommit(ps2_1, c2_1, 2),
changeAndCommit(ps1_1, c1_1, 2));
assertRelated(ps, changeAndCommit(ps2_1, c2_1, 2), changeAndCommit(ps1_1, c1_1, 2));
}
}
@@ -178,35 +147,23 @@ public class GetRelatedIT extends AbstractDaemonTest {
// 1,2
// Create two commits and push.
RevCommit c1_1 = commitBuilder()
.add("a.txt", "1")
.message("subject: 1")
.create();
RevCommit c2_1 = commitBuilder()
.add("b.txt", "2")
.message("subject: 2")
.create();
RevCommit c1_1 = commitBuilder().add("a.txt", "1").message("subject: 1").create();
RevCommit c2_1 = commitBuilder().add("b.txt", "2").message("subject: 2").create();
pushHead(testRepo, "refs/for/master", false);
PatchSet.Id ps1_1 = getPatchSetId(c1_1);
PatchSet.Id ps2_1 = getPatchSetId(c2_1);
// Amend parent change and push.
testRepo.reset("HEAD~1");
RevCommit c1_2 = amendBuilder()
.add("c.txt", "2")
.create();
RevCommit c1_2 = amendBuilder().add("c.txt", "2").create();
pushHead(testRepo, "refs/for/master", false);
PatchSet.Id ps1_2 = getPatchSetId(c1_2);
for (PatchSet.Id ps : ImmutableList.of(ps2_1, ps1_1)) {
assertRelated(ps,
changeAndCommit(ps2_1, c2_1, 1),
changeAndCommit(ps1_1, c1_1, 2));
assertRelated(ps, changeAndCommit(ps2_1, c2_1, 1), changeAndCommit(ps1_1, c1_1, 2));
}
assertRelated(ps1_2,
changeAndCommit(ps2_1, c2_1, 1),
changeAndCommit(ps1_2, c1_2, 2));
assertRelated(ps1_2, changeAndCommit(ps2_1, c2_1, 1), changeAndCommit(ps1_2, c1_2, 2));
}
@Test
@@ -217,14 +174,8 @@ public class GetRelatedIT extends AbstractDaemonTest {
// Create two commits and push.
ObjectId initial = repo().exactRef("HEAD").getObjectId();
RevCommit c1_1 = commitBuilder()
.add("a.txt", "1")
.message("subject: 1")
.create();
RevCommit c2_1 = commitBuilder()
.add("b.txt", "2")
.message("subject: 2")
.create();
RevCommit c1_1 = commitBuilder().add("a.txt", "1").message("subject: 1").create();
RevCommit c2_1 = commitBuilder().add("b.txt", "2").message("subject: 2").create();
pushHead(testRepo, "refs/for/master", false);
PatchSet.Id ps1_1 = getPatchSetId(c1_1);
PatchSet.Id ps2_1 = getPatchSetId(c2_1);
@@ -233,24 +184,23 @@ public class GetRelatedIT extends AbstractDaemonTest {
testRepo.reset(initial);
RevCommit c2_2 = testRepo.cherryPick(c2_1);
RevCommit c1_2 = testRepo.cherryPick(c1_1);
RevCommit c3_1 = commitBuilder()
.add("c.txt", "3")
.message("subject: 3")
.create();
RevCommit c3_1 = commitBuilder().add("c.txt", "3").message("subject: 3").create();
pushHead(testRepo, "refs/for/master", false);
PatchSet.Id ps1_2 = getPatchSetId(c1_1);
PatchSet.Id ps2_2 = getPatchSetId(c2_1);
PatchSet.Id ps3_1 = getPatchSetId(c3_1);
for (PatchSet.Id ps : ImmutableList.of(ps3_1, ps2_2, ps1_2)) {
assertRelated(ps,
assertRelated(
ps,
changeAndCommit(ps3_1, c3_1, 1),
changeAndCommit(ps1_2, c1_2, 2),
changeAndCommit(ps2_2, c2_2, 2));
}
for (PatchSet.Id ps : ImmutableList.of(ps2_1, ps1_1)) {
assertRelated(ps,
assertRelated(
ps,
changeAndCommit(ps3_1, c3_1, 1),
changeAndCommit(ps2_1, c2_1, 2),
changeAndCommit(ps1_1, c1_1, 2));
@@ -264,18 +214,9 @@ public class GetRelatedIT extends AbstractDaemonTest {
// 1,2---2,2---3,2
// Create three commits and push.
RevCommit c1_1 = commitBuilder()
.add("a.txt", "1")
.message("subject: 1")
.create();
RevCommit c2_1 = commitBuilder()
.add("b.txt", "1")
.message("subject: 2")
.create();
RevCommit c3_1 = commitBuilder()
.add("b.txt", "1")
.message("subject: 3")
.create();
RevCommit c1_1 = commitBuilder().add("a.txt", "1").message("subject: 1").create();
RevCommit c2_1 = commitBuilder().add("b.txt", "1").message("subject: 2").create();
RevCommit c3_1 = commitBuilder().add("b.txt", "1").message("subject: 3").create();
pushHead(testRepo, "refs/for/master", false);
PatchSet.Id ps1_1 = getPatchSetId(c1_1);
PatchSet.Id ps2_1 = getPatchSetId(c2_1);
@@ -283,31 +224,27 @@ public class GetRelatedIT extends AbstractDaemonTest {
// Amend all changes change and push.
testRepo.reset(c1_1);
RevCommit c1_2 = amendBuilder()
.add("a.txt", "2")
.create();
RevCommit c2_2 = commitBuilder()
.add("b.txt", "2")
.message(parseBody(c2_1).getFullMessage())
.create();
RevCommit c3_2 = commitBuilder()
.add("b.txt", "3")
.message(parseBody(c3_1).getFullMessage())
.create();
RevCommit c1_2 = amendBuilder().add("a.txt", "2").create();
RevCommit c2_2 =
commitBuilder().add("b.txt", "2").message(parseBody(c2_1).getFullMessage()).create();
RevCommit c3_2 =
commitBuilder().add("b.txt", "3").message(parseBody(c3_1).getFullMessage()).create();
pushHead(testRepo, "refs/for/master", false);
PatchSet.Id ps1_2 = getPatchSetId(c1_2);
PatchSet.Id ps2_2 = getPatchSetId(c2_2);
PatchSet.Id ps3_2 = getPatchSetId(c3_2);
for (PatchSet.Id ps : ImmutableList.of(ps1_1, ps2_1, ps3_1)) {
assertRelated(ps,
assertRelated(
ps,
changeAndCommit(ps3_1, c3_1, 2),
changeAndCommit(ps2_1, c2_1, 2),
changeAndCommit(ps1_1, c1_1, 2));
}
for (PatchSet.Id ps : ImmutableList.of(ps1_2, ps2_2, ps3_2)) {
assertRelated(ps,
assertRelated(
ps,
changeAndCommit(ps3_2, c3_2, 2),
changeAndCommit(ps2_2, c2_2, 2),
changeAndCommit(ps1_2, c1_2, 2));
@@ -322,18 +259,9 @@ public class GetRelatedIT extends AbstractDaemonTest {
// \---4,1
// Create three commits and push.
RevCommit c1_1 = commitBuilder()
.add("a.txt", "1")
.message("subject: 1")
.create();
RevCommit c2_1 = commitBuilder()
.add("b.txt", "1")
.message("subject: 2")
.create();
RevCommit c3_1 = commitBuilder()
.add("b.txt", "1")
.message("subject: 3")
.create();
RevCommit c1_1 = commitBuilder().add("a.txt", "1").message("subject: 1").create();
RevCommit c2_1 = commitBuilder().add("b.txt", "1").message("subject: 2").create();
RevCommit c3_1 = commitBuilder().add("b.txt", "1").message("subject: 3").create();
pushHead(testRepo, "refs/for/master", false);
PatchSet.Id ps1_1 = getPatchSetId(c1_1);
PatchSet.Id ps2_1 = getPatchSetId(c2_1);
@@ -341,17 +269,11 @@ public class GetRelatedIT extends AbstractDaemonTest {
// Amend all changes change and push.
testRepo.reset(c1_1);
RevCommit c1_2 = amendBuilder()
.add("a.txt", "2")
.create();
RevCommit c2_2 = commitBuilder()
.add("b.txt", "2")
.message(parseBody(c2_1).getFullMessage())
.create();
RevCommit c3_2 = commitBuilder()
.add("b.txt", "3")
.message(parseBody(c3_1).getFullMessage())
.create();
RevCommit c1_2 = amendBuilder().add("a.txt", "2").create();
RevCommit c2_2 =
commitBuilder().add("b.txt", "2").message(parseBody(c2_1).getFullMessage()).create();
RevCommit c3_2 =
commitBuilder().add("b.txt", "3").message(parseBody(c3_1).getFullMessage()).create();
pushHead(testRepo, "refs/for/master", false);
PatchSet.Id ps1_2 = getPatchSetId(c1_2);
PatchSet.Id ps2_2 = getPatchSetId(c2_2);
@@ -359,15 +281,13 @@ public class GetRelatedIT extends AbstractDaemonTest {
// Add one more commit 4,1 based on 1,2.
testRepo.reset(c1_2);
RevCommit c4_1 = commitBuilder()
.add("d.txt", "4")
.message("subject: 4")
.create();
RevCommit c4_1 = commitBuilder().add("d.txt", "4").message("subject: 4").create();
pushHead(testRepo, "refs/for/master", false);
PatchSet.Id ps4_1 = getPatchSetId(c4_1);
// 1,1 is related indirectly to 4,1.
assertRelated(ps1_1,
assertRelated(
ps1_1,
changeAndCommit(ps4_1, c4_1, 1),
changeAndCommit(ps3_1, c3_1, 2),
changeAndCommit(ps2_1, c2_1, 2),
@@ -376,14 +296,16 @@ public class GetRelatedIT extends AbstractDaemonTest {
// 2,1 and 3,1 don't include 4,1 since we don't walk forward after walking
// backward.
for (PatchSet.Id ps : ImmutableList.of(ps2_1, ps3_1)) {
assertRelated(ps,
assertRelated(
ps,
changeAndCommit(ps3_1, c3_1, 2),
changeAndCommit(ps2_1, c2_1, 2),
changeAndCommit(ps1_1, c1_1, 2));
}
// 1,2 is related directly to 4,1, and the 2-3 parallel branch stays intact.
assertRelated(ps1_2,
assertRelated(
ps1_2,
changeAndCommit(ps4_1, c4_1, 1),
changeAndCommit(ps3_2, c3_2, 2),
changeAndCommit(ps2_2, c2_2, 2),
@@ -391,14 +313,13 @@ public class GetRelatedIT extends AbstractDaemonTest {
// 4,1 is only related to 1,2, since we don't walk forward after walking
// backward.
assertRelated(ps4_1,
changeAndCommit(ps4_1, c4_1, 1),
changeAndCommit(ps1_2, c1_2, 2));
assertRelated(ps4_1, changeAndCommit(ps4_1, c4_1, 1), changeAndCommit(ps1_2, c1_2, 2));
// 2,2 and 3,2 don't include 4,1 since we don't walk forward after walking
// backward.
for (PatchSet.Id ps : ImmutableList.of(ps2_2, ps3_2)) {
assertRelated(ps,
assertRelated(
ps,
changeAndCommit(ps3_2, c3_2, 2),
changeAndCommit(ps2_2, c2_2, 2),
changeAndCommit(ps1_2, c1_2, 2));
@@ -412,57 +333,44 @@ public class GetRelatedIT extends AbstractDaemonTest {
// 1,2---2,2---3,1
// Create two commits and push.
RevCommit c1_1 = commitBuilder()
.add("a.txt", "1")
.message("subject: 1")
.create();
RevCommit c2_1 = commitBuilder()
.add("b.txt", "2")
.message("subject: 2")
.create();
RevCommit c1_1 = commitBuilder().add("a.txt", "1").message("subject: 1").create();
RevCommit c2_1 = commitBuilder().add("b.txt", "2").message("subject: 2").create();
pushHead(testRepo, "refs/for/master", false);
PatchSet.Id ps1_1 = getPatchSetId(c1_1);
PatchSet.Id ps2_1 = getPatchSetId(c2_1);
// Amend both changes change and push.
testRepo.reset(c1_1);
RevCommit c1_2 = amendBuilder()
.add("a.txt", "2")
.create();
RevCommit c2_2 = commitBuilder()
.add("b.txt", "2")
.message(parseBody(c2_1).getFullMessage())
.create();
RevCommit c1_2 = amendBuilder().add("a.txt", "2").create();
RevCommit c2_2 =
commitBuilder().add("b.txt", "2").message(parseBody(c2_1).getFullMessage()).create();
pushHead(testRepo, "refs/for/master", false);
PatchSet.Id ps1_2 = getPatchSetId(c1_2);
PatchSet.Id ps2_2 = getPatchSetId(c2_2);
// PS 3,1 depends on 2,2.
RevCommit c3_1 = commitBuilder()
.add("c.txt", "1")
.message("subject: 3")
.create();
RevCommit c3_1 = commitBuilder().add("c.txt", "1").message("subject: 3").create();
pushHead(testRepo, "refs/for/master", false);
PatchSet.Id ps3_1 = getPatchSetId(c3_1);
// PS 3,2 depends on 2,1.
testRepo.reset(c2_1);
RevCommit c3_2 = commitBuilder()
.add("c.txt", "2")
.message(parseBody(c3_1).getFullMessage())
.create();
RevCommit c3_2 =
commitBuilder().add("c.txt", "2").message(parseBody(c3_1).getFullMessage()).create();
pushHead(testRepo, "refs/for/master", false);
PatchSet.Id ps3_2 = getPatchSetId(c3_2);
for (PatchSet.Id ps : ImmutableList.of(ps1_1, ps2_1, ps3_2)) {
assertRelated(ps,
assertRelated(
ps,
changeAndCommit(ps3_2, c3_2, 2),
changeAndCommit(ps2_1, c2_1, 2),
changeAndCommit(ps1_1, c1_1, 2));
}
for (PatchSet.Id ps : ImmutableList.of(ps1_2, ps2_2, ps3_1)) {
assertRelated(ps,
assertRelated(
ps,
changeAndCommit(ps3_1, c3_1, 2),
changeAndCommit(ps2_2, c2_2, 2),
changeAndCommit(ps1_2, c1_2, 2));
@@ -475,52 +383,32 @@ public class GetRelatedIT extends AbstractDaemonTest {
// \---4,1---5,1
// \--6,1---7,1
RevCommit c1_1 = commitBuilder()
.add("a.txt", "1")
.message("subject: 1")
.create();
RevCommit c2_1 = commitBuilder()
.add("b.txt", "2")
.message("subject: 2")
.create();
RevCommit c3_1 = commitBuilder()
.add("c.txt", "3")
.message("subject: 3")
.create();
RevCommit c1_1 = commitBuilder().add("a.txt", "1").message("subject: 1").create();
RevCommit c2_1 = commitBuilder().add("b.txt", "2").message("subject: 2").create();
RevCommit c3_1 = commitBuilder().add("c.txt", "3").message("subject: 3").create();
pushHead(testRepo, "refs/for/master", false);
PatchSet.Id ps1_1 = getPatchSetId(c1_1);
PatchSet.Id ps2_1 = getPatchSetId(c2_1);
PatchSet.Id ps3_1 = getPatchSetId(c3_1);
testRepo.reset(c1_1);
RevCommit c4_1 = commitBuilder()
.add("d.txt", "4")
.message("subject: 4")
.create();
RevCommit c5_1 = commitBuilder()
.add("e.txt", "5")
.message("subject: 5")
.create();
RevCommit c4_1 = commitBuilder().add("d.txt", "4").message("subject: 4").create();
RevCommit c5_1 = commitBuilder().add("e.txt", "5").message("subject: 5").create();
pushHead(testRepo, "refs/for/master", false);
PatchSet.Id ps4_1 = getPatchSetId(c4_1);
PatchSet.Id ps5_1 = getPatchSetId(c5_1);
testRepo.reset(c1_1);
RevCommit c6_1 = commitBuilder()
.add("f.txt", "6")
.message("subject: 6")
.create();
RevCommit c7_1 = commitBuilder()
.add("g.txt", "7")
.message("subject: 7")
.create();
RevCommit c6_1 = commitBuilder().add("f.txt", "6").message("subject: 6").create();
RevCommit c7_1 = commitBuilder().add("g.txt", "7").message("subject: 7").create();
pushHead(testRepo, "refs/for/master", false);
PatchSet.Id ps6_1 = getPatchSetId(c6_1);
PatchSet.Id ps7_1 = getPatchSetId(c7_1);
// All changes are related to 1,1, keeping each of the parallel branches
// intact.
assertRelated(ps1_1,
assertRelated(
ps1_1,
changeAndCommit(ps7_1, c7_1, 1),
changeAndCommit(ps6_1, c6_1, 1),
changeAndCommit(ps5_1, c5_1, 1),
@@ -531,7 +419,8 @@ public class GetRelatedIT extends AbstractDaemonTest {
// The 2-3 branch is only related back to 1, not the other branches.
for (PatchSet.Id ps : ImmutableList.of(ps2_1, ps3_1)) {
assertRelated(ps,
assertRelated(
ps,
changeAndCommit(ps3_1, c3_1, 1),
changeAndCommit(ps2_1, c2_1, 1),
changeAndCommit(ps1_1, c1_1, 1));
@@ -539,7 +428,8 @@ public class GetRelatedIT extends AbstractDaemonTest {
// The 4-5 branch is only related back to 1, not the other branches.
for (PatchSet.Id ps : ImmutableList.of(ps4_1, ps5_1)) {
assertRelated(ps,
assertRelated(
ps,
changeAndCommit(ps5_1, c5_1, 1),
changeAndCommit(ps4_1, c4_1, 1),
changeAndCommit(ps1_1, c1_1, 1));
@@ -547,7 +437,8 @@ public class GetRelatedIT extends AbstractDaemonTest {
// The 6-7 branch is only related back to 1, not the other branches.
for (PatchSet.Id ps : ImmutableList.of(ps6_1, ps7_1)) {
assertRelated(ps,
assertRelated(
ps,
changeAndCommit(ps7_1, c7_1, 1),
changeAndCommit(ps6_1, c6_1, 1),
changeAndCommit(ps1_1, c1_1, 1));
@@ -559,30 +450,15 @@ public class GetRelatedIT extends AbstractDaemonTest {
// 1,1---2,1---3,1
// \---2,E---/
RevCommit c1_1 = commitBuilder()
.add("a.txt", "1")
.message("subject: 1")
.create();
RevCommit c2_1 = commitBuilder()
.add("b.txt", "2")
.message("subject: 2")
.create();
RevCommit c3_1 = commitBuilder()
.add("c.txt", "3")
.message("subject: 3")
.create();
RevCommit c1_1 = commitBuilder().add("a.txt", "1").message("subject: 1").create();
RevCommit c2_1 = commitBuilder().add("b.txt", "2").message("subject: 2").create();
RevCommit c3_1 = commitBuilder().add("c.txt", "3").message("subject: 3").create();
pushHead(testRepo, "refs/for/master", false);
Change ch2 = getChange(c2_1).change();
String changeId2 = ch2.getKey().get();
gApi.changes()
.id(changeId2)
.edit()
.create();
gApi.changes()
.id(changeId2)
.edit()
.modifyFile("a.txt", RawInputUtil.create(new byte[] {'a'}));
gApi.changes().id(changeId2).edit().create();
gApi.changes().id(changeId2).edit().modifyFile("a.txt", RawInputUtil.create(new byte[] {'a'}));
Optional<EditInfo> edit = getEdit(changeId2);
assertThat(edit).isPresent();
ObjectId editRev = ObjectId.fromString(edit.get().commit.commit);
@@ -593,13 +469,15 @@ public class GetRelatedIT extends AbstractDaemonTest {
PatchSet.Id ps3_1 = getPatchSetId(c3_1);
for (PatchSet.Id ps : ImmutableList.of(ps1_1, ps2_1, ps3_1)) {
assertRelated(ps,
assertRelated(
ps,
changeAndCommit(ps3_1, c3_1, 1),
changeAndCommit(ps2_1, c2_1, 1),
changeAndCommit(ps1_1, c1_1, 1));
}
assertRelated(ps2_edit,
assertRelated(
ps2_edit,
changeAndCommit(ps3_1, c3_1, 1),
changeAndCommit(new PatchSet.Id(ch2.getId(), 0), editRev, 1),
changeAndCommit(ps1_1, c1_1, 1));
@@ -610,63 +488,42 @@ public class GetRelatedIT extends AbstractDaemonTest {
// 1,1---2,1
// \---2,2
RevCommit c1_1 = commitBuilder()
.add("a.txt", "1")
.message("subject: 1")
.create();
RevCommit c2_1 = commitBuilder()
.add("b.txt", "2")
.message("subject: 2")
.create();
RevCommit c1_1 = commitBuilder().add("a.txt", "1").message("subject: 1").create();
RevCommit c2_1 = commitBuilder().add("b.txt", "2").message("subject: 2").create();
pushHead(testRepo, "refs/for/master", false);
PatchSet.Id psId1_1 = getPatchSetId(c1_1);
PatchSet.Id psId2_1 = getPatchSetId(c2_1);
for (PatchSet.Id psId : ImmutableList.of(psId1_1, psId2_1)) {
assertRelated(psId,
changeAndCommit(psId2_1, c2_1, 1),
changeAndCommit(psId1_1, c1_1, 1));
assertRelated(psId, changeAndCommit(psId2_1, c2_1, 1), changeAndCommit(psId1_1, c1_1, 1));
}
// Pretend PS1,1 was pushed before the groups field was added.
clearGroups(psId1_1);
indexer.index(
changeDataFactory.create(db, project, psId1_1.getParentKey()));
indexer.index(changeDataFactory.create(db, project, psId1_1.getParentKey()));
// PS1,1 has no groups, so disappeared from related changes.
assertRelated(psId2_1);
RevCommit c2_2 = testRepo.amend(c2_1)
.add("c.txt", "2")
.create();
RevCommit c2_2 = testRepo.amend(c2_1).add("c.txt", "2").create();
testRepo.reset(c2_2);
pushHead(testRepo, "refs/for/master", false);
PatchSet.Id psId2_2 = getPatchSetId(c2_2);
// Push updated the group for PS1,1, so it shows up in related changes even
// though a new patch set was not pushed.
assertRelated(psId2_2,
changeAndCommit(psId2_2, c2_2, 2),
changeAndCommit(psId1_1, c1_1, 1));
assertRelated(psId2_2, changeAndCommit(psId2_2, c2_2, 2), changeAndCommit(psId1_1, c1_1, 1));
}
@Test
@GerritConfig(name = "index.testReindexAfterUpdate", value = "false")
public void getRelatedForStaleChange() throws Exception {
RevCommit c1_1 = commitBuilder()
.add("a.txt", "1")
.message("subject: 1")
.create();
RevCommit c1_1 = commitBuilder().add("a.txt", "1").message("subject: 1").create();
RevCommit c2_1 = commitBuilder()
.add("b.txt", "1")
.message("subject: 1")
.create();
RevCommit c2_1 = commitBuilder().add("b.txt", "1").message("subject: 1").create();
pushHead(testRepo, "refs/for/master", false);
RevCommit c2_2 = testRepo.amend(c2_1)
.add("b.txt", "2")
.create();
RevCommit c2_2 = testRepo.amend(c2_1).add("b.txt", "2").create();
testRepo.reset(c2_2);
disableChangeIndexWrites();
@@ -680,18 +537,15 @@ public class GetRelatedIT extends AbstractDaemonTest {
PatchSet.Id psId2_1 = getPatchSetId(c2_1);
PatchSet.Id psId2_2 = new PatchSet.Id(psId2_1.changeId, psId2_1.get() + 1);
assertRelated(psId2_2, changeAndCommit(psId2_2, c2_2, 2),
changeAndCommit(psId1_1, c1_1, 1));
assertRelated(psId2_2, changeAndCommit(psId2_2, c2_2, 2), changeAndCommit(psId1_1, c1_1, 1));
}
private List<ChangeAndCommit> getRelated(PatchSet.Id ps) throws Exception {
return getRelated(ps.getParentKey(), ps.get());
}
private List<ChangeAndCommit> getRelated(Change.Id changeId, int ps)
throws Exception {
String url = String.format("/changes/%d/revisions/%d/related",
changeId.get(), ps);
private List<ChangeAndCommit> getRelated(Change.Id changeId, int ps) throws Exception {
String url = String.format("/changes/%d/revisions/%d/related", changeId.get(), ps);
RestResponse r = adminRestSession.get(url);
r.assertOK();
return newGson().fromJson(r.getReader(), RelatedInfo.class).changes;
@@ -723,38 +577,35 @@ public class GetRelatedIT extends AbstractDaemonTest {
}
private void clearGroups(final PatchSet.Id psId) throws Exception {
try (BatchUpdate bu = updateFactory.create(
db, project, user(user), TimeUtil.nowTs())) {
bu.addOp(psId.getParentKey(), new BatchUpdate.Op() {
@Override
public boolean updateChange(ChangeContext ctx) throws OrmException {
PatchSet ps = psUtil.get(ctx.getDb(), ctx.getNotes(), psId);
psUtil.setGroups(ctx.getDb(), ctx.getUpdate(psId), ps,
ImmutableList.<String> of());
ctx.bumpLastUpdatedOn(false);
return true;
}
});
try (BatchUpdate bu = updateFactory.create(db, project, user(user), TimeUtil.nowTs())) {
bu.addOp(
psId.getParentKey(),
new BatchUpdate.Op() {
@Override
public boolean updateChange(ChangeContext ctx) throws OrmException {
PatchSet ps = psUtil.get(ctx.getDb(), ctx.getNotes(), psId);
psUtil.setGroups(ctx.getDb(), ctx.getUpdate(psId), ps, ImmutableList.<String>of());
ctx.bumpLastUpdatedOn(false);
return true;
}
});
bu.execute();
}
}
private void assertRelated(PatchSet.Id psId, ChangeAndCommit... expected)
throws Exception {
private void assertRelated(PatchSet.Id psId, ChangeAndCommit... expected) throws Exception {
List<ChangeAndCommit> actual = getRelated(psId);
assertThat(actual).named("related to " + psId).hasSize(expected.length);
for (int i = 0; i < actual.size(); i++) {
String name = "index " + i + " related to " + psId;
ChangeAndCommit a = actual.get(i);
ChangeAndCommit e = expected[i];
assertThat(a._changeNumber).named("change ID of " + name)
.isEqualTo(e._changeNumber);
assertThat(a._changeNumber).named("change ID of " + name).isEqualTo(e._changeNumber);
// Don't bother checking changeId; assume _changeNumber is sufficient.
assertThat(a._revisionNumber).named("revision of " + name)
.isEqualTo(e._revisionNumber);
assertThat(a.commit.commit).named("commit of " + name)
.isEqualTo(e.commit.commit);
assertThat(a._currentRevisionNumber).named("current revision of " + name)
assertThat(a._revisionNumber).named("revision of " + name).isEqualTo(e._revisionNumber);
assertThat(a.commit.commit).named("commit of " + name).isEqualTo(e.commit.commit);
assertThat(a._currentRevisionNumber)
.named("current revision of " + name)
.isEqualTo(e._currentRevisionNumber);
}
}

View File

@@ -27,13 +27,11 @@ import com.google.gerrit.server.patch.PatchListCache;
import com.google.gerrit.server.patch.PatchListEntry;
import com.google.gerrit.server.patch.PatchListKey;
import com.google.inject.Inject;
import java.util.List;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.revwalk.RevCommit;
import org.junit.Test;
import java.util.List;
@NoHttpd
public class PatchListCacheIT extends AbstractDaemonTest {
private static String SUBJECT_1 = "subject 1";
@@ -44,24 +42,16 @@ public class PatchListCacheIT extends AbstractDaemonTest {
private static String FILE_C = "c.txt";
private static String FILE_D = "d.txt";
@Inject
private PatchListCache patchListCache;
@Inject private PatchListCache patchListCache;
@Test
public void listPatchesAgainstBase() throws Exception {
commitBuilder()
.add(FILE_D, "4")
.message(SUBJECT_1)
.create();
commitBuilder().add(FILE_D, "4").message(SUBJECT_1).create();
pushHead(testRepo, "refs/heads/master", false);
// Change 1, 1 (+FILE_A, -FILE_D)
RevCommit c = commitBuilder()
.add(FILE_A, "1")
.rm(FILE_D)
.message(SUBJECT_2)
.insertChangeId()
.create();
RevCommit c =
commitBuilder().add(FILE_A, "1").rm(FILE_D).message(SUBJECT_2).insertChangeId().create();
String id = getChangeId(testRepo, c).get();
pushHead(testRepo, "refs/for/master", false);
@@ -73,9 +63,7 @@ public class PatchListCacheIT extends AbstractDaemonTest {
assertDeleted(FILE_D, entries.get(2));
// Change 1,2 (+FILE_A, +FILE_B, -FILE_D)
c = amendBuilder()
.add(FILE_B, "2")
.create();
c = amendBuilder().add(FILE_B, "2").create();
pushHead(testRepo, "refs/for/master", false);
entries = getCurrentPatches(id);
@@ -89,18 +77,11 @@ public class PatchListCacheIT extends AbstractDaemonTest {
@Test
public void listPatchesAgainstBaseWithRebase() throws Exception {
commitBuilder()
.add(FILE_D, "4")
.message(SUBJECT_1)
.create();
commitBuilder().add(FILE_D, "4").message(SUBJECT_1).create();
pushHead(testRepo, "refs/heads/master", false);
// Change 1,1 (+FILE_A, -FILE_D)
RevCommit c = commitBuilder()
.add(FILE_A, "1")
.rm(FILE_D)
.message(SUBJECT_2)
.create();
RevCommit c = commitBuilder().add(FILE_A, "1").rm(FILE_D).message(SUBJECT_2).create();
String id = getChangeId(testRepo, c).get();
pushHead(testRepo, "refs/for/master", false);
List<PatchListEntry> entries = getCurrentPatches(id);
@@ -111,10 +92,7 @@ public class PatchListCacheIT extends AbstractDaemonTest {
// Change 2,1 (+FILE_B)
testRepo.reset("HEAD~1");
commitBuilder()
.add(FILE_B, "2")
.message(SUBJECT_3)
.create();
commitBuilder().add(FILE_B, "2").message(SUBJECT_3).create();
pushHead(testRepo, "refs/for/master", false);
// Change 1,2 (+FILE_A, -FILE_D))
@@ -131,37 +109,27 @@ public class PatchListCacheIT extends AbstractDaemonTest {
@Test
public void listPatchesAgainstOtherPatchSet() throws Exception {
commitBuilder()
.add(FILE_D, "4")
.message(SUBJECT_1)
.create();
commitBuilder().add(FILE_D, "4").message(SUBJECT_1).create();
pushHead(testRepo, "refs/heads/master", false);
// Change 1,1 (+FILE_A, +FILE_C, -FILE_D)
RevCommit a = commitBuilder()
.add(FILE_A, "1")
.add(FILE_C, "3")
.rm(FILE_D)
.message(SUBJECT_2)
.create();
RevCommit a =
commitBuilder().add(FILE_A, "1").add(FILE_C, "3").rm(FILE_D).message(SUBJECT_2).create();
pushHead(testRepo, "refs/for/master", false);
// Change 1,2 (+FILE_A, +FILE_B, -FILE_D)
RevCommit b = amendBuilder()
.add(FILE_B, "2")
.rm(FILE_C)
.create();
RevCommit b = amendBuilder().add(FILE_B, "2").rm(FILE_C).create();
pushHead(testRepo, "refs/for/master", false);
// Compare Change 1,1 with Change 1,2 (+FILE_B, -FILE_C)
List<PatchListEntry> entries = getPatches(a, b);
List<PatchListEntry> entries = getPatches(a, b);
assertThat(entries).hasSize(3);
assertModified(Patch.COMMIT_MSG, entries.get(0));
assertAdded(FILE_B, entries.get(1));
assertDeleted(FILE_C, entries.get(2));
// Compare Change 1,2 with Change 1,1 (-FILE_B, +FILE_C)
List<PatchListEntry> entriesReverse = getPatches(b, a);
List<PatchListEntry> entriesReverse = getPatches(b, a);
assertThat(entriesReverse).hasSize(3);
assertModified(Patch.COMMIT_MSG, entriesReverse.get(0));
assertDeleted(FILE_B, entriesReverse.get(1));
@@ -170,43 +138,31 @@ public class PatchListCacheIT extends AbstractDaemonTest {
@Test
public void listPatchesAgainstOtherPatchSetWithRebase() throws Exception {
commitBuilder()
.add(FILE_D, "4")
.message(SUBJECT_1)
.create();
commitBuilder().add(FILE_D, "4").message(SUBJECT_1).create();
pushHead(testRepo, "refs/heads/master", false);
// Change 1,1 (+FILE_A, -FILE_D)
RevCommit a = commitBuilder()
.add(FILE_A, "1")
.rm(FILE_D)
.message(SUBJECT_2)
.create();
RevCommit a = commitBuilder().add(FILE_A, "1").rm(FILE_D).message(SUBJECT_2).create();
pushHead(testRepo, "refs/for/master", false);
// Change 2,1 (+FILE_B)
testRepo.reset("HEAD~1");
commitBuilder()
.add(FILE_B, "2")
.message(SUBJECT_3)
.create();
commitBuilder().add(FILE_B, "2").message(SUBJECT_3).create();
pushHead(testRepo, "refs/for/master", false);
// Change 1,2 (+FILE_A, +FILE_C, -FILE_D)
testRepo.cherryPick(a);
RevCommit b = amendBuilder()
.add(FILE_C, "2")
.create();
RevCommit b = amendBuilder().add(FILE_C, "2").create();
pushHead(testRepo, "refs/for/master", false);
// Compare Change 1,1 with Change 1,2 (+FILE_C)
List<PatchListEntry> entries = getPatches(a, b);
List<PatchListEntry> entries = getPatches(a, b);
assertThat(entries).hasSize(2);
assertModified(Patch.COMMIT_MSG, entries.get(0));
assertAdded(FILE_C, entries.get(1));
// Compare Change 1,2 with Change 1,1 (-FILE_C)
List<PatchListEntry> entriesReverse = getPatches(b, a);
List<PatchListEntry> entriesReverse = getPatches(b, a);
assertThat(entriesReverse).hasSize(2);
assertModified(Patch.COMMIT_MSG, entriesReverse.get(0));
assertDeleted(FILE_C, entriesReverse.get(1));
@@ -232,17 +188,13 @@ public class PatchListCacheIT extends AbstractDaemonTest {
assertThat(e.getOldName()).isNull();
}
private List<PatchListEntry> getCurrentPatches(String changeId)
throws Exception {
return patchListCache
.get(getKey(null, getCurrentRevisionId(changeId)), project)
.getPatches();
private List<PatchListEntry> getCurrentPatches(String changeId) throws Exception {
return patchListCache.get(getKey(null, getCurrentRevisionId(changeId)), project).getPatches();
}
private List<PatchListEntry> getPatches(ObjectId revisionIdA, ObjectId revisionIdB)
throws Exception {
return patchListCache.get(getKey(revisionIdA, revisionIdB), project)
.getPatches();
return patchListCache.get(getKey(revisionIdA, revisionIdB), project).getPatches();
}
private PatchListKey getKey(ObjectId revisionIdA, ObjectId revisionIdB) {

View File

@@ -31,15 +31,13 @@ import com.google.gerrit.extensions.common.RevisionInfo;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.testutil.ConfigSuite;
import java.util.EnumSet;
import java.util.List;
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.revwalk.RevCommit;
import org.junit.Test;
import java.util.EnumSet;
import java.util.List;
public class SubmittedTogetherIT extends AbstractDaemonTest {
@ConfigSuite.Config
public static Config submitWholeTopicEnabled() {
@@ -48,21 +46,13 @@ public class SubmittedTogetherIT extends AbstractDaemonTest {
@Test
public void doesNotIncludeCurrentFiles() throws Exception {
RevCommit c1_1 = commitBuilder()
.add("a.txt", "1")
.message("subject: 1")
.create();
RevCommit c2_1 = commitBuilder()
.add("b.txt", "2")
.message("subject: 2")
.create();
RevCommit c1_1 = commitBuilder().add("a.txt", "1").message("subject: 1").create();
RevCommit c2_1 = commitBuilder().add("b.txt", "2").message("subject: 2").create();
String id2 = getChangeId(c2_1);
pushHead(testRepo, "refs/for/master", false);
SubmittedTogetherInfo info =
gApi.changes()
.id(id2)
.submittedTogether(EnumSet.of(NON_VISIBLE_CHANGES));
gApi.changes().id(id2).submittedTogether(EnumSet.of(NON_VISIBLE_CHANGES));
assertThat(info.changes).hasSize(2);
assertThat(info.changes.get(0).currentRevision).isEqualTo(c2_1.name());
assertThat(info.changes.get(1).currentRevision).isEqualTo(c1_1.name());
@@ -74,14 +64,8 @@ public class SubmittedTogetherIT extends AbstractDaemonTest {
@Test
public void returnsCurrentFilesIfOptionRequested() throws Exception {
RevCommit c1_1 = commitBuilder()
.add("a.txt", "1")
.message("subject: 1")
.create();
RevCommit c2_1 = commitBuilder()
.add("b.txt", "2")
.message("subject: 2")
.create();
RevCommit c1_1 = commitBuilder().add("a.txt", "1").message("subject: 1").create();
RevCommit c2_1 = commitBuilder().add("b.txt", "2").message("subject: 2").create();
String id2 = getChangeId(c2_1);
pushHead(testRepo, "refs/for/master", false);
@@ -89,8 +73,7 @@ public class SubmittedTogetherIT extends AbstractDaemonTest {
gApi.changes()
.id(id2)
.submittedTogether(
EnumSet.of(ListChangesOption.CURRENT_FILES),
EnumSet.of(NON_VISIBLE_CHANGES));
EnumSet.of(ListChangesOption.CURRENT_FILES), EnumSet.of(NON_VISIBLE_CHANGES));
assertThat(info.changes).hasSize(2);
assertThat(info.changes.get(0).currentRevision).isEqualTo(c2_1.name());
assertThat(info.changes.get(1).currentRevision).isEqualTo(c1_1.name());
@@ -106,15 +89,9 @@ public class SubmittedTogetherIT extends AbstractDaemonTest {
@Test
public void returnsAncestors() throws Exception {
// Create two commits and push.
RevCommit c1_1 = commitBuilder()
.add("a.txt", "1")
.message("subject: 1")
.create();
RevCommit c1_1 = commitBuilder().add("a.txt", "1").message("subject: 1").create();
String id1 = getChangeId(c1_1);
RevCommit c2_1 = commitBuilder()
.add("b.txt", "2")
.message("subject: 2")
.create();
RevCommit c2_1 = commitBuilder().add("b.txt", "2").message("subject: 2").create();
String id2 = getChangeId(c2_1);
pushHead(testRepo, "refs/for/master", false);
@@ -137,18 +114,12 @@ public class SubmittedTogetherIT extends AbstractDaemonTest {
public void respectsWholeTopicAndAncestors() throws Exception {
RevCommit initialHead = getRemoteHead();
// Create two independent commits and push.
RevCommit c1_1 = commitBuilder()
.add("a.txt", "1")
.message("subject: 1")
.create();
RevCommit c1_1 = commitBuilder().add("a.txt", "1").message("subject: 1").create();
String id1 = getChangeId(c1_1);
pushHead(testRepo, "refs/for/master/" + name("connectingTopic"), false);
testRepo.reset(initialHead);
RevCommit c2_1 = commitBuilder()
.add("b.txt", "2")
.message("subject: 2")
.create();
RevCommit c2_1 = commitBuilder().add("b.txt", "2").message("subject: 2").create();
String id2 = getChangeId(c2_1);
pushHead(testRepo, "refs/for/master/" + name("connectingTopic"), false);
@@ -195,9 +166,8 @@ public class SubmittedTogetherIT extends AbstractDaemonTest {
pushHead(testRepo, "refs/drafts/master/" + name("topic"), false);
setApiUser(user);
SubmittedTogetherInfo result = gApi.changes()
.id(id1)
.submittedTogether(EnumSet.of(NON_VISIBLE_CHANGES));
SubmittedTogetherInfo result =
gApi.changes().id(id1).submittedTogether(EnumSet.of(NON_VISIBLE_CHANGES));
if (isSubmitWholeTopicEnabled()) {
assertThat(result.changes).hasSize(1);
@@ -223,8 +193,7 @@ public class SubmittedTogetherIT extends AbstractDaemonTest {
setApiUser(user);
if (isSubmitWholeTopicEnabled()) {
exception.expect(AuthException.class);
exception.expectMessage(
"change would be submitted with a change that you cannot see");
exception.expectMessage("change would be submitted with a change that you cannot see");
gApi.changes().id(id1).submittedTogether();
} else {
List<ChangeInfo> result = gApi.changes().id(id1).submittedTogether();
@@ -286,9 +255,8 @@ public class SubmittedTogetherIT extends AbstractDaemonTest {
String id = getChangeId(change);
setApiUser(user);
SubmittedTogetherInfo result = gApi.changes()
.id(id)
.submittedTogether(EnumSet.of(NON_VISIBLE_CHANGES));
SubmittedTogetherInfo result =
gApi.changes().id(id).submittedTogether(EnumSet.of(NON_VISIBLE_CHANGES));
if (isSubmitWholeTopicEnabled()) {
assertThat(result.changes).hasSize(1);
assertThat(result.changes.get(0).changeId).isEqualTo(id);
@@ -303,25 +271,16 @@ public class SubmittedTogetherIT extends AbstractDaemonTest {
public void topicChaining() throws Exception {
RevCommit initialHead = getRemoteHead();
// Create two independent commits and push.
RevCommit c1_1 = commitBuilder()
.add("a.txt", "1")
.message("subject: 1")
.create();
RevCommit c1_1 = commitBuilder().add("a.txt", "1").message("subject: 1").create();
String id1 = getChangeId(c1_1);
pushHead(testRepo, "refs/for/master/" + name("connectingTopic"), false);
testRepo.reset(initialHead);
RevCommit c2_1 = commitBuilder()
.add("b.txt", "2")
.message("subject: 2")
.create();
RevCommit c2_1 = commitBuilder().add("b.txt", "2").message("subject: 2").create();
String id2 = getChangeId(c2_1);
pushHead(testRepo, "refs/for/master/" + name("connectingTopic"), false);
RevCommit c3_1 = commitBuilder()
.add("b.txt", "2")
.message("subject: 2")
.create();
RevCommit c3_1 = commitBuilder().add("b.txt", "2").message("subject: 2").create();
String id3 = getChangeId(c3_1);
pushHead(testRepo, "refs/for/master/" + name("unrelated-topic"), false);
@@ -341,17 +300,25 @@ public class SubmittedTogetherIT extends AbstractDaemonTest {
Project.NameKey p1 = createProject("a-new-project", null, false);
TestRepository<?> repo1 = cloneProject(p1);
RevCommit c1 = repo1.branch("HEAD").commit().insertChangeId()
.add("a.txt", "1")
.message("subject: 1")
.create();
RevCommit c1 =
repo1
.branch("HEAD")
.commit()
.insertChangeId()
.add("a.txt", "1")
.message("subject: 1")
.create();
String id1 = GitUtil.getChangeId(repo1, c1).get();
pushHead(repo1, "refs/for/master", false);
RevCommit c2 = repo1.branch("HEAD").commit().insertChangeId()
.add("b.txt", "2")
.message("subject: 2")
.create();
RevCommit c2 =
repo1
.branch("HEAD")
.commit()
.insertChangeId()
.add("b.txt", "2")
.message("subject: 2")
.create();
String id2 = GitUtil.getChangeId(repo1, c2).get();
pushHead(repo1, "refs/for/master", false);
assertSubmittedTogether(id1);
@@ -362,15 +329,9 @@ public class SubmittedTogetherIT extends AbstractDaemonTest {
@TestProjectInput(submitType = SubmitType.CHERRY_PICK)
public void testCherryPickWithoutAncestors() throws Exception {
// Create two commits and push.
RevCommit c1_1 = commitBuilder()
.add("a.txt", "1")
.message("subject: 1")
.create();
RevCommit c1_1 = commitBuilder().add("a.txt", "1").message("subject: 1").create();
String id1 = getChangeId(c1_1);
RevCommit c2_1 = commitBuilder()
.add("b.txt", "2")
.message("subject: 2")
.create();
RevCommit c2_1 = commitBuilder().add("b.txt", "2").message("subject: 2").create();
String id2 = getChangeId(c2_1);
pushHead(testRepo, "refs/for/master", false);
@@ -381,15 +342,9 @@ public class SubmittedTogetherIT extends AbstractDaemonTest {
@Test
public void submissionIdSavedOnMergeInOneProject() throws Exception {
// Create two commits and push.
RevCommit c1_1 = commitBuilder()
.add("a.txt", "1")
.message("subject: 1")
.create();
RevCommit c1_1 = commitBuilder().add("a.txt", "1").message("subject: 1").create();
String id1 = getChangeId(c1_1);
RevCommit c2_1 = commitBuilder()
.add("b.txt", "2")
.message("subject: 2")
.create();
RevCommit c2_1 = commitBuilder().add("b.txt", "2").message("subject: 2").create();
String id2 = getChangeId(c2_1);
pushHead(testRepo, "refs/for/master", false);
@@ -414,17 +369,10 @@ public class SubmittedTogetherIT extends AbstractDaemonTest {
}
private void submit(String changeId) throws Exception {
gApi.changes()
.id(changeId)
.current()
.submit();
gApi.changes().id(changeId).current().submit();
}
private void assertMerged(String changeId) throws Exception {
assertThat(gApi
.changes()
.id(changeId)
.get()
.status).isEqualTo(ChangeStatus.MERGED);
assertThat(gApi.changes().id(changeId).get().status).isEqualTo(ChangeStatus.MERGED);
}
}

View File

@@ -35,7 +35,6 @@ import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.server.git.ProjectConfig;
import com.google.gerrit.server.project.Util;
import com.google.inject.Inject;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -43,17 +42,13 @@ import org.junit.Test;
@NoHttpd
public class CommentAddedEventIT extends AbstractDaemonTest {
@Inject
private DynamicSet<CommentAddedListener> source;
@Inject private DynamicSet<CommentAddedListener> source;
private final LabelType label = category("CustomLabel",
value(1, "Positive"),
value(0, "No score"),
value(-1, "Negative"));
private final LabelType label =
category("CustomLabel", value(1, "Positive"), value(0, "No score"), value(-1, "Negative"));
private final LabelType pLabel = category("CustomLabel2",
value(1, "Positive"),
value(0, "No score"));
private final LabelType pLabel =
category("CustomLabel2", value(1, "Positive"), value(0, "No score"));
private RegistrationHandle eventListenerRegistration;
private CommentAddedListener.Event lastCommentAddedEvent;
@@ -61,20 +56,19 @@ public class CommentAddedEventIT extends AbstractDaemonTest {
@Before
public void setUp() throws Exception {
ProjectConfig cfg = projectCache.checkedGet(project).getConfig();
AccountGroup.UUID anonymousUsers =
systemGroupBackend.getGroup(ANONYMOUS_USERS).getUUID();
Util.allow(cfg, Permission.forLabel(label.getName()), -1, 1, anonymousUsers,
"refs/heads/*");
Util.allow(cfg, Permission.forLabel(pLabel.getName()), 0, 1, anonymousUsers,
"refs/heads/*");
AccountGroup.UUID anonymousUsers = systemGroupBackend.getGroup(ANONYMOUS_USERS).getUUID();
Util.allow(cfg, Permission.forLabel(label.getName()), -1, 1, anonymousUsers, "refs/heads/*");
Util.allow(cfg, Permission.forLabel(pLabel.getName()), 0, 1, anonymousUsers, "refs/heads/*");
saveProjectConfig(project, cfg);
eventListenerRegistration = source.add(new CommentAddedListener() {
@Override
public void onCommentAdded(Event event) {
lastCommentAddedEvent = event;
}
});
eventListenerRegistration =
source.add(
new CommentAddedListener() {
@Override
public void onCommentAdded(Event event) {
lastCommentAddedEvent = event;
}
});
}
@After
@@ -94,8 +88,7 @@ public class CommentAddedEventIT extends AbstractDaemonTest {
*/
private ApprovalValues getApprovalValues(LabelType label) {
ApprovalValues res = new ApprovalValues();
ApprovalInfo info =
lastCommentAddedEvent.getApprovals().get(label.getName());
ApprovalInfo info = lastCommentAddedEvent.getApprovals().get(label.getName());
if (info != null) {
res.value = info.value;
}
@@ -112,14 +105,13 @@ public class CommentAddedEventIT extends AbstractDaemonTest {
// push a new change with -1 vote
PushOneCommit.Result r = createChange();
ReviewInput reviewInput = new ReviewInput().label(
label.getName(), (short)-1);
ReviewInput reviewInput = new ReviewInput().label(label.getName(), (short) -1);
revision(r).review(reviewInput);
ApprovalValues attr = getApprovalValues(label);
assertThat(attr.oldValue).isEqualTo(0);
assertThat(attr.value).isEqualTo(-1);
assertThat(lastCommentAddedEvent.getComment()).isEqualTo(
String.format("Patch Set 1: %s-1", label.getName()));
assertThat(lastCommentAddedEvent.getComment())
.isEqualTo(String.format("Patch Set 1: %s-1", label.getName()));
}
@Test
@@ -134,14 +126,13 @@ public class CommentAddedEventIT extends AbstractDaemonTest {
// push a new revision with +1 vote
ChangeInfo c = get(r.getChangeId());
r = amendChange(c.changeId);
reviewInput = new ReviewInput().label(
label.getName(), (short)1);
reviewInput = new ReviewInput().label(label.getName(), (short) 1);
revision(r).review(reviewInput);
ApprovalValues attr = getApprovalValues(label);
assertThat(attr.oldValue).isEqualTo(0);
assertThat(attr.value).isEqualTo(1);
assertThat(lastCommentAddedEvent.getComment()).isEqualTo(
String.format("Patch Set 2: %s+1", label.getName()));
assertThat(lastCommentAddedEvent.getComment())
.isEqualTo(String.format("Patch Set 2: %s+1", label.getName()));
}
@Test
@@ -158,8 +149,8 @@ public class CommentAddedEventIT extends AbstractDaemonTest {
ApprovalValues attr = getApprovalValues(label);
assertThat(attr.oldValue).isNull();
assertThat(attr.value).isEqualTo(0);
assertThat(lastCommentAddedEvent.getComment()).isEqualTo(
String.format("Patch Set 1:\n\n%s", label.getName()));
assertThat(lastCommentAddedEvent.getComment())
.isEqualTo(String.format("Patch Set 1:\n\n%s", label.getName()));
// transition from un-voted to -1 vote
reviewInput = new ReviewInput().label(label.getName(), -1);
@@ -167,8 +158,8 @@ public class CommentAddedEventIT extends AbstractDaemonTest {
attr = getApprovalValues(label);
assertThat(attr.oldValue).isEqualTo(0);
assertThat(attr.value).isEqualTo(-1);
assertThat(lastCommentAddedEvent.getComment()).isEqualTo(
String.format("Patch Set 1: %s-1", label.getName()));
assertThat(lastCommentAddedEvent.getComment())
.isEqualTo(String.format("Patch Set 1: %s-1", label.getName()));
// transition vote from -1 to 0
reviewInput = new ReviewInput().label(label.getName(), 0);
@@ -176,8 +167,8 @@ public class CommentAddedEventIT extends AbstractDaemonTest {
attr = getApprovalValues(label);
assertThat(attr.oldValue).isEqualTo(-1);
assertThat(attr.value).isEqualTo(0);
assertThat(lastCommentAddedEvent.getComment()).isEqualTo(
String.format("Patch Set 1: -%s", label.getName()));
assertThat(lastCommentAddedEvent.getComment())
.isEqualTo(String.format("Patch Set 1: -%s", label.getName()));
// transition vote from 0 to 1
reviewInput = new ReviewInput().label(label.getName(), 1);
@@ -185,8 +176,8 @@ public class CommentAddedEventIT extends AbstractDaemonTest {
attr = getApprovalValues(label);
assertThat(attr.oldValue).isEqualTo(0);
assertThat(attr.value).isEqualTo(1);
assertThat(lastCommentAddedEvent.getComment()).isEqualTo(
String.format("Patch Set 1: %s+1", label.getName()));
assertThat(lastCommentAddedEvent.getComment())
.isEqualTo(String.format("Patch Set 1: %s+1", label.getName()));
// transition vote from 1 to -1
reviewInput = new ReviewInput().label(label.getName(), -1);
@@ -194,17 +185,17 @@ public class CommentAddedEventIT extends AbstractDaemonTest {
attr = getApprovalValues(label);
assertThat(attr.oldValue).isEqualTo(1);
assertThat(attr.value).isEqualTo(-1);
assertThat(lastCommentAddedEvent.getComment()).isEqualTo(
String.format("Patch Set 1: %s-1", label.getName()));
assertThat(lastCommentAddedEvent.getComment())
.isEqualTo(String.format("Patch Set 1: %s-1", label.getName()));
// review with message only, do not apply votes
reviewInput = new ReviewInput().message(label.getName());
revision(r).review(reviewInput);
attr = getApprovalValues(label);
assertThat(attr.oldValue).isNull(); // no vote change so not included
assertThat(attr.oldValue).isNull(); // no vote change so not included
assertThat(attr.value).isEqualTo(-1);
assertThat(lastCommentAddedEvent.getComment()).isEqualTo(
String.format("Patch Set 1:\n\n%s", label.getName()));
assertThat(lastCommentAddedEvent.getComment())
.isEqualTo(String.format("Patch Set 1:\n\n%s", label.getName()));
}
@Test
@@ -221,9 +212,8 @@ public class CommentAddedEventIT extends AbstractDaemonTest {
ApprovalValues labelAttr = getApprovalValues(label);
assertThat(labelAttr.oldValue).isEqualTo(0);
assertThat(labelAttr.value).isEqualTo(-1);
assertThat(lastCommentAddedEvent.getComment()).isEqualTo(
String.format("Patch Set 1: %s-1\n\n%s",
label.getName(), label.getName()));
assertThat(lastCommentAddedEvent.getComment())
.isEqualTo(String.format("Patch Set 1: %s-1\n\n%s", label.getName(), label.getName()));
// there should be 3 approval labels (label, pLabel, and CRVV)
assertThat(lastCommentAddedEvent.getApprovals()).hasSize(3);
@@ -249,9 +239,8 @@ public class CommentAddedEventIT extends AbstractDaemonTest {
pLabelAttr = getApprovalValues(pLabel);
assertThat(pLabelAttr.oldValue).isEqualTo(0);
assertThat(pLabelAttr.value).isEqualTo(1);
assertThat(lastCommentAddedEvent.getComment()).isEqualTo(
String.format("Patch Set 1: %s+1\n\n%s",
pLabel.getName(), pLabel.getName()));
assertThat(lastCommentAddedEvent.getComment())
.isEqualTo(String.format("Patch Set 1: %s+1\n\n%s", pLabel.getName(), pLabel.getName()));
// check the approvals that were not voted on
labelAttr = getApprovalValues(label);

View File

@@ -21,20 +21,17 @@ import com.google.gerrit.acceptance.NoHttpd;
import com.google.gerrit.server.mail.receive.MailReceiver;
import com.google.gerrit.testutil.ConfigSuite;
import com.google.inject.Inject;
import com.icegreen.greenmail.junit.GreenMailRule;
import com.icegreen.greenmail.user.GreenMailUser;
import com.icegreen.greenmail.util.GreenMail;
import com.icegreen.greenmail.util.GreenMailUtil;
import com.icegreen.greenmail.util.ServerSetupTest;
import javax.mail.internet.MimeMessage;
import org.eclipse.jgit.lib.Config;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import javax.mail.internet.MimeMessage;
@NoHttpd
@RunWith(ConfigSuite.class)
public class MailIT extends AbstractDaemonTest {
@@ -43,15 +40,12 @@ public class MailIT extends AbstractDaemonTest {
private static final String USERNAME = "user@domain.com";
private static final String PASSWORD = "password";
@Inject
private MailReceiver mailReceiver;
@Inject private MailReceiver mailReceiver;
@Inject
private GreenMail greenMail;
@Inject private GreenMail greenMail;
@Rule
public final GreenMailRule mockPop3Server = new GreenMailRule(
ServerSetupTest.SMTP_POP3_IMAP);
public final GreenMailRule mockPop3Server = new GreenMailRule(ServerSetupTest.SMTP_POP3_IMAP);
@ConfigSuite.Default
public static Config pop3Config() {
@@ -87,8 +81,7 @@ public class MailIT extends AbstractDaemonTest {
// Check that the message is still present
assertThat(mockPop3Server.getReceivedMessages().length).isEqualTo(1);
// Mark the message for deletion
mailReceiver.requestDeletion(
mockPop3Server.getReceivedMessages()[0].getMessageID());
mailReceiver.requestDeletion(mockPop3Server.getReceivedMessages()[0].getMessageID());
// Let Gerrit handle emails
mailReceiver.handleEmails(false);
// Check that the message was deleted
@@ -96,9 +89,7 @@ public class MailIT extends AbstractDaemonTest {
}
private MimeMessage createSimpleMessage() {
return GreenMailUtil
.createTextEmail(USERNAME, "from@localhost.com", "subject",
"body",
greenMail.getImap().getServerSetup());
return GreenMailUtil.createTextEmail(
USERNAME, "from@localhost.com", "subject", "body", greenMail.getImap().getServerSetup());
}
}

View File

@@ -26,11 +26,6 @@ import com.google.gerrit.server.mail.MailUtil;
import com.google.gerrit.server.mail.send.EmailHeader;
import com.google.gerrit.testutil.FakeEmailSender;
import com.google.gerrit.testutil.TestTimeUtil;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.sql.Timestamp;
import java.time.ZoneId;
import java.time.ZonedDateTime;
@@ -39,6 +34,9 @@ import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
/** Tests the presence of required metadata in email headers, text and html. */
public class MailMetadataIT extends AbstractDaemonTest {
@@ -59,16 +57,13 @@ public class MailMetadataIT extends AbstractDaemonTest {
@Test
public void metadataOnNewChange() throws Exception {
PushOneCommit.Result newChange = createChange();
gApi.changes()
.id(newChange.getChangeId())
.addReviewer(user.getId().toString());
gApi.changes().id(newChange.getChangeId()).addReviewer(user.getId().toString());
List<FakeEmailSender.Message> emails = sender.getMessages();
assertThat(emails).hasSize(1);
FakeEmailSender.Message message = emails.get(0);
String changeURL = "<" + canonicalWebUrl.get() +
newChange.getChange().getId().get() + ">";
String changeURL = "<" + canonicalWebUrl.get() + newChange.getChange().getId().get() + ">";
Map<String, Object> expectedHeaders = new HashMap<>();
expectedHeaders.put("Gerrit-PatchSet", "1");
@@ -88,9 +83,7 @@ public class MailMetadataIT extends AbstractDaemonTest {
@Test
public void metadataOnNewComment() throws Exception {
PushOneCommit.Result newChange = createChange();
gApi.changes()
.id(newChange.getChangeId())
.addReviewer(user.getId().toString());
gApi.changes().id(newChange.getChangeId()).addReviewer(user.getId().toString());
sender.clear();
// Review change
@@ -106,17 +99,14 @@ public class MailMetadataIT extends AbstractDaemonTest {
assertThat(emails).hasSize(1);
FakeEmailSender.Message message = emails.get(0);
String changeURL = "<" + canonicalWebUrl.get() +
newChange.getChange().getId().get() + ">";
String changeURL = "<" + canonicalWebUrl.get() + newChange.getChange().getId().get() + ">";
Map<String, Object> expectedHeaders = new HashMap<>();
expectedHeaders.put("Gerrit-PatchSet", "1");
expectedHeaders.put("Gerrit-Change-Id", newChange.getChangeId());
expectedHeaders.put("Gerrit-MessageType", "comment");
expectedHeaders.put("Gerrit-Commit",
newChange.getCommit().getId().name());
expectedHeaders.put("Gerrit-Commit", newChange.getCommit().getId().name());
expectedHeaders.put("Gerrit-ChangeURL", changeURL);
expectedHeaders.put("Gerrit-Comment-Date",
Iterables.getLast(result).date);
expectedHeaders.put("Gerrit-Comment-Date", Iterables.getLast(result).date);
assertHeaders(message.headers(), expectedHeaders);
@@ -126,39 +116,44 @@ public class MailMetadataIT extends AbstractDaemonTest {
assertTextFooter(message.body(), expectedHeaders);
}
private static void assertHeaders(Map<String, EmailHeader> have,
Map<String, Object> want) throws Exception {
private static void assertHeaders(Map<String, EmailHeader> have, Map<String, Object> want)
throws Exception {
for (Map.Entry<String, Object> entry : want.entrySet()) {
if (entry.getValue() instanceof String) {
assertThat(have).containsEntry("X-" + entry.getKey(),
new EmailHeader.String((String) entry.getValue()));
assertThat(have)
.containsEntry(
"X-" + entry.getKey(), new EmailHeader.String((String) entry.getValue()));
} else if (entry.getValue() instanceof Date) {
assertThat(have).containsEntry("X-" + entry.getKey(),
new EmailHeader.Date((Date) entry.getValue()));
assertThat(have)
.containsEntry("X-" + entry.getKey(), new EmailHeader.Date((Date) entry.getValue()));
} else {
throw new Exception("Object has unsupported type: " +
entry.getValue().getClass().getName() +
" must be java.util.Date or java.lang.String for key " +
entry.getKey());
throw new Exception(
"Object has unsupported type: "
+ entry.getValue().getClass().getName()
+ " must be java.util.Date or java.lang.String for key "
+ entry.getKey());
}
}
}
private static void assertTextFooter(String body,
Map<String, Object> want) throws Exception {
private static void assertTextFooter(String body, Map<String, Object> want) throws Exception {
for (Map.Entry<String, Object> entry : want.entrySet()) {
if (entry.getValue() instanceof String) {
assertThat(body).contains(entry.getKey() + ": " + entry.getValue());
} else if (entry.getValue() instanceof Timestamp) {
assertThat(body).contains(entry.getKey() + ": " +
MailUtil.rfcDateformatter.format(ZonedDateTime.ofInstant(
((Timestamp) entry.getValue()).toInstant(),
ZoneId.of("UTC"))));
assertThat(body)
.contains(
entry.getKey()
+ ": "
+ MailUtil.rfcDateformatter.format(
ZonedDateTime.ofInstant(
((Timestamp) entry.getValue()).toInstant(), ZoneId.of("UTC"))));
} else {
throw new Exception("Object has unsupported type: " +
entry.getValue().getClass().getName() +
" must be java.util.Date or java.lang.String for key " +
entry.getKey());
throw new Exception(
"Object has unsupported type: "
+ entry.getValue().getClass().getName()
+ " must be java.util.Date or java.lang.String for key "
+ entry.getKey());
}
}
}

View File

@@ -32,111 +32,108 @@ import com.google.gerrit.server.mail.MailUtil;
import com.google.gerrit.server.mail.receive.MailMessage;
import com.google.gerrit.server.mail.receive.MailProcessor;
import com.google.inject.Inject;
import org.joda.time.DateTime;
import org.junit.Test;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import org.joda.time.DateTime;
import org.junit.Test;
public class MailProcessorIT extends AbstractDaemonTest {
@Inject
private MailProcessor mailProcessor;
@Inject private MailProcessor mailProcessor;
@Test
public void parseAndPersistChangeMessage() throws Exception {
String changeId = createChangeWithReview();
ChangeInfo changeInfo = gApi.changes().id(changeId).get();
List<CommentInfo> comments = gApi.changes().id(changeId)
.current().commentsAsList();
String ts = MailUtil.rfcDateformatter.format(ZonedDateTime.ofInstant(
comments.get(0).updated.toInstant(),
ZoneId.of("UTC")));
List<CommentInfo> comments = gApi.changes().id(changeId).current().commentsAsList();
String ts =
MailUtil.rfcDateformatter.format(
ZonedDateTime.ofInstant(comments.get(0).updated.toInstant(), ZoneId.of("UTC")));
// Build Message
MailMessage.Builder b = messageBuilderWithDefaultFields();
String txt = newPlaintextBody(canonicalWebUrl.get() + "#/c/" +
changeInfo._number + "/1", "Test Message", null, null, null);
String txt =
newPlaintextBody(
canonicalWebUrl.get() + "#/c/" + changeInfo._number + "/1",
"Test Message",
null,
null,
null);
b.textContent(txt + textFooterForChange(changeId, ts));
mailProcessor.process(b.build());
Collection<ChangeMessageInfo> messages =
gApi.changes().id(changeId).get().messages;
Collection<ChangeMessageInfo> messages = gApi.changes().id(changeId).get().messages;
assertThat(messages).hasSize(3);
assertThat(Iterables.getLast(messages).message)
.isEqualTo("Patch Set 1:\nTest Message");
assertThat(Iterables.getLast(messages).tag)
.isEqualTo("mailMessageId=some id");
assertThat(Iterables.getLast(messages).message).isEqualTo("Patch Set 1:\nTest Message");
assertThat(Iterables.getLast(messages).tag).isEqualTo("mailMessageId=some id");
}
@Test
public void parseAndPersistInlineComment() throws Exception {
String changeId = createChangeWithReview();
ChangeInfo changeInfo = gApi.changes().id(changeId).get();
List<CommentInfo> comments = gApi.changes().id(changeId)
.current().commentsAsList();
String ts = MailUtil.rfcDateformatter.format(ZonedDateTime.ofInstant(
comments.get(0).updated.toInstant(),
ZoneId.of("UTC")));
List<CommentInfo> comments = gApi.changes().id(changeId).current().commentsAsList();
String ts =
MailUtil.rfcDateformatter.format(
ZonedDateTime.ofInstant(comments.get(0).updated.toInstant(), ZoneId.of("UTC")));
// Build Message
MailMessage.Builder b = messageBuilderWithDefaultFields();
String txt = newPlaintextBody(canonicalWebUrl.get() + "#/c/" +
changeInfo._number + "/1", null, "Some Inline Comment", null, null);
String txt =
newPlaintextBody(
canonicalWebUrl.get() + "#/c/" + changeInfo._number + "/1",
null,
"Some Inline Comment",
null,
null);
b.textContent(txt + textFooterForChange(changeId, ts));
mailProcessor.process(b.build());
// Assert messages
Collection<ChangeMessageInfo> messages =
gApi.changes().id(changeId).get().messages;
Collection<ChangeMessageInfo> messages = gApi.changes().id(changeId).get().messages;
assertThat(messages).hasSize(3);
assertThat(Iterables.getLast(messages).message)
.isEqualTo("Patch Set 1:\n(1 comment)");
assertThat(Iterables.getLast(messages).tag)
.isEqualTo("mailMessageId=some id");
assertThat(Iterables.getLast(messages).message).isEqualTo("Patch Set 1:\n(1 comment)");
assertThat(Iterables.getLast(messages).tag).isEqualTo("mailMessageId=some id");
// Assert comment
comments = gApi.changes().id(changeId).current().commentsAsList();
assertThat(comments).hasSize(3);
assertThat(comments.get(2).message)
.isEqualTo("Some Inline Comment");
assertThat(comments.get(2).tag)
.isEqualTo("mailMessageId=some id");
assertThat(comments.get(2).inReplyTo)
.isEqualTo(comments.get(1).id);
assertThat(comments.get(2).message).isEqualTo("Some Inline Comment");
assertThat(comments.get(2).tag).isEqualTo("mailMessageId=some id");
assertThat(comments.get(2).inReplyTo).isEqualTo(comments.get(1).id);
}
@Test
public void parseAndPersistFileComment() throws Exception {
String changeId = createChangeWithReview();
ChangeInfo changeInfo = gApi.changes().id(changeId).get();
List<CommentInfo> comments = gApi.changes().id(changeId)
.current().commentsAsList();
String ts = MailUtil.rfcDateformatter.format(ZonedDateTime.ofInstant(
comments.get(0).updated.toInstant(),
ZoneId.of("UTC")));
List<CommentInfo> comments = gApi.changes().id(changeId).current().commentsAsList();
String ts =
MailUtil.rfcDateformatter.format(
ZonedDateTime.ofInstant(comments.get(0).updated.toInstant(), ZoneId.of("UTC")));
// Build Message
MailMessage.Builder b = messageBuilderWithDefaultFields();
String txt = newPlaintextBody(canonicalWebUrl.get() + "#/c/" +
changeInfo._number + "/1", null, null, "Some Comment on File 1", null);
String txt =
newPlaintextBody(
canonicalWebUrl.get() + "#/c/" + changeInfo._number + "/1",
null,
null,
"Some Comment on File 1",
null);
b.textContent(txt + textFooterForChange(changeId, ts));
mailProcessor.process(b.build());
// Assert messages
Collection<ChangeMessageInfo> messages =
gApi.changes().id(changeId).get().messages;
Collection<ChangeMessageInfo> messages = gApi.changes().id(changeId).get().messages;
assertThat(messages).hasSize(3);
assertThat(Iterables.getLast(messages).message)
.isEqualTo("Patch Set 1:\n(1 comment)");
assertThat(Iterables.getLast(messages).tag)
.isEqualTo("mailMessageId=some id");
assertThat(Iterables.getLast(messages).message).isEqualTo("Patch Set 1:\n(1 comment)");
assertThat(Iterables.getLast(messages).tag).isEqualTo("mailMessageId=some id");
// Assert comment
comments = gApi.changes().id(changeId).current().commentsAsList();
@@ -151,16 +148,20 @@ public class MailProcessorIT extends AbstractDaemonTest {
public void parseAndPersistMessageTwice() throws Exception {
String changeId = createChangeWithReview();
ChangeInfo changeInfo = gApi.changes().id(changeId).get();
List<CommentInfo> comments = gApi.changes().id(changeId)
.current().commentsAsList();
String ts = MailUtil.rfcDateformatter.format(ZonedDateTime.ofInstant(
comments.get(0).updated.toInstant(),
ZoneId.of("UTC")));
List<CommentInfo> comments = gApi.changes().id(changeId).current().commentsAsList();
String ts =
MailUtil.rfcDateformatter.format(
ZonedDateTime.ofInstant(comments.get(0).updated.toInstant(), ZoneId.of("UTC")));
// Build Message
MailMessage.Builder b = messageBuilderWithDefaultFields();
String txt = newPlaintextBody(canonicalWebUrl.get() + "#/c/" +
changeInfo._number + "/1", null, "Some Inline Comment", null, null);
String txt =
newPlaintextBody(
canonicalWebUrl.get() + "#/c/" + changeInfo._number + "/1",
null,
"Some Inline Comment",
null,
null);
b.textContent(txt + textFooterForChange(changeId, ts));
mailProcessor.process(b.build());
@@ -177,17 +178,21 @@ public class MailProcessorIT extends AbstractDaemonTest {
public void parseAndPersistMessageFromInactiveAccount() throws Exception {
String changeId = createChangeWithReview();
ChangeInfo changeInfo = gApi.changes().id(changeId).get();
List<CommentInfo> comments = gApi.changes().id(changeId)
.current().commentsAsList();
String ts = MailUtil.rfcDateformatter.format(ZonedDateTime.ofInstant(
comments.get(0).updated.toInstant(),
ZoneId.of("UTC")));
List<CommentInfo> comments = gApi.changes().id(changeId).current().commentsAsList();
String ts =
MailUtil.rfcDateformatter.format(
ZonedDateTime.ofInstant(comments.get(0).updated.toInstant(), ZoneId.of("UTC")));
assertThat(comments).hasSize(2);
// Build Message
MailMessage.Builder b = messageBuilderWithDefaultFields();
String txt = newPlaintextBody(canonicalWebUrl.get() + "#/c/" +
changeInfo._number + "/1", null, "Some Inline Comment", null, null);
String txt =
newPlaintextBody(
canonicalWebUrl.get() + "#/c/" + changeInfo._number + "/1",
null,
"Some Inline Comment",
null,
null);
b.textContent(txt + textFooterForChange(changeId, ts));
// Set account state to inactive
@@ -203,8 +208,7 @@ public class MailProcessorIT extends AbstractDaemonTest {
gApi.accounts().id("user").setActive(true);
}
private static CommentInput newComment(String path, Side side, int line,
String message) {
private static CommentInput newComment(String path, Side side, int line, String message) {
CommentInput c = new CommentInput();
c.path = path;
c.side = side;
@@ -230,46 +234,58 @@ public class MailProcessorIT extends AbstractDaemonTest {
* @param fc1 Comment in reply to a comment of file 1.
* @return A string with all inline comments and the original quoted email.
*/
private static String newPlaintextBody(String changeURL, String changeMessage,
String c1, String f1, String fc1) {
return (changeMessage == null ? "" : changeMessage + "\n") +
"> Foo Bar has posted comments on this change. ( \n" +
"> " + changeURL +" )\n" +
"> \n" +
"> Change subject: Test change\n" +
"> ...............................................................\n" +
"> \n" +
"> \n" +
"> Patch Set 1: Code-Review+1\n" +
"> \n" +
"> (3 comments)\n" +
"> \n" +
"> " + changeURL + "/gerrit-server/test.txt\n" +
"> File \n" +
"> gerrit-server/test.txt:\n" +
(f1 == null ? "" : f1 + "\n") +
"> \n" +
"> Patch Set #4:\n" +
"> " + changeURL + "/gerrit-server/test.txt\n" +
"> \n" +
"> Some comment" +
"> \n" +
(fc1 == null ? "" : fc1 + "\n") +
"> " + changeURL + "/gerrit-server/test.txt@2\n" +
"> PS1, Line 2: throw new Exception(\"Object has unsupported: \" +\n" +
"> : entry.getValue() +\n" +
"> : \" must be java.util.Date\");\n" +
"> Should entry.getKey() be included in this message?\n" +
"> \n" +
(c1 == null ? "" : c1 + "\n") +
"> \n";
private static String newPlaintextBody(
String changeURL, String changeMessage, String c1, String f1, String fc1) {
return (changeMessage == null ? "" : changeMessage + "\n")
+ "> Foo Bar has posted comments on this change. ( \n"
+ "> "
+ changeURL
+ " )\n"
+ "> \n"
+ "> Change subject: Test change\n"
+ "> ...............................................................\n"
+ "> \n"
+ "> \n"
+ "> Patch Set 1: Code-Review+1\n"
+ "> \n"
+ "> (3 comments)\n"
+ "> \n"
+ "> "
+ changeURL
+ "/gerrit-server/test.txt\n"
+ "> File \n"
+ "> gerrit-server/test.txt:\n"
+ (f1 == null ? "" : f1 + "\n")
+ "> \n"
+ "> Patch Set #4:\n"
+ "> "
+ changeURL
+ "/gerrit-server/test.txt\n"
+ "> \n"
+ "> Some comment"
+ "> \n"
+ (fc1 == null ? "" : fc1 + "\n")
+ "> "
+ changeURL
+ "/gerrit-server/test.txt@2\n"
+ "> PS1, Line 2: throw new Exception(\"Object has unsupported: \" +\n"
+ "> : entry.getValue() +\n"
+ "> : \" must be java.util.Date\");\n"
+ "> Should entry.getKey() be included in this message?\n"
+ "> \n"
+ (c1 == null ? "" : c1 + "\n")
+ "> \n";
}
private static String textFooterForChange(String changeId, String timestamp) {
return "Gerrit-Change-Id: " + changeId + "\n" +
"Gerrit-PatchSet: 1\n" +
"Gerrit-MessageType: comment\n" +
"Gerrit-Comment-Date: " + timestamp + "\n";
return "Gerrit-Change-Id: "
+ changeId
+ "\n"
+ "Gerrit-PatchSet: 1\n"
+ "Gerrit-MessageType: comment\n"
+ "Gerrit-Comment-Date: "
+ timestamp
+ "\n";
}
private MailMessage.Builder messageBuilderWithDefaultFields() {
@@ -287,8 +303,8 @@ public class MailProcessorIT extends AbstractDaemonTest {
// Create change
String file = "gerrit-server/test.txt";
String contents = "contents \nlorem \nipsum \nlorem";
PushOneCommit push = pushFactory.create(db, admin.getIdent(), testRepo,
"first subject", file, contents);
PushOneCommit push =
pushFactory.create(db, admin.getIdent(), testRepo, "first subject", file, contents);
PushOneCommit.Result r = push.to("refs/for/master");
String changeId = r.getChangeId();

View File

@@ -89,7 +89,13 @@ import com.google.gwtorm.server.OrmException;
import com.google.gwtorm.server.OrmRuntimeException;
import com.google.inject.Inject;
import com.google.inject.Provider;
import java.sql.Timestamp;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import org.apache.http.Header;
import org.apache.http.message.BasicHeader;
import org.eclipse.jgit.junit.TestRepository;
@@ -103,14 +109,6 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.sql.Timestamp;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
public class ChangeRebuilderIT extends AbstractDaemonTest {
@ConfigSuite.Default
public static Config defaultConfig() {
@@ -126,38 +124,27 @@ public class ChangeRebuilderIT extends AbstractDaemonTest {
return cfg;
}
@Inject
private AllUsersName allUsers;
@Inject private AllUsersName allUsers;
@Inject
private NoteDbChecker checker;
@Inject private NoteDbChecker checker;
@Inject
private Rebuild rebuildHandler;
@Inject private Rebuild rebuildHandler;
@Inject
private Provider<ReviewDb> dbProvider;
@Inject private Provider<ReviewDb> dbProvider;
@Inject
private CommentsUtil commentsUtil;
@Inject private CommentsUtil commentsUtil;
@Inject
private Provider<PostReview> postReview;
@Inject private Provider<PostReview> postReview;
@Inject
private TestChangeRebuilderWrapper rebuilderWrapper;
@Inject private TestChangeRebuilderWrapper rebuilderWrapper;
@Inject
private BatchUpdate.Factory batchUpdateFactory;
@Inject private BatchUpdate.Factory batchUpdateFactory;
@Inject
private Sequences seq;
@Inject private Sequences seq;
@Inject
private ChangeBundleReader bundleReader;
@Inject private ChangeBundleReader bundleReader;
@Inject
private PatchSetInfoFactory patchSetInfoFactory;
@Inject private PatchSetInfoFactory patchSetInfoFactory;
@Before
public void setUp() throws Exception {
@@ -172,8 +159,7 @@ public class ChangeRebuilderIT extends AbstractDaemonTest {
}
@SuppressWarnings("deprecation")
private void setNotesMigration(boolean writeChanges, boolean readChanges)
throws Exception {
private void setNotesMigration(boolean writeChanges, boolean readChanges) throws Exception {
notesMigration.setWriteChanges(writeChanges);
notesMigration.setReadChanges(readChanges);
db = atrScope.reopenDb().getReviewDbProvider().get();
@@ -228,9 +214,9 @@ public class ChangeRebuilderIT extends AbstractDaemonTest {
Change c = TestChanges.newChange(project, user.getId(), seq.nextChangeId());
c.setCreatedOn(ts);
c.setLastUpdatedOn(ts);
PatchSet ps = TestChanges.newPatchSet(
c.currentPatchSetId(), "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef",
user.getId());
PatchSet ps =
TestChanges.newPatchSet(
c.currentPatchSetId(), "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef", user.getId());
ps.setCreatedOn(ts);
db.changes().insert(Collections.singleton(c));
db.patchSets().insert(Collections.singleton(ps));
@@ -272,8 +258,7 @@ public class ChangeRebuilderIT extends AbstractDaemonTest {
Change.Id id = psId.getParentKey();
// Events need to be otherwise identical for the account ID to be compared.
ChangeMessage msg1 =
insertMessage(id, psId, user.getId(), TimeUtil.nowTs(), "message 1");
ChangeMessage msg1 = insertMessage(id, psId, user.getId(), TimeUtil.nowTs(), "message 1");
insertMessage(id, psId, null, msg1.getWrittenOn(), "message 2");
checker.rebuildAndCheckChanges(id);
@@ -286,14 +271,12 @@ public class ChangeRebuilderIT extends AbstractDaemonTest {
Change.Id id = psId1.getParentKey();
// Events need to be otherwise identical for the PatchSet.ID to be compared.
ChangeMessage msg1 =
insertMessage(id, null, user.getId(), TimeUtil.nowTs(), "message 1");
ChangeMessage msg1 = insertMessage(id, null, user.getId(), TimeUtil.nowTs(), "message 1");
insertMessage(id, null, user.getId(), msg1.getWrittenOn(), "message 2");
PatchSet.Id psId2 = amendChange(r.getChangeId()).getPatchSetId();
ChangeMessage msg3 =
insertMessage(id, null, user.getId(), TimeUtil.nowTs(), "message 3");
ChangeMessage msg3 = insertMessage(id, null, user.getId(), TimeUtil.nowTs(), "message 3");
insertMessage(id, null, user.getId(), msg3.getWrittenOn(), "message 4");
checker.rebuildAndCheckChanges(id);
@@ -339,9 +322,7 @@ public class ChangeRebuilderIT extends AbstractDaemonTest {
public void restApiNotFoundWhenNoteDbDisabled() throws Exception {
PushOneCommit.Result r = createChange();
exception.expect(ResourceNotFoundException.class);
rebuildHandler.apply(
parseChangeResource(r.getChangeId()),
new Rebuild.Input());
rebuildHandler.apply(parseChangeResource(r.getChangeId()), new Rebuild.Input());
}
@Test
@@ -351,9 +332,7 @@ public class ChangeRebuilderIT extends AbstractDaemonTest {
setNotesMigration(true, false);
checker.assertNoChangeRef(project, id);
rebuildHandler.apply(
parseChangeResource(r.getChangeId()),
new Rebuild.Input());
rebuildHandler.apply(parseChangeResource(r.getChangeId()), new Rebuild.Input());
checker.checkChanges(id);
}
@@ -384,32 +363,41 @@ public class ChangeRebuilderIT extends AbstractDaemonTest {
Change.Id id = r.getPatchSetId().getParentKey();
ObjectId changeMetaId = getMetaRef(project, changeMetaRef(id));
assertThat(getUnwrappedDb().changes().get(id).getNoteDbState()).isEqualTo(
changeMetaId.name());
assertThat(getUnwrappedDb().changes().get(id).getNoteDbState()).isEqualTo(changeMetaId.name());
putDraft(user, id, 1, "comment by user", null);
ObjectId userDraftsId = getMetaRef(
allUsers, refsDraftComments(id, user.getId()));
assertThat(getUnwrappedDb().changes().get(id).getNoteDbState()).isEqualTo(
changeMetaId.name()
+ "," + user.getId() + "=" + userDraftsId.name());
ObjectId userDraftsId = getMetaRef(allUsers, refsDraftComments(id, user.getId()));
assertThat(getUnwrappedDb().changes().get(id).getNoteDbState())
.isEqualTo(changeMetaId.name() + "," + user.getId() + "=" + userDraftsId.name());
putDraft(admin, id, 2, "comment by admin", null);
ObjectId adminDraftsId = getMetaRef(
allUsers, refsDraftComments(id, admin.getId()));
ObjectId adminDraftsId = getMetaRef(allUsers, refsDraftComments(id, admin.getId()));
assertThat(admin.getId().get()).isLessThan(user.getId().get());
assertThat(getUnwrappedDb().changes().get(id).getNoteDbState()).isEqualTo(
changeMetaId.name()
+ "," + admin.getId() + "=" + adminDraftsId.name()
+ "," + user.getId() + "=" + userDraftsId.name());
assertThat(getUnwrappedDb().changes().get(id).getNoteDbState())
.isEqualTo(
changeMetaId.name()
+ ","
+ admin.getId()
+ "="
+ adminDraftsId.name()
+ ","
+ user.getId()
+ "="
+ userDraftsId.name());
putDraft(admin, id, 2, "revised comment by admin", null);
adminDraftsId = getMetaRef(
allUsers, refsDraftComments(id, admin.getId()));
assertThat(getUnwrappedDb().changes().get(id).getNoteDbState()).isEqualTo(
changeMetaId.name()
+ "," + admin.getId() + "=" + adminDraftsId.name()
+ "," + user.getId() + "=" + userDraftsId.name());
adminDraftsId = getMetaRef(allUsers, refsDraftComments(id, admin.getId()));
assertThat(getUnwrappedDb().changes().get(id).getNoteDbState())
.isEqualTo(
changeMetaId.name()
+ ","
+ admin.getId()
+ "="
+ adminDraftsId.name()
+ ","
+ user.getId()
+ "="
+ userDraftsId.name());
}
@Test
@@ -428,13 +416,12 @@ public class ChangeRebuilderIT extends AbstractDaemonTest {
// On next NoteDb read, the change is transparently rebuilt.
setNotesMigration(true, true);
assertThat(gApi.changes().id(id.get()).info().topic)
.isEqualTo(name("a-topic"));
assertThat(gApi.changes().id(id.get()).info().topic).isEqualTo(name("a-topic"));
assertChangeUpToDate(true, id);
// Check that the bundles are equal.
ChangeBundle actual = ChangeBundle.fromNotes(
commentsUtil, notesFactory.create(dbProvider.get(), project, id));
ChangeBundle actual =
ChangeBundle.fromNotes(commentsUtil, notesFactory.create(dbProvider.get(), project, id));
ChangeBundle expected = bundleReader.fromReviewDb(getUnwrappedDb(), id);
assertThat(actual.differencesFrom(expected)).isEmpty();
}
@@ -449,13 +436,11 @@ public class ChangeRebuilderIT extends AbstractDaemonTest {
// Update ReviewDb and NoteDb, then revert the corresponding NoteDb change
// to simulate it failing.
NoteDbChangeState oldState =
NoteDbChangeState.parse(getUnwrappedDb().changes().get(id));
NoteDbChangeState oldState = NoteDbChangeState.parse(getUnwrappedDb().changes().get(id));
String topic = name("a-topic");
gApi.changes().id(id.get()).topic(topic);
try (Repository repo = repoManager.openRepository(project)) {
new TestRepository<>(repo)
.update(RefNames.changeMetaRef(id), oldState.getChangeMetaId());
new TestRepository<>(repo).update(RefNames.changeMetaRef(id), oldState.getChangeMetaId());
}
assertChangeUpToDate(false, id);
@@ -465,21 +450,27 @@ public class ChangeRebuilderIT extends AbstractDaemonTest {
// executes. We simulate it here by using BatchUpdate directly and not going
// through an API handler.
final String msg = "message from BatchUpdate";
try (BatchUpdate bu = batchUpdateFactory.create(db, project,
identifiedUserFactory.create(user.getId()), TimeUtil.nowTs())) {
bu.addOp(id, new BatchUpdate.Op() {
@Override
public boolean updateChange(ChangeContext ctx) throws OrmException {
PatchSet.Id psId = ctx.getChange().currentPatchSetId();
ChangeMessage cm = new ChangeMessage(
new ChangeMessage.Key(id, ChangeUtil.messageUuid()),
ctx.getAccountId(), ctx.getWhen(), psId);
cm.setMessage(msg);
ctx.getDb().changeMessages().insert(Collections.singleton(cm));
ctx.getUpdate(psId).setChangeMessage(msg);
return true;
}
});
try (BatchUpdate bu =
batchUpdateFactory.create(
db, project, identifiedUserFactory.create(user.getId()), TimeUtil.nowTs())) {
bu.addOp(
id,
new BatchUpdate.Op() {
@Override
public boolean updateChange(ChangeContext ctx) throws OrmException {
PatchSet.Id psId = ctx.getChange().currentPatchSetId();
ChangeMessage cm =
new ChangeMessage(
new ChangeMessage.Key(id, ChangeUtil.messageUuid()),
ctx.getAccountId(),
ctx.getWhen(),
psId);
cm.setMessage(msg);
ctx.getDb().changeMessages().insert(Collections.singleton(cm));
ctx.getUpdate(psId).setChangeMessage(msg);
return true;
}
});
try {
bu.execute();
fail("expected update to fail");
@@ -527,20 +518,18 @@ public class ChangeRebuilderIT extends AbstractDaemonTest {
// background.
rebuilderWrapper.stealNextUpdate();
setNotesMigration(true, true);
assertThat(gApi.changes().id(id.get()).info().topic)
.isEqualTo(name("a-topic"));
assertThat(gApi.changes().id(id.get()).info().topic).isEqualTo(name("a-topic"));
assertChangeUpToDate(true, id);
// Check that the bundles are equal.
ChangeBundle actual = ChangeBundle.fromNotes(
commentsUtil, notesFactory.create(dbProvider.get(), project, id));
ChangeBundle actual =
ChangeBundle.fromNotes(commentsUtil, notesFactory.create(dbProvider.get(), project, id));
ChangeBundle expected = bundleReader.fromReviewDb(getUnwrappedDb(), id);
assertThat(actual.differencesFrom(expected)).isEmpty();
}
@Test
public void rebuildReturnsCorrectResultEvenIfSavingToNoteDbFailed()
throws Exception {
public void rebuildReturnsCorrectResultEvenIfSavingToNoteDbFailed() throws Exception {
setNotesMigration(true, true);
PushOneCommit.Result r = createChange();
@@ -575,8 +564,7 @@ public class ChangeRebuilderIT extends AbstractDaemonTest {
}
@Test
public void rebuildReturnsDraftResultWhenRebuildingInChangeNotesFails()
throws Exception {
public void rebuildReturnsDraftResultWhenRebuildingInChangeNotesFails() throws Exception {
setNotesMigration(true, true);
PushOneCommit.Result r = createChange();
@@ -584,24 +572,21 @@ public class ChangeRebuilderIT extends AbstractDaemonTest {
putDraft(user, id, 1, "comment by user", null);
assertChangeUpToDate(true, id);
ObjectId oldMetaId =
getMetaRef(allUsers, refsDraftComments(id, user.getId()));
ObjectId oldMetaId = getMetaRef(allUsers, refsDraftComments(id, user.getId()));
// Add a draft behind NoteDb's back.
setNotesMigration(false, false);
putDraft(user, id, 1, "second comment by user", null);
setInvalidNoteDbState(id);
assertDraftsUpToDate(false, id, user);
assertThat(getMetaRef(allUsers, refsDraftComments(id, user.getId())))
.isEqualTo(oldMetaId);
assertThat(getMetaRef(allUsers, refsDraftComments(id, user.getId()))).isEqualTo(oldMetaId);
// Force the next rebuild attempt to fail (in ChangeNotes).
rebuilderWrapper.failNextUpdate();
setNotesMigration(true, true);
ChangeNotes notes = notesFactory.create(dbProvider.get(), project, id);
notes.getDraftComments(user.getId());
assertThat(getMetaRef(allUsers, refsDraftComments(id, user.getId())))
.isEqualTo(oldMetaId);
assertThat(getMetaRef(allUsers, refsDraftComments(id, user.getId()))).isEqualTo(oldMetaId);
// Not up to date, but the actual returned state matches anyway.
assertDraftsUpToDate(false, id, user);
@@ -613,13 +598,11 @@ public class ChangeRebuilderIT extends AbstractDaemonTest {
notesFactory.create(dbProvider.get(), project, id);
assertChangeUpToDate(true, id);
assertDraftsUpToDate(true, id, user);
assertThat(getMetaRef(allUsers, refsDraftComments(id, user.getId())))
.isNotEqualTo(oldMetaId);
assertThat(getMetaRef(allUsers, refsDraftComments(id, user.getId()))).isNotEqualTo(oldMetaId);
}
@Test
public void rebuildReturnsDraftResultWhenRebuildingInDraftCommentNotesFails()
throws Exception {
public void rebuildReturnsDraftResultWhenRebuildingInDraftCommentNotesFails() throws Exception {
setNotesMigration(true, true);
PushOneCommit.Result r = createChange();
@@ -627,8 +610,7 @@ public class ChangeRebuilderIT extends AbstractDaemonTest {
putDraft(user, id, 1, "comment by user", null);
assertChangeUpToDate(true, id);
ObjectId oldMetaId =
getMetaRef(allUsers, refsDraftComments(id, user.getId()));
ObjectId oldMetaId = getMetaRef(allUsers, refsDraftComments(id, user.getId()));
// Add a draft behind NoteDb's back.
setNotesMigration(false, false);
@@ -637,30 +619,28 @@ public class ChangeRebuilderIT extends AbstractDaemonTest {
ReviewDb db = getUnwrappedDb();
Change c = db.changes().get(id);
// Leave change meta ID alone so DraftCommentNotes does the rebuild.
ObjectId badSha =
ObjectId.fromString("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef");
NoteDbChangeState bogusState = new NoteDbChangeState(
id,
PrimaryStorage.REVIEW_DB,
Optional.of(
NoteDbChangeState.RefState.create(
NoteDbChangeState.parse(c).getChangeMetaId(),
ImmutableMap.of(user.getId(), badSha))),
Optional.empty());
ObjectId badSha = ObjectId.fromString("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef");
NoteDbChangeState bogusState =
new NoteDbChangeState(
id,
PrimaryStorage.REVIEW_DB,
Optional.of(
NoteDbChangeState.RefState.create(
NoteDbChangeState.parse(c).getChangeMetaId(),
ImmutableMap.of(user.getId(), badSha))),
Optional.empty());
c.setNoteDbState(bogusState.toString());
db.changes().update(Collections.singleton(c));
assertDraftsUpToDate(false, id, user);
assertThat(getMetaRef(allUsers, refsDraftComments(id, user.getId())))
.isEqualTo(oldMetaId);
assertThat(getMetaRef(allUsers, refsDraftComments(id, user.getId()))).isEqualTo(oldMetaId);
// Force the next rebuild attempt to fail (in DraftCommentNotes).
rebuilderWrapper.failNextUpdate();
setNotesMigration(true, true);
ChangeNotes notes = notesFactory.create(dbProvider.get(), project, id);
notes.getDraftComments(user.getId());
assertThat(getMetaRef(allUsers, refsDraftComments(id, user.getId())))
.isEqualTo(oldMetaId);
assertThat(getMetaRef(allUsers, refsDraftComments(id, user.getId()))).isEqualTo(oldMetaId);
// Not up to date, but the actual returned state matches anyway.
assertChangeUpToDate(true, id);
@@ -670,12 +650,10 @@ public class ChangeRebuilderIT extends AbstractDaemonTest {
assertThat(actual.differencesFrom(expected)).isEmpty();
// Another rebuild attempt succeeds
notesFactory.create(dbProvider.get(), project, id)
.getDraftComments(user.getId());
notesFactory.create(dbProvider.get(), project, id).getDraftComments(user.getId());
assertChangeUpToDate(true, id);
assertDraftsUpToDate(true, id, user);
assertThat(getMetaRef(allUsers, refsDraftComments(id, user.getId())))
.isNotEqualTo(oldMetaId);
assertThat(getMetaRef(allUsers, refsDraftComments(id, user.getId()))).isNotEqualTo(oldMetaId);
}
@Test
@@ -696,8 +674,7 @@ public class ChangeRebuilderIT extends AbstractDaemonTest {
// On next NoteDb read, the drafts are transparently rebuilt.
setNotesMigration(true, true);
assertThat(gApi.changes().id(id.get()).current().drafts())
.containsKey(PushOneCommit.FILE_NAME);
assertThat(gApi.changes().id(id.get()).current().drafts()).containsKey(PushOneCommit.FILE_NAME);
assertDraftsUpToDate(true, id, user);
}
@@ -706,25 +683,26 @@ public class ChangeRebuilderIT extends AbstractDaemonTest {
// We don't have the code in our test harness to do signed pushes, so just
// use a hard-coded cert. This cert was actually generated by C git 2.2.0
// (albeit not for sending to Gerrit).
String cert = "certificate version 0.1\n"
+ "pusher Dave Borowitz <dborowitz@google.com> 1433954361 -0700\n"
+ "pushee git://localhost/repo.git\n"
+ "nonce 1433954361-bde756572d665bba81d8\n"
+ "\n"
+ "0000000000000000000000000000000000000000"
+ "b981a177396fb47345b7df3e4d3f854c6bea7"
+ "s/heads/master\n"
+ "-----BEGIN PGP SIGNATURE-----\n"
+ "Version: GnuPG v1\n"
+ "\n"
+ "iQEcBAABAgAGBQJVeGg5AAoJEPfTicJkUdPkUggH/RKAeI9/i/LduuiqrL/SSdIa\n"
+ "9tYaSqJKLbXz63M/AW4Sp+4u+dVCQvnAt/a35CVEnpZz6hN4Kn/tiswOWVJf4CO7\n"
+ "htNubGs5ZMwvD6sLYqKAnrM3WxV/2TbbjzjZW6Jkidz3jz/WRT4SmjGYiEO7aA+V\n"
+ "4ZdIS9f7sW5VsHHYlNThCA7vH8Uu48bUovFXyQlPTX0pToSgrWV3JnTxDNxfn3iG\n"
+ "IL0zTY/qwVCdXgFownLcs6J050xrrBWIKqfcWr3u4D2aCLyR0v+S/KArr7ulZygY\n"
+ "+SOklImn8TAZiNxhWtA6ens66IiammUkZYFv7SSzoPLFZT4dC84SmGPWgf94NoQ=\n"
+ "=XFeC\n"
+ "-----END PGP SIGNATURE-----\n";
String cert =
"certificate version 0.1\n"
+ "pusher Dave Borowitz <dborowitz@google.com> 1433954361 -0700\n"
+ "pushee git://localhost/repo.git\n"
+ "nonce 1433954361-bde756572d665bba81d8\n"
+ "\n"
+ "0000000000000000000000000000000000000000"
+ "b981a177396fb47345b7df3e4d3f854c6bea7"
+ "s/heads/master\n"
+ "-----BEGIN PGP SIGNATURE-----\n"
+ "Version: GnuPG v1\n"
+ "\n"
+ "iQEcBAABAgAGBQJVeGg5AAoJEPfTicJkUdPkUggH/RKAeI9/i/LduuiqrL/SSdIa\n"
+ "9tYaSqJKLbXz63M/AW4Sp+4u+dVCQvnAt/a35CVEnpZz6hN4Kn/tiswOWVJf4CO7\n"
+ "htNubGs5ZMwvD6sLYqKAnrM3WxV/2TbbjzjZW6Jkidz3jz/WRT4SmjGYiEO7aA+V\n"
+ "4ZdIS9f7sW5VsHHYlNThCA7vH8Uu48bUovFXyQlPTX0pToSgrWV3JnTxDNxfn3iG\n"
+ "IL0zTY/qwVCdXgFownLcs6J050xrrBWIKqfcWr3u4D2aCLyR0v+S/KArr7ulZygY\n"
+ "+SOklImn8TAZiNxhWtA6ens66IiammUkZYFv7SSzoPLFZT4dC84SmGPWgf94NoQ=\n"
+ "=XFeC\n"
+ "-----END PGP SIGNATURE-----\n";
PushOneCommit.Result r = createChange();
PatchSet.Id psId = r.getPatchSetId();
@@ -799,14 +777,20 @@ public class ChangeRebuilderIT extends AbstractDaemonTest {
}
@Test
public void noteDbUsesOriginalSubjectFromPatchSetAndIgnoresChangeField()
throws Exception {
public void noteDbUsesOriginalSubjectFromPatchSetAndIgnoresChangeField() throws Exception {
PushOneCommit.Result r = createChange();
String orig = r.getChange().change().getSubject();
r = pushFactory.create(
db, admin.getIdent(), testRepo, orig + " v2",
PushOneCommit.FILE_NAME, "new contents", r.getChangeId())
.to("refs/heads/master");
r =
pushFactory
.create(
db,
admin.getIdent(),
testRepo,
orig + " v2",
PushOneCommit.FILE_NAME,
"new contents",
r.getChangeId())
.to("refs/heads/master");
r.assertOkStatus();
PatchSet.Id psId = r.getPatchSetId();
@@ -831,8 +815,15 @@ public class ChangeRebuilderIT extends AbstractDaemonTest {
public void deleteDraftPS1WithNoOtherEntities() throws Exception {
PushOneCommit push = pushFactory.create(db, admin.getIdent(), testRepo);
PushOneCommit.Result r = push.to("refs/drafts/master");
push = pushFactory.create(db, admin.getIdent(), testRepo,
PushOneCommit.SUBJECT, "b.txt", "4711", r.getChangeId());
push =
pushFactory.create(
db,
admin.getIdent(),
testRepo,
PushOneCommit.SUBJECT,
"b.txt",
"4711",
r.getChangeId());
r = push.to("refs/drafts/master");
PatchSet.Id psId = r.getPatchSetId();
Change.Id id = psId.getParentKey();
@@ -852,11 +843,14 @@ public class ChangeRebuilderIT extends AbstractDaemonTest {
Change change = r.getChange().change();
Change.Id id = change.getId();
PatchLineComment comment = new PatchLineComment(
new PatchLineComment.Key(
new Patch.Key(new PatchSet.Id(id, 0), PushOneCommit.FILE_NAME),
"uuid"),
0, user.getId(), null, TimeUtil.nowTs());
PatchLineComment comment =
new PatchLineComment(
new PatchLineComment.Key(
new Patch.Key(new PatchSet.Id(id, 0), PushOneCommit.FILE_NAME), "uuid"),
0,
user.getId(),
null,
TimeUtil.nowTs());
comment.setSide((short) 1);
comment.setMessage("message");
comment.setStatus(PatchLineComment.Status.PUBLISHED);
@@ -873,8 +867,14 @@ public class ChangeRebuilderIT extends AbstractDaemonTest {
@Test
public void leadingSpacesInSubject() throws Exception {
String subj = " " + PushOneCommit.SUBJECT;
PushOneCommit push = pushFactory.create(db, admin.getIdent(), testRepo,
subj, PushOneCommit.FILE_NAME, PushOneCommit.FILE_CONTENT);
PushOneCommit push =
pushFactory.create(
db,
admin.getIdent(),
testRepo,
subj,
PushOneCommit.FILE_NAME,
PushOneCommit.FILE_CONTENT);
PushOneCommit.Result r = push.to("refs/for/master");
r.assertOkStatus();
Change change = r.getChange().change();
@@ -906,11 +906,9 @@ public class ChangeRebuilderIT extends AbstractDaemonTest {
oldDb.changes().update(Collections.singleton(c));
c = oldDb.changes().get(c.getId());
ChangeNotes newNotes =
notesFactory.createWithAutoRebuildingDisabled(c, null);
ChangeNotes newNotes = notesFactory.createWithAutoRebuildingDisabled(c, null);
assertThat(newNotes.getChange().getTopic()).isNotEqualTo(topic);
assertThat(newNotes.getChange().getTopic())
.isEqualTo(oldNotes.getChange().getTopic());
assertThat(newNotes.getChange().getTopic()).isEqualTo(oldNotes.getChange().getTopic());
}
@Test
@@ -978,8 +976,7 @@ public class ChangeRebuilderIT extends AbstractDaemonTest {
// On next NoteDb read, change is rebuilt in-memory but not stored.
setNotesMigration(false, true);
assertThat(gApi.changes().id(id.get()).info().topic)
.isEqualTo(name("a-topic"));
assertThat(gApi.changes().id(id.get()).info().topic).isEqualTo(name("a-topic"));
assertChangeUpToDate(false, id);
// Attempting to write directly causes failure.
@@ -991,8 +988,7 @@ public class ChangeRebuilderIT extends AbstractDaemonTest {
}
// Update was not written.
assertThat(gApi.changes().id(id.get()).info().topic)
.isEqualTo(name("a-topic"));
assertThat(gApi.changes().id(id.get()).info().topic).isEqualTo(name("a-topic"));
assertChangeUpToDate(false, id);
}
@@ -1049,18 +1045,17 @@ public class ChangeRebuilderIT extends AbstractDaemonTest {
adminRestSession.postWithHeader(prefix + "review", ri, runAs).assertOK();
di.message = "draft with impersonation";
adminRestSession.putWithHeader(prefix + "drafts", runAs, di)
.assertCreated();
adminRestSession.putWithHeader(prefix + "drafts", runAs, di).assertCreated();
} finally {
removeRunAs();
}
List<ChangeMessage> msgs =
Ordering.natural().onResultOf(ChangeMessage::getWrittenOn)
Ordering.natural()
.onResultOf(ChangeMessage::getWrittenOn)
.sortedCopy(db.changeMessages().byChange(id));
assertThat(msgs).hasSize(3);
assertThat(msgs.get(1).getMessage())
.endsWith("message without impersonation");
assertThat(msgs.get(1).getMessage()).endsWith("message without impersonation");
assertThat(msgs.get(1).getAuthor()).isEqualTo(user.id);
assertThat(msgs.get(1).getRealAuthor()).isEqualTo(user.id);
assertThat(msgs.get(2).getMessage()).endsWith("message with impersonation");
@@ -1076,23 +1071,20 @@ public class ChangeRebuilderIT extends AbstractDaemonTest {
Ordering<PatchLineComment> commentOrder =
Ordering.natural().onResultOf(PatchLineComment::getWrittenOn);
List<PatchLineComment> drafts = commentOrder.sortedCopy(
db.patchComments().draftByPatchSetAuthor(psId, user.id));
List<PatchLineComment> drafts =
commentOrder.sortedCopy(db.patchComments().draftByPatchSetAuthor(psId, user.id));
assertThat(drafts).hasSize(2);
assertThat(drafts.get(0).getMessage())
.isEqualTo("draft without impersonation");
assertThat(drafts.get(0).getMessage()).isEqualTo("draft without impersonation");
assertThat(drafts.get(0).getAuthor()).isEqualTo(user.id);
assertThat(drafts.get(0).getRealAuthor()).isEqualTo(user.id);
assertThat(drafts.get(1).getMessage())
.isEqualTo("draft with impersonation");
assertThat(drafts.get(1).getMessage()).isEqualTo("draft with impersonation");
assertThat(drafts.get(1).getAuthor()).isEqualTo(user.id);
assertThat(drafts.get(1).getRealAuthor()).isEqualTo(admin.id);
List<PatchLineComment> pub = commentOrder.sortedCopy(
db.patchComments().publishedByPatchSet(psId));
List<PatchLineComment> pub =
commentOrder.sortedCopy(db.patchComments().publishedByPatchSet(psId));
assertThat(pub).hasSize(2);
assertThat(pub.get(0).getMessage())
.isEqualTo("comment without impersonation");
assertThat(pub.get(0).getMessage()).isEqualTo("comment without impersonation");
assertThat(pub.get(0).getAuthor()).isEqualTo(user.id);
assertThat(pub.get(0).getRealAuthor()).isEqualTo(user.id);
assertThat(pub.get(1).getMessage()).isEqualTo("comment with impersonation");
@@ -1150,22 +1142,24 @@ public class ChangeRebuilderIT extends AbstractDaemonTest {
PushOneCommit.Result r2 = amendChange(r1.getChangeId());
PatchSet.Id psId2 = r2.getPatchSetId();
try (BatchUpdate bu = batchUpdateFactory.create(db, project,
identifiedUserFactory.create(user.getId()), TimeUtil.nowTs())) {
bu.addOp(id, new BatchUpdate.Op() {
@Override
public boolean updateChange(ChangeContext ctx)
throws PatchSetInfoNotAvailableException {
ctx.getChange().setCurrentPatchSet(
patchSetInfoFactory.get(ctx.getDb(), ctx.getNotes(), psId1));
return true;
}
});
try (BatchUpdate bu =
batchUpdateFactory.create(
db, project, identifiedUserFactory.create(user.getId()), TimeUtil.nowTs())) {
bu.addOp(
id,
new BatchUpdate.Op() {
@Override
public boolean updateChange(ChangeContext ctx)
throws PatchSetInfoNotAvailableException {
ctx.getChange()
.setCurrentPatchSet(patchSetInfoFactory.get(ctx.getDb(), ctx.getNotes(), psId1));
return true;
}
});
bu.execute();
}
ChangeNotes notes = notesFactory.create(db, project, id);
assertThat(psUtil.byChangeAsMap(db, notes).keySet())
.containsExactly(psId1, psId2);
assertThat(psUtil.byChangeAsMap(db, notes).keySet()).containsExactly(psId1, psId2);
assertThat(notes.getChange().currentPatchSetId()).isEqualTo(psId1);
assertThat(db.changes().get(id).currentPatchSetId()).isEqualTo(psId1);
@@ -1174,23 +1168,20 @@ public class ChangeRebuilderIT extends AbstractDaemonTest {
setNotesMigration(true, true);
notes = notesFactory.create(db, project, id);
assertThat(psUtil.byChangeAsMap(db, notes).keySet())
.containsExactly(psId1, psId2);
assertThat(psUtil.byChangeAsMap(db, notes).keySet()).containsExactly(psId1, psId2);
assertThat(notes.getChange().currentPatchSetId()).isEqualTo(psId1);
}
@Test
public void resolveCommentsInheritsValueFromParentWhenUnspecified()
throws Exception {
public void resolveCommentsInheritsValueFromParentWhenUnspecified() throws Exception {
PushOneCommit.Result r = createChange();
Change.Id id = r.getPatchSetId().getParentKey();
putDraft(user, id, 1, "comment", true);
putDraft(user, id, 1, "newComment", null);
Map<String, List<CommentInfo>> comments =
gApi.changes().id(id.get()).current().drafts();
for (List<CommentInfo> cList: comments.values()) {
for (CommentInfo ci: cList) {
Map<String, List<CommentInfo>> comments = gApi.changes().id(id.get()).current().drafts();
for (List<CommentInfo> cList : comments.values()) {
for (CommentInfo ci : cList) {
assertThat(ci.unresolved).isEqualTo(true);
}
}
@@ -1209,8 +1200,7 @@ public class ChangeRebuilderIT extends AbstractDaemonTest {
ReviewDb db = getUnwrappedDb();
Change c = db.changes().get(id);
NoteDbChangeState state = NoteDbChangeState.parse(c);
Timestamp until =
new Timestamp(TimeUtil.nowMs() + MILLISECONDS.convert(1, DAYS));
Timestamp until = new Timestamp(TimeUtil.nowMs() + MILLISECONDS.convert(1, DAYS));
state = state.withReadOnlyUntil(until);
c.setNoteDbState(state.toString());
db.changes().update(Collections.singleton(c));
@@ -1222,8 +1212,7 @@ public class ChangeRebuilderIT extends AbstractDaemonTest {
assertThat(e.getMessage()).contains("read-only until");
}
TestTimeUtil.setClock(
new Timestamp(until.getTime() + MILLISECONDS.convert(1, SECONDS)));
TestTimeUtil.setClock(new Timestamp(until.getTime() + MILLISECONDS.convert(1, SECONDS)));
rebuilderWrapper.rebuild(db, id);
}
@@ -1231,8 +1220,7 @@ public class ChangeRebuilderIT extends AbstractDaemonTest {
Throwable cause = e.getCause();
assertThat(cause).isInstanceOf(UpdateException.class);
assertThat(cause.getCause()).isInstanceOf(OrmException.class);
assertThat(cause.getCause())
.hasMessage(NoteDbUpdateManager.CHANGES_READ_ONLY);
assertThat(cause.getCause()).hasMessage(NoteDbUpdateManager.CHANGES_READ_ONLY);
}
private void setInvalidNoteDbState(Change.Id id) throws Exception {
@@ -1246,27 +1234,24 @@ public class ChangeRebuilderIT extends AbstractDaemonTest {
db.changes().update(Collections.singleton(c));
}
private void assertChangeUpToDate(boolean expected, Change.Id id)
throws Exception {
private void assertChangeUpToDate(boolean expected, Change.Id id) throws Exception {
try (Repository repo = repoManager.openRepository(project)) {
Change c = getUnwrappedDb().changes().get(id);
assertThat(c).isNotNull();
assertThat(c.getNoteDbState()).isNotNull();
assertThat(NoteDbChangeState.parse(c).isChangeUpToDate(
new RepoRefCache(repo)))
assertThat(NoteDbChangeState.parse(c).isChangeUpToDate(new RepoRefCache(repo)))
.isEqualTo(expected);
}
}
private void assertDraftsUpToDate(boolean expected, Change.Id changeId,
TestAccount account) throws Exception {
private void assertDraftsUpToDate(boolean expected, Change.Id changeId, TestAccount account)
throws Exception {
try (Repository repo = repoManager.openRepository(allUsers)) {
Change c = getUnwrappedDb().changes().get(changeId);
assertThat(c).isNotNull();
assertThat(c.getNoteDbState()).isNotNull();
NoteDbChangeState state = NoteDbChangeState.parse(c);
assertThat(state.areDraftsUpToDate(
new RepoRefCache(repo), account.getId()))
assertThat(state.areDraftsUpToDate(new RepoRefCache(repo), account.getId()))
.isEqualTo(expected);
}
}
@@ -1278,8 +1263,8 @@ public class ChangeRebuilderIT extends AbstractDaemonTest {
}
}
private void putDraft(TestAccount account, Change.Id id, int line, String msg,
Boolean unresolved) throws Exception {
private void putDraft(TestAccount account, Change.Id id, int line, String msg, Boolean unresolved)
throws Exception {
DraftInput in = new DraftInput();
in.line = line;
in.message = msg;
@@ -1293,8 +1278,8 @@ public class ChangeRebuilderIT extends AbstractDaemonTest {
}
}
private void putComment(TestAccount account, Change.Id id, int line,
String msg, String inReplyTo) throws Exception {
private void putComment(TestAccount account, Change.Id id, int line, String msg, String inReplyTo)
throws Exception {
CommentInput in = new CommentInput();
in.line = line;
in.message = msg;
@@ -1311,8 +1296,7 @@ public class ChangeRebuilderIT extends AbstractDaemonTest {
}
}
private void publishDrafts(TestAccount account, Change.Id id)
throws Exception {
private void publishDrafts(TestAccount account, Change.Id id) throws Exception {
ReviewInput rin = new ReviewInput();
rin.drafts = ReviewInput.DraftHandling.PUBLISH_ALL_REVISIONS;
AcceptanceTestRequestScope.Context old = setApiUser(account);
@@ -1323,11 +1307,11 @@ public class ChangeRebuilderIT extends AbstractDaemonTest {
}
}
private ChangeMessage insertMessage(Change.Id id, PatchSet.Id psId,
Account.Id author, Timestamp ts, String message) throws Exception {
ChangeMessage msg = new ChangeMessage(
new ChangeMessage.Key(id, ChangeUtil.messageUuid()),
author, ts, psId);
private ChangeMessage insertMessage(
Change.Id id, PatchSet.Id psId, Account.Id author, Timestamp ts, String message)
throws Exception {
ChangeMessage msg =
new ChangeMessage(new ChangeMessage.Key(id, ChangeUtil.messageUuid()), author, ts, psId);
msg.setMessage(message);
db.changeMessages().insert(Collections.singleton(msg));
@@ -1347,20 +1331,19 @@ public class ChangeRebuilderIT extends AbstractDaemonTest {
private void allowRunAs() throws Exception {
ProjectConfig cfg = projectCache.checkedGet(allProjects).getConfig();
Util.allow(cfg, GlobalCapability.RUN_AS,
systemGroupBackend.getGroup(REGISTERED_USERS).getUUID());
Util.allow(
cfg, GlobalCapability.RUN_AS, systemGroupBackend.getGroup(REGISTERED_USERS).getUUID());
saveProjectConfig(allProjects, cfg);
}
private void removeRunAs() throws Exception {
ProjectConfig cfg = projectCache.checkedGet(allProjects).getConfig();
Util.remove(cfg, GlobalCapability.RUN_AS,
systemGroupBackend.getGroup(REGISTERED_USERS).getUUID());
Util.remove(
cfg, GlobalCapability.RUN_AS, systemGroupBackend.getGroup(REGISTERED_USERS).getUUID());
saveProjectConfig(allProjects, cfg);
}
private Map<String, List<CommentInfo>> getPublishedComments(Change.Id id)
throws Exception {
private Map<String, List<CommentInfo>> getPublishedComments(Change.Id id) throws Exception {
return gApi.changes().id(id.get()).current().comments();
}
}

View File

@@ -23,6 +23,9 @@ import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.SECONDS;
import static java.util.stream.Collectors.toList;
import com.github.rholder.retry.Retryer;
import com.github.rholder.retry.RetryerBuilder;
import com.github.rholder.retry.StopStrategies;
import com.google.common.base.Throwables;
import com.google.common.collect.Iterables;
import com.google.gerrit.acceptance.AbstractDaemonTest;
@@ -53,22 +56,16 @@ import com.google.gwtorm.server.OrmException;
import com.google.gwtorm.server.OrmRuntimeException;
import com.google.inject.Inject;
import com.google.inject.util.Providers;
import com.github.rholder.retry.Retryer;
import com.github.rholder.retry.RetryerBuilder;
import com.github.rholder.retry.StopStrategies;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.Repository;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.sql.Timestamp;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.Repository;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class NoteDbPrimaryIT extends AbstractDaemonTest {
@ConfigSuite.Default
@@ -80,11 +77,9 @@ public class NoteDbPrimaryIT extends AbstractDaemonTest {
return cfg;
}
@Inject
private AllUsersName allUsers;
@Inject private AllUsersName allUsers;
@Inject
private TestChangeRebuilderWrapper rebuilderWrapper;
@Inject private TestChangeRebuilderWrapper rebuilderWrapper;
private PrimaryStorageMigrator migrator;
@@ -99,8 +94,7 @@ public class NoteDbPrimaryIT extends AbstractDaemonTest {
private PrimaryStorageMigrator newMigrator(
@Nullable Retryer<NoteDbChangeState> ensureRebuiltRetryer) {
return new PrimaryStorageMigrator(
cfg, Providers.of(db), repoManager, allUsers, rebuilderWrapper,
ensureRebuiltRetryer);
cfg, Providers.of(db), repoManager, allUsers, rebuilderWrapper, ensureRebuiltRetryer);
}
@After
@@ -119,8 +113,7 @@ public class NoteDbPrimaryIT extends AbstractDaemonTest {
ChangeInfo info = gApi.changes().id(id.get()).get();
assertThat(info.status).isEqualTo(ChangeStatus.MERGED);
ApprovalInfo approval =
Iterables.getOnlyElement(info.labels.get("Code-Review").all);
ApprovalInfo approval = Iterables.getOnlyElement(info.labels.get("Code-Review").all);
assertThat(approval._accountId).isEqualTo(admin.id.get());
assertThat(approval.value).isEqualTo(2);
assertThat(info.messages).hasSize(3);
@@ -150,14 +143,12 @@ public class NoteDbPrimaryIT extends AbstractDaemonTest {
din.message = "A comment";
gApi.changes().id(id.get()).current().createDraft(din);
CommentInfo di = Iterables.getOnlyElement(
gApi.changes().id(id.get()).current().drafts()
.get(PushOneCommit.FILE_NAME));
CommentInfo di =
Iterables.getOnlyElement(
gApi.changes().id(id.get()).current().drafts().get(PushOneCommit.FILE_NAME));
assertThat(di.message).isEqualTo(din.message);
assertThat(
db.patchComments().draftByChangeFileAuthor(id, din.path, admin.id))
.isEmpty();
assertThat(db.patchComments().draftByChangeFileAuthor(id, din.path, admin.id)).isEmpty();
gApi.changes().id(id.get()).current().draft(di.id).delete();
assertThat(gApi.changes().id(id.get()).current().drafts()).isEmpty();
@@ -170,13 +161,11 @@ public class NoteDbPrimaryIT extends AbstractDaemonTest {
setNoteDbPrimary(id);
gApi.changes().id(id.get()).current().review(ReviewInput.approve());
List<ApprovalInfo> approvals =
gApi.changes().id(id.get()).get().labels.get("Code-Review").all;
List<ApprovalInfo> approvals = gApi.changes().id(id.get()).get().labels.get("Code-Review").all;
assertThat(approvals).hasSize(1);
assertThat(approvals.get(0).value).isEqualTo(2);
gApi.changes().id(id.get()).reviewer(admin.id.toString())
.deleteVote("Code-Review");
gApi.changes().id(id.get()).reviewer(admin.id.toString()).deleteVote("Code-Review");
approvals = gApi.changes().id(id.get()).get().labels.get("Code-Review").all;
assertThat(approvals).hasSize(1);
@@ -190,8 +179,7 @@ public class NoteDbPrimaryIT extends AbstractDaemonTest {
setNoteDbPrimary(id);
gApi.changes().id(id.get()).current().review(ReviewInput.approve());
List<ApprovalInfo> approvals =
gApi.changes().id(id.get()).get().labels.get("Code-Review").all;
List<ApprovalInfo> approvals = gApi.changes().id(id.get()).get().labels.get("Code-Review").all;
assertThat(approvals).hasSize(1);
assertThat(approvals.get(0).value).isEqualTo(2);
@@ -241,25 +229,24 @@ public class NoteDbPrimaryIT extends AbstractDaemonTest {
c.setNoteDbState(state.toString());
db.changes().update(Collections.singleton(c));
assertThat(gApi.changes().id(id.get()).get().subject)
.isEqualTo(PushOneCommit.SUBJECT);
assertThat(gApi.changes().id(id.get()).get().subject).isEqualTo(PushOneCommit.SUBJECT);
assertThat(gApi.changes().id(id.get()).get().topic).isNull();
try {
gApi.changes().id(id.get()).topic("a-topic");
assert_().fail("expected read-only exception");
} catch (RestApiException e) {
Optional<Throwable> oe = Throwables.getCausalChain(e).stream()
.filter(x -> x instanceof OrmRuntimeException).findFirst();
assertThat(oe.isPresent())
.named("OrmRuntimeException in causal chain of " + e)
.isTrue();
Optional<Throwable> oe =
Throwables.getCausalChain(e)
.stream()
.filter(x -> x instanceof OrmRuntimeException)
.findFirst();
assertThat(oe.isPresent()).named("OrmRuntimeException in causal chain of " + e).isTrue();
assertThat(oe.get().getMessage()).contains("read-only");
}
assertThat(gApi.changes().id(id.get()).get().topic).isNull();
TestTimeUtil.setClock(new Timestamp(until.getTime() + 1000));
assertThat(gApi.changes().id(id.get()).get().subject)
.isEqualTo(PushOneCommit.SUBJECT);
assertThat(gApi.changes().id(id.get()).get().subject).isEqualTo(PushOneCommit.SUBJECT);
gApi.changes().id(id.get()).topic("a-topic");
assertThat(gApi.changes().id(id.get()).get().topic).isEqualTo("a-topic");
}
@@ -281,8 +268,7 @@ public class NoteDbPrimaryIT extends AbstractDaemonTest {
}
private void testMigrateToNoteDb(Change.Id id) throws Exception {
assertThat(PrimaryStorage.of(db.changes().get(id)))
.isEqualTo(PrimaryStorage.REVIEW_DB);
assertThat(PrimaryStorage.of(db.changes().get(id))).isEqualTo(PrimaryStorage.REVIEW_DB);
migrator.migrateToNoteDbPrimary(id);
assertNoteDbPrimary(id);
@@ -300,11 +286,12 @@ public class NoteDbPrimaryIT extends AbstractDaemonTest {
db.changes().update(Collections.singleton(c));
rebuilderWrapper.failNextUpdate();
migrator = newMigrator(
RetryerBuilder.<NoteDbChangeState> newBuilder()
.retryIfException()
.withStopStrategy(StopStrategies.neverStop())
.build());
migrator =
newMigrator(
RetryerBuilder.<NoteDbChangeState>newBuilder()
.retryIfException()
.withStopStrategy(StopStrategies.neverStop())
.build());
migrator.migrateToNoteDbPrimary(id);
assertNoteDbPrimary(id);
}
@@ -318,11 +305,12 @@ public class NoteDbPrimaryIT extends AbstractDaemonTest {
db.changes().update(Collections.singleton(c));
rebuilderWrapper.failNextUpdate();
migrator = newMigrator(
RetryerBuilder.<NoteDbChangeState> newBuilder()
.retryIfException()
.withStopStrategy(StopStrategies.stopAfterAttempt(1))
.build());
migrator =
newMigrator(
RetryerBuilder.<NoteDbChangeState>newBuilder()
.retryIfException()
.withStopStrategy(StopStrategies.stopAfterAttempt(1))
.build());
exception.expect(OrmException.class);
exception.expectMessage("Retrying failed");
migrator.migrateToNoteDbPrimary(id);
@@ -357,8 +345,7 @@ public class NoteDbPrimaryIT extends AbstractDaemonTest {
Change c = db.changes().get(id);
NoteDbChangeState state = NoteDbChangeState.parse(c);
Timestamp until =
new Timestamp(TimeUtil.nowMs() + MILLISECONDS.convert(1, DAYS));
Timestamp until = new Timestamp(TimeUtil.nowMs() + MILLISECONDS.convert(1, DAYS));
state = state.withReadOnlyUntil(until);
c.setNoteDbState(state.toString());
db.changes().update(Collections.singleton(c));
@@ -373,8 +360,7 @@ public class NoteDbPrimaryIT extends AbstractDaemonTest {
PushOneCommit.Result r = createChange();
Change.Id id = r.getChange().getId();
assertThat(PrimaryStorage.of(db.changes().get(id)))
.isEqualTo(PrimaryStorage.REVIEW_DB);
assertThat(PrimaryStorage.of(db.changes().get(id))).isEqualTo(PrimaryStorage.REVIEW_DB);
migrator.migrateToNoteDbPrimary(id);
assertNoteDbPrimary(id);
@@ -386,15 +372,11 @@ public class NoteDbPrimaryIT extends AbstractDaemonTest {
Change c = db.changes().get(id);
assertThat(c).named("change " + id).isNotNull();
NoteDbChangeState state = NoteDbChangeState.parse(c);
assertThat(state.getPrimaryStorage())
.named("storage of " + id)
.isEqualTo(REVIEW_DB);
assertThat(state.getPrimaryStorage()).named("storage of " + id).isEqualTo(REVIEW_DB);
try (Repository changeRepo = repoManager.openRepository(c.getProject());
Repository allUsersRepo = repoManager.openRepository(allUsers)) {
assertThat(
state.isUpToDate(
new RepoRefCache(changeRepo), new RepoRefCache(allUsersRepo)))
assertThat(state.isUpToDate(new RepoRefCache(changeRepo), new RepoRefCache(allUsersRepo)))
.named("change " + id + " up to date")
.isTrue();
}
@@ -404,13 +386,16 @@ public class NoteDbPrimaryIT extends AbstractDaemonTest {
}
private void assertNoteDbPrimary(Change.Id id) throws Exception {
assertThat(PrimaryStorage.of(db.changes().get(id)))
.isEqualTo(PrimaryStorage.NOTE_DB);
assertThat(PrimaryStorage.of(db.changes().get(id))).isEqualTo(PrimaryStorage.NOTE_DB);
}
private List<Account.Id> getReviewers(Change.Id id) throws Exception {
return gApi.changes().id(id.get()).get()
.reviewers.values().stream()
return gApi.changes()
.id(id.get())
.get()
.reviewers
.values()
.stream()
.flatMap(Collection::stream)
.map(a -> new Account.Id(a._accountId))
.collect(toList());

View File

@@ -37,7 +37,6 @@ import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.server.git.ProjectConfig;
import com.google.gerrit.server.project.Util;
import com.google.inject.Inject;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -45,17 +44,12 @@ import org.junit.Test;
@NoHttpd
public class CustomLabelIT extends AbstractDaemonTest {
@Inject
private DynamicSet<CommentAddedListener> source;
@Inject private DynamicSet<CommentAddedListener> source;
private final LabelType label = category("CustomLabel",
value(1, "Positive"),
value(0, "No score"),
value(-1, "Negative"));
private final LabelType label =
category("CustomLabel", value(1, "Positive"), value(0, "No score"), value(-1, "Negative"));
private final LabelType P = category("CustomLabel2",
value(1, "Positive"),
value(0, "No score"));
private final LabelType P = category("CustomLabel2", value(1, "Positive"), value(0, "No score"));
private RegistrationHandle eventListenerRegistration;
private CommentAddedListener.Event lastCommentAddedEvent;
@@ -63,20 +57,19 @@ public class CustomLabelIT extends AbstractDaemonTest {
@Before
public void setUp() throws Exception {
ProjectConfig cfg = projectCache.checkedGet(project).getConfig();
AccountGroup.UUID anonymousUsers =
systemGroupBackend.getGroup(ANONYMOUS_USERS).getUUID();
Util.allow(cfg, Permission.forLabel(label.getName()), -1, 1, anonymousUsers,
"refs/heads/*");
Util.allow(cfg, Permission.forLabel(P.getName()), 0, 1, anonymousUsers,
"refs/heads/*");
AccountGroup.UUID anonymousUsers = systemGroupBackend.getGroup(ANONYMOUS_USERS).getUUID();
Util.allow(cfg, Permission.forLabel(label.getName()), -1, 1, anonymousUsers, "refs/heads/*");
Util.allow(cfg, Permission.forLabel(P.getName()), 0, 1, anonymousUsers, "refs/heads/*");
saveProjectConfig(project, cfg);
eventListenerRegistration = source.add(new CommentAddedListener() {
@Override
public void onCommentAdded(Event event) {
lastCommentAddedEvent = event;
}
});
eventListenerRegistration =
source.add(
new CommentAddedListener() {
@Override
public void onCommentAdded(Event event) {
lastCommentAddedEvent = event;
}
});
}
@After
@@ -145,9 +138,7 @@ public class CustomLabelIT extends AbstractDaemonTest {
PushOneCommit.Result r = createChange();
AddReviewerInput in = new AddReviewerInput();
in.reviewer = user.email;
gApi.changes()
.id(r.getChangeId())
.addReviewer(in);
gApi.changes().id(r.getChangeId()).addReviewer(in);
ReviewInput input = new ReviewInput().label(P.getName(), 0);
input.message = "foo";
@@ -159,8 +150,7 @@ public class CustomLabelIT extends AbstractDaemonTest {
assertThat(q.disliked).isNull();
assertThat(q.rejected).isNull();
assertThat(q.blocking).isNull();
assertThat(lastCommentAddedEvent.getComment()).isEqualTo(
"Patch Set 1:\n\n" + input.message);
assertThat(lastCommentAddedEvent.getComment()).isEqualTo("Patch Set 1:\n\n" + input.message);
}
@Test
@@ -199,8 +189,7 @@ public class CustomLabelIT extends AbstractDaemonTest {
in = new ReviewInput();
in.label(label.getName(), label.getMax().getValue());
exception.expect(ResourceConflictException.class);
exception.expectMessage(
"Voting on labels disallowed after submit: " + label.getName());
exception.expectMessage("Voting on labels disallowed after submit: " + label.getName());
revision(r).review(in);
}

View File

@@ -27,14 +27,12 @@ import com.google.gerrit.server.git.NotifyConfig;
import com.google.gerrit.server.git.ProjectConfig;
import com.google.gerrit.server.mail.Address;
import com.google.gerrit.testutil.FakeEmailSender.Message;
import java.util.EnumSet;
import java.util.List;
import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
import org.eclipse.jgit.junit.TestRepository;
import org.junit.Test;
import java.util.EnumSet;
import java.util.List;
@NoHttpd
@Sandboxed
public class ProjectWatchIT extends AbstractDaemonTest {
@@ -52,19 +50,23 @@ public class ProjectWatchIT extends AbstractDaemonTest {
cfg.putNotifyConfig("watch", nc);
saveProjectConfig(project, cfg);
PushOneCommit.Result r = pushFactory.create(db, admin.getIdent(), testRepo,
"original subject", "a", "a1")
.to("refs/for/master");
PushOneCommit.Result r =
pushFactory
.create(db, admin.getIdent(), testRepo, "original subject", "a", "a1")
.to("refs/for/master");
r.assertOkStatus();
r = pushFactory.create(db, admin.getIdent(), testRepo,
"super sekret subject", "a", "a2", r.getChangeId())
.to("refs/for/master");
r =
pushFactory
.create(
db, admin.getIdent(), testRepo, "super sekret subject", "a", "a2", r.getChangeId())
.to("refs/for/master");
r.assertOkStatus();
r = pushFactory.create(db, admin.getIdent(), testRepo,
"back to original subject", "a", "a3")
.to("refs/for/master");
r =
pushFactory
.create(db, admin.getIdent(), testRepo, "back to original subject", "a", "a3")
.to("refs/for/master");
r.assertOkStatus();
List<Message> messages = sender.getMessages();
@@ -86,9 +88,10 @@ public class ProjectWatchIT extends AbstractDaemonTest {
setApiUser(admin);
TestRepository<InMemoryRepository> watchedRepo =
cloneProject(new Project.NameKey(watchedProject), admin);
PushOneCommit.Result r = pushFactory
.create(db, admin.getIdent(), watchedRepo, "TRIGGER", "a", "a1")
.to("refs/for/master");
PushOneCommit.Result r =
pushFactory
.create(db, admin.getIdent(), watchedRepo, "TRIGGER", "a", "a1")
.to("refs/for/master");
r.assertOkStatus();
// push a change to non-watched project -> should not trigger email
@@ -96,8 +99,10 @@ public class ProjectWatchIT extends AbstractDaemonTest {
String notWatchedProject = createProject("otherProject").get();
TestRepository<InMemoryRepository> notWatchedRepo =
cloneProject(new Project.NameKey(notWatchedProject), admin);
r = pushFactory.create(db, admin.getIdent(), notWatchedRepo,
"DONT_TRIGGER", "a", "a1").to("refs/for/master");
r =
pushFactory
.create(db, admin.getIdent(), notWatchedRepo, "DONT_TRIGGER", "a", "a1")
.to("refs/for/master");
r.assertOkStatus();
// assert email notification
@@ -126,9 +131,10 @@ public class ProjectWatchIT extends AbstractDaemonTest {
setApiUser(admin);
TestRepository<InMemoryRepository> watchedRepo =
cloneProject(new Project.NameKey(watchedProject), admin);
PushOneCommit.Result r = pushFactory
.create(db, admin.getIdent(), watchedRepo, "TRIGGER", "a.txt", "a1")
.to("refs/for/master");
PushOneCommit.Result r =
pushFactory
.create(db, admin.getIdent(), watchedRepo, "TRIGGER", "a.txt", "a1")
.to("refs/for/master");
r.assertOkStatus();
// assert email notification for user
@@ -147,8 +153,10 @@ public class ProjectWatchIT extends AbstractDaemonTest {
// push a change to non-watched file -> should not trigger email
// notification for user, only for user2
r = pushFactory.create(db, admin.getIdent(), watchedRepo,
"TRIGGER_USER2", "b.txt", "b1").to("refs/for/master");
r =
pushFactory
.create(db, admin.getIdent(), watchedRepo, "TRIGGER_USER2", "b.txt", "b1")
.to("refs/for/master");
r.assertOkStatus();
// assert email notification
@@ -172,10 +180,10 @@ public class ProjectWatchIT extends AbstractDaemonTest {
setApiUser(admin);
TestRepository<InMemoryRepository> watchedRepo =
cloneProject(new Project.NameKey(watchedProject), admin);
PushOneCommit.Result r = pushFactory
.create(db, admin.getIdent(), watchedRepo,
"Document multimaster setup", "a.txt", "a1")
.to("refs/for/master");
PushOneCommit.Result r =
pushFactory
.create(db, admin.getIdent(), watchedRepo, "Document multimaster setup", "a.txt", "a1")
.to("refs/for/master");
r.assertOkStatus();
// assert email notification for user
@@ -183,14 +191,16 @@ public class ProjectWatchIT extends AbstractDaemonTest {
assertThat(messages).hasSize(1);
Message m = messages.get(0);
assertThat(m.rcpt()).containsExactly(user.emailAddress);
assertThat(m.body())
.contains("Change subject: Document multimaster setup\n");
assertThat(m.body()).contains("Change subject: Document multimaster setup\n");
assertThat(m.body()).contains("Gerrit-PatchSet: 1\n");
sender.clear();
// push a change without keyword -> should not trigger email notification
r = pushFactory.create(db, admin.getIdent(), watchedRepo,
"Cleanup cache implementation", "b.txt", "b1").to("refs/for/master");
r =
pushFactory
.create(
db, admin.getIdent(), watchedRepo, "Cleanup cache implementation", "b.txt", "b1")
.to("refs/for/master");
r.assertOkStatus();
// assert email notification
@@ -209,9 +219,10 @@ public class ProjectWatchIT extends AbstractDaemonTest {
setApiUser(admin);
TestRepository<InMemoryRepository> anyRepo =
cloneProject(new Project.NameKey(anyProject), admin);
PushOneCommit.Result r = pushFactory
.create(db, admin.getIdent(), anyRepo, "TRIGGER", "a", "a1")
.to("refs/for/master");
PushOneCommit.Result r =
pushFactory
.create(db, admin.getIdent(), anyRepo, "TRIGGER", "a", "a1")
.to("refs/for/master");
r.assertOkStatus();
// assert email notification
@@ -237,9 +248,10 @@ public class ProjectWatchIT extends AbstractDaemonTest {
setApiUser(admin);
TestRepository<InMemoryRepository> anyRepo =
cloneProject(new Project.NameKey(anyProject), admin);
PushOneCommit.Result r = pushFactory
.create(db, admin.getIdent(), anyRepo, "TRIGGER", "a.txt", "a1")
.to("refs/for/master");
PushOneCommit.Result r =
pushFactory
.create(db, admin.getIdent(), anyRepo, "TRIGGER", "a.txt", "a1")
.to("refs/for/master");
r.assertOkStatus();
// assert email notification for user
@@ -258,8 +270,10 @@ public class ProjectWatchIT extends AbstractDaemonTest {
// push a change to non-watched file in any project -> should not trigger
// email notification for user, only for user2
r = pushFactory.create(db, admin.getIdent(), anyRepo,
"TRIGGER_USER2", "b.txt", "b1").to("refs/for/master");
r =
pushFactory
.create(db, admin.getIdent(), anyRepo, "TRIGGER_USER2", "b.txt", "b1")
.to("refs/for/master");
r.assertOkStatus();
// assert email notification
@@ -284,10 +298,10 @@ public class ProjectWatchIT extends AbstractDaemonTest {
setApiUser(admin);
TestRepository<InMemoryRepository> anyRepo =
cloneProject(new Project.NameKey(anyProject), admin);
PushOneCommit.Result r = pushFactory
.create(db, admin.getIdent(), anyRepo,
"Document multimaster setup", "a.txt", "a1")
.to("refs/for/master");
PushOneCommit.Result r =
pushFactory
.create(db, admin.getIdent(), anyRepo, "Document multimaster setup", "a.txt", "a1")
.to("refs/for/master");
r.assertOkStatus();
// assert email notification for user
@@ -295,15 +309,16 @@ public class ProjectWatchIT extends AbstractDaemonTest {
assertThat(messages).hasSize(1);
Message m = messages.get(0);
assertThat(m.rcpt()).containsExactly(user.emailAddress);
assertThat(m.body())
.contains("Change subject: Document multimaster setup\n");
assertThat(m.body()).contains("Change subject: Document multimaster setup\n");
assertThat(m.body()).contains("Gerrit-PatchSet: 1\n");
sender.clear();
// push a change without keyword to any project -> should not trigger email
// notification
r = pushFactory.create(db, admin.getIdent(), anyRepo,
"Cleanup cache implementation", "b.txt", "b1").to("refs/for/master");
r =
pushFactory
.create(db, admin.getIdent(), anyRepo, "Cleanup cache implementation", "b.txt", "b1")
.to("refs/for/master");
r.assertOkStatus();
// assert email notification