乐趣区

基于ZStack设计一个较为简单的自动化测试系统

本文首发于泊浮目的专栏:https://segmentfault.com/blog…

背景
在笔者目前的项目中,大部分业务跑在基于 kvm 的 vm 上。鉴于对项目质量的追求及尽可能节省人力资源的目的,着手调研高测试覆盖率的解决方案。
由于项目基于 ZStack,所以架构与其较为相似,但在 vm 上添加了相应的 agent,通过其来控制 vm 中的操作系统与软件。
众所周知,ZStack 管理节点部分有一套较为完善的自动化测试框架,可以满足大多数场景。而 Utility 并非如此,只能通过黑盒测试来保证其质量,且许多测试场景需要 start up 一个真实的 ZStack 的环境,测试成本较高。
如果一部分测试可以设计在 agent 端,也就说是 agent 端的测试可以自举。这样就可以少设计一部分黑盒测试实例,降低潜在成本。
从业务看测试
从 vm agent 的业务逻辑来看,大多数业务都是修改 DB 配置、读 DB 配置,start, stop DB 等。而为了 case 之间不受到影响,我们在跑完测试之后,需要重置当前的测试环境。
方案选择
Docker
放弃。其无状态的特性简直完美契合上述需求。但是 docker 里只能跑单进程,对于 oracle 相关的业务,可能无法满足。且部分版本 oracle 对 Docker 的镜像支持上可能有问题。
在 docker 中可以通过一些 hack 的手段去做到在一个容器中起多进程,比如 systemd 或 supervisord。但是笔者对 docker 并不是非常的了解,所以没有继续研究下去。
Pouch
放弃。阿里自研的富容器技术,可以完美解决 docker 里单进程的问题——其实本质上也是在容器镜像起来时运行了一个 init 进程指定为 1 号进程,而不是像 docker 里在命令行中指定的进程。
在实践过程中发现有各种莫名其妙的报错,且相关文档不齐全。
VM By ZStack
目前的方案。通过 ZStack 来管理环境 vm 的生命周期,通过快照机制来还原环境。缺点也非常的明显,仅仅一个 case 生命周期就需要 1min+,生命周期大致如下:

使用 vm 跑测试
停止 vm
恢复快照
启动 vm

让人感到舒服的是,ZStack 提供了一套 Java SDK,可以直接通过 SDK 完成上述操作。
基于 ZStack 的自动化测试
对接 ZStack 根本没有什么困难之处。更多的是要从成本这个点去考虑整个测试系统的设计。
这里的成本则又可以分为两种成本:

物理资源成本:产品线上目前能够投入进测试的 host 较少,故在资源稀缺的情况下,得尽量用较少的 vm 去完成这件事。

时间成本:一个开发人员跑测试的时间越短越好,而不是花大量时间去等待测试环境准备、清理等。举个列子,如果我搭建一个 mysql 主备库,需要两台 vm,如果串行去完成生命周期相关的操作,那么就是 2min+;如果并行的去做,便是 1min+。同理,如果这些测试能够尽量并行的去跑,则可以省下更多的时间。

角色
角色示意图如下:
TestCase
一个测试实例,含有测试代码。同时它会向 ResourcePool 申请所需的 vm。
TestGroup
根据当前的策略组织 TestCase 去并行的跑这些 Case。在这里可以控制并发粒度,最后将会提交给 Junit 的跑测试。
JUnitCore.runClasses(new ParallelComputer(true, true)
, testGroup.toArray(arrayTestGroup));
ResourcePool
资源池的概念其实有点像云。比如组内有 4 个开发,那么 4 个开发几乎是不可能同时跑测试的,同时有 2 个开发在跑测试也是小概率事件。与其每个人都申请几台测试 vm 放在那边(一天可能就跑 1、2 小时的测试),还不如大家都共享一个池内的 vm,避免资源的浪费。就像公有云卖你 1core512m,你去架个网站,但是它料到你用不了这么多,所以它就会超分超卖。
这个类会根据配置文件或者网络请求存入相应测试用的 vm,并记录这些 vm 是否被使用,为了防止其他开发者一起跑测试的时候共用同一台 vm,会给使用中的 vm 打上一个 user tag,避免冲撞。另外,SessionId 等常量也是从这里刷新而来。
小结
通过本文,向大家介绍了一下笔者目前在项目中设计的一个基于 ZStack 的自动化测试系统。基于各方各面的成本限制,故此设计的较为简单。如果后续有些较大的改动或显著的改进,笔者还会与大家继续分享。如果大家对于这方面的自动化测试有较好的实践或者建议,也欢迎在留言中一起交流学习。**

退出移动版