Use repository specific work dirs (#1510)

With this change, work dirs are created in the
directory of the repository and no longer in the
global scm work dir directory. This is relevant due
to two facts:

1. Repositories may contain confidential data and therefore
   reside in special directories (that may be mounted on
   special drives). It may be considered a breach when these
   directories are cloned or otherwise copied to global
   temporary drives.
2. Big repositories may overload global temp spaces. It may be
   easier to create special drives with more space for such
   big repositories.
This commit is contained in:
René Pfeuffer
2021-01-28 12:53:39 +01:00
committed by GitHub
parent 57c9484d41
commit bd3671b428
23 changed files with 167 additions and 43 deletions

View File

@@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed ### Changed
- Directory name for git LFS files ([#1504](https://github.com/scm-manager/scm-manager/pull/1504)) - Directory name for git LFS files ([#1504](https://github.com/scm-manager/scm-manager/pull/1504))
- Temporary data for repositories is kept in the repository directory, not in a global directory ([#1510](https://github.com/scm-manager/scm-manager/pull/1510))
- Migrate integration tests to bdd ([#1497](https://github.com/scm-manager/scm-manager/pull/1497)) - Migrate integration tests to bdd ([#1497](https://github.com/scm-manager/scm-manager/pull/1497))
- Layout of proxy settings ([#1502](https://github.com/scm-manager/scm-manager/pull/1502)) - Layout of proxy settings ([#1502](https://github.com/scm-manager/scm-manager/pull/1502))
- Apply test ids to production builds for usage in e2e tests ([#1499](https://github.com/scm-manager/scm-manager/pull/1499)) - Apply test ids to production builds for usage in e2e tests ([#1499](https://github.com/scm-manager/scm-manager/pull/1499))

View File

@@ -81,9 +81,9 @@ public class ModifyCommandBuilder {
private final ModifyCommandRequest request = new ModifyCommandRequest(); private final ModifyCommandRequest request = new ModifyCommandRequest();
ModifyCommandBuilder(ModifyCommand command, WorkdirProvider workdirProvider, @Nullable EMail eMail) { ModifyCommandBuilder(ModifyCommand command, WorkdirProvider workdirProvider, String repositoryId, @Nullable EMail eMail) {
this.command = command; this.command = command;
this.workdir = workdirProvider.createNewWorkdir(); this.workdir = workdirProvider.createNewWorkdir(repositoryId);
this.eMail = eMail; this.eMail = eMail;
} }

View File

@@ -444,7 +444,7 @@ public final class RepositoryService implements Closeable {
LOG.debug("create modify command for repository {}", LOG.debug("create modify command for repository {}",
repository.getNamespaceAndName()); repository.getNamespaceAndName());
return new ModifyCommandBuilder(provider.getModifyCommand(), workdirProvider, eMail); return new ModifyCommandBuilder(provider.getModifyCommand(), workdirProvider, repository.getId(), eMail);
} }
/** /**

View File

@@ -46,7 +46,7 @@ public class NoneCachingWorkingCopyPool implements WorkingCopyPool {
@Override @Override
public <R, W> WorkingCopy<R, W> getWorkingCopy(SimpleWorkingCopyFactory<R, W, ?>.WorkingCopyContext context) { public <R, W> WorkingCopy<R, W> getWorkingCopy(SimpleWorkingCopyFactory<R, W, ?>.WorkingCopyContext context) {
return context.initialize(workdirProvider.createNewWorkdir()); return context.initialize(workdirProvider.createNewWorkdir(context.getScmRepository().getId()));
} }
@Override @Override

View File

@@ -96,7 +96,7 @@ public class SimpleCachingWorkingCopyPool implements WorkingCopyPool {
private <R, W> WorkingCopy<R, W> createNewWorkingCopy(SimpleWorkingCopyFactory<R, W, ?>.WorkingCopyContext workingCopyContext) { private <R, W> WorkingCopy<R, W> createNewWorkingCopy(SimpleWorkingCopyFactory<R, W, ?>.WorkingCopyContext workingCopyContext) {
Stopwatch stopwatch = Stopwatch.createStarted(); Stopwatch stopwatch = Stopwatch.createStarted();
File newWorkdir = workdirProvider.createNewWorkdir(); File newWorkdir = workdirProvider.createNewWorkdir(workingCopyContext.getScmRepository().getId());
WorkingCopy<R, W> parentAndClone = workingCopyContext.initialize(newWorkdir); WorkingCopy<R, W> parentAndClone = workingCopyContext.initialize(newWorkdir);
LOG.debug("initialized new workdir for {} in path {} in {}", workingCopyContext.getScmRepository(), newWorkdir, stopwatch.stop()); LOG.debug("initialized new workdir for {} in path {} in {}", workingCopyContext.getScmRepository(), newWorkdir, stopwatch.stop());
return parentAndClone; return parentAndClone;

View File

@@ -31,6 +31,10 @@ public class WorkdirCreationException extends ExceptionWithContext {
public static final String CODE = "3tS0mjSoo1"; public static final String CODE = "3tS0mjSoo1";
public WorkdirCreationException(String path) {
super(ContextEntry.ContextBuilder.entity("Path", path).build(), "Could not create directory " + path);
}
public WorkdirCreationException(String path, Exception cause) { public WorkdirCreationException(String path, Exception cause) {
super(ContextEntry.ContextBuilder.entity("Path", path).build(), "Could not create directory " + path, cause); super(ContextEntry.ContextBuilder.entity("Path", path).build(), "Could not create directory " + path, cause);
} }

View File

@@ -24,30 +24,55 @@
package sonia.scm.repository.work; package sonia.scm.repository.work;
import sonia.scm.repository.RepositoryLocationResolver;
import javax.inject.Inject;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path;
public class WorkdirProvider { public class WorkdirProvider {
private final File rootDirectory; private final File rootDirectory;
private final RepositoryLocationResolver repositoryLocationResolver;
private final boolean useRepositorySpecificDir;
public WorkdirProvider() { @Inject
this(new File(System.getProperty("scm.workdir" , System.getProperty("java.io.tmpdir")), "scm-work")); public WorkdirProvider(RepositoryLocationResolver repositoryLocationResolver) {
this(new File(System.getProperty("scm.workdir" , System.getProperty("java.io.tmpdir")), "scm-work"), repositoryLocationResolver, System.getProperty("scm.workdir") == null);
} }
public WorkdirProvider(File rootDirectory) { public WorkdirProvider(File rootDirectory, RepositoryLocationResolver repositoryLocationResolver, boolean useRepositorySpecificDir) {
this.rootDirectory = rootDirectory; this.rootDirectory = rootDirectory;
this.repositoryLocationResolver = repositoryLocationResolver;
this.useRepositorySpecificDir = useRepositorySpecificDir;
if (!rootDirectory.exists() && !rootDirectory.mkdirs()) { if (!rootDirectory.exists() && !rootDirectory.mkdirs()) {
throw new IllegalStateException("could not create pool directory " + rootDirectory); throw new IllegalStateException("could not create pool directory " + rootDirectory);
} }
} }
public File createNewWorkdir() { public File createNewWorkdir() {
return createWorkDir(this.rootDirectory);
}
public File createNewWorkdir(String repositoryId) {
if (useRepositorySpecificDir) {
return createWorkDir(repositoryLocationResolver.forClass(Path.class).getLocation(repositoryId).resolve("work").toFile());
} else {
return createNewWorkdir();
}
}
private File createWorkDir(File baseDirectory) {
// recreate base directory when it may be deleted (see https://github.com/scm-manager/scm-manager/issues/1493 for example)
if (!baseDirectory.exists() && !baseDirectory.mkdirs()) {
throw new WorkdirCreationException(baseDirectory.toString());
}
try { try {
return Files.createTempDirectory(rootDirectory.toPath(),"workdir").toFile(); return Files.createTempDirectory(baseDirectory.toPath(),"work-").toFile();
} catch (IOException e) { } catch (IOException e) {
throw new WorkdirCreationException(rootDirectory.toString(), e); throw new WorkdirCreationException(baseDirectory.toString(), e);
} }
} }
} }

View File

@@ -83,8 +83,8 @@ class ModifyCommandBuilderTest {
@BeforeEach @BeforeEach
void initWorkdir(@TempDir Path temp) throws IOException { void initWorkdir(@TempDir Path temp) throws IOException {
workdir = Files.createDirectory(temp.resolve("workdir")); workdir = Files.createDirectory(temp.resolve("workdir"));
lenient().when(workdirProvider.createNewWorkdir()).thenReturn(workdir.toFile()); lenient().when(workdirProvider.createNewWorkdir("1")).thenReturn(workdir.toFile());
commandBuilder = new ModifyCommandBuilder(command, workdirProvider, new EMail(SCM_CONFIGURATION)); commandBuilder = new ModifyCommandBuilder(command, workdirProvider, "1", new EMail(SCM_CONFIGURATION));
} }
@BeforeEach @BeforeEach

View File

@@ -38,6 +38,7 @@ import java.nio.file.Path;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.lenient; import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.never; import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
@@ -68,7 +69,7 @@ class SimpleCachingWorkingCopyPoolTest {
@Test @Test
void shouldCreateNewWorkdirForTheFirstRequest(@TempDir Path temp) { void shouldCreateNewWorkdirForTheFirstRequest(@TempDir Path temp) {
when(workingCopyContext.getScmRepository()).thenReturn(REPOSITORY); when(workingCopyContext.getScmRepository()).thenReturn(REPOSITORY);
when(workdirProvider.createNewWorkdir()).thenReturn(temp.toFile()); when(workdirProvider.createNewWorkdir(anyString())).thenReturn(temp.toFile());
WorkingCopy<?, ?> workdir = simpleCachingWorkingCopyPool.getWorkingCopy(workingCopyContext); WorkingCopy<?, ?> workdir = simpleCachingWorkingCopyPool.getWorkingCopy(workingCopyContext);
@@ -78,7 +79,7 @@ class SimpleCachingWorkingCopyPoolTest {
@Test @Test
void shouldCreateWorkdirOnlyOnceForTheSameRepository(@TempDir Path temp) throws SimpleWorkingCopyFactory.ReclaimFailedException { void shouldCreateWorkdirOnlyOnceForTheSameRepository(@TempDir Path temp) throws SimpleWorkingCopyFactory.ReclaimFailedException {
when(workingCopyContext.getScmRepository()).thenReturn(REPOSITORY); when(workingCopyContext.getScmRepository()).thenReturn(REPOSITORY);
when(workdirProvider.createNewWorkdir()).thenReturn(temp.toFile()); when(workdirProvider.createNewWorkdir(anyString())).thenReturn(temp.toFile());
WorkingCopy<?, ?> firstWorkdir = simpleCachingWorkingCopyPool.getWorkingCopy(workingCopyContext); WorkingCopy<?, ?> firstWorkdir = simpleCachingWorkingCopyPool.getWorkingCopy(workingCopyContext);
simpleCachingWorkingCopyPool.contextClosed(workingCopyContext, firstWorkdir.getDirectory()); simpleCachingWorkingCopyPool.contextClosed(workingCopyContext, firstWorkdir.getDirectory());
@@ -96,7 +97,7 @@ class SimpleCachingWorkingCopyPoolTest {
firstDirectory.mkdirs(); firstDirectory.mkdirs();
File secondDirectory = temp.resolve("second").toFile(); File secondDirectory = temp.resolve("second").toFile();
secondDirectory.mkdirs(); secondDirectory.mkdirs();
when(workdirProvider.createNewWorkdir()).thenReturn( when(workdirProvider.createNewWorkdir(anyString())).thenReturn(
firstDirectory, firstDirectory,
secondDirectory); secondDirectory);

View File

@@ -29,16 +29,20 @@ import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.rules.TemporaryFolder; import org.junit.rules.TemporaryFolder;
import sonia.scm.repository.Repository; import sonia.scm.repository.Repository;
import sonia.scm.repository.RepositoryLocationResolver;
import sonia.scm.repository.RepositoryProvider; import sonia.scm.repository.RepositoryProvider;
import sonia.scm.util.IOUtil; import sonia.scm.util.IOUtil;
import java.io.Closeable; import java.io.Closeable;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Path;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
public class SimpleWorkingCopyFactoryTest { public class SimpleWorkingCopyFactoryTest {
@@ -51,6 +55,8 @@ public class SimpleWorkingCopyFactoryTest {
public TemporaryFolder temporaryFolder = new TemporaryFolder(); public TemporaryFolder temporaryFolder = new TemporaryFolder();
private SimpleWorkingCopyFactory<Closeable, Closeable, Context> simpleWorkingCopyFactory; private SimpleWorkingCopyFactory<Closeable, Closeable, Context> simpleWorkingCopyFactory;
private final RepositoryLocationResolver repositoryLocationResolver = mock(RepositoryLocationResolver.class);
private String initialBranchForLastCloneCall; private String initialBranchForLastCloneCall;
private boolean workdirIsCached = false; private boolean workdirIsCached = false;
@@ -58,11 +64,11 @@ public class SimpleWorkingCopyFactoryTest {
@Before @Before
public void initFactory() throws IOException { public void initFactory() throws IOException {
WorkdirProvider workdirProvider = new WorkdirProvider(temporaryFolder.newFolder()); WorkdirProvider workdirProvider = new WorkdirProvider(temporaryFolder.newFolder(), repositoryLocationResolver, false);
WorkingCopyPool configurableTestWorkingCopyPool = new WorkingCopyPool() { WorkingCopyPool configurableTestWorkingCopyPool = new WorkingCopyPool() {
@Override @Override
public <R, W> WorkingCopy<R, W> getWorkingCopy(SimpleWorkingCopyFactory<R, W, ?>.WorkingCopyContext context) { public <R, W> WorkingCopy<R, W> getWorkingCopy(SimpleWorkingCopyFactory<R, W, ?>.WorkingCopyContext context) {
workdir = workdirProvider.createNewWorkdir(); workdir = workdirProvider.createNewWorkdir(context.getScmRepository().getId());
return context.initialize(workdir); return context.initialize(workdir);
} }
@@ -99,6 +105,10 @@ public class SimpleWorkingCopyFactoryTest {
workingCopy.close(); workingCopy.close();
} }
}; };
RepositoryLocationResolver.RepositoryLocationResolverInstance instanceMock = mock(RepositoryLocationResolver.RepositoryLocationResolverInstance.class);
when(repositoryLocationResolver.forClass(Path.class)).thenReturn(instanceMock);
when(instanceMock.getLocation(anyString())).thenAnswer(invocation -> temporaryFolder.newFolder(invocation.getArgument(0, String.class)).toPath());
} }
@Test @Test

View File

@@ -0,0 +1,93 @@
/*
* MIT License
*
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package sonia.scm.repository.work;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.api.io.TempDir;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import sonia.scm.repository.RepositoryLocationResolver;
import sonia.scm.repository.RepositoryLocationResolver.RepositoryLocationResolverInstance;
import java.io.File;
import java.nio.file.Path;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
class WorkdirProviderTest {
@Mock
private RepositoryLocationResolver repositoryLocationResolver;
@Mock
private RepositoryLocationResolverInstance<Path> repositoryLocationResolverInstance;
@BeforeEach
void initResolver(@TempDir Path temp) {
lenient().when(repositoryLocationResolver.forClass(Path.class)).thenReturn(repositoryLocationResolverInstance);
}
@Test
void shouldUseGlobalTempDirectory(@TempDir Path temp) {
WorkdirProvider provider = new WorkdirProvider(temp.toFile(), repositoryLocationResolver, true);
File newWorkdir = provider.createNewWorkdir();
assertThat(newWorkdir).exists();
assertThat(newWorkdir).hasParent(temp.toFile());
verify(repositoryLocationResolverInstance, never()).getLocation(anyString());
}
@Test
void shouldUseRepositorySpecificDirectory(@TempDir Path temp) {
when(repositoryLocationResolverInstance.getLocation("42")).thenReturn(temp.resolve("repo-dir"));
WorkdirProvider provider = new WorkdirProvider(temp.toFile(), repositoryLocationResolver, true);
File newWorkdir = provider.createNewWorkdir("42");
assertThat(newWorkdir).exists();
assertThat(newWorkdir.getParentFile()).hasName("work");
assertThat(newWorkdir.getParentFile().getParentFile()).hasName("repo-dir");
}
@Test
void shouldUseGlobalDirectoryIfExplicitlySet(@TempDir Path temp) {
WorkdirProvider provider = new WorkdirProvider(temp.toFile(), repositoryLocationResolver, false);
File newWorkdir = provider.createNewWorkdir("42");
assertThat(newWorkdir).exists();
assertThat(newWorkdir).hasParent(temp.toFile());
verify(repositoryLocationResolverInstance, never()).getLocation(anyString());
}
}

View File

@@ -29,16 +29,12 @@ import com.github.sdorra.shiro.SubjectAware;
import org.apache.shiro.subject.SimplePrincipalCollection; import org.apache.shiro.subject.SimplePrincipalCollection;
import org.apache.shiro.subject.Subject; import org.apache.shiro.subject.Subject;
import org.eclipse.jgit.api.Git; import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.CanceledException;
import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.lib.CommitBuilder;
import org.eclipse.jgit.lib.GpgSignature;
import org.eclipse.jgit.lib.GpgSigner; import org.eclipse.jgit.lib.GpgSigner;
import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.PersonIdent; import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.transport.CredentialsProvider;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
@@ -520,7 +516,7 @@ public class GitMergeCommandTest extends AbstractGitCommandTestBase {
} }
private GitMergeCommand createCommand(Consumer<Git> interceptor) { private GitMergeCommand createCommand(Consumer<Git> interceptor) {
return new GitMergeCommand(createContext(), new SimpleGitWorkingCopyFactory(new NoneCachingWorkingCopyPool(new WorkdirProvider()))) { return new GitMergeCommand(createContext(), new SimpleGitWorkingCopyFactory(new NoneCachingWorkingCopyPool(new WorkdirProvider(repositoryLocationResolver)))) {
@Override @Override
<R, W extends GitCloneWorker<R>> R inClone(Function<Git, W> workerSupplier, GitWorkingCopyFactory workingCopyFactory, String initialBranch) { <R, W extends GitCloneWorker<R>> R inClone(Function<Git, W> workerSupplier, GitWorkingCopyFactory workingCopyFactory, String initialBranch) {
Function<Git, W> interceptedWorkerSupplier = git -> { Function<Git, W> interceptedWorkerSupplier = git -> {

View File

@@ -92,7 +92,7 @@ public class GitMergeCommand_Conflict_Test extends AbstractGitCommandTestBase {
} }
private MergeConflictResult computeMergeConflictResult(String branchToMerge, String targetBranch) { private MergeConflictResult computeMergeConflictResult(String branchToMerge, String targetBranch) {
GitMergeCommand gitMergeCommand = new GitMergeCommand(createContext(), new SimpleGitWorkingCopyFactory(new NoneCachingWorkingCopyPool(new WorkdirProvider()))); GitMergeCommand gitMergeCommand = new GitMergeCommand(createContext(), new SimpleGitWorkingCopyFactory(new NoneCachingWorkingCopyPool(new WorkdirProvider(repositoryLocationResolver))));
MergeCommandRequest mergeCommandRequest = new MergeCommandRequest(); MergeCommandRequest mergeCommandRequest = new MergeCommandRequest();
mergeCommandRequest.setBranchToMerge(branchToMerge); mergeCommandRequest.setBranchToMerge(branchToMerge);
mergeCommandRequest.setTargetBranch(targetBranch); mergeCommandRequest.setTargetBranch(targetBranch);

View File

@@ -72,7 +72,7 @@ class GitModifyCommandTestBase extends AbstractGitCommandTestBase {
GitModifyCommand createCommand() { GitModifyCommand createCommand() {
return new GitModifyCommand( return new GitModifyCommand(
createContext(), createContext(),
new SimpleGitWorkingCopyFactory(new NoneCachingWorkingCopyPool(new WorkdirProvider())), new SimpleGitWorkingCopyFactory(new NoneCachingWorkingCopyPool(new WorkdirProvider(repositoryLocationResolver))),
lfsBlobStoreFactory, lfsBlobStoreFactory,
createGitRepositoryConfigStoreProvider()); createGitRepositoryConfigStoreProvider());
} }

View File

@@ -34,7 +34,6 @@ import org.junit.Before;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.rules.TemporaryFolder; import org.junit.rules.TemporaryFolder;
import sonia.scm.repository.GitChangesetConverterFactory;
import sonia.scm.repository.GitRepositoryHandler; import sonia.scm.repository.GitRepositoryHandler;
import sonia.scm.repository.GitTestHelper; import sonia.scm.repository.GitTestHelper;
import sonia.scm.repository.PreProcessorUtil; import sonia.scm.repository.PreProcessorUtil;
@@ -69,7 +68,7 @@ public class SimpleGitWorkingCopyFactoryTest extends AbstractGitCommandTestBase
GitRepositoryHandler gitRepositoryHandler = mock(GitRepositoryHandler.class); GitRepositoryHandler gitRepositoryHandler = mock(GitRepositoryHandler.class);
proto = new ScmTransportProtocol(of(GitTestHelper.createConverterFactory()), of(hookEventFacade), of(gitRepositoryHandler)); proto = new ScmTransportProtocol(of(GitTestHelper.createConverterFactory()), of(hookEventFacade), of(gitRepositoryHandler));
Transport.register(proto); Transport.register(proto);
workdirProvider = new WorkdirProvider(temporaryFolder.newFolder()); workdirProvider = new WorkdirProvider(temporaryFolder.newFolder(), repositoryLocationResolver, false);
} }
@Test @Test

View File

@@ -25,7 +25,6 @@
package sonia.scm.repository.spi; package sonia.scm.repository.spi;
import com.aragost.javahg.commands.PullCommand; import com.aragost.javahg.commands.PullCommand;
import com.google.inject.util.Providers;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import sonia.scm.repository.Branch; import sonia.scm.repository.Branch;
@@ -46,7 +45,7 @@ public class HgBranchCommandTest extends AbstractHgCommandTestBase {
@Before @Before
public void initWorkingCopyFactory() { public void initWorkingCopyFactory() {
workingCopyFactory = new SimpleHgWorkingCopyFactory(new NoneCachingWorkingCopyPool(new WorkdirProvider())) { workingCopyFactory = new SimpleHgWorkingCopyFactory(new NoneCachingWorkingCopyPool(new WorkdirProvider(repositoryLocationResolver))) {
@Override @Override
public void configure(PullCommand pullCommand) { public void configure(PullCommand pullCommand) {
// we do not want to configure http hooks in this unit test // we do not want to configure http hooks in this unit test

View File

@@ -51,7 +51,7 @@ public class HgModifyCommandTest extends AbstractHgCommandTestBase {
@Before @Before
public void initHgModifyCommand() { public void initHgModifyCommand() {
SimpleHgWorkingCopyFactory workingCopyFactory = new SimpleHgWorkingCopyFactory(new NoneCachingWorkingCopyPool(new WorkdirProvider())) { SimpleHgWorkingCopyFactory workingCopyFactory = new SimpleHgWorkingCopyFactory(new NoneCachingWorkingCopyPool(new WorkdirProvider(repositoryLocationResolver))) {
@Override @Override
public void configure(com.aragost.javahg.commands.PullCommand pullCommand) { public void configure(com.aragost.javahg.commands.PullCommand pullCommand) {
// we do not want to configure http hooks in this unit test // we do not want to configure http hooks in this unit test

View File

@@ -25,10 +25,8 @@
package sonia.scm.repository.spi; package sonia.scm.repository.spi;
import com.aragost.javahg.commands.PullCommand; import com.aragost.javahg.commands.PullCommand;
import com.google.inject.util.Providers;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import sonia.scm.repository.HgTestUtil;
import sonia.scm.repository.Tag; import sonia.scm.repository.Tag;
import sonia.scm.repository.api.TagCreateRequest; import sonia.scm.repository.api.TagCreateRequest;
import sonia.scm.repository.api.TagDeleteRequest; import sonia.scm.repository.api.TagDeleteRequest;
@@ -46,7 +44,7 @@ public class HgTagCommandTest extends AbstractHgCommandTestBase {
@Before @Before
public void initWorkingCopyFactory() { public void initWorkingCopyFactory() {
workingCopyFactory = new SimpleHgWorkingCopyFactory(new NoneCachingWorkingCopyPool(new WorkdirProvider())) { workingCopyFactory = new SimpleHgWorkingCopyFactory(new NoneCachingWorkingCopyPool(new WorkdirProvider(repositoryLocationResolver))) {
@Override @Override
public void configure(PullCommand pullCommand) { public void configure(PullCommand pullCommand) {
// we do not want to configure http hooks in this unit test // we do not want to configure http hooks in this unit test

View File

@@ -25,13 +25,10 @@
package sonia.scm.repository.spi; package sonia.scm.repository.spi;
import com.aragost.javahg.Repository; import com.aragost.javahg.Repository;
import com.google.inject.util.Providers;
import org.junit.Before; import org.junit.Before;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.rules.TemporaryFolder; import org.junit.rules.TemporaryFolder;
import sonia.scm.repository.HgEnvironmentBuilder;
import sonia.scm.repository.HgTestUtil;
import sonia.scm.repository.work.SimpleCachingWorkingCopyPool; import sonia.scm.repository.work.SimpleCachingWorkingCopyPool;
import sonia.scm.repository.work.WorkdirProvider; import sonia.scm.repository.work.WorkdirProvider;
import sonia.scm.repository.work.WorkingCopy; import sonia.scm.repository.work.WorkingCopy;
@@ -55,7 +52,7 @@ public class SimpleHgWorkingCopyFactoryTest extends AbstractHgCommandTestBase {
@Before @Before
public void bindScmProtocol() throws IOException { public void bindScmProtocol() throws IOException {
workdirProvider = new WorkdirProvider(temporaryFolder.newFolder()); workdirProvider = new WorkdirProvider(temporaryFolder.newFolder(), repositoryLocationResolver, false);
workingCopyFactory = new SimpleHgWorkingCopyFactory(new SimpleCachingWorkingCopyPool(workdirProvider)) { workingCopyFactory = new SimpleHgWorkingCopyFactory(new SimpleCachingWorkingCopyPool(workdirProvider)) {
@Override @Override
public void configure(com.aragost.javahg.commands.PullCommand pullCommand) { public void configure(com.aragost.javahg.commands.PullCommand pullCommand) {

View File

@@ -49,7 +49,7 @@ public class SimpleSvnWorkingCopyFactoryTest extends AbstractSvnCommandTestBase
@Before @Before
public void initWorkDirProvider() throws IOException { public void initWorkDirProvider() throws IOException {
workdirProvider = new WorkdirProvider(temporaryFolder.newFolder()); workdirProvider = new WorkdirProvider(temporaryFolder.newFolder(), repositoryLocationResolver, false);
} }
@Test @Test

View File

@@ -57,7 +57,7 @@ public class SvnModifyCommandTest extends AbstractSvnCommandTestBase {
@Before @Before
public void initSvnModifyCommand() { public void initSvnModifyCommand() {
context = createContext(); context = createContext();
workingCopyFactory = new SimpleSvnWorkingCopyFactory(new NoneCachingWorkingCopyPool(new WorkdirProvider(context.getDirectory()))); workingCopyFactory = new SimpleSvnWorkingCopyFactory(new NoneCachingWorkingCopyPool(new WorkdirProvider(context.getDirectory(), repositoryLocationResolver, false)));
svnModifyCommand = new SvnModifyCommand(context, workingCopyFactory); svnModifyCommand = new SvnModifyCommand(context, workingCopyFactory);
} }

View File

@@ -107,7 +107,7 @@ public class FullScmRepositoryExporter {
} }
private void writeRepository(RepositoryService service, TarArchiveOutputStream taos) throws IOException { private void writeRepository(RepositoryService service, TarArchiveOutputStream taos) throws IOException {
File newWorkdir = workdirProvider.createNewWorkdir(); File newWorkdir = workdirProvider.createNewWorkdir(service.getRepository().getId());
try { try {
File repositoryFile = Files.createFile(Paths.get(newWorkdir.getPath(), "repository")).toFile(); File repositoryFile = Files.createFile(Paths.get(newWorkdir.getPath(), "repository")).toFile();
try (FileOutputStream repositoryFos = new FileOutputStream(repositoryFile)) { try (FileOutputStream repositoryFos = new FileOutputStream(repositoryFile)) {
@@ -124,7 +124,7 @@ public class FullScmRepositoryExporter {
} }
private void writeStoreData(Repository repository, TarArchiveOutputStream taos) throws IOException { private void writeStoreData(Repository repository, TarArchiveOutputStream taos) throws IOException {
File newWorkdir = workdirProvider.createNewWorkdir(); File newWorkdir = workdirProvider.createNewWorkdir(repository.getId());
try { try {
File metadata = Files.createFile(Paths.get(newWorkdir.getPath(), "metadata")).toFile(); File metadata = Files.createFile(Paths.get(newWorkdir.getPath(), "metadata")).toFile();
try (FileOutputStream metadataFos = new FileOutputStream(metadata)) { try (FileOutputStream metadataFos = new FileOutputStream(metadata)) {

View File

@@ -87,7 +87,8 @@ class FullScmRepositoryExporterTest {
void shouldExportEverythingAsTarArchive(@TempDir Path temp) throws IOException { void shouldExportEverythingAsTarArchive(@TempDir Path temp) throws IOException {
BundleCommandBuilder bundleCommandBuilder = mock(BundleCommandBuilder.class); BundleCommandBuilder bundleCommandBuilder = mock(BundleCommandBuilder.class);
when(repositoryService.getBundleCommand()).thenReturn(bundleCommandBuilder); when(repositoryService.getBundleCommand()).thenReturn(bundleCommandBuilder);
when(workdirProvider.createNewWorkdir()).thenAnswer(invocation -> createWorkDir(temp)); when(repositoryService.getRepository()).thenReturn(REPOSITORY);
when(workdirProvider.createNewWorkdir(anyString())).thenAnswer(invocation -> createWorkDir(temp, invocation.getArgument(0, String.class)));
ByteArrayOutputStream baos = new ByteArrayOutputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream();
exporter.export(REPOSITORY, baos); exporter.export(REPOSITORY, baos);
@@ -98,8 +99,8 @@ class FullScmRepositoryExporterTest {
workDirsCreated.forEach(wd -> assertThat(wd).doesNotExist()); workDirsCreated.forEach(wd -> assertThat(wd).doesNotExist());
} }
private File createWorkDir(Path temp) throws IOException { private File createWorkDir(Path temp, String repositoryId) throws IOException {
Path newWorkDir = temp.resolve("workDir-" + workDirsCreated.size()); Path newWorkDir = temp.resolve("workDir-" + repositoryId);
workDirsCreated.add(newWorkDir); workDirsCreated.add(newWorkDir);
Files.createDirectories(newWorkDir); Files.createDirectories(newWorkDir);
return newWorkDir.toFile(); return newWorkDir.toFile();