diff --git a/pom.xml b/pom.xml index 87c7e99..a6404d2 100644 --- a/pom.xml +++ b/pom.xml @@ -132,6 +132,37 @@ lombok 1.16.4 + + + org.mockito + mockito-core + 1.10.19 + test + + + org.hamcrest + hamcrest-core + + + + + org.powermock + powermock-module-junit4 + 1.6.2 + test + + + org.powermock + powermock-api-mockito + 1.6.2 + test + + + org.mockito + mockito-all + + + diff --git a/src/main/java/com/griddynamics/cd/nrp/internal/uploading/impl/ConfigurationsManagerImpl.java b/src/main/java/com/griddynamics/cd/nrp/internal/uploading/impl/ConfigurationsManagerImpl.java index 5d4b4be..4dc835b 100644 --- a/src/main/java/com/griddynamics/cd/nrp/internal/uploading/impl/ConfigurationsManagerImpl.java +++ b/src/main/java/com/griddynamics/cd/nrp/internal/uploading/impl/ConfigurationsManagerImpl.java @@ -66,7 +66,7 @@ public ConfigurationsManagerImpl(NexusConfiguration nexusConfiguration) { @PostConstruct public void init() { log.trace("Initializing plugin configurations"); - reloadConfigurations(); + reloadConfigurations(CONFIG_FILENAME); } /** @@ -78,7 +78,7 @@ public ReplicationPluginConfiguration getConfiguration() { if (config == null) { synchronized (this) { if (config == null) { - reloadConfigurations(); + reloadConfigurations(CONFIG_FILENAME); } } } @@ -89,8 +89,8 @@ public ReplicationPluginConfiguration getConfiguration() { * Reloads {@link ConfigurationsManagerImpl#config} * from XML plugin configurations file */ - public void reloadConfigurations() { - File file = getConfigurationFile(); + public void reloadConfigurations(String filename) { + File file = getConfigurationFile(filename); try { JAXBContext jaxbContext = JAXBContext.newInstance(ReplicationPluginConfiguration.class); @@ -104,7 +104,7 @@ public void reloadConfigurations() { /** * Returns plugin configurations XML file */ - private File getConfigurationFile() { - return new File(nexusConfiguration.getConfigurationDirectory(), CONFIG_FILENAME); + private File getConfigurationFile(String filename) { + return new File(nexusConfiguration.getConfigurationDirectory(), filename); } } diff --git a/src/test/java/com/griddynamics/cd/nrp/internal/rest/ArtifactUpdatePlexusResourceTest.java b/src/test/java/com/griddynamics/cd/nrp/internal/rest/ArtifactUpdatePlexusResourceTest.java new file mode 100644 index 0000000..7ce3985 --- /dev/null +++ b/src/test/java/com/griddynamics/cd/nrp/internal/rest/ArtifactUpdatePlexusResourceTest.java @@ -0,0 +1,151 @@ +package com.griddynamics.cd.nrp.internal.rest; + +import com.griddynamics.cd.nrp.internal.model.api.ArtifactMetaInfo; +import com.griddynamics.cd.nrp.internal.model.api.RestResponse; +import com.thoughtworks.xstream.XStream; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Matchers; +import org.mockito.Mockito; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.restlet.data.Request; +import org.sonatype.nexus.proxy.maven.ArtifactStoreHelper; +import org.sonatype.nexus.proxy.maven.ArtifactStoreRequest; +import org.sonatype.nexus.proxy.maven.maven2.M2Repository; +import org.sonatype.nexus.proxy.registry.RepositoryRegistry; +import org.sonatype.nexus.proxy.repository.Repository; +import org.sonatype.plexus.rest.resource.PathProtectionDescriptor; + +import java.util.ArrayList; + +import static org.junit.Assert.*; + +@RunWith(PowerMockRunner.class) +@PrepareForTest(ArtifactUpdatePlexusResource.class) +public class ArtifactUpdatePlexusResourceTest { + + private final String REQUEST_URI = "/artifact/maven/update"; + + private ArtifactUpdatePlexusResource artifactUpdatePlexusResource; + private ArtifactMetaInfo artifactMetaInfo; + + @Before + public void setUp() throws Exception { + artifactUpdatePlexusResource = PowerMockito.spy(new ArtifactUpdatePlexusResource()); + artifactMetaInfo = new ArtifactMetaInfo("http://localhost:8081/nexus", "com.griddynamics.cd", "nexus-replication-plugin", "1.0", "snapshots"); + artifactMetaInfo.setExtension("jar"); + } + + @Test + public void testGetResourceUri() throws Exception { + assertEquals(artifactUpdatePlexusResource.getResourceUri(), REQUEST_URI); + } + + @Test + public void testGetResourceProtection() throws Exception { + PathProtectionDescriptor resourceProtection = artifactUpdatePlexusResource.getResourceProtection(); + assertEquals("Incorrect request URI in security configuration", resourceProtection.getPathPattern(), REQUEST_URI); + assertEquals("Incorrect permissions for API", resourceProtection.getFilterExpression(), "authcBasic,perms[nexus:artifact]"); + } + + @Test + public void testGetPayloadInstance() throws Exception { + Object instance = artifactUpdatePlexusResource.getPayloadInstance(); + assertNotNull(REQUEST_URI + " resource should be configured to return ArtifactMetaInfo as request body DTO. Method returns null.", instance); + assertTrue(REQUEST_URI + " resource should be configured to return ArtifactMetaInfo as request body DTO. Method returns incorrect type.", instance instanceof ArtifactMetaInfo); + } + + @Test + public void testConfigureXStream() throws Exception { + XStream xstream = Mockito.mock(XStream.class); + artifactUpdatePlexusResource.configureXStream(xstream); + Mockito.verify(xstream, Mockito.times(1)).processAnnotations(ArtifactMetaInfo.class); + Mockito.verify(xstream, Mockito.times(1)).processAnnotations(RestResponse.class); + } + + @Test + public void testPostForEmptyRepositoriesList() throws Exception { + // Mocks initialization + Request request = Mockito.mock(Request.class); + PowerMockito.when(artifactUpdatePlexusResource, "getRepositoryRegistry").thenReturn(PowerMockito.mock(RepositoryRegistry.class)); + + // Tested method invocation + RestResponse response = (RestResponse) artifactUpdatePlexusResource.post(null, request, null, artifactMetaInfo); + // Asserts + assertEquals("Method should return message that no proxies found", response.getMessage(), "No proxies for this artifact."); + assertFalse("Method should return error status because of no proxies found", response.isSuccess()); + } + + @Test + public void testPostForOneRepositoryList() throws Exception { + // Init mocks + ArtifactStoreHelper artifactStoreHelper = PowerMockito.mock(ArtifactStoreHelper.class); + ArrayList repositories = new ArrayList<>(); + M2Repository repository = PowerMockito.mock(M2Repository.class); + PowerMockito.when(repository.getRemoteUrl()).thenReturn("http://localhost:8081/nexus/content/repositories/snapshots/"); + PowerMockito.when(repository.getId()).thenReturn("replica-1"); + PowerMockito.when(repository.getArtifactStoreHelper()).thenReturn(artifactStoreHelper); + repositories.add(repository); + + Request request = new Request(); + RepositoryRegistry repositoryRegistry = PowerMockito.mock(RepositoryRegistry.class); + PowerMockito.when(repositoryRegistry, "getRepositories").thenReturn(repositories); + PowerMockito.when(artifactUpdatePlexusResource, "getRepositoryRegistry").thenReturn(repositoryRegistry); + ArtifactStoreRequest storeRequest = PowerMockito.mock(ArtifactStoreRequest.class); + PowerMockito.doReturn(storeRequest).when(artifactUpdatePlexusResource, "getResourceStoreRequest", + Matchers.eq(request), Matchers.eq(false), Matchers.eq(false), Matchers.eq("replica-1"), Matchers.eq(artifactMetaInfo.getGroupId()), + Matchers.eq(artifactMetaInfo.getArtifactId()), Matchers.eq(artifactMetaInfo.getVersion()), Matchers.eq(artifactMetaInfo.getPackaging()), + Matchers.eq(artifactMetaInfo.getClassifier()), Matchers.eq(artifactMetaInfo.getExtension())); + // Tested method invocation + RestResponse response = (RestResponse) artifactUpdatePlexusResource.post(null, request, null, artifactMetaInfo); + // Asserts + Mockito.verify(artifactStoreHelper, Mockito.times(1)).retrieveArtifact(storeRequest); + Assert.assertEquals("Request should return that artifact is resolved", "Artifact is resolved.", response.getMessage()); + Assert.assertTrue("Request should be success.", response.isSuccess()); + } + + @Test + public void testPostForTwoMatchedRepositories() throws Exception { + // Init mocks + ArtifactStoreHelper artifactStoreHelper = PowerMockito.mock(ArtifactStoreHelper.class); + ArrayList repositories = new ArrayList<>(); + M2Repository repository = PowerMockito.mock(M2Repository.class); + PowerMockito.when(repository.getRemoteUrl()).thenReturn("http://localhost:8081/nexus/content/repositories/snapshots/"); + PowerMockito.when(repository.getId()).thenReturn("replica-1"); + PowerMockito.when(repository.getArtifactStoreHelper()).thenReturn(artifactStoreHelper); + repositories.add(repository); + + repository = PowerMockito.mock(M2Repository.class); + PowerMockito.when(repository.getRemoteUrl()).thenReturn("http://localhost:8081/nexus/content/repositories/snapshots/"); + PowerMockito.when(repository.getId()).thenReturn("replica-2"); + PowerMockito.when(repository.getArtifactStoreHelper()).thenReturn(artifactStoreHelper); + repositories.add(repository); + + repository = PowerMockito.mock(M2Repository.class); + PowerMockito.when(repository.getRemoteUrl()).thenReturn("http://localhost:8085/nexus/content/repositories/releases/"); + PowerMockito.when(repository.getId()).thenReturn("replica-3"); + PowerMockito.when(repository.getArtifactStoreHelper()).thenReturn(artifactStoreHelper); + repositories.add(repository); + + Request request = new Request(); + RepositoryRegistry repositoryRegistry = PowerMockito.mock(RepositoryRegistry.class); + PowerMockito.when(repositoryRegistry, "getRepositories").thenReturn(repositories); + PowerMockito.when(artifactUpdatePlexusResource, "getRepositoryRegistry").thenReturn(repositoryRegistry); + ArtifactStoreRequest storeRequest = PowerMockito.mock(ArtifactStoreRequest.class); + PowerMockito.doReturn(storeRequest).when(artifactUpdatePlexusResource, "getResourceStoreRequest", + Matchers.eq(request), Matchers.eq(false), Matchers.eq(false), Matchers.any(), Matchers.eq(artifactMetaInfo.getGroupId()), + Matchers.eq(artifactMetaInfo.getArtifactId()), Matchers.eq(artifactMetaInfo.getVersion()), Matchers.eq(artifactMetaInfo.getPackaging()), + Matchers.eq(artifactMetaInfo.getClassifier()), Matchers.eq(artifactMetaInfo.getExtension())); + + // Tested method invocation + RestResponse response = (RestResponse) artifactUpdatePlexusResource.post(null, request, null, artifactMetaInfo); + // Asserts + Mockito.verify(artifactStoreHelper, Mockito.times(2)).retrieveArtifact(storeRequest); + Assert.assertEquals("Request should return that artifact is resolved", "Artifact is resolved.", response.getMessage()); + Assert.assertTrue("Request should be success.", response.isSuccess()); + } +} \ No newline at end of file diff --git a/src/test/java/com/griddynamics/cd/nrp/internal/uploading/impl/ArtifactUpdateApiClientImplTest.java b/src/test/java/com/griddynamics/cd/nrp/internal/uploading/impl/ArtifactUpdateApiClientImplTest.java new file mode 100644 index 0000000..49d8cbf --- /dev/null +++ b/src/test/java/com/griddynamics/cd/nrp/internal/uploading/impl/ArtifactUpdateApiClientImplTest.java @@ -0,0 +1,65 @@ +package com.griddynamics.cd.nrp.internal.uploading.impl; + +import com.griddynamics.cd.nrp.internal.uploading.ArtifactUpdateApiClient; +import com.sun.jersey.api.client.Client; +import com.sun.jersey.api.client.ClientHandler; +import com.sun.jersey.api.client.TerminatingClientHandler; +import com.sun.jersey.api.client.filter.ClientFilter; +import com.sun.jersey.api.client.filter.HTTPBasicAuthFilter; +import org.junit.Assert; +import org.junit.Test; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.reflect.Whitebox; + +public class ArtifactUpdateApiClientImplTest { + @Test + public void testGetClientAuth() throws Exception { + testAuthUser("admin", "admin123", "Basic YWRtaW46YWRtaW4xMjM="); + } + + @Test + public void testGetClientAuthEmptyPassword() throws Exception { + testAuthUser("admin", "", "Basic YWRtaW46"); + } + + @Test + public void testGetClientEmptyUser() throws Exception { + testAnonymousUser("", "admin123"); + testAnonymousUser("", null); + } + + @Test + public void testGetClientNullUser() throws Exception { + testAnonymousUser(null, "somePass"); + testAnonymousUser(null, null); + } + + private void testAuthUser(String admin, String admin123, String expectedAuthentication) throws Exception { + ArtifactUpdateApiClient artifactUpdateApiClient = new ArtifactUpdateApiClientImpl(PowerMockito.mock(ConfigurationsManagerImpl.class)); + Client client = Whitebox.invokeMethod(artifactUpdateApiClient, "getClient", admin, admin123); + ClientHandler current = Whitebox.getInternalState(client, "head"); + while (!(current instanceof TerminatingClientHandler)) { + if (current instanceof HTTPBasicAuthFilter) { + HTTPBasicAuthFilter authFilter = (HTTPBasicAuthFilter) current; + Assert.assertEquals(expectedAuthentication, Whitebox.getInternalState(authFilter, "authentication")); + } + if (current instanceof ClientFilter) { + current = ((ClientFilter) current).getNext(); + } + } + } + + private void testAnonymousUser(String login, String password) throws Exception { + ArtifactUpdateApiClient artifactUpdateApiClient = new ArtifactUpdateApiClientImpl(PowerMockito.mock(ConfigurationsManagerImpl.class)); + Client client = Whitebox.invokeMethod(artifactUpdateApiClient, "getClient", login, password); + ClientHandler current = Whitebox.getInternalState(client, "head"); + while (!(current instanceof TerminatingClientHandler)) { + if (current instanceof HTTPBasicAuthFilter) { + Assert.fail("Request should not contain HTTPBasicAuthFilter for anonymous user"); + } + if (current instanceof ClientFilter) { + current = ((ClientFilter) current).getNext(); + } + } + } +} \ No newline at end of file diff --git a/src/test/java/com/griddynamics/cd/nrp/internal/uploading/impl/ConfigurationsManagerImplTest.java b/src/test/java/com/griddynamics/cd/nrp/internal/uploading/impl/ConfigurationsManagerImplTest.java new file mode 100644 index 0000000..39724f1 --- /dev/null +++ b/src/test/java/com/griddynamics/cd/nrp/internal/uploading/impl/ConfigurationsManagerImplTest.java @@ -0,0 +1,57 @@ +package com.griddynamics.cd.nrp.internal.uploading.impl; + +import com.griddynamics.cd.nrp.internal.model.config.NexusServer; +import com.griddynamics.cd.nrp.internal.model.config.ReplicationPluginConfiguration; +import org.junit.Assert; +import org.junit.Test; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.reflect.Whitebox; +import org.sonatype.nexus.configuration.application.NexusConfiguration; + +import java.io.File; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.net.URL; +import java.util.Iterator; + +import static org.junit.Assert.*; + +public class ConfigurationsManagerImplTest { + + private final String FIRST_CONFIGURATION_FILE = "replication-plugin.xml"; + private final String SECOND_CONFIGURATION_FILE = "replication-plugin-2.xml"; + + @Test + public void testGetConfiguration() throws Exception { + NexusConfiguration nexusConfiguration = PowerMockito.mock(NexusConfiguration.class); + URL configFile = getClass().getClassLoader().getResource(FIRST_CONFIGURATION_FILE); + PowerMockito.when(nexusConfiguration.getConfigurationDirectory()).thenReturn(new File(configFile.getFile()).getParentFile()); + ConfigurationsManagerImpl configurationsManager = PowerMockito.spy(new ConfigurationsManagerImpl(nexusConfiguration)); + + ReplicationPluginConfiguration configuration = configurationsManager.getConfiguration(); + Assert.assertEquals("My url was written incorrectly", "http://localhost:8081/nexus", configuration.getMyUrl()); + Assert.assertEquals("Incorrect count of servers", 1, configuration.getServers().size()); + Iterator iterator = configuration.getServers().iterator(); + if (iterator.hasNext()) { + NexusServer nexusServer = iterator.next(); + Assert.assertEquals("Server url was written incorrectly", "http://localhost:8083/nexus", nexusServer.getUrl()); + Assert.assertEquals("User was written incorrectly", "admin", nexusServer.getUser()); + Assert.assertEquals("Password was written incorrectly", "admin123", nexusServer.getPassword()); + } + } + + @Test + public void testReloadConfigurations() throws Exception { + NexusConfiguration nexusConfiguration = PowerMockito.mock(NexusConfiguration.class); + URL configFile = getClass().getClassLoader().getResource(FIRST_CONFIGURATION_FILE); + PowerMockito.when(nexusConfiguration.getConfigurationDirectory()).thenReturn(new File(configFile.getFile()).getParentFile()); + ConfigurationsManagerImpl configurationsManager = PowerMockito.spy(new ConfigurationsManagerImpl(nexusConfiguration)); + + ReplicationPluginConfiguration configuration = configurationsManager.getConfiguration(); + Assert.assertEquals("First file should contain one nexus server only", 1, configuration.getServers().size()); + + configurationsManager.reloadConfigurations(SECOND_CONFIGURATION_FILE); + configuration = configurationsManager.getConfiguration(); + Assert.assertEquals("Second file should contain two nexus servers", 2, configuration.getServers().size()); + } +} \ No newline at end of file diff --git a/src/test/resources/replication-plugin-2.xml b/src/test/resources/replication-plugin-2.xml new file mode 100644 index 0000000..4bfa8d6 --- /dev/null +++ b/src/test/resources/replication-plugin-2.xml @@ -0,0 +1,15 @@ + + + + + http://localhost:8083/nexus + admin + admin123 + + + http://localhost:8083/nexus2 + admin2 + admin123 + + + diff --git a/src/test/resources/replication-plugin.xml b/src/test/resources/replication-plugin.xml new file mode 100644 index 0000000..95d9854 --- /dev/null +++ b/src/test/resources/replication-plugin.xml @@ -0,0 +1,10 @@ + + + + + http://localhost:8083/nexus + admin + admin123 + + +