use of com.google.gerrit.server.update.BatchUpdateOp in project gerrit by GerritCodeReview.
the class AbstractSubmit method setChangeStatusToNew.
private void setChangeStatusToNew(PushOneCommit.Result... changes) throws Exception {
for (PushOneCommit.Result change : changes) {
try (BatchUpdate bu = batchUpdateFactory.create(db, project, userFactory.create(admin.id), TimeUtil.nowTs())) {
bu.addOp(change.getChange().getId(), new BatchUpdateOp() {
@Override
public boolean updateChange(ChangeContext ctx) throws OrmException {
ctx.getChange().setStatus(Change.Status.NEW);
ctx.getUpdate(ctx.getChange().currentPatchSetId()).setStatus(Change.Status.NEW);
return true;
}
});
bu.execute();
}
}
}
use of com.google.gerrit.server.update.BatchUpdateOp in project gerrit by GerritCodeReview.
the class ConsistencyCheckerIT method mergeChange.
private ChangeControl mergeChange(ChangeControl ctl) throws Exception {
final ObjectId oldId = getDestRef(ctl);
final ObjectId newId = ObjectId.fromString(psUtil.current(db, ctl.getNotes()).getRevision().get());
final String dest = ctl.getChange().getDest().get();
try (BatchUpdate bu = newUpdate(adminId)) {
bu.addOp(ctl.getId(), new BatchUpdateOp() {
@Override
public void updateRepo(RepoContext ctx) throws IOException {
ctx.addRefUpdate(oldId, newId, dest);
}
@Override
public boolean updateChange(ChangeContext ctx) throws OrmException {
ctx.getChange().setStatus(Change.Status.MERGED);
ctx.getUpdate(ctx.getChange().currentPatchSetId()).fixStatus(Change.Status.MERGED);
return true;
}
});
bu.execute();
}
return reload(ctl);
}
use of com.google.gerrit.server.update.BatchUpdateOp in project gerrit by GerritCodeReview.
the class ConsistencyCheckerIT method mergedChangeIsNotMerged.
@Test
public void mergedChangeIsNotMerged() throws Exception {
ChangeControl ctl = insertChange();
try (BatchUpdate bu = newUpdate(adminId)) {
bu.addOp(ctl.getId(), new BatchUpdateOp() {
@Override
public boolean updateChange(ChangeContext ctx) throws OrmException {
ctx.getChange().setStatus(Change.Status.MERGED);
ctx.getUpdate(ctx.getChange().currentPatchSetId()).fixStatus(Change.Status.MERGED);
return true;
}
});
bu.execute();
}
ctl = reload(ctl);
String rev = psUtil.current(db, ctl.getNotes()).getRevision().get();
ObjectId tip = getDestRef(ctl);
assertProblems(ctl, null, problem("Patch set 1 (" + rev + ") is not merged into destination ref" + " refs/heads/master (" + tip.name() + "), but change status is MERGED"));
}
use of com.google.gerrit.server.update.BatchUpdateOp in project gerrit by GerritCodeReview.
the class ChangeRebuilderIT method rebuildAutomaticallyWithinBatchUpdate.
@Test
public void rebuildAutomaticallyWithinBatchUpdate() throws Exception {
setNotesMigration(true, true);
PushOneCommit.Result r = createChange();
final Change.Id id = r.getPatchSetId().getParentKey();
assertChangeUpToDate(true, id);
// Update ReviewDb and NoteDb, then revert the corresponding NoteDb change
// to simulate it failing.
NoteDbChangeState oldState = NoteDbChangeState.parse(getUnwrappedDb().changes().get(id));
String topic = name("a-topic");
gApi.changes().id(id.get()).topic(topic);
try (Repository repo = repoManager.openRepository(project)) {
new TestRepository<>(repo).update(RefNames.changeMetaRef(id), oldState.getChangeMetaId());
}
assertChangeUpToDate(false, id);
// Next NoteDb read comes inside the transaction started by BatchUpdate. In
// reality this could be caused by a failed update happening between when
// the change is parsed by ChangesCollection and when the BatchUpdate
// executes. We simulate it here by using BatchUpdate directly and not going
// through an API handler.
final String msg = "message from BatchUpdate";
try (BatchUpdate bu = batchUpdateFactory.create(db, project, identifiedUserFactory.create(user.getId()), TimeUtil.nowTs())) {
bu.addOp(id, new BatchUpdateOp() {
@Override
public boolean updateChange(ChangeContext ctx) throws OrmException {
PatchSet.Id psId = ctx.getChange().currentPatchSetId();
ChangeMessage cm = new ChangeMessage(new ChangeMessage.Key(id, ChangeUtil.messageUuid()), ctx.getAccountId(), ctx.getWhen(), psId);
cm.setMessage(msg);
ctx.getDb().changeMessages().insert(Collections.singleton(cm));
ctx.getUpdate(psId).setChangeMessage(msg);
return true;
}
});
try {
bu.execute();
fail("expected update to fail");
} catch (UpdateException e) {
assertThat(e.getMessage()).contains("cannot copy ChangeNotesState");
}
}
// TODO(dborowitz): Re-enable these assertions once we fix auto-rebuilding
// in the BatchUpdate path.
//// As an implementation detail, change wasn't actually rebuilt inside the
//// BatchUpdate transaction, but it was rebuilt during read for the
//// subsequent reindex. Thus it's impossible to actually observe an
//// out-of-date state in the caller.
//assertChangeUpToDate(true, id);
//// Check that the bundles are equal.
//ChangeNotes notes = notesFactory.create(dbProvider.get(), project, id);
//ChangeBundle actual = ChangeBundle.fromNotes(commentsUtil, notes);
//ChangeBundle expected = bundleReader.fromReviewDb(getUnwrappedDb(), id);
//assertThat(actual.differencesFrom(expected)).isEmpty();
//assertThat(
// Iterables.transform(
// notes.getChangeMessages(),
// ChangeMessage::getMessage))
// .contains(msg);
//assertThat(actual.getChange().getTopic()).isEqualTo(topic);
}
use of com.google.gerrit.server.update.BatchUpdateOp in project gerrit by GerritCodeReview.
the class ConsistencyChecker method insertMergedPatchSet.
private void insertMergedPatchSet(final RevCommit commit, @Nullable final PatchSet.Id psIdToDelete, boolean reuseOldPsId) {
ProblemInfo notFound = problem("No patch set found for merged commit " + commit.name());
if (!user.get().isIdentifiedUser()) {
notFound.status = Status.FIX_FAILED;
notFound.outcome = "Must be called by an identified user to insert new patch set";
return;
}
ProblemInfo insertPatchSetProblem;
ProblemInfo deleteOldPatchSetProblem;
if (psIdToDelete == null) {
insertPatchSetProblem = problem(String.format("Expected merged commit %s has no associated patch set", commit.name()));
deleteOldPatchSetProblem = null;
} else {
String msg = String.format("Expected merge commit %s corresponds to patch set %s," + " not the current patch set %s", commit.name(), psIdToDelete.get(), change().currentPatchSetId().get());
// Maybe an identical problem, but different fix.
deleteOldPatchSetProblem = reuseOldPsId ? null : problem(msg);
insertPatchSetProblem = problem(msg);
}
List<ProblemInfo> currProblems = new ArrayList<>(3);
currProblems.add(notFound);
if (deleteOldPatchSetProblem != null) {
currProblems.add(insertPatchSetProblem);
}
currProblems.add(insertPatchSetProblem);
try {
PatchSet.Id psId = (psIdToDelete != null && reuseOldPsId) ? psIdToDelete : ChangeUtil.nextPatchSetId(repo, change().currentPatchSetId());
PatchSetInserter inserter = patchSetInserterFactory.create(ctl, psId, commit);
try (BatchUpdate bu = newBatchUpdate()) {
bu.setRepository(repo, rw, oi);
if (psIdToDelete != null) {
// Delete the given patch set ref. If reuseOldPsId is true,
// PatchSetInserter will reinsert the same ref, making it a no-op.
bu.addOp(ctl.getId(), new BatchUpdateOp() {
@Override
public void updateRepo(RepoContext ctx) throws IOException {
ctx.addRefUpdate(commit, ObjectId.zeroId(), psIdToDelete.toRefName());
}
});
if (!reuseOldPsId) {
bu.addOp(ctl.getId(), new DeletePatchSetFromDbOp(checkNotNull(deleteOldPatchSetProblem), psIdToDelete));
}
}
bu.addOp(ctl.getId(), inserter.setValidate(false).setFireRevisionCreated(false).setNotify(NotifyHandling.NONE).setAllowClosed(true).setMessage("Patch set for merged commit inserted by consistency checker"));
bu.addOp(ctl.getId(), new FixMergedOp(notFound));
bu.execute();
}
ctl = changeControlFactory.controlFor(db.get(), inserter.getChange(), ctl.getUser());
insertPatchSetProblem.status = Status.FIXED;
insertPatchSetProblem.outcome = "Inserted as patch set " + psId.get();
} catch (OrmException | IOException | UpdateException | RestApiException e) {
warn(e);
for (ProblemInfo pi : currProblems) {
pi.status = Status.FIX_FAILED;
pi.outcome = "Error inserting merged patch set";
}
return;
}
}
Aggregations