Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CI: Run sanitizers in docker #580

Merged
merged 42 commits into from
Jan 30, 2025
Merged
Show file tree
Hide file tree
Changes from 39 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
5b8e6bc
Add Dockerfile to build and run sanitizers in docker
alexander-e1off Jan 20, 2025
1f0c39a
Run sanitizers in docker on CI
alexander-e1off Jan 21, 2025
2064cc3
Fix yaml formatting
alexander-e1off Jan 21, 2025
ac3c7ee
Fix yaml formatting
alexander-e1off Jan 21, 2025
9d15f48
Remove debug
alexander-e1off Jan 21, 2025
96a25c3
Try to remove unneeded stuff to save space
alexander-e1off Jan 21, 2025
76e1c44
Fix removed dirs
alexander-e1off Jan 21, 2025
48876bb
Save more space by removing unneeded pkgs
alexander-e1off Jan 22, 2025
86d0fdc
Remove sudo
alexander-e1off Jan 22, 2025
4b9f84f
debug
alexander-e1off Jan 22, 2025
65e8109
debug1
alexander-e1off Jan 22, 2025
d069c30
debug2
alexander-e1off Jan 22, 2025
3f7d05a
debug2
alexander-e1off Jan 22, 2025
d7693b3
debug3
alexander-e1off Jan 22, 2025
191b804
debug4
alexander-e1off Jan 22, 2025
901ae70
debug5
alexander-e1off Jan 22, 2025
43e2850
debug6
alexander-e1off Jan 22, 2025
adc1aef
debug6
alexander-e1off Jan 22, 2025
6b193a3
debug7
alexander-e1off Jan 22, 2025
86f8e21
debug8
alexander-e1off Jan 22, 2025
9a26172
debug9
alexander-e1off Jan 22, 2025
4c5f356
debug10
alexander-e1off Jan 22, 2025
a1e9a19
debug11
alexander-e1off Jan 22, 2025
978613c
debug12
alexander-e1off Jan 22, 2025
2691a37
debug13
alexander-e1off Jan 22, 2025
150d2ae
debug14
alexander-e1off Jan 22, 2025
3ed216d
debug15
alexander-e1off Jan 22, 2025
c0be965
debug16
alexander-e1off Jan 22, 2025
60ae789
Remove debug
alexander-e1off Jan 22, 2025
55ab64a
Fix deps
alexander-e1off Jan 22, 2025
339407f
Remove run layer
alexander-e1off Jan 22, 2025
6d1c32d
Add checking of input arg
alexander-e1off Jan 23, 2025
95eb4a0
Merge main, fix merge conflicts
alexander-e1off Jan 23, 2025
578a12b
Remove sanitizers folder from workflows
alexander-e1off Jan 23, 2025
5c26572
Fix deps
alexander-e1off Jan 23, 2025
dcefe43
Cleanup, update readme.md
alexander-e1off Jan 23, 2025
f45a233
Fix comment
alexander-e1off Jan 23, 2025
891bf9e
Merge remote-tracking branch 'upstream/main' into sanitizers-in-docker
alexander-e1off Jan 24, 2025
c5b582e
Merge remote-tracking branch 'upstream/main' into sanitizers-in-docker
alexander-e1off Jan 29, 2025
fad5dc1
Fix review comments
alexander-e1off Jan 29, 2025
7906927
Fix typo
alexander-e1off Jan 29, 2025
fafea37
Remove debug
alexander-e1off Jan 29, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 17 additions & 13 deletions .github/workflows/sanitize.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,30 @@ concurrency:
cancel-in-progress: true

jobs:
get_dependencies:
name: "Dependencies"
if: github.event.review.state == 'APPROVED'
uses: ./.github/workflows/dependencies.yaml

build_and_run_sanitizer:
name: ${{ matrix.mode }}
needs: get_dependencies
strategy:
matrix:
mode: ["asan", "msan", "tsan", "ubsan"]
fail-fast: false
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
if: github.event.review.state == 'APPROVED'
steps:
- uses: actions/checkout@v4
- uses: actions/cache/restore@v4
with:
path: deps
key: ${{ needs.get_dependencies.outputs.cache_key }}
- name : Strip ubuntu-24.04 to avoid space quota exceeding
alexander-e1off marked this conversation as resolved.
Show resolved Hide resolved
run: |
sudo apt-get purge \
678098 marked this conversation as resolved.
Show resolved Hide resolved
azure-cli microsoft-edge-stable google-cloud-cli \
google-chrome-stable temurin-21-jdk temurin-17-jdk \
temurin-11-jdk dotnet-sdk-8.0 firefox temurin-8-jdk \
powershell libllvm17t64 libllvm18 libllvm16t64 \
openjdk-21-jre-headless mysql-server-core-8.0
sudo apt-get autoremove
sudo apt-get autoclean
- name: Build [${{ matrix.mode }}]
run: ${{ github.workspace }}/.github/workflows/sanitizers/build_sanitizer.sh ${{ matrix.mode }}
run: |
docker build -f ${{ github.workspace }}/docker/sanitizers/Dockerfile \
--no-cache --build-arg SANITIZER_NAME=${{ matrix.mode }} \
-t sanitizer-${{ matrix.mode }} .
- name: UT [c++,${{ matrix.mode }}]
run: ${{ github.workspace }}/cmake.bld/Linux/run-unittests.sh
run: docker run --rm sanitizer-${{ matrix.mode }}
17 changes: 16 additions & 1 deletion docker/build_deps.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,22 @@

# This script downloads, builds, and installs the required build dependencies of BMQ
# from github.com/bloomberg. Software packages are installed to the /opt/bb prefix.
# If the optional argument 'only-download' is provided, the script will only download
678098 marked this conversation as resolved.
Show resolved Hide resolved
# dependencies, build and install steps are skipped.
678098 marked this conversation as resolved.
Show resolved Hide resolved

set -euxo pipefail

if [ $# == 1 ]; then
if [[ $1 == "only-download" ]]; then
DO_BUILD=false
else
echo "Unexpected optional argument, only 'only-download' is supported"
exit 1
fi
else
DO_BUILD=true
fi

fetch_git() {
local org=$1
local repo=$2
Expand Down Expand Up @@ -68,4 +81,6 @@ build() {

fetch_deps
configure
build
if [ "${DO_BUILD}" = true ]; then
build
fi
25 changes: 25 additions & 0 deletions docker/sanitizers/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# syntax=docker/dockerfile:1

FROM docker.io/ubuntu:24.04

# Check if SANITIZER_NAME argument is passed
ARG SANITIZER_NAME
RUN if [ -z $SANITIZER_NAME ]; then \
echo "Required SANITIZER_NAME build argument is not passed." ;\
exit 1 ;\
fi

# Copy blazingmq source code
WORKDIR /blazingmq
COPY docker docker
COPY etc etc
COPY src src
COPY CMakeLists.txt ./

# Build with sanitizer instrumentation
RUN chmod +x docker/build_deps.sh
RUN chmod +x docker/sanitizers/build_sanitizer.sh
678098 marked this conversation as resolved.
Show resolved Hide resolved
RUN docker/sanitizers/build_sanitizer.sh ${SANITIZER_NAME}

# Run unit tests
CMD [ "/blazingmq/cmake.bld/Linux/run-unittests.sh" ]
25 changes: 25 additions & 0 deletions docker/sanitizers/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Purpose
This folder contains scripts to run BlazingMQ and it dependencies under sanitizer (asan, msan, tsan and ubsan) in Docker container.
678098 marked this conversation as resolved.
Show resolved Hide resolved

Usually sanitizers check is done on CI, but using Docker it is possible to run sanitizers check in both CI and local environment.

## Running sanitizer check in local environment to debug sanitizer issues
- Prerequisites: docker should be installed;
- Run docker build from the BlazingMQ root folder:
```
docker build -f docker/sanitizers/Dockerfile --no-cache --build-arg SANITIZER_NAME=<sanitizer-name> -t sanitizer-<sanitizer-name> .
```
NOTE: `sanitizer-name` is `asan`, `msan`, `tsan` or `ubsan`.

- Run docker container with unit tests
```
docker run --rm sanitizer-<sanitizer-name>
```
NOTE: `sanitizer-name` - sanitizer's name from previous step.

For debbugging, it is possible to run docker container with `/bin/bash` option and run desired tests manually, e.g.
```
docker run --rm -it sanitizer-<sanitizer-name> /bin/bash

root@923efd7529a4:/blazingmq# cd cmake.bld/Linux && ./run-env.sh ctest -R <test-name>
```
66 changes: 34 additions & 32 deletions ...b/workflows/sanitizers/build_sanitizer.sh → docker/sanitizers/build_sanitizer.sh
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
# - Clang
# - LLVM libc++ standard library
# - A CMake toolchain file specific for instrumented build
# It is currently used to build instrumented BlazingMQ binaries for CI for all
# It is used to build instrumented BlazingMQ binaries for all
# Clang sanitizers (i.e. Address/Leak, Memory, Thread, UndefinedBehavior).
#
# It performs the following:
Expand All @@ -18,11 +18,10 @@
# 6) Build sanitizer-instrumented BlazingMQ unit tests.
# 7) Generate scripts to run unit tests:
# ./cmake.bld/Linux/run-unittests.sh
# This script is used as-is by CI to run unit tests under sanitizer.

set -eux

# :: Required arguments :::::::::::::::::::::::::::::::::::::::::::::::::::::::
# Check required arguments
if [ -z "${1}" ]; then
echo 'Error: Missing sanitizer name.' >&2
echo ' (Usage: build_sanitizer.sh <sanitizer-name>)' >&2
Expand All @@ -31,19 +30,11 @@ fi

SANITIZER_NAME="${1}"

# Github's 'ubuntu-22.04' image contains a lot of preinstalled tools,
# see https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2204-Readme.md.
# Uninstall uneeded tools which cause of versions clash.
sudo apt-get purge \
llvm-14 \
clang-14 \
gcc-9 \
gcc-10 \
gcc-11 \
gcc-12

# Install prerequisites
sudo apt-get update && sudo apt-get install -qy \
# Set up CA certificates first before installing other dependencies
apt-get update && \
apt-get install -y ca-certificates && \
apt-get install -qy --no-install-recommends \
lsb-release \
wget \
software-properties-common \
Expand All @@ -54,31 +45,33 @@ sudo apt-get update && sudo apt-get install -qy \
ninja-build \
bison \
libfl-dev \
pkg-config
pkg-config \
&& rm -rf /var/lib/apt/lists/*

# Install prerequisites for LLVM: latest cmake version, Ubuntu apt repository contains cmake version 3.22.1
# Install prerequisites for LLVM: latest cmake version, Ubuntu apt repository contains stale version
wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null \
| gpg --dearmor - \
| sudo tee /etc/apt/trusted.gpg.d/kitware.gpg >/dev/null
sudo apt-add-repository -y "deb https://apt.kitware.com/ubuntu/ $(lsb_release -cs) main"
sudo apt-get install -qy cmake
| tee /etc/apt/trusted.gpg.d/kitware.gpg >/dev/null
apt-add-repository -y "deb https://apt.kitware.com/ubuntu/ $(lsb_release -cs) main"
apt-get install -qy cmake

# Install LLVM
wget https://apt.llvm.org/llvm.sh
chmod +x llvm.sh
LLVM_VERSION=17
sudo ./llvm.sh ${LLVM_VERSION} all
LLVM_VERSION=18
LLVM_TAG="llvmorg-18.1.8"
./llvm.sh ${LLVM_VERSION} all

# Create version-agnostic pointers to required LLVM binaries.
sudo ln -sf /usr/bin/clang-${LLVM_VERSION} /usr/bin/clang
sudo ln -sf /usr/bin/clang++-${LLVM_VERSION} /usr/bin/clang++
sudo ln -sf /usr/bin/llvm-symbolizer-${LLVM_VERSION} /usr/bin/llvm-symbolizer
ln -sf /usr/bin/clang-${LLVM_VERSION} /usr/bin/clang
ln -sf /usr/bin/clang++-${LLVM_VERSION} /usr/bin/clang++
ln -sf /usr/bin/llvm-symbolizer-${LLVM_VERSION} /usr/bin/llvm-symbolizer

# Set some initial constants
PARALLELISM=8

DIR_ROOT="${PWD}"
DIR_SCRIPTS="${DIR_ROOT}/.github/workflows/sanitizers"
DIR_SCRIPTS="${DIR_ROOT}/docker/sanitizers"
DIR_EXTERNAL="${DIR_ROOT}/deps"
DIR_SRCS_EXT="${DIR_EXTERNAL}/srcs"
DIR_BUILD_EXT="${DIR_EXTERNAL}/cmake.bld"
Expand Down Expand Up @@ -111,24 +104,28 @@ github_url() { echo "https://github.com/$1.git"; }
# Download external dependencies
mkdir -p "${DIR_SRCS_EXT}"

# Download LLVM
LLVM_TAG="llvmorg-17.0.6"
# Download LLVM sources
curl -SL "https://github.com/llvm/llvm-project/archive/refs/tags/${LLVM_TAG}.tar.gz" \
| tar -xzC "${DIR_SRCS_EXT}"
mv "${DIR_SRCS_EXT}/llvm-project-${LLVM_TAG}" "${DIR_SRCS_EXT}/llvm-project"

# Download google-benchmark
GOOGLE_BENCHMARK_TAG="v1.8.4"
# Download google-benchmark sources
GOOGLE_BENCHMARK_TAG="v1.9.1"
checkoutGitRepo "$(github_url google/benchmark)" "${GOOGLE_BENCHMARK_TAG}" "google-benchmark"

# Download googletest
GOOGLETEST_TAG="v1.14.0"
# Download googletest sources
GOOGLETEST_TAG="v1.15.2"
checkoutGitRepo "$(github_url google/googletest)" "${GOOGLETEST_TAG}" "googletest"

# Download zlib
ZLIB_TAG="v1.3.1"
checkoutGitRepo "$(github_url madler/zlib)" "${ZLIB_TAG}" "zlib"

# Download bde-tools, bde and ntf-core sources
cd "${DIR_EXTERNAL}"
"${DIR_ROOT}"/docker/build_deps.sh "only-download"
cd -

# Build libc++ with required instrumentation
#
# The extent to which all dependencies to be compiled with sanitizer-support
Expand Down Expand Up @@ -236,6 +233,11 @@ cmake -B "${DIR_SRCS_EXT}/zlib/cmake.bld" -S "${DIR_SRCS_EXT}/zlib" \
cmake --build "${DIR_SRCS_EXT}/zlib/cmake.bld" -j${PARALLELISM}
cmake --install "${DIR_SRCS_EXT}/zlib/cmake.bld"

# Remove un-needed folders
rm -rf "${DIR_BUILD_EXT}"
rm -rf "${DIR_SRCS_EXT}/bde"
rm -rf "${DIR_SRCS_EXT}/ntf-core"

# Build BlazingMQ
PKG_CONFIG_PATH="/opt/bb/lib64/pkgconfig:/opt/bb/lib/pkgconfig:/opt/bb/share/pkgconfig:$(pkg-config --variable pc_path pkg-config)" \
cmake -B "${DIR_BUILD_BMQ}" -S "${DIR_SRC_BMQ}" -G Ninja \
Expand Down
Loading