// 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));
  }
}
