Cleanup repository dao

This commit is contained in:
René Pfeuffer
2019-05-10 16:32:14 +02:00
parent e1625bf92f
commit c63510536a
2 changed files with 72 additions and 43 deletions

View File

@@ -104,23 +104,21 @@ public class XmlRepositoryDAO implements RepositoryDAO {
public void add(Repository repository) { public void add(Repository repository) {
Repository clone = repository.clone(); Repository clone = repository.clone();
try {
synchronized (this) { synchronized (this) {
Path repositoryPath = repositoryLocationResolver.create(repository.getId()); Path repositoryPath = repositoryLocationResolver.create(repository.getId());
Path resolvedPath = repositoryPath;
fileSystem.create(resolvedPath.toFile());
Path metadataPath = resolveDataPath(resolvedPath); try {
Path metadataPath = resolveDataPath(repositoryPath);
metadataStore.write(metadataPath, repository); metadataStore.write(metadataPath, repository);
} catch (Exception e) {
repositoryLocationResolver.remove(repository.getId());
throw new InternalRepositoryException(repository, "failed to create filesystem", e);
}
byId.put(repository.getId(), clone); byId.put(repository.getId(), clone);
byNamespaceAndName.put(repository.getNamespaceAndName(), clone); byNamespaceAndName.put(repository.getNamespaceAndName(), clone);
} }
} catch (Exception e) {
repositoryLocationResolver.remove(repository.getId());
throw new InternalRepositoryException(repository, "failed to create filesystem", e);
}
} }

View File

@@ -14,26 +14,14 @@ import org.mockito.quality.Strictness;
import sonia.scm.SCMContextProvider; import sonia.scm.SCMContextProvider;
import sonia.scm.io.DefaultFileSystem; import sonia.scm.io.DefaultFileSystem;
import sonia.scm.io.FileSystem; import sonia.scm.io.FileSystem;
import sonia.scm.repository.InitialRepositoryLocationResolver;
import sonia.scm.repository.NamespaceAndName;
import sonia.scm.repository.Repository; import sonia.scm.repository.Repository;
import sonia.scm.repository.RepositoryLocationResolver;
import sonia.scm.repository.RepositoryPermission;
import sonia.scm.repository.RepositoryTestData;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.Clock;
import java.util.Collection;
import java.util.Collections;
import java.util.concurrent.atomic.AtomicLong;
import static java.util.Arrays.asList;
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.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
@ExtendWith({MockitoExtension.class, TempDirectory.class}) @ExtendWith({MockitoExtension.class, TempDirectory.class})
@@ -52,31 +40,25 @@ class XmlRepositoryDAOTest {
private XmlRepositoryDAO dao; private XmlRepositoryDAO dao;
private Path baseDirectory; private Path basePath;
private AtomicLong atomicClock;
@BeforeEach @BeforeEach
void createDAO(@TempDirectory.TempDir Path baseDirectory) { void createDAO(@TempDirectory.TempDir Path basePath) {
this.baseDirectory = baseDirectory; this.basePath = basePath;
this.atomicClock = new AtomicLong();
when(locationResolver.create("42")).thenReturn(Paths.get("repos", "42")); when(locationResolver.create(anyString())).thenAnswer(invocation -> {
when(locationResolver.create("23")).thenReturn(Paths.get("repos", "puzzle")); Path resolvedPath = basePath.resolve(invocation.getArgument(0).toString());
Files.createDirectories(resolvedPath);
when(context.getBaseDirectory()).thenReturn(baseDirectory.toFile()); return resolvedPath;
when(context.resolve(any(Path.class))).then(ic -> {
Path path = ic.getArgument(0);
return baseDirectory.resolve(path);
}); });
when(locationResolver.remove(anyString())).thenAnswer(invocation -> basePath.resolve(invocation.getArgument(0).toString()));
when(context.getBaseDirectory()).thenReturn(basePath.toFile());
dao = createDAO(); dao = createDAO();
} }
private XmlRepositoryDAO createDAO() { private XmlRepositoryDAO createDAO() {
Clock clock = mock(Clock.class);
when(clock.millis()).then(ic -> atomicClock.incrementAndGet());
return new XmlRepositoryDAO(context, locationResolver, fileSystem); return new XmlRepositoryDAO(context, locationResolver, fileSystem);
} }
@@ -87,14 +69,14 @@ class XmlRepositoryDAOTest {
@Test @Test
void shouldReturnCreationTimeOfLocationResolver() { void shouldReturnCreationTimeOfLocationResolver() {
long now = atomicClock.get(); long now = 42L;
when(locationResolver.getCreationTime()).thenReturn(now); when(locationResolver.getCreationTime()).thenReturn(now);
assertThat(dao.getCreationTime()).isEqualTo(now); assertThat(dao.getCreationTime()).isEqualTo(now);
} }
@Test @Test
void shouldReturnLasModifiedOfLocationResolver() { void shouldReturnLasModifiedOfLocationResolver() {
long now = atomicClock.get(); long now = 42L;
when(locationResolver.getLastModified()).thenReturn(now); when(locationResolver.getLastModified()).thenReturn(now);
assertThat(dao.getLastModified()).isEqualTo(now); assertThat(dao.getLastModified()).isEqualTo(now);
} }
@@ -108,6 +90,36 @@ class XmlRepositoryDAOTest {
assertThat(dao.contains(REPOSITORY.getNamespaceAndName())).isTrue(); assertThat(dao.contains(REPOSITORY.getNamespaceAndName())).isTrue();
} }
@Test
void shouldPersistRepository() {
dao.add(REPOSITORY);
String content = getXmlFileContent(REPOSITORY.getId());
assertThat(content).contains("<id>42</id>");
}
@Test
void shouldDeleteDataFile() {
dao.add(REPOSITORY);
dao.delete(REPOSITORY);
assertThat(metadataFile(REPOSITORY.getId())).doesNotExist();
}
@Test
void shouldModifyRepository() {
dao.add(REPOSITORY);
Repository changedRepository = REPOSITORY.clone();
changedRepository.setContact("change");
dao.modify(changedRepository);
String content = getXmlFileContent(REPOSITORY.getId());
assertThat(content).contains("change");
}
// @Test // @Test
// void shouldReturnFalseForEachContainsMethod() { // void shouldReturnFalseForEachContainsMethod() {
// Repository heartOfGold = createHeartOfGold(); // Repository heartOfGold = createHeartOfGold();
@@ -375,6 +387,25 @@ class XmlRepositoryDAOTest {
// assertThat(dao.getLastModified()).isEqualTo(lastModified); // assertThat(dao.getLastModified()).isEqualTo(lastModified);
// } // }
private String getXmlFileContent(String id) {
Path storePath = metadataFile(id);
assertThat(storePath).isRegularFile();
return content(storePath);
}
private Path metadataFile(String id) {
return locationResolver.create(id).resolve("metadata.xml");
}
private String content(Path storePath) {
try {
return new String(Files.readAllBytes(storePath), Charsets.UTF_8);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private static Repository createRepository(String id) { private static Repository createRepository(String id) {
return new Repository(id, "xml", "space", "id"); return new Repository(id, "xml", "space", "id");
} }