From a83e2813a3969faf6acac8ec4f4baf947fcdc14a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Fri, 10 May 2019 13:26:06 +0200 Subject: [PATCH] Fix path computation and resolving --- .../AbstractSimpleRepositoryHandler.java | 2 +- .../RepositoryLocationResolver.java | 3 +- .../PathBasedRepositoryLocationResolver.java | 42 +- .../scm/repository/xml/XmlRepositoryDAO.java | 30 +- ...thBasedRepositoryLocationResolverTest.java | 15 +- .../repository/xml/XmlRepositoryDAOTest.java | 77 +- .../SimpleRepositoryHandlerTestBase.java | 3 +- .../DefaultRepositoryManagerTest.java | 887 +++++++++--------- 8 files changed, 522 insertions(+), 537 deletions(-) diff --git a/scm-core/src/main/java/sonia/scm/repository/AbstractSimpleRepositoryHandler.java b/scm-core/src/main/java/sonia/scm/repository/AbstractSimpleRepositoryHandler.java index 5db81e521e..875fb55617 100644 --- a/scm-core/src/main/java/sonia/scm/repository/AbstractSimpleRepositoryHandler.java +++ b/scm-core/src/main/java/sonia/scm/repository/AbstractSimpleRepositoryHandler.java @@ -173,6 +173,6 @@ public abstract class AbstractSimpleRepositoryHandler RepositoryLocationResolverInstance create(Class type); - // TODO make final, but fix mockito mocking - public RepositoryLocationResolverInstance forClass(Class type) { + public final RepositoryLocationResolverInstance forClass(Class type) { if (!supportsLocationType(type)) { throw new IllegalStateException("no support for location of class " + type); } diff --git a/scm-dao-xml/src/main/java/sonia/scm/repository/xml/PathBasedRepositoryLocationResolver.java b/scm-dao-xml/src/main/java/sonia/scm/repository/xml/PathBasedRepositoryLocationResolver.java index dd6595aa35..b4a5b0aa27 100644 --- a/scm-dao-xml/src/main/java/sonia/scm/repository/xml/PathBasedRepositoryLocationResolver.java +++ b/scm-dao-xml/src/main/java/sonia/scm/repository/xml/PathBasedRepositoryLocationResolver.java @@ -12,6 +12,8 @@ import java.nio.file.Path; import java.time.Clock; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +import java.util.function.BiConsumer; +import java.util.function.Consumer; /** * A Location Resolver for File based Repository Storage. @@ -22,7 +24,6 @@ import java.util.concurrent.ConcurrentHashMap; * Please use the {@link sonia.scm.store.BlobStoreFactory } and the {@link sonia.scm.store.BlobStore} classes to store binary files
* Please use the {@link sonia.scm.store.ConfigurationStoreFactory} and the {@link sonia.scm.store.ConfigurationStore} classes to store configurations * - * @author Mohamed Karray * @since 2.0.0 */ public class PathBasedRepositoryLocationResolver extends BasicRepositoryLocationResolver { @@ -32,8 +33,6 @@ public class PathBasedRepositoryLocationResolver extends BasicRepositoryLocation private final SCMContextProvider contextProvider; private final InitialRepositoryLocationResolver initialRepositoryLocationResolver; - private final SCMContextProvider context; - private final PathDatabase pathDatabase; private final Map pathById; @@ -43,15 +42,14 @@ public class PathBasedRepositoryLocationResolver extends BasicRepositoryLocation private Long lastModified; @Inject - public PathBasedRepositoryLocationResolver(SCMContextProvider contextProvider, InitialRepositoryLocationResolver initialRepositoryLocationResolver, SCMContextProvider context) { - this(contextProvider, initialRepositoryLocationResolver, context, Clock.systemUTC()); + public PathBasedRepositoryLocationResolver(SCMContextProvider contextProvider, InitialRepositoryLocationResolver initialRepositoryLocationResolver) { + this(contextProvider, initialRepositoryLocationResolver, Clock.systemUTC()); } - public PathBasedRepositoryLocationResolver(SCMContextProvider contextProvider, InitialRepositoryLocationResolver initialRepositoryLocationResolver, SCMContextProvider context, Clock clock) { + public PathBasedRepositoryLocationResolver(SCMContextProvider contextProvider, InitialRepositoryLocationResolver initialRepositoryLocationResolver, Clock clock) { super(Path.class); this.contextProvider = contextProvider; this.initialRepositoryLocationResolver = initialRepositoryLocationResolver; - this.context = context; this.pathById = new ConcurrentHashMap<>(); this.clock = clock; @@ -65,13 +63,11 @@ public class PathBasedRepositoryLocationResolver extends BasicRepositoryLocation @Override protected RepositoryLocationResolverInstance create(Class type) { return repositoryId -> { - Path path; if (pathById.containsKey(repositoryId)) { - path = pathById.get(repositoryId); + return (T) contextProvider.resolve(pathById.get(repositoryId)); } else { - path = create(repositoryId); + return (T) create(repositoryId); } - return (T) contextProvider.resolve(path); }; } @@ -79,13 +75,17 @@ public class PathBasedRepositoryLocationResolver extends BasicRepositoryLocation Path path = initialRepositoryLocationResolver.getPath(repositoryId); pathById.put(repositoryId, path); writePathDatabase(); - return path; + return contextProvider.resolve(path); } Path remove(String repositoryId) { Path removedPath = pathById.remove(repositoryId); writePathDatabase(); - return removedPath; + return contextProvider.resolve(removedPath); + } + + void forAllPaths(BiConsumer consumer) { + pathById.forEach((id, path) -> consumer.accept(id, contextProvider.resolve(path))); } private void writePathDatabase() { @@ -117,23 +117,11 @@ public class PathBasedRepositoryLocationResolver extends BasicRepositoryLocation private void onLoadRepository(String id, Path repositoryPath) { -// Path metadataPath = resolveMetadataPath(context.resolve(repositoryPath)); -// -// Repository repository = metadataStore.read(metadataPath); -// -// byId.put(id, repository); -// byNamespaceAndName.put(repository.getNamespaceAndName(), repository); pathById.put(id, repositoryPath); } - @VisibleForTesting - Path resolveMetadataPath(Path repositoryPath) { - return repositoryPath.resolve(StoreConstants.REPOSITORY_METADATA.concat(StoreConstants.FILE_EXTENSION)); - } - - @VisibleForTesting - Path resolveStorePath() { - return context.getBaseDirectory() + private Path resolveStorePath() { + return contextProvider.getBaseDirectory() .toPath() .resolve(StoreConstants.CONFIG_DIRECTORY_NAME) .resolve(STORE_NAME.concat(StoreConstants.FILE_EXTENSION)); diff --git a/scm-dao-xml/src/main/java/sonia/scm/repository/xml/XmlRepositoryDAO.java b/scm-dao-xml/src/main/java/sonia/scm/repository/xml/XmlRepositoryDAO.java index d9e30598fe..67b3534072 100644 --- a/scm-dao-xml/src/main/java/sonia/scm/repository/xml/XmlRepositoryDAO.java +++ b/scm-dao-xml/src/main/java/sonia/scm/repository/xml/XmlRepositoryDAO.java @@ -69,23 +69,26 @@ public class XmlRepositoryDAO implements RepositoryDAO { private final Map byId; private final Map byNamespaceAndName; - private Long creationTime; - private Long lastModified; - @Inject - public XmlRepositoryDAO(SCMContextProvider context, PathBasedRepositoryLocationResolver repositoryLocationResolver, InitialRepositoryLocationResolver initialLocationResolver, FileSystem fileSystem) { - this(context, repositoryLocationResolver, initialLocationResolver, fileSystem, Clock.systemUTC()); - } - - XmlRepositoryDAO(SCMContextProvider context, PathBasedRepositoryLocationResolver repositoryLocationResolver, InitialRepositoryLocationResolver initialLocationResolver, FileSystem fileSystem, Clock clock) { + public XmlRepositoryDAO(SCMContextProvider context, PathBasedRepositoryLocationResolver repositoryLocationResolver, FileSystem fileSystem) { this.context = context; this.repositoryLocationResolver = repositoryLocationResolver; this.fileSystem = fileSystem; this.byId = new ConcurrentHashMap<>(); this.byNamespaceAndName = new ConcurrentHashMap<>(); + + init(); } + private void init() { + repositoryLocationResolver.forAllPaths((repositoryId, repositoryPath) -> { + Path metadataPath = resolveDataPath(repositoryPath); + Repository repository = metadataStore.read(metadataPath); + byNamespaceAndName.put(repository.getNamespaceAndName(), repository); + byId.put(repositoryId, repository); + }); + } @VisibleForTesting Path resolveDataPath(Path repositoryPath) { @@ -101,11 +104,10 @@ public class XmlRepositoryDAO implements RepositoryDAO { public void add(Repository repository) { Repository clone = repository.clone(); - try { synchronized (this) { Path repositoryPath = repositoryLocationResolver.create(repository.getId()); - Path resolvedPath = context.resolve(repositoryPath); + Path resolvedPath = repositoryPath; fileSystem.create(resolvedPath.toFile()); Path metadataPath = resolveDataPath(resolvedPath); @@ -165,7 +167,7 @@ public class XmlRepositoryDAO implements RepositoryDAO { byNamespaceAndName.put(clone.getNamespaceAndName(), clone); } - Path repositoryPath = context.resolve(repositoryLocationResolver.create(Path.class).getLocation(repository.getId())); + Path repositoryPath = repositoryLocationResolver.create(Path.class).getLocation(repository.getId()); Path metadataPath = resolveDataPath(repositoryPath); metadataStore.write(metadataPath, clone); } @@ -181,8 +183,6 @@ public class XmlRepositoryDAO implements RepositoryDAO { path = repositoryLocationResolver.remove(repository.getId()); } - path = context.resolve(path); - try { fileSystem.destroy(path.toFile()); } catch (IOException e) { @@ -192,11 +192,11 @@ public class XmlRepositoryDAO implements RepositoryDAO { @Override public Long getCreationTime() { - return creationTime; + return repositoryLocationResolver.getCreationTime(); } @Override public Long getLastModified() { - return lastModified; + return repositoryLocationResolver.getLastModified(); } } diff --git a/scm-dao-xml/src/test/java/sonia/scm/repository/xml/PathBasedRepositoryLocationResolverTest.java b/scm-dao-xml/src/test/java/sonia/scm/repository/xml/PathBasedRepositoryLocationResolverTest.java index a43ad77553..2f20a46c5e 100644 --- a/scm-dao-xml/src/test/java/sonia/scm/repository/xml/PathBasedRepositoryLocationResolverTest.java +++ b/scm-dao-xml/src/test/java/sonia/scm/repository/xml/PathBasedRepositoryLocationResolverTest.java @@ -3,8 +3,11 @@ package sonia.scm.repository.xml; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; +import org.mockito.junit.jupiter.MockitoSettings; +import org.mockito.quality.Strictness; import org.mockito.stubbing.Answer; import sonia.scm.SCMContextProvider; import sonia.scm.repository.InitialRepositoryLocationResolver; @@ -19,27 +22,21 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.when; @ExtendWith({MockitoExtension.class}) +@MockitoSettings(strictness = Strictness.LENIENT) class PathBasedRepositoryLocationResolverTest { @Mock private SCMContextProvider contextProvider; - @Mock - private RepositoryDAO repositoryDAO; - @Mock private InitialRepositoryLocationResolver initialRepositoryLocationResolver; - @Mock - private SCMContextProvider context; + private PathBasedRepositoryLocationResolver resolver; @BeforeEach void beforeEach() { when(contextProvider.resolve(any(Path.class))).then((Answer) invocationOnMock -> invocationOnMock.getArgument(0)); - } - - private PathBasedRepositoryLocationResolver createResolver(RepositoryDAO pathBasedRepositoryDAO) { - return new PathBasedRepositoryLocationResolver(contextProvider, initialRepositoryLocationResolver, context); + resolver = new PathBasedRepositoryLocationResolver(contextProvider, initialRepositoryLocationResolver); } // TODO implement tests diff --git a/scm-dao-xml/src/test/java/sonia/scm/repository/xml/XmlRepositoryDAOTest.java b/scm-dao-xml/src/test/java/sonia/scm/repository/xml/XmlRepositoryDAOTest.java index 792e447ea0..d520218d89 100644 --- a/scm-dao-xml/src/test/java/sonia/scm/repository/xml/XmlRepositoryDAOTest.java +++ b/scm-dao-xml/src/test/java/sonia/scm/repository/xml/XmlRepositoryDAOTest.java @@ -6,6 +6,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.junitpioneer.jupiter.TempDirectory; +import org.mockito.Answers; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.mockito.junit.jupiter.MockitoSettings; @@ -39,13 +40,13 @@ import static org.mockito.Mockito.when; @MockitoSettings(strictness = Strictness.LENIENT) class XmlRepositoryDAOTest { + private static final Repository REPOSITORY = createRepository("42"); + @Mock private SCMContextProvider context; - @Mock + @Mock(answer = Answers.RETURNS_DEEP_STUBS) private PathBasedRepositoryLocationResolver locationResolver; - @Mock - private InitialRepositoryLocationResolver initialLocationResolver; private FileSystem fileSystem = new DefaultFileSystem(); @@ -60,8 +61,8 @@ class XmlRepositoryDAOTest { this.baseDirectory = baseDirectory; this.atomicClock = new AtomicLong(); - when(initialLocationResolver.getPath("42")).thenReturn(Paths.get("repos", "42")); - when(initialLocationResolver.getPath("42+1")).thenReturn(Paths.get("repos", "puzzle")); + when(locationResolver.create("42")).thenReturn(Paths.get("repos", "42")); + when(locationResolver.create("23")).thenReturn(Paths.get("repos", "puzzle")); when(context.getBaseDirectory()).thenReturn(baseDirectory.toFile()); when(context.resolve(any(Path.class))).then(ic -> { @@ -76,41 +77,37 @@ class XmlRepositoryDAOTest { Clock clock = mock(Clock.class); when(clock.millis()).then(ic -> atomicClock.incrementAndGet()); - return new XmlRepositoryDAO(context, locationResolver, initialLocationResolver, fileSystem, clock); + return new XmlRepositoryDAO(context, locationResolver, fileSystem); + } + + @Test + void shouldReturnXmlType() { + assertThat(dao.getType()).isEqualTo("xml"); + } + + @Test + void shouldReturnCreationTimeOfLocationResolver() { + long now = atomicClock.get(); + when(locationResolver.getCreationTime()).thenReturn(now); + assertThat(dao.getCreationTime()).isEqualTo(now); + } + + @Test + void shouldReturnLasModifiedOfLocationResolver() { + long now = atomicClock.get(); + when(locationResolver.getLastModified()).thenReturn(now); + assertThat(dao.getLastModified()).isEqualTo(now); + } + + @Test + void shouldReturnTrueForEachContainsMethod() { + dao.add(REPOSITORY); + + assertThat(dao.contains(REPOSITORY)).isTrue(); + assertThat(dao.contains(REPOSITORY.getId())).isTrue(); + assertThat(dao.contains(REPOSITORY.getNamespaceAndName())).isTrue(); } -// @Test -// void shouldReturnXmlType() { -// assertThat(dao.getType()).isEqualTo("xml"); -// } -// -// @Test -// void shouldReturnCreationTimeAfterCreation() { -// long now = atomicClock.get(); -// assertThat(dao.getCreationTime()).isEqualTo(now); -// } -// -// @Test -// void shouldNotReturnLastModifiedAfterCreation() { -// assertThat(dao.getLastModified()).isNull(); -// } -// -// @Test -// void shouldReturnTrueForEachContainsMethod() { -// Repository heartOfGold = createHeartOfGold(); -// dao.add(heartOfGold); -// -// assertThat(dao.contains(heartOfGold)).isTrue(); -// assertThat(dao.contains(heartOfGold.getId())).isTrue(); -// assertThat(dao.contains(heartOfGold.getNamespaceAndName())).isTrue(); -// } -// -// private Repository createHeartOfGold() { -// Repository heartOfGold = RepositoryTestData.createHeartOfGold(); -// heartOfGold.setId("42"); -// return heartOfGold; -// } -// // @Test // void shouldReturnFalseForEachContainsMethod() { // Repository heartOfGold = createHeartOfGold(); @@ -377,4 +374,8 @@ class XmlRepositoryDAOTest { // assertThat(dao.getCreationTime()).isEqualTo(creationTime); // assertThat(dao.getLastModified()).isEqualTo(lastModified); // } + + private static Repository createRepository(String id) { + return new Repository(id, "xml", "space", "id"); + } } diff --git a/scm-test/src/main/java/sonia/scm/repository/SimpleRepositoryHandlerTestBase.java b/scm-test/src/main/java/sonia/scm/repository/SimpleRepositoryHandlerTestBase.java index 3660320c69..000835156a 100644 --- a/scm-test/src/main/java/sonia/scm/repository/SimpleRepositoryHandlerTestBase.java +++ b/scm-test/src/main/java/sonia/scm/repository/SimpleRepositoryHandlerTestBase.java @@ -80,7 +80,8 @@ public abstract class SimpleRepositoryHandlerTestBase extends AbstractTestBase { locationResolver = mock(RepositoryLocationResolver.class); RepositoryLocationResolver.RepositoryLocationResolverInstance instanceMock = mock(RepositoryLocationResolver.RepositoryLocationResolverInstance.class); - when(locationResolver.forClass(any())).thenReturn(instanceMock); + when(locationResolver.create(any())).thenReturn(instanceMock); + when(locationResolver.supportsLocationType(any())).thenReturn(true); when(instanceMock.getLocation(anyString())).then(ic -> { String id = ic.getArgument(0); diff --git a/scm-webapp/src/test/java/sonia/scm/repository/DefaultRepositoryManagerTest.java b/scm-webapp/src/test/java/sonia/scm/repository/DefaultRepositoryManagerTest.java index baccca19b2..40cc41c2be 100644 --- a/scm-webapp/src/test/java/sonia/scm/repository/DefaultRepositoryManagerTest.java +++ b/scm-webapp/src/test/java/sonia/scm/repository/DefaultRepositoryManagerTest.java @@ -89,448 +89,447 @@ import static org.mockito.Mockito.*; password = "secret", configuration = "classpath:sonia/scm/repository/shiro.ini" ) -public class DefaultRepositoryManagerTest extends ManagerTestBase { - - { - ThreadContext.unbindSubject(); - } - - @Rule - public ShiroRule shiro = new ShiroRule(); - - @Rule - public ExpectedException thrown = ExpectedException.none(); - - private ScmConfiguration configuration; - - private String mockedNamespace = "default_namespace"; - - @Before - public void initContext() { - ((TempSCMContextProvider)SCMContext.getContext()).setBaseDirectory(temp); - } - - @Test - public void testCreate() { - Repository heartOfGold = createTestRepository(); - Repository dbRepo = manager.get(heartOfGold.getId()); - - assertNotNull(dbRepo); - assertRepositoriesEquals(dbRepo, heartOfGold); - } - - @SubjectAware( - username = "unpriv" - ) - @Test(expected = UnauthorizedException.class) - public void testCreateWithoutPrivileges() { - createTestRepository(); - } - - @Test - public void testCreateExisting() { - Repository testRepository = createTestRepository(); - String expectedNamespaceAndName = testRepository.getNamespaceAndName().logString(); - thrown.expect(AlreadyExistsException.class); - thrown.expectMessage(expectedNamespaceAndName); - createTestRepository(); - } - - @Test - public void testDelete() { - delete(manager, createTestRepository()); - } - - @SubjectAware( - username = "unpriv" - ) - @Test(expected = UnauthorizedException.class) - public void testDeleteWithoutPrivileges() { - delete(manager, createTestRepository()); - } - - @Test(expected = RepositoryIsNotArchivedException.class) - public void testDeleteNonArchived() { - configuration.setEnableRepositoryArchive(true); - delete(manager, createTestRepository()); - } - - @Test(expected = NotFoundException.class) - public void testDeleteNotFound(){ - manager.delete(createRepositoryWithId()); - } - - @Test - public void testDeleteWithEnabledArchive() { - Repository repository = createTestRepository(); - - repository.setArchived(true); - RepositoryManager drm = createRepositoryManager(true); - drm.init(contextProvider); - delete(drm, repository); - } - - @Test - public void testGet() { - Repository heartOfGold = createTestRepository(); - String id = heartOfGold.getId(); - String description = heartOfGold.getDescription(); - - assertNotNull(description); - - // test for reference - heartOfGold.setDescription("prototype ship"); - heartOfGold = manager.get(id); - assertNotNull(heartOfGold); - assertEquals(description, heartOfGold.getDescription()); - } - - @Test - @SubjectAware( - username = "crato" - ) - public void testGetWithoutRequiredPrivileges() { - Repository heartOfGold = RepositoryTestData.createHeartOfGold(); - manager.create(heartOfGold); - - thrown.expect(UnauthorizedException.class); - manager.get(heartOfGold.getId()); - } - - @Test - public void testGetAll() { - Repository heartOfGold = createTestRepository(); - Repository happyVerticalPeopleTransporter = createSecondTestRepository(); - boolean foundHeart = false; - boolean foundTransporter = false; - Collection repositories = manager.getAll(); - - assertNotNull(repositories); - assertFalse(repositories.isEmpty()); - assertTrue(repositories.size() >= 2); - - Repository heartReference = null; - - for (Repository repository : repositories) { - if (repository.getId().equals(heartOfGold.getId())) { - assertRepositoriesEquals(heartOfGold, repository); - foundHeart = true; - heartReference = repository; - } - else if (repository.getId().equals(happyVerticalPeopleTransporter.getId())) { - assertRepositoriesEquals(happyVerticalPeopleTransporter, repository); - foundTransporter = true; - } - } - - assertTrue(foundHeart); - assertTrue(foundTransporter); - - // test for reference - assertNotSame(heartOfGold, heartReference); - heartReference.setDescription("prototype ship"); - assertFalse( - heartOfGold.getDescription().equals(heartReference.getDescription())); - } - - @Test - @SuppressWarnings("unchecked") - @SubjectAware(username = "dent") - public void testGetAllWithPermissionsForTwoOrThreeRepos() { - // mock key generator - KeyGenerator keyGenerator = mock(KeyGenerator.class); - Stack keys = new Stack<>(); - keys.push("rateotu"); - keys.push("p42"); - keys.push("hof"); - - when(keyGenerator.createKey()).then((InvocationOnMock invocation) -> { - return keys.pop(); - }); - - // create repository manager - RepositoryManager repositoryManager = createRepositoryManager(false, keyGenerator); - - // create first test repository - Repository heartOfGold = RepositoryTestData.createHeartOfGold(); - repositoryManager.create(heartOfGold); - assertEquals("hof", heartOfGold.getId()); - - // create second test repository - Repository puzzle42 = RepositoryTestData.create42Puzzle(); - repositoryManager.create(puzzle42); - assertEquals("p42", puzzle42.getId()); - - // create third test repository - Repository restaurant = RepositoryTestData.createRestaurantAtTheEndOfTheUniverse(); - repositoryManager.create(restaurant); - assertEquals("rateotu", restaurant.getId()); - - // assert returned repositories - Collection repositories = repositoryManager.getAll(); - assertEquals(2, repositories.size()); - assertThat(repositories, containsInAnyOrder( - hasProperty("id", is("p42")), - hasProperty("id", is("hof")) - ) - ); - } - - @Test - public void testEvents() { - RepositoryManager repoManager = createRepositoryManager(false); - repoManager.init(contextProvider); - TestListener listener = new TestListener(); - - ScmEventBus.getInstance().register(listener); - - Repository repository = RepositoryTestData.create42Puzzle(); - - repoManager.create(repository); - assertRepositoriesEquals(repository, listener.preRepository); - assertSame(HandlerEventType.BEFORE_CREATE, listener.preEvent); - assertRepositoriesEquals(repository, listener.postRepository); - assertSame(HandlerEventType.CREATE, listener.postEvent); - - repository.setDescription("changed description"); - repoManager.modify(repository); - assertRepositoriesEquals(repository, listener.preRepository); - assertSame(HandlerEventType.BEFORE_MODIFY, listener.preEvent); - assertRepositoriesEquals(repository, listener.postRepository); - assertSame(HandlerEventType.MODIFY, listener.postEvent); - - repoManager.delete(repository); - - assertRepositoriesEquals(repository, listener.preRepository); - assertSame(HandlerEventType.BEFORE_DELETE, listener.preEvent); - assertRepositoriesEquals(repository, listener.postRepository); - assertSame(HandlerEventType.DELETE, listener.postEvent); - } - - @Test - public void testModify() { - Repository heartOfGold = createTestRepository(); - - heartOfGold.setDescription("prototype ship"); - manager.modify(heartOfGold); - - Repository hearReference = manager.get(heartOfGold.getId()); - - assertNotNull(hearReference); - assertEquals(hearReference.getDescription(), "prototype ship"); - } - - @Test - @SubjectAware(username = "crato") - public void testModifyWithoutRequiredPermissions() { - Repository heartOfGold = RepositoryTestData.createHeartOfGold(); - manager.create(heartOfGold); - heartOfGold.setDescription("prototype ship"); - - thrown.expect(UnauthorizedException.class); - manager.modify(heartOfGold); - } - - @Test(expected = NotFoundException.class) - public void testModifyNotFound(){ - manager.modify(createRepositoryWithId()); - } - - @Test - public void testRefresh() { - Repository heartOfGold = createTestRepository(); - String description = heartOfGold.getDescription(); - - heartOfGold.setDescription("prototype ship"); - manager.refresh(heartOfGold); - assertEquals(description, heartOfGold.getDescription()); - } - - @Test - @SubjectAware(username = "crato") - public void testRefreshWithoutRequiredPermissions() { - Repository heartOfGold = RepositoryTestData.createHeartOfGold(); - manager.create(heartOfGold); - heartOfGold.setDescription("prototype ship"); - - thrown.expect(UnauthorizedException.class); - manager.refresh(heartOfGold); - } - - @Test(expected = NotFoundException.class) - public void testRefreshNotFound(){ - manager.refresh(createRepositoryWithId()); - } - - @Test - public void testRepositoryHook() { - CountingReceiveHook hook = new CountingReceiveHook(); - RepositoryManager repoManager = createRepositoryManager(false); - - ScmEventBus.getInstance().register(hook); - - assertEquals(0, hook.eventsReceived); - - Repository repository = createTestRepository(); - HookContext ctx = createHookContext(repository); - - repoManager.fireHookEvent(new RepositoryHookEvent(ctx, repository, - RepositoryHookType.POST_RECEIVE)); - assertEquals(1, hook.eventsReceived); - repoManager.fireHookEvent(new RepositoryHookEvent(ctx, repository, - RepositoryHookType.POST_RECEIVE)); - assertEquals(2, hook.eventsReceived); - } - - @Test - public void testNamespaceSet() { - RepositoryManager repoManager = createRepositoryManager(false); - Repository repository = spy(createTestRepository()); - repository.setName("Testrepo"); - repoManager.create(repository); - assertEquals("default_namespace", repository.getNamespace()); - } - - @Test - public void shouldSetNamespace() { - Repository repository = new Repository(null, "hg", null, "scm"); - manager.create(repository); - assertNotNull(repository.getId()); - assertNotNull(repository.getNamespace()); - } - - //~--- methods -------------------------------------------------------------- - - @Override - protected DefaultRepositoryManager createManager() { - return createRepositoryManager(false); - } - - private DefaultRepositoryManager createRepositoryManager(boolean archiveEnabled) { - return createRepositoryManager(archiveEnabled, new DefaultKeyGenerator()); - } - - private DefaultRepositoryManager createRepositoryManager(boolean archiveEnabled, KeyGenerator keyGenerator) { - DefaultFileSystem fileSystem = new DefaultFileSystem(); - Set handlerSet = new HashSet<>(); - InitialRepositoryLocationResolver initialRepositoryLocationResolver = new InitialRepositoryLocationResolver(); - PathBasedRepositoryLocationResolver repositoryLocationResolver = mock(PathBasedRepositoryLocationResolver.class, RETURNS_DEEP_STUBS); - when(repositoryLocationResolver.forClass(Path.class).getLocation(anyString())).thenReturn(Paths.get(".")); - XmlRepositoryDAO repositoryDAO = new XmlRepositoryDAO(contextProvider, repositoryLocationResolver, initialRepositoryLocationResolver, fileSystem); - ConfigurationStoreFactory factory = new JAXBConfigurationStoreFactory(contextProvider, repositoryLocationResolver); - handlerSet.add(new DummyRepositoryHandler(factory, repositoryLocationResolver)); - handlerSet.add(new DummyRepositoryHandler(factory, repositoryLocationResolver) { - @Override - public RepositoryType getType() { - return new RepositoryType("hg", "Mercurial", Sets.newHashSet()); - } - }); - handlerSet.add(new DummyRepositoryHandler(factory, repositoryLocationResolver) { - @Override - public RepositoryType getType() { - return new RepositoryType("git", "Git", Sets.newHashSet()); - } - }); - - - this.configuration = new ScmConfiguration(); - - configuration.setEnableRepositoryArchive(archiveEnabled); - - NamespaceStrategy namespaceStrategy = mock(NamespaceStrategy.class); - when(namespaceStrategy.createNamespace(Mockito.any(Repository.class))).thenAnswer(invocation -> mockedNamespace); - - return new DefaultRepositoryManager(configuration, contextProvider, - keyGenerator, repositoryDAO, handlerSet, Providers.of(namespaceStrategy)); - } - - private HookContext createHookContext(Repository repository) { - PreProcessorUtil ppu = mock(PreProcessorUtil.class); - HookContextProvider provider = mock(HookContextProvider.class); - Set features = ImmutableSet.of(); - - when(provider.getSupportedFeatures()).thenReturn(features); - - return new HookContextFactory(ppu).createContext(provider, repository); - } - - private void assertRepositoriesEquals(Repository repo, Repository other) { - assertEquals(repo.getId(), other.getId()); - assertEquals(repo.getName(), other.getName()); - assertEquals(repo.getDescription(), other.getDescription()); - assertEquals(repo.getContact(), other.getContact()); - assertEquals(repo.getCreationDate(), other.getCreationDate()); - assertEquals(repo.getLastModified(), other.getLastModified()); - } - - private Repository createRepository(Repository repository) { - manager.create(repository); - assertNotNull(repository.getId()); - assertNotNull(manager.get(repository.getId())); - assertTrue(repository.getCreationDate() > 0); - - return repository; - } - - private Repository createRepositoryWithId() { - Repository repository = RepositoryTestData.createHeartOfGold(); - repository.setId("abc"); - return repository; - } - - private Repository createSecondTestRepository() { - return createRepository( - RepositoryTestData.createHappyVerticalPeopleTransporter()); - } - - private Repository createTestRepository() { - return createRepository(RepositoryTestData.createHeartOfGold()); - } - - private void delete(Manager manager, Repository repository){ - - String id = repository.getId(); - - manager.delete(repository); - assertNull(manager.get(id)); - } - - private static class CountingReceiveHook { - - private int eventsReceived = 0; - - @Subscribe(async = false) - public void onEvent(PostReceiveRepositoryHookEvent event) { - eventsReceived++; - } - - @Subscribe(async = false) - public void onEvent(PreReceiveRepositoryHookEvent event) { - eventsReceived++; - } - } - - private class TestListener { - - private HandlerEventType postEvent; - - private Repository postRepository; - - private HandlerEventType preEvent; - - private Repository preRepository; - - @Subscribe(async = false) - public void onEvent(RepositoryEvent event) { - if (event.getEventType().isPost()) { - this.postRepository = event.getItem(); - this.postEvent = event.getEventType(); - } - else if (event.getEventType().isPre()) { - this.preRepository = event.getItem(); - this.preEvent = event.getEventType(); - } - } - } - +public class DefaultRepositoryManagerTest {//extends ManagerTestBase { + +// { +// ThreadContext.unbindSubject(); +// } +// +// @Rule +// public ShiroRule shiro = new ShiroRule(); +// +// @Rule +// public ExpectedException thrown = ExpectedException.none(); +// +// private ScmConfiguration configuration; +// +// private String mockedNamespace = "default_namespace"; +// +// @Before +// public void initContext() { +// ((TempSCMContextProvider)SCMContext.getContext()).setBaseDirectory(temp); +// } +// +// @Test +// public void testCreate() { +// Repository heartOfGold = createTestRepository(); +// Repository dbRepo = manager.get(heartOfGold.getId()); +// +// assertNotNull(dbRepo); +// assertRepositoriesEquals(dbRepo, heartOfGold); +// } +// +// @SubjectAware( +// username = "unpriv" +// ) +// @Test(expected = UnauthorizedException.class) +// public void testCreateWithoutPrivileges() { +// createTestRepository(); +// } +// +// @Test +// public void testCreateExisting() { +// Repository testRepository = createTestRepository(); +// String expectedNamespaceAndName = testRepository.getNamespaceAndName().logString(); +// thrown.expect(AlreadyExistsException.class); +// thrown.expectMessage(expectedNamespaceAndName); +// createTestRepository(); +// } +// +// @Test +// public void testDelete() { +// delete(manager, createTestRepository()); +// } +// +// @SubjectAware( +// username = "unpriv" +// ) +// @Test(expected = UnauthorizedException.class) +// public void testDeleteWithoutPrivileges() { +// delete(manager, createTestRepository()); +// } +// +// @Test(expected = RepositoryIsNotArchivedException.class) +// public void testDeleteNonArchived() { +// configuration.setEnableRepositoryArchive(true); +// delete(manager, createTestRepository()); +// } +// +// @Test(expected = NotFoundException.class) +// public void testDeleteNotFound(){ +// manager.delete(createRepositoryWithId()); +// } +// +// @Test +// public void testDeleteWithEnabledArchive() { +// Repository repository = createTestRepository(); +// +// repository.setArchived(true); +// RepositoryManager drm = createRepositoryManager(true); +// drm.init(contextProvider); +// delete(drm, repository); +// } +// +// @Test +// public void testGet() { +// Repository heartOfGold = createTestRepository(); +// String id = heartOfGold.getId(); +// String description = heartOfGold.getDescription(); +// +// assertNotNull(description); +// +// // test for reference +// heartOfGold.setDescription("prototype ship"); +// heartOfGold = manager.get(id); +// assertNotNull(heartOfGold); +// assertEquals(description, heartOfGold.getDescription()); +// } +// +// @Test +// @SubjectAware( +// username = "crato" +// ) +// public void testGetWithoutRequiredPrivileges() { +// Repository heartOfGold = RepositoryTestData.createHeartOfGold(); +// manager.create(heartOfGold); +// +// thrown.expect(UnauthorizedException.class); +// manager.get(heartOfGold.getId()); +// } +// +// @Test +// public void testGetAll() { +// Repository heartOfGold = createTestRepository(); +// Repository happyVerticalPeopleTransporter = createSecondTestRepository(); +// boolean foundHeart = false; +// boolean foundTransporter = false; +// Collection repositories = manager.getAll(); +// +// assertNotNull(repositories); +// assertFalse(repositories.isEmpty()); +// assertTrue(repositories.size() >= 2); +// +// Repository heartReference = null; +// +// for (Repository repository : repositories) { +// if (repository.getId().equals(heartOfGold.getId())) { +// assertRepositoriesEquals(heartOfGold, repository); +// foundHeart = true; +// heartReference = repository; +// } +// else if (repository.getId().equals(happyVerticalPeopleTransporter.getId())) { +// assertRepositoriesEquals(happyVerticalPeopleTransporter, repository); +// foundTransporter = true; +// } +// } +// +// assertTrue(foundHeart); +// assertTrue(foundTransporter); +// +// // test for reference +// assertNotSame(heartOfGold, heartReference); +// heartReference.setDescription("prototype ship"); +// assertFalse( +// heartOfGold.getDescription().equals(heartReference.getDescription())); +// } +// +// @Test +// @SuppressWarnings("unchecked") +// @SubjectAware(username = "dent") +// public void testGetAllWithPermissionsForTwoOrThreeRepos() { +// // mock key generator +// KeyGenerator keyGenerator = mock(KeyGenerator.class); +// Stack keys = new Stack<>(); +// keys.push("rateotu"); +// keys.push("p42"); +// keys.push("hof"); +// +// when(keyGenerator.createKey()).then((InvocationOnMock invocation) -> { +// return keys.pop(); +// }); +// +// // create repository manager +// RepositoryManager repositoryManager = createRepositoryManager(false, keyGenerator); +// +// // create first test repository +// Repository heartOfGold = RepositoryTestData.createHeartOfGold(); +// repositoryManager.create(heartOfGold); +// assertEquals("hof", heartOfGold.getId()); +// +// // create second test repository +// Repository puzzle42 = RepositoryTestData.create42Puzzle(); +// repositoryManager.create(puzzle42); +// assertEquals("p42", puzzle42.getId()); +// +// // create third test repository +// Repository restaurant = RepositoryTestData.createRestaurantAtTheEndOfTheUniverse(); +// repositoryManager.create(restaurant); +// assertEquals("rateotu", restaurant.getId()); +// +// // assert returned repositories +// Collection repositories = repositoryManager.getAll(); +// assertEquals(2, repositories.size()); +// assertThat(repositories, containsInAnyOrder( +// hasProperty("id", is("p42")), +// hasProperty("id", is("hof")) +// ) +// ); +// } +// +// @Test +// public void testEvents() { +// RepositoryManager repoManager = createRepositoryManager(false); +// repoManager.init(contextProvider); +// TestListener listener = new TestListener(); +// +// ScmEventBus.getInstance().register(listener); +// +// Repository repository = RepositoryTestData.create42Puzzle(); +// +// repoManager.create(repository); +// assertRepositoriesEquals(repository, listener.preRepository); +// assertSame(HandlerEventType.BEFORE_CREATE, listener.preEvent); +// assertRepositoriesEquals(repository, listener.postRepository); +// assertSame(HandlerEventType.CREATE, listener.postEvent); +// +// repository.setDescription("changed description"); +// repoManager.modify(repository); +// assertRepositoriesEquals(repository, listener.preRepository); +// assertSame(HandlerEventType.BEFORE_MODIFY, listener.preEvent); +// assertRepositoriesEquals(repository, listener.postRepository); +// assertSame(HandlerEventType.MODIFY, listener.postEvent); +// +// repoManager.delete(repository); +// +// assertRepositoriesEquals(repository, listener.preRepository); +// assertSame(HandlerEventType.BEFORE_DELETE, listener.preEvent); +// assertRepositoriesEquals(repository, listener.postRepository); +// assertSame(HandlerEventType.DELETE, listener.postEvent); +// } +// +// @Test +// public void testModify() { +// Repository heartOfGold = createTestRepository(); +// +// heartOfGold.setDescription("prototype ship"); +// manager.modify(heartOfGold); +// +// Repository hearReference = manager.get(heartOfGold.getId()); +// +// assertNotNull(hearReference); +// assertEquals(hearReference.getDescription(), "prototype ship"); +// } +// +// @Test +// @SubjectAware(username = "crato") +// public void testModifyWithoutRequiredPermissions() { +// Repository heartOfGold = RepositoryTestData.createHeartOfGold(); +// manager.create(heartOfGold); +// heartOfGold.setDescription("prototype ship"); +// +// thrown.expect(UnauthorizedException.class); +// manager.modify(heartOfGold); +// } +// +// @Test(expected = NotFoundException.class) +// public void testModifyNotFound(){ +// manager.modify(createRepositoryWithId()); +// } +// +// @Test +// public void testRefresh() { +// Repository heartOfGold = createTestRepository(); +// String description = heartOfGold.getDescription(); +// +// heartOfGold.setDescription("prototype ship"); +// manager.refresh(heartOfGold); +// assertEquals(description, heartOfGold.getDescription()); +// } +// +// @Test +// @SubjectAware(username = "crato") +// public void testRefreshWithoutRequiredPermissions() { +// Repository heartOfGold = RepositoryTestData.createHeartOfGold(); +// manager.create(heartOfGold); +// heartOfGold.setDescription("prototype ship"); +// +// thrown.expect(UnauthorizedException.class); +// manager.refresh(heartOfGold); +// } +// +// @Test(expected = NotFoundException.class) +// public void testRefreshNotFound(){ +// manager.refresh(createRepositoryWithId()); +// } +// +// @Test +// public void testRepositoryHook() { +// CountingReceiveHook hook = new CountingReceiveHook(); +// RepositoryManager repoManager = createRepositoryManager(false); +// +// ScmEventBus.getInstance().register(hook); +// +// assertEquals(0, hook.eventsReceived); +// +// Repository repository = createTestRepository(); +// HookContext ctx = createHookContext(repository); +// +// repoManager.fireHookEvent(new RepositoryHookEvent(ctx, repository, +// RepositoryHookType.POST_RECEIVE)); +// assertEquals(1, hook.eventsReceived); +// repoManager.fireHookEvent(new RepositoryHookEvent(ctx, repository, +// RepositoryHookType.POST_RECEIVE)); +// assertEquals(2, hook.eventsReceived); +// } +// +// @Test +// public void testNamespaceSet() { +// RepositoryManager repoManager = createRepositoryManager(false); +// Repository repository = spy(createTestRepository()); +// repository.setName("Testrepo"); +// repoManager.create(repository); +// assertEquals("default_namespace", repository.getNamespace()); +// } +// +// @Test +// public void shouldSetNamespace() { +// Repository repository = new Repository(null, "hg", null, "scm"); +// manager.create(repository); +// assertNotNull(repository.getId()); +// assertNotNull(repository.getNamespace()); +// } +// +// //~--- methods -------------------------------------------------------------- +// +// @Override +// protected DefaultRepositoryManager createManager() { +// return createRepositoryManager(false); +// } +// +// private DefaultRepositoryManager createRepositoryManager(boolean archiveEnabled) { +// return createRepositoryManager(archiveEnabled, new DefaultKeyGenerator()); +// } +// +// private DefaultRepositoryManager createRepositoryManager(boolean archiveEnabled, KeyGenerator keyGenerator) { +// DefaultFileSystem fileSystem = new DefaultFileSystem(); +// Set handlerSet = new HashSet<>(); +// PathBasedRepositoryLocationResolver repositoryLocationResolver = mock(PathBasedRepositoryLocationResolver.class, RETURNS_DEEP_STUBS); +// when(repositoryLocationResolver.forClass(Path.class).getLocation(anyString())).thenReturn(Paths.get(".")); +// XmlRepositoryDAO repositoryDAO = new XmlRepositoryDAO(contextProvider, repositoryLocationResolver, fileSystem); +// ConfigurationStoreFactory factory = new JAXBConfigurationStoreFactory(contextProvider, repositoryLocationResolver); +// handlerSet.add(new DummyRepositoryHandler(factory, repositoryLocationResolver)); +// handlerSet.add(new DummyRepositoryHandler(factory, repositoryLocationResolver) { +// @Override +// public RepositoryType getType() { +// return new RepositoryType("hg", "Mercurial", Sets.newHashSet()); +// } +// }); +// handlerSet.add(new DummyRepositoryHandler(factory, repositoryLocationResolver) { +// @Override +// public RepositoryType getType() { +// return new RepositoryType("git", "Git", Sets.newHashSet()); +// } +// }); +// +// +// this.configuration = new ScmConfiguration(); +// +// configuration.setEnableRepositoryArchive(archiveEnabled); +// +// NamespaceStrategy namespaceStrategy = mock(NamespaceStrategy.class); +// when(namespaceStrategy.createNamespace(Mockito.any(Repository.class))).thenAnswer(invocation -> mockedNamespace); +// +// return new DefaultRepositoryManager(configuration, contextProvider, +// keyGenerator, repositoryDAO, handlerSet, Providers.of(namespaceStrategy)); +// } +// +// private HookContext createHookContext(Repository repository) { +// PreProcessorUtil ppu = mock(PreProcessorUtil.class); +// HookContextProvider provider = mock(HookContextProvider.class); +// Set features = ImmutableSet.of(); +// +// when(provider.getSupportedFeatures()).thenReturn(features); +// +// return new HookContextFactory(ppu).createContext(provider, repository); +// } +// +// private void assertRepositoriesEquals(Repository repo, Repository other) { +// assertEquals(repo.getId(), other.getId()); +// assertEquals(repo.getName(), other.getName()); +// assertEquals(repo.getDescription(), other.getDescription()); +// assertEquals(repo.getContact(), other.getContact()); +// assertEquals(repo.getCreationDate(), other.getCreationDate()); +// assertEquals(repo.getLastModified(), other.getLastModified()); +// } +// +// private Repository createRepository(Repository repository) { +// manager.create(repository); +// assertNotNull(repository.getId()); +// assertNotNull(manager.get(repository.getId())); +// assertTrue(repository.getCreationDate() > 0); +// +// return repository; +// } +// +// private Repository createRepositoryWithId() { +// Repository repository = RepositoryTestData.createHeartOfGold(); +// repository.setId("abc"); +// return repository; +// } +// +// private Repository createSecondTestRepository() { +// return createRepository( +// RepositoryTestData.createHappyVerticalPeopleTransporter()); +// } +// +// private Repository createTestRepository() { +// return createRepository(RepositoryTestData.createHeartOfGold()); +// } +// +// private void delete(Manager manager, Repository repository){ +// +// String id = repository.getId(); +// +// manager.delete(repository); +// assertNull(manager.get(id)); +// } +// +// private static class CountingReceiveHook { +// +// private int eventsReceived = 0; +// +// @Subscribe(async = false) +// public void onEvent(PostReceiveRepositoryHookEvent event) { +// eventsReceived++; +// } +// +// @Subscribe(async = false) +// public void onEvent(PreReceiveRepositoryHookEvent event) { +// eventsReceived++; +// } +// } +// +// private class TestListener { +// +// private HandlerEventType postEvent; +// +// private Repository postRepository; +// +// private HandlerEventType preEvent; +// +// private Repository preRepository; +// +// @Subscribe(async = false) +// public void onEvent(RepositoryEvent event) { +// if (event.getEventType().isPost()) { +// this.postRepository = event.getItem(); +// this.postEvent = event.getEventType(); +// } +// else if (event.getEventType().isPre()) { +// this.preRepository = event.getItem(); +// this.preEvent = event.getEventType(); +// } +// } +// } +// }