maven和docker_与Maven和Docker的集成测试

maven和docker

Docker是其中的新热点之一。 与传统虚拟机相比,它具有一组不同的技术和思想,并通过容器的思想实现了相似但同时又有所不同的东西:几乎所有VM都具有强大的功能,但速度更快,并且还具有许多有趣的附加功能。

在本文中,我假设您已经对Docker有所了解,并且知道如何与之交互。 如果不是这种情况,我可以建议您从以下链接开始:

  • http://www.docker.io/gettingstarted
  • http://coreos.com/docs/launching-containers/building/getting-started-with-docker/
  • http://robknight.org.uk/blog/2013/05/drupal-on-docker/

我对该主题的个人贡献是向您展示可能的工作流程 ,使您可以从Maven作业中启动和停止Docker容器

我研究此功能的原因是为了帮助使用Maven构建的Java项目中的测试和集成测试 。 这个问题是众所周知的:您的代码与外部系统和服务交互。 根据您实际编写的内容,这可能意味着数据库,消息代理,Web服务等。

测试这些交互的常用策略是:

  • 在内存服务器中; 用Java实现,通常很快,但是很多时候它们的局限性在于它们不是真实的东西
  • 您实现的存根服务层,以提供所需的接口。
  • 真实的外部流程 (有时是远程的),用于测试真实的交互。

这些策略有效,但通常需要付出很多努力才能落实到位。 最完整的一种,即使用适当的外部服务的那种,会给与隔离有关的问题带来问题:想象一下您正在与数据库进行交互,并且在其他人访问相同资源的同时执行读/写操作。 同样,您可能会找到正确的工作流程,这些工作流程涉及创建单独的模式等等,但是,这又是额外的工作,而且通常不是很简单的活动。

如果我们能拥有与这些外部系统相同的机会,但完全隔离,那不是很好吗? 如果我也增加报价,您会怎么看?

Docker是为我们提供这一机会的工具。

在测试套件的开头,您可以使用所需的所有服务启动一组Docker容器,并在结束时将其拆解。 您的Maven工作可以成为这些服务的唯一使用者,并且需要所有隔离功能。 您可以在Dockerfile的帮助下轻松编写所有脚本,最后,它们只不过是一系列顺序的命令行调用。

让我们看看如何启用所有这些功能。

显然,第一个前提条件是在您的系统上安装Docker。 您可能已经知道Docker技术取决于Linux内核的功能,所以您必须使用Linux或需要传统VM的帮助来托管D​​ocker服务器进程。

这是官方文档指南,向您展示如何在不同的Linux发行版中进行安装: http : //docs.docker.io/en/latest/installation/

相反,这是一个非常快速的指南,显示了如何在MacOSX上进行安装: http : //blog.javabien.net/2014/03/03/setup-docker-on-osx-the-no-brainer-way /

准备就绪并安装Docker后,需要应用特定的配置

在最新版本的Docker中,默认情况下仅通过Unix套接字公开其远程API。 尽管我们可以使用正确的代码与它们进行交互,但我发现通过HTTP与API进行交互要容易得多。 为此,您必须将特定标志传递给Docker守护进程,以使其也监听HTTP。

我正在使用Fedora,要修改的配置文件是/usr/lib/systemd/system/docker.service

[Unit]
Description=Docker Application Container Engine
Documentation=http://docs.docker.io
After=network.target[Service]
ExecStart=/usr/bin/docker -d -H tcp://127.0.0.1:4243 -H unix:///var/run/docker.sock
Restart=on-failure[Install]
WantedBy=multi-user.target

与默认值相比,唯一的修改是添加了-H tcp://127.0.0.1:4243

现在,在重新加载systemd脚本并重新启动服务之后,我有了一个Docker守护程序,该守护程序向我展示了一个不错的REST API ,可以用curl戳一下。

sudo systemctl daemon-reload
sudo systemctl restart docker
curl http://127.0.0.1:4243/images/json # returns a json in output

您可能还希望此配置能够在将来的Docker rpm更新中保留下来。 为了实现这一点,您必须将刚刚修改的文件复制到可以保留rpm更新的位置。 在systemd实现此目标的正确方法是:

sudo cp /usr/lib/systemd/system/docker.service /etc/systemd/system

如果您使用的是Ubuntu ,则必须配置其他文件。 查看此页面: http : //blog.trifork.com/2013/12/24/docker-from-a-distance-the-remote-api/

现在,我们拥有与Docker轻松交互所需的一切。

您可能会期望我在此向您介绍如何使用Maven Docker插件 。 不幸的是,事实并非如此。 还没有这样的插件 ,或者至少我不知道它。 我正在考虑编写一个,但是目前我已经借助GMaven插件,一些Groovy代码和Java库Rest-assuredSwift解决了我的问题。

这是启动Docker容器代码

import com.jayway.restassured.RestAssured
import static com.jayway.restassured.RestAssured.*
import static com.jayway.restassured.matcher.RestAssuredMatchers.*
import com.jayway.restassured.path.json.JsonPath
import com.jayway.restassured.response.ResponseRestAssured.baseURI = "http://127.0.0.1"
RestAssured.port = 4243// here you can specify advance docker params, but the mandatory one is the name of the Image you want to use
def dockerImageConf = '{"Image":"${docker.image}"}'
def dockerImageName = JsonPath.from(dockerImageConf).get("Image")log.info "Creating new Docker container from image $dockerImageName"
def response =  with().body(dockerImageConf).post("/containers/create")if( 404 == response.statusCode ) {log.info "Docker image not found in local repo. Trying to dowload image '$dockerImageName' from remote repos"response = with().parameter("fromImage", dockerImageName).post("/images/create")def message = response.asString()//odd: rest api always returns 200 and doesn't return proper json. I have to grepif( message.contains("404") ) fail("Image $dockerImageName NOT FOUND remotely. Abort. $message}")log.info "Image downloaded"// retry to create the containerresponse = with().body(dockerImageConf).post("/containers/create")if( 404 == response.statusCode ) fail("Unable to create container with conf $dockerImageConf: ${response.asString()}")
}def containerId = response.jsonPath().get("Id")log.info "Container created with id $containerId"// set the containerId to be retrieved later during the stop phase
project.properties.setProperty("containerId", "$containerId")log.info "Starting container $containerId"
with().post("/containers/$containerId/start").asString()def ip = with().get("/containers/$containerId/json").path("NetworkSettings.IPAddress")log.info "Container started with ip: $ip" System.setProperty("MONGODB_HOSTNAME", "$ip")
System.setProperty("MONGODB_PORT", "27017")

这是阻止他们的人

import com.jayway.restassured.RestAssured
import static com.jayway.restassured.RestAssured.*
import static com.jayway.restassured.matcher.RestAssuredMatchers.*RestAssured.baseURI = "http://127.0.0.1"
RestAssured.port = 4243def containerId = project.properties.getProperty('containerId')
log.info "Stopping Docker container $containerId"
with().post("/containers/$containerId/stop")
log.info "Docker container stopped"
if( true == ${docker.remove.container} ){with().delete("/containers/$containerId")log.info "Docker container deleted"
}

放心的流利API应该可以提示正在发生的事情,内联注释应该可以澄清它,但是让我添加一些注释。 启动容器的代码是我对docker run功能的实现,如此处的官方API文档所述: http : //docs.docker.io/en/latest/reference/api/docker_remote_api_v1.9/#inside-docker -跑

我要解决特定问题是如何将Docker容器的ID从Maven阶段传播到另一个阶段 。 通过以下代码,我已经实现了功能:

// set the containerId to be retrieved later during the stop phase project.properties.setProperty("containerId", "$containerId")

我还公开了一些Maven属性,可用于与API交互:

  • docker.image –您要旋转的图像的名称
  • docker.remove.container –如果设置为false,则告诉Maven不要从文件系统中删除已停止的容器(在作业完成后用于检查Docker容器)

例如

mvn verify -Ddocker.image=pantinor/fuse -Ddocker.remove.container=false

您可以在此处找到完整的工作示例。 有人告诉我,有时我的语法着色器脚本会吃一些关键字或更改单词的大小写,因此,如果要复制和粘贴,可能是从Github裁剪的一个更好的主意。

这是使用命令mvn verify运行Maven构建时输出的一部分:

...
[INFO] --- gmaven-plugin:1.4:execute (start-docker-images) @ gmaven-docker ---
[INFO] Creating new Docker container from image {"Image":"pantinor/centos-mongodb"}
log4j:WARN No appenders could be found for logger (org.apache.http.impl.conn.BasicClientConnectionManager).
log4j:WARN Please initialize the log4j system properly.
[INFO] Container created with id 5283d970dc16bd7d64ec08744b5ecec09b57d9a81162826e847666b8fb421dbc
[INFO] Starting container 5283d970dc16bd7d64ec08744b5ecec09b57d9a81162826e847666b8fb421dbc
[INFO] Container started with ip: 172.17.0.2...[INFO] --- gmaven-plugin:1.4:execute (stop-docker-images) @ gmaven-docker ---
[INFO] Stopping Docker container 5283d970dc16bd7d64ec08744b5ecec09b57d9a81162826e847666b8fb421dbc
[INFO] Docker container stopped
[INFO] Docker container deleted...

如果您有任何疑问或建议,请随时告诉我!

完整的Maven`pom.xml`也可以在这里找到: https ://raw.githubusercontent.com/paoloantinori/gmaven_docker/master/pom.xml

<!--?xml version="1.0"?-->
<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/xsd/maven-4.0.0.xsd"><modelversion>4.0.0</modelversion><artifactid>gmaven-docker</artifactid><groupid>paolo.test</groupid><version>1.0.0-SNAPSHOT</version><name>Sample Maven Docker integration</name><description>See companion blogpost here: </description><build><plugins><plugin><groupid>org.codehaus.gmaven</groupid><artifactid>gmaven-plugin</artifactid><version>1.4</version><configuration><providerselection>2.0</providerselection></configuration><executions><execution><id>start-docker-images</id><phase>test</phase><goals><goal>execute</goal></goals><configuration><source><!--[CDATA[
import com.jayway.restassured.RestAssured
import static   com.jayway.restassured.RestAssured.*
import static   com.jayway.restassured.matcher.RestAssuredMatchers.*RestAssured.baseURI = "http://127.0.0.1"
RestAssured.port = 4243// here you can specify advance docker params, but the mandatory one is the name of the Image you want to use
def dockerImage = '{"Image":"pantinor/centos-mongodb"}'log.info "Creating new Docker container from image $dockerImage"
def response =  with().body(dockerImage).post("/containers/create")if( 404 == response.statusCode ) {log.info "[INFO] Docker Image not found. Downloading from Docker Registry"log.info with().parameter("fromImage", "pantinor/centos-mongodb").post("/images/create").asString()log.info "Image downloaded"
}// retry to create the container
def containerId = with().body(dockerImage).post("/containers/create").path("Id")log.info "Container created with id $containerId"// set the containerId to be retrieved later during the stop phase
project.properties.setProperty("containerId", "$containerId")log.info "Starting container $containerId"
with().post("/containers/$containerId/start").asString()def ip = with().get("/containers/$containerId/json").path("NetworkSettings.IPAddress")log.info "Container started with ip: $ip"System.setProperty("MONGODB_HOSTNAME", "$ip")
System.setProperty("MONGODB_PORT", "27017")
]]--></configuration></execution><execution><id>stop-docker-images</id><phase>post-integration-test</phase><goals><goal>execute</goal></goals><configuration><source><!--[CDATA[
import com.jayway.restassured.RestAssured
import static   com.jayway.restassured.RestAssured.*
import static   com.jayway.restassured.matcher.RestAssuredMatchers.*RestAssured.baseURI = "http://127.0.0.1"
RestAssured.port = 4243def containerId = project.properties.getProperty('containerId')
log.info "Stopping Docker container $containerId"
with().post("/containers/$containerId/stop")
log.info "Docker container stopped"
with().delete("/containers/$containerId")
log.info "Docker container deleted"
]]--></configuration></execution></executions></plugin></plugins></build><dependencies><dependency><groupid>com.jayway.restassured</groupid><artifactid>rest-assured</artifactid><version>1.8.1</version><scope>test</scope></dependency></dependencies>
</project>

参考:在Someday Never Comes博客上,我们的JCG合作伙伴 Paolo Antinori 与Maven和Docker进行了集成测试 。

翻译自: https://www.javacodegeeks.com/2014/03/integration-testing-with-maven-and-docker.html

maven和docker

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/341910.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[渝粤教育] 盐城师范学院 光学 参考 资料

教育 -光学-章节资料考试资料-盐城师范学院【】 判断题 1、【判断题】1-1下列说法正确吗&#xff1f;&#xff08;a&#xff09;相干叠加服从波的叠加原理&#xff0c;非相干叠加不服从波的迭加原理。 A、正确 B、错误 参考资料【 】 2、【判断题】1-1下列说法正确吗&#xff1…

如何从使用环境上区别光纤收发器?

根据针对不同环境&#xff0c;就需求不同性质产品。光纤收发器也一样有工业级和商业级之分&#xff0c;但是又区别于市场上TP-LINGK和D-link等(这些是家庭使用的3C电子产品很低端&#xff0c;大部分是回收二手货元器件生产&#xff0c;客户群体及应用的环境不一样)。在使用环境…

[渝粤教育] 苏州科技大学 混凝土结构设计原理 参考 资料

教育 -混凝土结构设计原理-章节资料考试资料-苏州科技大学【】 第1章测试 1、【单选题】均布荷载作用下简支梁上部受压下部受拉的试验被称为 A、路标试验 B、钢标试验 C、混标试验 D、简支梁试验 参考资料【 】 2、【单选题】钢筋混凝土结构中钢筋主要受&#xff08; &#xff…

保存您的lambda,以备不时之需-保存到文件

介绍 简短的帖子&#xff0c;描述了如何将Java lambda持久保存到文件中以在不同的过程中重复使用。 序列化Lambda Java 8中引入的Lambda使函数成为Java语言的一等公民&#xff08;几乎&#xff09;。 它们消除了使用专用类来保存函数的需要。 但是&#xff0c;这是如何进行的呢…

[渝粤教育] 西北工业大学 机械原理 参考 资料

教育 -机械原理-章节资料考试资料-西北工业大学【】 第一周单元测验 1、【单选题】手机属于。 A、机械 B、机构 C、机器 D、即不属机构&#xff0c;也不属机器 参考资料【 】 2、【单选题】下列常用装置哪些属于机器。 A、电动卷扬机 B、折叠烫衣板 C、手动窗扇开闭装置 D、汽车…

16槽双电源机架式光纤收发器产品优势介绍

双电源光纤收发器能满足远距离、高速、高宽带的快速以太网工作组用户的需要。产品性能稳定可靠&#xff0c;符合以太网标准&#xff0c;并具有防雷击保护措施。双电源光纤收发器适用于电信及各种宽带数据网要求高可靠性数据传输或组建IP数据传输专网的领域&#xff0c;是宽带校…

[渝粤教育] 西南交通大学 土木工程试验与量测技术 参考 资料

教育 -土木工程试验与量测技术-章节资料考试资料-西南交通大学【】 电阻应变片的粘贴及防潮工艺实验 1、【单选题】在测定石砌拱桥结构在车辆荷载作用下的应变时&#xff0c;最适合选用的应变传感器是&#xff08;&#xff09; A、电阻应变片 B、手持式应变仪 C、振弦式应变计 …

aws iam 架构图_使用IAM保护您的AWS基础架构

aws iam 架构图在开发新产品并发现合适的产品市场时&#xff0c;每个团队都需要快速行动。 尤其是初创公司&#xff0c;因为公司的整个未来都取决于快速找到为您的产品付款的人。 对于初创企业和其他团队来说&#xff0c; Amazon Web Services是令人难以置信的工具&#xff0c…

百兆光纤收发器和千兆光纤收发器的区别

百兆光纤收发器&#xff08;又名百兆光电转换器&#xff09;是一种快速以太网转换器。光纤收发器全面兼容IEEE802.3、IEEE802.3u、IEEE802.1d标准。支持全双工、半双工、自适应三种工作模式。 千兆光纤收发器&#xff08;又名光电转换器&#xff09;是一种快速以太网&#xff…

[渝粤教育] 西南石油大学 建设法规 参考 资料

教育 -建设法规-章节资料考试资料-西南石油大学【】 第一章单元小测 1、【单选题】法律关系产生的前提是( ) A、公民的法律意识 B、法律的存在 C、交易的发生 D、物的转移 参考资料【 】 2、【单选题】下列民事行为中属于代理的是&#xff08; &#xff09;。 A、由于事务繁忙&…

[渝粤教育] 西安建筑科技大学 环境规划与管理 参考 资料

教育 -环境规划与管理-章节资料考试资料-西安建筑科技大学【】 第一章单元测验 1、【单选题】1979年国家颁布了《中华人民共和国环境保护法&#xff08;试行&#xff09;》&#xff0c;( )实施了新的《环境保护法》 A、 2015年1月1日 B、2014年4月24日 C、 2015年4月24日 D、20…

常见光纤收发器组网方式介绍

在光纤网络布线中&#xff0c;光纤收发器的应用已经越来越普遍&#xff0c;仅需一芯光纤&#xff0c;便可组成一个环网&#xff0c;节约了布线成本&#xff0c;其中一个点出现故障&#xff0c;不影响其他点的使用。接下来我们就几种常见的光纤收发器组网方式进行简单的介绍&…

[渝粤教育] 郑州商学院 商学概论 参考 资料

教育 -商学概论-章节资料考试资料-郑州商学院【】 Chapter 1 单元测试 1、【单选题】_____ not only provide factors of production (or resources) but also consume goods and services. A、Suppliers B、Nonprofits C、Entrepreneurs D、Households 参考资料【 】 2、【单选…

[渝粤教育] 郑州航空工业管理学院 电工电子技术基础 参考 资料

教育 -电工电子技术基础-章节资料考试资料-郑州航空工业管理学院【】 小节测试 1、【判断题】任何一个完整的电路都必须有电源、负载和中间环节三个基本部分组成。 A、正确 B、错误 参考资料【 】 2、【判断题】电路的作用是对电能进行传输、分配和转换&#xff1b;而对电信号进…

工业级光电转换器产品介绍

光电转换器是一种类似于基带MODEM&#xff08;数字调制解调器&#xff09;的设备&#xff0c;和基带MODEM不同的是接入的是光纤专线&#xff0c;是光信号&#xff0c;分为全双工流控&#xff0c;半双工背压控制。那么&#xff0c;什么是工业级光电转换器呢&#xff1f;接下来就…

[渝粤教育] 重庆大学 电子商务 参考 资料

教育 -电子商务-章节资料考试资料-重庆大学【】 1.1 随堂测验 1、【单选题】狭义的电子商务的英文表达是&#xff1a; A、Electronic Commerce B、Electronic Business C、Electronic Government D、Electronic Banking 参考资料【 】 2、【单选题】狭义的电子商务不包括下面的…

工业级光纤收发器的选用方法

工业级光纤收发器又叫工业级光电转换器&#xff0c;是一种将短距离的双绞线电信号和长距离的光信号进行互换的以太网传输媒体转换单元。观察角度的不同使人们对工业级光纤收发器有着不同的认识&#xff0c;比如按传输速率分为单10M、100M的工业级光纤收发器、10/100M自适应的工…

[渝粤教育] 长沙民政职业技术学院 高职公共英语(一) 参考 资料

教育 -高职公共英语&#xff08;一&#xff09;-章节资料考试资料-长沙民政职业技术学院【】 Test 1 1、【单选题】You will find more opportunities in the new campus. A、chances B、times C、honors D、worries 参考资料【 】 2、【单选题】We were very astonished that …

java8 默认方法_Java 8的默认方法:可以做什么和不能做什么?

java8 默认方法什么是默认方法 在Java 8发行版中&#xff0c;您可以修改接口以添加新方法&#xff0c;以便该接口与实现该接口的类保持兼容。 万一您开发了一个库&#xff0c;该库将由基辅到纽约的几位程序员使用&#xff0c;那么这非常重要。 在Java 8出现之前&#xff0c;如果…

【渝粤教育】国家开放大学2018年春季 0609-22T中级财务会计(1) 参考试题

科目编号&#xff1a;0609 座位号 2017-2018学年度第二学期期末考试 中级财务会计&#xff08;1&#xff09; 试题 2018年 7 月 一、单选题&#xff08;本大题共10小题&#xff0c;每小题3分&#xff0c;共计30分&#xff09; &#xff08;★请考生务必将答案填入到下面对应序…