package org.jenkinsci.plugins.stashNotifier; import com.cloudbees.plugins.credentials.Credentials; import com.cloudbees.plugins.credentials.domains.DomainRequirement; import hudson.EnvVars; import hudson.ProxyConfiguration; import hudson.model.AbstractBuild; import hudson.model.AbstractProject; import hudson.model.BuildListener; import hudson.model.Item; import hudson.plugins.git.Revision; import hudson.plugins.git.util.Build; import hudson.plugins.git.util.BuildData; import hudson.util.Secret; import jenkins.model.Jenkins; import org.acegisecurity.Authentication; import org.apache.http.HttpHost; import org.apache.http.StatusLine; import org.apache.http.auth.AuthScope; import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.AuthenticationStrategy; import org.apache.http.client.CredentialsProvider; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.conn.ClientConnectionManager; import org.apache.http.conn.HttpClientConnectionManager; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClientBuilder; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mockito; import org.powermock.api.mockito.PowerMockito; import org.powermock.core.classloader.annotations.PowerMockIgnore; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; import java.io.IOException; import java.io.PrintStream; import java.lang.reflect.Array; import java.util.ArrayList; import java.util.Collections; import java.util.List; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.*; @RunWith(PowerMockRunner.class) @PrepareForTest({Secret.class, Jenkins.class, HttpClientBuilder.class}) @PowerMockIgnore("javax.net.ssl.*") public class StashNotifierTest { final static String sha1 = "1234567890123456789012345678901234567890"; private HttpClientBuilder httpClientBuilder; private Jenkins jenkins; public StashNotifier buildStashNotifier(String stashBaseUrl) { return new StashNotifier( stashBaseUrl, "scot", true, null, true, null, false, false); } StashNotifier sn; BuildListener buildListener; AbstractBuild<?,?> build; @Before public void setUp() throws IOException, InterruptedException { PowerMockito.mockStatic(Secret.class); PowerMockito.mockStatic(Jenkins.class); PowerMockito.mockStatic(HttpClientBuilder.class); buildListener = mock(BuildListener.class); jenkins = mock(Jenkins.class); build = mock(AbstractBuild.class); AbstractProject project = mock(AbstractProject.class); EnvVars environment = mock(EnvVars.class); PrintStream logger = System.out; Secret secret = mock(Secret.class); httpClientBuilder = PowerMockito.mock(HttpClientBuilder.class); CloseableHttpClient client = mock(CloseableHttpClient.class); ClientConnectionManager connectionManager = mock(ClientConnectionManager.class); CloseableHttpResponse resp = mock(CloseableHttpResponse.class); HttpUriRequest req = mock(HttpUriRequest.class); StatusLine statusLine = mock(StatusLine.class); BuildData action = mock(BuildData.class); Revision revision = mock(Revision.class); Build lastBuild = mock(Build.class); List<BuildData> actions = Collections.singletonList(action); when(Jenkins.getInstance()).thenReturn(jenkins); when(jenkins.getRootUrl()).thenReturn("http://localhost/"); when(build.getEnvironment(buildListener)).thenReturn(environment); when(action.getLastBuiltRevision()).thenReturn(revision); when(revision.getSha1String()).thenReturn(sha1); when(build.getProject()).thenReturn(project); when(build.getFullDisplayName()).thenReturn("foo"); when(build.getUrl()).thenReturn("foo"); when(build.getActions(BuildData.class)).thenReturn(actions); when(environment.expand(anyString())).thenReturn(sha1); when(buildListener.getLogger()).thenReturn(logger); when(Secret.fromString("tiger")).thenReturn(secret); when(Secret.toString(secret)).thenReturn("tiger"); when(secret.getPlainText()).thenReturn("tiger"); when(HttpClientBuilder.create()).thenReturn(httpClientBuilder); when(httpClientBuilder.build()).thenReturn(client); when(client.getConnectionManager()).thenReturn(connectionManager); when(client.execute((HttpUriRequest)anyObject())).thenReturn(resp); when(resp.getStatusLine()).thenReturn(statusLine); when(statusLine.getStatusCode()).thenReturn(204); action.lastBuild = lastBuild; when(lastBuild.getMarked()).thenReturn(revision); sn = buildStashNotifier("http://localhost"); } @Test public void test_prebuild_normal() { assertTrue(sn.prebuild(build, buildListener)); } @Test public void test_prebuild_null_revision() { when(build.getActions(BuildData.class)).thenReturn(Collections.singletonList(mock(BuildData.class))); assertTrue(sn.prebuild(build, buildListener)); } @Test public void test_build_http_client_with_proxy() throws Exception { //given StashNotifier sn = spy(this.sn); doReturn(new ArrayList<Credentials>()).when(sn).lookupCredentials( Mockito.<Class>anyObject(), Mockito.<Item>anyObject(), Mockito.<Authentication>anyObject(), Mockito.<ArrayList<DomainRequirement>>anyObject()); String address = "192.168.1.1"; int port = 8080; String login = "admin"; String password = "123"; Secret secret = mock(Secret.class); when(Secret.fromString(password)).thenReturn(secret); when(Secret.toString(secret)).thenReturn(password); when(secret.getPlainText()).thenReturn(password); when(httpClientBuilder.setProxy(any(HttpHost.class))).thenReturn(httpClientBuilder); when(httpClientBuilder.setDefaultCredentialsProvider(any(CredentialsProvider.class))).thenReturn(httpClientBuilder); when(httpClientBuilder.setProxyAuthenticationStrategy(any(AuthenticationStrategy.class))).thenReturn(httpClientBuilder); jenkins.proxy = new ProxyConfiguration(address, port, login, password); PrintStream logger = mock(PrintStream.class); //when sn.getHttpClient(logger, build); //then ArgumentCaptor<HttpHost> proxyCaptor = ArgumentCaptor.forClass(HttpHost.class); verify(httpClientBuilder).setProxy(proxyCaptor.capture()); HttpHost proxy = proxyCaptor.getValue(); //address assertThat(proxy.getHostName(), is(address)); assertThat(proxy.getPort(), is(port)); assertThat(proxy.getSchemeName(), is("http")); ArgumentCaptor<CredentialsProvider> credentialsProviderCaptor = ArgumentCaptor.forClass(CredentialsProvider.class); verify(httpClientBuilder).setDefaultCredentialsProvider(credentialsProviderCaptor.capture()); CredentialsProvider credentialsProvider = credentialsProviderCaptor.getValue(); org.apache.http.auth.UsernamePasswordCredentials credentials = (UsernamePasswordCredentials) credentialsProvider.getCredentials(new AuthScope(proxy)); //credentials assertThat(credentials.getUserName(), is(login)); assertThat(credentials.getPassword(), is(password)); } @Test public void test_build_http_client_https() throws Exception { //given sn = PowerMockito.spy(buildStashNotifier("https://localhost")); doReturn(new ArrayList<Credentials>()).when(sn).lookupCredentials( Mockito.<Class>anyObject(), Mockito.<Item>anyObject(), Mockito.<Authentication>anyObject(), Mockito.<ArrayList<DomainRequirement>>anyObject()); PrintStream logger = mock(PrintStream.class); //when sn.getHttpClient(logger, build); //then verify(httpClientBuilder).setSSLSocketFactory(any(SSLConnectionSocketFactory.class)); verify(httpClientBuilder).setConnectionManager(any(HttpClientConnectionManager.class)); } }