干货 | 提前在开发阶段暴露代码问题,携程Alchemy代码质量平台

news2024/7/4 5:20:09

作者简介

Lyan,携程资深后端开发工程师,负责自动化测试框架及平台类工具开发,关注Devops、研发效能领域。

一、背景

随着敏捷开发,DevOps开发模式的流行,代码质量分析作为研发质量保证体系的重要组成部分,不仅能有效的降低因频繁迭代带来的故障风险,而且对整个工程团队的效能提升有着巨大的价值。

携程很久以前就已经开始进行DevOps的建设,通过Gitlab CI/CD在开发提交代码触发的流水线pipeline中引入静态扫描、单元测试、集成测试等流程,在开发过程中打造了一套闭环的代码质量保障体系。其中,在静态代码分析阶段引入了SonarQube,并且通过对原有SonarQube代码规范库中的规范进行筛选和扩展,形成了自己的代码规范库。但是在实际应用过程中,我们发现仍然有一些问题需要优化解决:

  • 在开发过程中,代码规范只能通过开发人员自我约束,缺少统一的平台对各应用代码的潜在风险问题统一进行分析,且问题难以定位到开发人员进行治理。

  • 代码单元测试通过率和代码覆盖率都很高,但仍然存在一些在单元测试阶段应被发现的问题未暴露出来,导致上线后出现bug,单元测试用例的质量缺乏有效性及可靠性保证。

  • 随着项目的发展,开发人员为了避免影响已有功能,在开发过程中大量复制粘贴,导致出现很多难以维护的重复代码,且程序逻辑结构过于复杂,修改逻辑牵一发而动全身,可维护性差。

  • 代码中充斥着大量的sql拼接,以及一些不规范的写法导致潜在的问题,需要对此类代码进行治理。

二、平台介绍

Alchemy平台是一个代码质量分析平台,提供Infer分析、代码分析、自定义扫描、代码搜索等功能,其中代码质量分析内容包含代码行,sonar问题, infer问题,UT规则,重复代码以及圈复杂度等。用户可以根据自己的需求在平台上进行扫描项配置,并查看应用的代码质量分析结果。

为了及时获得对提交代码变更的质量反馈,作为DevOps中重要的一环,Alchemy平台与Gitlab CI/CD相结合,将静态代码分析提前至开发提交或合并代码阶段。开发人员提交代码至Gitlab,触发流水线相关任务执行,任务执行完成之后可以对某些指标(如增量代码引入的空指针)设置红线进行卡点,如果指标在指定范围内,允许合并代码并发布,如果指标超过了红线设置范围,则不允许合并代码,开发人员修复问题后再次提交代码进行流水线的集成发布。扫描分析结果可以在Gitlab或者Alchemy平台上展示,帮助开发人员在快速迭代的同时保证代码质量。

05e661f773c9fd0ddafa278f2f9b7ea6.png

静态代码扫描流程

三、系统架构

Alchemy平台包含Alchemy-client、Alchemy-service和Alchemy-web。其中,Alchemy-client为扫描脚本,包含Infer分析,UT扫描,重复代码扫描、自定义扫描等功能,集成到Docker镜像中,Alchemy-service提供数据存储、分析等后台服务,且依赖代码搜索服务CodeSearch-Service实现代码搜索功能,Alchemy-web负责页面交互。

开发人员提交代码,触发Gitlab CI/CD中静态代码分析job在GitRunner中执行,执行时先从Docker仓库下载镜像,启动容器后执行Alchemy-client脚本,脚本会根据平台配置来执行相应的扫描任务,扫描完成后,将结果上传至Alchemy-service,存储到mongodb数据库,最终在前端页面展示分析结果。

fe8c02ae7838b6afb6a0a4b46edd9eaf.png

Alchemy架构图

四、功能

4.1 Infer分析

Infer是Facebook出品的一个静态分析工具,可以分析Java、Objective-c或者C代码,报告潜在的问题,包括空指针,资源泄漏等。Alchemy平台将Infer引入代码静态分析阶段,目前已支持全量和增量分析两种模式。

全量模式需分析应用仓库中的所有代码,能分析出所有代码引入的潜在问题,对于代码量较大的应用,由于需要分析所有代码文件,扫描时间比较长,在一定程度上影响开发发布进度,且对未修改的代码进行了非必要的重复分析,在代码修改量较少的情况下造成资源浪费。因此,我们尝试加入缓存机制,并引入了增量分析模式,增量模式需要获取本次提交修改的文件,在分析阶段只针对这些改动文件进行分析,能大大节省分析时间。Infer分析流程如下:

9f61e239b2c82927e81f6ee95889d2f3.png

Infer分析流程图

在分析过程中,首先判断是否为第一次分析,如果没有分析历史记录,则系统默认采用全量模式,否则需判断Infer扫描配置,若配置为全量模式,则分析此代码工程的全部文件,若配置为增量模式,需获取此次提交修改的文件列表,编译过程完成之后,在分析阶段指定文件列表进行分析。获取到分析出的问题列表后,判断问题所在的行是否为修改行,如果是,则记录为本次修改导致的新增问题,否则为历史遗留的全量问题。

在实际应用中,针对封装的判空方法,通过添加@TrueOnNull或@FalseOnNull注解,可识别对象的判空操作。但对于第三方包的判空方法,如CollectionUtils.isEmpty(), 由于未添加注解,即使添加判空方法,仍会被误识别为空引用。因此,Alchemy平台加入了忽略操作,针对此类问题进行二次确认,避免重复误判。

4ff9db380a2d24d3f6109faed79e5036.png

Infer误判结果

4.2 UT规则扫描

单元测试是DevOps流程中一个非常重要的环节,我们可以利用通过率和代码覆盖率等指标来衡量单元测试用例的完整程度,却很难保证用例的有效性。阿里巴巴java开发手册规定,单元测试不允许使用System.out来进行人肉验证,必须使用断言assert来验证。

在实际的开发过程中,开发人员把主要的时间用在写业务逻辑代码上,在编写单元测试用例时,往往容易忽略对结果的验证,虽然通过率和代码覆盖率很高,但上线后仍然出现未对接口结果进行验证而导致严重问题的情况。无效的单元测试用例包含以下几种:

  • 空函数:函数体为空;

  • 空断言:用例中实现了对被测接口的调用逻辑,但未对接口返回结果进行验证;

  • 伪断言:用例中使用类似assertTrue(True)的假断言。

通过扫描空断言、空函数、伪断言等问题,能判断该用例是否对代码逻辑进行必要的验证。Alchemy平台支持单元测试用例的有效性验证,目前,平台支持Java、Kotlin、Groovy和Nodejs,同时也支持全量和增量2种扫描结果,全量结果即为所有测试用例中不满足规则的用例,增量结果为本次提交修改的测试用例中不满足规则的用例。

7cb7287342d2cc99ddc9b864524603d4.png

UT扫描流程

对单个单元测试文件的扫描流程如图。首先根据文件后缀判断语言类型,然后根据不同语言类型规则获取该文件中的用例信息,包含case名称、起止行、作者、最近修改时间、函数内容等,针对函数内容,先判断用例是否有断言,如果有,则判断是否为伪断言,如果未断言或者被判为伪断言,还需进一步根据用例的起止行,结合本次提交的改动信息,分析该用例是否为增量改动的用例,如果是则标记为增量问题,最后将结果推送给gitlab,在合并代码或发布时根据红线配置进行卡点。扫描结果如图所示。

28ac947d6c240b67706b9f21c8e7ba49.png

UT扫描结果

4.3 重复代码扫描

重复代码即为重复或近似的代码,在开发过程中,开发人员为了避免影响现有功能,使用复制粘贴快速完成开发任务,导致出现大量的重复代码。重复代码不仅让代码量大增,造成编译速度慢,而且占用大量存储空间,如果想要修改其中一段代码逻辑,则需要同时修改多个地方,容易遗漏,可维护性差。

当前市面上有很多代码检测工具,如Simian,PMD-CPD,CloneDR等,由于在实现算法上有所不同,不同工具所能检测的重复代码类型也不尽相同。我们利用PMD-CPD扫描代码仓库,可以检测出单文件或多个文件中除了空格、注释、换行以及变量名以外内容完全一致的代码段信息,这些信息包含文件路径、代码段内容、起止行以及作者信息,详情结果如图所示。

9f11ac5aaed1da1217ea78f001212ece.png

重复代码详情结果

4.4 自定义规则扫描

Alchemy支持对自定义规则的扫描,通过配置自定义正则表达式和扫描范围,识别代码文件中满足配置规则的代码段,可用于扫描代码中的拼接SQL,敏感词等,并且可将不合规的代码定位到相关开发人员。

423ffcad0e82a4fffc1331896895a104.png

自定义扫描流程

单个文件扫描流程如图,首先判断文件是否在扫描范围内,若不在则直接跳转扫描下一个文件,否则读取文件内容,同时根据文件类型获取对应的自定义规则,匹配满足规则的代码段信息,包含代码段内容、严重程度、起止行、作者等。在某些场景下,需要设置子规则进行二次匹配,比如扫描update未指定where条件的sql语句,可先根据规则找到update语句,然后根据子规则判断是否带where条件,最终记录二次匹配的结果。

4.5 代码分析

使用不同工具统计的代码质量指标可能分散在不同的平台,对这些指标进行全面分析的过程中难免会有所遗漏,特别是对于未设置发布卡点的指标,开发人员可能并不会关注它们,导致代码存在大量的潜在问题未被分析治理。

Alchemy代码分析模块可以对代码不同维度的指标进行统计分析,包括代码行、单元测试、infer问题、Sonar问题、重复代码、圈复杂度等。用户可以在代码分析页面查看各维度问题分布情况,从而对项目的整体风险指标进行更全面的分析,可以根据问题的严重程度设置优先级进行针对性的治理。

69621104c9626200cc4f3b25d3ee8843.png

代码分析结果

4.6 代码搜索

在开发过程中,对于一些公共操作如中间件的使用方式,开发人员可能需要四处寻找接入文档。Alchemy提供代码搜索功能,可以帮助开发人员根据关键词来查找收录项目中的代码使用示例,用户可以根据项目仓库、代码语言以及作者等条件进行细分查询。在编码过程中,命名规范是一个容易被忽视的问题,使用Alchemy的变量命名功能,用户可以根据不同语言,搜索中英文关键词来获取推荐的规范命名参考,能极大地提高开发效率。

4f0c6bcee691e0c65b4eb24e666a9bc1.png

代码搜索结果

五、结束语

在本文中,我们介绍了Alchemy平台提供的代码静态分析,代码探索以及通过与Gitlab CI/CD集成带来的持续集成能力,可以在开发阶段暴露出更多的代码潜在问题和风险,并及时反馈给相关人员。目前携程酒店已接入项目800+,且在开发提交代码和发布阶段将分析的潜在问题接入了卡点流程。在后续的工作中,我们将从以下几个方向进行进一步的优化:

  • 在代码分析层面支持更多语言;

  • 开发IDE插件,在编码阶段实时扫描代码;

  • 继续深挖代码风险指标,并引入评估机制。

【推荐阅读】

  • 质量保障新手段,携程回归测试平台实践

  • 携程机票前台Trace系统的演进之路

  • AREX-携程无代码侵入的流量回放实践

  • 携程机票BDD UI Testing框架 - Flybirds

9275bee74ee06367c87b069cbae721d4.jpeg

 “携程技术”公众号

  分享,交流,成长

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

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

相关文章

LVS负载均衡群集--NAT

目录 前言 一、对于lvs负载均衡的了解 1、群集(集群)的概述 1.1 出现的问题 1.2 解决高并发的方法 2、群集的类型 2.1 负载均衡群集 2.2 高可用群集(冗余 单点故障) 2.3 高性能运算群集(分布式) …

【C++面向对象程序设计】CH6 多态性与虚函数

目录 一、多态性的概念 二、一个典型的例子——【例6.1】 1.声明基类point类 2.声明派生类circle ​编辑 3.声明circle的派生类cylinder 三、虚函数 1.虚函数的作用 (1)派生类的对象可以给基类的对象赋值 (2)派生类的对象…

mmdetection3d SUN RGB-D数据集预处理

SUN RGB-D是普林斯顿大学发布的一种关于室内场景理解的数据集,共包含了10335个样本,其中训练样本和验证测试样本数量分别为5285和5050。每个样本包含了彩色图像(RGB)和深度(D)信息,并且分别进行…

智能微型断路器在道路照明、园区照明、隧道照明中的应用-安科瑞 时丽花

智能微型断路器应用场景 九小场所 商场、超市等购物场所 养老院、福利院、孤儿院等社会福利机构 图书馆、博物馆、科技馆、文化馆等文化活动中心 车站、轨道交通等交通枢纽 易燃易爆仓库、木材加工、纺织、喷涂、制药等企业 酒吧,网吧等娱乐场所 幼儿园、小…

B站视频弹幕不挡住人脸效果

前言 有天在B站看二舅的视频时,密密麻麻的弹幕居然没有二舅的人脸,很好奇是怎么做到的,于是决定一探究竟。 高端的效果,往往只需要采用最朴素的实现方式,琢磨了好一会儿,打开了F12,豁然开朗。…

Quartz深度实战

概述 Java语言中最正统的任务调度框架,几乎是首选。后来和Spring Schedule平分秋色;再后来会被一些轻量级的分布式任务调度平台,如XXL-Job取代。另外近几年Quartz的维护和发布几乎停滞,但这并不意味着Quartz被淘汰,还…

【干货】微信私域运营打法和案例拆解(附78页pdf下载链接)

省时查报告-专业、及时、全面的行研报告库省时查方案-专业、及时、全面的营销策划方案库【免费下载】2022年10月份热门报告盘点知识图谱在美团推荐场景中的应用实践.pdf清华大学256页PPT元宇宙研究报告.pdf(附下载链接)机器学习在B站推荐系统中的应用实践…

【吴恩达机器学习笔记】七、神经网络

✍个人博客:https://blog.csdn.net/Newin2020?spm1011.2415.3001.5343 📣专栏定位:为学习吴恩达机器学习视频的同学提供的随堂笔记。 📚专栏简介:在这个专栏,我将整理吴恩达机器学习视频的所有内容的笔记&…

数据库设计三范式

数据库设计三范式 范式是数据库设计时遵循的一种规范,不同的规范需要遵循不同的范式,只有充分遵循了数据库设计的范式,才能设计开发出冗余较小、高效、结构合理的数据库。 通常,我们在设计数据库的时候会要求遵循三范式。 第一…

《强化学习周刊》第69期:ICLR2023强化学习论文推荐、MIT实现自动调整内在奖励的强化学习...

No.69智源社区强化学习组强化学习研究观点资源活动周刊订阅告诉大家一个好消息,《强化学习周刊》已经开启“订阅功能”,以后我们会向您自动推送最新版的《强化学习周刊》。订阅方法:方式1:扫描下面二维码,进入《强化学…

使用Python PySNMP模块获取设备指标

一、PySNMP模块介绍: PySNMP 是一个跨平台的纯Python SNMP 引擎实现。它具有功能齐全的 SNMP 引擎,能够充当代理/管理器/代理角色,通过 IPv4/IPv6 和其他网络传输传输 SNMP v1/v2c/v3 协议版本。目前,使用较多的是SNMP v3和v2c版…

Robust Document Image Dewarping Method Using Text-Lines and Line Segments论文学习笔记

1 摘要 传统的基于文本行的文档去扭曲方法在处理复杂布局和/或非常少的文本行时会出现问题。当图像中没有对齐的文本行时,这通常意味着照片、图形和/或表格占据了输入的大部分。因此,对于健壮的文档去扭曲变形,我们建议除了对齐的文本行之外…

Python解题 - CSDN周赛第11期 - 圆桌请客(脑筋急转弯)

本来想着没有all pass就不写题解了,但在赛后对最后一题纠结了好久,然后发现是个类似脑筋急转弯的题,自己与正确答案只差一层纸,实在有点不吐不快。另外本期考了经典的背包问题的模板题,也值得记录下来,加深…

全志科技A40i国产开发板——性能参数综合测试

本次测试板卡是创龙科技旗下,一款基于全志科技A40i开发板,其接口资源丰富,可引出双路网口、双路CAN、双路USB、双路RS485等通信接口,板载Bluetooth、WIFI、4G(选配)模块,同时引出MIPI LCD、LVDS LCD、TFT LCD、HDMI OUT、CVBS OUT、CAMERA、LINE IN、H/P OUT等音视频多媒…

宿主机与开发板网络共享

宿主机网络共享 一、关键步骤 11. 网络共享简介 目标:宿主机可以用ssh连接开发板,开发板可以上网。 步骤:宿主机与目标机用网线直连,宿主机采用IP共享的方式连接开发板; 配置项IP开发板IP192.168.0.232宿主机以太网I…

Java 序列化原理

我的网站 | 我的博客 | 序列化解析工具 概念 Java为我们提供了一种默认的对象序列化机制,通过这种机制可以将一个实例对象写入到IO流中,当然这种IO流可以是文件流、网络流或者其他什么流。 代码的写法 ObjectOutputStream 对象输出流,用…

2022新一代设备维修管理系统助力企业降本增效

设备的维修是指企业或者设备密集型单位为了保持、恢复并提升设备使用寿命而定期对设备进行状态的维护,备件的更换,发生故障后的维修和恢复,从而让设备保证良好的运营状态,提升设备的可利用性并保证产能和设备安全。 大型企业在设…

C++11标准模板(STL)- 算法(std::merge)

定义于头文件 <algorithm> 算法库提供大量用途的函数&#xff08;例如查找、排序、计数、操作&#xff09;&#xff0c;它们在元素范围上操作。注意范围定义为 [first, last) &#xff0c;其中 last 指代要查询或修改的最后元素的后一个元素。 归并两个已排序的范围 st…

关于Mysql使用left join写查询语句执行很慢的问题解决

目录 &#xff08;一&#xff09;前言 &#xff08;二&#xff09;正文 1. 表结构/索引展示 &#xff08;1&#xff09;表结构 &#xff08;2&#xff09;各表索引情况 2. 存在性能问题的SQL语句 3. 解决思路 &#xff08;1&#xff09;执行计划思路调优 &#xff08;…

数字图像处理(入门篇)二 颜色空间

在对图像进行处理时&#xff0c;前提图像必须是以数据的形式来描述的&#xff0c;而颜色空间就是用数据来表征图像颜色的一种方法。颜色信息由三个独立的分量来综合表示&#xff0c;这三个独立的分量构成了一个三维的坐标空间&#xff0c;每种颜色信息都在该空间中被唯一地表示…