loader image

Test Solutions for Simulink Models & Production Code

Products

Test Solutions for Simulink Models & Production Code

Blog

Cloud-friendly testing for of model-based software components with Docker

Thabo Krick

Oldenburg, Germany

Toolchains in model-based automotive development projects

No doubt, model-based development (MBD) projects offer a lot of benefits for automotive embedded software development, especially in the mechatronics-focused domains. However, compared to classic software development which mostly relies on a compiler, maybe a build tool plus some libraries for testing, checks, etc., MBD is guaranteed to come with a heavy Windows-based toolchain from the vast MATLAB Simulink ecosystem.

To complicate things even further, these toolchains are usually entirely different for each company:

Cloud-friendly testing for of model-based software components with Docker
Fig.01: Model-based Development Toolchain

Consequently, there is no standard toolchain package or standard CI pipeline, let alone an off-the-shelf Amazon EC2 or AzureVM template. But we still don’t want to be forced to install 10 different tools whenever we provide a CI runner or developer VM. We need a solution that is easy to use, easy to rollout to CI runners, and easy to maintain.

Using Virtual Machines to ensure a consistent environment

Virtual machines seem to be the perfect fit. They provide a nice, sandboxed environment and – when working in a managed solution like Amazon EC2 or AzureVM or applying tools like Chef, Puppet, Ansible or Terraform – you can prepare VM templates that can be rolled out at scale.

This provides a huge benefit, as VM templates can be prepared by a central team – even allowing manual adaptions – and then be rolled out both as developer VMs and as CI unners. Keeping both worlds identical is a great advantage, especially when developers need to debug failed CI runs.

However, the flexibility of VMs is also a big weakness: humans naturally seek the path of least resistance and if something can be solved by a manual tweak, we will utilize that. Consequently, it’s hard to know the cause when the VMs suddenly act up after a roll out. Has someone forgotten an essential manual step? Or was the VM corrupted after the rollout – permanently modified by an application running inside it?

Broken access rights, missing or modified environment variables, or a full disk due to missing clean up routines are just some of the many things that tend to go wrong when VMs are deployed at scale.

This can be mitigated partially by applying a strict configuration-as-code approach; however, this usually requires additional management solutions. I’ve worked in projects where the solution was a nightly reset of VMs, to ensure that their state doesn’t stray too far from the original state, but in my opinion, those nightly resets were causing more problems than they solved.

A system should either stay the way that I left it or be entirely ephemeral. But a mix of these concepts leads to situations where it’s sometimes working great, sometimes slightly off, and at other times completely broken.

And to make things worse, having VMs constantly active in the cloud is very costly, with an especially bad cost-benefit ratio at times where they are idling, as Windows tends to make sure that the CPU doesn’t get bored. On the other hand, treating VMs for CI runners as entirely ephemeral (start on demand and discard after use) solves most of those problems, but also comes at a high price:

  • Big delays due to slow startup times (usually over 1 minute)
  • High resource consumption on startup (unrelated to the actual workload)
  • Compute, Memory and storage footprint increased by OS

Solving the pain-points with Docker Containers

The pain-points described above are not entirely new. For these exact reasons, containers have emerged as a leading solution.

If you’ve never heard of a container, feel free to google for a textbook explanation or consider the following perspective:

You can think of a virtual machine as a house. An application can run inside a VM the same way you can live in a house. The house has its own foundation, driveway, plumbing, central heating and utilities. If you run applications at scale using virtual machines, you duplicate all of that.

Similarly, you can think of a container as an apartment. You can also live in it, but not every apartment needs its own foundation, driveway, plumbing, central heating and utilities. When running applications at scale in containers, you basically operate a big student residence. The cheap rent this concept offers is directly reflected on your cloud bill 🤓

This already mitigates the problem of costly resource consumption overheads. But containers can do so much more! They are built from a text file recipe (the Dockerfile), which is kept in source control (configuration-as-code). This is important: changing the container means changing the Dockerfile and that means a commit to your git repository. In other words: it’s very easy to track changes and roll back a working state in case something breaks.

From the Dockerfile an immutable container image is built and stored in a container registry from where it can be accessed when needed. It starts up in a second, as the container shares the host’s kernel instead of having its own full-fledged operating system. This enables pretty much native performance and a minimal resource overhead while providing a well-defined sandbox environment for apps running in the container.

The only disadvantage: container technology was designed for Linux-based operating systems. While it’s also available on Windows, the experience is much smoother on Linux: This makes it harder to achieve environmental parity between CI and developer VMs (which are mostly Windows-based in automotive). But if anything, I would argue that a Linux-based container running your code using GCC is closer to your hardware target than a Windows server equipped with a Visual Studio compiler.

The only real deal-breaker can be the fact that your company’s toolchain includes tools that only run on Windows. But there’s a good chance that this doesn’t affect you: given the rising demand, most tool vendors in the industry have added Linux support in the last five years.

Putting it all together in an example

Now that we’ve established the benefits, let’s try it out with an example! Let’s consider a toolchain for a model-based CI workflow with MIL+SIL tests using:
  • MATLAB R2023b
  • BTC EmbeddedPlatform 24.3p0
  • GitHub Actions for CI

Our example has the following file structure:´

Cloud-friendly testing for of model-based software components with Docker

Our model is already working (=it compiles and can generate c-code) and we can run our tests using the Python script from the scripts-directory. But the script requires  the necessary toolchain to be available. Our goal for this example is to be able to say “run my tests on model and code” without requiring any software to be installed (except for Docker).

This is where the Dockerfile comes in as our recipe to define the required toolchain.

General approach: creating a container image

We will base our image on the official mathworks/matlab image and customize it to meet our needs, including adding BTC EmbeddedPlatform from the public image btces/ep. Most importantly, we’ll expose the tool versions as build arguments, so that we can easily adapt them whenever we want to switch tool versions:

ARG EP_RELEASE=24.2p0

ARG MATLAB_RELEASE=R2023b

 

FROM btces/ep:${EP_RELEASE} AS ep

FROM mathworks/matlab:${MATLAB_RELEASE} AS matlab

MATLAB-related steps

To customize MATLAB to our needs, we first use mpm (=matlab package manager) to setup the required products/toolboxes:

# ———————————————————————————

# MATLAB-specific configurations

# ———————————————————————————

# Install required matlab products & set up license

ARG MATLAB_RELEASE

ARG MATLAB_PRODUCTS=“Embedded_Coder AUTOSAR_Blockset MATLAB_Coder Simulink Simulink_Coder Simulink_Coverage Stateflow”

USER root

RUN apt update && apt-get install -y wget

RUN wget -q https://www.mathworks.com/mpm/glnxa64/mpm && chmod +x mpm \

    && ./mpm install \

    –release=${MATLAB_RELEASE}  \

    –destination=/opt/matlab  \

    –products ${MATLAB_PRODUCTS} \

    && rm -f mpm /tmp/mathworks_root.log \

    && ln -f -s /opt/matlab/bin/matlab /usr/local/bin/matlab

# configure MATLAB license server

ENV MLM_LICENSE_FILE=27000@matlab.license.server

 

At the time of writing, the MATLAB images no longer shipped a compiler, so we’ll add gcc:

# mex-compiler: gcc 11

RUN export DEBIAN_FRONTEND=noninteractive && apt-get install -y gcc-11 && update-alternatives –install /usr/bin/gcc gcc /usr/bin/gcc-11 100 && update-alternatives –config gcc && apt-get install -y g++-11 && update-alternatives –install /usr/bin/g++ g++ /usr/bin/g++-11 100 && update-alternatives –config g++ && apt-get install -y cpp-11 && update-alternatives –install /usr/bin/cpp cpp /usr/bin/cpp-11 100 && update-alternatives –config cpp

MATLAB-related steps

Up next, we’ll add BTC EmbeddedPlatform from its public image and integrate it with MATLAB:

# ———————————————————————————

# BTC-specific configurations

# ———————————————————————————

# Copy files from public image btces/ep

COPY –chown=1000 –from=ep /opt /opt

COPY –chown=1000 –from=ep /root/.BTC /root/.BTC

# integrate BTC with MATLAB

RUN chmod +x /opt/ep/addMLIntegration.bash && /opt/ep/addMLIntegration.bash

# configure BTC license server

ENV LICENSE_LOCATION=27000@btc.license.server

 

# install python module btc_embedded

RUN pip3 install –no-cache-dir btc_embedded

ENV PYTHONUNBUFFERED=1

 

Finally, we restore the default user and ensure that we can pass a Python script as the entry point for this container by removing its default behavior (to start up MATLAB):

USER matlab

# Override default MATLAB entrypoint

ENTRYPOINT [ ]

CMD [ ]

Using the image

At the start of this section, we stated our goal:

[to be] able to say “run my tests on model and code” without requiring any software to be installed (except for Docker).

Based on the Dockerfile we defined, we can build our image with a simple Docker build (the image name “mbdtest” is arbitrary, you can pick any name you like):

 docker build -t mbdtest .

We’ve now reached our goal, being able to run our tests with a simple Docker run call. We’ll also make the current directory available as the workdir to have access to our model files, scripts, etc.:

docker run –volume “$(pwd):/workdir” –workdir “/workdir” mbdtest python3 scripts/run_tests.py

Et voilà!

Finishing touches

The only change we do before we integrate this in a CI pipeline is to control the MATLAB and BTC versions via environment variables. That makes it trivial to switch to a different version:

docker build -t mbdtest:${EP_RELEASE}_${MATLAB_RELEASE} \

    –build-arg EP_RELEASE=${EP_RELEASE} \

    –build-arg MATLAB_RELEASE=${MATLAB_RELEASE} \

    .

 

docker run –volume “$(pwd):/workdir” \

    –workdir “/workdir” \

    mbdtest:${EP_RELEASE}_${MATLAB_RELEASE} \

    python3 scripts/run_tests.py

Below’s a screenshot of a pull request which switches the MATLAB version from R2023b to R2024a – this the beauty of a nicely prepared Dockerized workflow:

Cloud-friendly testing for of model-based software components with Docker

Conclusion

We’ve seen that both virtual machines as well as containers are capable of supporting the complex toolchains common in automotive software development and thereby enable scalable CI workflows in the cloud.

Virtual machines are the go-to solution for many, as they feel more natural to anyone who’s familiar with managing servers. Powerful template mechanisms enable a rollout of well-defined environments at scale, albeit without the benefit of immutability.

As more and more resources are hosted in the cloud, the underlying costs – previously often hidden – become apparent and reveal one of the major weaknesses of virtual machines at scale: the overhead of a full-fledged operating system. Mitigated only by running multiple workflows in the same VM which counteracts the goal of keeping independent workflows properly isolated.

Containers outshine VMs in most regards. Managing containerized application is much simpler than managing VMs, the startup time and resource footprint is as tiny, container images are immutable by design and encourage valuable practices such as “configuration-as-code” to ensure reproducibility at all times.

Personally, the only factors that I see in favor of VMs are the environmental parity of CI agents with the developer VMs (=common VM template) and the limited availability of some tools in Linux-based environments.

Thabo Krick

Oldenburg, Germany

Lead Application Engineer

Thabo Krick studied Economic Computer Science at the University of Oldenburg and joined BTC Embedded Systems AG in 2013 as a student. With his team he set up the Jenkins-based software pipeline for BTC development and testing activities across all departments. After his Bachelor degree, he developed plugins and provided technical support for BTC EmbeddedPlatform customers world-wide. Since 2017 Thabo has provided trainings and consulted customers from the automotive domain regarding their testing process, ISO 26262 and automation. In 2018 he became a "Certified Jenkins Engineer" by successfully passing the exam at the Jenkins World Congress in Nice/France.

Connect on LinkedIn

Popular Videos

Play Video
Play Video

Request Evaluation License

If you would like to try out our tools, we will gladly provide an evaluation license free of chargeEvaluations include a free launch workshop and also provide an opportunity for you to meet one-on-one with our support and engineering teams.

Schedule a Meeting

Do you have any questions or want to see our tools in action? If so, please use the link below to schedule a meeting, where a member of our engineering team will be happy to show you the features and use cases and directly answer any questions you might have.

Join our newsletter

Your email address will be submitted to the privacy-certified newsletter software CleverReach for technical distribution. For further information go to our privacy policy.

Videos

Discover some of the main features of our products in these short videos.