Skip to content

Comprehensive testing infrastructure refactor #39

Comprehensive testing infrastructure refactor

Comprehensive testing infrastructure refactor #39

Workflow file for this run

name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
env:
CARGO_TERM_COLOR: always
CARGO_INCREMENTAL: 0
jobs:
build:
name: Build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
fetch-depth: 1
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: stable
components: rustfmt, clippy
- name: Check formatting
run: cargo fmt --all -- --check
- name: Run clippy
run: cargo clippy --all-features -- -D warnings
- name: Build
run: cargo build --all-features
test:
name: Test & Coverage
runs-on: ubuntu-latest
needs: build
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: stable
components: llvm-tools-preview
- uses: taiki-e/install-action@cargo-llvm-cov
- name: Install osquery
run: |
wget -q https://github.com/osquery/osquery/releases/download/5.20.0/osquery_5.20.0-1.linux_amd64.deb
sudo dpkg -i osquery_5.20.0-1.linux_amd64.deb
osqueryi --version
- name: Build workspace (including extensions)
run: cargo build --workspace
- name: Start osqueryd with extensions
run: |
# Create directories
sudo mkdir -p /var/osquery /etc/osquery
# Create extensions.load file pointing to our built extensions
# Note: workspace members are built to target/debug/, not target/debug/examples/
# Binary names: config_static (underscore), logger-file, two-tables (hyphens)
echo "$PWD/target/debug/config_static" | sudo tee /etc/osquery/extensions.load
echo "$PWD/target/debug/logger-file" | sudo tee -a /etc/osquery/extensions.load
echo "$PWD/target/debug/two-tables" | sudo tee -a /etc/osquery/extensions.load
# Set up test environment
export TEST_LOGGER_FILE=/tmp/test_logger.log
export TEST_CONFIG_MARKER_FILE=/tmp/test_config_marker
touch "$TEST_LOGGER_FILE"
# Start osqueryd
# --allow_unsafe is needed for CI where target/debug/ has non-root ownership
sudo osqueryd --ephemeral \
--disable_extensions=false \
--extensions_socket=/var/osquery/osquery.em \
--extensions_autoload=/etc/osquery/extensions.load \
--config_plugin=static_config \
--logger_plugin=file_logger \
--database_path=/tmp/osquery.db \
--disable_watchdog \
--allow_unsafe \
--force &
# Wait for socket with timeout
for i in $(seq 1 30); do
if [ -S /var/osquery/osquery.em ]; then
echo "osquery socket ready"
sudo chmod 777 /var/osquery/osquery.em
break
fi
if [ $i -eq 30 ]; then
echo "ERROR: osquery socket not ready after 30s"
exit 1
fi
sleep 1
done
# Wait for extensions to register
sleep 5
- name: Run coverage
id: coverage
run: |
export OSQUERY_SOCKET=/var/osquery/osquery.em
export TEST_LOGGER_FILE=/tmp/test_logger.log
export TEST_CONFIG_MARKER_FILE=/tmp/test_config_marker
cargo llvm-cov --all-features --workspace --lcov --output-path lcov.info --ignore-filename-regex "_osquery"
# Calculate coverage
if [ -f lcov.info ]; then
LINES_HIT=$(grep -E "^LH:" lcov.info | cut -d: -f2 | paste -sd+ | bc)
LINES_FOUND=$(grep -E "^LF:" lcov.info | cut -d: -f2 | paste -sd+ | bc)
if [ "$LINES_FOUND" -gt 0 ]; then
COVERAGE=$(echo "scale=1; $LINES_HIT * 100 / $LINES_FOUND" | bc)
else
COVERAGE="0.0"
fi
else
echo "ERROR: lcov.info not found"
exit 1
fi
echo "coverage=$COVERAGE" >> $GITHUB_OUTPUT
echo "Coverage: $COVERAGE%"
# Enforce 90% threshold (>= 90, not just >)
if [ $(echo "$COVERAGE < 90" | bc) -eq 1 ]; then
echo "ERROR: Coverage $COVERAGE% is below 90% threshold"
exit 1
fi
- name: Update coverage badge
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
uses: schneegans/[email protected]
with:
auth: ${{ secrets.GIST_TOKEN }}
gistID: 36626ec8e61a6ccda380befc41f2cae1
filename: coverage.json
label: coverage
message: ${{ steps.coverage.outputs.coverage }}%
valColorRange: ${{ steps.coverage.outputs.coverage }}
maxColorRange: 100
minColorRange: 0