summaryrefslogtreecommitdiffstats
path: root/gerrit-server/src/test/java/com/google/gerrit/server/notedb/ChangeBundleTest.java
diff options
context:
space:
mode:
Diffstat (limited to 'gerrit-server/src/test/java/com/google/gerrit/server/notedb/ChangeBundleTest.java')
-rw-r--r--gerrit-server/src/test/java/com/google/gerrit/server/notedb/ChangeBundleTest.java1972
1 files changed, 0 insertions, 1972 deletions
diff --git a/gerrit-server/src/test/java/com/google/gerrit/server/notedb/ChangeBundleTest.java b/gerrit-server/src/test/java/com/google/gerrit/server/notedb/ChangeBundleTest.java
deleted file mode 100644
index 80a8ab94c4..0000000000
--- a/gerrit-server/src/test/java/com/google/gerrit/server/notedb/ChangeBundleTest.java
+++ /dev/null
@@ -1,1972 +0,0 @@
-// Copyright (C) 2016 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.gerrit.server.notedb;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.gerrit.common.TimeUtil.roundToSecond;
-import static com.google.gerrit.server.notedb.ChangeBundle.Source.NOTE_DB;
-import static com.google.gerrit.server.notedb.ChangeBundle.Source.REVIEW_DB;
-import static com.google.gerrit.server.notedb.ReviewerStateInternal.CC;
-import static com.google.gerrit.server.notedb.ReviewerStateInternal.REVIEWER;
-import static java.util.concurrent.TimeUnit.MILLISECONDS;
-import static java.util.concurrent.TimeUnit.SECONDS;
-
-import com.google.common.collect.HashBasedTable;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Table;
-import com.google.gerrit.common.TimeUtil;
-import com.google.gerrit.reviewdb.client.Account;
-import com.google.gerrit.reviewdb.client.Change;
-import com.google.gerrit.reviewdb.client.ChangeMessage;
-import com.google.gerrit.reviewdb.client.LabelId;
-import com.google.gerrit.reviewdb.client.Patch;
-import com.google.gerrit.reviewdb.client.PatchLineComment;
-import com.google.gerrit.reviewdb.client.PatchSet;
-import com.google.gerrit.reviewdb.client.PatchSetApproval;
-import com.google.gerrit.reviewdb.client.Project;
-import com.google.gerrit.reviewdb.client.RevId;
-import com.google.gerrit.server.ReviewerSet;
-import com.google.gerrit.server.notedb.rebuild.ChangeRebuilderImpl;
-import com.google.gerrit.testutil.GerritBaseTests;
-import com.google.gerrit.testutil.TestChanges;
-import com.google.gerrit.testutil.TestTimeUtil;
-import com.google.gwtorm.protobuf.CodecFactory;
-import com.google.gwtorm.protobuf.ProtobufCodec;
-import java.sql.Timestamp;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.TimeZone;
-import org.joda.time.DateTime;
-import org.joda.time.DateTimeZone;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-public class ChangeBundleTest extends GerritBaseTests {
- private static final ProtobufCodec<Change> CHANGE_CODEC = CodecFactory.encoder(Change.class);
- private static final ProtobufCodec<ChangeMessage> CHANGE_MESSAGE_CODEC =
- CodecFactory.encoder(ChangeMessage.class);
- private static final ProtobufCodec<PatchSet> PATCH_SET_CODEC =
- CodecFactory.encoder(PatchSet.class);
- private static final ProtobufCodec<PatchSetApproval> PATCH_SET_APPROVAL_CODEC =
- CodecFactory.encoder(PatchSetApproval.class);
- private static final ProtobufCodec<PatchLineComment> PATCH_LINE_COMMENT_CODEC =
- CodecFactory.encoder(PatchLineComment.class);
-
- private String systemTimeZoneProperty;
- private TimeZone systemTimeZone;
-
- private Project.NameKey project;
- private Account.Id accountId;
-
- @Before
- public void setUp() {
- String tz = "US/Eastern";
- systemTimeZoneProperty = System.setProperty("user.timezone", tz);
- systemTimeZone = TimeZone.getDefault();
- TimeZone.setDefault(TimeZone.getTimeZone(tz));
- long maxMs = ChangeRebuilderImpl.MAX_WINDOW_MS;
- assertThat(maxMs).isGreaterThan(1000L);
- TestTimeUtil.resetWithClockStep(maxMs * 2, MILLISECONDS);
- project = new Project.NameKey("project");
- accountId = new Account.Id(100);
- }
-
- @After
- public void tearDown() {
- TestTimeUtil.useSystemTime();
- System.setProperty("user.timezone", systemTimeZoneProperty);
- TimeZone.setDefault(systemTimeZone);
- }
-
- private void superWindowResolution() {
- TestTimeUtil.setClockStep(ChangeRebuilderImpl.MAX_WINDOW_MS * 2, MILLISECONDS);
- TimeUtil.nowTs();
- }
-
- private void subWindowResolution() {
- TestTimeUtil.setClockStep(1, SECONDS);
- TimeUtil.nowTs();
- }
-
- @Test
- public void diffChangesDifferentIds() throws Exception {
- Change c1 = TestChanges.newChange(project, accountId);
- int id1 = c1.getId().get();
- Change c2 = TestChanges.newChange(project, accountId);
- int id2 = c2.getId().get();
- ChangeBundle b1 =
- new ChangeBundle(
- c1, messages(), patchSets(), approvals(), comments(), reviewers(), REVIEW_DB);
- ChangeBundle b2 =
- new ChangeBundle(
- c2, messages(), patchSets(), approvals(), comments(), reviewers(), REVIEW_DB);
-
- assertDiffs(
- b1,
- b2,
- "changeId differs for Changes: {" + id1 + "} != {" + id2 + "}",
- "createdOn differs for Changes: {2009-09-30 17:00:00.0} != {2009-09-30 17:00:06.0}",
- "effective last updated time differs for Changes:"
- + " {2009-09-30 17:00:00.0} != {2009-09-30 17:00:06.0}");
- }
-
- @Test
- public void diffChangesSameId() throws Exception {
- Change c1 = TestChanges.newChange(new Project.NameKey("project"), new Account.Id(100));
- Change c2 = clone(c1);
- ChangeBundle b1 =
- new ChangeBundle(
- c1, messages(), patchSets(), approvals(), comments(), reviewers(), REVIEW_DB);
- ChangeBundle b2 =
- new ChangeBundle(
- c2, messages(), patchSets(), approvals(), comments(), reviewers(), REVIEW_DB);
-
- assertNoDiffs(b1, b2);
-
- c2.setTopic("topic");
- assertDiffs(b1, b2, "topic differs for Change.Id " + c1.getId() + ": {null} != {topic}");
- }
-
- @Test
- public void diffChangesMixedSourcesAllowsSlop() throws Exception {
- subWindowResolution();
- Change c1 = TestChanges.newChange(new Project.NameKey("project"), new Account.Id(100));
- Change c2 = clone(c1);
- c2.setCreatedOn(TimeUtil.nowTs());
- c2.setLastUpdatedOn(TimeUtil.nowTs());
-
- // Both are ReviewDb, exact timestamp match is required.
- ChangeBundle b1 =
- new ChangeBundle(
- c1, messages(), patchSets(), approvals(), comments(), reviewers(), REVIEW_DB);
- ChangeBundle b2 =
- new ChangeBundle(
- c2, messages(), patchSets(), approvals(), comments(), reviewers(), REVIEW_DB);
- assertDiffs(
- b1,
- b2,
- "createdOn differs for Change.Id "
- + c1.getId()
- + ":"
- + " {2009-09-30 17:00:01.0} != {2009-09-30 17:00:02.0}",
- "effective last updated time differs for Change.Id "
- + c1.getId()
- + ":"
- + " {2009-09-30 17:00:01.0} != {2009-09-30 17:00:03.0}");
-
- // One NoteDb, slop is allowed.
- b1 =
- new ChangeBundle(
- c1, messages(), patchSets(), approvals(), comments(), reviewers(), NOTE_DB);
- b2 =
- new ChangeBundle(
- c2, messages(), patchSets(), approvals(), comments(), reviewers(), REVIEW_DB);
- assertNoDiffs(b1, b2);
- assertNoDiffs(b2, b1);
-
- // But not too much slop.
- superWindowResolution();
- Change c3 = clone(c1);
- c3.setLastUpdatedOn(TimeUtil.nowTs());
- b1 =
- new ChangeBundle(
- c1, messages(), patchSets(), approvals(), comments(), reviewers(), NOTE_DB);
- ChangeBundle b3 =
- new ChangeBundle(
- c3, messages(), patchSets(), approvals(), comments(), reviewers(), REVIEW_DB);
- String msg =
- "effective last updated time differs for Change.Id "
- + c1.getId()
- + " in NoteDb vs. ReviewDb:"
- + " {2009-09-30 17:00:01.0} != {2009-09-30 17:00:10.0}";
- assertDiffs(b1, b3, msg);
- assertDiffs(b3, b1, msg);
- }
-
- @Test
- public void diffChangesIgnoresOriginalSubjectInReviewDb() throws Exception {
- Change c1 = TestChanges.newChange(new Project.NameKey("project"), new Account.Id(100));
- c1.setCurrentPatchSet(c1.currentPatchSetId(), "Subject", "Original A");
- Change c2 = clone(c1);
- c2.setCurrentPatchSet(c2.currentPatchSetId(), c1.getSubject(), "Original B");
-
- // Both ReviewDb, exact match required.
- ChangeBundle b1 =
- new ChangeBundle(
- c1, messages(), patchSets(), approvals(), comments(), reviewers(), REVIEW_DB);
- ChangeBundle b2 =
- new ChangeBundle(
- c2, messages(), patchSets(), approvals(), comments(), reviewers(), REVIEW_DB);
- assertDiffs(
- b1,
- b2,
- "originalSubject differs for Change.Id "
- + c1.getId()
- + ":"
- + " {Original A} != {Original B}");
-
- // Both NoteDb, exact match required.
- b1 =
- new ChangeBundle(
- c1, messages(), patchSets(), approvals(), comments(), reviewers(), NOTE_DB);
- b2 =
- new ChangeBundle(
- c2, messages(), patchSets(), approvals(), comments(), reviewers(), NOTE_DB);
- assertDiffs(
- b1,
- b2,
- "originalSubject differs for Change.Id "
- + c1.getId()
- + ":"
- + " {Original A} != {Original B}");
-
- // One ReviewDb, one NoteDb, original subject is ignored.
- b1 =
- new ChangeBundle(
- c1, messages(), patchSets(), approvals(), comments(), reviewers(), REVIEW_DB);
- b2 =
- new ChangeBundle(
- c2, messages(), patchSets(), approvals(), comments(), reviewers(), NOTE_DB);
- assertNoDiffs(b1, b2);
- assertNoDiffs(b2, b1);
- }
-
- @Test
- public void diffChangesSanitizesSubjectsBeforeComparison() throws Exception {
- Change c1 = TestChanges.newChange(new Project.NameKey("project"), new Account.Id(100));
- c1.setCurrentPatchSet(c1.currentPatchSetId(), "Subject\r\rbody", "Original");
- Change c2 = clone(c1);
- c2.setCurrentPatchSet(c2.currentPatchSetId(), "Subject body", "Original");
-
- // Both ReviewDb, exact match required
- ChangeBundle b1 =
- new ChangeBundle(
- c1, messages(), patchSets(), approvals(), comments(), reviewers(), REVIEW_DB);
- ChangeBundle b2 =
- new ChangeBundle(
- c2, messages(), patchSets(), approvals(), comments(), reviewers(), REVIEW_DB);
- assertDiffs(
- b1,
- b2,
- "subject differs for Change.Id "
- + c1.getId()
- + ":"
- + " {Subject\r\rbody} != {Subject body}");
-
- // Both NoteDb, exact match required (although it should be impossible to
- // create a NoteDb change with '\r' in the subject).
- b1 =
- new ChangeBundle(
- c1, messages(), patchSets(), approvals(), comments(), reviewers(), NOTE_DB);
- b2 =
- new ChangeBundle(
- c2, messages(), patchSets(), approvals(), comments(), reviewers(), NOTE_DB);
- assertDiffs(
- b1,
- b2,
- "subject differs for Change.Id "
- + c1.getId()
- + ":"
- + " {Subject\r\rbody} != {Subject body}");
-
- // One ReviewDb, one NoteDb, '\r' is normalized to ' '.
- b1 =
- new ChangeBundle(
- c1, messages(), patchSets(), approvals(), comments(), reviewers(), REVIEW_DB);
- b2 =
- new ChangeBundle(
- c2, messages(), patchSets(), approvals(), comments(), reviewers(), NOTE_DB);
- assertNoDiffs(b1, b2);
- assertNoDiffs(b2, b1);
- }
-
- @Test
- public void diffChangesConsidersEmptyReviewDbTopicEquivalentToNullInNoteDb() throws Exception {
- Change c1 = TestChanges.newChange(new Project.NameKey("project"), new Account.Id(100));
- c1.setTopic("");
- Change c2 = clone(c1);
- c2.setTopic(null);
-
- // Both ReviewDb, exact match required.
- ChangeBundle b1 =
- new ChangeBundle(
- c1, messages(), patchSets(), approvals(), comments(), reviewers(), REVIEW_DB);
- ChangeBundle b2 =
- new ChangeBundle(
- c2, messages(), patchSets(), approvals(), comments(), reviewers(), REVIEW_DB);
- assertDiffs(b1, b2, "topic differs for Change.Id " + c1.getId() + ": {} != {null}");
-
- // Topic ignored if ReviewDb is empty and NoteDb is null.
- b1 =
- new ChangeBundle(
- c1, messages(), patchSets(), approvals(), comments(), reviewers(), REVIEW_DB);
- b2 =
- new ChangeBundle(
- c2, messages(), patchSets(), approvals(), comments(), reviewers(), NOTE_DB);
- assertNoDiffs(b1, b2);
-
- // Exact match still required if NoteDb has empty value (not realistic).
- b1 =
- new ChangeBundle(
- c1, messages(), patchSets(), approvals(), comments(), reviewers(), NOTE_DB);
- b2 =
- new ChangeBundle(
- c2, messages(), patchSets(), approvals(), comments(), reviewers(), REVIEW_DB);
- assertDiffs(b1, b2, "topic differs for Change.Id " + c1.getId() + ": {} != {null}");
-
- // Null is not equal to a non-empty string.
- Change c3 = clone(c1);
- c3.setTopic("topic");
- b1 =
- new ChangeBundle(
- c3, messages(), patchSets(), approvals(), comments(), reviewers(), REVIEW_DB);
- b2 =
- new ChangeBundle(
- c2, messages(), patchSets(), approvals(), comments(), reviewers(), NOTE_DB);
- assertDiffs(b1, b2, "topic differs for Change.Id " + c1.getId() + ": {topic} != {null}");
-
- // Null is equal to a string that is all whitespace.
- Change c4 = clone(c1);
- c4.setTopic(" ");
- b1 =
- new ChangeBundle(
- c4, messages(), patchSets(), approvals(), comments(), reviewers(), REVIEW_DB);
- b2 =
- new ChangeBundle(
- c2, messages(), patchSets(), approvals(), comments(), reviewers(), NOTE_DB);
- assertNoDiffs(b1, b2);
- assertNoDiffs(b2, b1);
- }
-
- @Test
- public void diffChangesIgnoresLeadingAndTrailingWhitespaceInReviewDbTopics() throws Exception {
- Change c1 = TestChanges.newChange(new Project.NameKey("project"), new Account.Id(100));
- c1.setTopic(" abc ");
- Change c2 = clone(c1);
- c2.setTopic("abc");
-
- // Both ReviewDb, exact match required.
- ChangeBundle b1 =
- new ChangeBundle(
- c1, messages(), patchSets(), approvals(), comments(), reviewers(), REVIEW_DB);
- ChangeBundle b2 =
- new ChangeBundle(
- c2, messages(), patchSets(), approvals(), comments(), reviewers(), REVIEW_DB);
- assertDiffs(b1, b2, "topic differs for Change.Id " + c1.getId() + ": { abc } != {abc}");
-
- // Leading whitespace in ReviewDb topic is ignored.
- b1 =
- new ChangeBundle(
- c1, messages(), patchSets(), approvals(), comments(), reviewers(), REVIEW_DB);
- b2 =
- new ChangeBundle(
- c2, messages(), patchSets(), approvals(), comments(), reviewers(), NOTE_DB);
- assertNoDiffs(b1, b2);
- assertNoDiffs(b2, b1);
-
- // Must match except for the leading/trailing whitespace.
- Change c3 = clone(c1);
- c3.setTopic("cba");
- b1 =
- new ChangeBundle(
- c1, messages(), patchSets(), approvals(), comments(), reviewers(), REVIEW_DB);
- b2 =
- new ChangeBundle(
- c3, messages(), patchSets(), approvals(), comments(), reviewers(), NOTE_DB);
- assertDiffs(b1, b2, "topic differs for Change.Id " + c1.getId() + ": { abc } != {cba}");
- }
-
- @Test
- public void diffChangesTakesMaxEntityTimestampFromReviewDb() throws Exception {
- Change c1 = TestChanges.newChange(new Project.NameKey("project"), new Account.Id(100));
- PatchSet ps = new PatchSet(c1.currentPatchSetId());
- ps.setRevision(new RevId("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"));
- ps.setUploader(accountId);
- ps.setCreatedOn(TimeUtil.nowTs());
- PatchSetApproval a =
- new PatchSetApproval(
- new PatchSetApproval.Key(c1.currentPatchSetId(), accountId, new LabelId("Code-Review")),
- (short) 1,
- TimeUtil.nowTs());
-
- Change c2 = clone(c1);
- c2.setLastUpdatedOn(a.getGranted());
-
- // Both ReviewDb, exact match required.
- ChangeBundle b1 =
- new ChangeBundle(
- c1, messages(), patchSets(ps), approvals(a), comments(), reviewers(), REVIEW_DB);
- ChangeBundle b2 =
- new ChangeBundle(
- c2, messages(), patchSets(ps), approvals(a), comments(), reviewers(), REVIEW_DB);
- assertDiffs(
- b1,
- b2,
- "effective last updated time differs for Change.Id "
- + c1.getId()
- + ":"
- + " {2009-09-30 17:00:00.0} != {2009-09-30 17:00:12.0}");
-
- // NoteDb allows latest timestamp from all entities in bundle.
- b2 =
- new ChangeBundle(
- c2, messages(), patchSets(ps), approvals(a), comments(), reviewers(), NOTE_DB);
- assertNoDiffs(b1, b2);
- }
-
- @Test
- public void diffChangesIgnoresChangeTimestampIfAnyOtherEntitiesExist() {
- Change c1 = TestChanges.newChange(new Project.NameKey("project"), new Account.Id(100));
- PatchSet ps = new PatchSet(c1.currentPatchSetId());
- ps.setRevision(new RevId("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"));
- ps.setUploader(accountId);
- ps.setCreatedOn(TimeUtil.nowTs());
- PatchSetApproval a =
- new PatchSetApproval(
- new PatchSetApproval.Key(c1.currentPatchSetId(), accountId, new LabelId("Code-Review")),
- (short) 1,
- TimeUtil.nowTs());
- c1.setLastUpdatedOn(a.getGranted());
-
- Change c2 = clone(c1);
- c2.setLastUpdatedOn(TimeUtil.nowTs());
-
- // ReviewDb has later lastUpdatedOn timestamp than NoteDb, allowed since
- // NoteDb matches the latest timestamp of a non-Change entity.
- ChangeBundle b1 =
- new ChangeBundle(
- c2, messages(), patchSets(ps), approvals(a), comments(), reviewers(), REVIEW_DB);
- ChangeBundle b2 =
- new ChangeBundle(
- c1, messages(), patchSets(ps), approvals(a), comments(), reviewers(), NOTE_DB);
- assertThat(b1.getChange().getLastUpdatedOn()).isGreaterThan(b2.getChange().getLastUpdatedOn());
- assertNoDiffs(b1, b2);
-
- // Timestamps must actually match if Change is the only entity.
- b1 =
- new ChangeBundle(
- c2, messages(), patchSets(), approvals(), comments(), reviewers(), REVIEW_DB);
- b2 =
- new ChangeBundle(
- c1, messages(), patchSets(), approvals(), comments(), reviewers(), NOTE_DB);
- assertDiffs(
- b1,
- b2,
- "effective last updated time differs for Change.Id "
- + c1.getId()
- + " in NoteDb vs. ReviewDb:"
- + " {2009-09-30 17:00:12.0} != {2009-09-30 17:00:18.0}");
- }
-
- @Test
- public void diffChangesAllowsReviewDbSubjectToBePrefixOfNoteDbSubject() throws Exception {
- Change c1 = TestChanges.newChange(new Project.NameKey("project"), new Account.Id(100));
- Change c2 = clone(c1);
- c2.setCurrentPatchSet(
- c1.currentPatchSetId(), c1.getSubject().substring(0, 10), c1.getOriginalSubject());
- assertThat(c2.getSubject()).isNotEqualTo(c1.getSubject());
-
- // Both ReviewDb, exact match required.
- ChangeBundle b1 =
- new ChangeBundle(
- c1, messages(), patchSets(), approvals(), comments(), reviewers(), REVIEW_DB);
- ChangeBundle b2 =
- new ChangeBundle(
- c2, messages(), patchSets(), approvals(), comments(), reviewers(), REVIEW_DB);
- assertDiffs(
- b1,
- b2,
- "subject differs for Change.Id " + c1.getId() + ": {Change subject} != {Change sub}");
-
- // ReviewDb has shorter subject, allowed.
- b1 =
- new ChangeBundle(
- c1, messages(), patchSets(), approvals(), comments(), reviewers(), NOTE_DB);
- b2 =
- new ChangeBundle(
- c2, messages(), patchSets(), approvals(), comments(), reviewers(), REVIEW_DB);
- assertNoDiffs(b1, b2);
-
- // NoteDb has shorter subject, not allowed.
- b1 =
- new ChangeBundle(
- c1, messages(), latest(c1), approvals(), comments(), reviewers(), REVIEW_DB);
- b2 =
- new ChangeBundle(c2, messages(), latest(c2), approvals(), comments(), reviewers(), NOTE_DB);
- assertDiffs(
- b1,
- b2,
- "subject differs for Change.Id " + c1.getId() + ": {Change subject} != {Change sub}");
- }
-
- @Test
- public void diffChangesTrimsLeadingSpacesFromReviewDbComparingToNoteDb() throws Exception {
- Change c1 = TestChanges.newChange(new Project.NameKey("project"), new Account.Id(100));
- Change c2 = clone(c1);
- c2.setCurrentPatchSet(c1.currentPatchSetId(), " " + c1.getSubject(), c1.getOriginalSubject());
-
- // Both ReviewDb, exact match required.
- ChangeBundle b1 =
- new ChangeBundle(
- c1, messages(), patchSets(), approvals(), comments(), reviewers(), REVIEW_DB);
- ChangeBundle b2 =
- new ChangeBundle(
- c2, messages(), patchSets(), approvals(), comments(), reviewers(), REVIEW_DB);
- assertDiffs(
- b1,
- b2,
- "subject differs for Change.Id "
- + c1.getId()
- + ":"
- + " {Change subject} != { Change subject}");
-
- // ReviewDb is missing leading spaces, allowed.
- b1 =
- new ChangeBundle(
- c1, messages(), patchSets(), approvals(), comments(), reviewers(), NOTE_DB);
- b2 =
- new ChangeBundle(
- c2, messages(), patchSets(), approvals(), comments(), reviewers(), REVIEW_DB);
- assertNoDiffs(b1, b2);
- assertNoDiffs(b2, b1);
- }
-
- @Test
- public void diffChangesDoesntTrimLeadingNonSpaceWhitespaceFromSubject() throws Exception {
- Change c1 = TestChanges.newChange(new Project.NameKey("project"), new Account.Id(100));
- Change c2 = clone(c1);
- c2.setCurrentPatchSet(c1.currentPatchSetId(), "\t" + c1.getSubject(), c1.getOriginalSubject());
-
- // Both ReviewDb.
- ChangeBundle b1 =
- new ChangeBundle(
- c1, messages(), patchSets(), approvals(), comments(), reviewers(), REVIEW_DB);
- ChangeBundle b2 =
- new ChangeBundle(
- c2, messages(), patchSets(), approvals(), comments(), reviewers(), REVIEW_DB);
- assertDiffs(
- b1,
- b2,
- "subject differs for Change.Id "
- + c1.getId()
- + ":"
- + " {Change subject} != {\tChange subject}");
-
- // One NoteDb.
- b1 =
- new ChangeBundle(c1, messages(), latest(c1), approvals(), comments(), reviewers(), NOTE_DB);
- b2 =
- new ChangeBundle(
- c2, messages(), latest(c2), approvals(), comments(), reviewers(), REVIEW_DB);
- assertDiffs(
- b1,
- b2,
- "subject differs for Change.Id "
- + c1.getId()
- + ":"
- + " {Change subject} != {\tChange subject}");
- assertDiffs(
- b2,
- b1,
- "subject differs for Change.Id "
- + c1.getId()
- + ":"
- + " {\tChange subject} != {Change subject}");
- }
-
- @Test
- public void diffChangesHandlesBuggyJGitSubjectExtraction() throws Exception {
- Change c1 = TestChanges.newChange(project, accountId);
- String buggySubject = "Subject\r \r Rest of message.";
- c1.setCurrentPatchSet(c1.currentPatchSetId(), buggySubject, buggySubject);
- Change c2 = clone(c1);
- c2.setCurrentPatchSet(c2.currentPatchSetId(), "Subject", "Subject");
-
- // Both ReviewDb.
- ChangeBundle b1 =
- new ChangeBundle(
- c1, messages(), patchSets(), approvals(), comments(), reviewers(), REVIEW_DB);
- ChangeBundle b2 =
- new ChangeBundle(
- c2, messages(), patchSets(), approvals(), comments(), reviewers(), REVIEW_DB);
- assertDiffs(
- b1,
- b2,
- "originalSubject differs for Change.Id "
- + c1.getId()
- + ":"
- + " {Subject\r \r Rest of message.} != {Subject}",
- "subject differs for Change.Id "
- + c1.getId()
- + ":"
- + " {Subject\r \r Rest of message.} != {Subject}");
-
- // NoteDb has correct subject without "\r ".
- b1 =
- new ChangeBundle(
- c1, messages(), patchSets(), approvals(), comments(), reviewers(), REVIEW_DB);
- b2 =
- new ChangeBundle(
- c2, messages(), patchSets(), approvals(), comments(), reviewers(), NOTE_DB);
- assertNoDiffs(b1, b2);
- assertNoDiffs(b2, b1);
- }
-
- @Test
- public void diffChangesIgnoresInvalidCurrentPatchSetIdInReviewDb() throws Exception {
- Change c1 = TestChanges.newChange(new Project.NameKey("project"), new Account.Id(100));
- Change c2 = clone(c1);
- c2.setCurrentPatchSet(
- new PatchSet.Id(c2.getId(), 0), "Unrelated subject", c2.getOriginalSubject());
-
- // Both ReviewDb.
- ChangeBundle b1 =
- new ChangeBundle(
- c1, messages(), patchSets(), approvals(), comments(), reviewers(), REVIEW_DB);
- ChangeBundle b2 =
- new ChangeBundle(
- c2, messages(), patchSets(), approvals(), comments(), reviewers(), REVIEW_DB);
- assertDiffs(
- b1,
- b2,
- "currentPatchSetId differs for Change.Id " + c1.getId() + ": {1} != {0}",
- "subject differs for Change.Id "
- + c1.getId()
- + ":"
- + " {Change subject} != {Unrelated subject}");
-
- // One NoteDb.
- //
- // This is based on a real corrupt change where all patch sets were deleted
- // but the Change entity stuck around, resulting in a currentPatchSetId of 0
- // after converting to NoteDb.
- b1 =
- new ChangeBundle(
- c1, messages(), patchSets(), approvals(), comments(), reviewers(), REVIEW_DB);
- b2 =
- new ChangeBundle(
- c2, messages(), patchSets(), approvals(), comments(), reviewers(), NOTE_DB);
- assertNoDiffs(b1, b2);
- assertNoDiffs(b2, b1);
- }
-
- @Test
- public void diffChangesAllowsCreatedToMatchLastUpdated() throws Exception {
- Change c1 = TestChanges.newChange(new Project.NameKey("project"), new Account.Id(100));
- c1.setCreatedOn(TimeUtil.nowTs());
- assertThat(c1.getCreatedOn()).isGreaterThan(c1.getLastUpdatedOn());
- Change c2 = clone(c1);
- c2.setCreatedOn(c2.getLastUpdatedOn());
-
- // Both ReviewDb.
- ChangeBundle b1 =
- new ChangeBundle(
- c1, messages(), patchSets(), approvals(), comments(), reviewers(), REVIEW_DB);
- ChangeBundle b2 =
- new ChangeBundle(
- c2, messages(), patchSets(), approvals(), comments(), reviewers(), REVIEW_DB);
- assertDiffs(
- b1,
- b2,
- "createdOn differs for Change.Id "
- + c1.getId()
- + ": {2009-09-30 17:00:06.0} != {2009-09-30 17:00:00.0}");
-
- // One NoteDb.
- b1 =
- new ChangeBundle(
- c1, messages(), patchSets(), approvals(), comments(), reviewers(), REVIEW_DB);
- b2 =
- new ChangeBundle(
- c2, messages(), patchSets(), approvals(), comments(), reviewers(), NOTE_DB);
- assertNoDiffs(b1, b2);
- assertNoDiffs(b2, b1);
- }
-
- @Test
- public void diffChangeMessageKeySets() throws Exception {
- Change c = TestChanges.newChange(project, accountId);
- int id = c.getId().get();
- ChangeMessage cm1 =
- new ChangeMessage(
- new ChangeMessage.Key(c.getId(), "uuid1"),
- accountId,
- TimeUtil.nowTs(),
- c.currentPatchSetId());
- ChangeMessage cm2 =
- new ChangeMessage(
- new ChangeMessage.Key(c.getId(), "uuid2"),
- accountId,
- TimeUtil.nowTs(),
- c.currentPatchSetId());
- ChangeBundle b1 =
- new ChangeBundle(
- c, messages(cm1), latest(c), approvals(), comments(), reviewers(), REVIEW_DB);
- ChangeBundle b2 =
- new ChangeBundle(
- c, messages(cm2), latest(c), approvals(), comments(), reviewers(), REVIEW_DB);
-
- assertDiffs(
- b1,
- b2,
- "ChangeMessage.Key sets differ:"
- + " ["
- + id
- + ",uuid1] only in A; ["
- + id
- + ",uuid2] only in B");
- }
-
- @Test
- public void diffChangeMessages() throws Exception {
- Change c = TestChanges.newChange(project, accountId);
- ChangeMessage cm1 =
- new ChangeMessage(
- new ChangeMessage.Key(c.getId(), "uuid"),
- accountId,
- TimeUtil.nowTs(),
- c.currentPatchSetId());
- cm1.setMessage("message 1");
- ChangeMessage cm2 = clone(cm1);
- ChangeBundle b1 =
- new ChangeBundle(
- c, messages(cm1), latest(c), approvals(), comments(), reviewers(), REVIEW_DB);
- ChangeBundle b2 =
- new ChangeBundle(
- c, messages(cm2), latest(c), approvals(), comments(), reviewers(), REVIEW_DB);
-
- assertNoDiffs(b1, b2);
-
- cm2.setMessage("message 2");
- assertDiffs(
- b1,
- b2,
- "message differs for ChangeMessage.Key "
- + c.getId()
- + ",uuid:"
- + " {message 1} != {message 2}");
- }
-
- @Test
- public void diffChangeMessagesIgnoresUuids() throws Exception {
- Change c = TestChanges.newChange(project, accountId);
- int id = c.getId().get();
- ChangeMessage cm1 =
- new ChangeMessage(
- new ChangeMessage.Key(c.getId(), "uuid1"),
- accountId,
- TimeUtil.nowTs(),
- c.currentPatchSetId());
- cm1.setMessage("message 1");
- ChangeMessage cm2 = clone(cm1);
- cm2.getKey().set("uuid2");
-
- ChangeBundle b1 =
- new ChangeBundle(
- c, messages(cm1), latest(c), approvals(), comments(), reviewers(), REVIEW_DB);
- ChangeBundle b2 =
- new ChangeBundle(
- c, messages(cm2), latest(c), approvals(), comments(), reviewers(), REVIEW_DB);
- // Both are ReviewDb, exact UUID match is required.
- assertDiffs(
- b1,
- b2,
- "ChangeMessage.Key sets differ:"
- + " ["
- + id
- + ",uuid1] only in A; ["
- + id
- + ",uuid2] only in B");
-
- // One NoteDb, UUIDs are ignored.
- b1 =
- new ChangeBundle(
- c, messages(cm1), latest(c), approvals(), comments(), reviewers(), REVIEW_DB);
- b2 =
- new ChangeBundle(
- c, messages(cm2), latest(c), approvals(), comments(), reviewers(), NOTE_DB);
- assertNoDiffs(b1, b2);
- }
-
- @Test
- public void diffChangeMessagesWithDifferentCounts() throws Exception {
- Change c = TestChanges.newChange(project, accountId);
- int id = c.getId().get();
- ChangeMessage cm1 =
- new ChangeMessage(
- new ChangeMessage.Key(c.getId(), "uuid1"),
- accountId,
- TimeUtil.nowTs(),
- c.currentPatchSetId());
- cm1.setMessage("message 1");
- ChangeMessage cm2 =
- new ChangeMessage(
- new ChangeMessage.Key(c.getId(), "uuid2"),
- accountId,
- TimeUtil.nowTs(),
- c.currentPatchSetId());
- cm1.setMessage("message 2");
-
- // Both ReviewDb: Uses same keySet diff as other types.
- ChangeBundle b1 =
- new ChangeBundle(
- c, messages(cm1, cm2), latest(c), approvals(), comments(), reviewers(), REVIEW_DB);
- ChangeBundle b2 =
- new ChangeBundle(
- c, messages(cm1), latest(c), approvals(), comments(), reviewers(), REVIEW_DB);
- assertDiffs(
- b1, b2, "ChangeMessage.Key sets differ: [" + id + ",uuid2] only in A; [] only in B");
-
- // One NoteDb: UUIDs in keys can't be used for comparison, just diff counts.
- b1 =
- new ChangeBundle(
- c, messages(cm1, cm2), latest(c), approvals(), comments(), reviewers(), REVIEW_DB);
- b2 =
- new ChangeBundle(
- c, messages(cm1), latest(c), approvals(), comments(), reviewers(), NOTE_DB);
- assertDiffs(b1, b2, "ChangeMessages differ for Change.Id " + id + "\nOnly in A:\n " + cm2);
- assertDiffs(b2, b1, "ChangeMessages differ for Change.Id " + id + "\nOnly in B:\n " + cm2);
- }
-
- @Test
- public void diffChangeMessagesMixedSourcesWithDifferences() throws Exception {
- Change c = TestChanges.newChange(project, accountId);
- int id = c.getId().get();
- ChangeMessage cm1 =
- new ChangeMessage(
- new ChangeMessage.Key(c.getId(), "uuid1"),
- accountId,
- TimeUtil.nowTs(),
- c.currentPatchSetId());
- cm1.setMessage("message 1");
- ChangeMessage cm2 = clone(cm1);
- cm2.setMessage("message 2");
- ChangeMessage cm3 = clone(cm1);
- cm3.getKey().set("uuid2"); // Differs only in UUID.
-
- ChangeBundle b1 =
- new ChangeBundle(
- c, messages(cm1, cm3), latest(c), approvals(), comments(), reviewers(), REVIEW_DB);
- ChangeBundle b2 =
- new ChangeBundle(
- c, messages(cm2, cm3), latest(c), approvals(), comments(), reviewers(), NOTE_DB);
- // Implementation happens to pair up cm1 in b1 with cm3 in b2 because it
- // depends on iteration order and doesn't care about UUIDs. The important
- // thing is that there's some diff.
- assertDiffs(
- b1,
- b2,
- "ChangeMessages differ for Change.Id "
- + id
- + "\n"
- + "Only in A:\n "
- + cm3
- + "\n"
- + "Only in B:\n "
- + cm2);
- assertDiffs(
- b2,
- b1,
- "ChangeMessages differ for Change.Id "
- + id
- + "\n"
- + "Only in A:\n "
- + cm2
- + "\n"
- + "Only in B:\n "
- + cm3);
- }
-
- @Test
- public void diffChangeMessagesMixedSourcesAllowsSlop() throws Exception {
- subWindowResolution();
- Change c = TestChanges.newChange(project, accountId);
- ChangeMessage cm1 =
- new ChangeMessage(
- new ChangeMessage.Key(c.getId(), "uuid1"),
- accountId,
- TimeUtil.nowTs(),
- c.currentPatchSetId());
- ChangeMessage cm2 = clone(cm1);
- cm2.setWrittenOn(TimeUtil.nowTs());
-
- // Both are ReviewDb, exact timestamp match is required.
- ChangeBundle b1 =
- new ChangeBundle(
- c, messages(cm1), latest(c), approvals(), comments(), reviewers(), REVIEW_DB);
- ChangeBundle b2 =
- new ChangeBundle(
- c, messages(cm2), latest(c), approvals(), comments(), reviewers(), REVIEW_DB);
- assertDiffs(
- b1,
- b2,
- "writtenOn differs for ChangeMessage.Key "
- + c.getId()
- + ",uuid1:"
- + " {2009-09-30 17:00:02.0} != {2009-09-30 17:00:03.0}");
-
- // One NoteDb, slop is allowed.
- b1 =
- new ChangeBundle(
- c, messages(cm1), latest(c), approvals(), comments(), reviewers(), NOTE_DB);
- b2 =
- new ChangeBundle(
- c, messages(cm2), latest(c), approvals(), comments(), reviewers(), REVIEW_DB);
- assertNoDiffs(b1, b2);
- assertNoDiffs(b2, b1);
-
- // But not too much slop.
- superWindowResolution();
- ChangeMessage cm3 = clone(cm1);
- cm3.setWrittenOn(TimeUtil.nowTs());
- b1 =
- new ChangeBundle(
- c, messages(cm1), latest(c), approvals(), comments(), reviewers(), NOTE_DB);
- ChangeBundle b3 =
- new ChangeBundle(
- c, messages(cm3), latest(c), approvals(), comments(), reviewers(), REVIEW_DB);
- int id = c.getId().get();
- assertDiffs(
- b1,
- b3,
- "ChangeMessages differ for Change.Id "
- + id
- + "\n"
- + "Only in A:\n "
- + cm1
- + "\n"
- + "Only in B:\n "
- + cm3);
- assertDiffs(
- b3,
- b1,
- "ChangeMessages differ for Change.Id "
- + id
- + "\n"
- + "Only in A:\n "
- + cm3
- + "\n"
- + "Only in B:\n "
- + cm1);
- }
-
- @Test
- public void diffChangeMessagesAllowsNullPatchSetIdFromReviewDb() throws Exception {
- Change c = TestChanges.newChange(project, accountId);
- int id = c.getId().get();
- ChangeMessage cm1 =
- new ChangeMessage(
- new ChangeMessage.Key(c.getId(), "uuid"),
- accountId,
- TimeUtil.nowTs(),
- c.currentPatchSetId());
- cm1.setMessage("message 1");
- ChangeMessage cm2 = clone(cm1);
- cm2.setPatchSetId(null);
-
- ChangeBundle b1 =
- new ChangeBundle(
- c, messages(cm1), latest(c), approvals(), comments(), reviewers(), REVIEW_DB);
- ChangeBundle b2 =
- new ChangeBundle(
- c, messages(cm2), latest(c), approvals(), comments(), reviewers(), REVIEW_DB);
-
- // Both are ReviewDb, exact patch set ID match is required.
- assertDiffs(
- b1,
- b2,
- "patchset differs for ChangeMessage.Key "
- + c.getId()
- + ",uuid:"
- + " {"
- + id
- + ",1} != {null}");
-
- // Null patch set ID on ReviewDb is ignored.
- b1 =
- new ChangeBundle(
- c, messages(cm1), latest(c), approvals(), comments(), reviewers(), NOTE_DB);
- b2 =
- new ChangeBundle(
- c, messages(cm2), latest(c), approvals(), comments(), reviewers(), REVIEW_DB);
- assertNoDiffs(b1, b2);
-
- // Null patch set ID on NoteDb is not ignored (but is not realistic).
- b1 =
- new ChangeBundle(
- c, messages(cm1), latest(c), approvals(), comments(), reviewers(), REVIEW_DB);
- b2 =
- new ChangeBundle(
- c, messages(cm2), latest(c), approvals(), comments(), reviewers(), NOTE_DB);
- assertDiffs(
- b1,
- b2,
- "ChangeMessages differ for Change.Id "
- + id
- + "\n"
- + "Only in A:\n "
- + cm1
- + "\n"
- + "Only in B:\n "
- + cm2);
- assertDiffs(
- b2,
- b1,
- "ChangeMessages differ for Change.Id "
- + id
- + "\n"
- + "Only in A:\n "
- + cm2
- + "\n"
- + "Only in B:\n "
- + cm1);
- }
-
- @Test
- public void diffPatchSetIdSets() throws Exception {
- Change c = TestChanges.newChange(project, accountId);
- TestChanges.incrementPatchSet(c);
-
- PatchSet ps1 = new PatchSet(new PatchSet.Id(c.getId(), 1));
- ps1.setRevision(new RevId("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"));
- ps1.setUploader(accountId);
- ps1.setCreatedOn(TimeUtil.nowTs());
- PatchSet ps2 = new PatchSet(new PatchSet.Id(c.getId(), 2));
- ps2.setRevision(new RevId("badc0feebadc0feebadc0feebadc0feebadc0fee"));
- ps2.setUploader(accountId);
- ps2.setCreatedOn(TimeUtil.nowTs());
-
- ChangeBundle b1 =
- new ChangeBundle(
- c, messages(), patchSets(ps2), approvals(), comments(), reviewers(), REVIEW_DB);
- ChangeBundle b2 =
- new ChangeBundle(
- c, messages(), patchSets(ps1, ps2), approvals(), comments(), reviewers(), REVIEW_DB);
-
- assertDiffs(b1, b2, "PatchSet.Id sets differ: [] only in A; [" + c.getId() + ",1] only in B");
- }
-
- @Test
- public void diffPatchSets() throws Exception {
- Change c = TestChanges.newChange(project, accountId);
- PatchSet ps1 = new PatchSet(c.currentPatchSetId());
- ps1.setRevision(new RevId("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"));
- ps1.setUploader(accountId);
- ps1.setCreatedOn(TimeUtil.nowTs());
- PatchSet ps2 = clone(ps1);
- ChangeBundle b1 =
- new ChangeBundle(
- c, messages(), patchSets(ps1), approvals(), comments(), reviewers(), REVIEW_DB);
- ChangeBundle b2 =
- new ChangeBundle(
- c, messages(), patchSets(ps2), approvals(), comments(), reviewers(), REVIEW_DB);
-
- assertNoDiffs(b1, b2);
-
- ps2.setRevision(new RevId("badc0feebadc0feebadc0feebadc0feebadc0fee"));
- assertDiffs(
- b1,
- b2,
- "revision differs for PatchSet.Id "
- + c.getId()
- + ",1:"
- + " {RevId{deadbeefdeadbeefdeadbeefdeadbeefdeadbeef}}"
- + " != {RevId{badc0feebadc0feebadc0feebadc0feebadc0fee}}");
- }
-
- @Test
- public void diffPatchSetsMixedSourcesAllowsSlop() throws Exception {
- subWindowResolution();
- Change c = TestChanges.newChange(project, accountId);
- PatchSet ps1 = new PatchSet(c.currentPatchSetId());
- ps1.setRevision(new RevId("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"));
- ps1.setUploader(accountId);
- ps1.setCreatedOn(roundToSecond(TimeUtil.nowTs()));
- PatchSet ps2 = clone(ps1);
- ps2.setCreatedOn(TimeUtil.nowTs());
-
- // Both are ReviewDb, exact timestamp match is required.
- ChangeBundle b1 =
- new ChangeBundle(
- c, messages(), patchSets(ps1), approvals(), comments(), reviewers(), REVIEW_DB);
- ChangeBundle b2 =
- new ChangeBundle(
- c, messages(), patchSets(ps2), approvals(), comments(), reviewers(), REVIEW_DB);
- assertDiffs(
- b1,
- b2,
- "createdOn differs for PatchSet.Id "
- + c.getId()
- + ",1:"
- + " {2009-09-30 17:00:02.0} != {2009-09-30 17:00:03.0}");
-
- // One NoteDb, slop is allowed.
- b1 =
- new ChangeBundle(
- c, messages(), patchSets(ps1), approvals(), comments(), reviewers(), NOTE_DB);
- b2 =
- new ChangeBundle(
- c, messages(), patchSets(ps2), approvals(), comments(), reviewers(), REVIEW_DB);
- assertNoDiffs(b1, b2);
-
- // But not too much slop.
- superWindowResolution();
- PatchSet ps3 = clone(ps1);
- ps3.setCreatedOn(TimeUtil.nowTs());
- b1 =
- new ChangeBundle(
- c, messages(), patchSets(ps1), approvals(), comments(), reviewers(), NOTE_DB);
- ChangeBundle b3 =
- new ChangeBundle(
- c, messages(), patchSets(ps3), approvals(), comments(), reviewers(), REVIEW_DB);
- String msg =
- "createdOn differs for PatchSet.Id "
- + c.getId()
- + ",1 in NoteDb vs. ReviewDb:"
- + " {2009-09-30 17:00:02.0} != {2009-09-30 17:00:10.0}";
- assertDiffs(b1, b3, msg);
- assertDiffs(b3, b1, msg);
- }
-
- @Test
- public void diffPatchSetsIgnoresTrailingNewlinesInPushCertificate() throws Exception {
- subWindowResolution();
- Change c = TestChanges.newChange(project, accountId);
- PatchSet ps1 = new PatchSet(c.currentPatchSetId());
- ps1.setRevision(new RevId("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"));
- ps1.setUploader(accountId);
- ps1.setCreatedOn(roundToSecond(TimeUtil.nowTs()));
- ps1.setPushCertificate("some cert");
- PatchSet ps2 = clone(ps1);
- ps2.setPushCertificate(ps2.getPushCertificate() + "\n\n");
-
- ChangeBundle b1 =
- new ChangeBundle(
- c, messages(), patchSets(ps1), approvals(), comments(), reviewers(), NOTE_DB);
- ChangeBundle b2 =
- new ChangeBundle(
- c, messages(), patchSets(ps2), approvals(), comments(), reviewers(), REVIEW_DB);
- assertNoDiffs(b1, b2);
- assertNoDiffs(b2, b1);
-
- b1 =
- new ChangeBundle(
- c, messages(), patchSets(ps1), approvals(), comments(), reviewers(), REVIEW_DB);
- b2 =
- new ChangeBundle(
- c, messages(), patchSets(ps2), approvals(), comments(), reviewers(), NOTE_DB);
- assertNoDiffs(b1, b2);
- assertNoDiffs(b2, b1);
- }
-
- @Test
- public void diffPatchSetsGreaterThanCurrent() throws Exception {
- Change c = TestChanges.newChange(project, accountId);
-
- PatchSet ps1 = new PatchSet(new PatchSet.Id(c.getId(), 1));
- ps1.setRevision(new RevId("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"));
- ps1.setUploader(accountId);
- ps1.setCreatedOn(TimeUtil.nowTs());
- PatchSet ps2 = new PatchSet(new PatchSet.Id(c.getId(), 2));
- ps2.setRevision(new RevId("badc0feebadc0feebadc0feebadc0feebadc0fee"));
- ps2.setUploader(accountId);
- ps2.setCreatedOn(TimeUtil.nowTs());
- assertThat(ps2.getId().get()).isGreaterThan(c.currentPatchSetId().get());
-
- ChangeMessage cm1 =
- new ChangeMessage(
- new ChangeMessage.Key(c.getId(), "uuid1"),
- accountId,
- TimeUtil.nowTs(),
- c.currentPatchSetId());
- ChangeMessage cm2 =
- new ChangeMessage(
- new ChangeMessage.Key(c.getId(), "uuid2"),
- accountId,
- TimeUtil.nowTs(),
- c.currentPatchSetId());
-
- PatchSetApproval a1 =
- new PatchSetApproval(
- new PatchSetApproval.Key(ps1.getId(), accountId, new LabelId("Code-Review")),
- (short) 1,
- TimeUtil.nowTs());
- PatchSetApproval a2 =
- new PatchSetApproval(
- new PatchSetApproval.Key(ps2.getId(), accountId, new LabelId("Code-Review")),
- (short) 1,
- TimeUtil.nowTs());
-
- // Both ReviewDb.
- ChangeBundle b1 =
- new ChangeBundle(
- c, messages(cm1), patchSets(ps1), approvals(a1), comments(), reviewers(), REVIEW_DB);
- ChangeBundle b2 =
- new ChangeBundle(
- c,
- messages(cm1, cm2),
- patchSets(ps1, ps2),
- approvals(a1, a2),
- comments(),
- reviewers(),
- REVIEW_DB);
- assertDiffs(
- b1,
- b2,
- "ChangeMessage.Key sets differ: [] only in A; [" + cm2.getKey() + "] only in B",
- "PatchSet.Id sets differ: [] only in A; [" + ps2.getId() + "] only in B",
- "PatchSetApproval.Key sets differ: [] only in A; [" + a2.getKey() + "] only in B");
-
- // One NoteDb.
- b1 =
- new ChangeBundle(
- c, messages(cm1), patchSets(ps1), approvals(a1), comments(), reviewers(), NOTE_DB);
- b2 =
- new ChangeBundle(
- c,
- messages(cm1, cm2),
- patchSets(ps1, ps2),
- approvals(a1, a2),
- comments(),
- reviewers(),
- REVIEW_DB);
- assertDiffs(
- b1,
- b2,
- "ChangeMessages differ for Change.Id " + c.getId() + "\nOnly in B:\n " + cm2,
- "PatchSet.Id sets differ: [] only in A; [" + ps2.getId() + "] only in B",
- "PatchSetApproval.Key sets differ: [] only in A; [" + a2.getKey() + "] only in B");
-
- // Both NoteDb.
- b1 =
- new ChangeBundle(
- c, messages(cm1), patchSets(ps1), approvals(a1), comments(), reviewers(), NOTE_DB);
- b2 =
- new ChangeBundle(
- c,
- messages(cm1, cm2),
- patchSets(ps1, ps2),
- approvals(a1, a2),
- comments(),
- reviewers(),
- NOTE_DB);
- assertDiffs(
- b1,
- b2,
- "ChangeMessages differ for Change.Id " + c.getId() + "\nOnly in B:\n " + cm2,
- "PatchSet.Id sets differ: [] only in A; [" + ps2.getId() + "] only in B",
- "PatchSetApproval.Key sets differ: [] only in A; [" + a2.getKey() + "] only in B");
- }
-
- @Test
- public void diffPatchSetsIgnoresLeadingAndTrailingWhitespaceInReviewDbDescriptions()
- throws Exception {
- Change c = TestChanges.newChange(project, accountId);
-
- PatchSet ps1 = new PatchSet(new PatchSet.Id(c.getId(), 1));
- ps1.setRevision(new RevId("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"));
- ps1.setUploader(accountId);
- ps1.setCreatedOn(TimeUtil.nowTs());
- ps1.setDescription(" abc ");
- PatchSet ps2 = clone(ps1);
- ps2.setDescription("abc");
-
- // Both ReviewDb, exact match required.
- ChangeBundle b1 =
- new ChangeBundle(
- c, messages(), patchSets(ps1), approvals(), comments(), reviewers(), REVIEW_DB);
- ChangeBundle b2 =
- new ChangeBundle(
- c, messages(), patchSets(ps2), approvals(), comments(), reviewers(), REVIEW_DB);
- assertDiffs(
- b1, b2, "description differs for PatchSet.Id " + ps1.getId() + ": { abc } != {abc}");
-
- // Whitespace in ReviewDb description is ignored.
- b1 =
- new ChangeBundle(
- c, messages(), patchSets(ps1), approvals(), comments(), reviewers(), REVIEW_DB);
- b2 =
- new ChangeBundle(
- c, messages(), patchSets(ps2), approvals(), comments(), reviewers(), NOTE_DB);
- assertNoDiffs(b1, b2);
- assertNoDiffs(b2, b1);
-
- // Must match except for the leading/trailing whitespace.
- PatchSet ps3 = clone(ps1);
- ps3.setDescription("cba");
- b1 =
- new ChangeBundle(
- c, messages(), patchSets(ps1), approvals(), comments(), reviewers(), REVIEW_DB);
- b2 =
- new ChangeBundle(
- c, messages(), patchSets(ps3), approvals(), comments(), reviewers(), NOTE_DB);
- assertDiffs(
- b1, b2, "description differs for PatchSet.Id " + ps1.getId() + ": { abc } != {cba}");
- }
-
- @Test
- public void diffPatchSetsIgnoresCreatedOnWhenReviewDbIsNonMonotonic() throws Exception {
- Change c = TestChanges.newChange(project, accountId);
-
- Timestamp beforePs1 = TimeUtil.nowTs();
-
- PatchSet goodPs1 = new PatchSet(new PatchSet.Id(c.getId(), 1));
- goodPs1.setRevision(new RevId("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"));
- goodPs1.setUploader(accountId);
- goodPs1.setCreatedOn(TimeUtil.nowTs());
- PatchSet goodPs2 = new PatchSet(new PatchSet.Id(c.getId(), 2));
- goodPs2.setRevision(new RevId("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"));
- goodPs2.setUploader(accountId);
- goodPs2.setCreatedOn(TimeUtil.nowTs());
- assertThat(goodPs2.getCreatedOn()).isGreaterThan(goodPs1.getCreatedOn());
-
- PatchSet badPs2 = clone(goodPs2);
- badPs2.setCreatedOn(beforePs1);
- assertThat(badPs2.getCreatedOn()).isLessThan(goodPs1.getCreatedOn());
-
- // Both ReviewDb, exact match required.
- ChangeBundle b1 =
- new ChangeBundle(
- c,
- messages(),
- patchSets(goodPs1, goodPs2),
- approvals(),
- comments(),
- reviewers(),
- REVIEW_DB);
- ChangeBundle b2 =
- new ChangeBundle(
- c,
- messages(),
- patchSets(goodPs1, badPs2),
- approvals(),
- comments(),
- reviewers(),
- REVIEW_DB);
- assertDiffs(
- b1,
- b2,
- "createdOn differs for PatchSet.Id "
- + badPs2.getId()
- + ":"
- + " {2009-09-30 17:00:18.0} != {2009-09-30 17:00:06.0}");
-
- // Non-monotonic in ReviewDb but monotonic in NoteDb, timestamps are
- // ignored, including for ps1.
- PatchSet badPs1 = clone(goodPs1);
- badPs1.setCreatedOn(TimeUtil.nowTs());
- b1 =
- new ChangeBundle(
- c,
- messages(),
- patchSets(badPs1, badPs2),
- approvals(),
- comments(),
- reviewers(),
- REVIEW_DB);
- b2 =
- new ChangeBundle(
- c,
- messages(),
- patchSets(goodPs1, goodPs2),
- approvals(),
- comments(),
- reviewers(),
- NOTE_DB);
- assertNoDiffs(b1, b2);
- assertNoDiffs(b2, b1);
-
- // Non-monotonic in NoteDb but monotonic in ReviewDb, timestamps are not
- // ignored.
- b1 =
- new ChangeBundle(
- c,
- messages(),
- patchSets(goodPs1, goodPs2),
- approvals(),
- comments(),
- reviewers(),
- REVIEW_DB);
- b2 =
- new ChangeBundle(
- c,
- messages(),
- patchSets(badPs1, badPs2),
- approvals(),
- comments(),
- reviewers(),
- NOTE_DB);
- assertDiffs(
- b1,
- b2,
- "createdOn differs for PatchSet.Id "
- + badPs1.getId()
- + " in NoteDb vs. ReviewDb:"
- + " {2009-09-30 17:00:24.0} != {2009-09-30 17:00:12.0}",
- "createdOn differs for PatchSet.Id "
- + badPs2.getId()
- + " in NoteDb vs. ReviewDb:"
- + " {2009-09-30 17:00:06.0} != {2009-09-30 17:00:18.0}");
- }
-
- @Test
- public void diffPatchSetsAllowsFirstPatchSetCreatedOnToMatchChangeCreatedOn() {
- Change c = TestChanges.newChange(project, accountId);
- c.setLastUpdatedOn(TimeUtil.nowTs());
-
- PatchSet goodPs1 = new PatchSet(new PatchSet.Id(c.getId(), 1));
- goodPs1.setRevision(new RevId("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"));
- goodPs1.setUploader(accountId);
- goodPs1.setCreatedOn(TimeUtil.nowTs());
- assertThat(goodPs1.getCreatedOn()).isGreaterThan(c.getCreatedOn());
-
- PatchSet ps1AtCreatedOn = clone(goodPs1);
- ps1AtCreatedOn.setCreatedOn(c.getCreatedOn());
-
- PatchSet goodPs2 = new PatchSet(new PatchSet.Id(c.getId(), 2));
- goodPs2.setRevision(new RevId("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"));
- goodPs2.setUploader(accountId);
- goodPs2.setCreatedOn(TimeUtil.nowTs());
-
- PatchSet ps2AtCreatedOn = clone(goodPs2);
- ps2AtCreatedOn.setCreatedOn(c.getCreatedOn());
-
- // Both ReviewDb, exact match required.
- ChangeBundle b1 =
- new ChangeBundle(
- c,
- messages(),
- patchSets(goodPs1, goodPs2),
- approvals(),
- comments(),
- reviewers(),
- REVIEW_DB);
- ChangeBundle b2 =
- new ChangeBundle(
- c,
- messages(),
- patchSets(ps1AtCreatedOn, ps2AtCreatedOn),
- approvals(),
- comments(),
- reviewers(),
- REVIEW_DB);
- assertDiffs(
- b1,
- b2,
- "createdOn differs for PatchSet.Id "
- + c.getId()
- + ",1: {2009-09-30 17:00:12.0} != {2009-09-30 17:00:00.0}",
- "createdOn differs for PatchSet.Id "
- + c.getId()
- + ",2: {2009-09-30 17:00:18.0} != {2009-09-30 17:00:00.0}");
-
- // One ReviewDb, PS1 is allowed to match change createdOn, but PS2 isn't.
- b1 =
- new ChangeBundle(
- c,
- messages(),
- patchSets(goodPs1, goodPs2),
- approvals(),
- comments(),
- reviewers(),
- REVIEW_DB);
- b2 =
- new ChangeBundle(
- c,
- messages(),
- patchSets(ps1AtCreatedOn, ps2AtCreatedOn),
- approvals(),
- comments(),
- reviewers(),
- NOTE_DB);
- assertDiffs(
- b1,
- b2,
- "createdOn differs for PatchSet.Id "
- + c.getId()
- + ",2 in NoteDb vs. ReviewDb: {2009-09-30 17:00:00.0} != {2009-09-30 17:00:18.0}");
- assertDiffs(
- b2,
- b1,
- "createdOn differs for PatchSet.Id "
- + c.getId()
- + ",2 in NoteDb vs. ReviewDb: {2009-09-30 17:00:00.0} != {2009-09-30 17:00:18.0}");
- }
-
- @Test
- public void diffPatchSetApprovalKeySets() throws Exception {
- Change c = TestChanges.newChange(project, accountId);
- int id = c.getId().get();
- PatchSetApproval a1 =
- new PatchSetApproval(
- new PatchSetApproval.Key(c.currentPatchSetId(), accountId, new LabelId("Code-Review")),
- (short) 1,
- TimeUtil.nowTs());
- PatchSetApproval a2 =
- new PatchSetApproval(
- new PatchSetApproval.Key(c.currentPatchSetId(), accountId, new LabelId("Verified")),
- (short) 1,
- TimeUtil.nowTs());
-
- ChangeBundle b1 =
- new ChangeBundle(
- c, messages(), latest(c), approvals(a1), comments(), reviewers(), REVIEW_DB);
- ChangeBundle b2 =
- new ChangeBundle(
- c, messages(), latest(c), approvals(a2), comments(), reviewers(), REVIEW_DB);
-
- assertDiffs(
- b1,
- b2,
- "PatchSetApproval.Key sets differ:"
- + " ["
- + id
- + "%2C1,100,Code-Review] only in A;"
- + " ["
- + id
- + "%2C1,100,Verified] only in B");
- }
-
- @Test
- public void diffPatchSetApprovals() throws Exception {
- Change c = TestChanges.newChange(project, accountId);
- PatchSetApproval a1 =
- new PatchSetApproval(
- new PatchSetApproval.Key(c.currentPatchSetId(), accountId, new LabelId("Code-Review")),
- (short) 1,
- TimeUtil.nowTs());
- PatchSetApproval a2 = clone(a1);
- ChangeBundle b1 =
- new ChangeBundle(
- c, messages(), latest(c), approvals(a1), comments(), reviewers(), REVIEW_DB);
- ChangeBundle b2 =
- new ChangeBundle(
- c, messages(), latest(c), approvals(a2), comments(), reviewers(), REVIEW_DB);
-
- assertNoDiffs(b1, b2);
-
- a2.setValue((short) -1);
- assertDiffs(
- b1,
- b2,
- "value differs for PatchSetApproval.Key "
- + c.getId()
- + "%2C1,100,Code-Review: {1} != {-1}");
- }
-
- @Test
- public void diffPatchSetApprovalsMixedSourcesAllowsSlop() throws Exception {
- Change c = TestChanges.newChange(project, accountId);
- subWindowResolution();
- PatchSetApproval a1 =
- new PatchSetApproval(
- new PatchSetApproval.Key(c.currentPatchSetId(), accountId, new LabelId("Code-Review")),
- (short) 1,
- roundToSecond(TimeUtil.nowTs()));
- PatchSetApproval a2 = clone(a1);
- a2.setGranted(TimeUtil.nowTs());
-
- // Both are ReviewDb, exact timestamp match is required.
- ChangeBundle b1 =
- new ChangeBundle(
- c, messages(), latest(c), approvals(a1), comments(), reviewers(), REVIEW_DB);
- ChangeBundle b2 =
- new ChangeBundle(
- c, messages(), latest(c), approvals(a2), comments(), reviewers(), REVIEW_DB);
- assertDiffs(
- b1,
- b2,
- "granted differs for PatchSetApproval.Key "
- + c.getId()
- + "%2C1,100,Code-Review:"
- + " {2009-09-30 17:00:07.0} != {2009-09-30 17:00:08.0}");
-
- // One NoteDb, slop is allowed.
- b1 =
- new ChangeBundle(c, messages(), latest(c), approvals(a1), comments(), reviewers(), NOTE_DB);
- b2 =
- new ChangeBundle(
- c, messages(), latest(c), approvals(a2), comments(), reviewers(), REVIEW_DB);
- assertNoDiffs(b1, b2);
-
- // But not too much slop.
- superWindowResolution();
- PatchSetApproval a3 = clone(a1);
- a3.setGranted(TimeUtil.nowTs());
- b1 =
- new ChangeBundle(c, messages(), latest(c), approvals(a1), comments(), reviewers(), NOTE_DB);
- ChangeBundle b3 =
- new ChangeBundle(
- c, messages(), latest(c), approvals(a3), comments(), reviewers(), REVIEW_DB);
- String msg =
- "granted differs for PatchSetApproval.Key "
- + c.getId()
- + "%2C1,100,Code-Review in NoteDb vs. ReviewDb:"
- + " {2009-09-30 17:00:07.0} != {2009-09-30 17:00:15.0}";
- assertDiffs(b1, b3, msg);
- assertDiffs(b3, b1, msg);
- }
-
- @Test
- public void diffPatchSetApprovalsAllowsTruncatedTimestampInNoteDb() throws Exception {
- Change c = TestChanges.newChange(project, accountId);
- PatchSetApproval a1 =
- new PatchSetApproval(
- new PatchSetApproval.Key(c.currentPatchSetId(), accountId, new LabelId("Code-Review")),
- (short) 1,
- c.getCreatedOn());
- PatchSetApproval a2 = clone(a1);
- a2.setGranted(
- new Timestamp(
- new DateTime(1900, 1, 1, 0, 0, 0, DateTimeZone.forTimeZone(TimeZone.getDefault()))
- .getMillis()));
-
- // Both are ReviewDb, exact match is required.
- ChangeBundle b1 =
- new ChangeBundle(
- c, messages(), latest(c), approvals(a1), comments(), reviewers(), REVIEW_DB);
- ChangeBundle b2 =
- new ChangeBundle(
- c, messages(), latest(c), approvals(a2), comments(), reviewers(), REVIEW_DB);
- assertDiffs(
- b1,
- b2,
- "granted differs for PatchSetApproval.Key "
- + c.getId()
- + "%2C1,100,Code-Review:"
- + " {2009-09-30 17:00:00.0} != {1900-01-01 00:00:00.0}");
-
- // Truncating NoteDb timestamp is allowed.
- b1 =
- new ChangeBundle(c, messages(), latest(c), approvals(a1), comments(), reviewers(), NOTE_DB);
- b2 =
- new ChangeBundle(
- c, messages(), latest(c), approvals(a2), comments(), reviewers(), REVIEW_DB);
- assertNoDiffs(b1, b2);
- assertNoDiffs(b2, b1);
- }
-
- @Test
- public void diffPatchSetApprovalsIgnoresPostSubmitBitOnZeroVote() throws Exception {
- Change c = TestChanges.newChange(project, accountId);
- c.setStatus(Change.Status.MERGED);
- PatchSetApproval a1 =
- new PatchSetApproval(
- new PatchSetApproval.Key(c.currentPatchSetId(), accountId, new LabelId("Code-Review")),
- (short) 0,
- TimeUtil.nowTs());
- a1.setPostSubmit(false);
- PatchSetApproval a2 = clone(a1);
- a2.setPostSubmit(true);
-
- // Both are ReviewDb, exact match is required.
- ChangeBundle b1 =
- new ChangeBundle(
- c, messages(), latest(c), approvals(a1), comments(), reviewers(), REVIEW_DB);
- ChangeBundle b2 =
- new ChangeBundle(
- c, messages(), latest(c), approvals(a2), comments(), reviewers(), REVIEW_DB);
- assertDiffs(
- b1,
- b2,
- "postSubmit differs for PatchSetApproval.Key "
- + c.getId()
- + "%2C1,100,Code-Review:"
- + " {false} != {true}");
-
- // One NoteDb, postSubmit is ignored.
- b1 =
- new ChangeBundle(
- c, messages(), latest(c), approvals(a1), comments(), reviewers(), REVIEW_DB);
- b2 =
- new ChangeBundle(c, messages(), latest(c), approvals(a2), comments(), reviewers(), NOTE_DB);
- assertNoDiffs(b1, b2);
- assertNoDiffs(b2, b1);
-
- // postSubmit is not ignored if vote isn't 0.
- a1.setValue((short) 1);
- a2.setValue((short) 1);
- assertDiffs(
- b1,
- b2,
- "postSubmit differs for PatchSetApproval.Key "
- + c.getId()
- + "%2C1,100,Code-Review:"
- + " {false} != {true}");
- assertDiffs(
- b2,
- b1,
- "postSubmit differs for PatchSetApproval.Key "
- + c.getId()
- + "%2C1,100,Code-Review:"
- + " {true} != {false}");
- }
-
- @Test
- public void diffReviewers() throws Exception {
- Change c = TestChanges.newChange(project, accountId);
- Timestamp now = TimeUtil.nowTs();
- ReviewerSet r1 = reviewers(REVIEWER, new Account.Id(1), now);
- ReviewerSet r2 = reviewers(REVIEWER, new Account.Id(2), now);
-
- ChangeBundle b1 =
- new ChangeBundle(c, messages(), latest(c), approvals(), comments(), r1, REVIEW_DB);
- ChangeBundle b2 =
- new ChangeBundle(c, messages(), latest(c), approvals(), comments(), r2, REVIEW_DB);
- assertNoDiffs(b1, b1);
- assertNoDiffs(b2, b2);
- assertDiffs(b1, b2, "reviewer sets differ: [1] only in A; [2] only in B");
- }
-
- @Test
- public void diffReviewersIgnoresStateAndTimestamp() throws Exception {
- Change c = TestChanges.newChange(project, accountId);
- ReviewerSet r1 = reviewers(REVIEWER, new Account.Id(1), TimeUtil.nowTs());
- ReviewerSet r2 = reviewers(CC, new Account.Id(1), TimeUtil.nowTs());
-
- ChangeBundle b1 =
- new ChangeBundle(c, messages(), latest(c), approvals(), comments(), r1, REVIEW_DB);
- ChangeBundle b2 =
- new ChangeBundle(c, messages(), latest(c), approvals(), comments(), r2, REVIEW_DB);
- assertNoDiffs(b1, b1);
- assertNoDiffs(b2, b2);
- }
-
- @Test
- public void diffPatchLineCommentKeySets() throws Exception {
- Change c = TestChanges.newChange(project, accountId);
- int id = c.getId().get();
- PatchLineComment c1 =
- new PatchLineComment(
- new PatchLineComment.Key(new Patch.Key(c.currentPatchSetId(), "filename1"), "uuid1"),
- 5,
- accountId,
- null,
- TimeUtil.nowTs());
- PatchLineComment c2 =
- new PatchLineComment(
- new PatchLineComment.Key(new Patch.Key(c.currentPatchSetId(), "filename2"), "uuid2"),
- 5,
- accountId,
- null,
- TimeUtil.nowTs());
-
- ChangeBundle b1 =
- new ChangeBundle(
- c, messages(), latest(c), approvals(), comments(c1), reviewers(), REVIEW_DB);
- ChangeBundle b2 =
- new ChangeBundle(
- c, messages(), latest(c), approvals(), comments(c2), reviewers(), REVIEW_DB);
-
- assertDiffs(
- b1,
- b2,
- "PatchLineComment.Key sets differ:"
- + " ["
- + id
- + ",1,filename1,uuid1] only in A;"
- + " ["
- + id
- + ",1,filename2,uuid2] only in B");
- }
-
- @Test
- public void diffPatchLineComments() throws Exception {
- Change c = TestChanges.newChange(project, accountId);
- PatchLineComment c1 =
- new PatchLineComment(
- new PatchLineComment.Key(new Patch.Key(c.currentPatchSetId(), "filename"), "uuid"),
- 5,
- accountId,
- null,
- TimeUtil.nowTs());
- PatchLineComment c2 = clone(c1);
- ChangeBundle b1 =
- new ChangeBundle(
- c, messages(), latest(c), approvals(), comments(c1), reviewers(), REVIEW_DB);
- ChangeBundle b2 =
- new ChangeBundle(
- c, messages(), latest(c), approvals(), comments(c2), reviewers(), REVIEW_DB);
-
- assertNoDiffs(b1, b2);
-
- c2.setStatus(PatchLineComment.Status.PUBLISHED);
- assertDiffs(
- b1,
- b2,
- "status differs for PatchLineComment.Key " + c.getId() + ",1,filename,uuid: {d} != {P}");
- }
-
- @Test
- public void diffPatchLineCommentsMixedSourcesAllowsSlop() throws Exception {
- subWindowResolution();
- Change c = TestChanges.newChange(project, accountId);
- PatchLineComment c1 =
- new PatchLineComment(
- new PatchLineComment.Key(new Patch.Key(c.currentPatchSetId(), "filename"), "uuid"),
- 5,
- accountId,
- null,
- roundToSecond(TimeUtil.nowTs()));
- PatchLineComment c2 = clone(c1);
- c2.setWrittenOn(TimeUtil.nowTs());
-
- // Both are ReviewDb, exact timestamp match is required.
- ChangeBundle b1 =
- new ChangeBundle(
- c, messages(), latest(c), approvals(), comments(c1), reviewers(), REVIEW_DB);
- ChangeBundle b2 =
- new ChangeBundle(
- c, messages(), latest(c), approvals(), comments(c2), reviewers(), REVIEW_DB);
- assertDiffs(
- b1,
- b2,
- "writtenOn differs for PatchLineComment.Key "
- + c.getId()
- + ",1,filename,uuid:"
- + " {2009-09-30 17:00:02.0} != {2009-09-30 17:00:03.0}");
-
- // One NoteDb, slop is allowed.
- b1 =
- new ChangeBundle(c, messages(), latest(c), approvals(), comments(c1), reviewers(), NOTE_DB);
- b2 =
- new ChangeBundle(
- c, messages(), latest(c), approvals(), comments(c2), reviewers(), REVIEW_DB);
- assertNoDiffs(b1, b2);
-
- // But not too much slop.
- superWindowResolution();
- PatchLineComment c3 = clone(c1);
- c3.setWrittenOn(TimeUtil.nowTs());
- b1 =
- new ChangeBundle(c, messages(), latest(c), approvals(), comments(c1), reviewers(), NOTE_DB);
- ChangeBundle b3 =
- new ChangeBundle(
- c, messages(), latest(c), approvals(), comments(c3), reviewers(), REVIEW_DB);
- String msg =
- "writtenOn differs for PatchLineComment.Key "
- + c.getId()
- + ",1,filename,uuid in NoteDb vs. ReviewDb:"
- + " {2009-09-30 17:00:02.0} != {2009-09-30 17:00:10.0}";
- assertDiffs(b1, b3, msg);
- assertDiffs(b3, b1, msg);
- }
-
- @Test
- public void diffPatchLineCommentsIgnoresCommentsOnInvalidPatchSet() throws Exception {
- Change c = TestChanges.newChange(project, accountId);
- PatchLineComment c1 =
- new PatchLineComment(
- new PatchLineComment.Key(new Patch.Key(c.currentPatchSetId(), "filename1"), "uuid1"),
- 5,
- accountId,
- null,
- TimeUtil.nowTs());
- PatchLineComment c2 =
- new PatchLineComment(
- new PatchLineComment.Key(
- new Patch.Key(new PatchSet.Id(c.getId(), 0), "filename2"), "uuid2"),
- 5,
- accountId,
- null,
- TimeUtil.nowTs());
-
- ChangeBundle b1 =
- new ChangeBundle(
- c, messages(), latest(c), approvals(), comments(c1, c2), reviewers(), REVIEW_DB);
- ChangeBundle b2 =
- new ChangeBundle(
- c, messages(), latest(c), approvals(), comments(c1), reviewers(), REVIEW_DB);
- assertNoDiffs(b1, b2);
- }
-
- private static void assertNoDiffs(ChangeBundle a, ChangeBundle b) {
- assertThat(a.differencesFrom(b)).isEmpty();
- assertThat(b.differencesFrom(a)).isEmpty();
- }
-
- private static void assertDiffs(ChangeBundle a, ChangeBundle b, String first, String... rest) {
- List<String> actual = a.differencesFrom(b);
- if (actual.size() == 1 && rest.length == 0) {
- // This error message is much easier to read.
- assertThat(actual.get(0)).isEqualTo(first);
- } else {
- List<String> expected = new ArrayList<>(1 + rest.length);
- expected.add(first);
- Collections.addAll(expected, rest);
- assertThat(actual).containsExactlyElementsIn(expected).inOrder();
- }
- assertThat(a).isNotEqualTo(b);
- }
-
- private static List<ChangeMessage> messages(ChangeMessage... ents) {
- return Arrays.asList(ents);
- }
-
- private static List<PatchSet> patchSets(PatchSet... ents) {
- return Arrays.asList(ents);
- }
-
- private static List<PatchSet> latest(Change c) {
- PatchSet ps = new PatchSet(c.currentPatchSetId());
- ps.setCreatedOn(c.getLastUpdatedOn());
- return ImmutableList.of(ps);
- }
-
- private static List<PatchSetApproval> approvals(PatchSetApproval... ents) {
- return Arrays.asList(ents);
- }
-
- private static ReviewerSet reviewers(Object... ents) {
- checkArgument(ents.length % 3 == 0);
- Table<ReviewerStateInternal, Account.Id, Timestamp> t = HashBasedTable.create();
- for (int i = 0; i < ents.length; i += 3) {
- t.put((ReviewerStateInternal) ents[i], (Account.Id) ents[i + 1], (Timestamp) ents[i + 2]);
- }
- return ReviewerSet.fromTable(t);
- }
-
- private static List<PatchLineComment> comments(PatchLineComment... ents) {
- return Arrays.asList(ents);
- }
-
- private static Change clone(Change ent) {
- return clone(CHANGE_CODEC, ent);
- }
-
- private static ChangeMessage clone(ChangeMessage ent) {
- return clone(CHANGE_MESSAGE_CODEC, ent);
- }
-
- private static PatchSet clone(PatchSet ent) {
- return clone(PATCH_SET_CODEC, ent);
- }
-
- private static PatchSetApproval clone(PatchSetApproval ent) {
- return clone(PATCH_SET_APPROVAL_CODEC, ent);
- }
-
- private static PatchLineComment clone(PatchLineComment ent) {
- return clone(PATCH_LINE_COMMENT_CODEC, ent);
- }
-
- private static <T> T clone(ProtobufCodec<T> codec, T obj) {
- return codec.decode(codec.encodeToByteArray(obj));
- }
-}