技术文章和通讯

基于GitLab的Simulink模型的持续集成验证

作者:Jemima普利帕蒂,Anand Vaidyanathan Sarma, David Boissy, MathWorks


本文是由两部分组成的系列文章中的第二篇。第1部分,Simulink模型的持续集成验证,着眼于利用GitLab®版本控制和Jenkins持续集成(CI)。本文使用GitLab进行版本控制和CI。

本例中使用的项目可在GitHub®而且文件交换下载。

持续集成工作流

持续集成(Continuous Integration, CI)是一种敏捷方法的最佳实践,开发人员定期提交并合并他们的源代码更改到一个中央存储库中。这些“变更集”随后被自动构建、限定并发布。图1演示了这个基本的CI工作流和开发工作流。

图1。CI工作流。

图1。CI工作流。

案例研究:在GitLab中验证、构建和测试一个Simulink模型

在这个例子中,我们使用基于模型的设计和CI在巡航控制系统上执行基于需求的测试(图2)。

图2。巡航控制系统。

图2。巡航控制系统。

CI管道

CI管道在技术文章中有解释,Simulink模型的持续集成验证.我们将应用这些相同的概念来定义GitLab中的管道。每次更改被推送到GitLab存储库时,我们的CI管道就会被执行。管道如图3所示。

图3。巡航控制系统管路

图3。巡航控制系统管路。

这个示例管道中的阶段如下:

  1. 验证建模指南:MATLAB®脚本,该脚本使用ISO26262检查在模型上运行Model Advisor并生成HTML报告。
  2. 生成代码:用MATLAB脚本构建模型并生成相应的构建报告。
  3. 执行测试用例:在指定的模型上运行单元测试,并生成相应的报告。
  4. 包工件:这里生成一个包含与前一个阶段相关信息的汇总报告。
  5. 部署:来自前一个阶段的所有工件被下载到管道中指定的工件路径。

工作流步骤

工作流程包括以下步骤(图4):

  1. 触发在GitLab中创建一个管道,观察验证和构建阶段通过。
  2. 检测GitLab CI管道中的一个测试用例失败,并创建一个问题来跟踪和讨论错误修复。
  3. 繁殖该问题在我们的桌面MATLAB。
  4. 修复这个问题在模型中。
  5. 在本地测试以确保测试用例通过。
  6. 审查测试分支上的更改。
  7. 提交更改到Git,并在GitLab中触发CI管道。
  8. 验证、构建和测试在GitLab。
  9. 创建一个合并请求将测试分支的更改合并到主分支中,并关闭相应的Issue。
图4。工作流示例。

图4。工作流示例。

我们通过CI循环的第一次失败的传递如图左上角所示。它显示了CI测试失败、本地复制、标准放松以及CI工作流的成功完成。

工作流细节

1.我们首先触发通过将MATLAB中的变化推送到GitLab中来实现GitLab中的管道。模型标准检查和代码生成通过。

管道的状态可以在项目的主页上看到。通过单击该图标,可以看到管道中作业的状态。红色符号表示管道失效。

这是显示触发提交失败的父子管道。相应的子管道可以在第二列的“Downstream”下展开。

2.接下来,我们检测“TargetSpeedThrottle”管道内部的故障。子管道“TargetSpeedThrottle”失败。这个失败的管道可以通过单击查看。

由于测试阶段失败,所以不会执行其他阶段。可以通过单击失败的作业查看控制台输出。

在观察输出时,我们可以说“opMode Increment”单元测试用例失败了。一个新问题可以通过点击右侧的“New Issue”按钮来创建。可以使用此表单输入描述和其他字段,这将为存储库创建一个新问题。

创建的问题如下所示,#1是相应的问题编号。

article-gitlabci-verification-simulink-workflow-details2d-issue-number

3.为了更好地理解失败,我们繁殖使用Simulink Test™本地测试故障。打开测试文件“TargetSpeedThrottleTestManager.”mldatax”位于“设计/TargetSpeedThrottle/管道/测试/收集”文件夹中,并运行测试用例“opMode Increment”。在测试套件中,我们可以看到“Verify Statements”对于“opMode Increment”单元测试失败了,如图所示。

4.来修复打开“Design/TargetSpeedThrottle/specification/TargetSpeedThrottle.”slx”模型,并导航到测试工具“TargetSpeedThrottle_Harness”中的测试评估块,如图所示。

评估断言“throtCC”和“exp_throtCC”之间的差异小于0.1%,如所示。

这种评估过于严格,无法检查差异是否小于0.1%。必须将此值更改为0.005以修复测试。

5.在我们的模拟中,这个问题似乎是固定的。确认,我们在本地测试,保存模型并在测试管理器中重新运行测试。注意,它通过了新的评估标准。

6.我们已经解决了这个问题,并在当地进行了验证。我们现在使用模型比较工具来审查在将更改提交给版本控制之前。

我们还可以使用模型比较工具的发布特性来检查代码。

7.bug修复后,我们提交这些更改并推送到带有MATLAB项目的GitLab上的远程存储库,添加一个提交消息来注意评估标准的更改。

可以使用特定的短语来编写提交消息自动关闭的问题.在这里,提交消息“Fixes #1”将自动关闭在管道失败时(最近的CI管道通过时)创建的问题。

然后我们注意到GitLab存储库中的最新提交。

8.GitLab CI管道运行。我们看到验证、构建和测试现在通过管道阶段。

9.我们现在可以启动一个合并请求,将测试分支中的更改合并到主分支中。在GitLab中,在Repository下,我们可以选择branch,然后单击合并请求在测试分支上的最新提交旁边,或者使用出现在存储库页面顶部的“创建合并请求”按钮。

我们完成表单并提交合并请求。

作为分支的所有者,我们可以通过单击merge按钮来接受合并请求。根据我们的CI设置,我们还可以在CI管道通过后启用自动合并。所有更改现在都在主分支上捕获,管道自动开始在主分支上运行。

在管道执行之后,相应的问题将自动关闭。

在管道中执行了验证、构建和测试阶段之后,将为每个模型在包阶段生成一个摘要报告。

举例说明:工具、资源和需求

本例中使用的项目可用于下载。下面的部分概述了帮助您入门的资源,以及您将需要的工具以及应该如何配置它们。下面的部分概述了帮助您入门的资源,以及您将需要的工具以及应该如何配置它们。

配置系统

采用GitLab作为版本控制系统和CI系统。MATLAB和GitLab必须一起配置。下面的教程将帮助您进行设置。

所需的工具

  • GitLab帐户。GitLab用于源代码控制,而CI和作为云服务可用。MATLAB项目包括一个用于与GitLab通信的Git接口。

CI的许可考虑

如果您计划在多个主机或云上执行CI,请联系MathWorks (continuous-integration@mathworks.com)寻求帮助。注意:诸如MathWorks编码器和编译器产品2022世界杯八强谁会赢?之类的转换产品可能需要客户端访问许可证(CAL)。

附录1:配置MATLAB项目和GitLab

步骤1。配置MATLAB项目使用源代码控制

在我们的示例中,第一步是配置我们的项目以使用GitLab的源代码控制。

  1. 创建一个名为MBDExampleWithGitLab的新目录,将示例加载到其中,并打开MATLAB项目MBDExampleWithGitLab.prj。
  2. 在GitLab中,创建一个新项目这将是远程存储库。它的名字。MBDExampleWithGitLab并记录它所在的URL。
  3. 在MATLAB中,转换项目使用源代码控制。在Project选项卡上,单击使用源代码控制

点击将项目添加到源代码控制中

4.点击转换

5.点击开放项目当完成。

该项目现在处于本地Git源代码控制之下。

步骤2。设置GitLab Runner

GitLab Runner是一个与GitLab CI/CD一起在管道中运行作业的应用程序。一定是一个GitLab Runner安装注册;而且开始执行管道。

要安装、注册和启动对应于您的操作系统的GitLab Runner,请参考上面提到的步骤在这里(“config. properties”中的可选并发值。Toml”在这个例子中可以写成8)。在继续注册上述链接中的跑者之前,请参阅以下要点。

a. GitLab存储库可以为单个项目使用特定运行器。要为项目创建和注册特定运行程序,请遵循步骤在要求中提到,并与所使用的操作系统相对应。在注册过程中输入的标记将帮助识别要将哪个运行程序分配到GitLab中的哪个存储库。在本例中,标记应该被指定为“testci”,因为.yml文件(在当前示例中用于管道定义)的标记为“testci”。在注册过程中提到执行程序时,可以使用“shell”。这意味着管道将在执行期间使用shell环境。

b.成功注册跑步者后,将显示如下信息:

ci-simulink-using-gitlab-appendix1-step2-runner-registered

步骤3。GitLab个人访问令牌

创建一个个人访问令牌为GitLab存储库。重要的是要记录生成的个人访问令牌,因为它只能查看一次。创建一个CI / CD管道变量对于这个个人访问令牌(“Key”指变量名,“Value”是实际的令牌)。在Key字段中输入的这个变量名将用作管道定义中使用的Job Artifacts API的参数,因此请记下它。(要运行此示例,请将Key提到为CIPROJECTTOKEN。)

步骤4。配置管道

1.项目文件夹中的。yml文件描述了CI管道的不同阶段。的.gitlab-ci.ymlFile是指当代码被推入存储库时触发的主线程。的文件.driverSwRequest-gitlab-ci.yml.cruiseControlMode-gitlab-ci.yml.targetSpeedThrottle-gitlab-ci.yml,.crs_controller-gitlab-ci.yml引用模型的子管道,只有在特定的模型被更改或gitlab-ci时才会被触发。yml是改变。打开.yml文件并将标记字段更改为“testci”—类似于步骤2的GitLab Runner设置。一个例子如下:

2.修改工件路径

中的ARTIFACTS_DOWNLOAD_PATH变量进行验证和修改.gitlab-ci.yml.使用Jobs artifacts API在子管道的部署阶段下载这些构件。此变量值用于放置下载的工件路径。

appendix1-step4b-artifacts-download-path

3.为作业工件API指定个人访问令牌

每个子管道.yml文件(.driverSwRequest-gitlab-ci.yml.cruiseControlMode-gitlab-ci.yml.targetSpeedThrottle-gitlab-ci.yml而且.crs_controller-gitlab-ci.yml)中定义了一个部署阶段,该阶段使用Job Artifacts API下载整个子管道的工件。这个例子在API请求中使用了" PRIVATE-TOKEN: $CIPROJECTTOKEN "。中使用的Key字段名替换CIPROJECTTOKEN步骤3配置GitLab。

第5步。提交更改并将本地存储库推到GitLab

1.在Project选项卡上,单击远程

2.在GitLab中指定远程源的URL。这是承载GitLab存储库的URL。

点击验证要确保成功连接到远程存储库,请单击好吧.该项目现在配置为使用GitLab推送和拉取更改。

3.点击提交执行初始提交。

appendix1-step2-part3b-enter-comment

4.点击将所有更改从本地存储库推送到远程GitLab存储库。

5.刷新GitLab仪表板并观察MATLAB项目的内容。

由于GitLab Runner是在前面的步骤中设置的,所以一旦更改被推入存储库,管道就开始运行。的.gitlab-ci.ymlFile负责启动管道。

步骤6:创建测试分支

在此步骤中,我们创建一个测试分支,用于在与主分支合并之前测试和验证更改。

1.点击分支机构

扩大分支和标签的创建部分,将分支命名为“Test”,然后单击创建

2.现在观察分支浏览器中的Test。从Test分支单击开关然后关闭

3.将更改推到Test分支。在MATLAB中,选择将这些更改推送到GitLab,并观察GitLab中的Test分支。

附录2:管道和工件的解释

1.父子管道

此示例使用父子管道结构。

a.有一个由子管道组成的父管道(如上图第一列所示)。有4个触发器(显示为阶段“Downstream”下的4个作业)来指示4个子管道。每个子管道用于系统的每个模型,也可以通过在Downstream中展开它们来查看其进度。

上面显示的子管道显示了系统中“CruiseControlMode”模型的各个阶段。

2.子管道的阶段

  • 验证:使用Simulink Check™对ISO26262建模标准进行了验证。
  • 构建:在模型上执行代码生成。
  • 测试:这会执行为模型编写的单元测试。
  • 包:显示生成的工件和管道已经成功的最后阶段。
  • 部署:包含代码的任何部署的占位符阶段。管道的所有构件都是使用Job artifacts API下载的。

3.YAML的关键词

这个管道结构和作业定义必须在.yml文件中创建,这些文件由Runner用来执行管道。一个.gitlab-ci.yml保存任何项目的CI/CD管道的阶段和任务的配置细节。下面的步骤解释了用于构造前面步骤中描述的父子管道的.yml文件(本文中使用的示例拥有执行管道所需的所有.yml文件,但是下面的步骤简要描述了.yml文件的内容)。

a.最初父管道的各个阶段在.gitlab-ci.yml.进一步描述每个阶段的工作。

appendix2-part3a-gitlaciyml-stages

b.关键字“trigger”对应子管道。因为有4个模型,所以必须编写4个不同的作业。这里有一个例子。

每个作业都以惟一的作业名称开始,后跟它所属的阶段。因为它调用了另一个子管道,所以子管道的.yml文件是使用关键字“include”提到的。“strategy”关键字意味着在这个作业完成之前不会执行下一个作业。"rule"关键字表明,只有当用户对22-25行中提到的文件夹路径进行更改时,才必须触发子管道。

c.每4个子管道都有对应的.yml文件。它们还包括子管道的每个阶段下的阶段和作业的声明。下面是子管道中的一个作业的示例。

“标签”是指跑者注册时给予的标签。任何要执行的文件/命令都在“脚本”下提到。“工件”是在传递到下一个作业之前需要保存的文件。通常,在作业执行期间生成的任何文件,以及稍后在验证结果时对用户有帮助的文件,都被存储为工件。在这里,在模型的analyze文件夹中生成的报告/结果和日志被保存为工件。父管道的其他作业也可以在gitlab-ci.yml文件。

a.在Deploy阶段使用工作构件API.这里CIPROJECTTOKEN指的是之前为个人访问令牌创建的CI/CD变量。中的变量ARTIFACTS_DOWNLOAD_PATH被定义为.gitlab-ci.yml.请注意,甚至可以从后面步骤中提到的单个作业页面浏览/下载工件。

4.工件

a.可以从存储库页面查看管道。

绿色符号表示管道已经运行并且成功。

b.在单击该符号时,我们可以看到该管道中成功的作业。

每个作业的进度都可以通过点击查看。网址: 

这是打印任何输出语句的控制台。此外,可以从右侧的部分查看作业的工件,在那里可以浏览或下载工件。子管道中的每个阶段都会生成工件,直到Deploy阶段。

c.还可以在每个子管道作业中的“测试”选项卡下查看每个子管道的测试结果。

d.摘要报告执行作业时生成的任何报告/结果文件都存储在每个模型下的analyze文件夹中。除此之外,在每个子管道的末尾(在Package阶段中)还会创建一个汇总报告,其中包含子管道前几个阶段的所有结果。

下面是一个“DriverSwRequest”模型的摘要报告示例:

该报告出现在每个模型的“/analyze/package”文件夹中,模型名称后面跟着“SummaryReport”。用户可以从每个子管道的Package阶段下载这些报告作为工件。

如果子管道的任何阶段(Package之前)失败,则不能生成汇总报告,因为这只发生在Package阶段。一旦一个阶段失败,控制就不能进入下一个阶段。

5.每个阶段中的子管道作业工件

巡航控制项目在各个阶段生成以下工件:

  1. 验证:模型顾问结果报告
  2. 构建:一个构建报告,Codegen文件夹
  3. 测试:测试报告
  4. 包:analyze文件夹中的所有报告
  5. 部署:前面阶段的所有工件

6.如何检查管道是否正确执行

  1. 在工件中生成的总结报告是验证所有阶段结果统计的一个很好的起点。
  2. 管道中的所有作业都必须通过。如果MATLAB抛出 错误,那么由于MATLAB抛出的退出状态代码,管道作业将失败。

7.对于运行GitLab管道时出现的错误消息“error setting certificate verify locations”的任何问题,请参考以下内容:

2022年出版的

查看相关行业文章

Baidu
map