-
Notifications
You must be signed in to change notification settings - Fork 181
207 lines (185 loc) · 7.27 KB
/
Copy pathtests.yml
File metadata and controls
207 lines (185 loc) · 7.27 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
name: Unit tests
on:
push:
branches:
- main
# Always run full test suite on main branch
pull_request:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
permissions:
contents: read
jobs:
test:
permissions:
contents: read
strategy:
fail-fast: false # Continue running other components even if one fails
matrix:
include:
- component: common
coverage_module: buttercup.common
python: "3.12"
- component: orchestrator
coverage_module: buttercup.orchestrator
python: "3.12"
- component: program-model
coverage_module: buttercup.program_model
python: "3.12"
- component: seed-gen
coverage_module: buttercup.seed_gen
python: "3.12"
- component: patcher
coverage_module: buttercup.patcher
python: "3.12"
- component: fuzzer
coverage_module: buttercup.fuzzer
python: "3.12"
- component: fuzzer_runner
coverage_module: buttercup.fuzzer_runner
python: "3.12"
runs-on: ubuntu-latest
# Removed if: matrix.should_run since we're not using path filtering right now
services:
redis:
image: redis@sha256:e647cfe134bf5e8e74e620f66346f93418acfc240b71dd85640325cb7cd01402 # 7.4
options: >-
--health-cmd "redis-cli ping"
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 6379:6379
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
submodules: true
- name: Install uv
uses: astral-sh/setup-uv@d31148d669074a8d0a63714ba94f3201e7020bc3 # v8.3.0
- name: Setup uv cache
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: |
~/.cache/uv
~/.local/share/uv
key: ${{ runner.os }}-uv-${{ matrix.component }}-${{ hashFiles(format('{0}/uv.lock', matrix.component)) }}
restore-keys: |
${{ runner.os }}-uv-${{ matrix.component }}-
${{ runner.os }}-uv-
- name: Download Wasm runtime
run: wget https://github.com/vmware-labs/webassembly-language-runtimes/releases/download/python%2F3.12.0%2B20231211-040d5a6/python-3.12.0.wasm
if: matrix.component == 'seed-gen'
working-directory: seed-gen
- name: Install dependencies for program-model, seed-gen, and patcher
if: matrix.component == 'program-model' || matrix.component == 'seed-gen' || matrix.component == 'patcher'
run: |
sudo apt-get update
sudo apt-get install -y codequery ripgrep
make install-cscope
- name: Install minimal dependencies
if: matrix.component != 'program-model' && matrix.component != 'seed-gen' && matrix.component != 'patcher' && matrix.component != 'fuzzer' && matrix.component != 'fuzzer_runner'
run: |
sudo apt-get update
sudo apt-get install -y ripgrep
# Fuzzer and fuzzer_runner only need ripgrep, no codequery
- name: Install fuzzer dependencies
if: matrix.component == 'fuzzer' || matrix.component == 'fuzzer_runner'
run: |
sudo apt-get update
sudo apt-get install -y ripgrep
- name: Prepare environment
run: |
export DEBIAN_FRONTEND=noninteractive
sudo apt-get update
sudo mkdir -p /crs_scratch
sudo chmod -R 777 /crs_scratch
- name: Setup ${{ matrix.component }} component
run: |
uv sync --all-extras --frozen
# Install test reporting tools into the project venv
# This avoids adding them to every component's dependencies
uv pip install 'pytest-html>=4.1.1' 'pytest-cov>=6.0.0'
working-directory: ${{ matrix.component }}
- name: Run tests on ${{ matrix.component }} component
run: |
uv run --frozen pytest -svv \
--junit-xml=test-results.xml \
--html=test-report.html \
--self-contained-html \
--cov=${{ matrix.coverage_module }} \
--cov-report=xml \
--cov-report=html \
--cov-report=term
env:
PYTHON_WASM_BUILD_PATH: "python-3.12.0.wasm"
working-directory: ${{ matrix.component }}
- name: Audit dependencies for vulnerabilities
if: always()
run: |
# Ignore CVEs with no available fix:
# - CVE-2026-4539: pygments ReDoS in AdlLexer (no fix available)
# Use --skip-editable to ignore local packages not on PyPI
# Use uvx to run pip-audit in an isolated environment
uvx pip-audit --strict --desc \
--skip-editable \
--ignore-vuln CVE-2026-4539
working-directory: ${{ matrix.component }}
- name: Generate test summary
if: always()
run: |
echo "### Test Results: ${{ matrix.component }}" >> "$GITHUB_STEP_SUMMARY"
echo "" >> "$GITHUB_STEP_SUMMARY"
if [ -f "${{ matrix.component }}/test-results.xml" ]; then
python -c "
import xml.etree.ElementTree as ET
tree = ET.parse('${{ matrix.component }}/test-results.xml')
root = tree.getroot()
tests = root.get('tests', '0')
failures = root.get('failures', '0')
errors = root.get('errors', '0')
skipped = root.get('skipped', '0')
time = root.get('time', '0')
print(f'- **Total Tests**: {tests}')
print(f'- **Passed**: {int(tests) - int(failures) - int(errors) - int(skipped)}')
print(f'- **Failed**: {failures}')
print(f'- **Errors**: {errors}')
print(f'- **Skipped**: {skipped}')
print(f'- **Duration**: {float(time):.2f}s')
" >> "$GITHUB_STEP_SUMMARY"
else
echo "No test results found" >> "$GITHUB_STEP_SUMMARY"
fi
- name: Upload test results
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: test-results-${{ matrix.component }}-py${{ matrix.python }}
path: |
${{ matrix.component }}/test-results.xml
${{ matrix.component }}/test-report.html
${{ matrix.component }}/coverage.xml
${{ matrix.component }}/htmlcov/
retention-days: 30
# Coverage will be uploaded in a separate job after all tests complete
# Consolidated coverage upload after all tests complete
coverage-upload:
permissions:
contents: read
needs: [test]
if: always()
runs-on: ubuntu-latest
steps:
- name: Download all coverage reports
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
pattern: test-results-*
path: coverage-reports
- name: Upload coverage to Codecov
uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
with:
directory: coverage-reports
files: '*/coverage.xml,**/coverage.xml'
fail_ci_if_error: false
verbose: true