From 8101c2fc7b6ca2b2fa1d835f2c5b2a5f159539a0 Mon Sep 17 00:00:00 2001 From: Joel Baranick Date: Wed, 21 Oct 2015 14:21:34 -0700 Subject: Support credentials by allowing UsernamePasswordCredentials to be picked when configuring BitbucketBuildTrigger and change BitbucketRepository to use the credentials when setting up the ApiClient. --- .../BitbucketBuildTrigger.java | 31 +++++++++++++--------- .../BitbucketRepository.java | 19 +++++++++++-- .../BitbucketBuildTrigger/config.jelly | 9 +++---- 3 files changed, 39 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger.java b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger.java index 879facb..974d3eb 100644 --- a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger.java +++ b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger.java @@ -1,12 +1,17 @@ package bitbucketpullrequestbuilder.bitbucketpullrequestbuilder; import antlr.ANTLRException; +import com.cloudbees.plugins.credentials.CredentialsProvider; +import com.cloudbees.plugins.credentials.common.StandardListBoxModel; +import com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials; +import com.cloudbees.plugins.credentials.common.UsernamePasswordCredentials; import hudson.Extension; import hudson.model.*; import hudson.model.queue.QueueTaskFuture; import hudson.plugins.git.RevisionParameterAction; import hudson.triggers.Trigger; import hudson.triggers.TriggerDescriptor; +import hudson.util.ListBoxModel; import net.sf.json.JSONObject; import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.StaplerRequest; @@ -17,6 +22,8 @@ import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; +import static com.cloudbees.plugins.credentials.CredentialsMatchers.instanceOf; + /** * Created by nishio */ @@ -24,8 +31,7 @@ public class BitbucketBuildTrigger extends Trigger> { private static final Logger logger = Logger.getLogger(BitbucketBuildTrigger.class.getName()); private final String projectPath; private final String cron; - private final String username; - private final String password; + private final String credentialsId; private final String repositoryOwner; private final String repositoryName; private final String ciSkipPhrases; @@ -41,8 +47,7 @@ public class BitbucketBuildTrigger extends Trigger> { public BitbucketBuildTrigger( String projectPath, String cron, - String username, - String password, + String credentialsId, String repositoryOwner, String repositoryName, String ciSkipPhrases, @@ -52,8 +57,7 @@ public class BitbucketBuildTrigger extends Trigger> { super(cron); this.projectPath = projectPath; this.cron = cron; - this.username = username; - this.password = password; + this.credentialsId = credentialsId; this.repositoryOwner = repositoryOwner; this.repositoryName = repositoryName; this.ciSkipPhrases = ciSkipPhrases; @@ -69,12 +73,8 @@ public class BitbucketBuildTrigger extends Trigger> { return this.cron; } - public String getUsername() { - return username; - } - - public String getPassword() { - return password; + public String getCredentialsId() { + return credentialsId; } public String getRepositoryOwner() { @@ -180,5 +180,12 @@ public class BitbucketBuildTrigger extends Trigger> { save(); return super.configure(req, json); } + + public ListBoxModel doFillCredentialsIdItems() { + return new StandardListBoxModel() + .withEmptySelection() + .withMatching(instanceOf(UsernamePasswordCredentials.class), + CredentialsProvider.lookupCredentials(StandardUsernamePasswordCredentials.class)); + } } } diff --git a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketRepository.java b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketRepository.java index bdf5d7c..8606c45 100644 --- a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketRepository.java +++ b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketRepository.java @@ -10,6 +10,12 @@ import java.util.regex.Pattern; import bitbucketpullrequestbuilder.bitbucketpullrequestbuilder.bitbucket.ApiClient; import bitbucketpullrequestbuilder.bitbucketpullrequestbuilder.bitbucket.Pullrequest; +import com.cloudbees.plugins.credentials.CredentialsMatchers; +import com.cloudbees.plugins.credentials.CredentialsProvider; +import com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials; +import com.cloudbees.plugins.credentials.common.UsernamePasswordCredentials; + +import static com.cloudbees.plugins.credentials.CredentialsMatchers.instanceOf; /** * Created by nishio @@ -39,9 +45,10 @@ public class BitbucketRepository { public void init() { trigger = this.builder.getTrigger(); + StandardUsernamePasswordCredentials credentials = getCredentials(trigger.getCredentialsId()); client = new ApiClient( - trigger.getUsername(), - trigger.getPassword(), + credentials.getUsername(), + credentials.getPassword().getPlainText(), trigger.getRepositoryOwner(), trigger.getRepositoryName()); } @@ -192,4 +199,12 @@ public class BitbucketRepository { } return false; } + + private StandardUsernamePasswordCredentials getCredentials(String credentialsId) { + return CredentialsMatchers + .firstOrNull( + CredentialsProvider.lookupCredentials(StandardUsernamePasswordCredentials.class), + CredentialsMatchers.allOf(CredentialsMatchers.withId(credentialsId), + instanceOf(UsernamePasswordCredentials.class))); + } } diff --git a/src/main/resources/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger/config.jelly b/src/main/resources/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger/config.jelly index 0eee781..df43e5a 100644 --- a/src/main/resources/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger/config.jelly +++ b/src/main/resources/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger/config.jelly @@ -1,12 +1,9 @@ - + - - - - - + + -- cgit v1.2.3 From f2294ad4c37592d4046fd02e35439340278b09a0 Mon Sep 17 00:00:00 2001 From: Joel Baranick Date: Wed, 28 Oct 2015 12:54:10 -0700 Subject: Add support for plaintext username/password unless credentials are specified. --- .gitignore | 4 ++++ .../bitbucketpullrequestbuilder/BitbucketBuildTrigger.java | 14 ++++++++++++++ .../bitbucketpullrequestbuilder/BitbucketRepository.java | 11 +++++++++-- .../BitbucketBuildTrigger/config.jelly | 6 ++++++ 4 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 .gitignore (limited to 'src') diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3c7b603 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +target +*.iml +.idea +dependency-reduced-pom.xml diff --git a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger.java b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger.java index 974d3eb..09802af 100644 --- a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger.java +++ b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger.java @@ -32,6 +32,8 @@ public class BitbucketBuildTrigger extends Trigger> { private final String projectPath; private final String cron; private final String credentialsId; + private final String username; + private final String password; private final String repositoryOwner; private final String repositoryName; private final String ciSkipPhrases; @@ -48,6 +50,8 @@ public class BitbucketBuildTrigger extends Trigger> { String projectPath, String cron, String credentialsId, + String username, + String password, String repositoryOwner, String repositoryName, String ciSkipPhrases, @@ -58,6 +62,8 @@ public class BitbucketBuildTrigger extends Trigger> { this.projectPath = projectPath; this.cron = cron; this.credentialsId = credentialsId; + this.username = username; + this.password = password; this.repositoryOwner = repositoryOwner; this.repositoryName = repositoryName; this.ciSkipPhrases = ciSkipPhrases; @@ -77,6 +83,14 @@ public class BitbucketBuildTrigger extends Trigger> { return credentialsId; } + public String getUsername() { + return username; + } + + public String getPassword() { + return password; + } + public String getRepositoryOwner() { return repositoryOwner; } diff --git a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketRepository.java b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketRepository.java index 8606c45..fb43f12 100644 --- a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketRepository.java +++ b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketRepository.java @@ -45,10 +45,17 @@ public class BitbucketRepository { public void init() { trigger = this.builder.getTrigger(); + String username = trigger.getUsername(); + String password = trigger.getPassword(); StandardUsernamePasswordCredentials credentials = getCredentials(trigger.getCredentialsId()); + if (credentials != null) { + username = credentials.getUsername(); + password = credentials.getPassword().getPlainText(); + } + client = new ApiClient( - credentials.getUsername(), - credentials.getPassword().getPlainText(), + username, + password, trigger.getRepositoryOwner(), trigger.getRepositoryName()); } diff --git a/src/main/resources/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger/config.jelly b/src/main/resources/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger/config.jelly index df43e5a..db5ca0f 100644 --- a/src/main/resources/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger/config.jelly +++ b/src/main/resources/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger/config.jelly @@ -5,6 +5,12 @@ + + + + + + -- cgit v1.2.3 From 06eccb61d2aa83b9d3a7e94724a6d207011de2d4 Mon Sep 17 00:00:00 2001 From: Maxim Epishchev Date: Mon, 1 Feb 2016 18:21:01 +0300 Subject: Add tests for integration CredentialsSupport functional By default we using username/password from original text fields (config.jelly). If credentials ID provided in plugin settings - using them for BitBucket API auth. --- .../BitbucketRepository.java | 43 ++++-- .../bitbucket/ApiClient.java | 71 +++++++--- src/test/java/BitbucketBuildFilterTest.java | 30 +--- src/test/java/BitbucketBuildRepositoryTest.java | 153 +++++++++++++++++++++ 4 files changed, 234 insertions(+), 63 deletions(-) create mode 100644 src/test/java/BitbucketBuildRepositoryTest.java (limited to 'src') diff --git a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketRepository.java b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketRepository.java index d8c736e..23b0607 100644 --- a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketRepository.java +++ b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketRepository.java @@ -23,7 +23,7 @@ import jenkins.scm.api.SCMSourceOwner; import jenkins.scm.api.SCMSourceOwners; import org.apache.commons.lang.StringUtils; -static com.cloudbees.plugins.credentials.CredentialsMatchers.instanceOf; +import static com.cloudbees.plugins.credentials.CredentialsMatchers.instanceOf; /** * Created by nishio @@ -40,33 +40,46 @@ public class BitbucketRepository { private BitbucketPullRequestsBuilder builder; private BitbucketBuildTrigger trigger; private ApiClient client; - + public BitbucketRepository(String projectPath, BitbucketPullRequestsBuilder builder) { this.projectPath = projectPath; this.builder = builder; } public void init() { - this.init(null); + this.init(null, null); + } + + public void init(Class httpFactory) { + this.init(null, httpFactory); } public void init(ApiClient client) { + this.init(client, null); + } + + public void init(ApiClient client, Class httpFactory) { this.trigger = this.builder.getTrigger(); - String username = trigger.getUsername(); - String password = trigger.getPassword(); - StandardUsernamePasswordCredentials credentials = getCredentials(trigger.getCredentialsId()); - if (credentials != null) { - username = credentials.getUsername(); - password = credentials.getPassword().getPlainText(); - } - this.client = (client == null) ? new ApiClient( + + if (client == null) { + String username = trigger.getUsername(); + String password = trigger.getPassword(); + StandardUsernamePasswordCredentials credentials = getCredentials(trigger.getCredentialsId()); + if (credentials != null) { + username = credentials.getUsername(); + password = credentials.getPassword().getPlainText(); + } + this.client = new ApiClient( username, password, trigger.getRepositoryOwner(), trigger.getRepositoryName(), trigger.getCiKey(), - trigger.getCiName() - ) : client; + trigger.getCiName(), + httpFactory + ); + + } else this.client = client; } public Collection getTargetPullRequests() { @@ -80,6 +93,10 @@ public class BitbucketRepository { } return targetPullRequests; } + + public ApiClient getClient() { + return this.client; + } public void addFutureBuildTasks(Collection pullRequests) { for(Pullrequest pullRequest : pullRequests) { diff --git a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/bitbucket/ApiClient.java b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/bitbucket/ApiClient.java index e635f65..509dfaf 100644 --- a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/bitbucket/ApiClient.java +++ b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/bitbucket/ApiClient.java @@ -17,7 +17,6 @@ import java.util.logging.Logger; import jenkins.model.Jenkins; import hudson.ProxyConfiguration; import org.apache.commons.httpclient.methods.PutMethod; -import org.apache.commons.httpclient.params.HttpMethodParams; import org.apache.commons.httpclient.util.EncodingUtil; /** @@ -33,13 +32,55 @@ public class ApiClient { private Credentials credentials; private String key; private String name; - - public ApiClient(String username, String password, String owner, String repositoryName, String key, String name) { + private HttpClientFactory factory; + + public static class HttpClientFactory { + public static final HttpClientFactory INSTANCE = new HttpClientFactory(); + + public HttpClient getInstanceHttpClient() { + HttpClient client = new HttpClient(); + if (Jenkins.getInstance() == null) return client; + + ProxyConfiguration proxy = Jenkins.getInstance().proxy; + if (proxy == null) return client; + + logger.log(Level.INFO, "Jenkins proxy: {0}:{1}", new Object[]{ proxy.name, proxy.port }); + client.getHostConfiguration().setProxy(proxy.name, proxy.port); + String username = proxy.getUserName(); + String password = proxy.getPassword(); + + // Consider it to be passed if username specified. Sufficient? + if (username != null && !"".equals(username.trim())) { + logger.log(Level.INFO, "Using proxy authentication (user={0})", username); + client.getState().setProxyCredentials(AuthScope.ANY, + new UsernamePasswordCredentials(username, password)); + } + + return client; + } + } + + public ApiClient( + String username, String password, + String owner, String repositoryName, + String key, String name, + Class httpFactory + ) { this.credentials = new UsernamePasswordCredentials(username, password); this.owner = owner; this.repositoryName = repositoryName; this.key = key; this.name = name; + + try { + this.factory = (httpFactory != null) ? httpFactory.newInstance() : HttpClientFactory.INSTANCE; + } catch(InstantiationException e) { + logger.log(Level.WARNING, "failed new instance of {0}: {1} ", new Object[] { httpFactory.getName(), e }); + e.printStackTrace(); + } catch (IllegalAccessException e) { + logger.log(Level.WARNING, "failed new instance of {0}: {1} ", new Object[] { httpFactory.getName(), e }); + e.printStackTrace(); + } } public List getPullRequests() { @@ -47,6 +88,7 @@ public class ApiClient { return parse(get(v2("/pullrequests/")), Pullrequest.Response.class).getPullrequests(); } catch(Exception e) { logger.log(Level.WARNING, "invalid pull request response.", e); + e.printStackTrace(); } return Collections.EMPTY_LIST; } @@ -56,6 +98,7 @@ public class ApiClient { return parse(get(v1("/pullrequests/" + pullRequestId + "/comments")), new TypeReference>() {}); } catch(Exception e) { logger.log(Level.WARNING, "invalid pull request response.", e); + e.printStackTrace(); } return Collections.EMPTY_LIST; } @@ -112,6 +155,7 @@ public class ApiClient { return parse(post(v2("/pullrequests/" + pullRequestId + "/approve"), new NameValuePair[]{}), Pullrequest.Participant.class); } catch (IOException e) { + logger.log(Level.WARNING, "Invalid pull request approval response.", e); e.printStackTrace(); } return null; @@ -131,24 +175,7 @@ public class ApiClient { } private HttpClient getHttpClient() { - HttpClient client = new HttpClient(); - if (Jenkins.getInstance() == null) return client; - - ProxyConfiguration proxy = Jenkins.getInstance().proxy; - if (proxy == null) return client; - - logger.info("Jenkins proxy: " + proxy.name + ":" + proxy.port); - client.getHostConfiguration().setProxy(proxy.name, proxy.port); - String username = proxy.getUserName(); - String password = proxy.getPassword(); - - // Consider it to be passed if username specified. Sufficient? - if (username != null && !"".equals(username.trim())) { - logger.info("Using proxy authentication (user=" + username + ")"); - client.getState().setProxyCredentials(AuthScope.ANY, - new UsernamePasswordCredentials(username, password)); - } - return client; + return this.factory.getInstanceHttpClient(); } private String v1(String url) { @@ -193,8 +220,10 @@ public class ApiClient { client.executeMethod(req); return req.getResponseBodyAsString(); } catch (HttpException e) { + logger.log(Level.WARNING, "Failed to send request.", e); e.printStackTrace(); } catch (IOException e) { + logger.log(Level.WARNING, "Failed to send request.", e); e.printStackTrace(); } return null; diff --git a/src/test/java/BitbucketBuildFilterTest.java b/src/test/java/BitbucketBuildFilterTest.java index 0fabfe4..9b84e73 100644 --- a/src/test/java/BitbucketBuildFilterTest.java +++ b/src/test/java/BitbucketBuildFilterTest.java @@ -1,8 +1,3 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ import bitbucketpullrequestbuilder.bitbucketpullrequestbuilder.BitbucketBuildFilter; import bitbucketpullrequestbuilder.bitbucketpullrequestbuilder.BitbucketCause; @@ -10,9 +5,7 @@ import bitbucketpullrequestbuilder.bitbucketpullrequestbuilder.BitbucketPullRequ import bitbucketpullrequestbuilder.bitbucketpullrequestbuilder.BitbucketRepository; import bitbucketpullrequestbuilder.bitbucketpullrequestbuilder.bitbucket.ApiClient; import bitbucketpullrequestbuilder.bitbucketpullrequestbuilder.bitbucket.Pullrequest; -import java.util.Arrays; import java.util.Calendar; -import java.util.Collection; import java.util.LinkedList; import java.util.List; import java.util.regex.Pattern; @@ -25,8 +18,7 @@ import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.WithoutJenkins; /** - * - * @author maxvodo + * Tests */ public class BitbucketBuildFilterTest { @@ -288,24 +280,4 @@ public class BitbucketBuildFilterTest { for(Pullrequest.Comment comment : comments) assertFalse(repo.hasMyBuildTagInTTPComment(comment.getContent(), myBuildKey)); } - - //@Test - @WithoutJenkins - public void ttpCommentTest() { - ApiClient client = EasyMock.createNiceMock(ApiClient.class); - Collection> prs = new LinkedList>(); - - prs.add(Arrays.asList(new Pullrequest[] { - new Pullrequest() - })); - - for(List pr : prs) EasyMock.expect(client.getPullRequests()).andReturn(pr).times(1); - BitbucketPullRequestsBuilder builder = EasyMock.createMock(BitbucketPullRequestsBuilder.class); - EasyMock.replay(client, builder); - - BitbucketRepository repo = new BitbucketRepository("", builder); - repo.init(client); - - Collection targetPRs = repo.getTargetPullRequests(); - } } diff --git a/src/test/java/BitbucketBuildRepositoryTest.java b/src/test/java/BitbucketBuildRepositoryTest.java new file mode 100644 index 0000000..bb6de8f --- /dev/null +++ b/src/test/java/BitbucketBuildRepositoryTest.java @@ -0,0 +1,153 @@ + +import bitbucketpullrequestbuilder.bitbucketpullrequestbuilder.BitbucketBuildTrigger; +import bitbucketpullrequestbuilder.bitbucketpullrequestbuilder.BitbucketPullRequestsBuilder; +import bitbucketpullrequestbuilder.bitbucketpullrequestbuilder.BitbucketRepository; +import bitbucketpullrequestbuilder.bitbucketpullrequestbuilder.bitbucket.ApiClient; +import com.cloudbees.plugins.credentials.CredentialsProvider; +import com.cloudbees.plugins.credentials.CredentialsScope; +import com.cloudbees.plugins.credentials.CredentialsStore; +import com.cloudbees.plugins.credentials.domains.Domain; +import com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl; +import org.easymock.*; +import org.junit.Test; +import static org.junit.Assert.*; +import org.junit.Rule; +import org.jvnet.hudson.test.JenkinsRule; +import jenkins.model.Jenkins; +import org.apache.commons.httpclient.Credentials; +import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.HttpState; +import org.apache.commons.httpclient.UsernamePasswordCredentials; +import org.apache.commons.httpclient.auth.AuthScope; +import org.junit.Assert; + + +interface ICredentialsInterceptor { + void assertCredentials(Credentials actual); +} + +/** + * Utility class for interceptor functionality + * @param + */ +class HttpClientInterceptor extends HttpClient { + + class CredentialsInterceptor extends HttpState { + private final T interceptor; + public CredentialsInterceptor(T interceptor) { this.interceptor = interceptor; } + + @Override + public synchronized void setCredentials(AuthScope authscope, Credentials credentials) { + super.setCredentials(authscope, credentials); + this.interceptor.assertCredentials(credentials); + throw new AssertionError(); + } + } + + private final T interceptor; + public HttpClientInterceptor(T interceptor) { this.interceptor = interceptor; } + + @Override + public synchronized HttpState getState() { return new CredentialsInterceptor(this.interceptor); } +} + +/** + * Utility class for credentials assertion + * Used with + * @author maxvodo + */ +class AssertCredentials implements ICredentialsInterceptor { + private final Credentials expected; + public AssertCredentials(Credentials expected) { this.expected = expected; } + + public void assertCredentials(Credentials actual) { + if (actual == null) assertTrue(this.expected == null); + else assertTrue(this.expected != null); + + if (actual instanceof UsernamePasswordCredentials) { + UsernamePasswordCredentials actual_ = (UsernamePasswordCredentials)actual, + expected_ = (UsernamePasswordCredentials)this.expected; + assertNotNull(expected_); + Assert.assertArrayEquals(new Object[] { + actual_.getUserName(), actual_.getPassword() + }, new Object[] { + expected_.getUserName(), expected_.getPassword() + }); + } + } +} + +/** + * Tests + */ +public class BitbucketBuildRepositoryTest { + + @Rule + public JenkinsRule jRule = new JenkinsRule(); + + @Test + public void repositorySimpleUserPasswordTest() throws Exception { + BitbucketBuildTrigger trigger = new BitbucketBuildTrigger( + "", "@hourly", + "JenkinsCID", + "foo", + "bar", + "", "", + "", true, + "", "", "", + true, + true + ); + + BitbucketPullRequestsBuilder builder = EasyMock.createMock(BitbucketPullRequestsBuilder.class); + EasyMock.expect(builder.getTrigger()).andReturn(trigger).anyTimes(); + EasyMock.replay(builder); + + ApiClient.HttpClientFactory httpFactory = EasyMock.createMock(ApiClient.HttpClientFactory.class); + EasyMock.expect(httpFactory.getInstanceHttpClient()).andReturn( + new HttpClientInterceptor(new AssertCredentials(new UsernamePasswordCredentials("foo", "bar"))) + ).anyTimes(); + EasyMock.replay(httpFactory); + + BitbucketRepository repo = new BitbucketRepository("", builder); + repo.init(httpFactory.getClass()); + + try { repo.postPullRequestApproval("prId"); } catch(Error e) { assertTrue(e instanceof AssertionError); } + } + + @Test + public void repositoryCtorWithTriggerTest() throws Exception { + BitbucketBuildTrigger trigger = new BitbucketBuildTrigger( + "", "@hourly", + "JenkinsCID", + "foo", + "bar", + "", "", + "", true, + "", "", "", + true, + true + ); + + BitbucketPullRequestsBuilder builder = EasyMock.createMock(BitbucketPullRequestsBuilder.class); + EasyMock.expect(builder.getTrigger()).andReturn(trigger).anyTimes(); + EasyMock.replay(builder); + + CredentialsStore store = CredentialsProvider.lookupStores(Jenkins.getInstance()).iterator().next(); + assertNotNull(store); + store.addCredentials(Domain.global(), new UsernamePasswordCredentialsImpl( + CredentialsScope.GLOBAL, "JenkinsCID", "description", "username", "password" + )); + + ApiClient.HttpClientFactory httpFactory = EasyMock.createMock(ApiClient.HttpClientFactory.class); + EasyMock.expect(httpFactory.getInstanceHttpClient()).andReturn( + new HttpClientInterceptor(new AssertCredentials(new UsernamePasswordCredentials("username", "password"))) + ).anyTimes(); + EasyMock.replay(httpFactory); + + BitbucketRepository repo = new BitbucketRepository("", builder); + repo.init(httpFactory.getClass()); + + try { repo.postPullRequestApproval("prId"); } catch(Error e) { assertTrue(e instanceof AssertionError); } + } +} -- cgit v1.2.3 From 340c1c44bad78992ec49746d3776c3cff1a96fbd Mon Sep 17 00:00:00 2001 From: Maxim Epishchev Date: Wed, 3 Feb 2016 14:34:44 +0300 Subject: Limit size "key" field in BitBucket POST API Refactoring method ApiClient::computeAPIKey() to check maximum size of computed key. Now field size contolled by special constant ApiClient::MAX_KEY_SIZE_BB_API. This changes will resolve, in my opinion, issue with continuously rebuilding: method ApiClient::hasBuildStatus() fail and PR's are always trigger new builds. --- .../BitbucketPullRequestsBuilder.java | 17 ++- .../BitbucketRepository.java | 4 + .../bitbucket/ApiClient.java | 32 +++++- src/test/java/BitbucketBuildFilterTest.java | 9 +- src/test/java/BitbucketBuildRepositoryTest.java | 115 ++++++++++++++++++++- 5 files changed, 169 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketPullRequestsBuilder.java b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketPullRequestsBuilder.java index c5d4159..d337796 100644 --- a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketPullRequestsBuilder.java +++ b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketPullRequestsBuilder.java @@ -2,10 +2,15 @@ package bitbucketpullrequestbuilder.bitbucketpullrequestbuilder; import bitbucketpullrequestbuilder.bitbucketpullrequestbuilder.bitbucket.Pullrequest; import hudson.model.AbstractProject; + +import java.io.UnsupportedEncodingException; import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; import java.util.Collection; +import java.util.logging.Level; import java.util.logging.Logger; + import org.apache.commons.codec.binary.Hex; /** @@ -54,12 +59,20 @@ public class BitbucketPullRequestsBuilder { return this.project; } + /** + * Return MD5 hashed full project name or full project name, if MD5 hash provider inaccessible + * @return unique project id + */ public String getProjectId() { try { final MessageDigest MD5 = MessageDigest.getInstance("MD5"); return new String(Hex.encodeHex(MD5.digest(this.project.getFullName().getBytes("UTF-8")))); - } catch (Exception exc) { - logger.severe(exc.toString()); + } catch (NoSuchAlgorithmException exc) { + logger.log(Level.WARNING, "Failed to produce hash", exc); + exc.printStackTrace(); + } catch (UnsupportedEncodingException exc) { + logger.log(Level.WARNING, "Failed to produce hash", exc); + exc.printStackTrace(); } return this.project.getFullName(); } diff --git a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketRepository.java b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketRepository.java index 23b0607..8439eea 100644 --- a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketRepository.java +++ b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketRepository.java @@ -9,18 +9,22 @@ import java.util.logging.Logger; import bitbucketpullrequestbuilder.bitbucketpullrequestbuilder.bitbucket.ApiClient; import bitbucketpullrequestbuilder.bitbucketpullrequestbuilder.bitbucket.BuildState; import bitbucketpullrequestbuilder.bitbucketpullrequestbuilder.bitbucket.Pullrequest; + import java.util.LinkedList; import java.util.logging.Level; import java.util.regex.Matcher; import java.util.regex.Pattern; + import com.cloudbees.plugins.credentials.CredentialsMatchers; import com.cloudbees.plugins.credentials.CredentialsProvider; import com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials; import com.cloudbees.plugins.credentials.common.UsernamePasswordCredentials; + import jenkins.model.Jenkins; import jenkins.scm.api.SCMSource; import jenkins.scm.api.SCMSourceOwner; import jenkins.scm.api.SCMSourceOwners; + import org.apache.commons.lang.StringUtils; import static com.cloudbees.plugins.credentials.CredentialsMatchers.instanceOf; diff --git a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/bitbucket/ApiClient.java b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/bitbucket/ApiClient.java index 509dfaf..047bf5a 100644 --- a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/bitbucket/ApiClient.java +++ b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/bitbucket/ApiClient.java @@ -16,6 +16,11 @@ import java.util.logging.Logger; import jenkins.model.Jenkins; import hudson.ProxyConfiguration; + +import java.io.UnsupportedEncodingException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import org.apache.commons.codec.binary.Hex; import org.apache.commons.httpclient.methods.PutMethod; import org.apache.commons.httpclient.util.EncodingUtil; @@ -26,13 +31,15 @@ public class ApiClient { private static final Logger logger = Logger.getLogger(ApiClient.class.getName()); private static final String V1_API_BASE_URL = "https://bitbucket.org/api/1.0/repositories/"; private static final String V2_API_BASE_URL = "https://bitbucket.org/api/2.0/repositories/"; - private static final String COMPUTED_KEY_FORMAT = "%s-%s"; + private static final String COMPUTED_KEY_FORMAT = "%s-%s"; private String owner; private String repositoryName; private Credentials credentials; private String key; private String name; private HttpClientFactory factory; + + public static final byte MAX_KEY_SIZE_BB_API = 40; public static class HttpClientFactory { public static final HttpClientFactory INSTANCE = new HttpClientFactory(); @@ -107,8 +114,29 @@ public class ApiClient { return this.name; } + private static MessageDigest SHA1 = null; + + /** + * Retrun + * @param keyExPart + * @return key parameter for call BitBucket API + */ private String computeAPIKey(String keyExPart) { - return String.format(COMPUTED_KEY_FORMAT, this.key, keyExPart); + String computedKey = String.format(COMPUTED_KEY_FORMAT, this.key, keyExPart); + + if (computedKey.length() > MAX_KEY_SIZE_BB_API) { + try { + if (SHA1 == null) SHA1 = MessageDigest.getInstance("SHA1"); + return new String(Hex.encodeHex(SHA1.digest(computedKey.getBytes("UTF-8")))); + } catch(NoSuchAlgorithmException e) { + logger.log(Level.WARNING, "Failed to create hash provider", e); + e.printStackTrace(); + } catch (UnsupportedEncodingException e) { + logger.log(Level.WARNING, "Failed to create hash provider", e); + e.printStackTrace(); + } + } + return (computedKey.length() <= MAX_KEY_SIZE_BB_API) ? computedKey : computedKey.substring(0, MAX_KEY_SIZE_BB_API); } public String buildStatusKey(String bsKey) { diff --git a/src/test/java/BitbucketBuildFilterTest.java b/src/test/java/BitbucketBuildFilterTest.java index 9b84e73..3b35dbc 100644 --- a/src/test/java/BitbucketBuildFilterTest.java +++ b/src/test/java/BitbucketBuildFilterTest.java @@ -5,17 +5,20 @@ import bitbucketpullrequestbuilder.bitbucketpullrequestbuilder.BitbucketPullRequ import bitbucketpullrequestbuilder.bitbucketpullrequestbuilder.BitbucketRepository; import bitbucketpullrequestbuilder.bitbucketpullrequestbuilder.bitbucket.ApiClient; import bitbucketpullrequestbuilder.bitbucketpullrequestbuilder.bitbucket.Pullrequest; + import java.util.Calendar; import java.util.LinkedList; import java.util.List; import java.util.regex.Pattern; + import jenkins.plugins.git.AbstractGitSCMSource; +import org.jvnet.hudson.test.JenkinsRule; +import org.jvnet.hudson.test.WithoutJenkins; + import org.easymock.*; import org.junit.Test; -import static org.junit.Assert.*; import org.junit.Rule; -import org.jvnet.hudson.test.JenkinsRule; -import org.jvnet.hudson.test.WithoutJenkins; +import static org.junit.Assert.*; /** * Tests diff --git a/src/test/java/BitbucketBuildRepositoryTest.java b/src/test/java/BitbucketBuildRepositoryTest.java index bb6de8f..5f1aca2 100644 --- a/src/test/java/BitbucketBuildRepositoryTest.java +++ b/src/test/java/BitbucketBuildRepositoryTest.java @@ -1,25 +1,41 @@ +import antlr.ANTLRException; + import bitbucketpullrequestbuilder.bitbucketpullrequestbuilder.BitbucketBuildTrigger; import bitbucketpullrequestbuilder.bitbucketpullrequestbuilder.BitbucketPullRequestsBuilder; import bitbucketpullrequestbuilder.bitbucketpullrequestbuilder.BitbucketRepository; import bitbucketpullrequestbuilder.bitbucketpullrequestbuilder.bitbucket.ApiClient; + import com.cloudbees.plugins.credentials.CredentialsProvider; import com.cloudbees.plugins.credentials.CredentialsScope; import com.cloudbees.plugins.credentials.CredentialsStore; import com.cloudbees.plugins.credentials.domains.Domain; import com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl; + +import com.google.common.base.Function; +import com.google.common.collect.Collections2; + +import java.io.UnsupportedEncodingException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.Arrays; +import java.util.Collection; import org.easymock.*; import org.junit.Test; import static org.junit.Assert.*; import org.junit.Rule; +import org.junit.Assert; import org.jvnet.hudson.test.JenkinsRule; + import jenkins.model.Jenkins; +import org.jvnet.hudson.test.WithoutJenkins; + +import org.apache.commons.codec.binary.Hex; import org.apache.commons.httpclient.Credentials; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpState; import org.apache.commons.httpclient.UsernamePasswordCredentials; import org.apache.commons.httpclient.auth.AuthScope; -import org.junit.Assert; interface ICredentialsInterceptor { @@ -150,4 +166,101 @@ public class BitbucketBuildRepositoryTest { try { repo.postPullRequestApproval("prId"); } catch(Error e) { assertTrue(e instanceof AssertionError); } } + + class MD5HasherFunction implements Function { + protected final MessageDigest MD5; + public MD5HasherFunction(MessageDigest md5) { this.MD5 = md5; } + public String apply(String f) { + try { return new String(Hex.encodeHex(MD5.digest(f.getBytes("UTF-8")))); } catch(UnsupportedEncodingException e) { } + return null; + } + } + + class SHA1HasherFunction implements Function { + protected final MessageDigest SHA1; + public SHA1HasherFunction(MessageDigest sha1) { this.SHA1 = sha1; } + public String apply(String f) { + try { return new String(Hex.encodeHex(SHA1.digest(f.getBytes("UTF-8")))); } catch(UnsupportedEncodingException e) { } + return null; + } + } + + @Test + @WithoutJenkins + public void repositoryProjectIdTest() throws ANTLRException, NoSuchAlgorithmException, UnsupportedEncodingException { + BitbucketBuildTrigger trigger = new BitbucketBuildTrigger( + "", "@hourly", + "JenkinsCID", + "foo", + "bar", + "", "", + "", true, + "jenkins", "Jenkins", "", + true, + true + ); + + BitbucketPullRequestsBuilder builder = EasyMock.createMock(BitbucketPullRequestsBuilder.class); + EasyMock.expect(builder.getTrigger()).andReturn(trigger).anyTimes(); + + final MessageDigest MD5 = MessageDigest.getInstance("MD5"); + + String[] projectIds = new String[] { + "one", + "Second project", + "Project abstract 1.1", + "Good project, careated at " + (new java.util.Date()).toString(), + }; + + Collection hashedProjectIdsCollection = Collections2.transform(Arrays.asList(projectIds), new MD5HasherFunction(MD5)); + String[] hashedPojectIds = hashedProjectIdsCollection.toArray(new String[hashedProjectIdsCollection.size()]); + + for(String projectId : hashedPojectIds) { + EasyMock.expect(builder.getProjectId()).andReturn(projectId).times(1); + } + EasyMock.replay(builder); + + BitbucketRepository repo = new BitbucketRepository("", builder); + repo.init(); + + for(String projectId : projectIds) { + String hashMD5 = new String(Hex.encodeHex(MD5.digest(projectId.getBytes("UTF-8")))); + String buildStatusKey = repo.getClient().buildStatusKey(builder.getProjectId()); + + assertTrue(buildStatusKey.length() <= ApiClient.MAX_KEY_SIZE_BB_API); + assertEquals(buildStatusKey, "jenkins-" + hashMD5); + } + } + + @Test + @WithoutJenkins + public void triggerLongCIKeyTest() throws ANTLRException, NoSuchAlgorithmException { + BitbucketBuildTrigger trigger = new BitbucketBuildTrigger( + "", "@hourly", + "JenkinsCID", + "foo", + "bar", + "", "", + "", true, + "jenkins-too-long-ci-key", "Jenkins", "", + true, + true + ); + + final MessageDigest MD5 = MessageDigest.getInstance("MD5"); + final MessageDigest SHA1 = MessageDigest.getInstance("SHA1"); + + BitbucketPullRequestsBuilder builder = EasyMock.createMock(BitbucketPullRequestsBuilder.class); + EasyMock.expect(builder.getTrigger()).andReturn(trigger).anyTimes(); + EasyMock.expect(builder.getProjectId()).andReturn((new MD5HasherFunction(MD5)).apply("projectId")).anyTimes(); + EasyMock.replay(builder); + + BitbucketRepository repo = new BitbucketRepository("", builder); + repo.init(); + + String buildStatusKey = repo.getClient().buildStatusKey(builder.getProjectId()); + assertTrue(buildStatusKey.length() <= ApiClient.MAX_KEY_SIZE_BB_API); + assertFalse(buildStatusKey.startsWith("jenkins-")); + assertEquals((new SHA1HasherFunction(SHA1)).apply("jenkins-too-long-ci-key" + "-" + builder.getProjectId()), buildStatusKey); + } } -- cgit v1.2.3 From 4c667ab93e7e4fd57ac2b38a423447072d1606ed Mon Sep 17 00:00:00 2001 From: Maxim Epishchev Date: Thu, 4 Feb 2016 10:59:33 +0300 Subject: Allow default "none" credential in BitbucketRepository::getCredentials() Using by default only username and passwords fields to provide BitBucket auth cause NullReferenceException in BitbucketRepository::getCredentials(), because credentialsId is null. It's my fault :( --- .../bitbucketpullrequestbuilder/BitbucketRepository.java | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketRepository.java b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketRepository.java index 8439eea..3bc3928 100644 --- a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketRepository.java +++ b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketRepository.java @@ -303,6 +303,7 @@ public class BitbucketRepository { } private StandardUsernamePasswordCredentials getCredentials(String credentialsId) { + if (null == credentialsId) return null; return CredentialsMatchers .firstOrNull( CredentialsProvider.lookupCredentials(StandardUsernamePasswordCredentials.class), -- cgit v1.2.3 From 85a09f7392c50531365e89e94766a9caf3cac0f1 Mon Sep 17 00:00:00 2001 From: Maxim Epishchev Date: Thu, 4 Feb 2016 11:54:42 +0300 Subject: Remove overqualified using of Class as HttpClient interceptor Constructor of ApiClient now using just T type to make possible using of HttpClient interceptor in tests. --- .../bitbucketpullrequestbuilder/BitbucketRepository.java | 4 ++-- .../bitbucketpullrequestbuilder/bitbucket/ApiClient.java | 15 +++------------ src/test/java/BitbucketBuildRepositoryTest.java | 16 ++++++++++------ 3 files changed, 15 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketRepository.java b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketRepository.java index 3bc3928..9b92775 100644 --- a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketRepository.java +++ b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketRepository.java @@ -54,7 +54,7 @@ public class BitbucketRepository { this.init(null, null); } - public void init(Class httpFactory) { + public void init(T httpFactory) { this.init(null, httpFactory); } @@ -62,7 +62,7 @@ public class BitbucketRepository { this.init(client, null); } - public void init(ApiClient client, Class httpFactory) { + public void init(ApiClient client, T httpFactory) { this.trigger = this.builder.getTrigger(); if (client == null) { diff --git a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/bitbucket/ApiClient.java b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/bitbucket/ApiClient.java index 047bf5a..19bff34 100644 --- a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/bitbucket/ApiClient.java +++ b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/bitbucket/ApiClient.java @@ -71,23 +71,14 @@ public class ApiClient { String username, String password, String owner, String repositoryName, String key, String name, - Class httpFactory + T httpFactory ) { this.credentials = new UsernamePasswordCredentials(username, password); this.owner = owner; this.repositoryName = repositoryName; this.key = key; - this.name = name; - - try { - this.factory = (httpFactory != null) ? httpFactory.newInstance() : HttpClientFactory.INSTANCE; - } catch(InstantiationException e) { - logger.log(Level.WARNING, "failed new instance of {0}: {1} ", new Object[] { httpFactory.getName(), e }); - e.printStackTrace(); - } catch (IllegalAccessException e) { - logger.log(Level.WARNING, "failed new instance of {0}: {1} ", new Object[] { httpFactory.getName(), e }); - e.printStackTrace(); - } + this.name = name; + this.factory = httpFactory != null ? httpFactory : HttpClientFactory.INSTANCE; } public List getPullRequests() { diff --git a/src/test/java/BitbucketBuildRepositoryTest.java b/src/test/java/BitbucketBuildRepositoryTest.java index 5f1aca2..953bd81 100644 --- a/src/test/java/BitbucketBuildRepositoryTest.java +++ b/src/test/java/BitbucketBuildRepositoryTest.java @@ -20,6 +20,7 @@ import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Arrays; import java.util.Collection; +import java.util.logging.Logger; import org.easymock.*; import org.junit.Test; import static org.junit.Assert.*; @@ -47,6 +48,7 @@ interface ICredentialsInterceptor { * @param */ class HttpClientInterceptor extends HttpClient { + private static final Logger logger = Logger.getLogger(HttpClientInterceptor.class.getName()); class CredentialsInterceptor extends HttpState { private final T interceptor; @@ -54,6 +56,7 @@ class HttpClientInterceptor extends HttpClien @Override public synchronized void setCredentials(AuthScope authscope, Credentials credentials) { + logger.info("Inject setCredentials"); super.setCredentials(authscope, credentials); this.interceptor.assertCredentials(credentials); throw new AssertionError(); @@ -73,10 +76,13 @@ class HttpClientInterceptor extends HttpClien * @author maxvodo */ class AssertCredentials implements ICredentialsInterceptor { + private static final Logger logger = Logger.getLogger(AssertCredentials.class.getName()); + private final Credentials expected; public AssertCredentials(Credentials expected) { this.expected = expected; } public void assertCredentials(Credentials actual) { + logger.info("Assert credential"); if (actual == null) assertTrue(this.expected == null); else assertTrue(this.expected != null); @@ -119,14 +125,14 @@ public class BitbucketBuildRepositoryTest { EasyMock.expect(builder.getTrigger()).andReturn(trigger).anyTimes(); EasyMock.replay(builder); - ApiClient.HttpClientFactory httpFactory = EasyMock.createMock(ApiClient.HttpClientFactory.class); + ApiClient.HttpClientFactory httpFactory = EasyMock.createNiceMock(ApiClient.HttpClientFactory.class); EasyMock.expect(httpFactory.getInstanceHttpClient()).andReturn( new HttpClientInterceptor(new AssertCredentials(new UsernamePasswordCredentials("foo", "bar"))) ).anyTimes(); EasyMock.replay(httpFactory); BitbucketRepository repo = new BitbucketRepository("", builder); - repo.init(httpFactory.getClass()); + repo.init(httpFactory); try { repo.postPullRequestApproval("prId"); } catch(Error e) { assertTrue(e instanceof AssertionError); } } @@ -155,14 +161,14 @@ public class BitbucketBuildRepositoryTest { CredentialsScope.GLOBAL, "JenkinsCID", "description", "username", "password" )); - ApiClient.HttpClientFactory httpFactory = EasyMock.createMock(ApiClient.HttpClientFactory.class); + ApiClient.HttpClientFactory httpFactory = EasyMock.createNiceMock(ApiClient.HttpClientFactory.class); EasyMock.expect(httpFactory.getInstanceHttpClient()).andReturn( new HttpClientInterceptor(new AssertCredentials(new UsernamePasswordCredentials("username", "password"))) ).anyTimes(); EasyMock.replay(httpFactory); BitbucketRepository repo = new BitbucketRepository("", builder); - repo.init(httpFactory.getClass()); + repo.init(httpFactory); try { repo.postPullRequestApproval("prId"); } catch(Error e) { assertTrue(e instanceof AssertionError); } } @@ -186,7 +192,6 @@ public class BitbucketBuildRepositoryTest { } @Test - @WithoutJenkins public void repositoryProjectIdTest() throws ANTLRException, NoSuchAlgorithmException, UnsupportedEncodingException { BitbucketBuildTrigger trigger = new BitbucketBuildTrigger( "", "@hourly", @@ -233,7 +238,6 @@ public class BitbucketBuildRepositoryTest { } @Test - @WithoutJenkins public void triggerLongCIKeyTest() throws ANTLRException, NoSuchAlgorithmException { BitbucketBuildTrigger trigger = new BitbucketBuildTrigger( "", "@hourly", -- cgit v1.2.3