blob: 6739890d482255f6571b394359d1fdd433187c3e [file] [log] [blame]
// 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.plugins.checks.db;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import com.google.common.truth.StringSubject;
import com.google.gerrit.entities.Project;
import com.google.gerrit.plugins.checks.CheckerRef;
import com.google.gerrit.plugins.checks.CheckerUuid;
import com.google.gerrit.server.config.AllProjectsName;
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
import com.google.gerrit.server.git.meta.MetaDataUpdate;
import com.google.gerrit.server.util.time.TimeUtil;
import java.io.IOException;
import java.util.TimeZone;
import org.eclipse.jgit.internal.storage.dfs.DfsRepositoryDescription;
import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
import org.junit.Before;
import org.junit.Test;
public class CheckersByRepositoryNotesTest {
private final TimeZone timeZone = TimeZone.getTimeZone("America/Los_Angeles");
private AllProjectsName projectName;
private Repository repository;
@Before
public void setUp() throws Exception {
projectName = new AllProjectsName("Test Repository");
repository = new InMemoryRepository(new DfsRepositoryDescription("Test Repository"));
}
@Test
public void getEmptyCheckersList() throws Exception {
CheckersByRepositoryNotes checkersByRepositoryNotes = loadCheckersByRepositoryNotes();
assertThat(checkersByRepositoryNotes.get(Project.nameKey("some-project"))).isEmpty();
}
@Test
public void insertCheckers() throws Exception {
CheckersByRepositoryNotes checkersByRepositoryNotes = loadCheckersByRepositoryNotes();
Project.NameKey project1 = Project.nameKey("some-project");
Project.NameKey project2 = Project.nameKey("other-project");
CheckerUuid checkerUuid1 = CheckerUuid.parse("foo:bar");
checkersByRepositoryNotes.insert(checkerUuid1, project1);
commit(checkersByRepositoryNotes);
assertThat(checkersByRepositoryNotes.get(project1)).containsExactly(checkerUuid1);
assertThat(checkersByRepositoryNotes.get(project2)).isEmpty();
CheckerUuid checkerUuid2 = CheckerUuid.parse("foo:baz");
checkersByRepositoryNotes.insert(checkerUuid2, project1);
commit(checkersByRepositoryNotes);
assertThat(checkersByRepositoryNotes.get(project1))
.containsExactly(checkerUuid1, checkerUuid2)
.inOrder();
assertThat(checkersByRepositoryNotes.get(project2)).isEmpty();
CheckerUuid checkerUuid3 = CheckerUuid.parse("bar:baz");
checkersByRepositoryNotes.insert(checkerUuid3, project2);
commit(checkersByRepositoryNotes);
assertThat(checkersByRepositoryNotes.get(project1))
.containsExactly(checkerUuid1, checkerUuid2)
.inOrder();
assertThat(checkersByRepositoryNotes.get(project2)).containsExactly(checkerUuid3);
}
@Test
public void insertCheckerTwice() throws Exception {
CheckersByRepositoryNotes checkersByRepositoryNotes = loadCheckersByRepositoryNotes();
CheckerUuid checkerUuid = CheckerUuid.parse("foo:bar");
Project.NameKey project = Project.nameKey("some-project");
checkersByRepositoryNotes.insert(checkerUuid, project);
commit(checkersByRepositoryNotes);
assertThat(checkersByRepositoryNotes.get(project)).containsExactly(checkerUuid);
ObjectId commitId = getRefsMetaCheckersState();
checkersByRepositoryNotes.insert(checkerUuid, project);
commit(checkersByRepositoryNotes);
assertThat(checkersByRepositoryNotes.get(project)).containsExactly(checkerUuid);
assertThat(getRefsMetaCheckersState()).isEqualTo(commitId);
}
@Test
public void removeCheckers() throws Exception {
CheckersByRepositoryNotes checkersByRepositoryNotes = loadCheckersByRepositoryNotes();
Project.NameKey project = Project.nameKey("some-project");
CheckerUuid checkerUuid1 = CheckerUuid.parse("bar:baz");
CheckerUuid checkerUuid2 = CheckerUuid.parse("foo:bar");
CheckerUuid checkerUuid3 = CheckerUuid.parse("foo:baz");
checkersByRepositoryNotes.insert(checkerUuid1, project);
checkersByRepositoryNotes.insert(checkerUuid2, project);
checkersByRepositoryNotes.insert(checkerUuid3, project);
commit(checkersByRepositoryNotes);
assertThat(checkersByRepositoryNotes.get(project))
.containsExactly(checkerUuid1, checkerUuid2, checkerUuid3)
.inOrder();
checkersByRepositoryNotes.remove(checkerUuid2, project);
commit(checkersByRepositoryNotes);
assertThat(checkersByRepositoryNotes.get(project))
.containsExactly(checkerUuid1, checkerUuid3)
.inOrder();
checkersByRepositoryNotes.remove(checkerUuid1, project);
commit(checkersByRepositoryNotes);
assertThat(checkersByRepositoryNotes.get(project)).containsExactly(checkerUuid3).inOrder();
checkersByRepositoryNotes.remove(checkerUuid3, project);
commit(checkersByRepositoryNotes);
assertThat(checkersByRepositoryNotes.get(project)).isEmpty();
}
@Test
public void removeNonExistingChecker() throws Exception {
CheckersByRepositoryNotes checkersByRepositoryNotes = loadCheckersByRepositoryNotes();
Project.NameKey project1 = Project.nameKey("some-project");
Project.NameKey project2 = Project.nameKey("other-project");
CheckerUuid checkerUuid1 = CheckerUuid.parse("foo:bar");
CheckerUuid checkerUuid2 = CheckerUuid.parse("foo:baz");
checkersByRepositoryNotes.insert(checkerUuid1, project1);
commit(checkersByRepositoryNotes);
assertThat(checkersByRepositoryNotes.get(project1)).containsExactly(checkerUuid1);
assertThat(checkersByRepositoryNotes.get(project2)).isEmpty();
ObjectId commitId = getRefsMetaCheckersState();
checkersByRepositoryNotes.remove(checkerUuid2, project1);
checkersByRepositoryNotes.remove(checkerUuid1, project2);
commit(checkersByRepositoryNotes);
assertThat(checkersByRepositoryNotes.get(project1)).containsExactly(checkerUuid1);
assertThat(checkersByRepositoryNotes.get(project2)).isEmpty();
assertThat(getRefsMetaCheckersState()).isEqualTo(commitId);
}
@Test
public void updateCheckers() throws Exception {
CheckersByRepositoryNotes checkersByRepositoryNotes = loadCheckersByRepositoryNotes();
Project.NameKey project1 = Project.nameKey("some-project");
Project.NameKey project2 = Project.nameKey("other-project");
CheckerUuid checkerUuid1 = CheckerUuid.parse("foo:bar");
CheckerUuid checkerUuid2 = CheckerUuid.parse("foo:baz");
checkersByRepositoryNotes.insert(checkerUuid1, project1);
checkersByRepositoryNotes.insert(checkerUuid2, project1);
commit(checkersByRepositoryNotes);
assertThat(checkersByRepositoryNotes.get(project1))
.containsExactly(checkerUuid1, checkerUuid2)
.inOrder();
assertThat(checkersByRepositoryNotes.get(project2)).isEmpty();
checkersByRepositoryNotes.update(checkerUuid1, project1, project2);
commit(checkersByRepositoryNotes);
assertThat(checkersByRepositoryNotes.get(project1)).containsExactly(checkerUuid2);
assertThat(checkersByRepositoryNotes.get(project2)).containsExactly(checkerUuid1);
checkersByRepositoryNotes.update(checkerUuid2, project1, project2);
commit(checkersByRepositoryNotes);
assertThat(checkersByRepositoryNotes.get(project1)).isEmpty();
assertThat(checkersByRepositoryNotes.get(project2))
.containsExactly(checkerUuid1, checkerUuid2)
.inOrder();
}
@Test
public void sortOrder() throws Exception {
CheckersByRepositoryNotes checkersByRepositoryNotes = loadCheckersByRepositoryNotes();
Project.NameKey project = Project.nameKey("some-project");
CheckerUuid checkerUuid1 = CheckerUuid.parse("foo:bar");
CheckerUuid checkerUuid2 = CheckerUuid.parse("foo:baz");
checkersByRepositoryNotes.insert(checkerUuid1, project);
checkersByRepositoryNotes.insert(checkerUuid2, project);
commit(checkersByRepositoryNotes);
assertThat(checkersByRepositoryNotes.get(project))
.containsExactly(checkerUuid1, checkerUuid2)
.inOrder();
CheckerUuid checkerUuid3 = CheckerUuid.parse("abc:xyz");
CheckerUuid checkerUuid4 = CheckerUuid.parse("xyz:abc");
checkersByRepositoryNotes.insert(checkerUuid3, project);
checkersByRepositoryNotes.insert(checkerUuid4, project);
commit(checkersByRepositoryNotes);
assertThat(checkersByRepositoryNotes.get(project))
.containsExactly(checkerUuid3, checkerUuid1, checkerUuid2, checkerUuid4)
.inOrder();
}
@Test
public void commitMessage() throws Exception {
CheckersByRepositoryNotes checkersByRepositoryNotes = loadCheckersByRepositoryNotes();
CheckerUuid checkerUuid = CheckerUuid.parse("foo:bar");
Project.NameKey project = Project.nameKey("some-project");
checkersByRepositoryNotes.insert(checkerUuid, project);
commit(checkersByRepositoryNotes);
assertThatCommitMessage()
.isEqualTo(
"Update checkers by repository\n\nChecker: "
+ checkerUuid.toString()
+ "\nRepository: "
+ project.get());
}
@Test
public void noOpUpdate() throws Exception {
CheckersByRepositoryNotes checkersByRepositoryNotes = loadCheckersByRepositoryNotes();
Project.NameKey project = Project.nameKey("some-project");
CheckerUuid checkerUuid1 = CheckerUuid.parse("foo:bar");
checkersByRepositoryNotes.insert(checkerUuid1, project);
commit(checkersByRepositoryNotes);
ObjectId commitId = getRefsMetaCheckersState();
// Set the repository of the checker to the same value that it currently has.
checkersByRepositoryNotes.update(checkerUuid1, project, project);
commit(checkersByRepositoryNotes);
assertThat(getRefsMetaCheckersState()).isEqualTo(commitId);
// Insert a new checker and remove it before commit.
CheckerUuid checkerUuid2 = CheckerUuid.parse("foo:baz");
checkersByRepositoryNotes.insert(checkerUuid2, project);
checkersByRepositoryNotes.remove(checkerUuid2, project);
commit(checkersByRepositoryNotes);
assertThat(getRefsMetaCheckersState()).isEqualTo(commitId);
}
@Test
public void getCheckersFromOldRevision() throws Exception {
CheckersByRepositoryNotes checkersByRepositoryNotes = loadCheckersByRepositoryNotes();
Project.NameKey project = Project.nameKey("some-project");
CheckerUuid checkerUuid1 = CheckerUuid.parse("foo:bar");
checkersByRepositoryNotes.insert(checkerUuid1, project);
commit(checkersByRepositoryNotes);
assertThat(checkersByRepositoryNotes.get(project)).containsExactly(checkerUuid1);
ObjectId oldRevision = getRefsMetaCheckersState();
CheckerUuid checkerUuid2 = CheckerUuid.parse("foo:baz");
checkersByRepositoryNotes.insert(checkerUuid2, project);
commit(checkersByRepositoryNotes);
assertThat(checkersByRepositoryNotes.get(project))
.containsExactly(checkerUuid1, checkerUuid2)
.inOrder();
assertThat(CheckersByRepositoryNotes.load(projectName, repository, oldRevision).get(project))
.containsExactly(checkerUuid1);
}
@Test
public void getCheckersFromZeroIdRevision() throws Exception {
assertThat(
CheckersByRepositoryNotes.load(projectName, repository, ObjectId.zeroId())
.get(Project.nameKey("some-project")))
.isEmpty();
}
@Test
public void getCheckersFromNullRevision() throws Exception {
assertThat(
CheckersByRepositoryNotes.load(projectName, repository, null)
.get(Project.nameKey("some-project")))
.isEmpty();
}
private CheckersByRepositoryNotes loadCheckersByRepositoryNotes() throws IOException {
return CheckersByRepositoryNotes.load(projectName, repository);
}
private void commit(CheckersByRepositoryNotes checkersByRepositoryNotes) throws IOException {
try (MetaDataUpdate metaDataUpdate = createMetaDataUpdate()) {
checkersByRepositoryNotes.commit(metaDataUpdate);
}
}
private MetaDataUpdate createMetaDataUpdate() {
PersonIdent serverIdent =
new PersonIdent(
"Gerrit Server", "noreply@gerritcodereview.com", TimeUtil.nowTs(), timeZone);
MetaDataUpdate metaDataUpdate =
new MetaDataUpdate(
GitReferenceUpdated.DISABLED, Project.nameKey("Test Repository"), repository);
metaDataUpdate.getCommitBuilder().setCommitter(serverIdent);
metaDataUpdate.getCommitBuilder().setAuthor(serverIdent);
return metaDataUpdate;
}
private ObjectId getRefsMetaCheckersState() throws IOException {
return repository.exactRef(CheckerRef.REFS_META_CHECKERS).getObjectId();
}
private StringSubject assertThatCommitMessage() throws IOException {
try (RevWalk rw = new RevWalk(repository)) {
RevCommit commit = rw.parseCommit(getRefsMetaCheckersState());
return assertWithMessage("commit message").that(commit.getFullMessage());
}
}
}