From 8fd406f4dc451b4cf32ba99898f55b9ccf9d88d1 Mon Sep 17 00:00:00 2001 From: stolp Date: Wed, 25 Mar 2015 15:53:00 +0000 Subject: [PATCH] JENKINS-27592: Support multiple test result set specifications for uploading Task-Url: https://issues.jenkins-ci.org/browse/JENKINS-27592 --- .../klaros/KlarosTestResultPublisher.java | 255 +++++++++++------- .../java/hudson/plugins/klaros/ResultSet.java | 26 ++ .../KlarosTestResultPublisher/config.jelly | 19 +- .../config.properties | 3 +- .../config_de.properties | 3 +- 5 files changed, 205 insertions(+), 101 deletions(-) create mode 100644 src/main/java/hudson/plugins/klaros/ResultSet.java diff --git a/src/main/java/hudson/plugins/klaros/KlarosTestResultPublisher.java b/src/main/java/hudson/plugins/klaros/KlarosTestResultPublisher.java index 74b54ae..3f55645 100644 --- a/src/main/java/hudson/plugins/klaros/KlarosTestResultPublisher.java +++ b/src/main/java/hudson/plugins/klaros/KlarosTestResultPublisher.java @@ -25,14 +25,14 @@ import hudson.Extension; import hudson.FilePath; +import hudson.FilePath.FileCallable; import hudson.Launcher; import hudson.Util; -import hudson.FilePath.FileCallable; +import hudson.model.BuildListener; +import hudson.model.Result; import hudson.model.AbstractBuild; import hudson.model.AbstractProject; -import hudson.model.BuildListener; import hudson.model.Hudson; -import hudson.model.Result; import hudson.remoting.VirtualChannel; import hudson.tasks.BuildStepDescriptor; import hudson.tasks.BuildStepMonitor; @@ -53,6 +53,7 @@ import net.sf.json.JSONObject; import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.HttpException; import org.apache.commons.httpclient.methods.FileRequestEntity; import org.apache.commons.httpclient.methods.PutMethod; import org.apache.commons.httpclient.methods.RequestEntity; @@ -88,9 +89,16 @@ public class KlarosTestResultPublisher extends Recorder implements Serializable /** The type. */ private String type = "junit"; - /** The path test results. */ + /** + * The path test results. + * + * @deprecated since 1.5 + */ private String pathTestResults; + /** The test result sets. */ + private ResultSet[] resultSets = new ResultSet[0]; + /** The Klaros URL to connect to. */ private String url; @@ -108,6 +116,7 @@ public class KlarosTestResultPublisher extends Recorder implements Serializable * @param sut the Klaros system under test to use * @param type the type of test result to import * @param pathTestResults the path to the test results + * @param resultSets the test result sets * @param url the Klaros application url * @param username the optional Klaros login user name * @param password the optional Klaros login password @@ -115,12 +124,19 @@ public class KlarosTestResultPublisher extends Recorder implements Serializable @DataBoundConstructor public KlarosTestResultPublisher(final String config, final String env, final String sut, final String type, final String pathTestResults, - final String url, final String username, final String password) { + final ResultSet[] resultSets, final String url, final String username, + final String password) { this.config = config; this.env = env; this.sut = sut; this.pathTestResults = pathTestResults; + this.resultSets = resultSets; + // Migrate old settings + if (StringUtils.isNotEmpty(pathTestResults)) { + this.resultSets = new ResultSet[]{new ResultSet(StringUtils + .trim(pathTestResults)) }; + } this.url = url; this.username = username; this.password = password; @@ -261,6 +277,7 @@ public void setSut(final String value) { * Gets the path test results. * * @return the path test results + * @deprecated use getResultSets() instead */ public String getPathTestResults() { @@ -271,12 +288,33 @@ public String getPathTestResults() { * Sets the path test results. * * @param value the new path test results + * @deprecated use setResultSets() instead */ public void setPathTestResults(final String value) { pathTestResults = StringUtils.trim(value); } + /** + * Gets the result sets. + * + * @return the result sets + */ + public ResultSet[] getResultSets() { + + return resultSets; + } + + /** + * Sets the result sets. + * + * @param values the new result sets + */ + public void setResultSets(ResultSet[] values) { + + resultSets = values; + } + /** * Gets the urls. * @@ -321,44 +359,47 @@ public String getKlarosUrl(final String sourceURL) { public boolean perform(final AbstractBuild build, final Launcher launcher, final BuildListener listener) { - final boolean result; + boolean result = false; - if (pathTestResults == null) { - listener.getLogger().println("There are no test result to import!"); + FilePath ws = build.getWorkspace(); + if (ws == null) { + listener.error("No workspace defined!"); + build.setResult(Result.FAILURE); result = false; } else { - listener.getLogger().println( - "The test result(s) contained in target " + pathTestResults - + " will be exported to the " - + "Klaros-Testmanagement Server at " + getUrl(url) + "."); - listener.getLogger().println( - "With parameters Project[" + config + "], Environment[" + env - + "], SUT[" + sut + "] and Type[" + type + "]."); - - FilePath ws = build.getWorkspace(); - if (ws == null) { - listener.error("No workspace defined!"); - build.setResult(Result.FAILURE); - result = false; - } else { + for (ResultSet resultSet : getResultSets()) { + if (StringUtils.isEmpty(resultSet.getSpec())) { + listener.getLogger().println( + "Empty result spec implementation detected"); + } else { + listener.getLogger().println( + "The test result(s) contained in target " + + resultSet.getSpec() + " will be exported to the " + + "Klaros-Testmanagement Server at " + getUrl(url) + + "."); + listener.getLogger().println( + "With parameters Project[" + config + "], Environment[" + env + + "], SUT[" + sut + "] and Type[" + type + "]."); - try { - FileCallableImplementation exporter = new FileCallableImplementation( - listener); - exporter.setKlarosUrl(getKlarosUrl(url)); - ws.act(exporter); - - } catch (IOException e) { - listener.getLogger().println("Failure to export test result(s)."); - e.printStackTrace(listener.getLogger()); - } catch (InterruptedException e) { - listener.getLogger().println("Failure to export test result(s)."); - e.printStackTrace(listener.getLogger()); - } + try { + FileCallableImplementation exporter = new FileCallableImplementation( + listener); + exporter.setKlarosUrl(getKlarosUrl(url)); + exporter.setResultSet(resultSet); + ws.act(exporter); - listener.getLogger().println("Test result(s) successfully exported."); + } catch (IOException e) { + listener.getLogger().println("Failure to export test result(s)."); + e.printStackTrace(listener.getLogger()); + } catch (InterruptedException e) { + listener.getLogger().println("Failure to export test result(s)."); + e.printStackTrace(listener.getLogger()); + } - result = true; + listener.getLogger().println("Test result(s) successfully exported."); + + result = true; + } } } return result; @@ -430,10 +471,9 @@ private final class FileCallableImplementation implements FileCallable invoke(final File baseDir, final VirtualChannel channel) List results = new ArrayList(); - FileSet src = Util.createFileSet(baseDir, pathTestResults); + FileSet src = Util.createFileSet(baseDir, resultSet.getSpec()); DirectoryScanner ds = src.getDirectoryScanner(); ds.scan(); if (ds.getIncludedFilesCount() == 0) { @@ -469,9 +509,13 @@ public List invoke(final File baseDir, final VirtualChannel channel) // Get target URL String targetUrl = klarosUrl; + if (targetUrl != null) { String strURL = buildServletURL(targetUrl); + // Get HTTP client + HttpClient httpclient = new HttpClient(); + // Prepare HTTP PUT for (String f : ds.getIncludedFiles()) { PutMethod put = new PutMethod(strURL); @@ -486,37 +530,34 @@ public List invoke(final File baseDir, final VirtualChannel channel) File file = new File(baseDir, f); int result; + + RequestEntity entity = new FileRequestEntity(file, + "text/xml; charset=ISO-8859-1"); + put.setRequestEntity(entity); + + // Execute request try { - RequestEntity entity = new FileRequestEntity(file, - "text/xml; charset=ISO-8859-1"); - put.setRequestEntity(entity); - // Get HTTP client - HttpClient httpclient = new HttpClient(); - - // Execute request - try { - result = httpclient.executeMethod(put); - - if (result != HttpServletResponse.SC_OK) { - StringBuffer msg = new StringBuffer() - .append("Export of ").append(file.getName()) - .append(" failed - Response status code: ") - .append(result).append(" for request URL: ") - .append(strURL).append("?").append(query); - String response = new String(put.getResponseBody()); - if (response != null && response.length() > 0) { - msg.append("\nReason: ").append(response); - } - listener.getLogger().println(msg.toString()); - } else { - results.add(result); - listener.getLogger().println( - "Test result file " + file.getName() - + " has been successfully exported."); + result = httpclient.executeMethod(put); + + if (result != HttpServletResponse.SC_OK) { + StringBuffer msg = new StringBuffer().append("Export of ") + .append(file.getName()).append( + " failed - Response status code: ").append( + result).append(" for request URL: ").append( + strURL).append("?").append(query); + String response = new String(put.getResponseBody()); + if (response != null && response.length() > 0) { + msg.append("\nReason: ").append(response); } - } catch (Exception e) { - e.printStackTrace(listener.getLogger()); + listener.getLogger().println(msg.toString()); + } else { + results.add(result); + listener.getLogger().println( + "Test result file " + file.getName() + + " has been successfully exported."); } + } catch (Exception e) { + e.printStackTrace(listener.getLogger()); } finally { // Release current connection to the connection pool // once you @@ -531,14 +572,24 @@ public List invoke(final File baseDir, final VirtualChannel channel) return results; } + /** + * Sets the result set to deliver the results from. + * + * @param value the new result set + */ + private void setResultSet(final ResultSet value) { + + resultSet = value; + } + /** * Sets the Klaros url to deliver the results to. * - * @param url the new klaros url + * @param value the new klaros url */ - private void setKlarosUrl(final String url) { + private void setKlarosUrl(final String value) { - klarosUrl = url; + klarosUrl = value; } } @@ -660,7 +711,7 @@ protected FormValidation check() throws IOException, ServletException { result = FormValidation.ok(); } else { result = FormValidation.error( // - "This is a valid URL but it doesn't look like Klaros-Testmanagement"); + "This URL does not point to a running Klaros-Testmanagement installation"); } } catch (IOException e) { result = handleIOException(value, e); @@ -728,38 +779,50 @@ public FormValidation doTestConnection(@QueryParameter final String url, query.append("username=").append(username).append("&password=").append( password).append("&type=").append("check"); } - System.out.println(strURL + '?' + query.toString()); put.setQueryString(query.toString()); try { RequestEntity entity = new StringRequestEntity("", "text/xml; charset=UTF-8", "UTF-8"); put.setRequestEntity(entity); - int result; - try { - HttpClient client = new HttpClient(); - result = client.executeMethod(put); - String response = ""; - if (result != HttpServletResponse.SC_OK) { - StringBuffer msg = new StringBuffer(); - response = new String(put.getResponseBody()); - if (response != null && response.length() > 0) { - msg.append("Connection failed: ").append(response); - System.out.println(msg.toString()); - } - return FormValidation.error(msg.toString()); + return putResultFile(put); + } catch (Exception e) { + return FormValidation.error(e.getMessage()); + } + } + + /** + * HTTP Put the result file. + * + * @param put the put request + * @return the form validation + * @throws IOException Signals that an I/O exception has occurred. + * @throws HttpException the http exception + */ + private FormValidation putResultFile(PutMethod put) throws IOException, + HttpException { + + try { + HttpClient client = new HttpClient(); + int result = client.executeMethod(put); + String response = ""; + if (result != HttpServletResponse.SC_OK) { + StringBuffer msg = new StringBuffer(); + response = new String(put.getResponseBody()); + if (response != null && response.length() > 0) { + msg.append("Connection failed: ").append(response); + System.out.println(msg.toString()); + } + return FormValidation.error(msg.toString()); + } else { + if (response != null && response.length() > 0) { + return FormValidation.ok(Messages.ConnectionEstablished() + ": " + + response); } else { - if (response != null && response.length() > 0) { - return FormValidation.ok(Messages.ConnectionEstablished() - + ": " + response); - } else { - return FormValidation.ok(Messages.ConnectionEstablished()); - } + return FormValidation.ok(Messages.ConnectionEstablished()); } - } finally { - put.releaseConnection(); } - } catch (Exception e) { - return FormValidation.error(e.getMessage()); + } finally { + put.releaseConnection(); } } } diff --git a/src/main/java/hudson/plugins/klaros/ResultSet.java b/src/main/java/hudson/plugins/klaros/ResultSet.java new file mode 100644 index 0000000..37654cb --- /dev/null +++ b/src/main/java/hudson/plugins/klaros/ResultSet.java @@ -0,0 +1,26 @@ +package hudson.plugins.klaros; + +import org.apache.commons.lang.StringUtils; +import org.kohsuke.stapler.DataBoundConstructor; + +public class ResultSet { + + private String spec; + + @DataBoundConstructor + public ResultSet(String spec) { + + this.spec = StringUtils.trim(spec); + } + + public String getSpec() { + + return spec; + } + + + public void setSpec(String spec) { + + this.spec = StringUtils.trim(spec); + } +} \ No newline at end of file diff --git a/src/main/resources/hudson/plugins/klaros/KlarosTestResultPublisher/config.jelly b/src/main/resources/hudson/plugins/klaros/KlarosTestResultPublisher/config.jelly index f12967e..ca2876b 100644 --- a/src/main/resources/hudson/plugins/klaros/KlarosTestResultPublisher/config.jelly +++ b/src/main/resources/hudson/plugins/klaros/KlarosTestResultPublisher/config.jelly @@ -76,10 +76,23 @@ - - + + + + + + + +
+ +
+
+
+
diff --git a/src/main/resources/hudson/plugins/klaros/KlarosTestResultPublisher/config.properties b/src/main/resources/hudson/plugins/klaros/KlarosTestResultPublisher/config.properties index 6e47b7e..1b89587 100644 --- a/src/main/resources/hudson/plugins/klaros/KlarosTestResultPublisher/config.properties +++ b/src/main/resources/hudson/plugins/klaros/KlarosTestResultPublisher/config.properties @@ -25,7 +25,8 @@ KlarosInstallationDescription=At least one installation must be defined in the g ProjectID=Project ID TestEnvironmentID=Test Environment ID SystemUnderTestID=System Under Test (SUT) ID -TestReportFiles=Test Report Files +TestResultSpec=Path +TestResults=Test Results UseAuthentication=Use Authentication Username=Username Password=Password diff --git a/src/main/resources/hudson/plugins/klaros/KlarosTestResultPublisher/config_de.properties b/src/main/resources/hudson/plugins/klaros/KlarosTestResultPublisher/config_de.properties index d5c4a74..2c12944 100644 --- a/src/main/resources/hudson/plugins/klaros/KlarosTestResultPublisher/config_de.properties +++ b/src/main/resources/hudson/plugins/klaros/KlarosTestResultPublisher/config_de.properties @@ -25,7 +25,8 @@ KlarosInstallationDescription=Mindestens eine Serverinstallation muss in der glo ProjectID=Projekt-ID TestEnvironmentID=Testumgebungs-ID SystemUnderTestID=SUT-ID -TestReportFiles=Test Report Dateien +TestResultSpec=Pfad +TestResults=Testergebnisse UseAuthentication=Authentifizierung benutzen Username=Benutzername Password=Passwort