Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
53 changes: 53 additions & 0 deletions .github/workflows/code-coverage.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
name: Code Coverage

on:
push:
branches: [ 'master', 'main', 'release/**' ]
pull_request:
branches: [ '*' ]

jobs:
coverage:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

# List compiler version
- name: List compiler and gcov version
run: |
gcc --version
gcov --version

# Install gcovr for coverage report generation
- name: Install gcovr
run: |
sudo apt-get update
sudo apt-get install -y gcovr

# Checkout wolfssl
- name: Checkout wolfssl
uses: actions/checkout@v4
with:
repository: wolfssl/wolfssl
path: wolfssl

# Run coverage
- name: Build and run tests with coverage
run: cd test && make coverage WOLFSSL_DIR=../wolfssl

# Display coverage summary in the action log
- name: Display coverage summary
run: |
echo "=== Coverage Summary ==="
cd test
gcovr Build --root .. --filter '\.\./src/.*' --filter '\.\./wolfhsm/.*' --print-summary

# Upload coverage report as artifact
- name: Upload coverage report
uses: actions/upload-artifact@v4
with:
name: coverage-report
path: coverage/
retention-days: 30

5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,8 @@ compile_commands.json
tools/static-analysis/reports/
*.xml
*.html

# Code coverage
*.gcda
*.gcno
coverage/
38 changes: 36 additions & 2 deletions test/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,12 @@ ifeq ($(ASAN),1)
LDFLAGS += -fsanitize=address
endif

# Add code coverage option
ifeq ($(COVERAGE),1)
CFLAGS += --coverage
LDFLAGS += --coverage
endif

## wolfSSL defines
ifeq ($(DEBUG_WOLFSSL),1)
DEF += -DDEBUG_WOLFSSL
Expand Down Expand Up @@ -190,7 +196,7 @@ vpath %.s $(dir $(SRC_ASM))

## Makefile Targets

.PHONY: build_app build_hex build_static clean run
.PHONY: build_app build_hex build_static clean run coverage

build_app: $(BUILD_DIR) $(BUILD_DIR)/$(BIN).elf
@echo Build complete.
Expand Down Expand Up @@ -238,7 +244,9 @@ clean:
$(BUILD_DIR)/*.o \
$(BUILD_DIR)/*.a \
$(BUILD_DIR)/*.sym \
$(BUILD_DIR)/*.disasm
$(BUILD_DIR)/*.disasm \
$(BUILD_DIR)/*.gcda \
$(BUILD_DIR)/*.gcno

# No prereq's here to stop from rebuilding with different options
run:
Expand All @@ -247,3 +255,29 @@ ifeq (,$(wildcard $(BUILD_DIR)/$(BIN).elf))
else
$(BUILD_DIR)/$(BIN).elf
endif

# Coverage target: build with coverage, run tests, and generate report
coverage:
@echo "Building with coverage enabled..."
$(MAKE) clean
$(eval COVERAGE_TARGETS := $(filter-out coverage,$(MAKECMDGOALS)))
$(MAKE) COVERAGE=1 $(if $(COVERAGE_TARGETS),$(COVERAGE_TARGETS),build_app)
@echo "Running tests..."
@if [ ! -f $(BUILD_DIR)/$(BIN).elf ]; then \
echo "Error: $(BUILD_DIR)/$(BIN).elf not found. Build failed."; \
exit 1; \
fi
$(BUILD_DIR)/$(BIN).elf
@echo "Generating coverage report..."
mkdir -p ../coverage && gcovr Build \
--root .. \
--gcov-executable gcov \
--filter '\.\./src/.*' \
--filter '\.\./wolfhsm/.*' \
--html-details ../coverage/index.html \
--print-summary
@echo "Coverage report generated at ../coverage/index.html"

# Prevent make from trying to build these as targets
%:
@:
64 changes: 64 additions & 0 deletions test/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,3 +97,67 @@ IMG_MGR ECC P256 Test completed successfully!
IMG_MGR AES128 CMAC Test completed successfully!
IMG_MGR RSA2048 Test completed successfully!
```

## Code Coverage

The test suite supports code coverage analysis using gcovr. To generate coverage reports:

**Note**: The coverage directory must exist before generating reports. The `make coverage` target creates this automatically, but if running gcovr manually, create it first with:
```bash
mkdir -p ../coverage
```

### Running Coverage

Use the convenient coverage target:
```bash
make coverage
```

This will:
1. Clean previous build artifacts
2. Rebuild with coverage instrumentation enabled
3. Run the test suite
4. Generate an HTML coverage report

The coverage report will be generated at `../coverage/index.html`.

### Manual Coverage Workflow

Alternatively, you can run coverage manually:

```bash
# Build with coverage enabled
make clean
make COVERAGE=1 DEBUG=1

# Run tests
make run

# Create coverage directory and generate report (from repository root)
cd ..
mkdir -p coverage
gcovr --root . \
--filter 'src/.*' \
--filter 'wolfhsm/.*' \
--html-details coverage/index.html \
--print-summary
```

### Coverage Options

You can customize the coverage report generation:

```bash
# Generate XML format (for CI/CD)
gcovr --root . --filter 'src/.*' --filter 'wolfhsm/.*' --xml coverage.xml

# Generate JSON format
gcovr --root . --filter 'src/.*' --filter 'wolfhsm/.*' --json coverage.json

# Include branch coverage
gcovr --root . --filter 'src/.*' --filter 'wolfhsm/.*' --branches --print-summary

# Set minimum coverage threshold (fails if below 80%)
gcovr --root . --filter 'src/.*' --filter 'wolfhsm/.*' --fail-under-line 80
```
6 changes: 3 additions & 3 deletions wolfhsm/wh_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -1047,9 +1047,9 @@ int wh_Client_KeyUnwrapAndCacheRequest(whClientContext* ctx,
* key.
* @return int Returns 0 on success, or a negative error code on failure.
*/
int wh_Client_UnrapKeyAndCacheResponse(whClientContext* ctx,
enum wc_CipherType cipherType,
uint16_t* keyIdOut);
int wh_Client_KeyUnwrapAndCacheResponse(whClientContext* ctx,
enum wc_CipherType cipherType,
uint16_t* keyIdOut);

/* Counter functions */
int wh_Client_CounterInitRequest(whClientContext* c, whNvmId counterId,
Expand Down