目录
最近小编接到一个任务用来监测和巡检网络入口是否正常,下面是我实现的思路图:
下面是我要实现的具体步骤:
一、安装Docker
在CentOS上,首先更新包管理工具并安装所需的包。
sudo yum update -y
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
接下来,添加Docker的官方仓库,然后安装Docker。
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
sudo yum install -y docker-ce docker-ce-cli containerd.io
在执行这步骤的时候可能会出现下载Docker不成功,我后面采用aliyun下载的并设置了自己的代理。
启动Docker服务,并设置为开机自启。
sudo systemctl start docker
sudo systemctl enable docker
二、安装Docker Compose
需要下载Docker Compose的当前稳定版本。检查Docker Compose GitHub仓库上的最新版本。
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
这里最开始下载存在问题,我是登录仓库后下载对应的文件后,通过scp命令上传到/usr/local/bin目录下,并重命名为docker-compose
chmod +x docker-compose-linux-x86_64
mv docker-compose-linux-x86_64 /usr/local/bin/docker-compose
验证安装是否成功。
docker-compose --version
三、准备测试用例
准备用pytest编写的测试用例。例如,创建一个简单的测试文件test_example.py
# test_example.py
def test_example():
assert 1 == 1
def test_example_fail():
assert 1 == 2
四、配置docker-compose.yml
创建docker-compose.yml文件来定义Jenkins服务。此配置将Jenkins作为服务运行,并准备了用于持久化数据和与宿主机的Docker守护进程通信的卷。因为我需要用到python脚本,采用pytest框架,这里我构建了python镜像。
version: '3.9'
services:
jenkins:
image: jenkins/jenkins:lts
container_name: jenkins
network_mode: "host"
user: root
restart: always
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /root/compose/jenkins/jenkins_data:/var/jenkins_home
- /root/compose/jenkins/pythonProject:/var/jenkins_home/pythonProject
- /root/compose/jenkins/apache-maven-3.9.8:/usr/local/apache-maven/apache-maven-3.9.8
- /root/compose/jenkins/jdk-11.0.23:/usr/local/jdk-11.0.23
- /root/compose/jenkins/conf/profile:/root/.bashrc
environment:
- TZ=Asia/Shanghai
python:
image: python:3.10
container_name: python
volumes:
- /root/compose/jenkins/pythonProject:/usr/src
working_dir: /usr/src
command: bash -c "pip install -r requirements.txt && tail -f /dev/null"
五、启动Jenkins
运行以下命令在后台启动Jenkins服务:
docker-compose up -d
我配置了portainer可视化界面,可看到启动后的镜像信息:
六、配置Jenkins和Allure插件
1.访问http:<机器名称>:8080进行Jenkins的初始化配置。
2.安装Allure Jenkins插件:进入管理--》插件管理,在“可选插件”标签页搜索“Allure Jenkins Plugin”进行安装。
3.重启Jenkins以应用安装的插件。
七、创建含pytest的Jenkins任务
1.在Jenkins中创建一个新的“自由风格的软件项目”。
2.在“源代码管理”部分,配置你的项目库(如果你的测试用例放在Git等版本控制系统中)。
3.在“构建”部分,添加“执行shell”步骤,填写命令来安装pytest和allure-pytest,并执行测试用例。
python3 -m ensurepip --upgrade # 确保pip3安装/更新
pip3 install pytest
pip3 install allure-pytest
python3 -m pytest --alluredir=allure-results test_example.py
后续网络入口特别多的情况下,执行一次会耗时2h,时间成本太高,修改shell语句:
cd /var/jenkins_home/pythonProject
#可以先安装pytest-xdist插件
pip3 install pytest-xdist
#通过requirements.txt文件包含全部的依赖插件
pip3 freeze > requirements.txt
#上面两个步骤可以提前在jenkins容器内执行,这里可不执行
pytest -n 8 test_redirects.py --alluredir "allure-results" --clean-alluredir
4.运行Jenkins任务并查看Allure报告
但是最开始这里执行会报错,pip和python不存在,采用新的方式在docker容器内下载python3
首先以root用户权限进入到jenkins容器内:
docker exec -itu root jenkins /bin/bash
执行命令:
apt-get update
#直接容器中安装 wget
apt install -y wget
#先安装依赖
apt -y install gcc automake autoconf libtool make
apt -y install make*
apt -y install zlib*
apt -y install openssl libssl-dev
apt install -y build-essential
apt install sudo
sudo apt-get update
sudo apt-get install build-essential python-dev python-setuptools python-pip python-smbus
sudo apt-get install build-essential libncursesw5-dev libgdbm-dev libc6-dev
sudo apt-get install zlib1g-dev libsqlite3-dev tk-dev
sudo apt-get install libssl-dev openssl
sudo apt-get install libffi-dev
sudo apt-get install libxpm-dev libxext-dev
sudo apt-get install zlib1g-dev libbz2-dev libssl-dev libncurses5-dev libsqlite3-dev
#下载python
wget https://www.python.org/ftp/python/3.12.1/Python-3.12.1.tgz
#解压下载的python包
tar -zvxf Python-3.12.1.tgz
#进入目录
cd /var/jenkins_home
#修改目录名称
mv Python-3.12.1 python3
#进入到python3目录
cd python3
#执行命令
./configure --prefix=/var/jenkins_home/python3
#make编译安装
./configure --prefix=/var/jenkins_home/python3 --with-ssl
#这时候可能会提示执行命令:
./configure --enable-optimizations
make
make install
#添加python3软链接
which python3
ln -s /var/jenkins_home/python3/bin/python3.12 /usr/local/bin/python3
#添加pip3软链接
ln -s /var/jenkins_home/python3/bin/pip3 /usr/local/bin/pip3
#检查是否安装成功
python3 --version
pip3 --version
运行刚刚配置的Jenkins任务。构建完成后,Jenkins将会显示一个“Allure报告”的链接,点击它即可查看详细的测试报告。
通过上述步骤就可以在CentOS系统上,通过docker-compose安装Jenkins,并通过Jenkins运行pytest编写的Python测试用例,并生成Allure测试报告了。
八、项目结果通知
1.通过企业微信通知
可在“执行shell”中加入语句:
curl https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=yourkey \
-H 'Content-Type: application/json' \
-d '
{
"msgtype": "markdown",
"markdown": {
"content": "# 基建消防队 <font color=\"warning\"></font>\n
> ### 级别状态: <font color=\"green\">S1 Recovered</font>\n
> ### 规则标题: <font color=\"comment\">监控对象失联</font>\n
> ### 规则备注: <font color=\"comment\">检查categraf到n9e链路是否正常</font>\n
> ### 负责人: <font color=\"comment\">@xxx</font>\n
> [查看详细报告](填写报告链接地址)"
},
"mentioned_list":["@all"]
}'
在后面监测过程中想要报告展示的信息更全面,包含总测试案例、通过案例和通过率等字段的展示,可以更直观的看出报告详情。为了实现此功能,首先编写了python测试脚本result.py:
import json
#需注意这里的地址一定是容器内的地址!
with open('/path/to/report/directory/widgets/summary.json', 'r') as f:
summary = json.load(f)
total_cases = summary['statistic']['total']
passed_cases = summary['statistic']['passed']
pass_rate = passed_cases / total_cases * 100
print(f"总测试案例:{total_cases}")
print(f"通过案例:{passed_cases}")
print(f"通过率:{pass_rate:.2f}%")
其次在构建项目中修改原有的"执行shell"脚本,这是我第一次写的脚本
# 运行Python脚本,捕获输出
output=$(python /var/jenkins_home/pythonProject/result.py)
# 使用curl发送企业微信消息
curl https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=yourkey \
-H 'Content-Type: application/json' \
-d '
{
"msgtype": "markdown",
"markdown": {
"content": "# 基建消防队 <font color=\"warning\"></font>\n
> ### 级别状态: <font color=\"green\">S1 Recovered</font>\n
> ### 规则标题: <font color=\"comment\">网络入口监测</font>\n
> ### 规则备注: <font color=\"comment\">检查网络入口是否正常通信</font>\n
> ### 负责人: <font color=\"comment\">@xxx/font>\n
> ### 报告详情: <font color=\"comment\">'$output'</font>
> [查看详细报告](填写你的报告链接地址)"
},
"mentioned_list":["@all"]
}'
上述脚本执行项目后在群里发送的样式为:
实在是太丑了,有没有!!
后面为了优化此报告,经历了不断的修改,最后给出正确的代码!
修改result.py脚本内容为:
import json
report_path = '/var/jenkins_home/pythonProject/allure-report/widgets/summary.json'
with open(report_path, 'r') as f:
summary = json.load(f)
total_cases = summary['statistic']['total']
passed_cases = summary['statistic']['passed']
pass_rate = passed_cases / total_cases * 100
# 构建markdown格式的消息
markdown_message = f"""
> ### 总测试案例:<font color=\\\"orange\\\">{total_cases}</font>
> ### 通过案例:<font color=\\\"green\\\">{passed_cases}</font>
> ### 通过率:<font color=\\\"green\\\">{pass_rate:.2f}%</font>
"""
print(markdown_message.strip())
修改shell脚本内容为:
# 运行Python脚本,捕获输出
output=$(python /var/jenkins_home/pythonProject/result.py)
# 使用curl发送企业微信消息,注意在此处使用双引号以允许变量展开
curl https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=yourkey \
-H 'Content-Type: application/json' \
-d "
{
\"msgtype\": \"markdown\",
\"markdown\": {
\"content\": \"# 基建消防队 <font color=\\\"warning\\\"></font>
> ### 级别状态: <font color=\\\"red\\\">S1 Recovered</font>
> ### 规则标题: <font color=\\\"comment\\\">网络入口监测</font>
> ### 规则备注: <font color=\\\"comment\\\">检查网络入口是否正常通信</font>
> ### 负责人: <font color=\\\"comment\\\">@xxx</font>
> ${output}
> [查看详细报告](填写你的报告链接地址)\"
},
\"mentioned_list\":[\"@all\"]
}"
这样报告明显好看多了呢~
后面接口越来越多的情况下,有些接口第一次调用是失败的,但是发现当有测试case执行失败时,竟然影响到了整个项目的构建结果,这个肯定是不合理的。需要修改shell脚本解决此问题:
cd /var/jenkins_home/pythonProject
pytest -v -n 8 test_networkMonitor.py --alluredir "allure-results" --clean-alluredir || true
加入“|| true”判断会保证,不管pytest结果如何,脚本的执行都会继续进行,从而避免因测试失败而影响到最后的构建结果。
2.通过邮件通知
(1)系统管理-->全局凭据配置-->设置发送邮件的用户名和密码作为全局凭据
(2)系统管理-->系统设置-->Extended E-mail Notification-->设置相关参数
(3)系统管理-->系统设置-->邮件通知-->设置相应参数
(4)你的项目-->构建后操作-->Editable Email Notification-->设置相应参数
这样就可以实现邮件发送啦~
九、配置域名DNS解析
最开始的思路是通过部署nginx,编写了docker-compose.yml文件
version: '3.9'
services:
jenkins:
image: jenkins/jenkins:lts
container_name: jenkins
network_mode: "host"
user: root
restart: always
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /root/compose/jenkins/jenkins_data:/var/jenkins_home
- /root/compose/jenkins/pythonProject:/var/jenkins_home/pythonProject
- /root/compose/jenkins/apache-maven-3.9.8:/usr/local/apache-maven/apache-maven-3.9.8
- /root/compose/jenkins/jdk-11.0.23:/usr/local/jdk-11.0.23
- /root/compose/jenkins/conf/profile:/root/.bashrc
environment:
- TZ=Asia/Shanghai
nginx:
image: nginx
container_name: nginx
restart: always
user: root
ports:
- "80:80"
volumes:
- /root/compose/jenkins/nginx:/etc/nginx/conf.d
depends_on:
- jenkins
在/root/compose/jenkins/nginx下新增nginx.conf文件,文件内容:
server {
listen 80;
server_name 你想要解析的域名;
location / {
proxy_pass http://你的机器IP:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
nginx启动之后,输入全新的域名就可以登录了
后续方案升级,端口转发交给docker,域名解析交给运维,不在需要nginx,最终的docker-compose.yml修改为:
version: '3.9'
services:
jenkins:
image: jenkins-terra:lts
container_name: jenkins
user: root
restart: always
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /root/compose/jenkins/jenkins_data:/var/jenkins_home
- /root/compose/jenkins/pythonProject:/var/jenkins_home/pythonProject
- /root/compose/jenkins/apache-maven-3.9.8:/usr/local/apache-maven/apache-maven-3.9.8
- /root/compose/jenkins/jdk-11.0.23:/usr/local/jdk-11.0.23
- /root/compose/jenkins/conf/profile:/root/.bashrc
environment:
- TZ=Asia/Shanghai
ports:
- "80:8080"
你学废了吗?
十、其他问题
需求:由于不在公司的时候,希望可以直观看到报错接口和报错原因
首先了解到报告是通过Allure报告展示的,之前可以通过点击Allure报告链接查看详细情况,我的思路是:通过编写python脚本调用Allure接口,首先调用了Overview这个接口获取failed_count这个参数,通过failed_count的值来加入if条件语句,当failed_count=0时,返回:“Allure report no error!”类似的信息,当failed_count!=0时,调用Allure报告的categories接口,返回具体的报错接口和报错原因。
代码段1:封装visit函数
import requests
class RequestHandler:
def __init__(self):
"""session管理器"""
self.session = requests.session()
def visit(self,method,url,params = None,data=None,json=None,headers=None):
result = self.session.request(method,url,params=params,data=data,json=json,headers=headers,verify=False)
try:
#返回json结果
print(result)
return result.json()
except Exception:
return 'not json'
def close_session(self):
self.session.close()
代码段2:调用Allure报告接口
import unittest
import allure
import os
import pytest
from common.requests_handler import RequestHandler
@allure.epic("查看allure报告界面")
@allure.feature("检查报错接口")
class TestCheckErrorInAllureReport(unittest.TestCase):
def setUp(self):
#请求类实例化
self.req = RequestHandler()
def tearDown(self):
self.req.close_session()
@allure.title("检查接口是否存在错误信息")
def test_check_error_in_report(self):
# 获取当前构建编号,并转换为整数类型
current_build_number_str = os.getenv('BUILD_NUMBER')
current_build_number = int(current_build_number_str)
BUILD_ID = current_build_number
print(f"Current Jenkins build ID: {BUILD_ID}")
with allure.step("step1:首先打开Overview界面"):
print("访问Overview界面成功")
url = '你要调用的Overview接口'.format(BUILD_ID)
headers = {
"Cookie": "你的Cookie",
"Accept": "application/json, text/javascript, */*; q=0.01",
"Content-Type": "application/json"
}
res = self.req.visit('get', url, headers=headers)
print(res)
print(type(res)) #这里最开始会有类型报错,所以打印了类型
failed_count = res['items'][0]['statistic']['failed']
print("failed_count: %s" % failed_count)
if failed_count > 0 :
with allure.step("step2:打开Categories界面"):
print("访问Categories界面成功,界面展示报错接口详情")
error_url = '你的categories接口'.format(BUILD_ID)
header = {
"Accept": "application/json, text/javascript, */*; q=0.01",
"Cookie": "你的Cookie"
}
res = self.req.visit('get', error_url, headers=header)
print(res)
else:
print("allure report no error!")
代码段3:封装check.py用于生成markdown消息模式
import re
import glob
report_path = "你的报告地址"
pattern = report_path + "*-attachment.txt"
# 将匹配到的所有文件内容合并
file_contents = ""
for file_name in glob.glob(pattern):
with open(file_name, "r") as file:
file_contents += file.read() + "\n"
# 搜索failed_count的值
failed_count_match = re.search(r"failed_count: (\d+)", file_contents)
failed_count = failed_count_match.group(1) if failed_count_match else "0"
# 查找所有失败的HTTP接口和对应的报错原因
error_pattern = re.compile(r"\[https?://[^\s]*]", re.DOTALL)
error_urls = error_pattern.findall(file_contents)
error_pattern1 = re.compile(r"'name': 'Failed: (.*)', 'children'", re.DOTALL)
error_reason = error_pattern1.findall(file_contents)
# 根据failed_count的值定制输出内容
if failed_count == "0":
markdown_message = "> ### 报告详情:<font color=\\\"comment\\\">Allure report no error!</font>"
else:
markdown_message = f"""
> ### 失败案例:<font color=\\\"#FF0000\\\">{failed_count}</font>
> ### 失败接口:<font color=\\\"#FF0000\\\">{error_urls}</font>
> ### 失败原因:<font color=\\\"comment\\\">{error_reason}</font>
"""
print(markdown_message.strip())
代码段4:项目的shell脚本中编写:
cd /var/jenkins_home/terra-jenkins
#pip3 freeze > requirements.txt
pytest -v -n 8 test_networkMonitor.py --clean-alluredir --alluredir "allure-results" || true
# 清除旧的报告内容
rm -rf /var/jenkins_home/terra-jenkins/allure-report
pytest -v test_check_allure_report.py --clean-alluredir --alluredir "check-allure"
# 运行Python脚本,捕获输出
output=$(python3 /var/jenkins_home/terra-jenkins/result.py)
message=$(python3 /var/jenkins_home/terra-jenkins/check.py)
# 使用curl发送企业微信消息,注意在此处使用双引号以允许变量展开
curl https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=yourkey \
-H 'Content-Type: application/json' \
-d "
{
\"msgtype\": \"markdown\",
\"markdown\": {
\"content\": \"# 基建消防队 <font color=\\\"warning\\\"></font>
> ### 规则标题: <font color=\\\"comment\\\">网络入口监测</font>
> ### 规则备注: <font color=\\\"comment\\\">检查网络入口是否正常通信</font>
> ### 负责人: <font color=\\\"comment\\\">@xxx Junping</font>
> ${output}
> ${message}
> [查看Allure详细报告](jenkins地址/job/${JOB_NAME}/allure/)\"
},
\"mentioned_list\":[\"@all\"]
}"
最开始获取BUILD_ID的时候执行是会报错:
很明显报错显示类型不正确,我们可能取的dict类型的,也尝试过改为dict类型,但之后执行仍然是各种类型报错,接口返回依然是404
而且还遇到一个问题, 执行时虽然能够正常获取到参数以及报错内容,但是点击Allure报告链接发现每次竟然展示的上一次的报告内容!!
后面通过查看日志惊奇的发现:
原来allure报告生成步骤是在执行python脚本和发送企业微信消息之后,这就会导致每次取的数据都是上一次的allure-report目录下的数据。那如何解决呢?当然要使用最合理的执行顺序!
因为之前的Allure报告生成是构建后操作步骤中添加的,要将执行的python脚本和发送企业微信消息的shell脚本内容必须也放在构建后操作步骤才能解决此问题。
需要下载插件:系统管理-->插件管理-->Available plugins-->搜索下载Post build task插件
修改项目原有的执行shell脚本
项目-->构建后操作步骤-->加入Post build task
编写脚本内容如下:
pytest -v test_check_allure_report.py --clean-alluredir --alluredir "check-allure"
# 运行Python脚本,捕获输出
output=$(python3 /var/jenkins_home/terra-jenkins/result.py)
message=$(python3 /var/jenkins_home/terra-jenkins/check.py)
# 使用curl发送企业微信消息,注意在此处使用双引号以允许变量展开
curl https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=yourkey \
-H 'Content-Type: application/json' \
-d "
{
\"msgtype\": \"markdown\",
\"markdown\": {
\"content\": \"# 基建消防队 <font color=\\\"warning\\\"></font>
> ### 规则标题: <font color=\\\"comment\\\">网络入口监测</font>
> ### 规则备注: <font color=\\\"comment\\\">检查网络入口是否正常通信</font>
> ### 负责人: <font color=\\\"comment\\\">@xxx</font>
> ${output}
> ${message}
> [查看Allure详细报告](jenkins地址/job/${JOB_NAME}/allure/)\"
},
\"mentioned_list\":[\"@all\"]
}"
通过上述整个项目已经全部完成,你学废了吗?