| // 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(); |
| } |
| } |