ChangeJson: Ensure limitToPsId revision is present in output

Due to a logic bug, we weren't including the limitToPsId revision in the
revisions map in the output ChangeInfo (unless it would have been
included for another reason, such as ALL_REVISIONS being requested).

In addition to a more direct test in RevisionIT, add a test to ActionsIT
ensuring that actions load on a non-current revision, which is the
codepath in the wild that led to discovering this bug.

Fixing the immediate bug unfortunately makes this code even uglier; it
cries out for a more thorough refactoring, but we need to fix this
critical bug preventing ActionVisitors from working. On the plus side,
the additional tests in this change will make that refactoring safer.

Change-Id: Iea61de55f2efc54d3955ff40f993a40e2936beb0
This commit is contained in:
Dave Borowitz
2017-08-29 11:29:04 -04:00
parent 8ecd222ed5
commit 04d82e10e6
3 changed files with 104 additions and 13 deletions

View File

@@ -586,7 +586,7 @@ public class ChangeJson {
// This block must come after the ChangeInfo is mostly populated, since
// it will be passed to ActionVisitors as-is.
if (needRevisions) {
out.revisions = revisions(ctl, cd, src, out);
out.revisions = revisions(ctl, cd, src, limitToPsId, out);
if (out.revisions != null) {
for (Map.Entry<String, RevisionInfo> entry : out.revisions.entrySet()) {
if (entry.getValue().isCurrent) {
@@ -1202,14 +1202,26 @@ public class ChangeJson {
}
private Map<String, RevisionInfo> revisions(
ChangeControl ctl, ChangeData cd, Map<PatchSet.Id, PatchSet> map, ChangeInfo changeInfo)
ChangeControl ctl,
ChangeData cd,
Map<PatchSet.Id, PatchSet> map,
Optional<PatchSet.Id> limitToPsId,
ChangeInfo changeInfo)
throws PatchListNotAvailableException, GpgException, OrmException, IOException {
Map<String, RevisionInfo> res = new LinkedHashMap<>();
try (Repository repo = openRepoIfNecessary(ctl);
RevWalk rw = newRevWalk(repo)) {
for (PatchSet in : map.values()) {
if ((has(ALL_REVISIONS) || in.getId().equals(ctl.getChange().currentPatchSetId()))
&& ctl.isPatchVisible(in, db.get())) {
PatchSet.Id id = in.getId();
boolean want = false;
if (has(ALL_REVISIONS)) {
want = true;
} else if (limitToPsId.isPresent()) {
want = id.equals(limitToPsId.get());
} else {
want = id.equals(ctl.getChange().currentPatchSetId());
}
if (want && ctl.isPatchVisible(in, db.get())) {
res.put(in.getRevision().get(), toRevisionInfo(ctl, cd, in, repo, rw, false, changeInfo));
}
}