/** * @file test.yml * @brief Gitea workflow for running tests */ name: Test on: push: branches: [main, develop] pull_request: branches: [main, develop] workflow_dispatch: schedule: - cron: '0 0 * * *' # Daily at midnight env: PROJECT_NAME: automotive-rtos BUILD_DIR: build jobs: # Unit tests unit-tests: name: Unit Tests runs-on: ubuntu-latest container: image: ghcr.io/automotive-rtos/build-env:latest steps: - name: Checkout code uses: actions/checkout@v3 with: submodules: recursive - name: Cache test build uses: actions/cache@v3 with: path: ${{ env.BUILD_DIR }}/tests key: unit-tests-${{ hashFiles('tests/unit/**/*.c', 'kernel/**/*.c', 'kernel/**/*.h') }} - name: Build unit tests run: | mkdir -p ${{ env.BUILD_DIR }}/tests/unit for test_file in tests/unit/test_*.c; do test_name=$(basename "$test_file" .c) echo "Building $test_name..." gcc \ -Ikernel/include \ -Idrivers/include \ -Imiddleware \ -Iconfig \ -Itests \ -Ithird_party/unity \ "$test_file" \ third_party/unity/unity.c \ -o "${{ env.BUILD_DIR }}/tests/unit/$test_name" \ -Wall -Wextra -Werror \ -g -O0 \ -coverage done - name: Run unit tests run: | passed=0 failed=0 for test_binary in ${{ env.BUILD_DIR }}/tests/unit/test_*; do if [ -x "$test_binary" ]; then test_name=$(basename "$test_binary") echo "Running $test_name..." if timeout 60 "$test_binary" > "$test_binary.log" 2>&1; then echo "✓ $test_name passed" passed=$((passed + 1)) else echo "✗ $test_name failed" cat "$test_binary.log" failed=$((failed + 1)) fi fi done echo "Passed: $passed" echo "Failed: $failed" if [ $failed -gt 0 ]; then exit 1 fi - name: Generate coverage report run: | cd ${{ env.BUILD_DIR }}/tests/unit gcov *.gcda mkdir -p ../../../${{ env.BUILD_DIR }}/coverage gcovr \ --root ../../.. \ --exclude tests \ --exclude third_party \ --html \ --html-details \ -o ../../../${{ env.BUILD_DIR }}/coverage/index.html - name: Upload coverage report uses: actions/upload-artifact@v3 with: name: coverage-report path: ${{ env.BUILD_DIR }}/coverage/ - name: Upload test logs if: always() uses: actions/upload-artifact@v3 with: name: unit-test-logs path: ${{ env.BUILD_DIR }}/tests/unit/*.log # Integration tests integration-tests: name: Integration Tests runs-on: ubuntu-latest container: image: ghcr.io/automotive-rtos/build-env:latest steps: - name: Checkout code uses: actions/checkout@v3 with: submodules: recursive - name: Build integration tests run: | mkdir -p ${{ env.BUILD_DIR }}/tests/integration for test_file in tests/integration/test_*.c; do test_name=$(basename "$test_file" .c) echo "Building $test_name..." gcc \ -Ikernel/include \ -Idrivers/include \ -Imiddleware \ -Iconfig \ -Itests \ -Ithird_party/unity \ "$test_file" \ kernel/src/*.c \ drivers/src/*.c \ middleware/can_stack/src/*.c \ third_party/unity/unity.c \ -o "${{ env.BUILD_DIR }}/tests/integration/$test_name" \ -Wall -Wextra \ -g -O0 \ -pthread done - name: Run integration tests run: | passed=0 failed=0 for test_binary in ${{ env.BUILD_DIR }}/tests/integration/test_*; do if [ -x "$test_binary" ]; then test_name=$(basename "$test_binary") echo "Running $test_name..." if timeout 120 "$test_binary" > "$test_binary.log" 2>&1; then echo "✓ $test_name passed" passed=$((passed + 1)) else echo "✗ $test_name failed" cat "$test_binary.log" failed=$((failed + 1)) fi fi done echo "Passed: $passed" echo "Failed: $failed" if [ $failed -gt 0 ]; then exit 1 fi - name: Upload test logs if: always() uses: actions/upload-artifact@v3 with: name: integration-test-logs path: ${{ env.BUILD_DIR }}/tests/integration/*.log # System tests system-tests: name: System Tests runs-on: ubuntu-latest container: image: ghcr.io/automotive-rtos/build-env:latest options: --privileged steps: - name: Checkout code uses: actions/checkout@v3 with: submodules: recursive - name: Build system tests run: | mkdir -p ${{ env.BUILD_DIR }}/tests/system for test_file in tests/system/test_*.c; do test_name=$(basename "$test_file" .c) echo "Building $test_name..." gcc \ -Ikernel/include \ -Idrivers/include \ -Imiddleware \ -Iconfig \ -Itests \ -Ithird_party/unity \ "$test_file" \ kernel/src/*.c \ drivers/src/*.c \ middleware/**/*.c \ third_party/unity/unity.c \ -o "${{ env.BUILD_DIR }}/tests/system/$test_name" \ -Wall -Wextra \ -g -O0 \ -pthread \ -DVIRTUAL_HARDWARE done - name: Run system tests run: | passed=0 failed=0 for test_binary in ${{ env.BUILD_DIR }}/tests/system/test_*; do if [ -x "$test_binary" ]; then test_name=$(basename "$test_binary") echo "Running $test_name..." if timeout 300 "$test_binary" > "$test_binary.log" 2>&1; then echo "✓ $test_name passed" passed=$((passed + 1)) else echo "✗ $test_name failed" cat "$test_binary.log" failed=$((failed + 1)) fi fi done echo "Passed: $passed" echo "Failed: $failed" if [ $failed -gt 0 ]; then exit 1 fi - name: Upload test logs if: always() uses: actions/upload-artifact@v3 with: name: system-test-logs path: ${{ env.BUILD_DIR }}/tests/system/*.log # Generate test report test-report: name: Generate Test Report needs: [unit-tests, integration-tests, system-tests] if: always() runs-on: ubuntu-latest steps: - name: Download test logs uses: actions/download-artifact@v3 with: path: test-logs - name: Generate summary run: | echo "# Test Summary" > test-summary.md echo "" >> test-summary.md echo "Date: $(date)" >> test-summary.md echo "" >> test-summary.md echo "## Results" >> test-summary.md echo "" >> test-summary.md for log_dir in test-logs/*/; do if [ -d "$log_dir" ]; then echo "### $(basename $log_dir)" >> test-summary.md echo "" >> test-summary.md for log_file in "$log_dir"/*.log; do if [ -f "$log_file" ]; then test_name=$(basename "$log_file" .log) if grep -q "FAIL" "$log_file"; then echo "- ❌ $test_name" >> test-summary.md else echo "- ✅ $test_name" >> test-summary.md fi fi done echo "" >> test-summary.md fi done - name: Upload summary uses: actions/upload-artifact@v3 with: name: test-summary path: test-summary.md