主要内容

使用 Jenkins 进行 Polyspace 分析的示例脚本

在持续集成过程中,开发人员将代码提交到共享存储库。使用 Jenkins® 等工具的自动化编译系统会定期或基于预定义的触发器对每次提交的代码进行编译和测试,并对该代码进行集成。您可以在此过程中运行 Polyspace® 分析。

A flow diagram of a typical continuous integration workflow. Developers submit code to a shared repository. Polyspace Server products can run on the newly submitted code and upload the results to a Polyspace Access web server. Multiple reviewers can fetch the results from the server and review the results on a web browser.

本主题提供了 Shell 示例脚本,这些脚本使用 Polyspace Bug Finder™ Server™ 运行 Polyspace 分析并上传结果,以供在 Polyspace Access™ Web 界面中进行审查。这些脚本还会向潜在的评审发送电子邮件通知。收到通知的评审可以登录到 Polyspace Access Web 界面(如果他们有 Polyspace Access 许可证)并审查结果。

将示例脚本扩展到您的开发过程

这些脚本是为特定的开发工具链编写的,但可以轻松扩展到您的工程、团队或组织中使用的过程。这些脚本还可在 Jenkins Freestyle 工程中运行。如果您使用的是 Jenkins Pipeline,请参阅用于 Polyspace 分析的 Jenkins Pipeline 脚本示例

具体而言,这些脚本:

  • 仅在 Linux® 上运行。

    这些脚本使用了一些特定于 Linux 的命令,例如 export。但是,这些命令并非 Polyspace 工作流不可或缺的一部分。如果您要编写 Windows® 脚本(.bat 文件),请改用等效的 Windows 命令。

  • 仅在安装 Polyspace 插件后才能与 Jenkins 配合使用。

    这些脚本是针对 Jenkins 插件设计的,这体现在以下两个方面:

    • 这些脚本使用辅助函数 $ps_helper$ps_helper_access 来简化脚本编写。这些辅助函数会导出 Polyspace 结果以用作电子邮件附件,并使用命令行实用工具来过滤结果。

      这些辅助函数仅适用于 Jenkins 插件。但是,Polyspace Bug Finder Server 安装提供了基础命令。在 Jenkins 以外的编译自动化工具中,您可以使用 polyspace-report-generator 命令或 polyspace-access -export (Polyspace Access) 命令创建这些辅助函数。请参阅发送包含 Polyspace Code Prover Server 结果的电子邮件通知

      如果您在 Jenkins 中执行分布式编译,则在执行 Polyspace 分析的主节点和代理节点上,都必须将该插件安装在同一操作系统上的同一文件夹中。否则,您将无法使用辅助函数。

    • 这些脚本可为电子邮件附件创建文本文件,并为个性化电子邮件创建邮件主题和正文。如果您在 Jenkins 中安装了 Polyspace 插件,则可在您的 Jenkins 工程中使用电子邮件插件的扩展。使用该电子邮件插件,您可以轻松发送采用先前创建的主题、正文和附件的个性化电子邮件。如果没有 Polyspace 插件,则您必须寻找其他方法来发送电子邮件。

  • 运行 Bug Finder 分析。

    这些脚本对演示示例 Bug_Finder_Example 运行 Bug Finder。如果您安装了 Polyspace Bug Finder Server 产品,则包含该演示示例的文件夹为 polyspaceserverroot/polyspace/examples/cxx/Bug_Finder_Example。其中,polyspaceserverroot 是 Polyspace Server 产品的安装文件夹,例如 /usr/local/Polyspace Server/R2019a/

    您可以轻松改写该脚本来运行 Code Prover。只需将 polyspace-bug-finder-server 替换为 polyspace-code-prover-server 即可。您可以使用专用于 Code Prover 的演示示例 Code_Prover_Example

前提条件

要在服务器端运行 Polyspace 分析并在 Polyspace Access Web 界面中审查结果,您必须执行以下一次性设置。

  • 要运行该分析,您必须安装 Polyspace Server 产品的一个实例。

  • 要上传结果,您必须设置托管 Polyspace Access 的 Web 界面所需的组件。

  • 要审查上传的结果,您(和审查结果的每位开发人员)必须拥有一个 Polyspace 许可证。

该要求对于服务器端执行的 Polyspace Code Prover™ 分析同样适用。

请参阅安装 Polyspace Server 和 Access 产品

要安装 Polyspace 插件,请在 Jenkins 界面中从左侧选择管理 Jenkins。选择管理插件。搜索 Polyspace 插件,然后下载并安装该插件。

Jenkins 中设置 Polyspace 插件

以下步骤概述了如何在安装 Polyspace 插件后在 Jenkins 中设置 Polyspace 分析。请注意,这些步骤适用于 Jenkins 版本 2.150.1。用于您的 Jenkins 版本和 Polyspace 插件安装的步骤可能稍有不同。

如果您使用其他编译自动化工具,则可以执行类似的设置步骤。

指定 Polyspace 命令的路径和 Polyspace Access Web 界面的服务器详细信息

指定包含 Polyspace 命令的文件夹的完整路径,以及托管 Polyspace Access Web 界面的服务器的主机名和端口号。指定这些路径后,要上传结果,您不必在脚本中使用命令的完整路径或服务器详细信息。

  1. 在 Jenkins 界面中,从左侧选择管理 Jenkins。选择配置系统

  2. Polyspace 部分中,指定以下信息:

    • Polyspace 命令的路径。

      该路径会引用 polyspaceserverroot/polyspace/bin,其中,polyspaceserverroot 是 Polyspace Server 产品的安装文件夹,例如 /usr/local/Polyspace Server/R2019a/

      Enter the path to Polyspace commands and a short name for the path.

    • 托管 Polyspace Access Web 界面的服务器使用的主机名、端口号和协议(httphttps)。

      Enter the protocol, host and port name for the Polyspace Access server, and a short name to refer to the server.

    使用名称字段,您可以定义一个方便的简化形式以供稍后在 Jenkins 工程中使用。

  3. 电子邮件通知部分中,指定您公司的 SMTP 服务器(以及发送电子邮件所需的其他详细信息)。

    Enter email server details.

创建用于运行 PolyspaceJenkins 工程

创建 Jenkins 工程(例如 Freestyle 工程)时,您可以通过前面定义的全局简化形式来引用 Polyspace 路径。

要创建用于运行 Polyspace 的 Jenkins 工程,请执行以下操作:

  1. 在 Jenkins 界面中,从左侧选择新项目。选择 Freestyle Project

  2. 在工程的编译环境部分中,输入您前面定义的两个简化名称:

    • 包含 Polyspace 命令的文件夹的路径名称

    • 托管 Polyspace Access Web 界面的服务器的详细信息名称。

    此外,请输入可用于将结果上传到 Polyspace Access Web 界面的登录名和密码。该登录名和密码必须与一个 Polyspace Access 许可证相关联。

    Enter path to Polyspace commands and Polyspace Access server details using short names you created earlier. Enter credentials that can be used to log in to Polyspace Access.

  3. 在工程的编译部分中,您可以输入使用 Polyspace 命令和(托管 Polyspace Access Web 界面的)服务器详细信息的脚本。这些脚本运行 Polyspace 分析,并将结果上传到 Polyspace Access Web 界面。

    Script to run Polyspace analysis from Jenkins

  4. 在工程的后编译操作部分中,配置电子邮件地址和分析完成后要发送的附件。

    Enter email addresses of recipients, name of file with Polyspace results, mail subject and mail body.

用于运行 Bug Finder、上传结果和发送常用通知的脚本

此脚本运行 Bug Finder 分析,上传结果,并导出影响程度高的缺陷,以包含在发送给所有收件人的常用通知电子邮件中。

此脚本假定当前文件夹包含具有 .c 文件的 sources 文件夹。如果不符合此假定条件,请使用源文件的完整路径修改 gcc -c sources/*.c 行。

set -e
export RESULT=ResultBF
export PROG=Bug_Finder_Example
export PARENT_PROJECT=/public/BugFinderExample_PRS_01

# ================================================================
# Trace build command and create an options file

build_cmd="gcc -c sources/*.c"
polyspace-configure \
      -allow-overwrite \
      -allow-build-error \
      -prog $PROG \
      -author jenkins \
      -output-options-file $PROG.psopts \
      $build_cmd


# ================================================================
# Run Bug Finder on the options file

polyspace-bug-finder-server -options-file $PROG.psopts -results-dir $RESULT

# ================================================================
# Upload results to Polyspace Access web interface

$ps_helper_access -create-project $PARENT_PROJECT
$ps_helper_access \
      -upload $RESULT \
      -parent-project $PARENT_PROJECT \
      -project $PROG

# ================================================================
# Export results filtered for defects with "High" impact

$ps_helper_access \
      -export $PARENT_PROJECT/$PROG \
      -output Results_All.tsv \
      -defects High

# ================================================================
# Finalize Jenkins status

exit 0

在脚本运行后,您可以创建一个编译后操作,以向所有收件人发送一封包含导出的 Results_All.tsv 文件的电子邮件。

Enter email addresses of recipients, name of file with Polyspace results, mail subject and mail body.

在此脚本中,$ps_helper_accesspolyspace-access (Polyspace Access) 命令的简化形式,其中包含指定主机名、端口、登录名和加密密码的选项。其他 polyspace-access 选项是在脚本中显式编写的。

用于运行 Bug Finder、上传结果和发送个性化通知的脚本

此脚本会运行前面的 Bug Finder 分析并上传结果。但是,此脚本在以下方面与以前的脚本不同:

  • 此脚本使用了一个 run_command 函数,该函数在运行命令时会显示一条消息。该函数有助于根据控制台输出确定脚本的哪个部分正在运行。

  • 导出结果时,此脚本会为不同的所有者创建单独的结果文件。

    • 主文件 Results_All.tsv 包含所有结果。此文件将以电子邮件附件形式发送给经理。经理的电子邮件是在编译后的步骤中配置的。

      如果该文件包含的缺陷超过 10 个,则编译状态被视为失败。此脚本会在电子邮件通知中发送 UNSTABLE 状态。

    • userA 导出的结果文件 Results_Users_userA.tsv 包含来自“编程”组且影响程度高的缺陷。

      此结果文件将以电子邮件附件形式发送给 userA

    • userB 导出的结果文件 Results_Users_userB.tsv 包含来自 bug_memstdlib() 函数的缺陷。

      此结果文件将以电子邮件附件形式发送给 userB

  • 将在文件 mailsubject_manager.txt 中为经理创建单独的邮件主题,并分别在文件 mailsubject_user_userA.txtmailsubject_user_userB.txt 中为用户 userAuserB 创建单独的电子邮件主题。

    将在文件 mailbody_manager.txt 中为发送给经理的电子邮件创建邮件正文。

此脚本:

  • 假定当前文件夹包含具有 .c 文件的 sources 文件夹。

    如果不符合此假定条件,请使用源文件的完整路径修改 gcc -c sources/*.c 行。

  • 假定用户名为 userAuserB。需要特别指出的是,电子邮件地址 userA@companyname.comuserB@companyname.com(根据之前配置的用户名和 SMTP 服务器确定)必须是实际电子邮件地址。

    请将这些名称替换为实际用户名。

set -e
export RESULT=ResultBF
export PROG=Bug_Finder_Example
export REPORT=Results_List.tsv


# ================================================================
# Define function to print message while running command
run_command()
{
# $1 is a message
# $2 $3 ... is the command to dump and to run
message=$1
shift
cat >> mailbody_manager.txt << EOF
$(date): $message

EOF
"$@"
}

# ================================================================
# Initialize mail body
cat > mailbody_manager.txt << EOF
Dear Manager(s)

Here is the report of the Jenkins Job ${JOB_NAME} #${BUILD_NUMBER}
It contains all Red Defect found in Bug Finder Example project

EOF

# ================================================================
# Trace build command and create options file

build_cmd="gcc -c sources/*.c"
run_command "Tracing build command",               \
            polyspace-configure                   \
                -allow-overwrite                  \
                -allow-build-error                \
                -prog $PROG                       \
                -author jenkins                   \
                -output-options-file $PROG.psopts \
                    $build_cmd

# ================================================================
# Run Bug Finder on the options file

run_command "Running Bug finder" \
            polyspace-bug-finder-server -options-file $PROG.psopts -results-dir $RESULT



# ================================================================
# Upload results to Polyspace Access web interface

run_command "Creating Project $PARENT_PROJECT" \
  $ps_helper_access -create-project $PARENT_PROJECT

run_command "Uploading on $PARENT_PROJECT/$PROG" \
  $ps_helper_access \
        -upload $RESULT \
        -parent-project $PARENT_PROJECT \
        -project $PROG \
        -output upload.output
PROJECT_RUNID=$($ps_helper prs_print_runid upload.output)
PROJECT_URL=$($ps_helper prs_print_projecturl upload.output $POLYSPACE_ACCESS_URL)

# ================================================================
# Export report

run_command "Exporting report from $PARENT_PROJECT/$PROG" \
  $ps_helper_access \
        -export $PROJECT_RUNID \
        -output $REPORT \
        -defects High


# ================================================================
# Filter Reports

run_command "Filtering reports for defects" \
            $ps_helper report_filter \
                $REPORT \
                Results_All.tsv \
                Family Defect \


# ================================================================
# Filter Reports for userA and userB

run_command "Filtering Reports for userA: Group=='Programming' and Information=='Impact: High'" \
            $ps_helper report_filter \
                $REPORT \
                Results_Users.tsv \
                userA \
                Group Programming \
                Information "Impact: High"
run_command "Filtering Reports for userB: Function=='bug_memstdlib()'" \
            $ps_helper report_filter \
                $REPORT \
                Results_Users.tsv \
                userB \
                Function "bug_memstdlib()"


# ================================================================
# Update Jenkins status
# Jenkins build status is unstable when there are more than 10 Defects

BUILD_STATUS=$($ps_helper report_status Results_All.tsv 10)

# ================================================================
# Update mail body and mail subject

NB_FINDINGS_ALL=$($ps_helper report_count_findings Results_All.tsv)
NB_FINDINGS_USERA=$($ps_helper report_count_findings Results_Users_userA.tsv)
NB_FINDINGS_USERB=$($ps_helper report_count_findings Results_Users_userB.tsv)
cat >> mailbody_manager.txt << EOF

Number of defects: $NB_FINDINGS_ALL
Number of findings owned by userA: $NB_FINDINGS_USERA
Number of findings owned by userB: $NB_FINDINGS_USERB

All results are uploaded in: $PROJECT_URL

Build Status: $BUILD_STATUS

EOF

cat >> mailsubject_manager.txt << EOF
Jenkins for Manager - Polyspace run completed with status $BUILD_STATUS and $NB_FINDINGS_ALL findings
EOF

for user in userA userB
do
  echo "Jenkins for $user - $($ps_helper report_count_findings Results_Users_$user.tsv)) findings" > mailsubject_user_$user.txt
done



# ================================================================
# Exit with correct build status

[ "$BUILD_STATUS" != "SUCCESS" ] && exit 129
exit 0

在脚本运行后,您可以创建一个编译后操作,以向经理发送一封包含导出的 Results_All.tsv 文件的电子邮件。在收件人字段中指定电子邮件地址,在邮件主题字段中指定电子邮件主题,在邮件正文字段中指定电子邮件正文。

此外,还会向 userAuserB 发送单独的电子邮件,其附件分别包含文件 Results_Users_userA.tsvResults_Users_userB.tsv(并且邮件主题为 mailsubject_user_userA.txtmailsubject_user_userB.txt 的内容)。电子邮件地址是 userA@companyname.comuserB@companyname.com(根据之前配置的用户名和 SMTP 服务器确定)。

Enter email addresses of recipients, name of file with Polyspace results, mail subject and mail body.

此脚本使用辅助函数 $ps_helper 根据组、影响和函数来过滤结果。此辅助函数使用命令行实用工具从主文件中过滤结果,并执行为每个所有者创建单独的结果文件等操作。此函数将采用这些操作作为参量:

  • report_filter:根据文本文件的内容从导出的文本文件中过滤结果。

    例如:

    $ps_helper report_filter \
                    Results_List.tsv \
                    Results_Users.tsv \
                    userA \
                    Group Programming \
                    Information "Impact: High"
    读取文件 Results_List.tsv 并向文件 Results_Users_userA.tsv 中写入。文本文件 Results_List.tsv 包含 GroupInformation 的列。只有 Group 列包含 ProgrammingInformation 列包含 Impact: High 的那些行才会写入到文件 Results_Users_userA.tsv 中。

  • report_status:根据文件中的结果数返回 UNSTABLESUCCESS

    例如:

    BUILD_STATUS=$($ps_helper report_status Results_All.tsv 10))
    当文件 Results_All.tsv 包含的结果超过 10 个(10 行)时返回 UNSTABLE

  • report_count_findings:报告文件中的结果数。

    例如:

    NB_FINDINGS_ALL=$($ps_helper report_count_findings Results_All.tsv)
    返回文件 Results_All.tsv 中的结果数(行数)。

  • prs_print_projecturl:使用主机名和端口号创建 Polyspace Access Web 界面的 URL。

    例如:

    PROJECT_URL=$($ps_helper prs_print_projecturl Results_All.tsv $POLYSPACE_ACCESS_URL)
    
    读取文件 Results_All.tsv(由 polyspace-access 命令导出),并在 $POLYSPACE_ACCESS_URL 中提取 Polyspace Access Web 界面的 URL,在 $PROJECT_URL 中提取当前工程的 URL。

另请参阅

| | |

主题