ChangeBundle: Ignore ReviewDb current PSID if invalid

Change-Id: I3d65834e20d2115d4ad8cceab197871a86df62f3
This commit is contained in:
Dave Borowitz
2016-05-28 13:40:48 -04:00
parent 71f8f8dbb4
commit 27e46da812
2 changed files with 63 additions and 16 deletions

View File

@@ -389,19 +389,22 @@ public class ChangeBundle {
private <K, V> Map<K, V> limitToValidPatchSets(Map<K, V> in, private <K, V> Map<K, V> limitToValidPatchSets(Map<K, V> in,
final Function<K, PatchSet.Id> func) { final Function<K, PatchSet.Id> func) {
final Predicate<PatchSet.Id> upToCurrent = upToCurrentPredicate();
return Maps.filterKeys( return Maps.filterKeys(
in, new Predicate<K>() { in, Predicates.compose(validPatchSetPredicate(), func));
@Override }
public boolean apply(K in) {
PatchSet.Id psId = func.apply(in); private Predicate<PatchSet.Id> validPatchSetPredicate() {
return upToCurrent.apply(psId) && patchSets.containsKey(psId); final Predicate<PatchSet.Id> upToCurrent = upToCurrentPredicate();
} return new Predicate<PatchSet.Id>() {
}); @Override
public boolean apply(PatchSet.Id in) {
return upToCurrent.apply(in) && patchSets.containsKey(in);
}
};
} }
private Collection<ChangeMessage> filterChangeMessages() { private Collection<ChangeMessage> filterChangeMessages() {
final Predicate<PatchSet.Id> upToCurrent = upToCurrentPredicate(); final Predicate<PatchSet.Id> validPatchSet = validPatchSetPredicate();
return Collections2.filter(changeMessages, return Collections2.filter(changeMessages,
new Predicate<ChangeMessage>() { new Predicate<ChangeMessage>() {
@Override @Override
@@ -410,7 +413,7 @@ public class ChangeBundle {
if (psId == null) { if (psId == null) {
return true; return true;
} }
return upToCurrent.apply(psId) && patchSets.containsKey(psId); return validPatchSet.apply(psId);
} }
}); });
} }
@@ -440,6 +443,7 @@ public class ChangeBundle {
String desc = a.getId().equals(b.getId()) ? describe(a.getId()) : "Changes"; String desc = a.getId().equals(b.getId()) ? describe(a.getId()) : "Changes";
boolean excludeCreatedOn = false; boolean excludeCreatedOn = false;
boolean excludeCurrentPatchSetId = false;
boolean excludeTopic = false; boolean excludeTopic = false;
Timestamp aUpdated = a.getLastUpdatedOn(); Timestamp aUpdated = a.getLastUpdatedOn();
Timestamp bUpdated = b.getLastUpdatedOn(); Timestamp bUpdated = b.getLastUpdatedOn();
@@ -483,12 +487,17 @@ public class ChangeBundle {
// //
// Ignore empty topic on the ReviewDb side if it is null on the NoteDb side. // Ignore empty topic on the ReviewDb side if it is null on the NoteDb side.
// //
// Ignore currentPatchSetId on NoteDb side if ReviewDb does not point to a
// valid patch set.
//
// Use max timestamp of all ReviewDb entities when comparing with NoteDb. // Use max timestamp of all ReviewDb entities when comparing with NoteDb.
if (bundleA.source == REVIEW_DB && bundleB.source == NOTE_DB) { if (bundleA.source == REVIEW_DB && bundleB.source == NOTE_DB) {
excludeCreatedOn = !timestampsDiffer( excludeCreatedOn = !timestampsDiffer(
bundleA, bundleA.getFirstPatchSetTime(), bundleB, b.getCreatedOn()); bundleA, bundleA.getFirstPatchSetTime(), bundleB, b.getCreatedOn());
aSubj = cleanReviewDbSubject(aSubj); aSubj = cleanReviewDbSubject(aSubj);
excludeSubject = bSubj.startsWith(aSubj); excludeCurrentPatchSetId =
!bundleA.validPatchSetPredicate().apply(a.currentPatchSetId());
excludeSubject = bSubj.startsWith(aSubj) || excludeCurrentPatchSetId;
excludeOrigSubj = true; excludeOrigSubj = true;
String aTopic = trimLeadingOrNull(a.getTopic()); String aTopic = trimLeadingOrNull(a.getTopic());
excludeTopic = Objects.equals(aTopic, b.getTopic()) excludeTopic = Objects.equals(aTopic, b.getTopic())
@@ -498,7 +507,9 @@ public class ChangeBundle {
excludeCreatedOn = !timestampsDiffer( excludeCreatedOn = !timestampsDiffer(
bundleA, a.getCreatedOn(), bundleB, bundleB.getFirstPatchSetTime()); bundleA, a.getCreatedOn(), bundleB, bundleB.getFirstPatchSetTime());
bSubj = cleanReviewDbSubject(bSubj); bSubj = cleanReviewDbSubject(bSubj);
excludeSubject = aSubj.startsWith(bSubj); excludeCurrentPatchSetId =
!bundleB.validPatchSetPredicate().apply(b.currentPatchSetId());
excludeSubject = aSubj.startsWith(bSubj) || excludeCurrentPatchSetId;
excludeOrigSubj = true; excludeOrigSubj = true;
String bTopic = trimLeadingOrNull(b.getTopic()); String bTopic = trimLeadingOrNull(b.getTopic());
excludeTopic = Objects.equals(bTopic, a.getTopic()) excludeTopic = Objects.equals(bTopic, a.getTopic())
@@ -513,6 +524,9 @@ public class ChangeBundle {
if (excludeCreatedOn) { if (excludeCreatedOn) {
exclude.add("createdOn"); exclude.add("createdOn");
} }
if (excludeCurrentPatchSetId) {
exclude.add("currentPatchSetId");
}
if (excludeOrigSubj) { if (excludeOrigSubj) {
exclude.add("originalSubject"); exclude.add("originalSubject");
} }

View File

@@ -413,9 +413,9 @@ public class ChangeBundleTest {
assertNoDiffs(b1, b2); assertNoDiffs(b1, b2);
// NoteDb has shorter subject, not allowed. // NoteDb has shorter subject, not allowed.
b1 = new ChangeBundle(c1, messages(), patchSets(), approvals(), b1 = new ChangeBundle(c1, messages(), latest(c1), approvals(),
comments(), reviewers(), REVIEW_DB); comments(), reviewers(), REVIEW_DB);
b2 = new ChangeBundle(c2, messages(), patchSets(), approvals(), b2 = new ChangeBundle(c2, messages(), latest(c2), approvals(),
comments(), reviewers(), NOTE_DB); comments(), reviewers(), NOTE_DB);
assertDiffs(b1, b2, assertDiffs(b1, b2,
"subject differs for Change.Id " + c1.getId() + ":" "subject differs for Change.Id " + c1.getId() + ":"
@@ -468,9 +468,9 @@ public class ChangeBundleTest {
+ " {Change subject} != {\tChange subject}"); + " {Change subject} != {\tChange subject}");
// One NoteDb. // One NoteDb.
b1 = new ChangeBundle(c1, messages(), patchSets(), approvals(), b1 = new ChangeBundle(c1, messages(), latest(c1), approvals(),
comments(), reviewers(), NOTE_DB); comments(), reviewers(), NOTE_DB);
b2 = new ChangeBundle(c2, messages(), patchSets(), approvals(), b2 = new ChangeBundle(c2, messages(), latest(c2), approvals(),
comments(), reviewers(), REVIEW_DB); comments(), reviewers(), REVIEW_DB);
assertDiffs(b1, b2, assertDiffs(b1, b2,
"subject differs for Change.Id " + c1.getId() + ":" "subject differs for Change.Id " + c1.getId() + ":"
@@ -508,6 +508,39 @@ public class ChangeBundleTest {
assertNoDiffs(b2, b1); 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 @Test
public void diffChangeMessageKeySets() throws Exception { public void diffChangeMessageKeySets() throws Exception {
Change c = TestChanges.newChange(project, accountId); Change c = TestChanges.newChange(project, accountId);