Implement consistency checker for NoteDb

Change the public interface of ConsistencyChecker to only take a
ChangeControl, since this always includes a pre-loaded ChangeNotes.
Not all callers have a ChangeData available, and it's wasteful to load
a Change just to turn around and load a ChangeNotes from it again.

This simplifies the interface and implementation, but does mean that
certain types of corruption, such as complete garbage in a NoteDb
commit message, will result in an error in the caller rather than a
nicely-formatted message. However, when rewriting the tests, I found
that there were not really any situations we cared about that are
really and truly corrupt data.

Most issues were due to the database and the underlying repo getting
out of sync. From the perspective of NoteDb, it's pretty easy to
generate these corrupt states. The only place we had to go behind the
back of normal change operations during tests was when pointing a
patch set at a nonexisting object, since otherwise PatchSetUtil will
try to parse the object to get the subject. It was easy enough to
manually construct a commit message there.

The most complicated fix was for deleting patch sets pointing to
nonexistent objects. I think this actually turned out nicer, since we
were able to decompose the problem into a set of independent deletion
operations that then get packaged together into a single BatchUpdate.

The one and only test that really cannot be replicated in NoteDb is
when the change destination repository is missing, since that's where
the NoteDb data would be stored. This one it's ok to skip.

Since I was rewriting the tests pretty much completely anyway, I
simplified some code by implementing ProblemInfo#equals so we can use
assertThat(problems).containsExactly(...) for more compact assertions.

Change-Id: I1d77f9202c053127089b4926383abf02aa24466b
This commit is contained in:
Dave Borowitz
2016-07-12 18:22:15 -04:00
parent 878ed3c90e
commit 2a1d82da9b
5 changed files with 780 additions and 566 deletions

View File

@@ -14,6 +14,8 @@
package com.google.gerrit.extensions.common;
import java.util.Objects;
public class ProblemInfo {
public enum Status {
FIXED, FIX_FAILED
@@ -23,6 +25,22 @@ public class ProblemInfo {
public Status status;
public String outcome;
@Override
public int hashCode() {
return Objects.hash(message, status, outcome);
}
@Override
public boolean equals(Object o) {
if (!(o instanceof ProblemInfo)) {
return false;
}
ProblemInfo p = (ProblemInfo) o;
return Objects.equals(message, p.message)
&& Objects.equals(status, p.status)
&& Objects.equals(outcome, p.outcome);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder(getClass().getSimpleName())