| // Copyright (C) 2016 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.ericsson.gerrit.plugins.gcconductor; |
| |
| import static com.google.common.truth.Truth.assertThat; |
| import static org.mockito.Mockito.doThrow; |
| import static org.mockito.Mockito.never; |
| import static org.mockito.Mockito.verify; |
| import static org.mockito.Mockito.when; |
| |
| import com.ericsson.gerrit.plugins.gcconductor.evaluator.EvaluatorConfig; |
| import java.io.File; |
| import java.io.IOException; |
| import java.nio.file.Files; |
| import java.nio.file.Path; |
| import java.util.Comparator; |
| import org.eclipse.jgit.api.Git; |
| import org.eclipse.jgit.api.ResetCommand.ResetType; |
| import org.eclipse.jgit.internal.storage.file.FileRepository; |
| import org.eclipse.jgit.lib.Repository; |
| import org.eclipse.jgit.revwalk.RevCommit; |
| import org.junit.Before; |
| import org.junit.Rule; |
| import org.junit.Test; |
| import org.junit.rules.TemporaryFolder; |
| import org.junit.runner.RunWith; |
| import org.mockito.Mock; |
| import org.mockito.junit.MockitoJUnitRunner; |
| |
| @RunWith(MockitoJUnitRunner.class) |
| public class EvaluationTaskTest { |
| |
| @Rule public TemporaryFolder dir = new TemporaryFolder(); |
| |
| private static final String SOME_HOSTNAME = "hostname"; |
| |
| @Mock private EvaluatorConfig cfg; |
| @Mock private GcQueue queue; |
| |
| private EvaluationTask task; |
| private Repository repository; |
| private String repositoryPath; |
| |
| @Before |
| public void setUp() throws Exception { |
| repository = createRepository("someRepo.git"); |
| repositoryPath = repository.getDirectory().getAbsolutePath(); |
| task = new EvaluationTask(cfg, queue, SOME_HOSTNAME, repositoryPath); |
| } |
| |
| @Test |
| public void dirtyRepositoryObjectsShouldBeAddedToTheQueue() throws Exception { |
| when(cfg.getPackedThreshold()).thenReturn(1); |
| addFileTo(repository); |
| when(queue.contains(repositoryPath)).thenReturn(false); |
| task = new EvaluationTask(cfg, queue, SOME_HOSTNAME, repositoryPath); |
| task.run(); |
| verify(queue).add(repositoryPath, SOME_HOSTNAME); |
| } |
| |
| @Test |
| public void dirtyRepositoryPacksShouldBeAddedToTheQueue() throws Exception { |
| when(cfg.getPackedThreshold()).thenReturn(1); |
| when(queue.contains(repositoryPath)).thenReturn(false); |
| addFileTo(repository); |
| gc(repository); |
| task = new EvaluationTask(cfg, queue, SOME_HOSTNAME, repositoryPath); |
| task.run(); |
| verify(queue).add(repositoryPath, SOME_HOSTNAME); |
| } |
| |
| @Test |
| public void repositoryShouldNotBeAddedIfAlreadyInQueue() throws Exception { |
| when(queue.contains(repositoryPath)).thenReturn(true); |
| task.run(); |
| verify(queue, never()).add(repositoryPath, SOME_HOSTNAME); |
| } |
| |
| @Test |
| public void cleanRepositoryShouldNotBeAddedToQueue() throws Exception { |
| when(cfg.getLooseThreshold()).thenReturn(1); |
| when(cfg.getPackedThreshold()).thenReturn(1); |
| when(queue.contains(repositoryPath)).thenReturn(false); |
| task.run(); |
| verify(queue, never()).add(repositoryPath, SOME_HOSTNAME); |
| } |
| |
| @Test |
| public void queueThrowsErrorCheckingIfRepositoryExists() throws Exception { |
| doThrow(new GcQueueException("some message", new Throwable())) |
| .when(queue) |
| .contains(repositoryPath); |
| task.run(); |
| verify(queue, never()).add(repositoryPath, SOME_HOSTNAME); |
| } |
| |
| @Test |
| public void queueThrowsErrorInsertingRepository() throws Exception { |
| when(queue.contains(repositoryPath)).thenReturn(false); |
| doThrow(new GcQueueException("some message", new Throwable())) |
| .when(queue) |
| .add(repositoryPath, SOME_HOSTNAME); |
| task.run(); |
| } |
| |
| @Test |
| public void repositoryNoLongerExist() throws Exception { |
| when(queue.contains(repositoryPath)).thenReturn(false); |
| dir.delete(); |
| task.run(); |
| verify(queue, never()).add(repositoryPath, SOME_HOSTNAME); |
| } |
| |
| @Test |
| public void toStringReturnsProperMessage() { |
| assertThat(task.toString()).isEqualTo("Evaluate if repository need GC: " + repositoryPath); |
| } |
| |
| @Test |
| public void noUnreferencedObjects() throws Exception { |
| addFileTo(repository); |
| FileRepository fileRepository = (FileRepository) repository; |
| assertThat(task.getUnreferencedLooseObjectsCount(fileRepository)).isEqualTo(0); |
| } |
| |
| @Test |
| public void unreferencedObjectsCountShouldBeOne() throws Exception { |
| try (Git git = new Git(repository)) { |
| RevCommit initialCommit = git.commit().setMessage("initial commit").call(); |
| addFileTo(repository); |
| git.reset().setMode(ResetType.HARD).setRef(initialCommit.getName()).call(); |
| } |
| FileRepository fileRepository = (FileRepository) repository; |
| removeReflog(fileRepository.getDirectory()); |
| assertThat(task.getUnreferencedLooseObjectsCount(fileRepository)).isEqualTo(1); |
| } |
| |
| private void removeReflog(File directory) throws IOException { |
| Path logs = directory.toPath().resolve("logs"); |
| Files.walk(logs).sorted(Comparator.reverseOrder()).map(Path::toFile).forEach(File::delete); |
| } |
| |
| private Repository createRepository(String repoName) throws Exception { |
| File repo = dir.newFolder(repoName); |
| try (Git git = Git.init().setDirectory(repo).call()) { |
| return git.getRepository(); |
| } |
| } |
| |
| private void addFileTo(Repository repository) throws Exception { |
| try (Git git = new Git(repository)) { |
| new File(repository.getDirectory().getParent(), "test"); |
| git.add().addFilepattern("test").call(); |
| git.commit().setMessage("Add test file").call(); |
| } |
| } |
| |
| private void gc(Repository repository) throws Exception { |
| try (Git git = new Git(repository)) { |
| git.gc().setAggressive(true).call(); |
| } |
| } |
| } |