自动化“快速”回滚方案
前言:
本文档只针对自动化产生的测试数据做回滚产生的解决方案,其中在阅读该文档前,读者需要了解docker,apollo,shell脚本等工具、语言。为什么文档标题为快速回滚呢。因为相信市面上有很多各种时序数据库,定时清理数据数据库之类的。最不济的还有回滚sql。但此类方案都属于备选方案,因为回滚这个动作本身就存在耗时,并且还要定义哪些东西需要回滚,哪些不需要回滚,指定时间,版本等相对来说非常繁琐。所以作者就产生了快速回滚和安全可靠的回滚方案。 此方案仅适用于后端项目配置项为动态加载的服务。例如:xx项目的后台是php,python等项目,由于脚本动态语言不需要编译的特性,可以灵活配置,所以java项目相关的动态配置需要开发人员做额外开发。
背景:
自动化测试脚本或平台,在日常测试工作中,经常会有类似此类场景:脚本第一次能通过,第二次却报错了的情况。对于此类脚本,我们大致分析了下有如下场景:
服务不稳定
测试数据已经产生不能重复利用
Redis中存在缓存
目的:
l 其中服务不稳定本身就属于一种系统级别的bug,有问题直接就可抛出来查看日志,所以此类问题不在解决方案中,
l 测试数据已经产生了,例如简单举例,登录测试案例,用户名密码已经通过脚本注册过了,再次注册肯定会提示用户名已存在,导致断言结果错误。
l 缓存中存在数据,导致校验结果的不一致。
接下来就介绍数据回滚相关细节部分:
首先大致回滚流程图如下:
一、数据准备和环境初始化
注:由于篇幅问题,搭建这些组件就不在这里叙述了
在准备数据之前,我们需要去被测服务器中的mysql目录将数据文件copy下来,
在docker服务器中安装docker并启动服务
l systemctl start docker
- 将mysql的镜像从docker仓库中拉下来
l docker pull mysql:5.7
- 初始化运行脚本deploy_docker.py 参数为:init 1.0.1 1
参数注释:deploy_docker.py共接收三个参数,类型,版本号和是否为新版本
Init为初始化的意思,
1.0.1为初始版本
1是true false的一个布尔值
运行完成之后,备份容器和当前容器启动完成
如何重启当前容器
deploy_docker.py deploy 1.0.1 0
deploy参数必填,1.0.1表示历史镜像版本号,详情参见docker_config.json,脚本中每次重启或者备份都会将对应的信息保存在docker_config.json文件中。
- 如何更新当前容器
deploy_docker.py deploy 1.0.2 1
deploy参数必填,1.0.1表示新镜像的版本号
二、当前容器和备份容器
当前容器:
我们通过mysql的镜像启动一个容器后,通过某某web系统或者其他手段,对数据库做了增删改的操作,这时需要回滚到启动之前的版本,只需要关闭当前容器并重启,数据就还原到启动之前的版本,但是有个问题是,假如业务系统的表结构从1.0更新到了1.1,我们重启容器,表结构又回到了1.0,所以这个时候我们的备份容器就派上用场了
备份容器:
我们通过同样的方式,通过mysql5.7镜像启动容器,并开放一个额外参数volumes,这个参数的意思是,docker容器和宿主机互相绑定一个目录,做数据挂载,也就是docker容器中产生的数据,会留存在宿主机绑定的这个目录。
特别需要注意的一点是:数据卷挂载到宿主机的目录必须是:/var/docker_file/docker/data,这个目录,由于偷懒所以没有抽成配置项出来,后续有时间优化
脚本文件则需要放置在/var/docker_file/docker这个目录,因为Dcokerfile读取的数据卷是当前目录./
那么相信了解完当前容器和备份容器,应该知道这两个的用处了,这里举个例子,
假如当前容器中有个库,里面有个test_table表,备份容器也有个test_table表,这时备份容器新增了另外一个表,叫test_table2,这时我们在build新镜像的时候,将备份容器中之前提到的,数据留存目录挂给当前容器,就可达到,当前容器和备份容器数据一致的效果了。
三、结合Apollo做数据配置热切换
<u>https://github.com/ctripcorp/apollo/wiki/Apollo%E5%BC%80%E6%94%BE%E5%B9%B3%E5%8F%B0</u>
Apollo官方文档中提供openapi,可以直接调用部分接口,达到修改数据的效果,这时我们拿到我们的appid和配置项对应的键值对修改即可达到效果
流程如下:
我们假设自动化测试脚本是在晚上的凌晨2点到3点执行,那么我们将数据库的端口和IP切换到容器mysql中,在执行完成之后,再将端口和IP切换到实际被测服务器的mysql中。
当然如果,你们公司mysql本就是通过容器映射出的,那就更方便了,直接关闭当前测试服的mysql容器,启动自动化mysql容器,执行完成关闭自动化mysql容器,最后启动测试服容器。
四、最终持续集成方案
这些任务需要持续集成方案的话,这里对jenkins简单说一下,首先将咱们的启动和部署脚本放置在jenkins服务器中,然后在shell命令处添加如下代码片段:
1.deploy_docker.py deploy 或者 deploy_docker.py init (具体根据需求来,init初始化基本只在第一次会用到,)
2.调用Apollo切换到docker容器数据库(这步根据自己需求决定是否切换)
3.自动化测试脚本调用,(这里执行自己编写的自动化测试脚本)