Fix Metric Threshold Violations in a Continuous Integration Systems Workflow

This example shows how to use the Metrics Dashboard with open-source tools GitLab™ and Jenkins™ to test and refine your model in a continuous integration systems workflow. Continuous integration is the practice of merging all developer working copies of project files to a shared mainline. This workflow saves time and improves quality by maintaining version control and automating and standardizing testing.

This example refers to a project that contains the shipped project matlab:sldemo_slproject_airframe and these additional files which are relevant to this example:

  • A MATLAB script that specifies metric thresholds and customizes the Metrics Dashboard.

  • A MATLAB unit test that collects metric data and checks whether there are metric threshold violations.

The example uses the Jenkins continuous integration server to run the MATLAB unit test to determine if there are metric threshold violations. Jenkins archives test results for you to download and investigate locally. GitLab is an online Git repository manager that you can configure to work with Jenkins. This diagram shows how Simulink Check, GitLab, and Jenkins work together in a continuous integration workflow.

Project Setup

The project contains all model, data, and configuration files including these files which are required for this example:

  • A MATLAB unit test that collects metric data for the project and checks that the model files contain no metric threshold violations. For more information on the MATLAB Unit tests, see Script-Based Unit Tests (MATLAB).

  • A setup.m file that activates the configuration XML files that define metric thresholds, set custom metric families, and customizes the Metrics Dashboard layout. For this example, this code is the setup.m script:

    function setup
        % refresh Model Advisor customizations
        Advisor.Manager.refresh_customizations();
            
        % set metric configuration with thresholds
        configFile = fullfile(pwd, 'config', 'MyConfiguration.xml');
        slmetric.config.setActiveConfiguration(configFile);
        
        uiconf = fullfile(pwd, 'config', 'MyDashboardConfiguration.xml');
        slmetric.dashboard.setActiveConfiguration(uiconf);
    end
    
    On the Project tab, click Startup Shudown. For the Startup files field, specify the setup.m file.

    For more information on how to customize the Metrics Dashboard, see Customize Metrics Dashboard Layout and Functionality.

  • An sl_customization.m file that activates the Model Advisor configuration file to customize the Model Advisor checks. For more information, see Create and Add Custom Checks - Basic Examples

  • A run script that executes during a Jenkins build. For this example, this code is in the run.m file:

    % script executed during Jenkins build
    function run(IN_CI)
         if (IN_CI)
            jenkins_workspace = getenv('WORKSPACE');
            cd(jenkins_workspace);
        end
    
        % open the sl project
        slproj = simulinkproject(pwd);
        
        % execute tests
        runUnitTest();
        
        slproj.close();
        
        if IN_CI
            exit
        end
    end
    

  • A cleanup.m file that resets the active metric configuration to the default configuration. For this example, this code is in the cleanup.m file script:

    function cleanup    
        rmpath(fullfile(pwd, 'data'));
        Advisor.Manager.refresh_customizations();
    
        % reset active metric configuration to default
        slmetric.config.setActiveConfiguration('');
        slmetric.dashboard.setActiveConfiguration('');
    end
    
    On the Project tab, click Startup Shudown. For the Shutdown files field, specify the cleanup.m file.

  • A .gitignore file that verifies that derived artifacts are not checked into GitLab. This code is in the .gitignore file:

    work/**
    reports/**
    *.asv
    *.autosave
    

GitLab Setup

Create a GitLab project for source-controlling your Project. For more information, see https://docs.gitlab.com/ee/README.html.

  1. Install the Git Client.

  2. Set up a branching workflow. With GitLab, from the main branch, create a temporary branch for implementing changes to the model files. Integration engineers can use Jenkins test results to decide whether to merge a temporary branch into the master branch. For more information, see

    https://git-scm.com/book/en/v1/Git-Branching-Branching-Workflows.

  3. Under Settings > Repository, protect the master branch by enforcing the use of merge requests when developers want to merge their changes into the master branch.

  4. Under Settings, on the Integrations page, add a webhook to the URL of your Jenkins project. This webhook triggers a build job on the Jenkins server.

Jenkins Setup

Install GitLab and Tap plugins. The MATLAB unit test uses the TAPPlugin to stream results to a .tap file. To enable communication of test status from MATLAB to the Jenkins job, Jenkins imports the .tap file.

Create a Jenkins project. Specify these configurations:

  1. In your Jenkins project, click Configure.

  2. On the General tab, specify a project name.

  3. On the Source Code Management tab, for the Repository URL field, specify the URL of your GitLab repository.

  4. On the Build Triggers tab, select Build when a change is pushed to GitLab.

  5. On the Build tab, execute MATLAB to call the run script. The run script opens the project and runs all unit tests. For the project in this example, the code is:

    matlab -nodisplay -r...
     "cd /var/lib/jenkins/workspace/'18b Metrics CI Demo'; run(true)"

  6. In the Post-build Actions tab, configure the TAP plugin to publish TAP results to Jenkins. In the Test Results field, specify reports/*.tap. For Files to archive, specify reports/**,work/**.

    The TAP plugin shows details from the MATLAB Unit test in the extended results of the job. The Jenkins archiving infrastructure saves derived artifacts that are generated during a Jenkins build.

Continuous Integration Workflow

After setting up your project, Jenkins, and GitLab, follow the continuous integration workflow.

Phase 1: Feature Development

  1. Create a local clone of the GitLab repository. See Clone from Git Repository (MATLAB).

  2. In Simulink, navigate to the local GitLab repository.

  3. Create a feature branch and fetch and check-out files. See Branch and Merge Files with Git (Simulink) and Pull, Push, and Fetch Files with Git (Simulink).

  4. Make any necessary changes to the project files.

  5. Simulate the model and validate the output in the Simulation Data Inspector.

  6. Run MATLAB unit tests. For more information, see runtests.

  7. Add and commit the modified models to the feature branch. See Branch and Merge Files with Git (Simulink) and Pull, Push, and Fetch Files with Git (Simulink).

  8. Push changes to the GitLab repository. See Branch and Merge Files with Git (Simulink) and Pull, Push, and Fetch Files with Git (Simulink).

  9. In GitLab, create a merge request. Select the feature branch as source branch and the target branch as master. Click Compare Branches and Continue.

  10. If the feature is not fully implemented, mark the merge request as a work in progress by adding the letters WIP: at the beginning of the request. If the merge request is not marked WIP:, it immediately triggers a build after creation.

  11. Click Submit Merge Request.

Phase 2: Qualification by Using Continuous Integration

  1. If the letters WIP: are not at the beginning of the merge request, the push command triggers a Jenkins build. In the Jenkins Setup part of this example, you configured Jenkins to perform a build when you pushed changes to GitLab. To remove the letters, click Resolve WIP status.

  2. Navigate to the Jenkins project. In Build History, you can see the build status.

  3. Click the Build.

  4. Click Tap Test Results.

  5. For this example, the MetricThresholdGateway.m unit test did not pass for three metrics because these metrics did not meet the thresholds. To investigate this data, you must download the data locally.

Phase 3: Investigate Quality Issues Locally

  1. Download the archived results to a local Git repository workspace.

  2. Unzip the downloaded files. Copy the reports/ and work/ folders to the respective folders in the local repository.

  3. To explore the results, open the project and the Metrics Dashboard.

  4. To resolve the test failures, make the necessary updates to the models. Push the changes to the feature branch in GitLab.

  5. Integration engineers can use Jenkins test results to decide when it is acceptable to perform the merge of the temporary branch into the master branch.

See Also

|

Related Topics