Featured Webinar: MISRA C++ 2023: Everything You Need to Know | Watch Now
Deploying Static Analysis and Unit Testing in Containerized Environments, Part 2
You may have read in a previous post about how to apply SAST and unit testing in a containerized environment. Here's a continuation on how you can aptly deploy static analysis and unit testing using Parasoft C/C++test Standard in a Docker container.
Jump to Section
Importance of Containerization for Testing & Static Analysis
Containers are an evolutionary, standardized, and portable packaging technology that’s being deployed right into today’s modern Agile development workflows like DevOps/DevSecOps. Containers were first introduced for web applications and microservices development and deployment where they gained wide adoption in the IT industry. Today, the embedded industry uses containers extensively.
Containers offer a quick reproduction of identical environments for embedded development, software testing, staging, and production at any phase of the SDLC.
Deploying containers provides several benefits.
- Speeds up software development time to market.
- Improves code safety, security, and reliability.
- Helps manage the growing complexity of development ecosystems.
- Offers the ability to dynamically respond to software delivery trials in a fast and continuously evolving market.
Explanation of Docker & Container Images
It’s important to understand the container architecture. Let’s go through a quick description. A container is an application bundled with other components or dependencies like binaries or specific language runtime libraries and configuration files. Containers have their own processes, their own network interfaces, and mounts.
Containers are also isolated from each other and run on top of a container engine, such as Docker, for easy portability and flexibility. In addition, containers share an operating system and run on any of the following:
- Linux, Windows, and Mac operating systems
- Virtual machines or physical servers
- Developers’ machines or in data centers on-premises
- The public cloud
It’s also important to understand the role of the container engine because it provides crucial functionalities, including:
- Operating-system-level virtualization
- The container runtime, which manages the container’s life cycle (execution, supervision, image transfer, storage, and network attachments)
- Kernel namespaces used for isolating resources
A container image is a static file with executable code and includes everything a container needs to run. Therefore, a container is a running instance of a container image. C/C++test ships with an example container image, but to be more specific, it’s a Docker file.
How to Create a Container Image
Part 1 of this post discussed the benefits of using containers to deploy embedded development toolchains. It showed how to configure Parasoft C/C++test Professional to work with the compilation toolchain and test execution environment deployed in a container.
Now, let’s look at creating a container image with Parasoft C/C++test Standard. I’ll demonstrate a simple example with an in-container static analysis execution.
Deploy Parasoft C/C++test Standard in a Docker Container
As a command line based tool, Parasoft C/C++test Standard is suitable for in-container deployments. It can be packaged with the compiler and build system into one container image and used for CI/CD and deployed to developers’ desktops for the local command line scans. The image below shows the high-level overview of this setup:
The diagram shows Jenkins using containerized C/C++test to run static analysis. In this specific setup, Parasoft C/C++test, the compilation toolchain, and the build tools are deployed in the container shown in the top right corner of the diagram.
The container below it in the bottom right, provides the execution environment, which may be required to execute runtime tests, like unit tests or automated system level tests.
If we intend to implement only static analysis, our setup will most likely include only one type of container with the compilation toolchain and Parasoft C/C++test.
Create a Container Image With Parasoft C/C++test
If you haven’t done already so, please install the latest release of the Parasoft C/C++test for Linux.
To simplify the process of creating a container image with C/C++test, the latest release ships with an example of the Dockerfile. You can find this Dockerfile in the following location:
<C/C++test standard installation>/integration/docker/Dockerfile
This simple Dockerfile focuses only on the required C/C++test steps to build the image. In most real world cases, you’ll need to merge this file with your Dockerfile.
Before we analyze the content in the example Dockerfile, let’s see how it works. My example assumes the following simple file structure:
1. Unzip the C/C++test distribution.
- cd $HOME/sandbox
- tar xzf parasoft_cpptest_standard-2020.1.0-linux.x86_64.tar.gz
2. Copy out the example Dockerfile from the distribution
- cp cpptest/integration/docker
3. Prepare a property file for the C/C++test with the information about the license. We’ll use the default cpptestcli.properties file as a base, so we’ll copy it to our working directory:
- cp cpptest/cpptestcli.properties
Edit it to insert the information about your license server location. Use your favorite editor to configure the licensing information. Save the file when you’re done.
4. Edit the Dockerfile and uncomment line number 13 (the one where the cpptestcli.properties file is copied from the local directory to the location in the containers). The line in the Dockerfile should look like this:
- COPY cpptestcli.properties /opt/parasoft/cpptest
5. Now, we’re ready to create the Docker image. Run the command to build the first image with C/C++test. The image name is “cpptest_ci_image”.
- docker build -t cpptest_ci_image
Docker will take some time to analyze its cache and download the required base image. Once this is done the C/C++test distribution is copied and installed into the image. After a minute or two, the image should be ready. Confirm it by executing the command to list the all the images:
- docker image -list
In the output, you should see the “cpptest_ci_image” listed at the top. Great, so we have an image built and ready. Now it is the time to test it!
Test the Container Image
For a simple test, use one of the helper/exemplary command lines provided inside the Dockerfile.
Use your favorite editor to open the Dockerfile, and scroll down to the bottom of the files. You should see couple of example command lines like this:
Let’s use the command line from line 26 to execute an in-container static analysis on one of the C/C++test examples shipped with the distribution.
Since we decided to build in the cpptestcli.properties file with the licensing information into the container, we can simplify the command line and remove the -settings option. The command line for the test should look like this:
- docker run –rm -v $PWD:$PWD -w /opt/parasoft/cpptest/examples/ATM cpptestcli -compiler gcc_9-64 -module . -trace make clean all
Voila! Static analysis was executed in-container. The results were reported on the console.
We could further configure the tool to produce the HTML report on the local file system, but that’s another story. Our primary goal was to create the container with C/C++test inside and configure it to execute static analysis. We achieved the goal.
Set Up a CI Server With Static Analysis
If you need to set up a CI server with static analysis as part of the process, your task is much simpler. Just access the container. The same is true if developers on your team want to run static analysis.
Need to upgrade Parasoft C/C++test to the latest release? Just download the distribution, rebuild your container image, and you’re done! The team and the automated infrastructure won’t even notice this operation. Smooth, easy, and reversible, if necessary.
About the Dockerfile Content
Before we finish, let’s look at the content of the Dockerfile shipped with Parasoft C/C++test that was just used to create our image. The image below shows the content of <install dir>/integration/docker/Dockerfile.
Here are the details:
- Line 2 specifies the Docker hub of the GCC image, which the container image is based on.
- Line 4 sets up the working directory for subsequent commands that will be executed in this script.
- Line 7, we are copying the C/C++test distribution (archive) to the container image.
- Line 10 extracts the distribution into the in-container location: /opt/parasoft (note the WORKDIR command from the line 4)
- Line 13 copies the customized cpptestcli.properties file from the local directory into the in-container installation of C/C++test. This step is optional and by default, it is commented out. In most of the cases, you’ll want to have some properties embedded into the installation of C/C++test. The most typical scenario is the license configuration, which will include the location of the license server, credentials, and so on.
- Line 16 removes the distribution archive. This is just a clean-up.
- Line 18 resets the workdir to /home (optional)
- Line 19 specifies the executable to run when the container starts.
This is all that’s needed to create a simple container with Parasoft C/C++test that is ready to execute static analysis.
As I mentioned, this is a simple Dockerfile. It was added to the product distribution to give you an example of what you may need to create a container image for your environment. You will need to adapt it to your needs or merge it with existing Dockerfiles.