blob: f335201327aa3bc203e9b6c8420c09ee28d06fca [file] [log] [blame]
// Copyright (C) 2018 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.server.notedb;
import static com.google.common.truth.Truth.assertThat;
import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import com.google.gerrit.entities.Project;
import com.google.gerrit.exceptions.StorageException;
import com.google.gerrit.git.LockFailureException;
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
import com.google.gerrit.truth.OptionalSubject;
import java.io.IOException;
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
import org.eclipse.jgit.internal.storage.dfs.DfsRepositoryDescription;
import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.RefUpdate;
import org.eclipse.jgit.revwalk.RevWalk;
import org.junit.Before;
import org.junit.Test;
public class IntBlobTest {
// Note: Can't easily test GitRefUpdated behavior, since binding GitRefUpdated requires a thick
// stack of dependencies, and it's not just a simple interface or abstract class.
private Project.NameKey projectName;
private InMemoryRepository repo;
private TestRepository<InMemoryRepository> tr;
private RevWalk rw;
@Before
public void setUp() throws Exception {
projectName = Project.nameKey("repo");
repo = new InMemoryRepository(new DfsRepositoryDescription(projectName.get()));
tr = new TestRepository<>(repo);
rw = tr.getRevWalk();
}
@Test
public void parseNoRef() throws Exception {
OptionalSubject.assertThat(IntBlob.parse(repo, "refs/nothing")).isEmpty();
}
@Test
public void parseNonBlob() throws Exception {
String refName = "refs/foo/master";
tr.branch(refName).commit().create();
assertThrows(IncorrectObjectTypeException.class, () -> IntBlob.parse(repo, refName));
}
@Test
public void parseValid() throws Exception {
String refName = "refs/foo";
ObjectId id = tr.update(refName, tr.blob("123"));
OptionalSubject.assertThat(IntBlob.parse(repo, refName))
.value()
.isEqualTo(IntBlob.create(id, 123));
}
@Test
public void parseWithWhitespace() throws Exception {
String refName = "refs/foo";
ObjectId id = tr.update(refName, tr.blob(" 123 "));
OptionalSubject.assertThat(IntBlob.parse(repo, refName))
.value()
.isEqualTo(IntBlob.create(id, 123));
}
@Test
public void parseInvalid() throws Exception {
String refName = "refs/foo";
ObjectId id = tr.update(refName, tr.blob("1 2 3"));
StorageException thrown =
assertThrows(StorageException.class, () -> IntBlob.parse(repo, refName));
assertThat(thrown).hasMessageThat().isEqualTo("invalid value in refs/foo blob at " + id.name());
}
@Test
public void tryStoreNoOldId() throws Exception {
String refName = "refs/foo";
RefUpdate ru =
IntBlob.tryStore(repo, rw, projectName, refName, null, 123, GitReferenceUpdated.DISABLED);
assertThat(ru.getResult()).isEqualTo(RefUpdate.Result.NEW);
assertThat(ru.getName()).isEqualTo(refName);
OptionalSubject.assertThat(IntBlob.parse(repo, refName))
.value()
.isEqualTo(IntBlob.create(ru.getNewObjectId(), 123));
}
@Test
public void tryStoreOldIdZero() throws Exception {
String refName = "refs/foo";
RefUpdate ru =
IntBlob.tryStore(
repo, rw, projectName, refName, ObjectId.zeroId(), 123, GitReferenceUpdated.DISABLED);
assertThat(ru.getResult()).isEqualTo(RefUpdate.Result.NEW);
assertThat(ru.getName()).isEqualTo(refName);
OptionalSubject.assertThat(IntBlob.parse(repo, refName))
.value()
.isEqualTo(IntBlob.create(ru.getNewObjectId(), 123));
}
@Test
public void tryStoreCorrectOldId() throws Exception {
String refName = "refs/foo";
ObjectId id = tr.update(refName, tr.blob("123"));
RefUpdate ru =
IntBlob.tryStore(repo, rw, projectName, refName, id, 456, GitReferenceUpdated.DISABLED);
assertThat(ru.getResult()).isEqualTo(RefUpdate.Result.FORCED);
assertThat(ru.getName()).isEqualTo(refName);
OptionalSubject.assertThat(IntBlob.parse(repo, refName))
.value()
.isEqualTo(IntBlob.create(ru.getNewObjectId(), 456));
}
@Test
public void tryStoreWrongOldId() throws Exception {
String refName = "refs/foo";
RefUpdate ru =
IntBlob.tryStore(
repo,
rw,
projectName,
refName,
ObjectId.fromString("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"),
123,
GitReferenceUpdated.DISABLED);
assertThat(ru.getResult()).isEqualTo(RefUpdate.Result.LOCK_FAILURE);
assertThat(ru.getName()).isEqualTo(refName);
OptionalSubject.assertThat(IntBlob.parse(repo, refName)).isEmpty();
}
@Test
public void storeNoOldId() throws Exception {
String refName = "refs/foo";
IntBlob.store(repo, rw, projectName, refName, null, 123, GitReferenceUpdated.DISABLED);
OptionalSubject.assertThat(IntBlob.parse(repo, refName))
.value()
.isEqualTo(IntBlob.create(getRef(refName), 123));
}
@Test
public void storeOldIdZero() throws Exception {
String refName = "refs/foo";
IntBlob.store(
repo, rw, projectName, refName, ObjectId.zeroId(), 123, GitReferenceUpdated.DISABLED);
OptionalSubject.assertThat(IntBlob.parse(repo, refName))
.value()
.isEqualTo(IntBlob.create(getRef(refName), 123));
}
@Test
public void storeCorrectOldId() throws Exception {
String refName = "refs/foo";
ObjectId id = tr.update(refName, tr.blob("123"));
IntBlob.store(repo, rw, projectName, refName, id, 456, GitReferenceUpdated.DISABLED);
OptionalSubject.assertThat(IntBlob.parse(repo, refName))
.value()
.isEqualTo(IntBlob.create(getRef(refName), 456));
}
@Test
public void storeWrongOldId() throws Exception {
String refName = "refs/foo";
LockFailureException thrown =
assertThrows(
LockFailureException.class,
() ->
IntBlob.store(
repo,
rw,
projectName,
refName,
ObjectId.fromString("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"),
123,
GitReferenceUpdated.DISABLED));
assertThat(thrown.getFailedRefs()).containsExactly("refs/foo");
OptionalSubject.assertThat(IntBlob.parse(repo, refName)).isEmpty();
}
private ObjectId getRef(String refName) throws IOException {
return repo.exactRef(refName).getObjectId();
}
}