Files
gerrit/javatests/com/google/gerrit/server/git/LocalDiskRepositoryManagerTest.java
Marco Miller 3aa536101d Merge branch 'stable-3.0' into stable-3.1
* stable-3.0:
  Update git submodules
  Update git submodules
  GitRepositoryManager should be responsible to enable/disable the GC

Adapt GitRepositoryManagerTest to the removal of GerritBaseTests in this
branch (commit a36b3580). Adapt that same class also to the local
package for Project.NameKey, as well as to the no longer thrown
exceptions.

Change-Id: I799c8884a779f68bcb341d4be3974e74a1974532
2021-03-09 14:51:45 -05:00

299 lines
10 KiB
Java

// Copyright (C) 2015 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.git;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.TruthJUnit.assume;
import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import com.google.gerrit.entities.Project;
import com.google.gerrit.server.config.SitePaths;
import com.google.gerrit.server.ioutil.HostPlatform;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import org.eclipse.jgit.errors.RepositoryNotFoundException;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.RepositoryCache;
import org.eclipse.jgit.lib.RepositoryCache.FileKey;
import org.eclipse.jgit.util.FS;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
public class LocalDiskRepositoryManagerTest {
@Rule public TemporaryFolder temporaryFolder = new TemporaryFolder();
private Config cfg;
private SitePaths site;
private LocalDiskRepositoryManager repoManager;
@Before
public void setUp() throws Exception {
site = new SitePaths(temporaryFolder.newFolder().toPath());
site.resolve("git").toFile().mkdir();
cfg = new Config();
cfg.setString("gerrit", null, "basePath", "git");
repoManager = new LocalDiskRepositoryManager(site, cfg);
}
@Test
public void testThatNullBasePathThrowsAnException() {
assertThrows(
IllegalStateException.class, () -> new LocalDiskRepositoryManager(site, new Config()));
}
@Test
public void projectCreation() throws Exception {
Project.NameKey projectA = Project.nameKey("projectA");
try (Repository repo = repoManager.createRepository(projectA)) {
assertThat(repo).isNotNull();
}
try (Repository repo = repoManager.openRepository(projectA)) {
assertThat(repo).isNotNull();
}
assertThat(repoManager.list()).containsExactly(projectA);
}
@Test
public void testProjectCreationWithEmptyName() throws Exception {
assertThrows(
RepositoryNotFoundException.class, () -> repoManager.createRepository(Project.nameKey("")));
}
@Test
public void testProjectCreationWithTrailingSlash() throws Exception {
assertThrows(
RepositoryNotFoundException.class,
() -> repoManager.createRepository(Project.nameKey("projectA/")));
}
@Test
public void testProjectCreationWithBackSlash() throws Exception {
assertThrows(
RepositoryNotFoundException.class,
() -> repoManager.createRepository(Project.nameKey("a\\projectA")));
}
@Test
public void testProjectCreationAbsolutePath() throws Exception {
assertThrows(
RepositoryNotFoundException.class,
() -> repoManager.createRepository(Project.nameKey("/projectA")));
}
@Test
public void testProjectCreationStartingWithDotDot() throws Exception {
assertThrows(
RepositoryNotFoundException.class,
() -> repoManager.createRepository(Project.nameKey("../projectA")));
}
@Test
public void testProjectCreationContainsDotDot() throws Exception {
assertThrows(
RepositoryNotFoundException.class,
() -> repoManager.createRepository(Project.nameKey("a/../projectA")));
}
@Test
public void testProjectCreationDotPathSegment() throws Exception {
assertThrows(
RepositoryNotFoundException.class,
() -> repoManager.createRepository(Project.nameKey("a/./projectA")));
}
@Test
public void testProjectCreationWithTwoSlashes() throws Exception {
assertThrows(
RepositoryNotFoundException.class,
() -> repoManager.createRepository(Project.nameKey("a//projectA")));
}
@Test
public void testProjectCreationWithPathSegmentEndingByDotGit() throws Exception {
assertThrows(
RepositoryNotFoundException.class,
() -> repoManager.createRepository(Project.nameKey("a/b.git/projectA")));
}
@Test
public void testProjectCreationWithQuestionMark() throws Exception {
assertThrows(
RepositoryNotFoundException.class,
() -> repoManager.createRepository(Project.nameKey("project?A")));
}
@Test
public void testProjectCreationWithPercentageSign() throws Exception {
assertThrows(
RepositoryNotFoundException.class,
() -> repoManager.createRepository(Project.nameKey("project%A")));
}
@Test
public void testProjectCreationWithWidlcard() throws Exception {
assertThrows(
RepositoryNotFoundException.class,
() -> repoManager.createRepository(Project.nameKey("project*A")));
}
@Test
public void testProjectCreationWithColon() throws Exception {
assertThrows(
RepositoryNotFoundException.class,
() -> repoManager.createRepository(Project.nameKey("project:A")));
}
@Test
public void testProjectCreationWithLessThatSign() throws Exception {
assertThrows(
RepositoryNotFoundException.class,
() -> repoManager.createRepository(Project.nameKey("project<A")));
}
@Test
public void testProjectCreationWithGreaterThatSign() throws Exception {
assertThrows(
RepositoryNotFoundException.class,
() -> repoManager.createRepository(Project.nameKey("project>A")));
}
@Test
public void testProjectCreationWithPipe() throws Exception {
assertThrows(
RepositoryNotFoundException.class,
() -> repoManager.createRepository(Project.nameKey("project|A")));
}
@Test
public void testProjectCreationWithDollarSign() throws Exception {
assertThrows(
RepositoryNotFoundException.class,
() -> repoManager.createRepository(Project.nameKey("project$A")));
}
@Test
public void testProjectCreationWithCarriageReturn() throws Exception {
assertThrows(
RepositoryNotFoundException.class,
() -> repoManager.createRepository(Project.nameKey("project\\rA")));
}
@Test
public void testProjectRecreation() throws Exception {
repoManager.createRepository(Project.nameKey("a"));
assertThrows(
IllegalStateException.class, () -> repoManager.createRepository(Project.nameKey("a")));
}
@Test
public void testProjectRecreationAfterRestart() throws Exception {
repoManager.createRepository(Project.nameKey("a"));
LocalDiskRepositoryManager newRepoManager = new LocalDiskRepositoryManager(site, cfg);
assertThrows(
IllegalStateException.class, () -> newRepoManager.createRepository(Project.nameKey("a")));
}
@Test
public void openRepositoryCreatedDirectlyOnDisk() throws Exception {
Project.NameKey projectA = Project.nameKey("projectA");
createRepository(repoManager.getBasePath(projectA), projectA.get());
try (Repository repo = repoManager.openRepository(projectA)) {
assertThat(repo).isNotNull();
}
assertThat(repoManager.list()).containsExactly(projectA);
}
@Test
public void testNameCaseMismatch() throws Exception {
assume().that(HostPlatform.isWin32() || HostPlatform.isMac()).isTrue();
repoManager.createRepository(Project.nameKey("a"));
assertThrows(
RepositoryCaseMismatchException.class,
() -> repoManager.createRepository(Project.nameKey("A")));
}
@Test
public void testNameCaseMismatchWithSymlink() throws Exception {
assume().that(HostPlatform.isWin32() || HostPlatform.isMac()).isTrue();
Project.NameKey name = Project.nameKey("a");
repoManager.createRepository(name);
createSymLink(name, "b.git");
assertThrows(
RepositoryCaseMismatchException.class,
() -> repoManager.createRepository(Project.nameKey("B")));
}
@Test
public void testNameCaseMismatchAfterRestart() throws Exception {
assume().that(HostPlatform.isWin32() || HostPlatform.isMac()).isTrue();
Project.NameKey name = Project.nameKey("a");
repoManager.createRepository(name);
LocalDiskRepositoryManager newRepoManager = new LocalDiskRepositoryManager(site, cfg);
assertThrows(
RepositoryCaseMismatchException.class,
() -> newRepoManager.createRepository(Project.nameKey("A")));
}
@Test
public void testRepositoryCanPerformGC() throws Exception {
assertThat(repoManager.canPerformGC()).isTrue();
}
private void createSymLink(Project.NameKey project, String link) throws IOException {
Path base = repoManager.getBasePath(project);
Path projectDir = base.resolve(project.get() + ".git");
Path symlink = base.resolve(link);
Files.createSymbolicLink(symlink, projectDir);
}
@Test
public void testOpenRepositoryInvalidName() throws Exception {
assertThrows(
RepositoryNotFoundException.class,
() -> repoManager.openRepository(Project.nameKey("project%?|<>A")));
}
@Test
public void list() throws Exception {
Project.NameKey projectA = Project.nameKey("projectA");
createRepository(repoManager.getBasePath(projectA), projectA.get());
Project.NameKey projectB = Project.nameKey("path/projectB");
createRepository(repoManager.getBasePath(projectB), projectB.get());
Project.NameKey projectC = Project.nameKey("anotherPath/path/projectC");
createRepository(repoManager.getBasePath(projectC), projectC.get());
// create an invalid git repo named only .git
repoManager.getBasePath(null).resolve(".git").toFile().mkdir();
// create an invalid repo name
createRepository(repoManager.getBasePath(null), "project?A");
assertThat(repoManager.list()).containsExactly(projectA, projectB, projectC);
}
private void createRepository(Path directory, String projectName) throws IOException {
String n = projectName + Constants.DOT_GIT_EXT;
FileKey loc = FileKey.exact(directory.resolve(n).toFile(), FS.DETECTED);
try (Repository db = RepositoryCache.open(loc, false)) {
db.create(true /* bare */);
}
}
}