Close repositories after usage

This commit is contained in:
René Pfeuffer
2019-03-29 11:47:44 +01:00
parent ee219f2d59
commit 00b27b5488
4 changed files with 87 additions and 2 deletions

View File

@@ -39,7 +39,9 @@ public abstract class SimpleWorkdirFactory<R, C> implements WorkdirFactory<R, C>
protected abstract Repository getScmRepository(C context);
protected abstract void closeRepository(R repository);
@SuppressWarnings("squid:S00112")
// We do allow implementations to throw arbitrary exceptions here, so that we can handle them in close
protected abstract void closeRepository(R repository) throws Exception;
protected abstract ParentAndClone<R> cloneRepository(C context, File target) throws IOException;

View File

@@ -15,11 +15,13 @@ public class WorkingCopy<R> implements AutoCloseable {
private final File directory;
private final R workingRepository;
private final R centralRepository;
private final Consumer<R> cleanup;
public WorkingCopy(R workingRepository, R centralRepository, Consumer<R> cleanup, File directory) {
this.directory = directory;
this.workingRepository = workingRepository;
this.centralRepository = centralRepository;
this.cleanup = cleanup;
}
public R getWorkingRepository() {
@@ -37,6 +39,8 @@ public class WorkingCopy<R> implements AutoCloseable {
@Override
public void close() {
try {
cleanup.accept(workingRepository);
cleanup.accept(centralRepository);
IOUtil.delete(directory);
} catch (IOException e) {
LOG.warn("could not delete temporary workdir '{}'", directory, e);

View File

@@ -0,0 +1,75 @@
package sonia.scm.repository.util;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import sonia.scm.repository.Repository;
import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
public class SimpleWorkdirFactoryTest {
private static final Repository REPOSITORY = new Repository("1", "git", "space", "X");
private final Closeable parent = mock(Closeable.class);
private final Closeable clone = mock(Closeable.class);
@Rule
public TemporaryFolder temporaryFolder = new TemporaryFolder();
private SimpleWorkdirFactory<Closeable, Context> simpleWorkdirFactory;
@Before
public void initFactory() throws IOException {
simpleWorkdirFactory = new SimpleWorkdirFactory<Closeable, Context>(temporaryFolder.newFolder()) {
@Override
protected Repository getScmRepository(Context context) {
return REPOSITORY;
}
@Override
protected void closeRepository(Closeable repository) throws IOException {
repository.close();
}
@Override
protected ParentAndClone<Closeable> cloneRepository(Context context, File target) {
return new ParentAndClone<>(parent, clone);
}
};
}
@Test
public void shouldCreateParentAndClone() {
Context context = new Context();
try (WorkingCopy<Closeable> workingCopy = simpleWorkdirFactory.createWorkingCopy(context)) {
assertThat(workingCopy.getCentralRepository()).isSameAs(parent);
assertThat(workingCopy.getWorkingRepository()).isSameAs(clone);
}
}
@Test
public void shouldCloseParent() throws IOException {
Context context = new Context();
try (WorkingCopy<Closeable> workingCopy = simpleWorkdirFactory.createWorkingCopy(context)) {}
verify(parent).close();
}
@Test
public void shouldCloseClone() throws IOException {
Context context = new Context();
try (WorkingCopy<Closeable> workingCopy = simpleWorkdirFactory.createWorkingCopy(context)) {}
verify(clone).close();
}
private static class Context {}
}

View File

@@ -38,8 +38,12 @@ public class SimpleGitWorkdirFactory extends SimpleWorkdirFactory<Repository, Gi
@Override
protected void closeRepository(Repository repository) {
// we have to check for null here, because we do not create a repository for
// the parent in cloneRepository
if (repository != null) {
repository.close();
}
}
@Override
protected sonia.scm.repository.Repository getScmRepository(GitContext context) {