Extract class to provide temporary work directories

This commit is contained in:
René Pfeuffer
2019-08-27 16:56:44 +02:00
parent 2a184eaf17
commit 4f21756d00
9 changed files with 55 additions and 31 deletions

View File

@@ -7,29 +7,21 @@ import sonia.scm.repository.Repository;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files;
public abstract class SimpleWorkdirFactory<R, C> implements WorkdirFactory<R, C> { public abstract class SimpleWorkdirFactory<R, C> implements WorkdirFactory<R, C> {
private static final Logger logger = LoggerFactory.getLogger(SimpleWorkdirFactory.class); private static final Logger logger = LoggerFactory.getLogger(SimpleWorkdirFactory.class);
private final File poolDirectory; private final WorkdirProvider workdirProvider;
public SimpleWorkdirFactory() { public SimpleWorkdirFactory(WorkdirProvider workdirProvider) {
this(new File(System.getProperty("scm.workdir" , System.getProperty("java.io.tmpdir")), "scm-work")); this.workdirProvider = workdirProvider;
}
public SimpleWorkdirFactory(File poolDirectory) {
this.poolDirectory = poolDirectory;
if (!poolDirectory.exists() && !poolDirectory.mkdirs()) {
throw new IllegalStateException("could not create pool directory " + poolDirectory);
}
} }
@Override @Override
public WorkingCopy<R> createWorkingCopy(C context) { public WorkingCopy<R> createWorkingCopy(C context) {
try { try {
File directory = createNewWorkdir(); File directory = workdirProvider.createNewWorkdir();
ParentAndClone<R> parentAndClone = cloneRepository(context, directory); ParentAndClone<R> parentAndClone = cloneRepository(context, directory);
return new WorkingCopy<>(parentAndClone.getClone(), parentAndClone.getParent(), this::close, directory); return new WorkingCopy<>(parentAndClone.getClone(), parentAndClone.getParent(), this::close, directory);
} catch (IOException e) { } catch (IOException e) {
@@ -45,10 +37,6 @@ public abstract class SimpleWorkdirFactory<R, C> implements WorkdirFactory<R, C>
protected abstract ParentAndClone<R> cloneRepository(C context, File target) throws IOException; protected abstract ParentAndClone<R> cloneRepository(C context, File target) throws IOException;
private File createNewWorkdir() throws IOException {
return Files.createTempDirectory(poolDirectory.toPath(),"workdir").toFile();
}
private void close(R repository) { private void close(R repository) {
try { try {
closeRepository(repository); closeRepository(repository);

View File

@@ -0,0 +1,29 @@
package sonia.scm.repository.util;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
public class WorkdirProvider {
private final File poolDirectory;
public WorkdirProvider() {
this(new File(System.getProperty("scm.workdir" , System.getProperty("java.io.tmpdir")), "scm-work"));
}
public WorkdirProvider(File poolDirectory) {
this.poolDirectory = poolDirectory;
if (!poolDirectory.exists() && !poolDirectory.mkdirs()) {
throw new IllegalStateException("could not create pool directory " + poolDirectory);
}
}
public File createNewWorkdir() {
try {
return Files.createTempDirectory(poolDirectory.toPath(),"workdir").toFile();
} catch (IOException e) {
throw new RuntimeException("could not create temporary workdir", e);
}
}
}

View File

@@ -28,7 +28,8 @@ public class SimpleWorkdirFactoryTest {
@Before @Before
public void initFactory() throws IOException { public void initFactory() throws IOException {
simpleWorkdirFactory = new SimpleWorkdirFactory<Closeable, Context>(temporaryFolder.newFolder()) { WorkdirProvider workdirProvider = new WorkdirProvider(temporaryFolder.newFolder());
simpleWorkdirFactory = new SimpleWorkdirFactory<Closeable, Context>(workdirProvider) {
@Override @Override
protected Repository getScmRepository(Context context) { protected Repository getScmRepository(Context context) {
return REPOSITORY; return REPOSITORY;

View File

@@ -7,16 +7,14 @@ import org.eclipse.jgit.transport.ScmTransportProtocol;
import sonia.scm.repository.GitWorkdirFactory; import sonia.scm.repository.GitWorkdirFactory;
import sonia.scm.repository.InternalRepositoryException; import sonia.scm.repository.InternalRepositoryException;
import sonia.scm.repository.util.SimpleWorkdirFactory; import sonia.scm.repository.util.SimpleWorkdirFactory;
import sonia.scm.repository.util.WorkdirProvider;
import java.io.File; import java.io.File;
public class SimpleGitWorkdirFactory extends SimpleWorkdirFactory<Repository, GitContext> implements GitWorkdirFactory { public class SimpleGitWorkdirFactory extends SimpleWorkdirFactory<Repository, GitContext> implements GitWorkdirFactory {
public SimpleGitWorkdirFactory() { public SimpleGitWorkdirFactory(WorkdirProvider workdirProvider) {
} super(workdirProvider);
SimpleGitWorkdirFactory(File poolDirectory) {
super(poolDirectory);
} }
@Override @Override

View File

@@ -5,6 +5,7 @@ import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import sonia.scm.repository.Branch; import sonia.scm.repository.Branch;
import sonia.scm.repository.api.BranchRequest; import sonia.scm.repository.api.BranchRequest;
import sonia.scm.repository.util.WorkdirProvider;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
@@ -25,7 +26,7 @@ public class GitBranchCommandTest extends AbstractGitCommandTestBase {
branchRequest.setParentBranch(source.getName()); branchRequest.setParentBranch(source.getName());
branchRequest.setNewBranch("new_branch"); branchRequest.setNewBranch("new_branch");
new GitBranchCommand(context, repository, new SimpleGitWorkdirFactory()).branch(branchRequest); new GitBranchCommand(context, repository, new SimpleGitWorkdirFactory(new WorkdirProvider())).branch(branchRequest);
Branch newBranch = findBranch(context, "new_branch"); Branch newBranch = findBranch(context, "new_branch");
Assertions.assertThat(newBranch.getRevision()).isEqualTo(source.getRevision()); Assertions.assertThat(newBranch.getRevision()).isEqualTo(source.getRevision());
@@ -45,7 +46,7 @@ public class GitBranchCommandTest extends AbstractGitCommandTestBase {
BranchRequest branchRequest = new BranchRequest(); BranchRequest branchRequest = new BranchRequest();
branchRequest.setNewBranch("new_branch"); branchRequest.setNewBranch("new_branch");
new GitBranchCommand(context, repository, new SimpleGitWorkdirFactory()).branch(branchRequest); new GitBranchCommand(context, repository, new SimpleGitWorkdirFactory(new WorkdirProvider())).branch(branchRequest);
Assertions.assertThat(readBranches(context)).filteredOn(b -> b.getName().equals("new_branch")).isNotEmpty(); Assertions.assertThat(readBranches(context)).filteredOn(b -> b.getName().equals("new_branch")).isNotEmpty();
} }

View File

@@ -24,6 +24,7 @@ import sonia.scm.repository.RepositoryManager;
import sonia.scm.repository.api.HookContextFactory; import sonia.scm.repository.api.HookContextFactory;
import sonia.scm.repository.api.MergeCommandResult; import sonia.scm.repository.api.MergeCommandResult;
import sonia.scm.repository.api.MergeDryRunCommandResult; import sonia.scm.repository.api.MergeDryRunCommandResult;
import sonia.scm.repository.util.WorkdirProvider;
import sonia.scm.user.User; import sonia.scm.user.User;
import java.io.IOException; import java.io.IOException;
@@ -244,6 +245,6 @@ public class GitMergeCommandTest extends AbstractGitCommandTestBase {
} }
private GitMergeCommand createCommand() { private GitMergeCommand createCommand() {
return new GitMergeCommand(createContext(), repository, new SimpleGitWorkdirFactory()); return new GitMergeCommand(createContext(), repository, new SimpleGitWorkdirFactory(new WorkdirProvider()));
} }
} }

View File

@@ -11,6 +11,7 @@ import sonia.scm.repository.GitRepositoryHandler;
import sonia.scm.repository.PreProcessorUtil; import sonia.scm.repository.PreProcessorUtil;
import sonia.scm.repository.RepositoryManager; import sonia.scm.repository.RepositoryManager;
import sonia.scm.repository.api.HookContextFactory; import sonia.scm.repository.api.HookContextFactory;
import sonia.scm.repository.util.WorkdirProvider;
import sonia.scm.repository.util.WorkingCopy; import sonia.scm.repository.util.WorkingCopy;
import java.io.File; import java.io.File;
@@ -29,19 +30,21 @@ public class SimpleGitWorkdirFactoryTest extends AbstractGitCommandTestBase {
// keep this so that it will not be garbage collected (Transport keeps this in a week reference) // keep this so that it will not be garbage collected (Transport keeps this in a week reference)
private ScmTransportProtocol proto; private ScmTransportProtocol proto;
private WorkdirProvider workdirProvider;
@Before @Before
public void bindScmProtocol() { public void bindScmProtocol() throws IOException {
HookContextFactory hookContextFactory = new HookContextFactory(mock(PreProcessorUtil.class)); HookContextFactory hookContextFactory = new HookContextFactory(mock(PreProcessorUtil.class));
HookEventFacade hookEventFacade = new HookEventFacade(of(mock(RepositoryManager.class)), hookContextFactory); HookEventFacade hookEventFacade = new HookEventFacade(of(mock(RepositoryManager.class)), hookContextFactory);
GitRepositoryHandler gitRepositoryHandler = mock(GitRepositoryHandler.class); GitRepositoryHandler gitRepositoryHandler = mock(GitRepositoryHandler.class);
proto = new ScmTransportProtocol(of(hookEventFacade), of(gitRepositoryHandler)); proto = new ScmTransportProtocol(of(hookEventFacade), of(gitRepositoryHandler));
Transport.register(proto); Transport.register(proto);
workdirProvider = new WorkdirProvider(temporaryFolder.newFolder());
} }
@Test @Test
public void emptyPoolShouldCreateNewWorkdir() throws IOException { public void emptyPoolShouldCreateNewWorkdir() throws IOException {
SimpleGitWorkdirFactory factory = new SimpleGitWorkdirFactory(temporaryFolder.newFolder()); SimpleGitWorkdirFactory factory = new SimpleGitWorkdirFactory(workdirProvider);
File masterRepo = createRepositoryDirectory(); File masterRepo = createRepositoryDirectory();
try (WorkingCopy<Repository> workingCopy = factory.createWorkingCopy(createContext())) { try (WorkingCopy<Repository> workingCopy = factory.createWorkingCopy(createContext())) {
@@ -59,7 +62,7 @@ public class SimpleGitWorkdirFactoryTest extends AbstractGitCommandTestBase {
@Test @Test
public void cloneFromPoolShouldNotBeReused() throws IOException { public void cloneFromPoolShouldNotBeReused() throws IOException {
SimpleGitWorkdirFactory factory = new SimpleGitWorkdirFactory(temporaryFolder.newFolder()); SimpleGitWorkdirFactory factory = new SimpleGitWorkdirFactory(workdirProvider);
File firstDirectory; File firstDirectory;
try (WorkingCopy<Repository> workingCopy = factory.createWorkingCopy(createContext())) { try (WorkingCopy<Repository> workingCopy = factory.createWorkingCopy(createContext())) {
@@ -73,7 +76,7 @@ public class SimpleGitWorkdirFactoryTest extends AbstractGitCommandTestBase {
@Test @Test
public void cloneFromPoolShouldBeDeletedOnClose() throws IOException { public void cloneFromPoolShouldBeDeletedOnClose() throws IOException {
SimpleGitWorkdirFactory factory = new SimpleGitWorkdirFactory(temporaryFolder.newFolder()); SimpleGitWorkdirFactory factory = new SimpleGitWorkdirFactory(workdirProvider);
File directory; File directory;
try (WorkingCopy<Repository> workingCopy = factory.createWorkingCopy(createContext())) { try (WorkingCopy<Repository> workingCopy = factory.createWorkingCopy(createContext())) {

View File

@@ -4,6 +4,7 @@ import com.aragost.javahg.Repository;
import com.aragost.javahg.commands.CloneCommand; import com.aragost.javahg.commands.CloneCommand;
import com.aragost.javahg.commands.PullCommand; import com.aragost.javahg.commands.PullCommand;
import sonia.scm.repository.util.SimpleWorkdirFactory; import sonia.scm.repository.util.SimpleWorkdirFactory;
import sonia.scm.repository.util.WorkdirProvider;
import sonia.scm.web.HgRepositoryEnvironmentBuilder; import sonia.scm.web.HgRepositoryEnvironmentBuilder;
import javax.inject.Inject; import javax.inject.Inject;
@@ -18,7 +19,8 @@ public class SimpleHgWorkdirFactory extends SimpleWorkdirFactory<Repository, HgC
private final Provider<HgRepositoryEnvironmentBuilder> hgRepositoryEnvironmentBuilder; private final Provider<HgRepositoryEnvironmentBuilder> hgRepositoryEnvironmentBuilder;
@Inject @Inject
public SimpleHgWorkdirFactory(Provider<HgRepositoryEnvironmentBuilder> hgRepositoryEnvironmentBuilder) { public SimpleHgWorkdirFactory(Provider<HgRepositoryEnvironmentBuilder> hgRepositoryEnvironmentBuilder, WorkdirProvider workdirProvider) {
super(workdirProvider);
this.hgRepositoryEnvironmentBuilder = hgRepositoryEnvironmentBuilder; this.hgRepositoryEnvironmentBuilder = hgRepositoryEnvironmentBuilder;
} }
@Override @Override

View File

@@ -7,6 +7,7 @@ import org.junit.Test;
import sonia.scm.repository.Branch; import sonia.scm.repository.Branch;
import sonia.scm.repository.HgTestUtil; import sonia.scm.repository.HgTestUtil;
import sonia.scm.repository.api.BranchRequest; import sonia.scm.repository.api.BranchRequest;
import sonia.scm.repository.util.WorkdirProvider;
import sonia.scm.web.HgRepositoryEnvironmentBuilder; import sonia.scm.web.HgRepositoryEnvironmentBuilder;
import java.io.IOException; import java.io.IOException;
@@ -20,7 +21,7 @@ public class HgBranchCommandTest extends AbstractHgCommandTestBase {
HgRepositoryEnvironmentBuilder hgRepositoryEnvironmentBuilder = HgRepositoryEnvironmentBuilder hgRepositoryEnvironmentBuilder =
new HgRepositoryEnvironmentBuilder(handler, HgTestUtil.createHookManager()); new HgRepositoryEnvironmentBuilder(handler, HgTestUtil.createHookManager());
SimpleHgWorkdirFactory workdirFactory = new SimpleHgWorkdirFactory(Providers.of(hgRepositoryEnvironmentBuilder)) { SimpleHgWorkdirFactory workdirFactory = new SimpleHgWorkdirFactory(Providers.of(hgRepositoryEnvironmentBuilder), new WorkdirProvider()) {
@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