通过自定义构建引擎和构建定义可以很方便的将各种代码测试或者编译工具集成入 RTC 自动化运行,同时也可以很便利的将测试或者编译结果上传回 RTC,供开发和测试人员查看。
IBM Checking Tool for Bugs Errors and Mistakes(本文后面将采用其文字缩写 BEAM)是 IBM 开发的一个静态分析工具,用于查找 C、C + +和 Java 程序中的错误。它直接对代码进行分析,不会尝试执行源代码,也不需要对代码进行编译连接,因此并不需要为代码编写任何测试用例。它是对代码进行语法扫描,以类似于一个编译器的方式验证分析的软件。它会通过尝试代码中的各种逻辑路径来找出可能发出错误的一条路径。常见的 BEAM 错误包括不适当的申请释放内存、未初始化内存、指针错误等。
RTC 构建引擎
RTC 使用构建引擎和构建定义,实现代码构建。构建引擎定义了一个本地代理程序,等待 RTC 服务器的构建请求。并通过一个所谓的构建定义,用于定义如何使用一个构建引擎的各种设置。如提供一些环境变量,安排构建任务,并指定构建引擎需要调用的命令。
图 1. 构建引擎与构建定义
构建引擎的建立
构建引擎通过一个 ID 来表示自己。
图 2. 构建引擎实例
在本地的计算机上,运行着一个代理程序用于检测 RTC 的构建请求。当接受到请求后,代理程序会启动一个预定义好的命令来完成构建。
可以使用如下命令启动代理程序:
"jbe -repository https://jazz07.rchland.ibm.com:17443/jazz -userId USERID \ -passwordFile XXX.bin -engineId IDofBuildEngine -sleeptime 1"
执行完此命令后,本地计算机就会出现下图所示的控制台界面。
图 3. 代理程序等待构建请求
当代理程序接受到 RTC 的构建请求,代理程序就会首先下载最新的代码到本地,然后执行预先在构建定义里面设定好的命令,这一部分会在下一小节介绍。命令执行完毕,构建结果与测试结果会上传回 RTC。
图 4. 构建结果传回 RTC
构建定义的设定
构建定义提供构建所需要的所以设定,包括使用哪些构建引擎,设置环境变量,安排构建计划,以及设置代理程序需要执行的命令。
图 5 表示代理程序在收到构建请求后将执行如下的命令:
"python.exe IbmBaseCoreBuildPkg\MasterBuild.py --clean ${Clean} --build ${Build}"
图 5. 构建定义设置代理程序需要执行的命令
图 6 表示了构建定义里面设置的环境变量。如变量"Clean"被赋予了"all"这个值。
图 6. 环境变量定义
图 7 也是构建定义的各种设置。"Workspace"表示代理程序需要从哪个 workspace 上下载代码到本地。 "Load directory"指定了一个本地目录用于存放下载下来的代码。如果"Delete directory before loading"被选中,在装载代码前整个目录将被删除。Accept Options 表示是否应该使用最新的代码以及构建是否应该被执行当没有任何变化时。
图 7. 构建定义中的各种设定
BEAM 自动化测试环境搭建
BEAM 下载
可以通过 https://w3.eda.ibm.com/beam/install.html 网站下载 BEAM,直接将下载的 exe 解压到一个路径如(D:\DevTool\beam)下。安装最新版本的 Perl,并将 Perl 加入到系统路径中。BEAM 官网推荐使用 ActivePerl 这个发行版,http://www.activestate.com/activeperl
新建配置文件
配置文件用于记录编译器的特性,对应于不同语言和不同编译器需要不同的配置文件。BEAM 可以通过手工选择编译器来生成自己的配置文件。下面就是一个使用 VC++ Compiler, cl.exe 生成配置文件的例子。
>perl beam_configure --c cl -o cl_c_config.tcl
-cl 表示需要使用 cl.exe 作为编译器
--c 表示提取 cl.exe 中的 c 语言特性
-o 指定配置文件的输出路径
集成入编译环境
因为 BEAM 通过扫描代码来进行静态分析,所以可以通过将 BEAM 集成到编译环境中来实现都所以代码的扫描。一个很方便的做法是将编译代码时所有调用 cl.exe 的地方加上调用 BEAM 的命令。在 windows 下,可以使用下述脚本代替 cl.exe。
cl %* beam_compile --beam::compiler=cl_c_config.tcl --beam::exit0 %* cl %*
调用两次 cl 是为了保证所有编译中间文件不会被 BEAM 覆盖或修改。用上述脚本所有 cl 要编译的文件都会先被 cl 编译然后被 BEAM 检测最后再运行一遍 cl。
BEAM 与 RTC 集成
由于 RTC 构建定义通过调用远程代理的脚本来实现构建,所以可以通过在脚本中加入调用 BEAM 的代码,就可以很方便的实现 RTC 与 BEAM 的集成。
我们在本文中的图 5 构建定义设置代理程序需要执行的命令中可以设置成自己编写脚本,在此脚本中,我们可以调用上一节中的三行脚本来代替正常编译使用的 cl.exe。同时我们可以设置成定时执行构建,譬如每隔 30 分钟执行一次,RTC 构建引擎就会自动从 RTC 源代码流上自动下载代码,然后执行我们自己的脚本,进行 BEAM 编译,最后把 BEAM 测试报告传回 RTC,这样就实现了对代码的自动化 BEAM 检测。
下图是我们在实验室环境下搭建的基于 RTC 构建引擎的 BEAM 自动化测试的运行效果。我们定义了名为 BeamTestBuilder 的构建引擎,在服务器上运行了代理程序用于检测 RTC 的构建请求,同时定义了 BEAM 构建定义 Core 3.0 Dev Beam Test,设定了每隔 30 分钟提交一次构建请求,这样就实现了自动化的 BEAM 测试环境。
图 8. BEAM&RTC 集成运行效果
构建请求完成后,构建结果(BEAM 测试报告)会上传回 RTC。下面的列出了一个常见的 BEAM 测试报告。
-- ERROR7 /*accessing beyond memory*/ >>>ERROR7_CommitVPD_3932edda1505 "c:\beam_commoncore_dev\BofmModulePkg\BOFMSupport\Capabilities.c", line 482: accessing beyond array bounds ONE POSSIBLE PATH LEADING TO THE ERROR: "c:\beam_commoncore_dev\BofmModulePkg\BOFMSupport\Capabilities.c", line 478: iterating some number of times "c:\beam_commoncore_dev\BofmModulePkg\BOFMSupport\Capabilities.c", line 478: assuming `i == 3' "c:\beam_commoncore_dev\BofmModulePkg\BOFMSupport\Capabilities.c", line 478: loop entry condition is true (used as evidence that error is possible) "c:\beam_commoncore_dev\BofmModulePkg\BOFMSupport\Capabilities.c", line 482: the index `i' is outside the bounds [0,1] of array `mCapabilitySizes'. The index has value = 3. VALUES AT THE END OF THE PATH: i = 3
BEAM 报告指出可能出现的静态代码错误,上图列出 Capabilities.c 中 可能出现的代码问题。并且会列出一条可能的逻辑链表示会造成这种问题的情况。
通过构建引擎,构建定义和 BEAM 脚本的结合,我们可以自动化运行监测代码中存在的错误,并及时通知给开发测试人员。这样就不用每个开发人员都自己安装 BEAM 测试环境,并且手动来测试自己的代码,从而大大节约了人力时间成本。
结束语
RTC 构建引擎是一个非常有用的工具,不仅仅可以和 BEAM 集成在一起实现自动化静态代码检测功能,其实也可以结合其他的编译工具,实现自动化编译,并且可以加入一些测试用例,实现自动化功能性测试。本文抛砖引玉,读者可以灵活应用构建引擎来实现自己需要的各类自动化功能。