Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Model Center   Code  
»áÔ±   
   
 
     
   
 ¶©ÔÄ
  ¾èÖú
jenkins²å¼þ¿ª·¢±Ê¼Ç
 
  2402  次浏览      27
 2018-2-8 
 
±à¼­ÍƼö:
±¾ÎÄÀ´×ÔÓÚcsdn,Jenkins²å¼þgettingCase¿ª·¢,gettingCase¹¦ÄÜ»ñÈ¡RallyDevÉϵÄijһ¸öTest CaseÐÅÏ¢¡£

µÚÒ»´Î×öJenkins²å¼þ¿ª·¢,Ë콫±Ê¼Ç¹«¿ª·ÖÏí

²å¼þÃû³Æ: gettingCase

²å¼þ¹¦ÄÜ: »ñÈ¡RallyDevÉϵÄijһ¸öTest CaseÐÅÏ¢

0.ÅäÖÃ.m2/settings.xml

Çë²éÔı¾ÎÄ×îºóµÄ²Î¿¼×ÊÁÏ

1.Maven´´½¨Jenkins²å¼þÏîÄ¿

mvn -U org.jenkins-ci.tools:maven-hpi-plugin:create

µÚÒ»´ÎÖ´Ðлá±È½ÏÂý,ÒòΪÐèÒªÏÂÔØºÜ¶àMaven²å¼þ.

Õâ¸ö´´½¨ÏîÄ¿µÄ¹ý³ÌÓÐ2²½»¥¶¯:

µÚÒ»²½ÐèÒª¿ª·¢ÕßÊäÈëMavenÏîÄ¿µÄgroupId

Enter the groupId of your plugin [org.jenkins-ci.plugins]:

com.technicolor.qcs

µÚ¶þ²½ÐèÒª¿ª·¢ÕßÊäÈëMavenÏîÄ¿µÄartifactId

Enter the artifactId of your plugin (normally without '-plugin' suffix):

gettingCase

2.»ùÓÚHello World²å¼þÏîÄ¿,ÐÞ¸ÄÒÔʵÏÖ×Ô¼º²å¼þ¹¦ÄÜ

2.1POM

ÐÞ¸Äpom.xmlÎļþ,Ôö¼ÓREST·ÃÎÊRallyDevµÄ¹¤¾ß°ü

Xml´úÂë
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>plugin</artifactId>
<version>1.509.3</version>
<!-- which version of Jenkins is this plugin built against? -->
</parent>

<groupId>com.technicolor.qcs</groupId>
<artifactId>gettingCase</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>hpi</packaging>
<description>Gets Rally Test Cases</description>

<developers>
<developer>
<id>feuyeux</id>
<name>eric han</name>
<email>feuyeux@gmail.com</email>
</developer>
</developers>
<dependencies>
<dependency>
<groupId>com.rallydev.rest</groupId>
<artifactId>rally-rest-api</artifactId>
<version>2.0.4</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<version>4.2.1</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.2.1</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient-cache</artifactId>
<version>4.2.1</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
<version>4.2.1</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>fluent-hc</artifactId>
<version>4.2.1</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.1</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.6</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.1</version>
</dependency>
</dependencies>

<repositories>
<repository>
<id>repo.jenkins-ci.org</id>
<url>http://repo.jenkins-ci.org/public/</url>
</repository>
</repositories>

<pluginRepositories>
<pluginRepository>
<id>repo.jenkins-ci.org</id>
<url>http://repo.jenkins-ci.org/public/</url>
</pluginRepository>
</pluginRepositories>
</project>

2.2 ±àдȫ¾ÖÅäÖÃÒ³Ãæ

/home/hanl/j-ci/gettingCase/src /main/resources/com/technicolor/qcs /gettingCase/GetCasesBuilder/global.jelly

Java´úÂë

<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form">
<f:section title="Getting Test Cases Builder">
<f:entry title="RallyDev User Name" field="userName">
<f:textbox />
</f:entry>
<f:entry title="RallyDev Password" field="password">
<f:password/>
</f:entry>

<f:entry title="HTTP Proxy URL" field="proxyURL">
<f:textbox />
</f:entry>
<f:entry title="RallyDev Proxy User Name" field="proxyUser">
<f:textbox />
</f:entry>
<f:entry title="RallyDev Proxy Password" field="proxyPassword">
<f:password />
</f:entry>
</f:section>
</j:jelly>

2.3 ±àдJOBÅäÖÃÒ³Ãæ

Java´úÂë

1 app HudsonÓ¦ÓóÌÐò¶ÔÏó
${app.displayName}. //Ó¦ÓõÄDisplayÃû³Æ

2 it µ±Ç°UIËùÊôµÄÄ£ÐͶÔÏó
${it.name} ¶ÔÓ¦ÓÚbuilderµÄgetName()·½·¨

3 h Ò»¸öÈ«¾ÖµÄ¹¤¾ßÀ࣬Ìṩ¾²Ì¬¹¤¾ß·½·¨

/home/hanl/j-ci/gettingCase/ src/main/resources/com/technicolor /qcs/gettingCase/GetCasesBuilder/config.jelly

Java´úÂë

<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form">
<f:entry title="Test Case No." field="testCaseId">
<f:textbox />
</f:entry>
</j:jelly>

2.4 ±àдÀ©Õ¹µã·½·¨

Java´úÂë

Ò»´Î¹¹½¨¹ý³Ìͨ³£°üÀ¨£º
SCM checkout - check out³öÔ´Âë
Pre-build - Ô¤±àÒë
Build wrapper -×¼±¸¹¹½¨µÄ»·¾³£¬ÉèÖû·¾³±äÁ¿µÈ
Builder runs - Ö´Ðй¹½¨£¬±ÈÈçµ÷ÓÃcalling Ant, Make
Recording - ¼Ç¼Êä³ö£¬Èç²âÊÔ½á¹û
Notification - ֪ͨ³ÉÔ±

/home/hanl/j-ci/gettingCase/ src/main/java/com/technicolor/ qcs/gettingCase/GetCasesBuilder.java

Java´úÂë

package com.technicolor.qcs.gettingCase;

import hudson.Launcher;
import hudson.Extension;
import hudson.util.FormValidation;
import hudson.model.AbstractBuild;
import hudson.model.BuildListener;
import hudson.model.AbstractProject;
import hudson.tasks.Builder;
import hudson.tasks.BuildStepDescriptor;
import net.sf.json.JSONObject;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.QueryParameter;

import javax.servlet.ServletException;
import java.io.IOException;
import java.io.PrintStream;

/**
* author:feuyeux
*/
public class GetCasesBuilder extends Builder {
public static final String RALLY_URL = "https://rally1.rallydev.com";
private final String testCaseId;

@DataBoundConstructor
public GetCasesBuilder(String testCaseId) {
this.testCaseId = testCaseId;
}

public String getTestCaseId() {
return testCaseId;
}

@Override
public boolean perform(AbstractBuild build, Launcher launcher, BuildListener listener) {
PrintStream out = listener.getLogger();
final String userName = getDescriptor().getUserName();
final String password = getDescriptor().getPassword();
final String proxyURL = getDescriptor().getProxyURL();
final String proxyUser = getDescriptor().getProxyUser();
final String proxyPassword = getDescriptor().getProxyPassword();

out.println("RallyDev User Name =" + userName);
out.println("HTTP Proxy=" + proxyUser + "@" + proxyURL);
out.println("RallyDev Test Case =" + getTestCaseId()+"\n");
RallyClient rallyClient = null;
try {
rallyClient = new RallyClient(RALLY_URL, userName, password, proxyURL, proxyUser, proxyPassword);
String caseInfo = rallyClient.getTestCases(testCaseId);
out.println(caseInfo);
} catch (Exception e) {
out.println(e.getMessage());
} finally {
try {
rallyClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return true;
}

@Override
public DescriptorImpl getDescriptor() {
return (DescriptorImpl) super.getDescriptor();
}

@Extension
public static final class DescriptorImpl extends BuildStepDescriptor<Builder> {
private String userName;
private String password;
private String proxyURL;
private String proxyUser;
private String proxyPassword;

public FormValidation doCheckName(@QueryParameter String value)
throws IOException, ServletException {
if (value.length() == 0)
return FormValidation.error("Please set a testCaseId");
return FormValidation.ok();
}

public boolean isApplicable(Class<? extends AbstractProject> aClass) {
return true;
}

public String getDisplayName() {
return "Getting Test cases from Rally";
}

@Override
public boolean configure(StaplerRequest req, JSONObject formData) throws FormException {
userName = formData.getString("userName");
password = formData.getString("password");
proxyURL = formData.getString("proxyURL");
proxyUser = formData.getString("proxyUser");
proxyPassword = formData.getString("proxyPassword");
save();
return super.configure(req, formData);
}

public String getUserName() {
return userName;
}

public String getPassword() {
return password;
}

public String getProxyURL() {
return proxyURL;
}

public String getProxyUser() {
return proxyUser;
}

public String getProxyPassword() {
return proxyPassword;
}
}
}

2.5 ±àдRallyDevÁ¬½ÓºÍ·ÃÎÊ·½·¨

/home/hanl/j-ci/gettingCase/src/ main/java/com/technicolor/ qcs/gettingCase/RallyClient.java

Java´úÂë

package com.technicolor.qcs.gettingCase;

import com.google.gson.JsonObject;
import com.rallydev.rest.RallyRestApi;
import com.rallydev.rest.request.GetRequest;
import com.rallydev.rest.response.GetResponse;
import com.rallydev.rest.response.Response;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;

/**
* author:feuyeux
*/
public class RallyClient {
/*https://github.com/RallyTools/RallyRestToolkitForJavahttps: //github.com/RallyTools/RallyRestToolkitForJava */
private final RallyRestApi restApi;

public RallyClient(String rally_url, String userName, String password, String proxyURL, String proxyUser, String proxyPassword) throws URISyntaxException {
restApi = new RallyRestApi(new URI(rally_url), userName, password);
restApi.setProxy(new URI(proxyURL), proxyUser, proxyPassword);
}

public void close() throws IOException {
restApi.close();
}

public String getTestCases(String testCaseId) {
/*https://rally1.rallydev.com/slm/doc/webservice/*/
StringBuilder result = new StringBuilder();

String version = restApi.getWsapiVersion();
result.append("RallyDev Rest Version=").append(version).append("\n");

final String query = "/testcase/"+testCaseId;
GetRequest queryRequest = new GetRequest(query);
GetResponse casesResponse = null;
try {
casesResponse = restApi.get(queryRequest);
} catch (IOException e) {
e.printStackTrace();
}
printWarningsOrErrors(casesResponse, result);
JsonObject caseJsonObject = casesResponse.getObject();

result.append("\n").append("Test Case Name: ").append(caseJsonObject.get("Name").getAsString());
result.append("\n").append("Test Case Type: ").append(caseJsonObject.get("Type").getAsString());
result.append("\n").append("Test Case URL: ").append(caseJsonObject.get("_ref").getAsString());
result.append("\n").append("Test Case Creation Time: ").append(caseJsonObject.get("CreationDate").getAsString());
result.append("\n").append("Test Case LastUpdate Time: ").append(caseJsonObject.get("LastUpdateDate").getAsString());
result.append("\n").append("Test Case's Project: ").append( caseJsonObject.get("Project").getAsJsonObject().get("_refObjectName") .getAsString());
result.append("\n").append("Test Case's Workspace: ").append( caseJsonObject.get("Workspace").getAsJsonObject().get("_refObjectName") .getAsString());

return result.toString();
}

private void printWarningsOrErrors(Response response, StringBuilder result) {
if (response.wasSuccessful()) {
result.append("\nSuccess.");
String[] warningList;
warningList = response.getWarnings();
for (int i = 0; i < warningList.length; i++) {
result.append("\twarning:\n" + warningList[i]);
}
} else {
String[] errorList;
errorList = response.getErrors();
if (errorList.length > 0) {
result.append("\nError.");

}
for (int i = 0; i < errorList.length; i++) {
result.append("\terror:\n" + errorList[i]);
}
}
}
}

3.µ÷ÊÔPlugin³ÌÐò

ÔÚÖÕ¶Ë/¿ØÖÆÌ¨,Ê×ÏÈÖ´ÐÐMaven±äÁ¿ÅäÖÃÃüÁî

Python´úÂë

set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport= dt_socket,server= y,address= 8000, suspend = n

cdµ½²å¼þÏîĿĿ¼,Ö´ÐÐÈçÏÂÃüÁî

Python´úÂë

hanl@hanl-ubuntu1204:~/j-ci/gettingCase$ mvn clean
hanl@hanl-ubuntu1204:~/j-ci/gettingCase$ mvnDebug hpi:run

Maven½«¶Ô8000¶Ë¿ÚÖ´ÐмàÌý,ÒÔ±ãÔÚIDEÖнøÐжϵãµ÷ÊÔ

Python´úÂë

Preparing to Execute Maven in Debug Mode
Listening for transport dt_socket at address: 8000

½øÈëIDE(±¾ÀýʹÓÃIntelliJ),Ñ¡ÔñRun²Ëµ¥µÄDebug,Ìí¼ÓÒ»¸ö8000¶Ë¿ÚµÄÔ¶³Ì·þÎñÆ÷

Ìí¼Ó¶Ïµã,µã»÷×óϽÇÔËÐе÷ÊÔ°´Å¥

´Ëʱ,Öն˽«Ö´ÐÐMaven¹¹½¨,²¢Æô¶¯Jetty·þÎñÆ÷.

Python´úÂë

hanl@hanl-ubuntu1204:~/j-ci/gettingCase$ mvnDebug hpi:run
Preparing to Execute Maven in Debug Mode
Listening for transport dt_socket at address: 8000
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building gettingCase 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] >>> maven-hpi-plugin:1.95:run (default-cli) @ gettingCase >>>
[INFO]
[INFO] --- maven-hpi-plugin:1.95:validate (default-validate) @ gettingCase ---
[INFO]
[INFO] --- maven-enforcer-plugin:1.0.1:enforce (enforce-maven) @ gettingCase ---
[INFO]
[INFO] --- maven-enforcer-plugin:1.0.1:display-info (display-info) @ gettingCase ---
[INFO] Maven Version: 3.0.4
[INFO] JDK Version: 1.7.0_25 normalized as: 1.7.0-25
[INFO] OS Info: Arch: amd64 Family: unix Name: linux Version: 3.2.0-54-generic
[INFO]
[INFO] --- maven-localizer-plugin:1.14:generate (default) @ gettingCase ---
[INFO]
[INFO] --- maven-resources-plugin:2.5:resources (default-resources) @ gettingCase ---
[debug] execute contextualize
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 5 resources
[INFO]
[INFO] --- maven-compiler-plugin:2.5:compile (default-compile) @ gettingCase ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] <<< maven-hpi-plugin:1.95:run (default-cli) @ gettingCase <<<
[INFO]
[INFO] --- maven-hpi-plugin:1.95:run (default-cli) @ gettingCase ---
[INFO] Generating ./work/plugins/gettingCase.hpl
[INFO] Copying dependency Jenkins plugin /home/hanl/.m2/repository/org/jenkins-ci/plugins/mailer/1.4/mailer-1.4.jar
[INFO] Copying dependency Jenkins plugin /home/hanl/.m2/repository/org/jenkins-ci/plugins/ant/1.1/ant-1.1.jar
[INFO] Copying dependency Jenkins plugin /home/hanl/.m2/repository/org/jenkins-ci/main/maven-plugin/1.509.3/maven-plugin-1.509.3.jar
[INFO] Copying dependency Jenkins plugin /home/hanl/.m2/repository/org/jenkins-ci/plugins/javadoc/1.0/javadoc-1.0.jar
[INFO] Copying dependency Jenkins plugin /home/hanl/.m2/repository/org/jenkins-ci/plugins/subversion/1.26/subversion-1.26.jar
[INFO] Copying dependency Jenkins plugin /home/hanl/.m2/repository/org/jenkins-ci/main/ui-samples-plugin/1.509.3/ui-samples-plugin-1.509.3.jar
[INFO] Configuring Jetty for project: gettingCase
2013-10-10 18:10:55.444::INFO: Logging to STDERR via org.mortbay.log.StdErrLog
[INFO] Context path = /jenkins
[INFO] Tmp directory = /home/hanl/j-ci/gettingCase/target/work
[INFO] Web defaults = jetty default
[INFO] Starting jetty 6.1.1 ...
2013-10-10 18:10:55.587::INFO: jetty-6.1.1
Jenkins home directory: /home/hanl/j-ci/gettingCase/./work found at: System.getProperty("HUDSON_HOME")
2013-10-10 18:10:59.572::INFO: Started SelectChannelConnector @ 0.0.0.0:8080
[INFO] Started Jetty Server
[INFO] Console reloading is ENABLED. Hit ENTER on the console to restart the context.
Oct 10, 2013 6:10:59 PM jenkins.InitReactorRunner$1 onAttained
INFO: Started initialization
Oct 10, 2013 6:11:01 PM jenkins.InitReactorRunner$1 onAttained
INFO: Listed all plugins
Oct 10, 2013 6:11:01 PM jenkins.InitReactorRunner$1 onAttained
INFO: Prepared all plugins
Oct 10, 2013 6:11:01 PM jenkins.InitReactorRunner$1 onAttained
INFO: Started all plugins
Oct 10, 2013 6:11:01 PM jenkins.InitReactorRunner$1 onAttained
INFO: Augmented all extensions
Oct 10, 2013 6:11:04 PM jenkins.InitReactorRunner$1 onAttained
INFO: Loaded all jobs
Oct 10, 2013 6:11:05 PM org.jenkinsci.main.modules.sshd.SSHD start
INFO: Started SSHD at port 54676
Oct 10, 2013 6:11:05 PM jenkins.InitReactorRunner$1 onAttained
INFO: Completed initialization
Oct 10, 2013 6:11:05 PM hudson.TcpSlaveAgentListener <init>
INFO: JNLP slave agent listener started on TCP port 47342
Oct 10, 2013 6:11:05 PM hudson.WebAppMain$2 run
INFO: Jenkins is fully up and running

4.²âÊÔ

ÔÚä¯ÀÀÆ÷ÖмÈëJenkinsµØÖ·,´´½¨Job²¢°´ÕÕÉÏÊöµÄÅäÖû·½Ú,Íê³ÉÅäÖÃ.

Ö´ÐÐBuild Job

´Ëʱ,¶ÏµãÓ¦Æä×÷ÓÃ,¿ÉÒÔÔÚIDEÖнøÐе÷ÊÔºÍ¼à¿Ø.

µ±Íê³Éµ÷ÊÔºó,½øÈëJenkins¹¹½¨½á¹ûÒ³Ãæ,¹Û²ì¹¹½¨½á¹ûÊÇ·ñ·ûºÏÔ¤ÆÚ.

µ½´Ë,»ñÈ¡²¢ÏÔʾRallyDevÖÐTest CaseµÄJenkins²å¼þ¿ª·¢Íê±Ï.

IntelliJ IDE ²å¼þ£º

https://wiki.jenkins-ci.org/display/JENKINS/IntelliJ+IDEA+plugin+for+Stapler

Stapler plugin for IntelliJ IDEA

²Î¿¼×ÊÁÏ

https://wiki.jenkins-ci.org/display/JENKINS/Plugin+tutorial

https://github.com/jenkinsci/hello-world-plugin

https://jenkins-ci.org/maven-site/jenkins-core/jelly-taglib-ref.html

ui-samples: http://localhost:8080/jenkins/ui-samples/

À©Õ¹µã£º https://wiki.jenkins-ci.org/display/JENKINS/Extension+points

Java´úÂë

<f:entry title="Test Station">
<select class="setting-input" name="AndroidBuilder.stationUrl">
<j:forEach var="inst" items="${descriptor.stations}">
<f:option selected="${inst.url==instance.stationUrl}">${inst.url}</f:option>
</j:forEach>
</select>
</f:entry>
   
2402 ´Îä¯ÀÀ       27
Ïà¹ØÎÄÕÂ

ΪʲôҪ×ö³ÖÐø²¿Êð£¿
ÆÊÎö¡°³ÖÐø½»¸¶¡±£ºÎå¸öºËÐÄʵ¼ù
¼¯³ÉÓë¹¹½¨Ö¸ÄÏ
³ÖÐø¼¯³É¹¤¾ßµÄÑ¡Ôñ-×°ÔØ
Ïà¹ØÎĵµ

³ÖÐø¼¯³É½éÉÜ
ʹÓÃHudson³ÖÐø¼¯³É
³ÖÐø¼¯³ÉÖ®-ÒÀÀµ¹ÜÀí
IPD¼¯³É²úÆ·¿ª·¢¹ÜÀí
Ïà¹Ø¿Î³Ì

ÅäÖùÜÀí¡¢ÈÕ¹¹½¨Óë³ÖÐø¼¯³É
Èí¼þ¼Ü¹¹Éè¼Æ·½·¨¡¢°¸ÀýÓëʵ¼ù
µ¥Ôª²âÊÔ¡¢Öع¹¼°³ÖÐø¼¯³É
»ùÓÚAndroidµÄµ¥Ôª¡¢ÐÔÄܲâÊÔ