51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

测试开发精英班,通向高级软件测试工程师【周活动】 找茬--心里圈的故事 !【长期招募】博为峰网校招聘兼职讲师!横扫BAT,Python全栈测试开发技能大全
【102期】:如何快速掌握APP自动化测试技能! 【专题】有远见的测试员已经开始学MySQL了 【干货】各大公司测试大牛职场晋升宝典 自学软件测试那点事
查看: 187|回复: 2

Jenkins RESTful API 定制化

[复制链接]

该用户从未签到

发表于 2019-4-10 17:05:19 | 显示全部楼层 |阅读模式
1.背景

Jenkins具有丰富的插件生态,足以满足我们日常工作的需求;如果我们想通过具体的Jenkins任务直接对外提供服务,而我们不想将内部的具体实现对外暴露(否则,需添加对应的用户权限,通过页面执行job);可以对外直接提供接口,第三方直接调用接口(比如提供给开发,提测前回归冒烟用例集),执行相应的Jenkins任务并获取任务结果。

2.Jenkins原生Remote access API

Jenkins提供了原生的Remote accsee API, 主要用来做:

1.检索Jenkins中信息
2.触发新构建
3.创建/复制任务

实例:

  1. 获取项目FastTest信息:
  2. curl -u user:pwd -X POST http://ip:port/jenkins/job/FastTest/api/xml
  3. 并支持Xpath进行信息提取,详见 https://issues.jenkins-ci.org/browse/JENKINS-626

  4. 触发新的构建(带参数构建):
  5. curl -u user:pwd -X POST http://ip:port/jenkins/job/FastTest/buildWithParameters -d "environment=运行环境&module=模块&mailer=收件人"

  6. 该接口响应头信息:
  7. * upload completely sent off: 94 out of 94 bytes
  8. < HTTP/1.1 201 Created
  9. < Server: Apache-Coyote/1.1
  10. < X-Content-Type-Options: nosniff
  11. < Location: http://ip:port/jenkins/queue/item/111/
  12. < Content-Length: 0
  13. < Date: Wed, 05 Oct 2016 07:39:39 GMT
  14. <
  15. * Connection #0 to host 10.210.228.50 left intact

  16. 但是该接口无任何返回信息。
复制代码

完整的Remote access API wiki 可以通过如下获取:

  1. curl  -u user:pwd -X POST http://ip:port/jenkins/job/FastTest/api/ > /Users/hugang/Desktop/jenkins_api_wiki.html
复制代码

原生的接口,功能较为简单、不友好,需封装Jenkins的api,提供有价值的接口返回信息。

3.Jenkins api wrappers

Jenkins api wrappers有多种编程语言实现, 可以很方便的操作Jenkins,具体如下:

Node.js: https://www.npmjs.com/package/jenkins-api

ruby: https://rubygems.org/gems/jenkins_api_client

python: https://pypi.python.org/pypi/python-jenkins/

java: https://github.com/jenkinsci/java-client-api

本文将使用java的Jenkins api wrappers:java-client-api作为介绍,定制适合自己的Jenkins RESTful API.

4.定制Jenkins RESTful API

新建一个Maven webapp工程,工程pom.xml中添加java-client-api依赖:

  1. <dependency>
  2.   <groupId>com.offbytwo.jenkins</groupId>
  3.   <artifactId>jenkins-client</artifactId>
  4.   <version>0.3.6</version>
  5. </dependency>
复制代码

项目使用Spring RESTful web service

Controller层

执行用例接口:

  1. package com.weibo.qa.fasttestapi.controller;


  2. import com.weibo.qa.fasttestapi.model.RunInfo;
  3. import com.weibo.qa.fasttestapi.service.EmailSuffixService;
  4. import com.weibo.qa.fasttestapi.service.FastTestJenkinsService;
  5. import org.springframework.web.bind.annotation.RequestMapping;
  6. import org.springframework.web.bind.annotation.RequestMethod;
  7. import org.springframework.web.bind.annotation.RequestParam;
  8. import org.springframework.web.bind.annotation.RestController;

  9. /**
  10. *
  11. * 接口/fasttest/run:
  12. *
  13. * params:
  14. *
  15. * env 测试环境
  16. * module 模块
  17. * email 收件人
  18. *
  19. *
  20. * result:
  21. *
  22. * {"result":true,"jobId":int值}
  23. *
  24. * Created by hugang on 16/9/19.
  25. */
  26. @RestController
  27. public class RunController {

  28.     @RequestMapping(value = "/fasttest/run.json", method = RequestMethod.POST)
  29.     public RunInfo runFasttest(@RequestParam(value = "env", required = true) String env,
  30.                         @RequestParam(value = "module", required = true, defaultValue = "BVT") String module,
  31.                         @RequestParam(value = "email", required = true, defaultValue = "hugang") String email){

  32.         FastTestJenkinsService fastTestJenkinsService = new FastTestJenkinsService();
  33.         // 增加邮箱后缀
  34.         EmailSuffixService emailSuffix = new EmailSuffixService();

  35.         String receiver = emailSuffix.addEmailSuffix(email);

  36.         int jobId = fastTestJenkinsService.buildJob(env, module, receiver);

  37.         RunInfo runInfo = new RunInfo();

  38.         runInfo.setJobId(jobId);
  39.         runInfo.setResult(true);

  40.         return runInfo;

  41.     }

  42. }
复制代码

根据jobId判断是否执行结束接口:

  1. package com.weibo.qa.fasttestapi.controller;

  2. import com.weibo.qa.fasttestapi.model.FinishInfo;
  3. import com.weibo.qa.fasttestapi.service.FastTestJenkinsService;
  4. import org.springframework.web.bind.annotation.*;

  5. /**
  6. * Created by hugang on 16/9/20.
  7. */

  8. @RestController
  9. public class FinishController {

  10.     @RequestMapping(value = "/fasttest/finish.json",method = RequestMethod.GET)
  11.     public @ResponseBody
  12.     FinishInfo isFinish(@RequestParam(value = "job_id", required = true)int job_id) {

  13.         FastTestJenkinsService fastTestJenkinsService = new FastTestJenkinsService();

  14.         boolean isFinish = fastTestJenkinsService.isJobFinish(job_id);

  15.         FinishInfo finishInfo = new FinishInfo();

  16.         finishInfo.setFinished(isFinish);

  17.         return finishInfo;

  18.     }
  19. }
复制代码
service层

执行具体的业务:FastTestJenkinsService.java

  1. package com.weibo.qa.fasttestapi.service;

  2. import com.offbytwo.jenkins.JenkinsServer;
  3. import com.offbytwo.jenkins.model.Job;
  4. import com.offbytwo.jenkins.model.JobWithDetails;

  5. import java.net.URI;
  6. import java.util.HashMap;
  7. import java.util.Map;

  8. /**
  9. * Created by hugang on 16/9/19.
  10. */
  11. public class FastTestJenkinsService {



  12.     /**
  13.      *
  14.      * @param env 测试环境
  15.      * @param module 测试模块
  16.      * @param email  收件人
  17.      * @return jobId
  18.      */
  19.     public int buildJob(String env, String module, String email) {

  20.         int buildNumber = 0;
  21.         try{
  22.             JenkinsServer jenkinsServer = new JenkinsServer(new URI("http://ip:port/jenkins"), "test", "pwd");

  23.             Map<String, Job> jobs = jenkinsServer.getJobs();

  24.             JobWithDetails job = jobs.get("FastTest").details();

  25.             // 即将执行任务的jobId
  26.             buildNumber = job.getNextBuildNumber();

  27.             // 参数化构建
  28.             Map<String, String> params = new HashMap<String, String>();
  29.             params.put("environment", env);
  30.             params.put("module", module);
  31.             params.put("mailer", email);
  32.             job.build(params);


  33.         }catch (Exception e){
  34.             e.printStackTrace();
  35.         } finally {

  36.         }
  37.         return buildNumber;
  38.     }


  39.     /**
  40.      *
  41.      * @param jobId
  42.      * @return 是否执行结束
  43.      */
  44.     public boolean isJobFinish(int jobId)  {

  45.         if(jobId <=0){
  46.             throw new IllegalArgumentException("jodId must greater than 0!");
  47.         }


  48.         try{

  49.             JenkinsServer jenkinsServer = new JenkinsServer(new URI("http://ip:port/jenkins"), "user", "pwd");

  50.             Map<String, Job> jobs = jenkinsServer.getJobs();

  51.             JobWithDetails job = jobs.get("FastTest").details();

  52.             boolean isBuilding = job.getBuildByNumber(jobId).details().isBuilding();

  53.             return !isBuilding;

  54.         } catch (Exception e){
  55.             e.printStackTrace();
  56.         } finally{

  57.         }

  58.         return false;
  59.     }
复制代码
model层

执行用例返回数据:RunInfo.java

  1. package com.weibo.qa.fasttestapi.model;

  2. /**
  3. * 执行用例接口返回的数据
  4. * Created by hugang on 16/9/19.
  5. */
  6. public class RunInfo {
  7.     private boolean result;
  8.     private int jobId;


  9.     public boolean isResult() {
  10.         return result;
  11.     }

  12.     public void setResult(boolean result) {
  13.         this.result = result;
  14.     }

  15.     public int getJobId() {
  16.         return jobId;
  17.     }

  18.     public void setJobId(int jobId) {
  19.         this.jobId = jobId;
  20.     }
  21. }
  22. 查看jobId对应的任务是否结束:FinishInfo.java

  23. package com.weibo.qa.fasttestapi.model;

  24. /**
  25. * 查看执行用例是否结束
  26. * Created by hugang on 16/9/19.
  27. */
  28. public class FinishInfo {
  29.     private boolean finished;

  30.     public boolean isFinished() {
  31.         return finished;
  32.     }

  33.     public void setFinished(boolean finished) {
  34.         this.finished = finished;
  35.     }
  36. }
复制代码


回复

使用道具 举报

本版积分规则

关闭

站长推荐上一条 /2 下一条

小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

GMT+8, 2019-5-19 22:57 , Processed in 0.059998 second(s), 24 queries .

Powered by Discuz! X3.2

© 2001-2019 Comsenz Inc.

快速回复 返回顶部 返回列表