From c4a080e751cd6149602b8285e5f6f8361f36c9de Mon Sep 17 00:00:00 2001 From: Juha Siponen Date: Sat, 6 Aug 2016 20:39:22 +0300 Subject: [PATCH 1/7] Support for building every commit This basically works by holding back commits until GoCD can schedule them. This assumes that GoCD starts scheduling the given commits right after the plugin gives them to the server. This will prevent the case where GoCD is building one commit whichs takes long time to build. Meanwhile other commits would be given to GoCD and it would merge these commits. That would result some of the commits to be skipped. This is useful when using tools like Gerrit which should make GoCD to build every change set and report the result back to Gerrit. Without this feature GoCD will skip some changeset if the changeset are related to each other. This feature requires access to Go's pipeline API so that it can check if the pipeline can be scheduled. This will also require the pipeline to have only one stage. Otherwise GoCD (tested on versions 16.2, 16.6) may require manual triggering of the second stage even when pipeline isn't configured to behave like this. --- README.md | 2 + .../gocd/github/GitHubPRBuildPlugin.java | 85 ++++++++++++++++--- .../github/jsonapi/HttpConnectionUtil.java | 33 +++++++ .../gocd/github/jsonapi/PipelineStatus.java | 10 +++ .../gocd/github/jsonapi/Server.java | 71 ++++++++++++++++ .../gocd/github/jsonapi/ServerFactory.java | 10 +++ .../gerrit/GerritPluginConfigurationView.java | 30 +++++++ .../provider/gerrit/GerritProvider.java | 3 +- .../DefaultScmPluginConfigurationView.java | 1 + .../gocd/github/util/PluginSettings.java | 33 +++++++ src/main/resources/views/plugin.template.html | 15 ++++ .../views/scm.template.branch.filter.html | 5 ++ src/main/resources/views/scm.template.html | 5 ++ .../gocd/github/GitHubPRBuildPluginTest.java | 32 ++++++- .../provider/gerrit/GerritProviderTest.java | 18 +++- .../github/provider/git/GitProviderTest.java | 12 ++- .../provider/github/GitHubProviderTest.java | 11 ++- .../provider/stash/StashProviderTest.java | 11 ++- 18 files changed, 360 insertions(+), 27 deletions(-) create mode 100644 src/main/java/in/ashwanthkumar/gocd/github/jsonapi/HttpConnectionUtil.java create mode 100644 src/main/java/in/ashwanthkumar/gocd/github/jsonapi/PipelineStatus.java create mode 100644 src/main/java/in/ashwanthkumar/gocd/github/jsonapi/Server.java create mode 100644 src/main/java/in/ashwanthkumar/gocd/github/jsonapi/ServerFactory.java create mode 100644 src/main/java/in/ashwanthkumar/gocd/github/provider/gerrit/GerritPluginConfigurationView.java create mode 100644 src/main/resources/views/plugin.template.html diff --git a/README.md b/README.md index 2338fb1..91691d7 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,8 @@ These plugins require GoCD version v15.x or above. - Build status notifier plugin will update Pull Request with build status ![On successful run of new pipeline][13] +- In order to force GoCD to build every commit the pipeline name has be defined for the material. + ### Github **Authentication:** diff --git a/src/main/java/in/ashwanthkumar/gocd/github/GitHubPRBuildPlugin.java b/src/main/java/in/ashwanthkumar/gocd/github/GitHubPRBuildPlugin.java index 867ef7f..37fdcd3 100644 --- a/src/main/java/in/ashwanthkumar/gocd/github/GitHubPRBuildPlugin.java +++ b/src/main/java/in/ashwanthkumar/gocd/github/GitHubPRBuildPlugin.java @@ -5,6 +5,7 @@ import com.thoughtworks.go.plugin.api.GoPluginIdentifier; import com.thoughtworks.go.plugin.api.annotation.Extension; import com.thoughtworks.go.plugin.api.logging.Logger; +import com.thoughtworks.go.plugin.api.request.DefaultGoApiRequest; import com.thoughtworks.go.plugin.api.request.GoPluginApiRequest; import com.thoughtworks.go.plugin.api.response.GoPluginApiResponse; import com.tw.go.plugin.GitHelper; @@ -13,12 +14,13 @@ import com.tw.go.plugin.model.Revision; import com.tw.go.plugin.util.ListUtil; import com.tw.go.plugin.util.StringUtil; +import in.ashwanthkumar.gocd.github.jsonapi.PipelineStatus; +import in.ashwanthkumar.gocd.github.jsonapi.Server; +import in.ashwanthkumar.gocd.github.jsonapi.ServerFactory; import in.ashwanthkumar.gocd.github.provider.Provider; import in.ashwanthkumar.gocd.github.settings.scm.PluginConfigurationView; -import in.ashwanthkumar.gocd.github.util.BranchFilter; -import in.ashwanthkumar.gocd.github.util.GitFactory; -import in.ashwanthkumar.gocd.github.util.GitFolderFactory; -import in.ashwanthkumar.gocd.github.util.JSONUtils; +import in.ashwanthkumar.gocd.github.util.*; +import in.ashwanthkumar.utils.lang.option.Option; import org.apache.commons.io.IOUtils; import java.io.IOException; @@ -31,6 +33,7 @@ @Extension public class GitHubPRBuildPlugin implements GoPlugin { + private static Logger LOGGER = Logger.getLoggerFor(GitHubPRBuildPlugin.class); public static final String EXTENSION_NAME = "scm"; @@ -61,6 +64,7 @@ public class GitHubPRBuildPlugin implements GoPlugin { private GitFactory gitFactory; private GitFolderFactory gitFolderFactory; private GoApplicationAccessor goApplicationAccessor; + private ServerFactory serverFactory; public GitHubPRBuildPlugin() { try { @@ -72,15 +76,17 @@ public GitHubPRBuildPlugin() { provider = (Provider) constructor.newInstance(); gitFactory = new GitFactory(); gitFolderFactory = new GitFolderFactory(); + serverFactory = new ServerFactory(); } catch (Exception e) { throw new RuntimeException("could not create provider", e); } } - public GitHubPRBuildPlugin(Provider provider, GitFactory gitFactory, GitFolderFactory gitFolderFactory, GoApplicationAccessor goApplicationAccessor) { + public GitHubPRBuildPlugin(Provider provider, GitFactory gitFactory, GitFolderFactory gitFolderFactory, ServerFactory serverFactory, GoApplicationAccessor goApplicationAccessor) { this.provider = provider; this.gitFactory = gitFactory; this.gitFolderFactory = gitFolderFactory; + this.serverFactory = serverFactory; this.goApplicationAccessor = goApplicationAccessor; } @@ -238,6 +244,7 @@ GoPluginApiResponse handleLatestRevisionSince(GoPluginApiRequest goPluginApiRequ Map oldBranchToRevisionMap = (Map) fromJSON(scmData.get(BRANCH_TO_REVISION_MAP)); String flyweightFolder = (String) requestBodyMap.get("flyweight-folder"); LOGGER.debug(String.format("Fetching latest for: %s", gitConfig.getUrl())); + Option pipelineName = Option.option(configuration.get("pipeline_name")); try { GitHelper git = gitFactory.create(gitConfig, gitFolderFactory.create(flyweightFolder)); @@ -258,6 +265,7 @@ GoPluginApiResponse handleLatestRevisionSince(GoPluginApiRequest goPluginApiRequ BranchFilter branchFilter = provider .getScmConfigurationView() .getBranchFilter(configuration); + Server server = serverFactory.getServer(getPluginSettings()); for (String branch : newBranchToRevisionMap.keySet()) { if (branchFilter.isBranchValid(branch)) { @@ -266,18 +274,40 @@ GoPluginApiResponse handleLatestRevisionSince(GoPluginApiRequest goPluginApiRequ // Otherwise Go.CD skips other changes (revisions) in this call. // You can think about it like if we always return a minimum item // of a set with comparable items. - String newValue = newBranchToRevisionMap.get(branch); - newerRevisions.put(branch, newValue); - oldBranchToRevisionMap.put(branch, newValue); - break; + + // Only schedule new revision if the pipeline doesn't have + // anything running at the moment. This should further prevent + // skipping revisions when the revisions are built in-order + // This is only checked if the pipeline name option is given + if (canSchedule(server, pipelineName)) { + String newValue = newBranchToRevisionMap.get(branch); + + LOGGER.debug("Schedule pipeline for branch " + branch + "@" + newValue); + + newerRevisions.put(branch, newValue); + oldBranchToRevisionMap.put(branch, newValue); + break; + } else { + // If can't schedule yet, just skip this round + // and return the old branches to revision map + // back so that we can continue where we left + // on the next round of polling for changes + + LOGGER.info("Schedule " + branch + " later"); + + Map response = new HashMap(); + Map scmDataMap = new HashMap(); + scmDataMap.put(BRANCH_TO_REVISION_MAP, JSONUtils.toJSON(oldBranchToRevisionMap)); + response.put("scm-data", scmDataMap); + return renderJSON(SUCCESS_RESPONSE_CODE, response); + } } - } else { - LOGGER.debug(String.format("Branch %s is filtered by branch matcher", branch)); } } if (newerRevisions.isEmpty()) { - LOGGER.debug(String.format("No updated PRs found. Old: %s New: %s", oldBranchToRevisionMap, newBranchToRevisionMap)); + LOGGER.debug("No updated PRs found."); + LOGGER.debug(String.format("Old: %s New: %s", oldBranchToRevisionMap, newBranchToRevisionMap)); Map response = new HashMap(); Map scmDataMap = new HashMap(); @@ -313,6 +343,24 @@ GoPluginApiResponse handleLatestRevisionSince(GoPluginApiRequest goPluginApiRequ } } + private boolean canSchedule(Server server, Option pipelineName) throws IOException { + if (pipelineName.isEmpty()) { + LOGGER.debug("Pipeline name not given. Can schedule"); + return true; + } + + LOGGER.info(String.format("Check can schedule pipeline %s", pipelineName.get())); + + PipelineStatus pipelineStatus = server.getPipelineStatus(pipelineName.get()); + if (pipelineStatus != null) { + LOGGER.info(String.format(" Pipeline schedulable: %s", pipelineStatus.schedulable)); + return pipelineStatus.schedulable; + } else { + LOGGER.debug(" Could not fetch pipeline status. Allow to schedule"); + return true; + } + } + private boolean branchHasNewChange(String previousSHA, String latestSHA) { return previousSHA == null || !previousSHA.equals(latestSHA); } @@ -440,4 +488,17 @@ public String responseBody() { }; } + public PluginSettings getPluginSettings() { + DefaultGoApiRequest request = + new DefaultGoApiRequest(GET_PLUGIN_SETTINGS, "1.0", provider.getPluginId()); + request.setRequestBody("{\"plugin-id\": \"" + provider.getPluginId().getExtension() + "\"}"); + String response = goApplicationAccessor.submit(request).responseBody(); + Map settings = JSONUtils.fromJSON(response, Map.class); + + return new PluginSettings( + (String)settings.get("go_api_host"), + (String)settings.get("go_api_username"), + (String)settings.get("go_api_password") + ); + } } diff --git a/src/main/java/in/ashwanthkumar/gocd/github/jsonapi/HttpConnectionUtil.java b/src/main/java/in/ashwanthkumar/gocd/github/jsonapi/HttpConnectionUtil.java new file mode 100644 index 0000000..8297552 --- /dev/null +++ b/src/main/java/in/ashwanthkumar/gocd/github/jsonapi/HttpConnectionUtil.java @@ -0,0 +1,33 @@ +package in.ashwanthkumar.gocd.github.jsonapi; + +import com.google.gson.GsonBuilder; +import com.google.gson.JsonElement; +import com.google.gson.JsonParser; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; + +public class HttpConnectionUtil { + + public HttpURLConnection getConnection(URL url) throws IOException { + return (HttpURLConnection) url.openConnection(); + } + + JsonElement responseToJson(Object content) { + JsonParser parser = new JsonParser(); + return parser.parse(new InputStreamReader((InputStream) content)); + } + + T convertResponse(JsonElement json, Class type) { + return new GsonBuilder().create().fromJson(json, type); + } + + public T responseToType(Object content, Class type) { + JsonElement element = responseToJson(content); + return convertResponse(element, type); + } + +} diff --git a/src/main/java/in/ashwanthkumar/gocd/github/jsonapi/PipelineStatus.java b/src/main/java/in/ashwanthkumar/gocd/github/jsonapi/PipelineStatus.java new file mode 100644 index 0000000..94541c9 --- /dev/null +++ b/src/main/java/in/ashwanthkumar/gocd/github/jsonapi/PipelineStatus.java @@ -0,0 +1,10 @@ +package in.ashwanthkumar.gocd.github.jsonapi; + +import com.google.gson.annotations.SerializedName; + +public class PipelineStatus { + + @SerializedName("schedulable") + public boolean schedulable; + +} diff --git a/src/main/java/in/ashwanthkumar/gocd/github/jsonapi/Server.java b/src/main/java/in/ashwanthkumar/gocd/github/jsonapi/Server.java new file mode 100644 index 0000000..fa9b182 --- /dev/null +++ b/src/main/java/in/ashwanthkumar/gocd/github/jsonapi/Server.java @@ -0,0 +1,71 @@ +package in.ashwanthkumar.gocd.github.jsonapi; + +import com.thoughtworks.go.plugin.api.logging.Logger; +import in.ashwanthkumar.gocd.github.util.PluginSettings; + +import javax.xml.bind.DatatypeConverter; +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URISyntaxException; +import java.net.URL; + +import static in.ashwanthkumar.utils.lang.StringUtils.isEmpty; + +public class Server { + private Logger LOG = Logger.getLoggerFor(Server.class); + + private PluginSettings settings; + private HttpConnectionUtil httpConnectionUtil; + + /** + * Construct a new server object, using credentials from PluginSettings. + */ + public Server(PluginSettings settings) { + this.settings = settings; + httpConnectionUtil = new HttpConnectionUtil(); + } + + Server(PluginSettings settings, HttpConnectionUtil httpConnectionUtil) { + this.settings = settings; + this.httpConnectionUtil = httpConnectionUtil; + } + + public T getResourceAs(URL url, Class type) + throws IOException { + URL normalizedUrl; + try { + normalizedUrl = url.toURI().normalize().toURL(); + } catch (URISyntaxException e) { + throw new RuntimeException(e); + } + LOG.info("Fetching " + normalizedUrl.toString()); + + HttpURLConnection request = httpConnectionUtil.getConnection(normalizedUrl); + + final String login = settings.getGoUsername(); + final String password = settings.getGoPassword(); + // Add in our HTTP authorization credentials if we have them. + if (!isEmpty(login) && !isEmpty(password)) { + String userpass = login + ":" + password; + String basicAuth = "Basic " + + DatatypeConverter.printBase64Binary(userpass.getBytes()); + request.setRequestProperty("Authorization", basicAuth); + } + + request.connect(); + + return httpConnectionUtil.responseToType(request.getContent(), type); + } + + public PipelineStatus getPipelineStatus(String pipelineName) + throws MalformedURLException, IOException { + final String apiHost = settings.getGoApiHost(); + URL url = new URL(String.format("%s/go/api/pipelines/%s/status", + apiHost, pipelineName)); + + LOG.info(String.format("Fetch pipeline %s status from %s", pipelineName, url)); + return getResourceAs(url, PipelineStatus.class); + } + +} diff --git a/src/main/java/in/ashwanthkumar/gocd/github/jsonapi/ServerFactory.java b/src/main/java/in/ashwanthkumar/gocd/github/jsonapi/ServerFactory.java new file mode 100644 index 0000000..e39a215 --- /dev/null +++ b/src/main/java/in/ashwanthkumar/gocd/github/jsonapi/ServerFactory.java @@ -0,0 +1,10 @@ +package in.ashwanthkumar.gocd.github.jsonapi; + +import in.ashwanthkumar.gocd.github.util.PluginSettings; + +public class ServerFactory { + + public Server getServer(PluginSettings settings) { + return new Server(settings); + } +} diff --git a/src/main/java/in/ashwanthkumar/gocd/github/provider/gerrit/GerritPluginConfigurationView.java b/src/main/java/in/ashwanthkumar/gocd/github/provider/gerrit/GerritPluginConfigurationView.java new file mode 100644 index 0000000..cd9f4f4 --- /dev/null +++ b/src/main/java/in/ashwanthkumar/gocd/github/provider/gerrit/GerritPluginConfigurationView.java @@ -0,0 +1,30 @@ +package in.ashwanthkumar.gocd.github.provider.gerrit; + +import in.ashwanthkumar.gocd.github.settings.general.GeneralPluginConfigurationView; +import in.ashwanthkumar.gocd.github.util.FieldFactory; + +import java.util.HashMap; +import java.util.Map; + +public class GerritPluginConfigurationView implements GeneralPluginConfigurationView { + + + @Override + public String templateName() { + return "/views/plugin.template.html"; + } + + @Override + public Map fields() { + Map response = new HashMap(); + response.put("go_api_host", FieldFactory.createForGeneral("Go API Host", null, false, false, "0")); + response.put("go_api_username", FieldFactory.createForGeneral("Go Username", null, false, false, "1")); + response.put("go_api_password", FieldFactory.createForGeneral("Go Password", null, false, true, "2")); + return response; + } + + @Override + public boolean hasConfigurationView() { + return true; + } +} diff --git a/src/main/java/in/ashwanthkumar/gocd/github/provider/gerrit/GerritProvider.java b/src/main/java/in/ashwanthkumar/gocd/github/provider/gerrit/GerritProvider.java index 0040cbb..f97e8bf 100644 --- a/src/main/java/in/ashwanthkumar/gocd/github/provider/gerrit/GerritProvider.java +++ b/src/main/java/in/ashwanthkumar/gocd/github/provider/gerrit/GerritProvider.java @@ -4,7 +4,6 @@ import com.tw.go.plugin.HelperFactory; import com.tw.go.plugin.model.GitConfig; import in.ashwanthkumar.gocd.github.provider.Provider; -import in.ashwanthkumar.gocd.github.settings.general.DefaultGeneralPluginConfigurationView; import in.ashwanthkumar.gocd.github.settings.general.GeneralPluginConfigurationView; import in.ashwanthkumar.gocd.github.settings.scm.DefaultScmPluginConfigurationView; import in.ashwanthkumar.gocd.github.settings.scm.ScmPluginConfigurationView; @@ -63,6 +62,6 @@ public ScmPluginConfigurationView getScmConfigurationView() { @Override public GeneralPluginConfigurationView getGeneralConfigurationView() { - return new DefaultGeneralPluginConfigurationView(); + return new GerritPluginConfigurationView(); } } diff --git a/src/main/java/in/ashwanthkumar/gocd/github/settings/scm/DefaultScmPluginConfigurationView.java b/src/main/java/in/ashwanthkumar/gocd/github/settings/scm/DefaultScmPluginConfigurationView.java index b4f4f8b..49cba14 100644 --- a/src/main/java/in/ashwanthkumar/gocd/github/settings/scm/DefaultScmPluginConfigurationView.java +++ b/src/main/java/in/ashwanthkumar/gocd/github/settings/scm/DefaultScmPluginConfigurationView.java @@ -20,6 +20,7 @@ public Map fields() { response.put("url", FieldFactory.createForScm("URL", null, true, true, false, "0")); response.put("username", FieldFactory.createForScm("Username", null, false, false, false, "1")); response.put("password", FieldFactory.createForScm("Password", null, false, false, true, "2")); + response.put("pipeline_name", FieldFactory.createForScm("Pipeline name", null, false, false, false, "3")); return response; } diff --git a/src/main/java/in/ashwanthkumar/gocd/github/util/PluginSettings.java b/src/main/java/in/ashwanthkumar/gocd/github/util/PluginSettings.java index a3318a2..2f07260 100644 --- a/src/main/java/in/ashwanthkumar/gocd/github/util/PluginSettings.java +++ b/src/main/java/in/ashwanthkumar/gocd/github/util/PluginSettings.java @@ -2,7 +2,40 @@ public class PluginSettings { + private String goApiHost; + private String goUsername; + private String goPassword; + public PluginSettings() { } + public PluginSettings(String goApiHost, String goUsername, String goPassword) { + this.goUsername = goUsername; + this.goPassword = goPassword; + this.goApiHost = goApiHost; + } + + public String getGoUsername() { + return goUsername; + } + + public void setGoUsername(String goUsername) { + this.goUsername = goUsername; + } + + public String getGoPassword() { + return goPassword; + } + + public void setGoPassword(String goPassword) { + this.goPassword = goPassword; + } + + public String getGoApiHost() { + return goApiHost; + } + + public void setGoApiHost(String goApiHost) { + this.goApiHost = goApiHost; + } } diff --git a/src/main/resources/views/plugin.template.html b/src/main/resources/views/plugin.template.html new file mode 100644 index 0000000..0f27c9e --- /dev/null +++ b/src/main/resources/views/plugin.template.html @@ -0,0 +1,15 @@ +
+ + + {{ GOINPUTNAME[go_api_host].$error.server }} +
+
+ + + {{ GOINPUTNAME[go_api_username].$error.server }} +
+
+ + + {{ GOINPUTNAME[go_api_password].$error.server }} +
diff --git a/src/main/resources/views/scm.template.branch.filter.html b/src/main/resources/views/scm.template.branch.filter.html index e1bc3da..96ccaf4 100644 --- a/src/main/resources/views/scm.template.branch.filter.html +++ b/src/main/resources/views/scm.template.branch.filter.html @@ -13,6 +13,11 @@ {{ GOINPUTNAME[password].$error.server }} +
+ + + {{ GOINPUTNAME[pipeline_name].$error.server }} +
diff --git a/src/main/resources/views/scm.template.html b/src/main/resources/views/scm.template.html index 14bab45..6b937a7 100644 --- a/src/main/resources/views/scm.template.html +++ b/src/main/resources/views/scm.template.html @@ -12,4 +12,9 @@ {{ GOINPUTNAME[password].$error.server }} +
+
+ + + {{ GOINPUTNAME[pipeline_name].$error.server }}
\ No newline at end of file diff --git a/src/test/java/in/ashwanthkumar/gocd/github/GitHubPRBuildPluginTest.java b/src/test/java/in/ashwanthkumar/gocd/github/GitHubPRBuildPluginTest.java index 48377f8..6c82072 100644 --- a/src/test/java/in/ashwanthkumar/gocd/github/GitHubPRBuildPluginTest.java +++ b/src/test/java/in/ashwanthkumar/gocd/github/GitHubPRBuildPluginTest.java @@ -10,6 +10,9 @@ import com.tw.go.plugin.model.GitConfig; import com.tw.go.plugin.model.ModifiedFile; import com.tw.go.plugin.model.Revision; +import in.ashwanthkumar.gocd.github.jsonapi.PipelineStatus; +import in.ashwanthkumar.gocd.github.jsonapi.Server; +import in.ashwanthkumar.gocd.github.jsonapi.ServerFactory; import in.ashwanthkumar.gocd.github.provider.gerrit.GerritProvider; import in.ashwanthkumar.gocd.github.provider.git.GitProvider; import in.ashwanthkumar.gocd.github.provider.github.GHUtils; @@ -17,6 +20,7 @@ import in.ashwanthkumar.gocd.github.util.GitFactory; import in.ashwanthkumar.gocd.github.util.GitFolderFactory; import in.ashwanthkumar.gocd.github.util.JSONUtils; +import in.ashwanthkumar.gocd.github.util.PluginSettings; import org.apache.commons.io.FileUtils; import org.junit.After; import org.junit.Before; @@ -180,13 +184,14 @@ public void shouldParseJSONMapCorrectly() { } @Test - public void shouldBuildWhitelistedBranch() { + public void shouldBuildWhitelistedBranch() throws Exception { GitFactory gitFactory = mock(GitFactory.class); GitFolderFactory gitFolderFactory = mock(GitFolderFactory.class); GitHubPRBuildPlugin plugin = new GitHubPRBuildPlugin( new GitProvider(), gitFactory, gitFolderFactory, + mockServerFactory(), mockGoApplicationAccessor() ); GitHubPRBuildPlugin pluginSpy = spy(plugin); @@ -202,13 +207,14 @@ public void shouldBuildWhitelistedBranch() { } @Test - public void shouldNotBuildBlacklistedBranch() { + public void shouldNotBuildBlacklistedBranch() throws Exception { GitFactory gitFactory = mock(GitFactory.class); GitFolderFactory gitFolderFactory = mock(GitFolderFactory.class); GitHubPRBuildPlugin plugin = new GitHubPRBuildPlugin( new GitProvider(), gitFactory, gitFolderFactory, + mockServerFactory(), mockGoApplicationAccessor() ); GitHubPRBuildPlugin pluginSpy = spy(plugin); @@ -224,13 +230,14 @@ public void shouldNotBuildBlacklistedBranch() { } @Test - public void shouldBuildBlacklistedBranchIfBlacklistingNotEnabled() { + public void shouldBuildBlacklistedBranchIfBlacklistingNotEnabled() throws Exception { GitFactory gitFactory = mock(GitFactory.class); GitFolderFactory gitFolderFactory = mock(GitFolderFactory.class); GitHubPRBuildPlugin plugin = new GitHubPRBuildPlugin( new GerritProvider(), gitFactory, gitFolderFactory, + mockServerFactory(), mockGoApplicationAccessor() ); GitHubPRBuildPlugin pluginSpy = spy(plugin); @@ -325,6 +332,25 @@ private void verifyResponse(String responseBody, List pairs) { } } + private ServerFactory mockServerFactory() throws Exception { + ServerFactory serverFactory = mock(ServerFactory.class); + Server server = mock(Server.class); + PipelineStatus status = new PipelineStatus(); + status.schedulable = true; + when(server.getPipelineStatus(anyString())).thenReturn(status); + + when(serverFactory.getServer(any(PluginSettings.class))).thenReturn(server); + return serverFactory; + } + + private GoApplicationAccessor mockApplicationAccessor() { + GoApplicationAccessor accessor = mock(GoApplicationAccessor.class); + DefaultGoApiResponse respose = new DefaultGoApiResponse(200); + respose.setResponseBody("{}"); + when(accessor.submit(any(GoApiRequest.class))).thenReturn(respose); + return accessor; + } + private GoPluginApiRequest createGoPluginApiRequest(final String requestName, final Map request) { return new GoPluginApiRequest() { @Override diff --git a/src/test/java/in/ashwanthkumar/gocd/github/provider/gerrit/GerritProviderTest.java b/src/test/java/in/ashwanthkumar/gocd/github/provider/gerrit/GerritProviderTest.java index 23c3258..535bfeb 100644 --- a/src/test/java/in/ashwanthkumar/gocd/github/provider/gerrit/GerritProviderTest.java +++ b/src/test/java/in/ashwanthkumar/gocd/github/provider/gerrit/GerritProviderTest.java @@ -23,17 +23,27 @@ public void shouldReturnCorrectScmSettingsFields() throws Exception { PluginConfigurationView scmConfigurationView = getScmView(); assertThat(scmConfigurationView.fields().keySet(), - hasItems("url", "username", "password") + hasItems("url", "username", "password", "pipeline_name") ); - assertThat(scmConfigurationView.fields().size(), is(3)); + assertThat(scmConfigurationView.fields().size(), is(4)); } @Test public void shouldReturnCorrectGeneralSettingsTemplate() throws Exception { PluginConfigurationView generalConfigurationView = getGeneralView(); - assertThat(generalConfigurationView.templateName(), is("")); - assertThat(generalConfigurationView.hasConfigurationView(), is(false)); + assertThat(generalConfigurationView.templateName(), is("/views/plugin.template.html")); + assertThat(generalConfigurationView.hasConfigurationView(), is(true)); + } + + @Test + public void shouldReturnCorrectGeneralSettingsFields() throws Exception { + PluginConfigurationView generalConfigurationView = getGeneralView(); + + assertThat(generalConfigurationView.fields().keySet(), + hasItems("go_api_host", "go_api_username", "go_api_password") + ); + assertThat(generalConfigurationView.fields().size(), is(3)); } @Override diff --git a/src/test/java/in/ashwanthkumar/gocd/github/provider/git/GitProviderTest.java b/src/test/java/in/ashwanthkumar/gocd/github/provider/git/GitProviderTest.java index e73a2b1..457eec2 100644 --- a/src/test/java/in/ashwanthkumar/gocd/github/provider/git/GitProviderTest.java +++ b/src/test/java/in/ashwanthkumar/gocd/github/provider/git/GitProviderTest.java @@ -23,9 +23,9 @@ public void shouldReturnCorrectScmSettingsFields() throws Exception { PluginConfigurationView scmConfigurationView = getScmView(); assertThat(scmConfigurationView.fields().keySet(), - hasItems("url", "username", "password", "branchwhitelist", "branchblacklist") + hasItems("url", "username", "password", "pipeline_name", "branchwhitelist", "branchblacklist") ); - assertThat(scmConfigurationView.fields().size(), is(5)); + assertThat(scmConfigurationView.fields().size(), is(6)); } @Test @@ -36,6 +36,14 @@ public void shouldReturnCorrectGeneralSettingsTemplate() throws Exception { assertThat(generalConfigurationView.hasConfigurationView(), is(false)); } + @Test + public void shouldReturnCorrectGeneralSettingsFields() throws Exception { + PluginConfigurationView generalConfigurationView = getGeneralView(); + + assertThat(generalConfigurationView.fields().size(), is(0)); + + } + @Override protected Provider getProvider() { return new GitProvider(); diff --git a/src/test/java/in/ashwanthkumar/gocd/github/provider/github/GitHubProviderTest.java b/src/test/java/in/ashwanthkumar/gocd/github/provider/github/GitHubProviderTest.java index d680c29..0be5d92 100644 --- a/src/test/java/in/ashwanthkumar/gocd/github/provider/github/GitHubProviderTest.java +++ b/src/test/java/in/ashwanthkumar/gocd/github/provider/github/GitHubProviderTest.java @@ -23,9 +23,9 @@ public void shouldReturnCorrectScmSettingsFields() throws Exception { PluginConfigurationView scmConfigurationView = getScmView(); assertThat(scmConfigurationView.fields().keySet(), - hasItems("url", "username", "password") + hasItems("url", "username", "password", "pipeline_name") ); - assertThat(scmConfigurationView.fields().size(), is(3)); + assertThat(scmConfigurationView.fields().size(), is(4)); } @Test @@ -36,6 +36,13 @@ public void shouldReturnCorrectGeneralSettingsTemplate() throws Exception { assertThat(generalConfigurationView.hasConfigurationView(), is(false)); } + @Test + public void shouldReturnCorrectGeneralSettingsFields() throws Exception { + PluginConfigurationView generalConfigurationView = getGeneralView(); + + assertThat(generalConfigurationView.fields().size(), is(0)); + } + @Override protected Provider getProvider() { return new GitHubProvider(); diff --git a/src/test/java/in/ashwanthkumar/gocd/github/provider/stash/StashProviderTest.java b/src/test/java/in/ashwanthkumar/gocd/github/provider/stash/StashProviderTest.java index b16d2e9..89fbfac 100644 --- a/src/test/java/in/ashwanthkumar/gocd/github/provider/stash/StashProviderTest.java +++ b/src/test/java/in/ashwanthkumar/gocd/github/provider/stash/StashProviderTest.java @@ -23,9 +23,9 @@ public void shouldReturnCorrectScmSettingsFields() throws Exception { PluginConfigurationView scmConfigurationView = getScmView(); assertThat(scmConfigurationView.fields().keySet(), - hasItems("url", "username", "password") + hasItems("url", "username", "password", "pipeline_name") ); - assertThat(scmConfigurationView.fields().size(), is(3)); + assertThat(scmConfigurationView.fields().size(), is(4)); } @Test @@ -36,6 +36,13 @@ public void shouldReturnCorrectGeneralSettingsTemplate() throws Exception { assertThat(generalConfigurationView.hasConfigurationView(), is(false)); } + @Test + public void shouldReturnCorrectGeneralSettingsFields() throws Exception { + PluginConfigurationView generalConfigurationView = getGeneralView(); + + assertThat(generalConfigurationView.fields().size(), is(0)); + } + @Override protected Provider getProvider() { return new StashProvider(); From a31dc92c9be586d6d8bae9f4a43300db7e75b2ef Mon Sep 17 00:00:00 2001 From: Juha Siponen Date: Sun, 24 Jul 2016 19:41:54 +0300 Subject: [PATCH 2/7] Refactor plugin setting parsing --- .../gocd/github/GitHubPRBuildPlugin.java | 14 +++---- .../gocd/github/jsonapi/Server.java | 12 +++--- .../gocd/github/jsonapi/ServerFactory.java | 4 +- .../gerrit/GerritPluginConfigurationView.java | 12 ++++++ ...DefaultGeneralPluginConfigurationView.java | 4 ++ .../general/DefaultGeneralPluginSettings.java | 30 +++++++++++++- .../GeneralPluginConfigurationView.java | 5 +++ .../general/GeneralPluginSettings.java | 5 +++ .../gocd/github/util/PluginSettings.java | 41 ------------------- .../gocd/github/GitHubPRBuildPluginTest.java | 4 +- 10 files changed, 71 insertions(+), 60 deletions(-) delete mode 100644 src/main/java/in/ashwanthkumar/gocd/github/util/PluginSettings.java diff --git a/src/main/java/in/ashwanthkumar/gocd/github/GitHubPRBuildPlugin.java b/src/main/java/in/ashwanthkumar/gocd/github/GitHubPRBuildPlugin.java index 37fdcd3..ee8bdfc 100644 --- a/src/main/java/in/ashwanthkumar/gocd/github/GitHubPRBuildPlugin.java +++ b/src/main/java/in/ashwanthkumar/gocd/github/GitHubPRBuildPlugin.java @@ -18,8 +18,12 @@ import in.ashwanthkumar.gocd.github.jsonapi.Server; import in.ashwanthkumar.gocd.github.jsonapi.ServerFactory; import in.ashwanthkumar.gocd.github.provider.Provider; +import in.ashwanthkumar.gocd.github.settings.general.GeneralPluginSettings; import in.ashwanthkumar.gocd.github.settings.scm.PluginConfigurationView; -import in.ashwanthkumar.gocd.github.util.*; +import in.ashwanthkumar.gocd.github.util.BranchFilter; +import in.ashwanthkumar.gocd.github.util.GitFactory; +import in.ashwanthkumar.gocd.github.util.GitFolderFactory; +import in.ashwanthkumar.gocd.github.util.JSONUtils; import in.ashwanthkumar.utils.lang.option.Option; import org.apache.commons.io.IOUtils; @@ -488,17 +492,13 @@ public String responseBody() { }; } - public PluginSettings getPluginSettings() { + public GeneralPluginSettings getPluginSettings() { DefaultGoApiRequest request = new DefaultGoApiRequest(GET_PLUGIN_SETTINGS, "1.0", provider.getPluginId()); request.setRequestBody("{\"plugin-id\": \"" + provider.getPluginId().getExtension() + "\"}"); String response = goApplicationAccessor.submit(request).responseBody(); Map settings = JSONUtils.fromJSON(response, Map.class); - return new PluginSettings( - (String)settings.get("go_api_host"), - (String)settings.get("go_api_username"), - (String)settings.get("go_api_password") - ); + return provider.getGeneralConfigurationView().getSettings(settings); } } diff --git a/src/main/java/in/ashwanthkumar/gocd/github/jsonapi/Server.java b/src/main/java/in/ashwanthkumar/gocd/github/jsonapi/Server.java index fa9b182..8d76f6e 100644 --- a/src/main/java/in/ashwanthkumar/gocd/github/jsonapi/Server.java +++ b/src/main/java/in/ashwanthkumar/gocd/github/jsonapi/Server.java @@ -1,7 +1,7 @@ package in.ashwanthkumar.gocd.github.jsonapi; import com.thoughtworks.go.plugin.api.logging.Logger; -import in.ashwanthkumar.gocd.github.util.PluginSettings; +import in.ashwanthkumar.gocd.github.settings.general.GeneralPluginSettings; import javax.xml.bind.DatatypeConverter; import java.io.IOException; @@ -15,18 +15,18 @@ public class Server { private Logger LOG = Logger.getLoggerFor(Server.class); - private PluginSettings settings; + private GeneralPluginSettings settings; private HttpConnectionUtil httpConnectionUtil; /** * Construct a new server object, using credentials from PluginSettings. */ - public Server(PluginSettings settings) { + public Server(GeneralPluginSettings settings) { this.settings = settings; httpConnectionUtil = new HttpConnectionUtil(); } - Server(PluginSettings settings, HttpConnectionUtil httpConnectionUtil) { + Server(GeneralPluginSettings settings, HttpConnectionUtil httpConnectionUtil) { this.settings = settings; this.httpConnectionUtil = httpConnectionUtil; } @@ -43,8 +43,8 @@ public T getResourceAs(URL url, Class type) HttpURLConnection request = httpConnectionUtil.getConnection(normalizedUrl); - final String login = settings.getGoUsername(); - final String password = settings.getGoPassword(); + final String login = settings.getGoApiUsername(); + final String password = settings.getGoApiPassword(); // Add in our HTTP authorization credentials if we have them. if (!isEmpty(login) && !isEmpty(password)) { String userpass = login + ":" + password; diff --git a/src/main/java/in/ashwanthkumar/gocd/github/jsonapi/ServerFactory.java b/src/main/java/in/ashwanthkumar/gocd/github/jsonapi/ServerFactory.java index e39a215..2dedd84 100644 --- a/src/main/java/in/ashwanthkumar/gocd/github/jsonapi/ServerFactory.java +++ b/src/main/java/in/ashwanthkumar/gocd/github/jsonapi/ServerFactory.java @@ -1,10 +1,10 @@ package in.ashwanthkumar.gocd.github.jsonapi; -import in.ashwanthkumar.gocd.github.util.PluginSettings; +import in.ashwanthkumar.gocd.github.settings.general.GeneralPluginSettings; public class ServerFactory { - public Server getServer(PluginSettings settings) { + public Server getServer(GeneralPluginSettings settings) { return new Server(settings); } } diff --git a/src/main/java/in/ashwanthkumar/gocd/github/provider/gerrit/GerritPluginConfigurationView.java b/src/main/java/in/ashwanthkumar/gocd/github/provider/gerrit/GerritPluginConfigurationView.java index cd9f4f4..478f44e 100644 --- a/src/main/java/in/ashwanthkumar/gocd/github/provider/gerrit/GerritPluginConfigurationView.java +++ b/src/main/java/in/ashwanthkumar/gocd/github/provider/gerrit/GerritPluginConfigurationView.java @@ -1,6 +1,8 @@ package in.ashwanthkumar.gocd.github.provider.gerrit; +import in.ashwanthkumar.gocd.github.settings.general.DefaultGeneralPluginSettings; import in.ashwanthkumar.gocd.github.settings.general.GeneralPluginConfigurationView; +import in.ashwanthkumar.gocd.github.settings.general.GeneralPluginSettings; import in.ashwanthkumar.gocd.github.util.FieldFactory; import java.util.HashMap; @@ -27,4 +29,14 @@ public Map fields() { public boolean hasConfigurationView() { return true; } + + public GeneralPluginSettings getSettings(Map rawSettings) { + GeneralPluginSettings settings = new DefaultGeneralPluginSettings( + (String)rawSettings.get("go_api_host"), + (String)rawSettings.get("go_api_username"), + (String)rawSettings.get("go_api_password") + ); + + return settings; + } } diff --git a/src/main/java/in/ashwanthkumar/gocd/github/settings/general/DefaultGeneralPluginConfigurationView.java b/src/main/java/in/ashwanthkumar/gocd/github/settings/general/DefaultGeneralPluginConfigurationView.java index 3f12c25..f9c4916 100644 --- a/src/main/java/in/ashwanthkumar/gocd/github/settings/general/DefaultGeneralPluginConfigurationView.java +++ b/src/main/java/in/ashwanthkumar/gocd/github/settings/general/DefaultGeneralPluginConfigurationView.java @@ -21,4 +21,8 @@ public Map fields() { public boolean hasConfigurationView() { return false; } + + public GeneralPluginSettings getSettings(Map rawSettings) { + return new DefaultGeneralPluginSettings(); + } } diff --git a/src/main/java/in/ashwanthkumar/gocd/github/settings/general/DefaultGeneralPluginSettings.java b/src/main/java/in/ashwanthkumar/gocd/github/settings/general/DefaultGeneralPluginSettings.java index 8a194aa..fbd8bc4 100644 --- a/src/main/java/in/ashwanthkumar/gocd/github/settings/general/DefaultGeneralPluginSettings.java +++ b/src/main/java/in/ashwanthkumar/gocd/github/settings/general/DefaultGeneralPluginSettings.java @@ -1,6 +1,32 @@ package in.ashwanthkumar.gocd.github.settings.general; -import in.ashwanthkumar.gocd.github.settings.scm.ScmPluginSettings; +public class DefaultGeneralPluginSettings implements GeneralPluginSettings { -public class DefaultGeneralPluginSettings implements ScmPluginSettings { + private String goApiHost; + private String goApiUsername; + private String goApiPassword; + + public DefaultGeneralPluginSettings() { + } + + public DefaultGeneralPluginSettings(String goApiHost, String goApiUsername, String goApiPassword) { + this.goApiHost = goApiHost; + this.goApiUsername = goApiUsername; + this.goApiPassword = goApiPassword; + } + + @Override + public String getGoApiHost() { + return goApiHost; + } + + @Override + public String getGoApiUsername() { + return goApiUsername; + } + + @Override + public String getGoApiPassword() { + return goApiPassword; + } } diff --git a/src/main/java/in/ashwanthkumar/gocd/github/settings/general/GeneralPluginConfigurationView.java b/src/main/java/in/ashwanthkumar/gocd/github/settings/general/GeneralPluginConfigurationView.java index 3b5aab6..46f167f 100644 --- a/src/main/java/in/ashwanthkumar/gocd/github/settings/general/GeneralPluginConfigurationView.java +++ b/src/main/java/in/ashwanthkumar/gocd/github/settings/general/GeneralPluginConfigurationView.java @@ -2,5 +2,10 @@ import in.ashwanthkumar.gocd.github.settings.scm.PluginConfigurationView; +import java.util.Map; + public interface GeneralPluginConfigurationView extends PluginConfigurationView { + + GeneralPluginSettings getSettings(Map rawSettings); + } diff --git a/src/main/java/in/ashwanthkumar/gocd/github/settings/general/GeneralPluginSettings.java b/src/main/java/in/ashwanthkumar/gocd/github/settings/general/GeneralPluginSettings.java index 436cdbf..f6f7e29 100644 --- a/src/main/java/in/ashwanthkumar/gocd/github/settings/general/GeneralPluginSettings.java +++ b/src/main/java/in/ashwanthkumar/gocd/github/settings/general/GeneralPluginSettings.java @@ -1,4 +1,9 @@ package in.ashwanthkumar.gocd.github.settings.general; public interface GeneralPluginSettings { + + String getGoApiHost(); + String getGoApiUsername(); + String getGoApiPassword(); + } diff --git a/src/main/java/in/ashwanthkumar/gocd/github/util/PluginSettings.java b/src/main/java/in/ashwanthkumar/gocd/github/util/PluginSettings.java deleted file mode 100644 index 2f07260..0000000 --- a/src/main/java/in/ashwanthkumar/gocd/github/util/PluginSettings.java +++ /dev/null @@ -1,41 +0,0 @@ -package in.ashwanthkumar.gocd.github.util; - -public class PluginSettings { - - private String goApiHost; - private String goUsername; - private String goPassword; - - public PluginSettings() { - } - - public PluginSettings(String goApiHost, String goUsername, String goPassword) { - this.goUsername = goUsername; - this.goPassword = goPassword; - this.goApiHost = goApiHost; - } - - public String getGoUsername() { - return goUsername; - } - - public void setGoUsername(String goUsername) { - this.goUsername = goUsername; - } - - public String getGoPassword() { - return goPassword; - } - - public void setGoPassword(String goPassword) { - this.goPassword = goPassword; - } - - public String getGoApiHost() { - return goApiHost; - } - - public void setGoApiHost(String goApiHost) { - this.goApiHost = goApiHost; - } -} diff --git a/src/test/java/in/ashwanthkumar/gocd/github/GitHubPRBuildPluginTest.java b/src/test/java/in/ashwanthkumar/gocd/github/GitHubPRBuildPluginTest.java index 6c82072..8231fbc 100644 --- a/src/test/java/in/ashwanthkumar/gocd/github/GitHubPRBuildPluginTest.java +++ b/src/test/java/in/ashwanthkumar/gocd/github/GitHubPRBuildPluginTest.java @@ -17,10 +17,10 @@ import in.ashwanthkumar.gocd.github.provider.git.GitProvider; import in.ashwanthkumar.gocd.github.provider.github.GHUtils; import in.ashwanthkumar.gocd.github.provider.github.GitHubProvider; +import in.ashwanthkumar.gocd.github.settings.general.GeneralPluginSettings; import in.ashwanthkumar.gocd.github.util.GitFactory; import in.ashwanthkumar.gocd.github.util.GitFolderFactory; import in.ashwanthkumar.gocd.github.util.JSONUtils; -import in.ashwanthkumar.gocd.github.util.PluginSettings; import org.apache.commons.io.FileUtils; import org.junit.After; import org.junit.Before; @@ -339,7 +339,7 @@ private ServerFactory mockServerFactory() throws Exception { status.schedulable = true; when(server.getPipelineStatus(anyString())).thenReturn(status); - when(serverFactory.getServer(any(PluginSettings.class))).thenReturn(server); + when(serverFactory.getServer(any(GeneralPluginSettings.class))).thenReturn(server); return serverFactory; } From 2537527717e01d9b8caa599263a26ffa23ef18a1 Mon Sep 17 00:00:00 2001 From: Juha Siponen Date: Sun, 24 Jul 2016 20:16:25 +0300 Subject: [PATCH 3/7] Refactor scm plugin settings handling --- .../gocd/github/GitHubPRBuildPlugin.java | 49 ++++++++++++++----- .../git/GitScmPluginConfigurationView.java | 25 ++++++++-- .../provider/git/GitScmPluginSettings.java | 23 +++++++++ .../DefaultScmPluginConfigurationView.java | 14 +++++- .../scm/DefaultScmPluginSettings.java | 20 ++++++++ .../scm/ScmPluginConfigurationView.java | 4 +- .../settings/scm/ScmPluginSettings.java | 7 +++ .../gocd/github/GitHubPRBuildPluginTest.java | 4 +- 8 files changed, 125 insertions(+), 21 deletions(-) create mode 100644 src/main/java/in/ashwanthkumar/gocd/github/provider/git/GitScmPluginSettings.java diff --git a/src/main/java/in/ashwanthkumar/gocd/github/GitHubPRBuildPlugin.java b/src/main/java/in/ashwanthkumar/gocd/github/GitHubPRBuildPlugin.java index ee8bdfc..af1eaf4 100644 --- a/src/main/java/in/ashwanthkumar/gocd/github/GitHubPRBuildPlugin.java +++ b/src/main/java/in/ashwanthkumar/gocd/github/GitHubPRBuildPlugin.java @@ -20,6 +20,7 @@ import in.ashwanthkumar.gocd.github.provider.Provider; import in.ashwanthkumar.gocd.github.settings.general.GeneralPluginSettings; import in.ashwanthkumar.gocd.github.settings.scm.PluginConfigurationView; +import in.ashwanthkumar.gocd.github.settings.scm.ScmPluginSettings; import in.ashwanthkumar.gocd.github.util.BranchFilter; import in.ashwanthkumar.gocd.github.util.GitFactory; import in.ashwanthkumar.gocd.github.util.GitFolderFactory; @@ -148,6 +149,16 @@ void setProvider(Provider provider) { this.provider = provider; } + public Provider getProvider() { + return provider; + } + + GitConfig getGitConfig(ScmPluginSettings scmPluginSettings) { + GitConfig gitConfig = scmPluginSettings.getGitConfig(); + provider.addConfigData(gitConfig); + return gitConfig; + } + private GoPluginApiResponse handlePluginView() throws IOException { return getPluginView(provider, provider.getGeneralConfigurationView()); } @@ -183,7 +194,9 @@ private GoPluginApiResponse getPluginConfiguration(PluginConfigurationView view) private GoPluginApiResponse handleSCMValidation(GoPluginApiRequest goPluginApiRequest) { Map requestBodyMap = (Map) fromJSON(goPluginApiRequest.requestBody()); final Map configuration = keyValuePairs(requestBodyMap, "scm-configuration"); - final GitConfig gitConfig = getGitConfig(configuration); + ScmPluginSettings scmSettings = provider.getScmConfigurationView().getSettings(configuration); + + final GitConfig gitConfig = getGitConfig(scmSettings); List> response = new ArrayList>(); validate(response, new FieldValidator() { @@ -198,7 +211,9 @@ public void validate(Map fieldValidation) { private GoPluginApiResponse handleSCMCheckConnection(GoPluginApiRequest goPluginApiRequest) { Map requestBodyMap = (Map) fromJSON(goPluginApiRequest.requestBody()); Map configuration = keyValuePairs(requestBodyMap, "scm-configuration"); - GitConfig gitConfig = getGitConfig(configuration); + ScmPluginSettings scmSettings = provider.getScmConfigurationView().getSettings(configuration); + + GitConfig gitConfig = getGitConfig(scmSettings); Map response = new HashMap(); List messages = new ArrayList(); @@ -216,7 +231,12 @@ private GoPluginApiResponse handleSCMCheckConnection(GoPluginApiRequest goPlugin GoPluginApiResponse handleGetLatestRevision(GoPluginApiRequest goPluginApiRequest) { Map requestBodyMap = (Map) fromJSON(goPluginApiRequest.requestBody()); Map configuration = keyValuePairs(requestBodyMap, "scm-configuration"); - GitConfig gitConfig = getGitConfig(configuration); + + ScmPluginSettings scmSettings = provider.getScmConfigurationView().getSettings(configuration); + + GitConfig gitConfig = getGitConfig(scmSettings); + + String flyweightFolder = (String) requestBodyMap.get("flyweight-folder"); LOGGER.info(String.format("Flyweight: %s", flyweightFolder)); @@ -243,12 +263,15 @@ GoPluginApiResponse handleGetLatestRevision(GoPluginApiRequest goPluginApiReques GoPluginApiResponse handleLatestRevisionSince(GoPluginApiRequest goPluginApiRequest) { Map requestBodyMap = (Map) fromJSON(goPluginApiRequest.requestBody()); Map configuration = keyValuePairs(requestBodyMap, "scm-configuration"); - GitConfig gitConfig = getGitConfig(configuration); + ScmPluginSettings scmSettings = provider.getScmConfigurationView().getSettings(configuration); + + GitConfig gitConfig = getGitConfig(scmSettings); + Map scmData = (Map) requestBodyMap.get("scm-data"); Map oldBranchToRevisionMap = (Map) fromJSON(scmData.get(BRANCH_TO_REVISION_MAP)); String flyweightFolder = (String) requestBodyMap.get("flyweight-folder"); LOGGER.debug(String.format("Fetching latest for: %s", gitConfig.getUrl())); - Option pipelineName = Option.option(configuration.get("pipeline_name")); + Option pipelineName = Option.option(scmSettings.getPipelineName()); try { GitHelper git = gitFactory.create(gitConfig, gitFolderFactory.create(flyweightFolder)); @@ -268,7 +291,8 @@ GoPluginApiResponse handleLatestRevisionSince(GoPluginApiRequest goPluginApiRequ BranchFilter branchFilter = provider .getScmConfigurationView() - .getBranchFilter(configuration); + .getBranchFilter(scmSettings); + Server server = serverFactory.getServer(getPluginSettings()); for (String branch : newBranchToRevisionMap.keySet()) { @@ -371,8 +395,13 @@ private boolean branchHasNewChange(String previousSHA, String latestSHA) { private GoPluginApiResponse handleCheckout(GoPluginApiRequest goPluginApiRequest) { Map requestBodyMap = (Map) fromJSON(goPluginApiRequest.requestBody()); + Map configuration = keyValuePairs(requestBodyMap, "scm-configuration"); - GitConfig gitConfig = getGitConfig(configuration); + ScmPluginSettings scmSettings = provider.getScmConfigurationView().getSettings(configuration); + + GitConfig gitConfig = getGitConfig(scmSettings); + provider.addConfigData(gitConfig); + String destinationFolder = (String) requestBodyMap.get("destination-folder"); Map revisionMap = (Map) requestBodyMap.get("revision"); String revision = (String) revisionMap.get("revision"); @@ -394,12 +423,6 @@ private GoPluginApiResponse handleCheckout(GoPluginApiRequest goPluginApiRequest } } - GitConfig getGitConfig(Map configuration) { - GitConfig gitConfig = new GitConfig(configuration.get("url"), configuration.get("username"), configuration.get("password"), null); - provider.addConfigData(gitConfig); - return gitConfig; - } - private void validate(List> response, FieldValidator fieldValidator) { Map fieldValidation = new HashMap(); fieldValidator.validate(fieldValidation); diff --git a/src/main/java/in/ashwanthkumar/gocd/github/provider/git/GitScmPluginConfigurationView.java b/src/main/java/in/ashwanthkumar/gocd/github/provider/git/GitScmPluginConfigurationView.java index 7c1d3e9..b2d1080 100644 --- a/src/main/java/in/ashwanthkumar/gocd/github/provider/git/GitScmPluginConfigurationView.java +++ b/src/main/java/in/ashwanthkumar/gocd/github/provider/git/GitScmPluginConfigurationView.java @@ -1,6 +1,7 @@ package in.ashwanthkumar.gocd.github.provider.git; import in.ashwanthkumar.gocd.github.settings.scm.DefaultScmPluginConfigurationView; +import in.ashwanthkumar.gocd.github.settings.scm.ScmPluginSettings; import in.ashwanthkumar.gocd.github.util.BranchFilter; import in.ashwanthkumar.gocd.github.util.FieldFactory; @@ -27,11 +28,27 @@ public Map fields() { } @Override - public BranchFilter getBranchFilter(Map configuration) { - String blacklist = configuration.get(BRANCH_BLACKLIST_PROPERTY_NAME); - String whitelist = configuration.get(BRANCH_WHITELIST_PROPERTY_NAME); + public BranchFilter getBranchFilter(ScmPluginSettings scmSettings) { + GitScmPluginSettings gitScmSettings = (GitScmPluginSettings) scmSettings; - return new BranchFilter(blacklist, whitelist); + return new BranchFilter( + gitScmSettings.getBranchBlacklist(), + gitScmSettings.getBranchWhitelist() + ); } + @Override + public ScmPluginSettings getSettings(Map rawSettings) { + ScmPluginSettings settings = new GitScmPluginSettings( + rawSettings.get("url"), + rawSettings.get("username"), + rawSettings.get("password"), + null, + rawSettings.get("pipeline_name"), + rawSettings.get(BRANCH_BLACKLIST_PROPERTY_NAME), + rawSettings.get(BRANCH_WHITELIST_PROPERTY_NAME) + ); + + return settings; + } } diff --git a/src/main/java/in/ashwanthkumar/gocd/github/provider/git/GitScmPluginSettings.java b/src/main/java/in/ashwanthkumar/gocd/github/provider/git/GitScmPluginSettings.java new file mode 100644 index 0000000..41073d4 --- /dev/null +++ b/src/main/java/in/ashwanthkumar/gocd/github/provider/git/GitScmPluginSettings.java @@ -0,0 +1,23 @@ +package in.ashwanthkumar.gocd.github.provider.git; + +import in.ashwanthkumar.gocd.github.settings.scm.DefaultScmPluginSettings; + +public class GitScmPluginSettings extends DefaultScmPluginSettings { + + private String branchBlacklist; + private String branchWhitelist; + + public GitScmPluginSettings(String url, String username, String password, String branch, String pipelineName, String branchBlacklist, String branchWhitelist) { + super(url, username, password, branch, pipelineName); + this.branchBlacklist = branchBlacklist; + this.branchWhitelist = branchWhitelist; + } + + public String getBranchBlacklist() { + return branchBlacklist; + } + + public String getBranchWhitelist() { + return branchWhitelist; + } +} diff --git a/src/main/java/in/ashwanthkumar/gocd/github/settings/scm/DefaultScmPluginConfigurationView.java b/src/main/java/in/ashwanthkumar/gocd/github/settings/scm/DefaultScmPluginConfigurationView.java index 49cba14..224402a 100644 --- a/src/main/java/in/ashwanthkumar/gocd/github/settings/scm/DefaultScmPluginConfigurationView.java +++ b/src/main/java/in/ashwanthkumar/gocd/github/settings/scm/DefaultScmPluginConfigurationView.java @@ -25,7 +25,7 @@ public Map fields() { } @Override - public BranchFilter getBranchFilter(Map configuration) { + public BranchFilter getBranchFilter(ScmPluginSettings scmSettings) { return new BranchFilter(); } @@ -33,4 +33,16 @@ public BranchFilter getBranchFilter(Map configuration) { public boolean hasConfigurationView() { return true; } + + public ScmPluginSettings getSettings(Map rawSettings) { + ScmPluginSettings settings = new DefaultScmPluginSettings( + rawSettings.get("url"), + rawSettings.get("username"), + rawSettings.get("password"), + null, + rawSettings.get("pipeline_name") + ); + + return settings; + } } diff --git a/src/main/java/in/ashwanthkumar/gocd/github/settings/scm/DefaultScmPluginSettings.java b/src/main/java/in/ashwanthkumar/gocd/github/settings/scm/DefaultScmPluginSettings.java index 55ef2c6..f1d725b 100644 --- a/src/main/java/in/ashwanthkumar/gocd/github/settings/scm/DefaultScmPluginSettings.java +++ b/src/main/java/in/ashwanthkumar/gocd/github/settings/scm/DefaultScmPluginSettings.java @@ -1,4 +1,24 @@ package in.ashwanthkumar.gocd.github.settings.scm; +import com.tw.go.plugin.model.GitConfig; + public class DefaultScmPluginSettings implements ScmPluginSettings { + + private GitConfig gitConfig; + private String pipelineName; + + public DefaultScmPluginSettings(String url, String username, String password, String branch, String pipelineName) { + this.gitConfig = new GitConfig(url, username, password, branch); + this.pipelineName = pipelineName; + } + + @Override + public GitConfig getGitConfig() { + return gitConfig; + } + + @Override + public String getPipelineName() { + return pipelineName; + } } diff --git a/src/main/java/in/ashwanthkumar/gocd/github/settings/scm/ScmPluginConfigurationView.java b/src/main/java/in/ashwanthkumar/gocd/github/settings/scm/ScmPluginConfigurationView.java index eb48b88..9bff842 100644 --- a/src/main/java/in/ashwanthkumar/gocd/github/settings/scm/ScmPluginConfigurationView.java +++ b/src/main/java/in/ashwanthkumar/gocd/github/settings/scm/ScmPluginConfigurationView.java @@ -6,5 +6,7 @@ public interface ScmPluginConfigurationView extends PluginConfigurationView { - BranchFilter getBranchFilter(Map configuration); + BranchFilter getBranchFilter(ScmPluginSettings scmSettings); + + ScmPluginSettings getSettings(Map rawSettings); } diff --git a/src/main/java/in/ashwanthkumar/gocd/github/settings/scm/ScmPluginSettings.java b/src/main/java/in/ashwanthkumar/gocd/github/settings/scm/ScmPluginSettings.java index b3e6e1b..801bc62 100644 --- a/src/main/java/in/ashwanthkumar/gocd/github/settings/scm/ScmPluginSettings.java +++ b/src/main/java/in/ashwanthkumar/gocd/github/settings/scm/ScmPluginSettings.java @@ -1,4 +1,11 @@ package in.ashwanthkumar.gocd.github.settings.scm; +import com.tw.go.plugin.model.GitConfig; + public interface ScmPluginSettings { + + GitConfig getGitConfig(); + + String getPipelineName(); + } diff --git a/src/test/java/in/ashwanthkumar/gocd/github/GitHubPRBuildPluginTest.java b/src/test/java/in/ashwanthkumar/gocd/github/GitHubPRBuildPluginTest.java index 8231fbc..f253b92 100644 --- a/src/test/java/in/ashwanthkumar/gocd/github/GitHubPRBuildPluginTest.java +++ b/src/test/java/in/ashwanthkumar/gocd/github/GitHubPRBuildPluginTest.java @@ -80,7 +80,7 @@ public void shouldBuildGitConfig() { GitHubPRBuildPlugin plugin = new GitHubPRBuildPlugin(); plugin.setProvider(new GitHubProvider()); - GitConfig gitConfig = plugin.getGitConfig(configuration); + GitConfig gitConfig = plugin.getGitConfig(plugin.getProvider().getScmConfigurationView().getSettings(configuration)); assertThat(gitConfig.getUrl(), is("url")); assertThat(gitConfig.getUsername(), is("config-username")); @@ -89,7 +89,7 @@ public void shouldBuildGitConfig() { configuration.remove("username"); configuration.remove("password"); - gitConfig = plugin.getGitConfig(configuration); + gitConfig = plugin.getGitConfig(plugin.getProvider().getScmConfigurationView().getSettings(configuration)); assertThat(gitConfig.getUrl(), is("url")); assertThat(gitConfig.getUsername(), is(usernameProperty)); From e043c4c05a520aed4aa88d36c60e906e1dc509c7 Mon Sep 17 00:00:00 2001 From: Juha Siponen Date: Sun, 7 Aug 2016 12:58:48 +0300 Subject: [PATCH 4/7] Remove general plugin settings from plugins that don't require them Only Gerrit uses plugin level settings for now. --- .../gocd/github/GitHubPRBuildPlugin.java | 19 +++++++---- .../gocd/github/jsonapi/Server.java | 10 ++++-- .../gerrit/GerritPluginConfigurationView.java | 6 ++-- .../provider/gerrit/GerritPluginSettings.java | 32 +++++++++++++++++++ .../general/DefaultGeneralPluginSettings.java | 27 ---------------- .../general/GeneralPluginSettings.java | 5 --- .../settings/general/GoApiSettings.java | 8 +++++ .../DefaultScmPluginConfigurationView.java | 1 + ...plate.html => gerrit.plugin.template.html} | 0 .../provider/gerrit/GerritProviderTest.java | 2 +- .../github/provider/git/GitProviderTest.java | 1 - 11 files changed, 64 insertions(+), 47 deletions(-) create mode 100644 src/main/java/in/ashwanthkumar/gocd/github/provider/gerrit/GerritPluginSettings.java create mode 100644 src/main/java/in/ashwanthkumar/gocd/github/settings/general/GoApiSettings.java rename src/main/resources/views/{plugin.template.html => gerrit.plugin.template.html} (100%) diff --git a/src/main/java/in/ashwanthkumar/gocd/github/GitHubPRBuildPlugin.java b/src/main/java/in/ashwanthkumar/gocd/github/GitHubPRBuildPlugin.java index af1eaf4..d4a7eb1 100644 --- a/src/main/java/in/ashwanthkumar/gocd/github/GitHubPRBuildPlugin.java +++ b/src/main/java/in/ashwanthkumar/gocd/github/GitHubPRBuildPlugin.java @@ -516,12 +516,17 @@ public String responseBody() { } public GeneralPluginSettings getPluginSettings() { - DefaultGoApiRequest request = - new DefaultGoApiRequest(GET_PLUGIN_SETTINGS, "1.0", provider.getPluginId()); - request.setRequestBody("{\"plugin-id\": \"" + provider.getPluginId().getExtension() + "\"}"); - String response = goApplicationAccessor.submit(request).responseBody(); - Map settings = JSONUtils.fromJSON(response, Map.class); - - return provider.getGeneralConfigurationView().getSettings(settings); + if (provider.getGeneralConfigurationView().hasConfigurationView()) { + DefaultGoApiRequest request = + new DefaultGoApiRequest(GET_PLUGIN_SETTINGS, "1.0", provider.getPluginId()); + request.setRequestBody("{\"plugin-id\": \"" + provider.getPluginId().getExtension() + "\"}"); + String response = goApplicationAccessor.submit(request).responseBody(); + Map settings = JSONUtils.fromJSON(response, Map.class); + return provider.getGeneralConfigurationView().getSettings(settings); + } else { + return provider + .getGeneralConfigurationView() + .getSettings(Collections.emptyMap()); + } } } diff --git a/src/main/java/in/ashwanthkumar/gocd/github/jsonapi/Server.java b/src/main/java/in/ashwanthkumar/gocd/github/jsonapi/Server.java index 8d76f6e..cf11719 100644 --- a/src/main/java/in/ashwanthkumar/gocd/github/jsonapi/Server.java +++ b/src/main/java/in/ashwanthkumar/gocd/github/jsonapi/Server.java @@ -2,6 +2,7 @@ import com.thoughtworks.go.plugin.api.logging.Logger; import in.ashwanthkumar.gocd.github.settings.general.GeneralPluginSettings; +import in.ashwanthkumar.gocd.github.settings.general.GoApiSettings; import javax.xml.bind.DatatypeConverter; import java.io.IOException; @@ -43,8 +44,9 @@ public T getResourceAs(URL url, Class type) HttpURLConnection request = httpConnectionUtil.getConnection(normalizedUrl); - final String login = settings.getGoApiUsername(); - final String password = settings.getGoApiPassword(); + GoApiSettings goApiSettings = (GoApiSettings) settings; + final String login = goApiSettings.getGoApiUsername(); + final String password = goApiSettings.getGoApiPassword(); // Add in our HTTP authorization credentials if we have them. if (!isEmpty(login) && !isEmpty(password)) { String userpass = login + ":" + password; @@ -60,7 +62,9 @@ public T getResourceAs(URL url, Class type) public PipelineStatus getPipelineStatus(String pipelineName) throws MalformedURLException, IOException { - final String apiHost = settings.getGoApiHost(); + GoApiSettings goApiSettings = (GoApiSettings) settings; + + final String apiHost = goApiSettings.getGoApiHost(); URL url = new URL(String.format("%s/go/api/pipelines/%s/status", apiHost, pipelineName)); diff --git a/src/main/java/in/ashwanthkumar/gocd/github/provider/gerrit/GerritPluginConfigurationView.java b/src/main/java/in/ashwanthkumar/gocd/github/provider/gerrit/GerritPluginConfigurationView.java index 478f44e..07f62c9 100644 --- a/src/main/java/in/ashwanthkumar/gocd/github/provider/gerrit/GerritPluginConfigurationView.java +++ b/src/main/java/in/ashwanthkumar/gocd/github/provider/gerrit/GerritPluginConfigurationView.java @@ -1,6 +1,5 @@ package in.ashwanthkumar.gocd.github.provider.gerrit; -import in.ashwanthkumar.gocd.github.settings.general.DefaultGeneralPluginSettings; import in.ashwanthkumar.gocd.github.settings.general.GeneralPluginConfigurationView; import in.ashwanthkumar.gocd.github.settings.general.GeneralPluginSettings; import in.ashwanthkumar.gocd.github.util.FieldFactory; @@ -13,7 +12,7 @@ public class GerritPluginConfigurationView implements GeneralPluginConfiguration @Override public String templateName() { - return "/views/plugin.template.html"; + return "/views/gerrit.plugin.template.html"; } @Override @@ -30,8 +29,9 @@ public boolean hasConfigurationView() { return true; } + @Override public GeneralPluginSettings getSettings(Map rawSettings) { - GeneralPluginSettings settings = new DefaultGeneralPluginSettings( + GerritPluginSettings settings = new GerritPluginSettings( (String)rawSettings.get("go_api_host"), (String)rawSettings.get("go_api_username"), (String)rawSettings.get("go_api_password") diff --git a/src/main/java/in/ashwanthkumar/gocd/github/provider/gerrit/GerritPluginSettings.java b/src/main/java/in/ashwanthkumar/gocd/github/provider/gerrit/GerritPluginSettings.java new file mode 100644 index 0000000..fc4070e --- /dev/null +++ b/src/main/java/in/ashwanthkumar/gocd/github/provider/gerrit/GerritPluginSettings.java @@ -0,0 +1,32 @@ +package in.ashwanthkumar.gocd.github.provider.gerrit; + +import in.ashwanthkumar.gocd.github.settings.general.GeneralPluginSettings; +import in.ashwanthkumar.gocd.github.settings.general.GoApiSettings; + +public class GerritPluginSettings implements GoApiSettings, GeneralPluginSettings { + + private String goApiHost; + private String goApiUsername; + private String goApiPassword; + + public GerritPluginSettings(String goApiHost, String goApiUsername, String goApiPassword) { + this.goApiHost = goApiHost; + this.goApiUsername = goApiUsername; + this.goApiPassword = goApiPassword; + } + + @Override + public String getGoApiHost() { + return goApiHost; + } + + @Override + public String getGoApiUsername() { + return goApiUsername; + } + + @Override + public String getGoApiPassword() { + return goApiPassword; + } +} diff --git a/src/main/java/in/ashwanthkumar/gocd/github/settings/general/DefaultGeneralPluginSettings.java b/src/main/java/in/ashwanthkumar/gocd/github/settings/general/DefaultGeneralPluginSettings.java index fbd8bc4..0e2c590 100644 --- a/src/main/java/in/ashwanthkumar/gocd/github/settings/general/DefaultGeneralPluginSettings.java +++ b/src/main/java/in/ashwanthkumar/gocd/github/settings/general/DefaultGeneralPluginSettings.java @@ -2,31 +2,4 @@ public class DefaultGeneralPluginSettings implements GeneralPluginSettings { - private String goApiHost; - private String goApiUsername; - private String goApiPassword; - - public DefaultGeneralPluginSettings() { - } - - public DefaultGeneralPluginSettings(String goApiHost, String goApiUsername, String goApiPassword) { - this.goApiHost = goApiHost; - this.goApiUsername = goApiUsername; - this.goApiPassword = goApiPassword; - } - - @Override - public String getGoApiHost() { - return goApiHost; - } - - @Override - public String getGoApiUsername() { - return goApiUsername; - } - - @Override - public String getGoApiPassword() { - return goApiPassword; - } } diff --git a/src/main/java/in/ashwanthkumar/gocd/github/settings/general/GeneralPluginSettings.java b/src/main/java/in/ashwanthkumar/gocd/github/settings/general/GeneralPluginSettings.java index f6f7e29..436cdbf 100644 --- a/src/main/java/in/ashwanthkumar/gocd/github/settings/general/GeneralPluginSettings.java +++ b/src/main/java/in/ashwanthkumar/gocd/github/settings/general/GeneralPluginSettings.java @@ -1,9 +1,4 @@ package in.ashwanthkumar.gocd.github.settings.general; public interface GeneralPluginSettings { - - String getGoApiHost(); - String getGoApiUsername(); - String getGoApiPassword(); - } diff --git a/src/main/java/in/ashwanthkumar/gocd/github/settings/general/GoApiSettings.java b/src/main/java/in/ashwanthkumar/gocd/github/settings/general/GoApiSettings.java new file mode 100644 index 0000000..428884b --- /dev/null +++ b/src/main/java/in/ashwanthkumar/gocd/github/settings/general/GoApiSettings.java @@ -0,0 +1,8 @@ +package in.ashwanthkumar.gocd.github.settings.general; + +public interface GoApiSettings { + + String getGoApiHost(); + String getGoApiUsername(); + String getGoApiPassword(); +} diff --git a/src/main/java/in/ashwanthkumar/gocd/github/settings/scm/DefaultScmPluginConfigurationView.java b/src/main/java/in/ashwanthkumar/gocd/github/settings/scm/DefaultScmPluginConfigurationView.java index 224402a..080703f 100644 --- a/src/main/java/in/ashwanthkumar/gocd/github/settings/scm/DefaultScmPluginConfigurationView.java +++ b/src/main/java/in/ashwanthkumar/gocd/github/settings/scm/DefaultScmPluginConfigurationView.java @@ -45,4 +45,5 @@ public ScmPluginSettings getSettings(Map rawSettings) { return settings; } + } diff --git a/src/main/resources/views/plugin.template.html b/src/main/resources/views/gerrit.plugin.template.html similarity index 100% rename from src/main/resources/views/plugin.template.html rename to src/main/resources/views/gerrit.plugin.template.html diff --git a/src/test/java/in/ashwanthkumar/gocd/github/provider/gerrit/GerritProviderTest.java b/src/test/java/in/ashwanthkumar/gocd/github/provider/gerrit/GerritProviderTest.java index 535bfeb..b715168 100644 --- a/src/test/java/in/ashwanthkumar/gocd/github/provider/gerrit/GerritProviderTest.java +++ b/src/test/java/in/ashwanthkumar/gocd/github/provider/gerrit/GerritProviderTest.java @@ -32,7 +32,7 @@ public void shouldReturnCorrectScmSettingsFields() throws Exception { public void shouldReturnCorrectGeneralSettingsTemplate() throws Exception { PluginConfigurationView generalConfigurationView = getGeneralView(); - assertThat(generalConfigurationView.templateName(), is("/views/plugin.template.html")); + assertThat(generalConfigurationView.templateName(), is("/views/gerrit.plugin.template.html")); assertThat(generalConfigurationView.hasConfigurationView(), is(true)); } diff --git a/src/test/java/in/ashwanthkumar/gocd/github/provider/git/GitProviderTest.java b/src/test/java/in/ashwanthkumar/gocd/github/provider/git/GitProviderTest.java index 457eec2..e666402 100644 --- a/src/test/java/in/ashwanthkumar/gocd/github/provider/git/GitProviderTest.java +++ b/src/test/java/in/ashwanthkumar/gocd/github/provider/git/GitProviderTest.java @@ -41,7 +41,6 @@ public void shouldReturnCorrectGeneralSettingsFields() throws Exception { PluginConfigurationView generalConfigurationView = getGeneralView(); assertThat(generalConfigurationView.fields().size(), is(0)); - } @Override From 055475d2d287c5d09e989c3d4425bd27b0b75eeb Mon Sep 17 00:00:00 2001 From: Juha Siponen Date: Sun, 14 Aug 2016 21:57:39 +0300 Subject: [PATCH 5/7] Add support for checking if pipeline is building --- .../gocd/github/jsonapi/Job.java | 34 +++++++ .../gocd/github/jsonapi/Pipeline.java | 55 +++++++++++ .../gocd/github/jsonapi/PipelineHistory.java | 31 +++++++ .../gocd/github/jsonapi/Server.java | 11 +++ .../gocd/github/jsonapi/Stage.java | 37 ++++++++ .../gocd/github/jsonapi/CanRun.java | 5 + .../gocd/github/jsonapi/JobTest.java | 39 ++++++++ .../github/jsonapi/PipelineHistoryTest.java | 91 +++++++++++++++++++ .../gocd/github/jsonapi/PipelineTest.java | 68 ++++++++++++++ .../gocd/github/jsonapi/StageTest.java | 55 +++++++++++ 10 files changed, 426 insertions(+) create mode 100644 src/main/java/in/ashwanthkumar/gocd/github/jsonapi/Job.java create mode 100644 src/main/java/in/ashwanthkumar/gocd/github/jsonapi/Pipeline.java create mode 100644 src/main/java/in/ashwanthkumar/gocd/github/jsonapi/PipelineHistory.java create mode 100644 src/main/java/in/ashwanthkumar/gocd/github/jsonapi/Stage.java create mode 100644 src/test/java/in/ashwanthkumar/gocd/github/jsonapi/CanRun.java create mode 100644 src/test/java/in/ashwanthkumar/gocd/github/jsonapi/JobTest.java create mode 100644 src/test/java/in/ashwanthkumar/gocd/github/jsonapi/PipelineHistoryTest.java create mode 100644 src/test/java/in/ashwanthkumar/gocd/github/jsonapi/PipelineTest.java create mode 100644 src/test/java/in/ashwanthkumar/gocd/github/jsonapi/StageTest.java diff --git a/src/main/java/in/ashwanthkumar/gocd/github/jsonapi/Job.java b/src/main/java/in/ashwanthkumar/gocd/github/jsonapi/Job.java new file mode 100644 index 0000000..a43ad27 --- /dev/null +++ b/src/main/java/in/ashwanthkumar/gocd/github/jsonapi/Job.java @@ -0,0 +1,34 @@ +package in.ashwanthkumar.gocd.github.jsonapi; + +import com.google.gson.annotations.SerializedName; + +public class Job { + + @SerializedName("state") + private String state; + + public Job() { + } + + public Job(String state) { + this.state = state; + } + + public String getState() { + return state; + } + + public boolean isRunningOrScheduled() { + return "assigned".equalsIgnoreCase(state) + || "scheduled".equalsIgnoreCase(state) + || "building".equalsIgnoreCase(state); + + } + + @Override + public String toString() { + return "Job{" + + "state='" + state + '\'' + + '}'; + } +} diff --git a/src/main/java/in/ashwanthkumar/gocd/github/jsonapi/Pipeline.java b/src/main/java/in/ashwanthkumar/gocd/github/jsonapi/Pipeline.java new file mode 100644 index 0000000..63c95fe --- /dev/null +++ b/src/main/java/in/ashwanthkumar/gocd/github/jsonapi/Pipeline.java @@ -0,0 +1,55 @@ +package in.ashwanthkumar.gocd.github.jsonapi; + +import com.google.gson.annotations.SerializedName; + +import java.util.List; + +public class Pipeline { + + @SerializedName("stages") + private List stages; + + @SerializedName("preparing_to_schedule") + private boolean preparingToSchedule; + + @SerializedName("can_run") + private boolean canRun; + + public Pipeline() { + } + + public Pipeline(boolean preparingToSchedule, boolean canRun, List stages) { + this.stages = stages; + this.preparingToSchedule = preparingToSchedule; + this.canRun = canRun; + } + + public boolean isPreparingToSchedule() { + return preparingToSchedule; + } + + public List getStages() { + return stages; + } + + public boolean isCanRun() { + return canRun; + } + + public boolean isRunningOrScheduled() { + if (preparingToSchedule) { + return true; + } + + if (!canRun) { + return true; + } + + for (Stage stage : stages) { + if (stage.isRunningOrScheduled()) { + return true; + } + } + return false; + } +} diff --git a/src/main/java/in/ashwanthkumar/gocd/github/jsonapi/PipelineHistory.java b/src/main/java/in/ashwanthkumar/gocd/github/jsonapi/PipelineHistory.java new file mode 100644 index 0000000..5318de3 --- /dev/null +++ b/src/main/java/in/ashwanthkumar/gocd/github/jsonapi/PipelineHistory.java @@ -0,0 +1,31 @@ +package in.ashwanthkumar.gocd.github.jsonapi; + +import com.google.gson.annotations.SerializedName; + +import java.util.List; + +public class PipelineHistory { + + @SerializedName("pipelines") + private List pipelines; + + public PipelineHistory() { + } + + public PipelineHistory(List pipelines) { + this.pipelines = pipelines; + } + + public List getPipelines() { + return pipelines; + } + + boolean isPipelineRunningOrScheduled() { + for (Pipeline pipeline : pipelines) { + if (pipeline.isRunningOrScheduled()) { + return true; + } + } + return false; + } +} diff --git a/src/main/java/in/ashwanthkumar/gocd/github/jsonapi/Server.java b/src/main/java/in/ashwanthkumar/gocd/github/jsonapi/Server.java index cf11719..c7e91dd 100644 --- a/src/main/java/in/ashwanthkumar/gocd/github/jsonapi/Server.java +++ b/src/main/java/in/ashwanthkumar/gocd/github/jsonapi/Server.java @@ -72,4 +72,15 @@ public PipelineStatus getPipelineStatus(String pipelineName) return getResourceAs(url, PipelineStatus.class); } + public PipelineHistory getPipelineHistory(String pipelineName) + throws MalformedURLException, IOException { + GoApiSettings goApiSettings = (GoApiSettings) settings; + + final String apiHost = goApiSettings.getGoApiHost(); + URL url = new URL(String.format("%s/go/api/pipelines/%s/history", + apiHost, pipelineName)); + + LOG.info(String.format("Fetch pipeline %s history from %s", pipelineName, url)); + return getResourceAs(url, PipelineHistory.class); + } } diff --git a/src/main/java/in/ashwanthkumar/gocd/github/jsonapi/Stage.java b/src/main/java/in/ashwanthkumar/gocd/github/jsonapi/Stage.java new file mode 100644 index 0000000..3e8983d --- /dev/null +++ b/src/main/java/in/ashwanthkumar/gocd/github/jsonapi/Stage.java @@ -0,0 +1,37 @@ +package in.ashwanthkumar.gocd.github.jsonapi; + +import com.google.gson.annotations.SerializedName; + +import java.util.List; + +public class Stage { + + + @SerializedName("can_run") + private boolean canRun; + + @SerializedName("jobs") + private List jobs; + + public Stage() { + } + + public Stage(boolean canRun, List jobs) { + this.canRun = canRun; + this.jobs = jobs; + } + + + public boolean isRunningOrScheduled() { + if (!canRun) { + return true; + } + + for (Job job : jobs) { + if (job.isRunningOrScheduled()) { + return true; + } + } + return false; + } +} diff --git a/src/test/java/in/ashwanthkumar/gocd/github/jsonapi/CanRun.java b/src/test/java/in/ashwanthkumar/gocd/github/jsonapi/CanRun.java new file mode 100644 index 0000000..f108a15 --- /dev/null +++ b/src/test/java/in/ashwanthkumar/gocd/github/jsonapi/CanRun.java @@ -0,0 +1,5 @@ +package in.ashwanthkumar.gocd.github.jsonapi; + +enum CanRun { + YES, NO +} diff --git a/src/test/java/in/ashwanthkumar/gocd/github/jsonapi/JobTest.java b/src/test/java/in/ashwanthkumar/gocd/github/jsonapi/JobTest.java new file mode 100644 index 0000000..566ebc7 --- /dev/null +++ b/src/test/java/in/ashwanthkumar/gocd/github/jsonapi/JobTest.java @@ -0,0 +1,39 @@ +package in.ashwanthkumar.gocd.github.jsonapi; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +import java.util.Arrays; +import java.util.Collection; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +@RunWith(Parameterized.class) +public class JobTest { + + @Parameterized.Parameters(name = "Job state {0}. Job running or scheduled expected {1}") + public static Collection data() { + return Arrays.asList(new Object[][] { + {"assigned", true}, + {"building", true}, + {"scheduled", true}, + {"completed", false}, + }); + } + + private final String state; + private final boolean result; + + public JobTest(String state, boolean result) { + this.state = state; + this.result = result; + } + + @Test + public void shouldReturnCorrectBuildingStatus() { + assertThat(new Job(state).isRunningOrScheduled(), is(result)); + } + +} \ No newline at end of file diff --git a/src/test/java/in/ashwanthkumar/gocd/github/jsonapi/PipelineHistoryTest.java b/src/test/java/in/ashwanthkumar/gocd/github/jsonapi/PipelineHistoryTest.java new file mode 100644 index 0000000..6439741 --- /dev/null +++ b/src/test/java/in/ashwanthkumar/gocd/github/jsonapi/PipelineHistoryTest.java @@ -0,0 +1,91 @@ +package in.ashwanthkumar.gocd.github.jsonapi; + +import org.junit.Test; + +import java.util.List; + +import static java.util.Arrays.asList; +import static org.hamcrest.core.Is.is; +import static org.junit.Assert.assertThat; + +public class PipelineHistoryTest { + + @Test + public void shouldShowPipelineRunnableWhenJobsCompleted() { + + final boolean canRunPipeline = true; + final boolean preparingToSchedule = false; + final boolean canRunStage = true; + final String jobStage = "Completed"; + + List pipelines = asList( + new Pipeline( + preparingToSchedule, + canRunPipeline, + asList( + new Stage( + canRunStage, + asList(new Job(jobStage)) + ) + ) + ) + ); + + PipelineHistory history = new PipelineHistory(pipelines); + + assertThat(history.isPipelineRunningOrScheduled(), is(false)); + } + + @Test + public void shouldShowPipelineNotRunnableWhenJobsAssigned() { + + final boolean canRunPipeline = true; + final boolean preparingToSchedule = false; + final boolean canRunStage = true; + final String jobStage = "Assigned"; + + List pipelines = asList( + new Pipeline( + preparingToSchedule, + canRunPipeline, + asList( + new Stage( + canRunStage, + asList(new Job(jobStage)) + ) + ) + ) + ); + + PipelineHistory history = new PipelineHistory(pipelines); + + assertThat(history.isPipelineRunningOrScheduled(), is(true)); + } + + @Test + public void shouldShowPipelineNotRunnableWhenJobsBuilding() { + + final boolean canRunPipeline = true; + final boolean preparingToSchedule = false; + final boolean canRunStage = true; + final String jobStage = "Building"; + + List pipelines = asList( + new Pipeline( + preparingToSchedule, + canRunPipeline, + asList( + new Stage( + canRunStage, + asList(new Job(jobStage)) + ) + ) + ) + ); + + PipelineHistory history = new PipelineHistory(pipelines); + + assertThat(history.isPipelineRunningOrScheduled(), is(true)); + } + +} \ No newline at end of file diff --git a/src/test/java/in/ashwanthkumar/gocd/github/jsonapi/PipelineTest.java b/src/test/java/in/ashwanthkumar/gocd/github/jsonapi/PipelineTest.java new file mode 100644 index 0000000..f7c2382 --- /dev/null +++ b/src/test/java/in/ashwanthkumar/gocd/github/jsonapi/PipelineTest.java @@ -0,0 +1,68 @@ +package in.ashwanthkumar.gocd.github.jsonapi; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +@RunWith(Parameterized.class) +public class PipelineTest { + + private enum PreparingToSchedule { + YES, NO + } + + private static List stagesRunningOrScheduled(boolean... states) { + List stages = new ArrayList<>(states.length); + for (boolean state : states) { + Stage stage = mock(Stage.class); + when(stage.isRunningOrScheduled()).thenReturn(state); + when(stage.toString()).thenReturn("Stage.isRunningOrScheduled=" + state); + stages.add(stage); + } + return stages; + } + + @Parameterized.Parameters(name = "Pipeline can run: {0}, preparing to schedule: {1}, stages: {2}. Expected {3}") + public static Collection data() { + return Arrays.asList(new Object[][] { + {PreparingToSchedule.YES, CanRun.YES, stagesRunningOrScheduled(true), true}, + {PreparingToSchedule.YES, CanRun.NO, stagesRunningOrScheduled(true), true}, + {PreparingToSchedule.NO, CanRun.YES, stagesRunningOrScheduled(true), true}, + {PreparingToSchedule.NO, CanRun.NO, stagesRunningOrScheduled(true), true}, + + {PreparingToSchedule.YES, CanRun.YES, stagesRunningOrScheduled(false), true}, + {PreparingToSchedule.YES, CanRun.NO, stagesRunningOrScheduled(false), true}, + {PreparingToSchedule.NO, CanRun.YES, stagesRunningOrScheduled(false), false}, + {PreparingToSchedule.NO, CanRun.NO, stagesRunningOrScheduled(false), true}, + }); + } + + private final boolean preparingToSchedule; + private final boolean canRun; + private final List stages; + private final boolean expected; + + public PipelineTest(PreparingToSchedule preparingToSchedule, CanRun canRun, List stages, boolean expected) { + this.preparingToSchedule = preparingToSchedule.equals(PreparingToSchedule.YES); + this.canRun = canRun.equals(CanRun.YES); + this.stages = stages; + this.expected = expected; + } + + @Test + public void shouldReturnCorrectStatus() { + assertThat(new Pipeline(preparingToSchedule, canRun, stages) + .isRunningOrScheduled(), is(expected)); + } + +} \ No newline at end of file diff --git a/src/test/java/in/ashwanthkumar/gocd/github/jsonapi/StageTest.java b/src/test/java/in/ashwanthkumar/gocd/github/jsonapi/StageTest.java new file mode 100644 index 0000000..2aba266 --- /dev/null +++ b/src/test/java/in/ashwanthkumar/gocd/github/jsonapi/StageTest.java @@ -0,0 +1,55 @@ +package in.ashwanthkumar.gocd.github.jsonapi; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +@RunWith(Parameterized.class) +public class StageTest { + + private static List jobsRunningOrScheduled(boolean... states) { + List jobs = new ArrayList<>(states.length); + for (boolean state : states) { + Job stage = mock(Job.class); + when(stage.isRunningOrScheduled()).thenReturn(state); + when(stage.toString()).thenReturn("Job.isRunningOrScheduled=" + state); + jobs.add(stage); + } + return jobs; + } + + @Parameterized.Parameters(name = "Stage can run {0}, job statuses: {1}. Expected {2}") + public static Collection data() { + return Arrays.asList(new Object[][] { + {CanRun.YES, jobsRunningOrScheduled(false), false}, + {CanRun.NO, jobsRunningOrScheduled(true), true}, + {CanRun.YES, jobsRunningOrScheduled(true), true}, + {CanRun.YES, jobsRunningOrScheduled(false, false, true), true}, + }); + } + + private final boolean canRun; + private final List jobs; + private final boolean expected; + + public StageTest(CanRun canRun, List jobs, boolean expected) { + this.canRun = canRun.equals(CanRun.YES); + this.jobs = jobs; + this.expected = expected; + } + + @Test + public void shouldReturnCorrectStatus() { + assertThat(new Stage(canRun, jobs).isRunningOrScheduled(), is(expected)); + } +} \ No newline at end of file From 65bad1e06f2caa912b016522fae0b4fab875f104 Mon Sep 17 00:00:00 2001 From: Juha Siponen Date: Sun, 21 Aug 2016 20:11:32 +0300 Subject: [PATCH 6/7] Also check that pipeline jobs aren't running Don't allow to start a build if there is something still building. --- .../gocd/github/GitHubPRBuildPlugin.java | 21 ++-- .../gocd/github/jsonapi/PipelineHistory.java | 2 +- .../gocd/github/jsonapi/PipelineStatus.java | 6 + .../gocd/github/GitHubPRBuildPluginTest.java | 103 ++++++++++++++++++ 4 files changed, 124 insertions(+), 8 deletions(-) diff --git a/src/main/java/in/ashwanthkumar/gocd/github/GitHubPRBuildPlugin.java b/src/main/java/in/ashwanthkumar/gocd/github/GitHubPRBuildPlugin.java index d4a7eb1..a5d9c73 100644 --- a/src/main/java/in/ashwanthkumar/gocd/github/GitHubPRBuildPlugin.java +++ b/src/main/java/in/ashwanthkumar/gocd/github/GitHubPRBuildPlugin.java @@ -14,6 +14,7 @@ import com.tw.go.plugin.model.Revision; import com.tw.go.plugin.util.ListUtil; import com.tw.go.plugin.util.StringUtil; +import in.ashwanthkumar.gocd.github.jsonapi.PipelineHistory; import in.ashwanthkumar.gocd.github.jsonapi.PipelineStatus; import in.ashwanthkumar.gocd.github.jsonapi.Server; import in.ashwanthkumar.gocd.github.jsonapi.ServerFactory; @@ -371,20 +372,26 @@ GoPluginApiResponse handleLatestRevisionSince(GoPluginApiRequest goPluginApiRequ } } - private boolean canSchedule(Server server, Option pipelineName) throws IOException { - if (pipelineName.isEmpty()) { + boolean canSchedule(Server server, Option pipelineNameOption) throws IOException { + if (pipelineNameOption.isEmpty()) { LOGGER.debug("Pipeline name not given. Can schedule"); return true; } - LOGGER.info(String.format("Check can schedule pipeline %s", pipelineName.get())); + final String pipelineName = pipelineNameOption.get(); - PipelineStatus pipelineStatus = server.getPipelineStatus(pipelineName.get()); + LOGGER.info(String.format("Check can schedule pipeline %s", pipelineName)); + + PipelineStatus pipelineStatus = server.getPipelineStatus(pipelineName); if (pipelineStatus != null) { - LOGGER.info(String.format(" Pipeline schedulable: %s", pipelineStatus.schedulable)); - return pipelineStatus.schedulable; + if (pipelineStatus.schedulable) { + PipelineHistory pipelineHistory = server.getPipelineHistory(pipelineName); + return pipelineHistory == null + || !pipelineHistory.isPipelineRunningOrScheduled(); + } else { + return false; + } } else { - LOGGER.debug(" Could not fetch pipeline status. Allow to schedule"); return true; } } diff --git a/src/main/java/in/ashwanthkumar/gocd/github/jsonapi/PipelineHistory.java b/src/main/java/in/ashwanthkumar/gocd/github/jsonapi/PipelineHistory.java index 5318de3..763bb63 100644 --- a/src/main/java/in/ashwanthkumar/gocd/github/jsonapi/PipelineHistory.java +++ b/src/main/java/in/ashwanthkumar/gocd/github/jsonapi/PipelineHistory.java @@ -20,7 +20,7 @@ public List getPipelines() { return pipelines; } - boolean isPipelineRunningOrScheduled() { + public boolean isPipelineRunningOrScheduled() { for (Pipeline pipeline : pipelines) { if (pipeline.isRunningOrScheduled()) { return true; diff --git a/src/main/java/in/ashwanthkumar/gocd/github/jsonapi/PipelineStatus.java b/src/main/java/in/ashwanthkumar/gocd/github/jsonapi/PipelineStatus.java index 94541c9..a153826 100644 --- a/src/main/java/in/ashwanthkumar/gocd/github/jsonapi/PipelineStatus.java +++ b/src/main/java/in/ashwanthkumar/gocd/github/jsonapi/PipelineStatus.java @@ -7,4 +7,10 @@ public class PipelineStatus { @SerializedName("schedulable") public boolean schedulable; + public PipelineStatus() { + } + + public PipelineStatus(boolean schedulable) { + this.schedulable = schedulable; + } } diff --git a/src/test/java/in/ashwanthkumar/gocd/github/GitHubPRBuildPluginTest.java b/src/test/java/in/ashwanthkumar/gocd/github/GitHubPRBuildPluginTest.java index f253b92..f009bc7 100644 --- a/src/test/java/in/ashwanthkumar/gocd/github/GitHubPRBuildPluginTest.java +++ b/src/test/java/in/ashwanthkumar/gocd/github/GitHubPRBuildPluginTest.java @@ -10,6 +10,7 @@ import com.tw.go.plugin.model.GitConfig; import com.tw.go.plugin.model.ModifiedFile; import com.tw.go.plugin.model.Revision; +import in.ashwanthkumar.gocd.github.jsonapi.PipelineHistory; import in.ashwanthkumar.gocd.github.jsonapi.PipelineStatus; import in.ashwanthkumar.gocd.github.jsonapi.Server; import in.ashwanthkumar.gocd.github.jsonapi.ServerFactory; @@ -21,6 +22,7 @@ import in.ashwanthkumar.gocd.github.util.GitFactory; import in.ashwanthkumar.gocd.github.util.GitFolderFactory; import in.ashwanthkumar.gocd.github.util.JSONUtils; +import in.ashwanthkumar.utils.lang.option.Option; import org.apache.commons.io.FileUtils; import org.junit.After; import org.junit.Before; @@ -252,6 +254,107 @@ public void shouldBuildBlacklistedBranchIfBlacklistingNotEnabled() throws Except assertThat(response.responseCode(), is(200)); } + @Test + public void shouldSchedule() throws Exception { + GitFactory gitFactory = mock(GitFactory.class); + GitFolderFactory gitFolderFactory = mock(GitFolderFactory.class); + GitHubPRBuildPlugin plugin = new GitHubPRBuildPlugin( + new GerritProvider(), + gitFactory, + gitFolderFactory, + mockServerFactory(), + mockGoApplicationAccessor() + ); + + Server server = mock(Server.class); + when(server.getPipelineStatus("pipeline")).thenReturn(new PipelineStatus(true)); + PipelineHistory pipelineHistory = mockPipelineHistory(false); + when(server.getPipelineHistory("pipeline")).thenReturn(pipelineHistory); + + assertThat(plugin.canSchedule(server, Option.option("pipeline")), is(true)); + } + + @Test + public void shouldNotScheduleIfPipelineNotSchedulable() throws Exception { + GitFactory gitFactory = mock(GitFactory.class); + GitFolderFactory gitFolderFactory = mock(GitFolderFactory.class); + GitHubPRBuildPlugin plugin = new GitHubPRBuildPlugin( + new GerritProvider(), + gitFactory, + gitFolderFactory, + mockServerFactory(), + mockGoApplicationAccessor() + ); + + Server server = mock(Server.class); + when(server.getPipelineStatus("pipeline")).thenReturn(new PipelineStatus(false)); + PipelineHistory pipelineHistory = mockPipelineHistory(false); + when(server.getPipelineHistory("pipeline")).thenReturn(pipelineHistory); + + assertThat(plugin.canSchedule(server, Option.option("pipeline")), is(false)); + } + + @Test + public void shouldNotScheduleIfPipelineHistoryContainsRunningJobs() throws Exception { + GitFactory gitFactory = mock(GitFactory.class); + GitFolderFactory gitFolderFactory = mock(GitFolderFactory.class); + GitHubPRBuildPlugin plugin = new GitHubPRBuildPlugin( + new GerritProvider(), + gitFactory, + gitFolderFactory, + mockServerFactory(), + mockGoApplicationAccessor() + ); + + Server server = mock(Server.class); + when(server.getPipelineStatus("pipeline")).thenReturn(new PipelineStatus(true)); + PipelineHistory pipelineHistory = mockPipelineHistory(true); + when(server.getPipelineHistory("pipeline")).thenReturn(pipelineHistory); + + assertThat(plugin.canSchedule(server, Option.option("pipeline")), is(false)); + } + + @Test + public void shouldScheduleIfNoPipelineStatusFound() throws Exception { + GitFactory gitFactory = mock(GitFactory.class); + GitFolderFactory gitFolderFactory = mock(GitFolderFactory.class); + GitHubPRBuildPlugin plugin = new GitHubPRBuildPlugin( + new GerritProvider(), + gitFactory, + gitFolderFactory, + mockServerFactory(), + mockGoApplicationAccessor() + ); + + Server server = mock(Server.class); + + assertThat(plugin.canSchedule(server, Option.option("pipeline")), is(true)); + } + + @Test + public void shouldScheduleIfNoPipelineHistoryFound() throws Exception { + GitFactory gitFactory = mock(GitFactory.class); + GitFolderFactory gitFolderFactory = mock(GitFolderFactory.class); + GitHubPRBuildPlugin plugin = new GitHubPRBuildPlugin( + new GerritProvider(), + gitFactory, + gitFolderFactory, + mockServerFactory(), + mockGoApplicationAccessor() + ); + + Server server = mock(Server.class); + when(server.getPipelineStatus("pipeline")).thenReturn(new PipelineStatus(true)); + + assertThat(plugin.canSchedule(server, Option.option("pipeline")), is(true)); + } + + private PipelineHistory mockPipelineHistory(boolean isRunning) { + PipelineHistory pipelineHistory = mock(PipelineHistory.class); + when(pipelineHistory.isPipelineRunningOrScheduled()).thenReturn(isRunning); + return pipelineHistory; + } + private GoPluginApiRequest mockRequest() { GoPluginApiRequest request = mock(GoPluginApiRequest.class); when(request.requestBody()).thenReturn("{\n" + From 8c6436e5d9b8dd8bea5f5bb0bce5768635d711c4 Mon Sep 17 00:00:00 2001 From: Juha Siponen Date: Thu, 8 Sep 2016 10:52:36 +0300 Subject: [PATCH 7/7] Improve pipeline building status unit tests --- .../github/jsonapi/PipelineHistoryTest.java | 29 +++++++++++++++++++ .../gocd/github/jsonapi/PipelineTest.java | 11 +++++++ .../gocd/github/jsonapi/StageTest.java | 1 + 3 files changed, 41 insertions(+) diff --git a/src/test/java/in/ashwanthkumar/gocd/github/jsonapi/PipelineHistoryTest.java b/src/test/java/in/ashwanthkumar/gocd/github/jsonapi/PipelineHistoryTest.java index 6439741..5e96695 100644 --- a/src/test/java/in/ashwanthkumar/gocd/github/jsonapi/PipelineHistoryTest.java +++ b/src/test/java/in/ashwanthkumar/gocd/github/jsonapi/PipelineHistoryTest.java @@ -88,4 +88,33 @@ public void shouldShowPipelineNotRunnableWhenJobsBuilding() { assertThat(history.isPipelineRunningOrScheduled(), is(true)); } + @Test + public void shouldShowPipelineNotRunnableWhenOneOfMultipleJobsBuilding() { + + final boolean canRunPipeline = true; + final boolean preparingToSchedule = false; + final boolean canRunStage = true; + + List pipelines = asList( + new Pipeline( + preparingToSchedule, + canRunPipeline, + asList( + new Stage( + canRunStage, + asList( + new Job("Completed"), + new Job("Building"), + new Job("Completed") + ) + ) + ) + ) + ); + + PipelineHistory history = new PipelineHistory(pipelines); + + assertThat(history.isPipelineRunningOrScheduled(), is(true)); + } + } \ No newline at end of file diff --git a/src/test/java/in/ashwanthkumar/gocd/github/jsonapi/PipelineTest.java b/src/test/java/in/ashwanthkumar/gocd/github/jsonapi/PipelineTest.java index f7c2382..21c47b5 100644 --- a/src/test/java/in/ashwanthkumar/gocd/github/jsonapi/PipelineTest.java +++ b/src/test/java/in/ashwanthkumar/gocd/github/jsonapi/PipelineTest.java @@ -44,6 +44,17 @@ public static Collection data() { {PreparingToSchedule.YES, CanRun.NO, stagesRunningOrScheduled(false), true}, {PreparingToSchedule.NO, CanRun.YES, stagesRunningOrScheduled(false), false}, {PreparingToSchedule.NO, CanRun.NO, stagesRunningOrScheduled(false), true}, + + // Multiple stages + {PreparingToSchedule.YES, CanRun.YES, stagesRunningOrScheduled(false, false, true), true}, + {PreparingToSchedule.YES, CanRun.NO, stagesRunningOrScheduled(false, false, true), true}, + {PreparingToSchedule.NO, CanRun.YES, stagesRunningOrScheduled(false, false, true), true}, + {PreparingToSchedule.NO, CanRun.NO, stagesRunningOrScheduled(false, false, true), true}, + + {PreparingToSchedule.YES, CanRun.YES, stagesRunningOrScheduled(false, false, true, false), true}, + {PreparingToSchedule.YES, CanRun.NO, stagesRunningOrScheduled(false, false, true, false), true}, + {PreparingToSchedule.NO, CanRun.YES, stagesRunningOrScheduled(false, false, true, false), true}, + {PreparingToSchedule.NO, CanRun.NO, stagesRunningOrScheduled(false, false, true, false), true}, }); } diff --git a/src/test/java/in/ashwanthkumar/gocd/github/jsonapi/StageTest.java b/src/test/java/in/ashwanthkumar/gocd/github/jsonapi/StageTest.java index 2aba266..aba52cb 100644 --- a/src/test/java/in/ashwanthkumar/gocd/github/jsonapi/StageTest.java +++ b/src/test/java/in/ashwanthkumar/gocd/github/jsonapi/StageTest.java @@ -35,6 +35,7 @@ public static Collection data() { {CanRun.NO, jobsRunningOrScheduled(true), true}, {CanRun.YES, jobsRunningOrScheduled(true), true}, {CanRun.YES, jobsRunningOrScheduled(false, false, true), true}, + {CanRun.YES, jobsRunningOrScheduled(false, true, false), true}, }); }