2023年6月16日,2023上海国际嵌入式展(embedded world China 2023)圆满落幕。龙智参与此次展会并展示了其针对嵌入式行业的DevSecOps解决方案,帮助企业实现合规、可追溯、高效优质、单一可信数据源的嵌入式开发。
展会期间,龙智资深DevSecOps顾问巫晓光带来了题为“更好、更快、更安全:嵌入式开发中的最佳实践和工具链构建”的主题演讲,受到参展观众关注。
以下是完整文字实录(有删改润色):
大家好,我是龙智的技术工程师巫晓光。今天非常荣幸跟大家分享嵌入式开发中的心得与体会。我分享的主题是“更好、更快、更安全:嵌入式开发中的最佳实践和工具链构建”,主要分为三个部分,首先是版本控制,其次是质量合规,最后是测试自动化。
版本控制
俗话说有人的地方就有江湖,有开发人员的地方就会用到版本控制工具,这已经成为了业界共识,版本控制是团队协作的基础。
当企业规模较小时,一般使用一些开源的版本控制工具,比如Git、SVN等。由于这个时候客户规模较小,数据量不大,业务也比较单一,开源的版本控制工具能够基本满足需求。但随着企业规模的扩大,数据量和用户都随之增长,业务也更加复杂,版本控制工具就会面临一系列的挑战。
版本控制系统面临的挑战
首先是分支管理的难度增加。通常来说,我们使用的分支类型有主分支、开发分支以及发布分支等。如果有多个功能在并行开发,就会拉出很多功能分支,到项目开发的后期,一个项目就可能有几十个分支。维护这些分支间的关系会变得非常复杂,如果只用命名的方式进行区别,而没有一个图形化的界面去展示分支关系,可能会随着时间推移而忘记分支间的关系。
另外,分支合并也成为一个难题。目前市场上的一些版本控制工具,分支合并能力很弱。大家可能都有类似经历,在分支合并时,会引入一系列不必要的冲突,需要人工去解决。往往一个发布周期的前几天都是在解决这些冲突。
第二个挑战是数据量过大。龙智的一些客户后期数据量达到几十、上百T。
数据量达到这个级别,面临的问题就是数据提交速度会非常慢,例如一些10G以上的大文件,提交速度非常缓慢,并且经常提交失败。
数据量过大还会导致存储问题。单个库是无法承受如此之大的数据量的,只能将数据进行拆分,再放到各个系统中,这导致了后期维护的成本成倍增加。到了开发后期,可追溯性也成为一个问题,因为数据分散在不同的系统中。
面临的第三个挑战是跨地域协作。企业规模扩大后,项目组成员分布在全国甚至全球各地的情况。在这种情况下,面临最明显的问题就是跨地域提交。因为带宽或网络波动,可能会造成提交延时或失败。
第四个挑战来自于安全及审计需求。开源版本控制工具的权限控制能力较弱,比如Git的权限控制是到项目级别,SVN是到文件夹级别。在项目中,难免有一些重要文件需要进行严格的访问权限控制,这样就需要版本控制系统的权限控制力度细化到文件级别。并且,如果在审计方面没有完备的日志,后期定位、追溯问题都会十分麻烦。
当企业面临的问题越来越多时,其实是在释放一个信号:目前所使用的版本控制工具已经无法满足企业的业务需求了。同时,也会发现工作效率在下降、管理成本增加。虽然在版本控制工具上节省了开支,但无论是成本管理还是工作效益,都造成了很大的损失,这是隐性的成本。
所以,此时要改变观念,把版本控制工具放在更重要的位置,需要为企业寻找一款更高效、更安全的版本控制工具。
强壮的版本控制系统是研发流程的核心
强壮的版本控制系统是研发流程的核心。为什么这样说?企业,特别是软件企业,大部分的劳动成果(比如设计资料、代码、配置项、生成物等)最终都会转换成数字资产,而这些都投入了大量时间和资金,所以数字资产很重要。
其次,所有的研发工作都是围绕着数字资产展开的。作为管理这些资产的版本控制工具,更是处于研发流程核心位置。它为团队围绕数字资产展开的工作保驾护航。一款好的版本控制系统可以在单一的平台上安全、高速地管理您的一切数字资产,无论资产的类型、位置、大小以及体量。
那么,如何评判一款版本控制工具是强壮的?我认为可以从以下几个方面来考虑。
首先是性能。简单列举一下,第一点,需要有很好的伸缩性。当企业规模只有几十名用户时,使用都很方便。但企业规模扩大,就需要版本控制系统能够支撑上万名用户。或是当数据量增加到几百T的时候,版本控制系统需要实现平滑的升级。第二点,对于全球团队合作的情况,则要求版本控制系统是灵活的分布式部署,以满足团队间的高效协作需求。第三点,需要支撑每天数以千计的流水线构建。企业每天可能有成百上千的流水线在构建,对于版本控制系统的性能来说也是一个挑战。第四点,现在的企业很多依赖于使用Git的开源项目,那么,版本控制系统需要提供一种可能性,既能兼容前端的开源工具,又能通过版本控制系统强大的后台为后端提供支撑。最后,是统一的企业级灾备计划。备份需要能够轻松维护,一旦发现问题事故,也能快速恢复,最大程度降低企业的损失。
然后是安全。版本控制系统需要有非常灵活、强大的权限控制机制,能够在文件级别进行版本控制。并且需要非常灵活,能够通过组的方式将权限下放给真正了解项目的人。审计方面需要有完备的记录,谁修改、谁访问、何时修改、何时访问等都需要记录在册,这是后期审计的基础。
最后是界面友好。版本控制系统需要与DevOps生命周期中各个环节的工具进行良好地集成,例如IDE工具、代码评审工具、需求管理工具以及后期的流水线集成。集成后即可推动DevOps的各个环节,加速产品迭代。
我推荐Perforce的旗舰版本控制工具——Helix Core。这是一款高效、安全的版本控制工具,也深受客户的喜爱。客户英伟达在评价Perforce Helix Core时提到,Perforce Helix Core作为他们唯一的可信数据源,是非常重要的存在。
质量与合规
代码质量对企业来说非常重要,尤其对嵌入式行业的企业来说更为重要。因为嵌入式的企业软件涉及到航空航天、医疗、汽车等行业,这些行业有着非常严苛的行业安全标准。众所周知,再好的软件工程师都无法避免Bug的产生。既然无法避免,那我们能改变什么?一是发现Bug的时机,二是发现Bug的方法。
代码质量与企业成本息息相关
这张图展示了代码质量和企业成本的关系。横坐标代表了软件的各个生命周期,包括开发、单元测试、功能测试、系统测试以及发布阶段。深蓝色的曲线表明,有85%的Bug都是在开发阶段产生的。再看一下橙色的曲线,它表明了Bug在测试阶段被发现,可以看到橙色曲线在开发阶段几乎没有发现Bug。再来红色曲线,它代表修复Bug的成本,可以看到在开发阶段,修复Bug的成本非常低,到测试阶段成本就成倍增加了。到后期,比如产品上线后,再发现Bug,修复的成本将呈指数级上升。
这一点相信大家都深有体会。在开发阶段,Bug是最容易被修复的,因为在开发环境中很容易重现Bug。到了测试阶段,因为测试人员需要准备大量的测试用例和测试数据,另外还涉及到开发人员的发布成本,以及开发与测试的沟通成本,所以会成倍增加。产品上线后再发现问题,(修复成本)就会呈指数级增长,原因有几个方面。
一是产品已经对客户造成损失,这时涉及到经济赔偿的问题,比如汽车行业,一旦发现汽车质量问题,就需要大量召回。二是在客户现场发现问题,则需要技术支持人员驻场,驻场本身也有成本。最令人头疼的问题是,我们到达客户现场后发现,Bug很难复现。它往往呈现一种随机性,很难捕捉。受制于线上环境,我们无法模拟大量数据,这时需要就现场搭建模拟环境。现场搭建需要花费数天,在这期间Bug修复是没有进展的。这时,您可能开始思考,有没有可能将发现或修复Bug的时机左移到开发阶段呢?
更早地发现问题
目前,一些企业采取的做法是人工代码审核,这能够在开发阶段发现一些问题,但有很大的局限性。首先,过多的依赖人工的经验。目前,龙智的一些客户采用的做法是人工审核,这种方法在一定程度上可以在开发阶段发现问题,但其实还是存在很大的局限性。大家也可能有类似经验,在审核时,没有强制性要求,我们就会提出一些无关痛痒的问题,例如代码命名不规范、大小写不规范等。另外,因为代码少则几万行,多则上百万行,人工审核难以全面地覆盖所有代码。这时,我们可能针对一些核心代码进行审核,而且审核效果也不明显。
行业合规标准
我的建议是引入静态代码扫描工具,它可以有效地在代码阶段发现代码质量问题。先简单介绍一下静态代码扫描工具的原理。它的原理是利用一些权威的、常见的代码标准(例如MISRA、AUTOSAR等),以及成熟的算法来扫描代码,并发现质量问题。
常用的代码标准
再来介绍一下代码标准。其实代码标准的作用更像是一个紧箍咒,将代码框定在一个安全的范围内。它限制了一些开发行为,从而避免一些开发中常见的错误,以及避免了安全隐患问题,包括常见的数据污染、内存泄漏等。如果说代码标准是紧箍咒,那么静态代码分析工具就是会念紧箍咒的唐僧。
一款好的静态代码分析工具应该符合什么条件?又该如何选择静态代码分析工具呢?首先,它需要误报率、漏报率低,关键的错误不能漏报。它也不能引入不必要的报警,干扰开发人员。第二,这款工具的检查规则需要更全面,尽可能多地覆盖常见错误。第三,扫描速度快。因为代码的规则和标准通常有成百上千条,代码又有几百万行,对于静态代码分析工具来说,工作量是两个数值的乘积。所以,它需要有成熟的算法来加快扫描的速度。第四,需要对开发人员友好,最好是开箱即用的。C、C++编译器有上百种,这就需要静态代码分析工具能与编译器进行紧密集成,并且不需要人工进行手动适配。最后一点,它应该能够轻松地与CI流水线工具进行集成。
静态代码分析工具一方面能够提高代码质量,一方面也可以帮助满足行业合规性要求。汽车、航天航空等行业通常面临着严苛的代码合规性要求,它们需要通过各种合规认证,常见的标准有:IEC 61508(通用工业,国防)、ISO 26262(汽车)、EN 50128(铁路)等。
我解释一下行业标准和代码标准之间的关系。因为很多刚开始使用静态代码分析工具的用户可能会混淆这两个概念。简单地来说,这两者之间是执行和被执行的关系。行业标准通常比较抽象、宽泛,它需要一个具体的执行者。而具体的执行者就是代码标准里的一些规则。
这里要提到一点,最下面一行(CERT、CWE等)是安全规则。
行业标准认证
行业标准认证会让用户感到十分头疼,因为认证是件麻烦事,规则很抽象、很宽泛。企业不知道该如何执行,该匹配什么规则。这里来看个简单的示例。英文是Enforcement of low complexity,中文意思是代码执行需要低复杂度。大家都知道这句话的意思,但无从下手。什么叫低复杂度?如何衡量?以及需要匹配什么规则去执行低复杂度?这些都缺少一个详细的说明。
合规指导
静态代码分析工具中的合规指导书可以提供帮助,它对合规的标准进行了详细的说明。
上图是Perforce静态代码扫描工具Helix QAC对于ISO 26262(汽车)标准的详细说明。左边是ISO 26262的一些条款,右边放大的图中则是详细说明。针对低复杂度,可以使用圈复杂度和路径复杂度两个指标来衡量,也可以使用MISRA的规则,本书中都有详细说明。
另外,在申请合规认证时,还需要准备一系列材料。静态代码扫描工具的安全手册中已包括了这些材料,包括工具本身的认证证书、产品的认证报告、工具的覆盖率详情、如何适配认证规则的说明,以及生成报告的插件。通过合规指导书,静态代码扫描工具能够帮助我们更方便、更快速地通过行业的合规认证。
SAST常见部署场景
静态代码扫描工具有三个常见的部署场景。首先是在IDE中即时分析。利用静态代码扫描工具中的IDE插件进行即时分析,让开发人员能够边写代码边扫描代码。第二,在代码提交时,代码仓库可以触发流水线,进行增量/全量检查。第三,每天对主分支进行检查。我推荐将第一、二点作为可选项,第三点我希望作为企业的必选项。在每天对主要分支进行检查的同时,还可以设置一个质量门限。
另外,像MISRA这样的规则非常严苛,一开始就放开所有规则是不现实的,这样可能造成一行代码扫描出几十个错误的情况,导致开发阶段处理Bug的阻力很大。所以我的建议是,刚开始使用静态代码扫描工具时,先启用一些优先级较高的关键规则,从而降低阻力。当开发人员的质量意识提高后,再逐渐把规则调到更加严格。
在这里,我推荐两款Perforce旗下的静态扫描工具,一款是Helix QAC,另一个款Klocwork。这两款工具各具特点,QAC更能满足合规性要求,它的代码标准覆盖率更高。它对于AUTOSAR的微覆盖率已达96%,这是非常高的。并且它拥有30多年的历史,专注于C/C++语言的代码分析,在嵌入式开发中颇负盛名。
Klocwork支持多种语言,并能很好地支持百万行甚至千万行代码的大型项目。除此之外,它的界面也十分友好,易于使用。
大家可以看到客户对QAC的评价——我们对HelixQAC印象深刻,因为它发现了其他工具遗漏的问题。而Klocwork则是在大型项目上更具性能优势。
测试自动化
测试对于代码质量来说非常重要。目前,很多企业主要采用手动测试的方法,这也催生了很多挑战。
人工测试面临的挑战
首先是软件迭代速度加快,无法在短时间内完成大量测试用例。现在的软件迭代速度非常快,可能一周发布一个版本,这就需要进行大量的回归测试。如果全凭人工,无法覆盖这么多测试。另一个经常会出现的情况,就是在准备上线的前几天,突然发现了Bug,需要紧急修复。这时,我们只能对软件进行冒烟测试,或是针对主要功能进行测试,无法覆盖大量的测试用例。重复性的测试通常比较繁琐枯燥,这会增加测试人员的负担。人工的疲劳或疏忽也会导致测试结果覆盖率低,不可靠。并且,性能和安全测试都是人工测试薄弱的地方。
既然人工测试面临这么多挑战,是否可以考虑引入自动化测试工具来解决问题呢?一起来看下自动化测试的现状。
自动化测试
首先,自动化测试无法完全取代人工测试。自动化测试更多是针对一些重复性测试,例如回归测试等,效率优于人工测试。第二,自动化测试的占比在不断增加。很多企业其实也在开发自动化测试的框架,但这种框架的学习成本较高,对于测试人员的要求较高,脚本维护也很麻烦。所以很多企业会选择无代码/低代码的自动化测试工具,通过录制、回放以及检查的功能完成测试,不需要编写脚本,降低测试人员的学习成本。
这里提到的自动化测试包括两个方面,一是UI自动化测试,也就是界面测试,另一个是API(接口)测试。很多医疗软件有人工交互的界面,还有上位机也会简单的做一些界面,这些都是使用UI自动化测试的场景。
UI自动化测试工具选择
一款好的UI自动化测试工具应该具备哪些条件?首先需要能够支持多平台测试。现在的产品呈现平台多样化的趋势,有桌面、Web和移动端等。甚至还有一些工业设备和穿戴式的设备,UI自动化测试工具最好能够对所有平台进行支撑。第二点是需要能够支持多种技术框架。现在的技术框架层出不穷,需要自动化测试工具尽可能多的集成和兼容。第三点是对象识别能力强,准确的定位控件。这也是很多自动化测试工具的弱点,许多工具的对象识别能力较差。在对控件属性进行修改后,自动化测试工具可能无法识别,这时就需要使用脚本或重新录制,降低了工作效率。最后是需要方便地与CI/CD、版本管理等工具集成。
符合这些条件的UI自动化测试工具就是SmartBear的TestComplete。“在回归测试方面,它为企业节约了大量时间。平常需要三天的测试现在三小时就能完成。”这是客户对TestComplete的评价。
API自动化测试工具选择
另一个方面涉及到API接口的自动化测试。API接口是非常适合使用自动化测试的,因为API接口通常是纯数据结构,这种结构本身是需要机器读取的一种语言。
那么,一款好的API自动化测试工具需要具备哪些条件?首先是需要支持多种协议。通信协议多种多样,应用层的协议也是如此,这些都需要工具能支持。第二是能够快速构建测试步骤,需要工具有一些图形化的界面帮助快速设置断言、检查点,以及快速搭建测试步骤等。第三是支持内置数据字典,可以帮助快速自动生成安全测试。最后一点是能够模拟各种真实场景进行性能测试。
API自动化测试工具我推荐SmartBear的ReadyAPI。
客户对这款产品的评价中提到:“ReadyAPI就是我们技术的核心”。
我今天的演讲就到这里,谢谢大家。