Files
gerrit/javatests/com/google/gerrit/acceptance/api/revision/GetBlameIT.java
Edwin Kempin 59e3f0b6fa Upgrade gitiles-servlet and blame-cache to 0.2-11
If a file doesn't exist in a commit we expect the GetBlame REST endpoint
to return an empty BlameInfo list. This works well unless the file
existed once and had been deleted. E.g. if there is a change that
recreates a file and the user clicks on 'SHOW BLAME' on the diff screen
the request to get the blame info for the base commit fails with 500
Internal Server Error. For example the newly added
GetBlameIT#forRecreatedFileFromBase test was failing like this:

com.google.common.util.concurrent.UncheckedExecutionException: java.lang.NullPointerException
	at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2051)
	at com.google.common.cache.LocalCache.get(LocalCache.java:3953)
	at com.google.common.cache.LocalCache$LocalManualCache.get(LocalCache.java:4873)
	at com.google.gitiles.blame.cache.BlameCacheImpl.get(BlameCacheImpl.java:114)
	at com.google.gerrit.server.restapi.change.GetBlame.blame(GetBlame.java:145)
	at com.google.gerrit.server.restapi.change.GetBlame.apply(GetBlame.java:118)
	at com.google.gerrit.server.api.changes.FileApiImpl$2.get(FileApiImpl.java:149)
	at com.google.gerrit.acceptance.api.revision.GetBlameIT.forRecreatedFileFromBase(GetBlameIT.java:123)
        ...
Caused by: java.lang.NullPointerException
	at com.google.gitiles.blame.cache.BlameCacheImpl.loadRegions(BlameCacheImpl.java:156)
	at com.google.gitiles.blame.cache.BlameCacheImpl.loadBlame(BlameCacheImpl.java:139)
	at com.google.gitiles.blame.cache.BlameCacheImpl.lambda$newLoader$1(BlameCacheImpl.java:103)
	at com.google.common.cache.LocalCache$LocalManualCache$1.load(LocalCache.java:4878)
	at com.google.common.cache.LocalCache$LoadingValueReference.loadFuture(LocalCache.java:3529)
	at com.google.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2278)
	at com.google.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2155)
	at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2045)
	... 48 more

The updated version of blame-cache includes a fix for this.

Likely we want to have more tests for the GetBlame REST endpoint, but
adding those is outside the scope of this change.

Bug: Issue 5082
Change-Id: I11b529b48495e563148040dfb7f56379de13d128
Signed-off-by: Edwin Kempin <ekempin@google.com>
2019-11-14 11:29:10 -08:00

129 lines
4.7 KiB
Java

// Copyright (C) 2019 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.gerrit.acceptance.api.revision;
import static com.google.common.truth.Truth.assertThat;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.PushOneCommit;
import com.google.gerrit.extensions.common.BlameInfo;
import com.google.gerrit.extensions.common.RangeInfo;
import java.util.List;
import org.junit.Test;
public class GetBlameIT extends AbstractDaemonTest {
@Test
public void forNonExistingFile() throws Exception {
PushOneCommit.Result r = createChange("Test Change", "foo.txt", "FOO");
List<BlameInfo> blameInfos =
gApi.changes().id(r.getChangeId()).current().file("non-existing.txt").blameRequest().get();
// File doesn't exist in commit.
assertThat(blameInfos).isEmpty();
}
@Test
public void forNonExistingFileFromBase() throws Exception {
PushOneCommit.Result r = createChange("Test Change", "foo.txt", "FOO");
List<BlameInfo> blameInfos =
gApi.changes()
.id(r.getChangeId())
.current()
.file("non-existing.txt")
.blameRequest()
.forBase(true)
.get();
// File doesn't exist in base commit.
assertThat(blameInfos).isEmpty();
}
@Test
public void forNewlyAddedFile() throws Exception {
PushOneCommit.Result r = createChange("Test Change", "foo.txt", "FOO");
List<BlameInfo> blameInfos =
gApi.changes().id(r.getChangeId()).current().file("foo.txt").blameRequest().get();
assertThat(blameInfos).hasSize(1);
BlameInfo blameInfo = blameInfos.get(0);
assertThat(blameInfo.author).isEqualTo(admin.fullName());
assertThat(blameInfo.id).isEqualTo(r.getCommit().getId().name());
assertThat(blameInfo.commitMsg).isEqualTo(r.getCommit().getFullMessage());
assertThat(blameInfo.time).isEqualTo(r.getCommit().getCommitTime());
assertThat(blameInfo.ranges).hasSize(1);
RangeInfo rangeInfo = blameInfo.ranges.get(0);
assertThat(rangeInfo.start).isEqualTo(1);
assertThat(rangeInfo.end).isEqualTo(1);
}
@Test
public void forNewlyAddedFileFromBase() throws Exception {
String changeId = createChange("Test Change", "foo.txt", "FOO").getChangeId();
List<BlameInfo> blameInfos =
gApi.changes().id(changeId).current().file("foo.txt").blameRequest().forBase(true).get();
// File doesn't exist in base commit.
assertThat(blameInfos).isEmpty();
}
@Test
public void forRecreatedFile() throws Exception {
// Create change that adds 'foo.txt'.
createChange("Change 1", "foo.txt", "FOO");
// Create change that deletes 'foo.txt'.
pushFactory
.create(admin.newIdent(), testRepo, "Change 2", "foo.txt", "FOO")
.rm("refs/for/master");
// Create change that recreates 'foo.txt'.
PushOneCommit.Result r = createChange("Change 3", "foo.txt", "FOO");
List<BlameInfo> blameInfos =
gApi.changes().id(r.getChangeId()).current().file("foo.txt").blameRequest().get();
assertThat(blameInfos).hasSize(1);
BlameInfo blameInfo = blameInfos.get(0);
assertThat(blameInfo.author).isEqualTo(admin.fullName());
assertThat(blameInfo.id).isEqualTo(r.getCommit().getId().name());
assertThat(blameInfo.commitMsg).isEqualTo(r.getCommit().getFullMessage());
assertThat(blameInfo.time).isEqualTo(r.getCommit().getCommitTime());
assertThat(blameInfo.ranges).hasSize(1);
RangeInfo rangeInfo = blameInfo.ranges.get(0);
assertThat(rangeInfo.start).isEqualTo(1);
assertThat(rangeInfo.end).isEqualTo(1);
}
@Test
public void forRecreatedFileFromBase() throws Exception {
// Create change that adds 'foo.txt'.
createChange("Change 1", "foo.txt", "FOO");
// Create change that deletes 'foo.txt'.
pushFactory
.create(admin.newIdent(), testRepo, "Change 2", "foo.txt", "FOO")
.rm("refs/for/master");
// Create change that recreates 'foo.txt'.
String changeId3 = createChange("Change 3", "foo.txt", "FOO").getChangeId();
List<BlameInfo> blameInfos =
gApi.changes().id(changeId3).current().file("foo.txt").blameRequest().forBase(true).get();
// File doesn't exist in base commit.
assertThat(blameInfos).isEmpty();
}
}