Fix auto-rebuilding of changes with missing NoteDb refs
Change-Id: I2066da896df694554885cdbddb3bd6949c7d86ec
This commit is contained in:
parent
05c99c5d83
commit
3d58cbeff4
@ -1313,6 +1313,36 @@ public class ChangeRebuilderIT extends AbstractDaemonTest {
|
||||
assertThat(getMetaRef(project, refName)).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void autoRebuildMissingRefWriteOnly() throws Exception {
|
||||
setNotesMigration(true, false);
|
||||
testAutoRebuildMissingRef();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void autoRebuildMissingRefReadWrite() throws Exception {
|
||||
setNotesMigration(true, true);
|
||||
testAutoRebuildMissingRef();
|
||||
}
|
||||
|
||||
private void testAutoRebuildMissingRef() throws Exception {
|
||||
PushOneCommit.Result r = createChange();
|
||||
Change.Id id = r.getChange().getId();
|
||||
|
||||
assertChangeUpToDate(true, id);
|
||||
notesFactory.createChecked(db, project, id);
|
||||
|
||||
try (Repository repo = repoManager.openRepository(project)) {
|
||||
RefUpdate ru = repo.updateRef(RefNames.changeMetaRef(id));
|
||||
ru.setForceUpdate(true);
|
||||
assertThat(ru.delete()).isEqualTo(RefUpdate.Result.FORCED);
|
||||
}
|
||||
assertChangeUpToDate(false, id);
|
||||
|
||||
notesFactory.createChecked(db, project, id);
|
||||
assertChangeUpToDate(true, id);
|
||||
}
|
||||
|
||||
private void assertChangesReadOnly(RestApiException e) throws Exception {
|
||||
Throwable cause = e.getCause();
|
||||
assertThat(cause).isInstanceOf(UpdateException.class);
|
||||
@ -1336,8 +1366,10 @@ public class ChangeRebuilderIT extends AbstractDaemonTest {
|
||||
Change c = getUnwrappedDb().changes().get(id);
|
||||
assertThat(c).isNotNull();
|
||||
assertThat(c.getNoteDbState()).isNotNull();
|
||||
assertThat(NoteDbChangeState.parse(c).isChangeUpToDate(new RepoRefCache(repo)))
|
||||
.isEqualTo(expected);
|
||||
NoteDbChangeState state = NoteDbChangeState.parse(c);
|
||||
assertThat(state).isNotNull();
|
||||
assertThat(state.getPrimaryStorage()).isEqualTo(PrimaryStorage.REVIEW_DB);
|
||||
assertThat(state.isChangeUpToDate(new RepoRefCache(repo))).isEqualTo(expected);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -732,16 +732,27 @@ public class ChangeNotes extends AbstractChangeNotes<ChangeNotes> {
|
||||
protected LoadHandle openHandle(Repository repo) throws NoSuchChangeException, IOException {
|
||||
if (autoRebuild) {
|
||||
NoteDbChangeState state = NoteDbChangeState.parse(change);
|
||||
if (args.migration.disableChangeReviewDb()) {
|
||||
checkState(
|
||||
state != null,
|
||||
"shouldn't have null NoteDbChangeState when ReviewDb disabled: %s",
|
||||
change);
|
||||
}
|
||||
ObjectId id = readRef(repo);
|
||||
if (id == null) {
|
||||
// Meta ref doesn't exist in NoteDb.
|
||||
|
||||
if (state == null) {
|
||||
// Either ReviewDb change is being newly created, or it exists in ReviewDb but has not yet
|
||||
// been rebuilt for the first time, e.g. because we just turned on write-only mode. In
|
||||
// both cases, we don't want to auto-rebuild, just proceed with an empty ChangeNotes.
|
||||
return super.openHandle(repo, id);
|
||||
} else if (shouldExist) {
|
||||
// TODO(dborowitz): This means we have a state recorded in noteDbState but the ref doesn't
|
||||
// exist for whatever reason. Doesn't this mean we should trigger an auto-rebuild, rather
|
||||
// than throwing?
|
||||
} else if (shouldExist && state.getPrimaryStorage() == PrimaryStorage.NOTE_DB) {
|
||||
throw new NoSuchChangeException(getChangeId());
|
||||
}
|
||||
|
||||
// ReviewDb claims NoteDb state exists, but meta ref isn't present: fall through and
|
||||
// auto-rebuild if necessary.
|
||||
}
|
||||
RefCache refs = this.refs != null ? this.refs : new RepoRefCache(repo);
|
||||
if (!NoteDbChangeState.isChangeUpToDate(state, refs, getChangeId())) {
|
||||
|
Loading…
Reference in New Issue
Block a user