// 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.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 com.google.gerrit.server.util.time.TimeUtil.truncateToSecond;
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.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.server.util.time.TimeUtil;
import com.google.gerrit.testing.GerritBaseTests;
import com.google.gerrit.testing.TestChanges;
import com.google.gerrit.testing.TestTimeUtil;
import com.google.gwtorm.protobuf.CodecFactory;
import com.google.gwtorm.protobuf.ProtobufCodec;
import java.sql.Timestamp;
import java.time.LocalDate;
import java.time.Month;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.TimeZone;
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 static final String TIMEZONE_ID = "US/Eastern";

  private String systemTimeZoneProperty;
  private TimeZone systemTimeZone;

  private Project.NameKey project;
  private Account.Id accountId;

  @Before
  public void setUp() {
    systemTimeZoneProperty = System.setProperty("user.timezone", TIMEZONE_ID);
    systemTimeZone = TimeZone.getDefault();
    TimeZone.setDefault(TimeZone.getTimeZone(TIMEZONE_ID));
    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(truncateToSecond(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(truncateToSecond(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,
            truncateToSecond(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(
            LocalDate.of(1900, Month.JANUARY, 1)
                .atStartOfDay()
                .atZone(ZoneId.of(TIMEZONE_ID))
                .toInstant()
                .toEpochMilli()));

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